639280631370aa6770b3adfc3c7471eeed5650d5
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_vxlan_bypass_reply)                  \
3452 _(sw_interface_set_l2_bridge_reply)                     \
3453 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3454 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3455 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3456 _(bridge_domain_add_del_reply)                          \
3457 _(sw_interface_set_l2_xconnect_reply)                   \
3458 _(l2fib_add_del_reply)                                  \
3459 _(ip_add_del_route_reply)                               \
3460 _(mpls_route_add_del_reply)                             \
3461 _(mpls_ip_bind_unbind_reply)                            \
3462 _(proxy_arp_add_del_reply)                              \
3463 _(proxy_arp_intfc_enable_disable_reply)                 \
3464 _(sw_interface_set_unnumbered_reply)                    \
3465 _(ip_neighbor_add_del_reply)                            \
3466 _(reset_vrf_reply)                                      \
3467 _(oam_add_del_reply)                                    \
3468 _(reset_fib_reply)                                      \
3469 _(dhcp_proxy_config_reply)                              \
3470 _(dhcp_proxy_config_2_reply)                            \
3471 _(dhcp_proxy_set_vss_reply)                             \
3472 _(dhcp_client_config_reply)                             \
3473 _(set_ip_flow_hash_reply)                               \
3474 _(sw_interface_ip6_enable_disable_reply)                \
3475 _(sw_interface_ip6_set_link_local_address_reply)        \
3476 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3477 _(sw_interface_ip6nd_ra_config_reply)                   \
3478 _(set_arp_neighbor_limit_reply)                         \
3479 _(l2_patch_add_del_reply)                               \
3480 _(sr_tunnel_add_del_reply)                              \
3481 _(sr_policy_add_del_reply)                              \
3482 _(sr_multicast_map_add_del_reply)                       \
3483 _(classify_add_del_session_reply)                       \
3484 _(classify_set_interface_ip_table_reply)                \
3485 _(classify_set_interface_l2_tables_reply)               \
3486 _(l2tpv3_set_tunnel_cookies_reply)                      \
3487 _(l2tpv3_interface_enable_disable_reply)                \
3488 _(l2tpv3_set_lookup_key_reply)                          \
3489 _(l2_fib_clear_table_reply)                             \
3490 _(l2_interface_efp_filter_reply)                        \
3491 _(l2_interface_vlan_tag_rewrite_reply)                  \
3492 _(modify_vhost_user_if_reply)                           \
3493 _(delete_vhost_user_if_reply)                           \
3494 _(want_ip4_arp_events_reply)                            \
3495 _(want_ip6_nd_events_reply)                             \
3496 _(input_acl_set_interface_reply)                        \
3497 _(ipsec_spd_add_del_reply)                              \
3498 _(ipsec_interface_add_del_spd_reply)                    \
3499 _(ipsec_spd_add_del_entry_reply)                        \
3500 _(ipsec_sad_add_del_entry_reply)                        \
3501 _(ipsec_sa_set_key_reply)                               \
3502 _(ikev2_profile_add_del_reply)                          \
3503 _(ikev2_profile_set_auth_reply)                         \
3504 _(ikev2_profile_set_id_reply)                           \
3505 _(ikev2_profile_set_ts_reply)                           \
3506 _(ikev2_set_local_key_reply)                            \
3507 _(delete_loopback_reply)                                \
3508 _(bd_ip_mac_add_del_reply)                              \
3509 _(map_del_domain_reply)                                 \
3510 _(map_add_del_rule_reply)                               \
3511 _(want_interface_events_reply)                          \
3512 _(want_stats_reply)                                     \
3513 _(cop_interface_enable_disable_reply)                   \
3514 _(cop_whitelist_enable_disable_reply)                   \
3515 _(sw_interface_clear_stats_reply)                       \
3516 _(ioam_enable_reply)                              \
3517 _(ioam_disable_reply)                              \
3518 _(lisp_add_del_locator_reply)                           \
3519 _(lisp_add_del_local_eid_reply)                         \
3520 _(lisp_add_del_remote_mapping_reply)                    \
3521 _(lisp_add_del_adjacency_reply)                         \
3522 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3523 _(lisp_add_del_map_resolver_reply)                      \
3524 _(lisp_gpe_enable_disable_reply)                        \
3525 _(lisp_gpe_add_del_iface_reply)                         \
3526 _(lisp_enable_disable_reply)                            \
3527 _(lisp_pitr_set_locator_set_reply)                      \
3528 _(lisp_map_request_mode_reply)                          \
3529 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3530 _(lisp_eid_table_add_del_map_reply)                     \
3531 _(vxlan_gpe_add_del_tunnel_reply)                       \
3532 _(af_packet_delete_reply)                               \
3533 _(policer_classify_set_interface_reply)                 \
3534 _(netmap_create_reply)                                  \
3535 _(netmap_delete_reply)                                  \
3536 _(set_ipfix_exporter_reply)                             \
3537 _(set_ipfix_classify_stream_reply)                      \
3538 _(ipfix_classify_table_add_del_reply)                   \
3539 _(flow_classify_set_interface_reply)                    \
3540 _(sw_interface_span_enable_disable_reply)               \
3541 _(pg_capture_reply)                                     \
3542 _(pg_enable_disable_reply)                              \
3543 _(ip_source_and_port_range_check_add_del_reply)         \
3544 _(ip_source_and_port_range_check_interface_add_del_reply)\
3545 _(delete_subif_reply)                                   \
3546 _(l2_interface_pbb_tag_rewrite_reply)                   \
3547 _(punt_reply)                                           \
3548 _(feature_enable_disable_reply)                         \
3549 _(sw_interface_tag_add_del_reply)                       \
3550 _(sw_interface_set_mtu_reply)
3551
3552 #define _(n)                                    \
3553     static void vl_api_##n##_t_handler          \
3554     (vl_api_##n##_t * mp)                       \
3555     {                                           \
3556         vat_main_t * vam = &vat_main;           \
3557         i32 retval = ntohl(mp->retval);         \
3558         if (vam->async_mode) {                  \
3559             vam->async_errors += (retval < 0);  \
3560         } else {                                \
3561             vam->retval = retval;               \
3562             vam->result_ready = 1;              \
3563         }                                       \
3564     }
3565 foreach_standard_reply_retval_handler;
3566 #undef _
3567
3568 #define _(n)                                    \
3569     static void vl_api_##n##_t_handler_json     \
3570     (vl_api_##n##_t * mp)                       \
3571     {                                           \
3572         vat_main_t * vam = &vat_main;           \
3573         vat_json_node_t node;                   \
3574         vat_json_init_object(&node);            \
3575         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3576         vat_json_print(vam->ofp, &node);        \
3577         vam->retval = ntohl(mp->retval);        \
3578         vam->result_ready = 1;                  \
3579     }
3580 foreach_standard_reply_retval_handler;
3581 #undef _
3582
3583 /*
3584  * Table of message reply handlers, must include boilerplate handlers
3585  * we just generated
3586  */
3587
3588 #define foreach_vpe_api_reply_msg                                       \
3589 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3590 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3591 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3592 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3593 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3594 _(CLI_REPLY, cli_reply)                                                 \
3595 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3596 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3597   sw_interface_add_del_address_reply)                                   \
3598 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3599 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3600 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3601 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3602 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3603   sw_interface_set_l2_xconnect_reply)                                   \
3604 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3605   sw_interface_set_l2_bridge_reply)                                     \
3606 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3607   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3608 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3609   sw_interface_set_dpdk_hqos_subport_reply)                             \
3610 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3611   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3612 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3613 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3614 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3615 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3616 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3617 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3618 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3619 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3620 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3621 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3622 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3623 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3624 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3625 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3626 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3627   proxy_arp_intfc_enable_disable_reply)                                 \
3628 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3629 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3630   sw_interface_set_unnumbered_reply)                                    \
3631 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3632 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3633 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3634 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3635 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3636 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3637 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3638 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3639 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3640 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3641 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3642 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3643   sw_interface_ip6_enable_disable_reply)                                \
3644 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3645   sw_interface_ip6_set_link_local_address_reply)                        \
3646 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3647   sw_interface_ip6nd_ra_prefix_reply)                                   \
3648 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3649   sw_interface_ip6nd_ra_config_reply)                                   \
3650 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3651 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3652 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3653 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3654 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3655 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3656 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3657 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3658 classify_set_interface_ip_table_reply)                                  \
3659 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3660   classify_set_interface_l2_tables_reply)                               \
3661 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3662 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3663 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3664 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3665 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3666   l2tpv3_interface_enable_disable_reply)                                \
3667 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3668 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3669 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3670 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3671 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3672 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3673 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3674 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3675 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3676 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3677 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3678 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3679 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3680 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3681 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3682 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3683 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3684 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3685 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3686 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3687 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3688 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3689 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3690 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3691 _(IP_DETAILS, ip_details)                                               \
3692 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3693 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3694 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3695 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3696 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3697 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3698 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3699 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3700 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3701 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3702 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3703 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3704 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3705 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3706 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3707 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3708 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3709 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3710 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3711 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3712 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3713 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3714 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3715 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3716 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3717 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3718 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3719 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3720 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3721 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3722 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3723 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3724 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3725 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3726 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3727 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3728 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3729 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3730 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3731 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3732 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3733 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3734 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3735 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3736 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3737 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3738 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3739 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3740 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3741 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3742 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3743 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3744 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3745   lisp_add_del_map_request_itr_rlocs_reply)                             \
3746 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3747   lisp_get_map_request_itr_rlocs_reply)                                 \
3748 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3749 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3750 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3751 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3752 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3753 _(POLICER_DETAILS, policer_details)                                     \
3754 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3755 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3756 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3757 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3758 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3759 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3760 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3761 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3762 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3763 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3764 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3765 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3766 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3767 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3768 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3769 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3770 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3771 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3772 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3773 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3774 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3775 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3776 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3777 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3778 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3779  ip_source_and_port_range_check_add_del_reply)                          \
3780 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3781  ip_source_and_port_range_check_interface_add_del_reply)                \
3782 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3783 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3784 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3785 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3786 _(PUNT_REPLY, punt_reply)                                               \
3787 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3788 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3789 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3790 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3791 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3792 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)
3793
3794 /* M: construct, but don't yet send a message */
3795
3796 #define M(T,t)                                  \
3797 do {                                            \
3798     vam->result_ready = 0;                      \
3799     mp = vl_msg_api_alloc(sizeof(*mp));         \
3800     memset (mp, 0, sizeof (*mp));               \
3801     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3802     mp->client_index = vam->my_client_index;    \
3803 } while(0);
3804
3805 #define M2(T,t,n)                               \
3806 do {                                            \
3807     vam->result_ready = 0;                      \
3808     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3809     memset (mp, 0, sizeof (*mp));               \
3810     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3811     mp->client_index = vam->my_client_index;    \
3812 } while(0);
3813
3814
3815 /* S: send a message */
3816 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3817
3818 /* W: wait for results, with timeout */
3819 #define W                                       \
3820 do {                                            \
3821     timeout = vat_time_now (vam) + 1.0;         \
3822                                                 \
3823     while (vat_time_now (vam) < timeout) {      \
3824         if (vam->result_ready == 1) {           \
3825             return (vam->retval);               \
3826         }                                       \
3827     }                                           \
3828     return -99;                                 \
3829 } while(0);
3830
3831 /* W2: wait for results, with timeout */
3832 #define W2(body)                                \
3833 do {                                            \
3834     timeout = vat_time_now (vam) + 1.0;         \
3835                                                 \
3836     while (vat_time_now (vam) < timeout) {      \
3837         if (vam->result_ready == 1) {           \
3838           (body);                               \
3839           return (vam->retval);                 \
3840         }                                       \
3841     }                                           \
3842     return -99;                                 \
3843 } while(0);
3844
3845 typedef struct
3846 {
3847   u8 *name;
3848   u32 value;
3849 } name_sort_t;
3850
3851
3852 #define STR_VTR_OP_CASE(op)     \
3853     case L2_VTR_ ## op:         \
3854         return "" # op;
3855
3856 static const char *
3857 str_vtr_op (u32 vtr_op)
3858 {
3859   switch (vtr_op)
3860     {
3861       STR_VTR_OP_CASE (DISABLED);
3862       STR_VTR_OP_CASE (PUSH_1);
3863       STR_VTR_OP_CASE (PUSH_2);
3864       STR_VTR_OP_CASE (POP_1);
3865       STR_VTR_OP_CASE (POP_2);
3866       STR_VTR_OP_CASE (TRANSLATE_1_1);
3867       STR_VTR_OP_CASE (TRANSLATE_1_2);
3868       STR_VTR_OP_CASE (TRANSLATE_2_1);
3869       STR_VTR_OP_CASE (TRANSLATE_2_2);
3870     }
3871
3872   return "UNKNOWN";
3873 }
3874
3875 static int
3876 dump_sub_interface_table (vat_main_t * vam)
3877 {
3878   const sw_interface_subif_t *sub = NULL;
3879
3880   if (vam->json_output)
3881     {
3882       clib_warning
3883         ("JSON output supported only for VPE API calls and dump_stats_table");
3884       return -99;
3885     }
3886
3887   fformat (vam->ofp,
3888            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3889            "Interface", "sw_if_index",
3890            "sub id", "dot1ad", "tags", "outer id",
3891            "inner id", "exact", "default", "outer any", "inner any");
3892
3893   vec_foreach (sub, vam->sw_if_subif_table)
3894   {
3895     fformat (vam->ofp,
3896              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3897              sub->interface_name,
3898              sub->sw_if_index,
3899              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3900              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3901              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3902              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3903     if (sub->vtr_op != L2_VTR_DISABLED)
3904       {
3905         fformat (vam->ofp,
3906                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3907                  "tag1: %d tag2: %d ]\n",
3908                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3909                  sub->vtr_tag1, sub->vtr_tag2);
3910       }
3911   }
3912
3913   return 0;
3914 }
3915
3916 static int
3917 name_sort_cmp (void *a1, void *a2)
3918 {
3919   name_sort_t *n1 = a1;
3920   name_sort_t *n2 = a2;
3921
3922   return strcmp ((char *) n1->name, (char *) n2->name);
3923 }
3924
3925 static int
3926 dump_interface_table (vat_main_t * vam)
3927 {
3928   hash_pair_t *p;
3929   name_sort_t *nses = 0, *ns;
3930
3931   if (vam->json_output)
3932     {
3933       clib_warning
3934         ("JSON output supported only for VPE API calls and dump_stats_table");
3935       return -99;
3936     }
3937
3938   /* *INDENT-OFF* */
3939   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3940   ({
3941     vec_add2 (nses, ns, 1);
3942     ns->name = (u8 *)(p->key);
3943     ns->value = (u32) p->value[0];
3944   }));
3945   /* *INDENT-ON* */
3946
3947   vec_sort_with_function (nses, name_sort_cmp);
3948
3949   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3950   vec_foreach (ns, nses)
3951   {
3952     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3953   }
3954   vec_free (nses);
3955   return 0;
3956 }
3957
3958 static int
3959 dump_ip_table (vat_main_t * vam, int is_ipv6)
3960 {
3961   const ip_details_t *det = NULL;
3962   const ip_address_details_t *address = NULL;
3963   u32 i = ~0;
3964
3965   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3966
3967   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3968   {
3969     i++;
3970     if (!det->present)
3971       {
3972         continue;
3973       }
3974     fformat (vam->ofp, "%-12d\n", i);
3975     fformat (vam->ofp,
3976              "            %-30s%-13s\n", "Address", "Prefix length");
3977     if (!det->addr)
3978       {
3979         continue;
3980       }
3981     vec_foreach (address, det->addr)
3982     {
3983       fformat (vam->ofp,
3984                "            %-30U%-13d\n",
3985                is_ipv6 ? format_ip6_address : format_ip4_address,
3986                address->ip, address->prefix_length);
3987     }
3988   }
3989
3990   return 0;
3991 }
3992
3993 static int
3994 dump_ipv4_table (vat_main_t * vam)
3995 {
3996   if (vam->json_output)
3997     {
3998       clib_warning
3999         ("JSON output supported only for VPE API calls and dump_stats_table");
4000       return -99;
4001     }
4002
4003   return dump_ip_table (vam, 0);
4004 }
4005
4006 static int
4007 dump_ipv6_table (vat_main_t * vam)
4008 {
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   return dump_ip_table (vam, 1);
4017 }
4018
4019 static char *
4020 counter_type_to_str (u8 counter_type, u8 is_combined)
4021 {
4022   if (!is_combined)
4023     {
4024       switch (counter_type)
4025         {
4026         case VNET_INTERFACE_COUNTER_DROP:
4027           return "drop";
4028         case VNET_INTERFACE_COUNTER_PUNT:
4029           return "punt";
4030         case VNET_INTERFACE_COUNTER_IP4:
4031           return "ip4";
4032         case VNET_INTERFACE_COUNTER_IP6:
4033           return "ip6";
4034         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4035           return "rx-no-buf";
4036         case VNET_INTERFACE_COUNTER_RX_MISS:
4037           return "rx-miss";
4038         case VNET_INTERFACE_COUNTER_RX_ERROR:
4039           return "rx-error";
4040         case VNET_INTERFACE_COUNTER_TX_ERROR:
4041           return "tx-error";
4042         default:
4043           return "INVALID-COUNTER-TYPE";
4044         }
4045     }
4046   else
4047     {
4048       switch (counter_type)
4049         {
4050         case VNET_INTERFACE_COUNTER_RX:
4051           return "rx";
4052         case VNET_INTERFACE_COUNTER_TX:
4053           return "tx";
4054         default:
4055           return "INVALID-COUNTER-TYPE";
4056         }
4057     }
4058 }
4059
4060 static int
4061 dump_stats_table (vat_main_t * vam)
4062 {
4063   vat_json_node_t node;
4064   vat_json_node_t *msg_array;
4065   vat_json_node_t *msg;
4066   vat_json_node_t *counter_array;
4067   vat_json_node_t *counter;
4068   interface_counter_t c;
4069   u64 packets;
4070   ip4_fib_counter_t *c4;
4071   ip6_fib_counter_t *c6;
4072   int i, j;
4073
4074   if (!vam->json_output)
4075     {
4076       clib_warning ("dump_stats_table supported only in JSON format");
4077       return -99;
4078     }
4079
4080   vat_json_init_object (&node);
4081
4082   /* interface counters */
4083   msg_array = vat_json_object_add (&node, "interface_counters");
4084   vat_json_init_array (msg_array);
4085   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4086     {
4087       msg = vat_json_array_add (msg_array);
4088       vat_json_init_object (msg);
4089       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4090                                        (u8 *) counter_type_to_str (i, 0));
4091       vat_json_object_add_int (msg, "is_combined", 0);
4092       counter_array = vat_json_object_add (msg, "data");
4093       vat_json_init_array (counter_array);
4094       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4095         {
4096           packets = vam->simple_interface_counters[i][j];
4097           vat_json_array_add_uint (counter_array, packets);
4098         }
4099     }
4100   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4101     {
4102       msg = vat_json_array_add (msg_array);
4103       vat_json_init_object (msg);
4104       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4105                                        (u8 *) counter_type_to_str (i, 1));
4106       vat_json_object_add_int (msg, "is_combined", 1);
4107       counter_array = vat_json_object_add (msg, "data");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4110         {
4111           c = vam->combined_interface_counters[i][j];
4112           counter = vat_json_array_add (counter_array);
4113           vat_json_init_object (counter);
4114           vat_json_object_add_uint (counter, "packets", c.packets);
4115           vat_json_object_add_uint (counter, "bytes", c.bytes);
4116         }
4117     }
4118
4119   /* ip4 fib counters */
4120   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4121   vat_json_init_array (msg_array);
4122   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_uint (msg, "vrf_id",
4127                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4128       counter_array = vat_json_object_add (msg, "c");
4129       vat_json_init_array (counter_array);
4130       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4131         {
4132           counter = vat_json_array_add (counter_array);
4133           vat_json_init_object (counter);
4134           c4 = &vam->ip4_fib_counters[i][j];
4135           vat_json_object_add_ip4 (counter, "address", c4->address);
4136           vat_json_object_add_uint (counter, "address_length",
4137                                     c4->address_length);
4138           vat_json_object_add_uint (counter, "packets", c4->packets);
4139           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4140         }
4141     }
4142
4143   /* ip6 fib counters */
4144   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4145   vat_json_init_array (msg_array);
4146   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4147     {
4148       msg = vat_json_array_add (msg_array);
4149       vat_json_init_object (msg);
4150       vat_json_object_add_uint (msg, "vrf_id",
4151                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4152       counter_array = vat_json_object_add (msg, "c");
4153       vat_json_init_array (counter_array);
4154       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4155         {
4156           counter = vat_json_array_add (counter_array);
4157           vat_json_init_object (counter);
4158           c6 = &vam->ip6_fib_counters[i][j];
4159           vat_json_object_add_ip6 (counter, "address", c6->address);
4160           vat_json_object_add_uint (counter, "address_length",
4161                                     c6->address_length);
4162           vat_json_object_add_uint (counter, "packets", c6->packets);
4163           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4164         }
4165     }
4166
4167   vat_json_print (vam->ofp, &node);
4168   vat_json_free (&node);
4169
4170   return 0;
4171 }
4172
4173 int
4174 exec (vat_main_t * vam)
4175 {
4176   api_main_t *am = &api_main;
4177   vl_api_cli_request_t *mp;
4178   f64 timeout;
4179   void *oldheap;
4180   u8 *cmd = 0;
4181   unformat_input_t *i = vam->input;
4182
4183   if (vec_len (i->buffer) == 0)
4184     return -1;
4185
4186   if (vam->exec_mode == 0 && unformat (i, "mode"))
4187     {
4188       vam->exec_mode = 1;
4189       return 0;
4190     }
4191   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4192     {
4193       vam->exec_mode = 0;
4194       return 0;
4195     }
4196
4197
4198   M (CLI_REQUEST, cli_request);
4199
4200   /*
4201    * Copy cmd into shared memory.
4202    * In order for the CLI command to work, it
4203    * must be a vector ending in \n, not a C-string ending
4204    * in \n\0.
4205    */
4206   pthread_mutex_lock (&am->vlib_rp->mutex);
4207   oldheap = svm_push_data_heap (am->vlib_rp);
4208
4209   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4210   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4211
4212   svm_pop_heap (oldheap);
4213   pthread_mutex_unlock (&am->vlib_rp->mutex);
4214
4215   mp->cmd_in_shmem = (u64) cmd;
4216   S;
4217   timeout = vat_time_now (vam) + 10.0;
4218
4219   while (vat_time_now (vam) < timeout)
4220     {
4221       if (vam->result_ready == 1)
4222         {
4223           u8 *free_me;
4224           if (vam->shmem_result != NULL)
4225             fformat (vam->ofp, "%s", vam->shmem_result);
4226           pthread_mutex_lock (&am->vlib_rp->mutex);
4227           oldheap = svm_push_data_heap (am->vlib_rp);
4228
4229           free_me = (u8 *) vam->shmem_result;
4230           vec_free (free_me);
4231
4232           svm_pop_heap (oldheap);
4233           pthread_mutex_unlock (&am->vlib_rp->mutex);
4234           return 0;
4235         }
4236     }
4237   return -99;
4238 }
4239
4240 /*
4241  * Future replacement of exec() that passes CLI buffers directly in
4242  * the API messages instead of an additional shared memory area.
4243  */
4244 static int
4245 exec_inband (vat_main_t * vam)
4246 {
4247   vl_api_cli_inband_t *mp;
4248   f64 timeout;
4249   unformat_input_t *i = vam->input;
4250
4251   if (vec_len (i->buffer) == 0)
4252     return -1;
4253
4254   if (vam->exec_mode == 0 && unformat (i, "mode"))
4255     {
4256       vam->exec_mode = 1;
4257       return 0;
4258     }
4259   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4260     {
4261       vam->exec_mode = 0;
4262       return 0;
4263     }
4264
4265   /*
4266    * In order for the CLI command to work, it
4267    * must be a vector ending in \n, not a C-string ending
4268    * in \n\0.
4269    */
4270   u32 len = vec_len (vam->input->buffer);
4271   M2 (CLI_INBAND, cli_inband, len);
4272   clib_memcpy (mp->cmd, vam->input->buffer, len);
4273   mp->length = htonl (len);
4274
4275   S;
4276   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4277 }
4278
4279 static int
4280 api_create_loopback (vat_main_t * vam)
4281 {
4282   unformat_input_t *i = vam->input;
4283   vl_api_create_loopback_t *mp;
4284   f64 timeout;
4285   u8 mac_address[6];
4286   u8 mac_set = 0;
4287
4288   memset (mac_address, 0, sizeof (mac_address));
4289
4290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4291     {
4292       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4293         mac_set = 1;
4294       else
4295         break;
4296     }
4297
4298   /* Construct the API message */
4299   M (CREATE_LOOPBACK, create_loopback);
4300   if (mac_set)
4301     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4302
4303   S;
4304   W;
4305 }
4306
4307 static int
4308 api_delete_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_delete_loopback_t *mp;
4312   f64 timeout;
4313   u32 sw_if_index = ~0;
4314
4315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4316     {
4317       if (unformat (i, "sw_if_index %d", &sw_if_index))
4318         ;
4319       else
4320         break;
4321     }
4322
4323   if (sw_if_index == ~0)
4324     {
4325       errmsg ("missing sw_if_index\n");
4326       return -99;
4327     }
4328
4329   /* Construct the API message */
4330   M (DELETE_LOOPBACK, delete_loopback);
4331   mp->sw_if_index = ntohl (sw_if_index);
4332
4333   S;
4334   W;
4335 }
4336
4337 static int
4338 api_want_stats (vat_main_t * vam)
4339 {
4340   unformat_input_t *i = vam->input;
4341   vl_api_want_stats_t *mp;
4342   f64 timeout;
4343   int enable = -1;
4344
4345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4346     {
4347       if (unformat (i, "enable"))
4348         enable = 1;
4349       else if (unformat (i, "disable"))
4350         enable = 0;
4351       else
4352         break;
4353     }
4354
4355   if (enable == -1)
4356     {
4357       errmsg ("missing enable|disable\n");
4358       return -99;
4359     }
4360
4361   M (WANT_STATS, want_stats);
4362   mp->enable_disable = enable;
4363
4364   S;
4365   W;
4366 }
4367
4368 static int
4369 api_want_interface_events (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_want_interface_events_t *mp;
4373   f64 timeout;
4374   int enable = -1;
4375
4376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4377     {
4378       if (unformat (i, "enable"))
4379         enable = 1;
4380       else if (unformat (i, "disable"))
4381         enable = 0;
4382       else
4383         break;
4384     }
4385
4386   if (enable == -1)
4387     {
4388       errmsg ("missing enable|disable\n");
4389       return -99;
4390     }
4391
4392   M (WANT_INTERFACE_EVENTS, want_interface_events);
4393   mp->enable_disable = enable;
4394
4395   vam->interface_event_display = enable;
4396
4397   S;
4398   W;
4399 }
4400
4401
4402 /* Note: non-static, called once to set up the initial intfc table */
4403 int
4404 api_sw_interface_dump (vat_main_t * vam)
4405 {
4406   vl_api_sw_interface_dump_t *mp;
4407   f64 timeout;
4408   hash_pair_t *p;
4409   name_sort_t *nses = 0, *ns;
4410   sw_interface_subif_t *sub = NULL;
4411
4412   /* Toss the old name table */
4413   /* *INDENT-OFF* */
4414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4415   ({
4416     vec_add2 (nses, ns, 1);
4417     ns->name = (u8 *)(p->key);
4418     ns->value = (u32) p->value[0];
4419   }));
4420   /* *INDENT-ON* */
4421
4422   hash_free (vam->sw_if_index_by_interface_name);
4423
4424   vec_foreach (ns, nses) vec_free (ns->name);
4425
4426   vec_free (nses);
4427
4428   vec_foreach (sub, vam->sw_if_subif_table)
4429   {
4430     vec_free (sub->interface_name);
4431   }
4432   vec_free (vam->sw_if_subif_table);
4433
4434   /* recreate the interface name hash table */
4435   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4436
4437   /* Get list of ethernets */
4438   M (SW_INTERFACE_DUMP, sw_interface_dump);
4439   mp->name_filter_valid = 1;
4440   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4441   S;
4442
4443   /* and local / loopback interfaces */
4444   M (SW_INTERFACE_DUMP, sw_interface_dump);
4445   mp->name_filter_valid = 1;
4446   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4447   S;
4448
4449   /* and packet-generator interfaces */
4450   M (SW_INTERFACE_DUMP, sw_interface_dump);
4451   mp->name_filter_valid = 1;
4452   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4453   S;
4454
4455   /* and vxlan-gpe tunnel interfaces */
4456   M (SW_INTERFACE_DUMP, sw_interface_dump);
4457   mp->name_filter_valid = 1;
4458   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4459            sizeof (mp->name_filter) - 1);
4460   S;
4461
4462   /* and vxlan tunnel interfaces */
4463   M (SW_INTERFACE_DUMP, sw_interface_dump);
4464   mp->name_filter_valid = 1;
4465   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4466   S;
4467
4468   /* and host (af_packet) interfaces */
4469   M (SW_INTERFACE_DUMP, sw_interface_dump);
4470   mp->name_filter_valid = 1;
4471   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4472   S;
4473
4474   /* and l2tpv3 tunnel interfaces */
4475   M (SW_INTERFACE_DUMP, sw_interface_dump);
4476   mp->name_filter_valid = 1;
4477   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4478            sizeof (mp->name_filter) - 1);
4479   S;
4480
4481   /* and GRE tunnel interfaces */
4482   M (SW_INTERFACE_DUMP, sw_interface_dump);
4483   mp->name_filter_valid = 1;
4484   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4485   S;
4486
4487   /* and LISP-GPE interfaces */
4488   M (SW_INTERFACE_DUMP, sw_interface_dump);
4489   mp->name_filter_valid = 1;
4490   strncpy ((char *) mp->name_filter, "lisp_gpe",
4491            sizeof (mp->name_filter) - 1);
4492   S;
4493
4494   /* and IPSEC tunnel interfaces */
4495   M (SW_INTERFACE_DUMP, sw_interface_dump);
4496   mp->name_filter_valid = 1;
4497   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4498   S;
4499
4500   /* Use a control ping for synchronization */
4501   {
4502     vl_api_control_ping_t *mp;
4503     M (CONTROL_PING, control_ping);
4504     S;
4505   }
4506   W;
4507 }
4508
4509 static int
4510 api_sw_interface_set_flags (vat_main_t * vam)
4511 {
4512   unformat_input_t *i = vam->input;
4513   vl_api_sw_interface_set_flags_t *mp;
4514   f64 timeout;
4515   u32 sw_if_index;
4516   u8 sw_if_index_set = 0;
4517   u8 admin_up = 0, link_up = 0;
4518
4519   /* Parse args required to build the message */
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "admin-up"))
4523         admin_up = 1;
4524       else if (unformat (i, "admin-down"))
4525         admin_up = 0;
4526       else if (unformat (i, "link-up"))
4527         link_up = 1;
4528       else if (unformat (i, "link-down"))
4529         link_up = 0;
4530       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4531         sw_if_index_set = 1;
4532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4533         sw_if_index_set = 1;
4534       else
4535         break;
4536     }
4537
4538   if (sw_if_index_set == 0)
4539     {
4540       errmsg ("missing interface name or sw_if_index\n");
4541       return -99;
4542     }
4543
4544   /* Construct the API message */
4545   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4546   mp->sw_if_index = ntohl (sw_if_index);
4547   mp->admin_up_down = admin_up;
4548   mp->link_up_down = link_up;
4549
4550   /* send it... */
4551   S;
4552
4553   /* Wait for a reply, return the good/bad news... */
4554   W;
4555 }
4556
4557 static int
4558 api_sw_interface_clear_stats (vat_main_t * vam)
4559 {
4560   unformat_input_t *i = vam->input;
4561   vl_api_sw_interface_clear_stats_t *mp;
4562   f64 timeout;
4563   u32 sw_if_index;
4564   u8 sw_if_index_set = 0;
4565
4566   /* Parse args required to build the message */
4567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4568     {
4569       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4570         sw_if_index_set = 1;
4571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4572         sw_if_index_set = 1;
4573       else
4574         break;
4575     }
4576
4577   /* Construct the API message */
4578   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4579
4580   if (sw_if_index_set == 1)
4581     mp->sw_if_index = ntohl (sw_if_index);
4582   else
4583     mp->sw_if_index = ~0;
4584
4585   /* send it... */
4586   S;
4587
4588   /* Wait for a reply, return the good/bad news... */
4589   W;
4590 }
4591
4592 static int
4593 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4594 {
4595   unformat_input_t *i = vam->input;
4596   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4597   f64 timeout;
4598   u32 sw_if_index;
4599   u8 sw_if_index_set = 0;
4600   u32 subport;
4601   u8 subport_set = 0;
4602   u32 pipe;
4603   u8 pipe_set = 0;
4604   u32 profile;
4605   u8 profile_set = 0;
4606
4607   /* Parse args required to build the message */
4608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4609     {
4610       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4611         sw_if_index_set = 1;
4612       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4613         sw_if_index_set = 1;
4614       else if (unformat (i, "subport %u", &subport))
4615         subport_set = 1;
4616       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4617         sw_if_index_set = 1;
4618       else if (unformat (i, "pipe %u", &pipe))
4619         pipe_set = 1;
4620       else if (unformat (i, "profile %u", &profile))
4621         profile_set = 1;
4622       else
4623         break;
4624     }
4625
4626   if (sw_if_index_set == 0)
4627     {
4628       errmsg ("missing interface name or sw_if_index\n");
4629       return -99;
4630     }
4631
4632   if (subport_set == 0)
4633     {
4634       errmsg ("missing subport \n");
4635       return -99;
4636     }
4637
4638   if (pipe_set == 0)
4639     {
4640       errmsg ("missing pipe\n");
4641       return -99;
4642     }
4643
4644   if (profile_set == 0)
4645     {
4646       errmsg ("missing profile\n");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4651
4652   mp->sw_if_index = ntohl (sw_if_index);
4653   mp->subport = ntohl (subport);
4654   mp->pipe = ntohl (pipe);
4655   mp->profile = ntohl (profile);
4656
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4669   f64 timeout;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u32 subport;
4673   u8 subport_set = 0;
4674   u32 tb_rate = 1250000000;     /* 10GbE */
4675   u32 tb_size = 1000000;
4676   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4677   u32 tc_period = 10;
4678
4679   /* Parse args required to build the message */
4680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4681     {
4682       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4683         sw_if_index_set = 1;
4684       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4685         sw_if_index_set = 1;
4686       else if (unformat (i, "subport %u", &subport))
4687         subport_set = 1;
4688       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4689         sw_if_index_set = 1;
4690       else if (unformat (i, "rate %u", &tb_rate))
4691         {
4692           u32 tc_id;
4693
4694           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4695                tc_id++)
4696             tc_rate[tc_id] = tb_rate;
4697         }
4698       else if (unformat (i, "bktsize %u", &tb_size))
4699         ;
4700       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4701         ;
4702       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4703         ;
4704       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4705         ;
4706       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4707         ;
4708       else if (unformat (i, "period %u", &tc_period))
4709         ;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index\n");
4717       return -99;
4718     }
4719
4720   if (subport_set == 0)
4721     {
4722       errmsg ("missing subport \n");
4723       return -99;
4724     }
4725
4726   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4727
4728   mp->sw_if_index = ntohl (sw_if_index);
4729   mp->subport = ntohl (subport);
4730   mp->tb_rate = ntohl (tb_rate);
4731   mp->tb_size = ntohl (tb_size);
4732   mp->tc_rate[0] = ntohl (tc_rate[0]);
4733   mp->tc_rate[1] = ntohl (tc_rate[1]);
4734   mp->tc_rate[2] = ntohl (tc_rate[2]);
4735   mp->tc_rate[3] = ntohl (tc_rate[3]);
4736   mp->tc_period = ntohl (tc_period);
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u8 entry_set = 0;
4753   u8 tc_set = 0;
4754   u8 queue_set = 0;
4755   u32 entry, tc, queue;
4756
4757   /* Parse args required to build the message */
4758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759     {
4760       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4761         sw_if_index_set = 1;
4762       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "entry %d", &entry))
4765         entry_set = 1;
4766       else if (unformat (i, "tc %d", &tc))
4767         tc_set = 1;
4768       else if (unformat (i, "queue %d", &queue))
4769         queue_set = 1;
4770       else
4771         break;
4772     }
4773
4774   if (sw_if_index_set == 0)
4775     {
4776       errmsg ("missing interface name or sw_if_index\n");
4777       return -99;
4778     }
4779
4780   if (entry_set == 0)
4781     {
4782       errmsg ("missing entry \n");
4783       return -99;
4784     }
4785
4786   if (tc_set == 0)
4787     {
4788       errmsg ("missing traffic class \n");
4789       return -99;
4790     }
4791
4792   if (queue_set == 0)
4793     {
4794       errmsg ("missing queue \n");
4795       return -99;
4796     }
4797
4798   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4799
4800   mp->sw_if_index = ntohl (sw_if_index);
4801   mp->entry = ntohl (entry);
4802   mp->tc = ntohl (tc);
4803   mp->queue = ntohl (queue);
4804
4805   S;
4806   W;
4807   /* NOTREACHED */
4808   return 0;
4809 }
4810
4811 static int
4812 api_sw_interface_add_del_address (vat_main_t * vam)
4813 {
4814   unformat_input_t *i = vam->input;
4815   vl_api_sw_interface_add_del_address_t *mp;
4816   f64 timeout;
4817   u32 sw_if_index;
4818   u8 sw_if_index_set = 0;
4819   u8 is_add = 1, del_all = 0;
4820   u32 address_length = 0;
4821   u8 v4_address_set = 0;
4822   u8 v6_address_set = 0;
4823   ip4_address_t v4address;
4824   ip6_address_t v6address;
4825
4826   /* Parse args required to build the message */
4827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4828     {
4829       if (unformat (i, "del-all"))
4830         del_all = 1;
4831       else if (unformat (i, "del"))
4832         is_add = 0;
4833       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4834         sw_if_index_set = 1;
4835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4836         sw_if_index_set = 1;
4837       else if (unformat (i, "%U/%d",
4838                          unformat_ip4_address, &v4address, &address_length))
4839         v4_address_set = 1;
4840       else if (unformat (i, "%U/%d",
4841                          unformat_ip6_address, &v6address, &address_length))
4842         v6_address_set = 1;
4843       else
4844         break;
4845     }
4846
4847   if (sw_if_index_set == 0)
4848     {
4849       errmsg ("missing interface name or sw_if_index\n");
4850       return -99;
4851     }
4852   if (v4_address_set && v6_address_set)
4853     {
4854       errmsg ("both v4 and v6 addresses set\n");
4855       return -99;
4856     }
4857   if (!v4_address_set && !v6_address_set && !del_all)
4858     {
4859       errmsg ("no addresses set\n");
4860       return -99;
4861     }
4862
4863   /* Construct the API message */
4864   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4865
4866   mp->sw_if_index = ntohl (sw_if_index);
4867   mp->is_add = is_add;
4868   mp->del_all = del_all;
4869   if (v6_address_set)
4870     {
4871       mp->is_ipv6 = 1;
4872       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4873     }
4874   else
4875     {
4876       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4877     }
4878   mp->address_length = address_length;
4879
4880   /* send it... */
4881   S;
4882
4883   /* Wait for a reply, return good/bad news  */
4884   W;
4885 }
4886
4887 static int
4888 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4889 {
4890   unformat_input_t *i = vam->input;
4891   vl_api_sw_interface_set_mpls_enable_t *mp;
4892   f64 timeout;
4893   u32 sw_if_index;
4894   u8 sw_if_index_set = 0;
4895   u8 enable = 1;
4896
4897   /* Parse args required to build the message */
4898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4899     {
4900       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4901         sw_if_index_set = 1;
4902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4903         sw_if_index_set = 1;
4904       else if (unformat (i, "disable"))
4905         enable = 0;
4906       else if (unformat (i, "dis"))
4907         enable = 0;
4908       else
4909         break;
4910     }
4911
4912   if (sw_if_index_set == 0)
4913     {
4914       errmsg ("missing interface name or sw_if_index\n");
4915       return -99;
4916     }
4917
4918   /* Construct the API message */
4919   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4920
4921   mp->sw_if_index = ntohl (sw_if_index);
4922   mp->enable = enable;
4923
4924   /* send it... */
4925   S;
4926
4927   /* Wait for a reply... */
4928   W;
4929 }
4930
4931 static int
4932 api_sw_interface_set_table (vat_main_t * vam)
4933 {
4934   unformat_input_t *i = vam->input;
4935   vl_api_sw_interface_set_table_t *mp;
4936   f64 timeout;
4937   u32 sw_if_index, vrf_id = 0;
4938   u8 sw_if_index_set = 0;
4939   u8 is_ipv6 = 0;
4940
4941   /* Parse args required to build the message */
4942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4943     {
4944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4945         sw_if_index_set = 1;
4946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4947         sw_if_index_set = 1;
4948       else if (unformat (i, "vrf %d", &vrf_id))
4949         ;
4950       else if (unformat (i, "ipv6"))
4951         is_ipv6 = 1;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   /* Construct the API message */
4963   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4964
4965   mp->sw_if_index = ntohl (sw_if_index);
4966   mp->is_ipv6 = is_ipv6;
4967   mp->vrf_id = ntohl (vrf_id);
4968
4969   /* send it... */
4970   S;
4971
4972   /* Wait for a reply... */
4973   W;
4974 }
4975
4976 static int
4977 api_sw_interface_set_vpath (vat_main_t * vam)
4978 {
4979   unformat_input_t *i = vam->input;
4980   vl_api_sw_interface_set_vpath_t *mp;
4981   f64 timeout;
4982   u32 sw_if_index = 0;
4983   u8 sw_if_index_set = 0;
4984   u8 is_enable = 0;
4985
4986   /* Parse args required to build the message */
4987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988     {
4989       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4990         sw_if_index_set = 1;
4991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "enable"))
4994         is_enable = 1;
4995       else if (unformat (i, "disable"))
4996         is_enable = 0;
4997       else
4998         break;
4999     }
5000
5001   if (sw_if_index_set == 0)
5002     {
5003       errmsg ("missing interface name or sw_if_index\n");
5004       return -99;
5005     }
5006
5007   /* Construct the API message */
5008   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5009
5010   mp->sw_if_index = ntohl (sw_if_index);
5011   mp->enable = is_enable;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply... */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5025   f64 timeout;
5026   u32 sw_if_index = 0;
5027   u8 sw_if_index_set = 0;
5028   u8 is_enable = 0;
5029   u8 is_ipv6 = 0;
5030
5031   /* Parse args required to build the message */
5032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5033     {
5034       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5035         sw_if_index_set = 1;
5036       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5037         sw_if_index_set = 1;
5038       else if (unformat (i, "enable"))
5039         is_enable = 1;
5040       else if (unformat (i, "disable"))
5041         is_enable = 0;
5042       else if (unformat (i, "ip4"))
5043         is_ipv6 = 0;
5044       else if (unformat (i, "ip6"))
5045         is_ipv6 = 1;
5046       else
5047         break;
5048     }
5049
5050   if (sw_if_index_set == 0)
5051     {
5052       errmsg ("missing interface name or sw_if_index\n");
5053       return -99;
5054     }
5055
5056   /* Construct the API message */
5057   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5058
5059   mp->sw_if_index = ntohl (sw_if_index);
5060   mp->enable = is_enable;
5061   mp->is_ipv6 = is_ipv6;
5062
5063   /* send it... */
5064   S;
5065
5066   /* Wait for a reply... */
5067   W;
5068 }
5069
5070 static int
5071 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5072 {
5073   unformat_input_t *i = vam->input;
5074   vl_api_sw_interface_set_l2_xconnect_t *mp;
5075   f64 timeout;
5076   u32 rx_sw_if_index;
5077   u8 rx_sw_if_index_set = 0;
5078   u32 tx_sw_if_index;
5079   u8 tx_sw_if_index_set = 0;
5080   u8 enable = 1;
5081
5082   /* Parse args required to build the message */
5083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5084     {
5085       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5086         rx_sw_if_index_set = 1;
5087       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5088         tx_sw_if_index_set = 1;
5089       else if (unformat (i, "rx"))
5090         {
5091           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5092             {
5093               if (unformat (i, "%U", unformat_sw_if_index, vam,
5094                             &rx_sw_if_index))
5095                 rx_sw_if_index_set = 1;
5096             }
5097           else
5098             break;
5099         }
5100       else if (unformat (i, "tx"))
5101         {
5102           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5103             {
5104               if (unformat (i, "%U", unformat_sw_if_index, vam,
5105                             &tx_sw_if_index))
5106                 tx_sw_if_index_set = 1;
5107             }
5108           else
5109             break;
5110         }
5111       else if (unformat (i, "enable"))
5112         enable = 1;
5113       else if (unformat (i, "disable"))
5114         enable = 0;
5115       else
5116         break;
5117     }
5118
5119   if (rx_sw_if_index_set == 0)
5120     {
5121       errmsg ("missing rx interface name or rx_sw_if_index\n");
5122       return -99;
5123     }
5124
5125   if (enable && (tx_sw_if_index_set == 0))
5126     {
5127       errmsg ("missing tx interface name or tx_sw_if_index\n");
5128       return -99;
5129     }
5130
5131   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5132
5133   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5134   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5135   mp->enable = enable;
5136
5137   S;
5138   W;
5139   /* NOTREACHED */
5140   return 0;
5141 }
5142
5143 static int
5144 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5145 {
5146   unformat_input_t *i = vam->input;
5147   vl_api_sw_interface_set_l2_bridge_t *mp;
5148   f64 timeout;
5149   u32 rx_sw_if_index;
5150   u8 rx_sw_if_index_set = 0;
5151   u32 bd_id;
5152   u8 bd_id_set = 0;
5153   u8 bvi = 0;
5154   u32 shg = 0;
5155   u8 enable = 1;
5156
5157   /* Parse args required to build the message */
5158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5159     {
5160       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5161         rx_sw_if_index_set = 1;
5162       else if (unformat (i, "bd_id %d", &bd_id))
5163         bd_id_set = 1;
5164       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5165         rx_sw_if_index_set = 1;
5166       else if (unformat (i, "shg %d", &shg))
5167         ;
5168       else if (unformat (i, "bvi"))
5169         bvi = 1;
5170       else if (unformat (i, "enable"))
5171         enable = 1;
5172       else if (unformat (i, "disable"))
5173         enable = 0;
5174       else
5175         break;
5176     }
5177
5178   if (rx_sw_if_index_set == 0)
5179     {
5180       errmsg ("missing rx interface name or sw_if_index\n");
5181       return -99;
5182     }
5183
5184   if (enable && (bd_id_set == 0))
5185     {
5186       errmsg ("missing bridge domain\n");
5187       return -99;
5188     }
5189
5190   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5191
5192   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5193   mp->bd_id = ntohl (bd_id);
5194   mp->shg = (u8) shg;
5195   mp->bvi = bvi;
5196   mp->enable = enable;
5197
5198   S;
5199   W;
5200   /* NOTREACHED */
5201   return 0;
5202 }
5203
5204 static int
5205 api_bridge_domain_dump (vat_main_t * vam)
5206 {
5207   unformat_input_t *i = vam->input;
5208   vl_api_bridge_domain_dump_t *mp;
5209   f64 timeout;
5210   u32 bd_id = ~0;
5211
5212   /* Parse args required to build the message */
5213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5214     {
5215       if (unformat (i, "bd_id %d", &bd_id))
5216         ;
5217       else
5218         break;
5219     }
5220
5221   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5222   mp->bd_id = ntohl (bd_id);
5223   S;
5224
5225   /* Use a control ping for synchronization */
5226   {
5227     vl_api_control_ping_t *mp;
5228     M (CONTROL_PING, control_ping);
5229     S;
5230   }
5231
5232   W;
5233   /* NOTREACHED */
5234   return 0;
5235 }
5236
5237 static int
5238 api_bridge_domain_add_del (vat_main_t * vam)
5239 {
5240   unformat_input_t *i = vam->input;
5241   vl_api_bridge_domain_add_del_t *mp;
5242   f64 timeout;
5243   u32 bd_id = ~0;
5244   u8 is_add = 1;
5245   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5246
5247   /* Parse args required to build the message */
5248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5249     {
5250       if (unformat (i, "bd_id %d", &bd_id))
5251         ;
5252       else if (unformat (i, "flood %d", &flood))
5253         ;
5254       else if (unformat (i, "uu-flood %d", &uu_flood))
5255         ;
5256       else if (unformat (i, "forward %d", &forward))
5257         ;
5258       else if (unformat (i, "learn %d", &learn))
5259         ;
5260       else if (unformat (i, "arp-term %d", &arp_term))
5261         ;
5262       else if (unformat (i, "del"))
5263         {
5264           is_add = 0;
5265           flood = uu_flood = forward = learn = 0;
5266         }
5267       else
5268         break;
5269     }
5270
5271   if (bd_id == ~0)
5272     {
5273       errmsg ("missing bridge domain\n");
5274       return -99;
5275     }
5276
5277   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5278
5279   mp->bd_id = ntohl (bd_id);
5280   mp->flood = flood;
5281   mp->uu_flood = uu_flood;
5282   mp->forward = forward;
5283   mp->learn = learn;
5284   mp->arp_term = arp_term;
5285   mp->is_add = is_add;
5286
5287   S;
5288   W;
5289   /* NOTREACHED */
5290   return 0;
5291 }
5292
5293 static int
5294 api_l2fib_add_del (vat_main_t * vam)
5295 {
5296   unformat_input_t *i = vam->input;
5297   vl_api_l2fib_add_del_t *mp;
5298   f64 timeout;
5299   u64 mac = 0;
5300   u8 mac_set = 0;
5301   u32 bd_id;
5302   u8 bd_id_set = 0;
5303   u32 sw_if_index = ~0;
5304   u8 sw_if_index_set = 0;
5305   u8 is_add = 1;
5306   u8 static_mac = 0;
5307   u8 filter_mac = 0;
5308   u8 bvi_mac = 0;
5309   int count = 1;
5310   f64 before = 0;
5311   int j;
5312
5313   /* Parse args required to build the message */
5314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5315     {
5316       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5317         mac_set = 1;
5318       else if (unformat (i, "bd_id %d", &bd_id))
5319         bd_id_set = 1;
5320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5321         sw_if_index_set = 1;
5322       else if (unformat (i, "sw_if"))
5323         {
5324           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5325             {
5326               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5327                 sw_if_index_set = 1;
5328             }
5329           else
5330             break;
5331         }
5332       else if (unformat (i, "static"))
5333         static_mac = 1;
5334       else if (unformat (i, "filter"))
5335         {
5336           filter_mac = 1;
5337           static_mac = 1;
5338         }
5339       else if (unformat (i, "bvi"))
5340         {
5341           bvi_mac = 1;
5342           static_mac = 1;
5343         }
5344       else if (unformat (i, "del"))
5345         is_add = 0;
5346       else if (unformat (i, "count %d", &count))
5347         ;
5348       else
5349         break;
5350     }
5351
5352   if (mac_set == 0)
5353     {
5354       errmsg ("missing mac address\n");
5355       return -99;
5356     }
5357
5358   if (bd_id_set == 0)
5359     {
5360       errmsg ("missing bridge domain\n");
5361       return -99;
5362     }
5363
5364   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5365     {
5366       errmsg ("missing interface name or sw_if_index\n");
5367       return -99;
5368     }
5369
5370   if (count > 1)
5371     {
5372       /* Turn on async mode */
5373       vam->async_mode = 1;
5374       vam->async_errors = 0;
5375       before = vat_time_now (vam);
5376     }
5377
5378   for (j = 0; j < count; j++)
5379     {
5380       M (L2FIB_ADD_DEL, l2fib_add_del);
5381
5382       mp->mac = mac;
5383       mp->bd_id = ntohl (bd_id);
5384       mp->is_add = is_add;
5385
5386       if (is_add)
5387         {
5388           mp->sw_if_index = ntohl (sw_if_index);
5389           mp->static_mac = static_mac;
5390           mp->filter_mac = filter_mac;
5391           mp->bvi_mac = bvi_mac;
5392         }
5393       increment_mac_address (&mac);
5394       /* send it... */
5395       S;
5396     }
5397
5398   if (count > 1)
5399     {
5400       vl_api_control_ping_t *mp;
5401       f64 after;
5402
5403       /* Shut off async mode */
5404       vam->async_mode = 0;
5405
5406       M (CONTROL_PING, control_ping);
5407       S;
5408
5409       timeout = vat_time_now (vam) + 1.0;
5410       while (vat_time_now (vam) < timeout)
5411         if (vam->result_ready == 1)
5412           goto out;
5413       vam->retval = -99;
5414
5415     out:
5416       if (vam->retval == -99)
5417         errmsg ("timeout\n");
5418
5419       if (vam->async_errors > 0)
5420         {
5421           errmsg ("%d asynchronous errors\n", vam->async_errors);
5422           vam->retval = -98;
5423         }
5424       vam->async_errors = 0;
5425       after = vat_time_now (vam);
5426
5427       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5428                count, after - before, count / (after - before));
5429     }
5430   else
5431     {
5432       /* Wait for a reply... */
5433       W;
5434     }
5435   /* Return the good/bad news */
5436   return (vam->retval);
5437 }
5438
5439 static int
5440 api_l2_flags (vat_main_t * vam)
5441 {
5442   unformat_input_t *i = vam->input;
5443   vl_api_l2_flags_t *mp;
5444   f64 timeout;
5445   u32 sw_if_index;
5446   u32 feature_bitmap = 0;
5447   u8 sw_if_index_set = 0;
5448
5449   /* Parse args required to build the message */
5450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5451     {
5452       if (unformat (i, "sw_if_index %d", &sw_if_index))
5453         sw_if_index_set = 1;
5454       else if (unformat (i, "sw_if"))
5455         {
5456           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5457             {
5458               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5459                 sw_if_index_set = 1;
5460             }
5461           else
5462             break;
5463         }
5464       else if (unformat (i, "learn"))
5465         feature_bitmap |= L2INPUT_FEAT_LEARN;
5466       else if (unformat (i, "forward"))
5467         feature_bitmap |= L2INPUT_FEAT_FWD;
5468       else if (unformat (i, "flood"))
5469         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5470       else if (unformat (i, "uu-flood"))
5471         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5472       else
5473         break;
5474     }
5475
5476   if (sw_if_index_set == 0)
5477     {
5478       errmsg ("missing interface name or sw_if_index\n");
5479       return -99;
5480     }
5481
5482   M (L2_FLAGS, l2_flags);
5483
5484   mp->sw_if_index = ntohl (sw_if_index);
5485   mp->feature_bitmap = ntohl (feature_bitmap);
5486
5487   S;
5488   W;
5489   /* NOTREACHED */
5490   return 0;
5491 }
5492
5493 static int
5494 api_bridge_flags (vat_main_t * vam)
5495 {
5496   unformat_input_t *i = vam->input;
5497   vl_api_bridge_flags_t *mp;
5498   f64 timeout;
5499   u32 bd_id;
5500   u8 bd_id_set = 0;
5501   u8 is_set = 1;
5502   u32 flags = 0;
5503
5504   /* Parse args required to build the message */
5505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5506     {
5507       if (unformat (i, "bd_id %d", &bd_id))
5508         bd_id_set = 1;
5509       else if (unformat (i, "learn"))
5510         flags |= L2_LEARN;
5511       else if (unformat (i, "forward"))
5512         flags |= L2_FWD;
5513       else if (unformat (i, "flood"))
5514         flags |= L2_FLOOD;
5515       else if (unformat (i, "uu-flood"))
5516         flags |= L2_UU_FLOOD;
5517       else if (unformat (i, "arp-term"))
5518         flags |= L2_ARP_TERM;
5519       else if (unformat (i, "off"))
5520         is_set = 0;
5521       else if (unformat (i, "disable"))
5522         is_set = 0;
5523       else
5524         break;
5525     }
5526
5527   if (bd_id_set == 0)
5528     {
5529       errmsg ("missing bridge domain\n");
5530       return -99;
5531     }
5532
5533   M (BRIDGE_FLAGS, bridge_flags);
5534
5535   mp->bd_id = ntohl (bd_id);
5536   mp->feature_bitmap = ntohl (flags);
5537   mp->is_set = is_set;
5538
5539   S;
5540   W;
5541   /* NOTREACHED */
5542   return 0;
5543 }
5544
5545 static int
5546 api_bd_ip_mac_add_del (vat_main_t * vam)
5547 {
5548   unformat_input_t *i = vam->input;
5549   vl_api_bd_ip_mac_add_del_t *mp;
5550   f64 timeout;
5551   u32 bd_id;
5552   u8 is_ipv6 = 0;
5553   u8 is_add = 1;
5554   u8 bd_id_set = 0;
5555   u8 ip_set = 0;
5556   u8 mac_set = 0;
5557   ip4_address_t v4addr;
5558   ip6_address_t v6addr;
5559   u8 macaddr[6];
5560
5561
5562   /* Parse args required to build the message */
5563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5564     {
5565       if (unformat (i, "bd_id %d", &bd_id))
5566         {
5567           bd_id_set++;
5568         }
5569       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5570         {
5571           ip_set++;
5572         }
5573       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5574         {
5575           ip_set++;
5576           is_ipv6++;
5577         }
5578       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5579         {
5580           mac_set++;
5581         }
5582       else if (unformat (i, "del"))
5583         is_add = 0;
5584       else
5585         break;
5586     }
5587
5588   if (bd_id_set == 0)
5589     {
5590       errmsg ("missing bridge domain\n");
5591       return -99;
5592     }
5593   else if (ip_set == 0)
5594     {
5595       errmsg ("missing IP address\n");
5596       return -99;
5597     }
5598   else if (mac_set == 0)
5599     {
5600       errmsg ("missing MAC address\n");
5601       return -99;
5602     }
5603
5604   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5605
5606   mp->bd_id = ntohl (bd_id);
5607   mp->is_ipv6 = is_ipv6;
5608   mp->is_add = is_add;
5609   if (is_ipv6)
5610     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5611   else
5612     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5613   clib_memcpy (mp->mac_address, macaddr, 6);
5614   S;
5615   W;
5616   /* NOTREACHED */
5617   return 0;
5618 }
5619
5620 static int
5621 api_tap_connect (vat_main_t * vam)
5622 {
5623   unformat_input_t *i = vam->input;
5624   vl_api_tap_connect_t *mp;
5625   f64 timeout;
5626   u8 mac_address[6];
5627   u8 random_mac = 1;
5628   u8 name_set = 0;
5629   u8 *tap_name;
5630   u8 *tag = 0;
5631
5632   memset (mac_address, 0, sizeof (mac_address));
5633
5634   /* Parse args required to build the message */
5635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5636     {
5637       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5638         {
5639           random_mac = 0;
5640         }
5641       else if (unformat (i, "random-mac"))
5642         random_mac = 1;
5643       else if (unformat (i, "tapname %s", &tap_name))
5644         name_set = 1;
5645       else if (unformat (i, "tag %s", &tag))
5646         ;
5647       else
5648         break;
5649     }
5650
5651   if (name_set == 0)
5652     {
5653       errmsg ("missing tap name\n");
5654       return -99;
5655     }
5656   if (vec_len (tap_name) > 63)
5657     {
5658       errmsg ("tap name too long\n");
5659       return -99;
5660     }
5661   vec_add1 (tap_name, 0);
5662
5663   if (vec_len (tag) > 63)
5664     {
5665       errmsg ("tag too long\n");
5666       return -99;
5667     }
5668
5669   /* Construct the API message */
5670   M (TAP_CONNECT, tap_connect);
5671
5672   mp->use_random_mac = random_mac;
5673   clib_memcpy (mp->mac_address, mac_address, 6);
5674   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5675   if (tag)
5676     clib_memcpy (mp->tag, tag, vec_len (tag));
5677
5678   vec_free (tap_name);
5679   vec_free (tag);
5680
5681   /* send it... */
5682   S;
5683
5684   /* Wait for a reply... */
5685   W;
5686 }
5687
5688 static int
5689 api_tap_modify (vat_main_t * vam)
5690 {
5691   unformat_input_t *i = vam->input;
5692   vl_api_tap_modify_t *mp;
5693   f64 timeout;
5694   u8 mac_address[6];
5695   u8 random_mac = 1;
5696   u8 name_set = 0;
5697   u8 *tap_name;
5698   u32 sw_if_index = ~0;
5699   u8 sw_if_index_set = 0;
5700
5701   memset (mac_address, 0, sizeof (mac_address));
5702
5703   /* Parse args required to build the message */
5704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5705     {
5706       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5707         sw_if_index_set = 1;
5708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5709         sw_if_index_set = 1;
5710       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5711         {
5712           random_mac = 0;
5713         }
5714       else if (unformat (i, "random-mac"))
5715         random_mac = 1;
5716       else if (unformat (i, "tapname %s", &tap_name))
5717         name_set = 1;
5718       else
5719         break;
5720     }
5721
5722   if (sw_if_index_set == 0)
5723     {
5724       errmsg ("missing vpp interface name");
5725       return -99;
5726     }
5727   if (name_set == 0)
5728     {
5729       errmsg ("missing tap name\n");
5730       return -99;
5731     }
5732   if (vec_len (tap_name) > 63)
5733     {
5734       errmsg ("tap name too long\n");
5735     }
5736   vec_add1 (tap_name, 0);
5737
5738   /* Construct the API message */
5739   M (TAP_MODIFY, tap_modify);
5740
5741   mp->use_random_mac = random_mac;
5742   mp->sw_if_index = ntohl (sw_if_index);
5743   clib_memcpy (mp->mac_address, mac_address, 6);
5744   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5745   vec_free (tap_name);
5746
5747   /* send it... */
5748   S;
5749
5750   /* Wait for a reply... */
5751   W;
5752 }
5753
5754 static int
5755 api_tap_delete (vat_main_t * vam)
5756 {
5757   unformat_input_t *i = vam->input;
5758   vl_api_tap_delete_t *mp;
5759   f64 timeout;
5760   u32 sw_if_index = ~0;
5761   u8 sw_if_index_set = 0;
5762
5763   /* Parse args required to build the message */
5764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765     {
5766       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5767         sw_if_index_set = 1;
5768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5769         sw_if_index_set = 1;
5770       else
5771         break;
5772     }
5773
5774   if (sw_if_index_set == 0)
5775     {
5776       errmsg ("missing vpp interface name");
5777       return -99;
5778     }
5779
5780   /* Construct the API message */
5781   M (TAP_DELETE, tap_delete);
5782
5783   mp->sw_if_index = ntohl (sw_if_index);
5784
5785   /* send it... */
5786   S;
5787
5788   /* Wait for a reply... */
5789   W;
5790 }
5791
5792 static int
5793 api_ip_add_del_route (vat_main_t * vam)
5794 {
5795   unformat_input_t *i = vam->input;
5796   vl_api_ip_add_del_route_t *mp;
5797   f64 timeout;
5798   u32 sw_if_index = ~0, vrf_id = 0;
5799   u8 is_ipv6 = 0;
5800   u8 is_local = 0, is_drop = 0;
5801   u8 is_unreach = 0, is_prohibit = 0;
5802   u8 create_vrf_if_needed = 0;
5803   u8 is_add = 1;
5804   u32 next_hop_weight = 1;
5805   u8 not_last = 0;
5806   u8 is_multipath = 0;
5807   u8 address_set = 0;
5808   u8 address_length_set = 0;
5809   u32 next_hop_table_id = 0;
5810   u32 resolve_attempts = 0;
5811   u32 dst_address_length = 0;
5812   u8 next_hop_set = 0;
5813   ip4_address_t v4_dst_address, v4_next_hop_address;
5814   ip6_address_t v6_dst_address, v6_next_hop_address;
5815   int count = 1;
5816   int j;
5817   f64 before = 0;
5818   u32 random_add_del = 0;
5819   u32 *random_vector = 0;
5820   uword *random_hash;
5821   u32 random_seed = 0xdeaddabe;
5822   u32 classify_table_index = ~0;
5823   u8 is_classify = 0;
5824   u8 resolve_host = 0, resolve_attached = 0;
5825   mpls_label_t *next_hop_out_label_stack = NULL;
5826   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5827   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
5828
5829   /* Parse args required to build the message */
5830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5831     {
5832       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5833         ;
5834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5835         ;
5836       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5837         {
5838           address_set = 1;
5839           is_ipv6 = 0;
5840         }
5841       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5842         {
5843           address_set = 1;
5844           is_ipv6 = 1;
5845         }
5846       else if (unformat (i, "/%d", &dst_address_length))
5847         {
5848           address_length_set = 1;
5849         }
5850
5851       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5852                                          &v4_next_hop_address))
5853         {
5854           next_hop_set = 1;
5855         }
5856       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5857                                          &v6_next_hop_address))
5858         {
5859           next_hop_set = 1;
5860         }
5861       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5862         ;
5863       else if (unformat (i, "weight %d", &next_hop_weight))
5864         ;
5865       else if (unformat (i, "drop"))
5866         {
5867           is_drop = 1;
5868         }
5869       else if (unformat (i, "null-send-unreach"))
5870         {
5871           is_unreach = 1;
5872         }
5873       else if (unformat (i, "null-send-prohibit"))
5874         {
5875           is_prohibit = 1;
5876         }
5877       else if (unformat (i, "local"))
5878         {
5879           is_local = 1;
5880         }
5881       else if (unformat (i, "classify %d", &classify_table_index))
5882         {
5883           is_classify = 1;
5884         }
5885       else if (unformat (i, "del"))
5886         is_add = 0;
5887       else if (unformat (i, "add"))
5888         is_add = 1;
5889       else if (unformat (i, "not-last"))
5890         not_last = 1;
5891       else if (unformat (i, "resolve-via-host"))
5892         resolve_host = 1;
5893       else if (unformat (i, "resolve-via-attached"))
5894         resolve_attached = 1;
5895       else if (unformat (i, "multipath"))
5896         is_multipath = 1;
5897       else if (unformat (i, "vrf %d", &vrf_id))
5898         ;
5899       else if (unformat (i, "create-vrf"))
5900         create_vrf_if_needed = 1;
5901       else if (unformat (i, "count %d", &count))
5902         ;
5903       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5904         ;
5905       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5906         ;
5907       else if (unformat (i, "out-label %d", &next_hop_out_label))
5908         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
5909       else if (unformat (i, "via-label %d", &next_hop_via_label))
5910         ;
5911       else if (unformat (i, "random"))
5912         random_add_del = 1;
5913       else if (unformat (i, "seed %d", &random_seed))
5914         ;
5915       else
5916         {
5917           clib_warning ("parse error '%U'", format_unformat_error, i);
5918           return -99;
5919         }
5920     }
5921
5922   if (!next_hop_set && !is_drop && !is_local &&
5923       !is_classify && !is_unreach && !is_prohibit &&
5924       MPLS_LABEL_INVALID == next_hop_via_label)
5925     {
5926       errmsg
5927         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5928       return -99;
5929     }
5930
5931   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
5932     {
5933       errmsg ("next hop and next-hop via label set\n");
5934       return -99;
5935     }
5936   if (address_set == 0)
5937     {
5938       errmsg ("missing addresses\n");
5939       return -99;
5940     }
5941
5942   if (address_length_set == 0)
5943     {
5944       errmsg ("missing address length\n");
5945       return -99;
5946     }
5947
5948   /* Generate a pile of unique, random routes */
5949   if (random_add_del)
5950     {
5951       u32 this_random_address;
5952       random_hash = hash_create (count, sizeof (uword));
5953
5954       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5955       for (j = 0; j <= count; j++)
5956         {
5957           do
5958             {
5959               this_random_address = random_u32 (&random_seed);
5960               this_random_address =
5961                 clib_host_to_net_u32 (this_random_address);
5962             }
5963           while (hash_get (random_hash, this_random_address));
5964           vec_add1 (random_vector, this_random_address);
5965           hash_set (random_hash, this_random_address, 1);
5966         }
5967       hash_free (random_hash);
5968       v4_dst_address.as_u32 = random_vector[0];
5969     }
5970
5971   if (count > 1)
5972     {
5973       /* Turn on async mode */
5974       vam->async_mode = 1;
5975       vam->async_errors = 0;
5976       before = vat_time_now (vam);
5977     }
5978
5979   for (j = 0; j < count; j++)
5980     {
5981       /* Construct the API message */
5982       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
5983           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
5984
5985       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5986       mp->table_id = ntohl (vrf_id);
5987       mp->create_vrf_if_needed = create_vrf_if_needed;
5988
5989       mp->is_add = is_add;
5990       mp->is_drop = is_drop;
5991       mp->is_unreach = is_unreach;
5992       mp->is_prohibit = is_prohibit;
5993       mp->is_ipv6 = is_ipv6;
5994       mp->is_local = is_local;
5995       mp->is_classify = is_classify;
5996       mp->is_multipath = is_multipath;
5997       mp->is_resolve_host = resolve_host;
5998       mp->is_resolve_attached = resolve_attached;
5999       mp->not_last = not_last;
6000       mp->next_hop_weight = next_hop_weight;
6001       mp->dst_address_length = dst_address_length;
6002       mp->next_hop_table_id = ntohl (next_hop_table_id);
6003       mp->classify_table_index = ntohl (classify_table_index);
6004       mp->next_hop_via_label = ntohl (next_hop_via_label);
6005       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6006       if (0 != mp->next_hop_n_out_labels)
6007         {
6008           memcpy (mp->next_hop_out_label_stack,
6009                   next_hop_out_label_stack,
6010                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6011           vec_free (next_hop_out_label_stack);
6012         }
6013
6014       if (is_ipv6)
6015         {
6016           clib_memcpy (mp->dst_address, &v6_dst_address,
6017                        sizeof (v6_dst_address));
6018           if (next_hop_set)
6019             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6020                          sizeof (v6_next_hop_address));
6021           increment_v6_address (&v6_dst_address);
6022         }
6023       else
6024         {
6025           clib_memcpy (mp->dst_address, &v4_dst_address,
6026                        sizeof (v4_dst_address));
6027           if (next_hop_set)
6028             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6029                          sizeof (v4_next_hop_address));
6030           if (random_add_del)
6031             v4_dst_address.as_u32 = random_vector[j + 1];
6032           else
6033             increment_v4_address (&v4_dst_address);
6034         }
6035       /* send it... */
6036       S;
6037       /* If we receive SIGTERM, stop now... */
6038       if (vam->do_exit)
6039         break;
6040     }
6041
6042   /* When testing multiple add/del ops, use a control-ping to sync */
6043   if (count > 1)
6044     {
6045       vl_api_control_ping_t *mp;
6046       f64 after;
6047
6048       /* Shut off async mode */
6049       vam->async_mode = 0;
6050
6051       M (CONTROL_PING, control_ping);
6052       S;
6053
6054       timeout = vat_time_now (vam) + 1.0;
6055       while (vat_time_now (vam) < timeout)
6056         if (vam->result_ready == 1)
6057           goto out;
6058       vam->retval = -99;
6059
6060     out:
6061       if (vam->retval == -99)
6062         errmsg ("timeout\n");
6063
6064       if (vam->async_errors > 0)
6065         {
6066           errmsg ("%d asynchronous errors\n", vam->async_errors);
6067           vam->retval = -98;
6068         }
6069       vam->async_errors = 0;
6070       after = vat_time_now (vam);
6071
6072       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6073       if (j > 0)
6074         count = j;
6075
6076       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6077                count, after - before, count / (after - before));
6078     }
6079   else
6080     {
6081       /* Wait for a reply... */
6082       W;
6083     }
6084
6085   /* Return the good/bad news */
6086   return (vam->retval);
6087 }
6088
6089 static int
6090 api_mpls_route_add_del (vat_main_t * vam)
6091 {
6092   unformat_input_t *i = vam->input;
6093   vl_api_mpls_route_add_del_t *mp;
6094   f64 timeout;
6095   u32 sw_if_index = ~0, table_id = 0;
6096   u8 create_table_if_needed = 0;
6097   u8 is_add = 1;
6098   u32 next_hop_weight = 1;
6099   u8 is_multipath = 0;
6100   u32 next_hop_table_id = 0;
6101   u8 next_hop_set = 0;
6102   ip4_address_t v4_next_hop_address = {
6103     .as_u32 = 0,
6104   };
6105   ip6_address_t v6_next_hop_address = { {0} };
6106   int count = 1;
6107   int j;
6108   f64 before = 0;
6109   u32 classify_table_index = ~0;
6110   u8 is_classify = 0;
6111   u8 resolve_host = 0, resolve_attached = 0;
6112   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6113   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6114   mpls_label_t *next_hop_out_label_stack = NULL;
6115   mpls_label_t local_label = MPLS_LABEL_INVALID;
6116   u8 is_eos = 0;
6117   u8 next_hop_proto_is_ip4 = 1;
6118
6119   /* Parse args required to build the message */
6120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6121     {
6122       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6123         ;
6124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6125         ;
6126       else if (unformat (i, "%d", &local_label))
6127         ;
6128       else if (unformat (i, "eos"))
6129         is_eos = 1;
6130       else if (unformat (i, "non-eos"))
6131         is_eos = 0;
6132       else if (unformat (i, "via %U", unformat_ip4_address,
6133                          &v4_next_hop_address))
6134         {
6135           next_hop_set = 1;
6136           next_hop_proto_is_ip4 = 1;
6137         }
6138       else if (unformat (i, "via %U", unformat_ip6_address,
6139                          &v6_next_hop_address))
6140         {
6141           next_hop_set = 1;
6142           next_hop_proto_is_ip4 = 0;
6143         }
6144       else if (unformat (i, "weight %d", &next_hop_weight))
6145         ;
6146       else if (unformat (i, "create-table"))
6147         create_table_if_needed = 1;
6148       else if (unformat (i, "classify %d", &classify_table_index))
6149         {
6150           is_classify = 1;
6151         }
6152       else if (unformat (i, "del"))
6153         is_add = 0;
6154       else if (unformat (i, "add"))
6155         is_add = 1;
6156       else if (unformat (i, "resolve-via-host"))
6157         resolve_host = 1;
6158       else if (unformat (i, "resolve-via-attached"))
6159         resolve_attached = 1;
6160       else if (unformat (i, "multipath"))
6161         is_multipath = 1;
6162       else if (unformat (i, "count %d", &count))
6163         ;
6164       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6165         {
6166           next_hop_set = 1;
6167           next_hop_proto_is_ip4 = 1;
6168         }
6169       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6170         {
6171           next_hop_set = 1;
6172           next_hop_proto_is_ip4 = 0;
6173         }
6174       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6175         ;
6176       else if (unformat (i, "via-label %d", &next_hop_via_label))
6177         ;
6178       else if (unformat (i, "out-label %d", &next_hop_out_label))
6179         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6180       else
6181         {
6182           clib_warning ("parse error '%U'", format_unformat_error, i);
6183           return -99;
6184         }
6185     }
6186
6187   if (!next_hop_set && !is_classify)
6188     {
6189       errmsg ("next hop / classify not set\n");
6190       return -99;
6191     }
6192
6193   if (MPLS_LABEL_INVALID == local_label)
6194     {
6195       errmsg ("missing label\n");
6196       return -99;
6197     }
6198
6199   if (count > 1)
6200     {
6201       /* Turn on async mode */
6202       vam->async_mode = 1;
6203       vam->async_errors = 0;
6204       before = vat_time_now (vam);
6205     }
6206
6207   for (j = 0; j < count; j++)
6208     {
6209       /* Construct the API message */
6210       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6211           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6212
6213       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6214       mp->mr_table_id = ntohl (table_id);
6215       mp->mr_create_table_if_needed = create_table_if_needed;
6216
6217       mp->mr_is_add = is_add;
6218       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6219       mp->mr_is_classify = is_classify;
6220       mp->mr_is_multipath = is_multipath;
6221       mp->mr_is_resolve_host = resolve_host;
6222       mp->mr_is_resolve_attached = resolve_attached;
6223       mp->mr_next_hop_weight = next_hop_weight;
6224       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6225       mp->mr_classify_table_index = ntohl (classify_table_index);
6226       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6227       mp->mr_label = ntohl (local_label);
6228       mp->mr_eos = is_eos;
6229
6230       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6231       if (0 != mp->mr_next_hop_n_out_labels)
6232         {
6233           memcpy (mp->mr_next_hop_out_label_stack,
6234                   next_hop_out_label_stack,
6235                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6236           vec_free (next_hop_out_label_stack);
6237         }
6238
6239       if (next_hop_set)
6240         {
6241           if (next_hop_proto_is_ip4)
6242             {
6243               clib_memcpy (mp->mr_next_hop,
6244                            &v4_next_hop_address,
6245                            sizeof (v4_next_hop_address));
6246             }
6247           else
6248             {
6249               clib_memcpy (mp->mr_next_hop,
6250                            &v6_next_hop_address,
6251                            sizeof (v6_next_hop_address));
6252             }
6253         }
6254       local_label++;
6255
6256       /* send it... */
6257       S;
6258       /* If we receive SIGTERM, stop now... */
6259       if (vam->do_exit)
6260         break;
6261     }
6262
6263   /* When testing multiple add/del ops, use a control-ping to sync */
6264   if (count > 1)
6265     {
6266       vl_api_control_ping_t *mp;
6267       f64 after;
6268
6269       /* Shut off async mode */
6270       vam->async_mode = 0;
6271
6272       M (CONTROL_PING, control_ping);
6273       S;
6274
6275       timeout = vat_time_now (vam) + 1.0;
6276       while (vat_time_now (vam) < timeout)
6277         if (vam->result_ready == 1)
6278           goto out;
6279       vam->retval = -99;
6280
6281     out:
6282       if (vam->retval == -99)
6283         errmsg ("timeout\n");
6284
6285       if (vam->async_errors > 0)
6286         {
6287           errmsg ("%d asynchronous errors\n", vam->async_errors);
6288           vam->retval = -98;
6289         }
6290       vam->async_errors = 0;
6291       after = vat_time_now (vam);
6292
6293       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6294       if (j > 0)
6295         count = j;
6296
6297       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6298                count, after - before, count / (after - before));
6299     }
6300   else
6301     {
6302       /* Wait for a reply... */
6303       W;
6304     }
6305
6306   /* Return the good/bad news */
6307   return (vam->retval);
6308 }
6309
6310 static int
6311 api_mpls_ip_bind_unbind (vat_main_t * vam)
6312 {
6313   unformat_input_t *i = vam->input;
6314   vl_api_mpls_ip_bind_unbind_t *mp;
6315   f64 timeout;
6316   u32 ip_table_id = 0;
6317   u8 create_table_if_needed = 0;
6318   u8 is_bind = 1;
6319   u8 is_ip4 = 1;
6320   ip4_address_t v4_address;
6321   ip6_address_t v6_address;
6322   u32 address_length;
6323   u8 address_set = 0;
6324   mpls_label_t local_label = MPLS_LABEL_INVALID;
6325
6326   /* Parse args required to build the message */
6327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6328     {
6329       if (unformat (i, "%U/%d", unformat_ip4_address,
6330                     &v4_address, &address_length))
6331         {
6332           is_ip4 = 1;
6333           address_set = 1;
6334         }
6335       else if (unformat (i, "%U/%d", unformat_ip6_address,
6336                          &v6_address, &address_length))
6337         {
6338           is_ip4 = 0;
6339           address_set = 1;
6340         }
6341       else if (unformat (i, "%d", &local_label))
6342         ;
6343       else if (unformat (i, "create-table"))
6344         create_table_if_needed = 1;
6345       else if (unformat (i, "table-id %d", &ip_table_id))
6346         ;
6347       else if (unformat (i, "unbind"))
6348         is_bind = 0;
6349       else if (unformat (i, "bind"))
6350         is_bind = 1;
6351       else
6352         {
6353           clib_warning ("parse error '%U'", format_unformat_error, i);
6354           return -99;
6355         }
6356     }
6357
6358   if (!address_set)
6359     {
6360       errmsg ("IP addres not set\n");
6361       return -99;
6362     }
6363
6364   if (MPLS_LABEL_INVALID == local_label)
6365     {
6366       errmsg ("missing label\n");
6367       return -99;
6368     }
6369
6370   /* Construct the API message */
6371   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6372
6373   mp->mb_create_table_if_needed = create_table_if_needed;
6374   mp->mb_is_bind = is_bind;
6375   mp->mb_is_ip4 = is_ip4;
6376   mp->mb_ip_table_id = ntohl (ip_table_id);
6377   mp->mb_mpls_table_id = 0;
6378   mp->mb_label = ntohl (local_label);
6379   mp->mb_address_length = address_length;
6380
6381   if (is_ip4)
6382     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6383   else
6384     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6385
6386   /* send it... */
6387   S;
6388
6389   /* Wait for a reply... */
6390   W;
6391 }
6392
6393 static int
6394 api_proxy_arp_add_del (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_proxy_arp_add_del_t *mp;
6398   f64 timeout;
6399   u32 vrf_id = 0;
6400   u8 is_add = 1;
6401   ip4_address_t lo, hi;
6402   u8 range_set = 0;
6403
6404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6405     {
6406       if (unformat (i, "vrf %d", &vrf_id))
6407         ;
6408       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6409                          unformat_ip4_address, &hi))
6410         range_set = 1;
6411       else if (unformat (i, "del"))
6412         is_add = 0;
6413       else
6414         {
6415           clib_warning ("parse error '%U'", format_unformat_error, i);
6416           return -99;
6417         }
6418     }
6419
6420   if (range_set == 0)
6421     {
6422       errmsg ("address range not set\n");
6423       return -99;
6424     }
6425
6426   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6427
6428   mp->vrf_id = ntohl (vrf_id);
6429   mp->is_add = is_add;
6430   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6431   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6432
6433   S;
6434   W;
6435   /* NOTREACHED */
6436   return 0;
6437 }
6438
6439 static int
6440 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6441 {
6442   unformat_input_t *i = vam->input;
6443   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6444   f64 timeout;
6445   u32 sw_if_index;
6446   u8 enable = 1;
6447   u8 sw_if_index_set = 0;
6448
6449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450     {
6451       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6452         sw_if_index_set = 1;
6453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6454         sw_if_index_set = 1;
6455       else if (unformat (i, "enable"))
6456         enable = 1;
6457       else if (unformat (i, "disable"))
6458         enable = 0;
6459       else
6460         {
6461           clib_warning ("parse error '%U'", format_unformat_error, i);
6462           return -99;
6463         }
6464     }
6465
6466   if (sw_if_index_set == 0)
6467     {
6468       errmsg ("missing interface name or sw_if_index\n");
6469       return -99;
6470     }
6471
6472   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6473
6474   mp->sw_if_index = ntohl (sw_if_index);
6475   mp->enable_disable = enable;
6476
6477   S;
6478   W;
6479   /* NOTREACHED */
6480   return 0;
6481 }
6482
6483 static int
6484 api_mpls_tunnel_add_del (vat_main_t * vam)
6485 {
6486   unformat_input_t *i = vam->input;
6487   vl_api_mpls_tunnel_add_del_t *mp;
6488   f64 timeout;
6489
6490   u8 is_add = 1;
6491   u8 l2_only = 0;
6492   u32 sw_if_index = ~0;
6493   u32 next_hop_sw_if_index = ~0;
6494   u32 next_hop_proto_is_ip4 = 1;
6495
6496   u32 next_hop_table_id = 0;
6497   ip4_address_t v4_next_hop_address = {
6498     .as_u32 = 0,
6499   };
6500   ip6_address_t v6_next_hop_address = { {0} };
6501   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6502
6503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6504     {
6505       if (unformat (i, "add"))
6506         is_add = 1;
6507       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6508         is_add = 0;
6509       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6510         ;
6511       else if (unformat (i, "via %U",
6512                          unformat_ip4_address, &v4_next_hop_address))
6513         {
6514           next_hop_proto_is_ip4 = 1;
6515         }
6516       else if (unformat (i, "via %U",
6517                          unformat_ip6_address, &v6_next_hop_address))
6518         {
6519           next_hop_proto_is_ip4 = 0;
6520         }
6521       else if (unformat (i, "l2-only"))
6522         l2_only = 1;
6523       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6524         ;
6525       else if (unformat (i, "out-label %d", &next_hop_out_label))
6526         vec_add1 (labels, ntohl (next_hop_out_label));
6527       else
6528         {
6529           clib_warning ("parse error '%U'", format_unformat_error, i);
6530           return -99;
6531         }
6532     }
6533
6534   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6535       sizeof (mpls_label_t) * vec_len (labels));
6536
6537   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6538   mp->mt_sw_if_index = ntohl (sw_if_index);
6539   mp->mt_is_add = is_add;
6540   mp->mt_l2_only = l2_only;
6541   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6542   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6543
6544   mp->mt_next_hop_n_out_labels = vec_len (labels);
6545
6546   if (0 != mp->mt_next_hop_n_out_labels)
6547     {
6548       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6549                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6550       vec_free (labels);
6551     }
6552
6553   if (next_hop_proto_is_ip4)
6554     {
6555       clib_memcpy (mp->mt_next_hop,
6556                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6557     }
6558   else
6559     {
6560       clib_memcpy (mp->mt_next_hop,
6561                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6562     }
6563
6564   S;
6565   W;
6566   /* NOTREACHED */
6567   return 0;
6568 }
6569
6570 static int
6571 api_sw_interface_set_unnumbered (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_sw_interface_set_unnumbered_t *mp;
6575   f64 timeout;
6576   u32 sw_if_index;
6577   u32 unnum_sw_index = ~0;
6578   u8 is_add = 1;
6579   u8 sw_if_index_set = 0;
6580
6581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6582     {
6583       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6584         sw_if_index_set = 1;
6585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586         sw_if_index_set = 1;
6587       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6588         ;
6589       else if (unformat (i, "del"))
6590         is_add = 0;
6591       else
6592         {
6593           clib_warning ("parse error '%U'", format_unformat_error, i);
6594           return -99;
6595         }
6596     }
6597
6598   if (sw_if_index_set == 0)
6599     {
6600       errmsg ("missing interface name or sw_if_index\n");
6601       return -99;
6602     }
6603
6604   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6605
6606   mp->sw_if_index = ntohl (sw_if_index);
6607   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6608   mp->is_add = is_add;
6609
6610   S;
6611   W;
6612   /* NOTREACHED */
6613   return 0;
6614 }
6615
6616 static int
6617 api_ip_neighbor_add_del (vat_main_t * vam)
6618 {
6619   unformat_input_t *i = vam->input;
6620   vl_api_ip_neighbor_add_del_t *mp;
6621   f64 timeout;
6622   u32 sw_if_index;
6623   u8 sw_if_index_set = 0;
6624   u32 vrf_id = 0;
6625   u8 is_add = 1;
6626   u8 is_static = 0;
6627   u8 mac_address[6];
6628   u8 mac_set = 0;
6629   u8 v4_address_set = 0;
6630   u8 v6_address_set = 0;
6631   ip4_address_t v4address;
6632   ip6_address_t v6address;
6633
6634   memset (mac_address, 0, sizeof (mac_address));
6635
6636   /* Parse args required to build the message */
6637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6638     {
6639       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6640         {
6641           mac_set = 1;
6642         }
6643       else if (unformat (i, "del"))
6644         is_add = 0;
6645       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6646         sw_if_index_set = 1;
6647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6648         sw_if_index_set = 1;
6649       else if (unformat (i, "is_static"))
6650         is_static = 1;
6651       else if (unformat (i, "vrf %d", &vrf_id))
6652         ;
6653       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6654         v4_address_set = 1;
6655       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6656         v6_address_set = 1;
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   if (v4_address_set && v6_address_set)
6670     {
6671       errmsg ("both v4 and v6 addresses set\n");
6672       return -99;
6673     }
6674   if (!v4_address_set && !v6_address_set)
6675     {
6676       errmsg ("no address set\n");
6677       return -99;
6678     }
6679
6680   /* Construct the API message */
6681   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6682
6683   mp->sw_if_index = ntohl (sw_if_index);
6684   mp->is_add = is_add;
6685   mp->vrf_id = ntohl (vrf_id);
6686   mp->is_static = is_static;
6687   if (mac_set)
6688     clib_memcpy (mp->mac_address, mac_address, 6);
6689   if (v6_address_set)
6690     {
6691       mp->is_ipv6 = 1;
6692       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6693     }
6694   else
6695     {
6696       /* mp->is_ipv6 = 0; via memset in M macro above */
6697       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6698     }
6699
6700   /* send it... */
6701   S;
6702
6703   /* Wait for a reply, return good/bad news  */
6704   W;
6705
6706   /* NOTREACHED */
6707   return 0;
6708 }
6709
6710 static int
6711 api_reset_vrf (vat_main_t * vam)
6712 {
6713   unformat_input_t *i = vam->input;
6714   vl_api_reset_vrf_t *mp;
6715   f64 timeout;
6716   u32 vrf_id = 0;
6717   u8 is_ipv6 = 0;
6718   u8 vrf_id_set = 0;
6719
6720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721     {
6722       if (unformat (i, "vrf %d", &vrf_id))
6723         vrf_id_set = 1;
6724       else if (unformat (i, "ipv6"))
6725         is_ipv6 = 1;
6726       else
6727         {
6728           clib_warning ("parse error '%U'", format_unformat_error, i);
6729           return -99;
6730         }
6731     }
6732
6733   if (vrf_id_set == 0)
6734     {
6735       errmsg ("missing vrf id\n");
6736       return -99;
6737     }
6738
6739   M (RESET_VRF, reset_vrf);
6740
6741   mp->vrf_id = ntohl (vrf_id);
6742   mp->is_ipv6 = is_ipv6;
6743
6744   S;
6745   W;
6746   /* NOTREACHED */
6747   return 0;
6748 }
6749
6750 static int
6751 api_create_vlan_subif (vat_main_t * vam)
6752 {
6753   unformat_input_t *i = vam->input;
6754   vl_api_create_vlan_subif_t *mp;
6755   f64 timeout;
6756   u32 sw_if_index;
6757   u8 sw_if_index_set = 0;
6758   u32 vlan_id;
6759   u8 vlan_id_set = 0;
6760
6761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (i, "sw_if_index %d", &sw_if_index))
6764         sw_if_index_set = 1;
6765       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6766         sw_if_index_set = 1;
6767       else if (unformat (i, "vlan %d", &vlan_id))
6768         vlan_id_set = 1;
6769       else
6770         {
6771           clib_warning ("parse error '%U'", format_unformat_error, i);
6772           return -99;
6773         }
6774     }
6775
6776   if (sw_if_index_set == 0)
6777     {
6778       errmsg ("missing interface name or sw_if_index\n");
6779       return -99;
6780     }
6781
6782   if (vlan_id_set == 0)
6783     {
6784       errmsg ("missing vlan_id\n");
6785       return -99;
6786     }
6787   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6788
6789   mp->sw_if_index = ntohl (sw_if_index);
6790   mp->vlan_id = ntohl (vlan_id);
6791
6792   S;
6793   W;
6794   /* NOTREACHED */
6795   return 0;
6796 }
6797
6798 #define foreach_create_subif_bit                \
6799 _(no_tags)                                      \
6800 _(one_tag)                                      \
6801 _(two_tags)                                     \
6802 _(dot1ad)                                       \
6803 _(exact_match)                                  \
6804 _(default_sub)                                  \
6805 _(outer_vlan_id_any)                            \
6806 _(inner_vlan_id_any)
6807
6808 static int
6809 api_create_subif (vat_main_t * vam)
6810 {
6811   unformat_input_t *i = vam->input;
6812   vl_api_create_subif_t *mp;
6813   f64 timeout;
6814   u32 sw_if_index;
6815   u8 sw_if_index_set = 0;
6816   u32 sub_id;
6817   u8 sub_id_set = 0;
6818   u32 no_tags = 0;
6819   u32 one_tag = 0;
6820   u32 two_tags = 0;
6821   u32 dot1ad = 0;
6822   u32 exact_match = 0;
6823   u32 default_sub = 0;
6824   u32 outer_vlan_id_any = 0;
6825   u32 inner_vlan_id_any = 0;
6826   u32 tmp;
6827   u16 outer_vlan_id = 0;
6828   u16 inner_vlan_id = 0;
6829
6830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6831     {
6832       if (unformat (i, "sw_if_index %d", &sw_if_index))
6833         sw_if_index_set = 1;
6834       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6835         sw_if_index_set = 1;
6836       else if (unformat (i, "sub_id %d", &sub_id))
6837         sub_id_set = 1;
6838       else if (unformat (i, "outer_vlan_id %d", &tmp))
6839         outer_vlan_id = tmp;
6840       else if (unformat (i, "inner_vlan_id %d", &tmp))
6841         inner_vlan_id = tmp;
6842
6843 #define _(a) else if (unformat (i, #a)) a = 1 ;
6844       foreach_create_subif_bit
6845 #undef _
6846         else
6847         {
6848           clib_warning ("parse error '%U'", format_unformat_error, i);
6849           return -99;
6850         }
6851     }
6852
6853   if (sw_if_index_set == 0)
6854     {
6855       errmsg ("missing interface name or sw_if_index\n");
6856       return -99;
6857     }
6858
6859   if (sub_id_set == 0)
6860     {
6861       errmsg ("missing sub_id\n");
6862       return -99;
6863     }
6864   M (CREATE_SUBIF, create_subif);
6865
6866   mp->sw_if_index = ntohl (sw_if_index);
6867   mp->sub_id = ntohl (sub_id);
6868
6869 #define _(a) mp->a = a;
6870   foreach_create_subif_bit;
6871 #undef _
6872
6873   mp->outer_vlan_id = ntohs (outer_vlan_id);
6874   mp->inner_vlan_id = ntohs (inner_vlan_id);
6875
6876   S;
6877   W;
6878   /* NOTREACHED */
6879   return 0;
6880 }
6881
6882 static int
6883 api_oam_add_del (vat_main_t * vam)
6884 {
6885   unformat_input_t *i = vam->input;
6886   vl_api_oam_add_del_t *mp;
6887   f64 timeout;
6888   u32 vrf_id = 0;
6889   u8 is_add = 1;
6890   ip4_address_t src, dst;
6891   u8 src_set = 0;
6892   u8 dst_set = 0;
6893
6894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6895     {
6896       if (unformat (i, "vrf %d", &vrf_id))
6897         ;
6898       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6899         src_set = 1;
6900       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6901         dst_set = 1;
6902       else if (unformat (i, "del"))
6903         is_add = 0;
6904       else
6905         {
6906           clib_warning ("parse error '%U'", format_unformat_error, i);
6907           return -99;
6908         }
6909     }
6910
6911   if (src_set == 0)
6912     {
6913       errmsg ("missing src addr\n");
6914       return -99;
6915     }
6916
6917   if (dst_set == 0)
6918     {
6919       errmsg ("missing dst addr\n");
6920       return -99;
6921     }
6922
6923   M (OAM_ADD_DEL, oam_add_del);
6924
6925   mp->vrf_id = ntohl (vrf_id);
6926   mp->is_add = is_add;
6927   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6928   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6929
6930   S;
6931   W;
6932   /* NOTREACHED */
6933   return 0;
6934 }
6935
6936 static int
6937 api_reset_fib (vat_main_t * vam)
6938 {
6939   unformat_input_t *i = vam->input;
6940   vl_api_reset_fib_t *mp;
6941   f64 timeout;
6942   u32 vrf_id = 0;
6943   u8 is_ipv6 = 0;
6944   u8 vrf_id_set = 0;
6945
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "vrf %d", &vrf_id))
6949         vrf_id_set = 1;
6950       else if (unformat (i, "ipv6"))
6951         is_ipv6 = 1;
6952       else
6953         {
6954           clib_warning ("parse error '%U'", format_unformat_error, i);
6955           return -99;
6956         }
6957     }
6958
6959   if (vrf_id_set == 0)
6960     {
6961       errmsg ("missing vrf id\n");
6962       return -99;
6963     }
6964
6965   M (RESET_FIB, reset_fib);
6966
6967   mp->vrf_id = ntohl (vrf_id);
6968   mp->is_ipv6 = is_ipv6;
6969
6970   S;
6971   W;
6972   /* NOTREACHED */
6973   return 0;
6974 }
6975
6976 static int
6977 api_dhcp_proxy_config (vat_main_t * vam)
6978 {
6979   unformat_input_t *i = vam->input;
6980   vl_api_dhcp_proxy_config_t *mp;
6981   f64 timeout;
6982   u32 vrf_id = 0;
6983   u8 is_add = 1;
6984   u8 insert_cid = 1;
6985   u8 v4_address_set = 0;
6986   u8 v6_address_set = 0;
6987   ip4_address_t v4address;
6988   ip6_address_t v6address;
6989   u8 v4_src_address_set = 0;
6990   u8 v6_src_address_set = 0;
6991   ip4_address_t v4srcaddress;
6992   ip6_address_t v6srcaddress;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "del"))
6998         is_add = 0;
6999       else if (unformat (i, "vrf %d", &vrf_id))
7000         ;
7001       else if (unformat (i, "insert-cid %d", &insert_cid))
7002         ;
7003       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7004         v4_address_set = 1;
7005       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7006         v6_address_set = 1;
7007       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7008         v4_src_address_set = 1;
7009       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7010         v6_src_address_set = 1;
7011       else
7012         break;
7013     }
7014
7015   if (v4_address_set && v6_address_set)
7016     {
7017       errmsg ("both v4 and v6 server addresses set\n");
7018       return -99;
7019     }
7020   if (!v4_address_set && !v6_address_set)
7021     {
7022       errmsg ("no server addresses set\n");
7023       return -99;
7024     }
7025
7026   if (v4_src_address_set && v6_src_address_set)
7027     {
7028       errmsg ("both v4 and v6  src addresses set\n");
7029       return -99;
7030     }
7031   if (!v4_src_address_set && !v6_src_address_set)
7032     {
7033       errmsg ("no src addresses set\n");
7034       return -99;
7035     }
7036
7037   if (!(v4_src_address_set && v4_address_set) &&
7038       !(v6_src_address_set && v6_address_set))
7039     {
7040       errmsg ("no matching server and src addresses set\n");
7041       return -99;
7042     }
7043
7044   /* Construct the API message */
7045   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7046
7047   mp->insert_circuit_id = insert_cid;
7048   mp->is_add = is_add;
7049   mp->vrf_id = ntohl (vrf_id);
7050   if (v6_address_set)
7051     {
7052       mp->is_ipv6 = 1;
7053       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7054       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7055     }
7056   else
7057     {
7058       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7059       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7060     }
7061
7062   /* send it... */
7063   S;
7064
7065   /* Wait for a reply, return good/bad news  */
7066   W;
7067   /* NOTREACHED */
7068   return 0;
7069 }
7070
7071 static int
7072 api_dhcp_proxy_config_2 (vat_main_t * vam)
7073 {
7074   unformat_input_t *i = vam->input;
7075   vl_api_dhcp_proxy_config_2_t *mp;
7076   f64 timeout;
7077   u32 rx_vrf_id = 0;
7078   u32 server_vrf_id = 0;
7079   u8 is_add = 1;
7080   u8 insert_cid = 1;
7081   u8 v4_address_set = 0;
7082   u8 v6_address_set = 0;
7083   ip4_address_t v4address;
7084   ip6_address_t v6address;
7085   u8 v4_src_address_set = 0;
7086   u8 v6_src_address_set = 0;
7087   ip4_address_t v4srcaddress;
7088   ip6_address_t v6srcaddress;
7089
7090   /* Parse args required to build the message */
7091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (i, "del"))
7094         is_add = 0;
7095       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7096         ;
7097       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7098         ;
7099       else if (unformat (i, "insert-cid %d", &insert_cid))
7100         ;
7101       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7102         v4_address_set = 1;
7103       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7104         v6_address_set = 1;
7105       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7106         v4_src_address_set = 1;
7107       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7108         v6_src_address_set = 1;
7109       else
7110         break;
7111     }
7112
7113   if (v4_address_set && v6_address_set)
7114     {
7115       errmsg ("both v4 and v6 server addresses set\n");
7116       return -99;
7117     }
7118   if (!v4_address_set && !v6_address_set)
7119     {
7120       errmsg ("no server addresses set\n");
7121       return -99;
7122     }
7123
7124   if (v4_src_address_set && v6_src_address_set)
7125     {
7126       errmsg ("both v4 and v6  src addresses set\n");
7127       return -99;
7128     }
7129   if (!v4_src_address_set && !v6_src_address_set)
7130     {
7131       errmsg ("no src addresses set\n");
7132       return -99;
7133     }
7134
7135   if (!(v4_src_address_set && v4_address_set) &&
7136       !(v6_src_address_set && v6_address_set))
7137     {
7138       errmsg ("no matching server and src addresses set\n");
7139       return -99;
7140     }
7141
7142   /* Construct the API message */
7143   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7144
7145   mp->insert_circuit_id = insert_cid;
7146   mp->is_add = is_add;
7147   mp->rx_vrf_id = ntohl (rx_vrf_id);
7148   mp->server_vrf_id = ntohl (server_vrf_id);
7149   if (v6_address_set)
7150     {
7151       mp->is_ipv6 = 1;
7152       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7153       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7154     }
7155   else
7156     {
7157       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7158       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7159     }
7160
7161   /* send it... */
7162   S;
7163
7164   /* Wait for a reply, return good/bad news  */
7165   W;
7166   /* NOTREACHED */
7167   return 0;
7168 }
7169
7170 static int
7171 api_dhcp_proxy_set_vss (vat_main_t * vam)
7172 {
7173   unformat_input_t *i = vam->input;
7174   vl_api_dhcp_proxy_set_vss_t *mp;
7175   f64 timeout;
7176   u8 is_ipv6 = 0;
7177   u8 is_add = 1;
7178   u32 tbl_id;
7179   u8 tbl_id_set = 0;
7180   u32 oui;
7181   u8 oui_set = 0;
7182   u32 fib_id;
7183   u8 fib_id_set = 0;
7184
7185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186     {
7187       if (unformat (i, "tbl_id %d", &tbl_id))
7188         tbl_id_set = 1;
7189       if (unformat (i, "fib_id %d", &fib_id))
7190         fib_id_set = 1;
7191       if (unformat (i, "oui %d", &oui))
7192         oui_set = 1;
7193       else if (unformat (i, "ipv6"))
7194         is_ipv6 = 1;
7195       else if (unformat (i, "del"))
7196         is_add = 0;
7197       else
7198         {
7199           clib_warning ("parse error '%U'", format_unformat_error, i);
7200           return -99;
7201         }
7202     }
7203
7204   if (tbl_id_set == 0)
7205     {
7206       errmsg ("missing tbl id\n");
7207       return -99;
7208     }
7209
7210   if (fib_id_set == 0)
7211     {
7212       errmsg ("missing fib id\n");
7213       return -99;
7214     }
7215   if (oui_set == 0)
7216     {
7217       errmsg ("missing oui\n");
7218       return -99;
7219     }
7220
7221   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7222   mp->tbl_id = ntohl (tbl_id);
7223   mp->fib_id = ntohl (fib_id);
7224   mp->oui = ntohl (oui);
7225   mp->is_ipv6 = is_ipv6;
7226   mp->is_add = is_add;
7227
7228   S;
7229   W;
7230   /* NOTREACHED */
7231   return 0;
7232 }
7233
7234 static int
7235 api_dhcp_client_config (vat_main_t * vam)
7236 {
7237   unformat_input_t *i = vam->input;
7238   vl_api_dhcp_client_config_t *mp;
7239   f64 timeout;
7240   u32 sw_if_index;
7241   u8 sw_if_index_set = 0;
7242   u8 is_add = 1;
7243   u8 *hostname = 0;
7244   u8 disable_event = 0;
7245
7246   /* Parse args required to build the message */
7247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7248     {
7249       if (unformat (i, "del"))
7250         is_add = 0;
7251       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7252         sw_if_index_set = 1;
7253       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7254         sw_if_index_set = 1;
7255       else if (unformat (i, "hostname %s", &hostname))
7256         ;
7257       else if (unformat (i, "disable_event"))
7258         disable_event = 1;
7259       else
7260         break;
7261     }
7262
7263   if (sw_if_index_set == 0)
7264     {
7265       errmsg ("missing interface name or sw_if_index\n");
7266       return -99;
7267     }
7268
7269   if (vec_len (hostname) > 63)
7270     {
7271       errmsg ("hostname too long\n");
7272     }
7273   vec_add1 (hostname, 0);
7274
7275   /* Construct the API message */
7276   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7277
7278   mp->sw_if_index = ntohl (sw_if_index);
7279   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7280   vec_free (hostname);
7281   mp->is_add = is_add;
7282   mp->want_dhcp_event = disable_event ? 0 : 1;
7283   mp->pid = getpid ();
7284
7285   /* send it... */
7286   S;
7287
7288   /* Wait for a reply, return good/bad news  */
7289   W;
7290   /* NOTREACHED */
7291   return 0;
7292 }
7293
7294 static int
7295 api_set_ip_flow_hash (vat_main_t * vam)
7296 {
7297   unformat_input_t *i = vam->input;
7298   vl_api_set_ip_flow_hash_t *mp;
7299   f64 timeout;
7300   u32 vrf_id = 0;
7301   u8 is_ipv6 = 0;
7302   u8 vrf_id_set = 0;
7303   u8 src = 0;
7304   u8 dst = 0;
7305   u8 sport = 0;
7306   u8 dport = 0;
7307   u8 proto = 0;
7308   u8 reverse = 0;
7309
7310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7311     {
7312       if (unformat (i, "vrf %d", &vrf_id))
7313         vrf_id_set = 1;
7314       else if (unformat (i, "ipv6"))
7315         is_ipv6 = 1;
7316       else if (unformat (i, "src"))
7317         src = 1;
7318       else if (unformat (i, "dst"))
7319         dst = 1;
7320       else if (unformat (i, "sport"))
7321         sport = 1;
7322       else if (unformat (i, "dport"))
7323         dport = 1;
7324       else if (unformat (i, "proto"))
7325         proto = 1;
7326       else if (unformat (i, "reverse"))
7327         reverse = 1;
7328
7329       else
7330         {
7331           clib_warning ("parse error '%U'", format_unformat_error, i);
7332           return -99;
7333         }
7334     }
7335
7336   if (vrf_id_set == 0)
7337     {
7338       errmsg ("missing vrf id\n");
7339       return -99;
7340     }
7341
7342   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7343   mp->src = src;
7344   mp->dst = dst;
7345   mp->sport = sport;
7346   mp->dport = dport;
7347   mp->proto = proto;
7348   mp->reverse = reverse;
7349   mp->vrf_id = ntohl (vrf_id);
7350   mp->is_ipv6 = is_ipv6;
7351
7352   S;
7353   W;
7354   /* NOTREACHED */
7355   return 0;
7356 }
7357
7358 static int
7359 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7360 {
7361   unformat_input_t *i = vam->input;
7362   vl_api_sw_interface_ip6_enable_disable_t *mp;
7363   f64 timeout;
7364   u32 sw_if_index;
7365   u8 sw_if_index_set = 0;
7366   u8 enable = 0;
7367
7368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7369     {
7370       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7371         sw_if_index_set = 1;
7372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7373         sw_if_index_set = 1;
7374       else if (unformat (i, "enable"))
7375         enable = 1;
7376       else if (unformat (i, "disable"))
7377         enable = 0;
7378       else
7379         {
7380           clib_warning ("parse error '%U'", format_unformat_error, i);
7381           return -99;
7382         }
7383     }
7384
7385   if (sw_if_index_set == 0)
7386     {
7387       errmsg ("missing interface name or sw_if_index\n");
7388       return -99;
7389     }
7390
7391   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7392
7393   mp->sw_if_index = ntohl (sw_if_index);
7394   mp->enable = enable;
7395
7396   S;
7397   W;
7398   /* NOTREACHED */
7399   return 0;
7400 }
7401
7402 static int
7403 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7404 {
7405   unformat_input_t *i = vam->input;
7406   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7407   f64 timeout;
7408   u32 sw_if_index;
7409   u8 sw_if_index_set = 0;
7410   u32 address_length = 0;
7411   u8 v6_address_set = 0;
7412   ip6_address_t v6address;
7413
7414   /* Parse args required to build the message */
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7418         sw_if_index_set = 1;
7419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7420         sw_if_index_set = 1;
7421       else if (unformat (i, "%U/%d",
7422                          unformat_ip6_address, &v6address, &address_length))
7423         v6_address_set = 1;
7424       else
7425         break;
7426     }
7427
7428   if (sw_if_index_set == 0)
7429     {
7430       errmsg ("missing interface name or sw_if_index\n");
7431       return -99;
7432     }
7433   if (!v6_address_set)
7434     {
7435       errmsg ("no address set\n");
7436       return -99;
7437     }
7438
7439   /* Construct the API message */
7440   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7441      sw_interface_ip6_set_link_local_address);
7442
7443   mp->sw_if_index = ntohl (sw_if_index);
7444   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7445   mp->address_length = address_length;
7446
7447   /* send it... */
7448   S;
7449
7450   /* Wait for a reply, return good/bad news  */
7451   W;
7452
7453   /* NOTREACHED */
7454   return 0;
7455 }
7456
7457
7458 static int
7459 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7460 {
7461   unformat_input_t *i = vam->input;
7462   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7463   f64 timeout;
7464   u32 sw_if_index;
7465   u8 sw_if_index_set = 0;
7466   u32 address_length = 0;
7467   u8 v6_address_set = 0;
7468   ip6_address_t v6address;
7469   u8 use_default = 0;
7470   u8 no_advertise = 0;
7471   u8 off_link = 0;
7472   u8 no_autoconfig = 0;
7473   u8 no_onlink = 0;
7474   u8 is_no = 0;
7475   u32 val_lifetime = 0;
7476   u32 pref_lifetime = 0;
7477
7478   /* Parse args required to build the message */
7479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7480     {
7481       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7482         sw_if_index_set = 1;
7483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7484         sw_if_index_set = 1;
7485       else if (unformat (i, "%U/%d",
7486                          unformat_ip6_address, &v6address, &address_length))
7487         v6_address_set = 1;
7488       else if (unformat (i, "val_life %d", &val_lifetime))
7489         ;
7490       else if (unformat (i, "pref_life %d", &pref_lifetime))
7491         ;
7492       else if (unformat (i, "def"))
7493         use_default = 1;
7494       else if (unformat (i, "noadv"))
7495         no_advertise = 1;
7496       else if (unformat (i, "offl"))
7497         off_link = 1;
7498       else if (unformat (i, "noauto"))
7499         no_autoconfig = 1;
7500       else if (unformat (i, "nolink"))
7501         no_onlink = 1;
7502       else if (unformat (i, "isno"))
7503         is_no = 1;
7504       else
7505         {
7506           clib_warning ("parse error '%U'", format_unformat_error, i);
7507           return -99;
7508         }
7509     }
7510
7511   if (sw_if_index_set == 0)
7512     {
7513       errmsg ("missing interface name or sw_if_index\n");
7514       return -99;
7515     }
7516   if (!v6_address_set)
7517     {
7518       errmsg ("no address set\n");
7519       return -99;
7520     }
7521
7522   /* Construct the API message */
7523   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7524
7525   mp->sw_if_index = ntohl (sw_if_index);
7526   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7527   mp->address_length = address_length;
7528   mp->use_default = use_default;
7529   mp->no_advertise = no_advertise;
7530   mp->off_link = off_link;
7531   mp->no_autoconfig = no_autoconfig;
7532   mp->no_onlink = no_onlink;
7533   mp->is_no = is_no;
7534   mp->val_lifetime = ntohl (val_lifetime);
7535   mp->pref_lifetime = ntohl (pref_lifetime);
7536
7537   /* send it... */
7538   S;
7539
7540   /* Wait for a reply, return good/bad news  */
7541   W;
7542
7543   /* NOTREACHED */
7544   return 0;
7545 }
7546
7547 static int
7548 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7549 {
7550   unformat_input_t *i = vam->input;
7551   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7552   f64 timeout;
7553   u32 sw_if_index;
7554   u8 sw_if_index_set = 0;
7555   u8 suppress = 0;
7556   u8 managed = 0;
7557   u8 other = 0;
7558   u8 ll_option = 0;
7559   u8 send_unicast = 0;
7560   u8 cease = 0;
7561   u8 is_no = 0;
7562   u8 default_router = 0;
7563   u32 max_interval = 0;
7564   u32 min_interval = 0;
7565   u32 lifetime = 0;
7566   u32 initial_count = 0;
7567   u32 initial_interval = 0;
7568
7569
7570   /* Parse args required to build the message */
7571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7572     {
7573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7574         sw_if_index_set = 1;
7575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7576         sw_if_index_set = 1;
7577       else if (unformat (i, "maxint %d", &max_interval))
7578         ;
7579       else if (unformat (i, "minint %d", &min_interval))
7580         ;
7581       else if (unformat (i, "life %d", &lifetime))
7582         ;
7583       else if (unformat (i, "count %d", &initial_count))
7584         ;
7585       else if (unformat (i, "interval %d", &initial_interval))
7586         ;
7587       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7588         suppress = 1;
7589       else if (unformat (i, "managed"))
7590         managed = 1;
7591       else if (unformat (i, "other"))
7592         other = 1;
7593       else if (unformat (i, "ll"))
7594         ll_option = 1;
7595       else if (unformat (i, "send"))
7596         send_unicast = 1;
7597       else if (unformat (i, "cease"))
7598         cease = 1;
7599       else if (unformat (i, "isno"))
7600         is_no = 1;
7601       else if (unformat (i, "def"))
7602         default_router = 1;
7603       else
7604         {
7605           clib_warning ("parse error '%U'", format_unformat_error, i);
7606           return -99;
7607         }
7608     }
7609
7610   if (sw_if_index_set == 0)
7611     {
7612       errmsg ("missing interface name or sw_if_index\n");
7613       return -99;
7614     }
7615
7616   /* Construct the API message */
7617   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7618
7619   mp->sw_if_index = ntohl (sw_if_index);
7620   mp->max_interval = ntohl (max_interval);
7621   mp->min_interval = ntohl (min_interval);
7622   mp->lifetime = ntohl (lifetime);
7623   mp->initial_count = ntohl (initial_count);
7624   mp->initial_interval = ntohl (initial_interval);
7625   mp->suppress = suppress;
7626   mp->managed = managed;
7627   mp->other = other;
7628   mp->ll_option = ll_option;
7629   mp->send_unicast = send_unicast;
7630   mp->cease = cease;
7631   mp->is_no = is_no;
7632   mp->default_router = default_router;
7633
7634   /* send it... */
7635   S;
7636
7637   /* Wait for a reply, return good/bad news  */
7638   W;
7639
7640   /* NOTREACHED */
7641   return 0;
7642 }
7643
7644 static int
7645 api_set_arp_neighbor_limit (vat_main_t * vam)
7646 {
7647   unformat_input_t *i = vam->input;
7648   vl_api_set_arp_neighbor_limit_t *mp;
7649   f64 timeout;
7650   u32 arp_nbr_limit;
7651   u8 limit_set = 0;
7652   u8 is_ipv6 = 0;
7653
7654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7655     {
7656       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7657         limit_set = 1;
7658       else if (unformat (i, "ipv6"))
7659         is_ipv6 = 1;
7660       else
7661         {
7662           clib_warning ("parse error '%U'", format_unformat_error, i);
7663           return -99;
7664         }
7665     }
7666
7667   if (limit_set == 0)
7668     {
7669       errmsg ("missing limit value\n");
7670       return -99;
7671     }
7672
7673   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7674
7675   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7676   mp->is_ipv6 = is_ipv6;
7677
7678   S;
7679   W;
7680   /* NOTREACHED */
7681   return 0;
7682 }
7683
7684 static int
7685 api_l2_patch_add_del (vat_main_t * vam)
7686 {
7687   unformat_input_t *i = vam->input;
7688   vl_api_l2_patch_add_del_t *mp;
7689   f64 timeout;
7690   u32 rx_sw_if_index;
7691   u8 rx_sw_if_index_set = 0;
7692   u32 tx_sw_if_index;
7693   u8 tx_sw_if_index_set = 0;
7694   u8 is_add = 1;
7695
7696   /* Parse args required to build the message */
7697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7698     {
7699       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7700         rx_sw_if_index_set = 1;
7701       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7702         tx_sw_if_index_set = 1;
7703       else if (unformat (i, "rx"))
7704         {
7705           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7706             {
7707               if (unformat (i, "%U", unformat_sw_if_index, vam,
7708                             &rx_sw_if_index))
7709                 rx_sw_if_index_set = 1;
7710             }
7711           else
7712             break;
7713         }
7714       else if (unformat (i, "tx"))
7715         {
7716           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717             {
7718               if (unformat (i, "%U", unformat_sw_if_index, vam,
7719                             &tx_sw_if_index))
7720                 tx_sw_if_index_set = 1;
7721             }
7722           else
7723             break;
7724         }
7725       else if (unformat (i, "del"))
7726         is_add = 0;
7727       else
7728         break;
7729     }
7730
7731   if (rx_sw_if_index_set == 0)
7732     {
7733       errmsg ("missing rx interface name or rx_sw_if_index\n");
7734       return -99;
7735     }
7736
7737   if (tx_sw_if_index_set == 0)
7738     {
7739       errmsg ("missing tx interface name or tx_sw_if_index\n");
7740       return -99;
7741     }
7742
7743   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7744
7745   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7746   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7747   mp->is_add = is_add;
7748
7749   S;
7750   W;
7751   /* NOTREACHED */
7752   return 0;
7753 }
7754
7755 static int
7756 api_ioam_enable (vat_main_t * vam)
7757 {
7758   unformat_input_t *input = vam->input;
7759   vl_api_ioam_enable_t *mp;
7760   f64 timeout;
7761   u32 id = 0;
7762   int has_trace_option = 0;
7763   int has_pot_option = 0;
7764   int has_seqno_option = 0;
7765   int has_analyse_option = 0;
7766
7767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7768     {
7769       if (unformat (input, "trace"))
7770         has_trace_option = 1;
7771       else if (unformat (input, "pot"))
7772         has_pot_option = 1;
7773       else if (unformat (input, "seqno"))
7774         has_seqno_option = 1;
7775       else if (unformat (input, "analyse"))
7776         has_analyse_option = 1;
7777       else
7778         break;
7779     }
7780   M (IOAM_ENABLE, ioam_enable);
7781   mp->id = htons (id);
7782   mp->seqno = has_seqno_option;
7783   mp->analyse = has_analyse_option;
7784   mp->pot_enable = has_pot_option;
7785   mp->trace_enable = has_trace_option;
7786
7787   S;
7788   W;
7789
7790   return (0);
7791
7792 }
7793
7794
7795 static int
7796 api_ioam_disable (vat_main_t * vam)
7797 {
7798   vl_api_ioam_disable_t *mp;
7799   f64 timeout;
7800
7801   M (IOAM_DISABLE, ioam_disable);
7802   S;
7803   W;
7804   return 0;
7805 }
7806
7807 static int
7808 api_sr_tunnel_add_del (vat_main_t * vam)
7809 {
7810   unformat_input_t *i = vam->input;
7811   vl_api_sr_tunnel_add_del_t *mp;
7812   f64 timeout;
7813   int is_del = 0;
7814   int pl_index;
7815   ip6_address_t src_address;
7816   int src_address_set = 0;
7817   ip6_address_t dst_address;
7818   u32 dst_mask_width;
7819   int dst_address_set = 0;
7820   u16 flags = 0;
7821   u32 rx_table_id = 0;
7822   u32 tx_table_id = 0;
7823   ip6_address_t *segments = 0;
7824   ip6_address_t *this_seg;
7825   ip6_address_t *tags = 0;
7826   ip6_address_t *this_tag;
7827   ip6_address_t next_address, tag;
7828   u8 *name = 0;
7829   u8 *policy_name = 0;
7830
7831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7832     {
7833       if (unformat (i, "del"))
7834         is_del = 1;
7835       else if (unformat (i, "name %s", &name))
7836         ;
7837       else if (unformat (i, "policy %s", &policy_name))
7838         ;
7839       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7840         ;
7841       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7842         ;
7843       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7844         src_address_set = 1;
7845       else if (unformat (i, "dst %U/%d",
7846                          unformat_ip6_address, &dst_address, &dst_mask_width))
7847         dst_address_set = 1;
7848       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7849         {
7850           vec_add2 (segments, this_seg, 1);
7851           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7852                        sizeof (*this_seg));
7853         }
7854       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7855         {
7856           vec_add2 (tags, this_tag, 1);
7857           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7858         }
7859       else if (unformat (i, "clean"))
7860         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7861       else if (unformat (i, "protected"))
7862         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7863       else if (unformat (i, "InPE %d", &pl_index))
7864         {
7865           if (pl_index <= 0 || pl_index > 4)
7866             {
7867             pl_index_range_error:
7868               errmsg ("pl index %d out of range\n", pl_index);
7869               return -99;
7870             }
7871           flags |=
7872             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7873         }
7874       else if (unformat (i, "EgPE %d", &pl_index))
7875         {
7876           if (pl_index <= 0 || pl_index > 4)
7877             goto pl_index_range_error;
7878           flags |=
7879             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7880         }
7881       else if (unformat (i, "OrgSrc %d", &pl_index))
7882         {
7883           if (pl_index <= 0 || pl_index > 4)
7884             goto pl_index_range_error;
7885           flags |=
7886             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7887         }
7888       else
7889         break;
7890     }
7891
7892   if (!src_address_set)
7893     {
7894       errmsg ("src address required\n");
7895       return -99;
7896     }
7897
7898   if (!dst_address_set)
7899     {
7900       errmsg ("dst address required\n");
7901       return -99;
7902     }
7903
7904   if (!segments)
7905     {
7906       errmsg ("at least one sr segment required\n");
7907       return -99;
7908     }
7909
7910   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7911       vec_len (segments) * sizeof (ip6_address_t)
7912       + vec_len (tags) * sizeof (ip6_address_t));
7913
7914   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7915   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7916   mp->dst_mask_width = dst_mask_width;
7917   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7918   mp->n_segments = vec_len (segments);
7919   mp->n_tags = vec_len (tags);
7920   mp->is_add = is_del == 0;
7921   clib_memcpy (mp->segs_and_tags, segments,
7922                vec_len (segments) * sizeof (ip6_address_t));
7923   clib_memcpy (mp->segs_and_tags +
7924                vec_len (segments) * sizeof (ip6_address_t), tags,
7925                vec_len (tags) * sizeof (ip6_address_t));
7926
7927   mp->outer_vrf_id = ntohl (rx_table_id);
7928   mp->inner_vrf_id = ntohl (tx_table_id);
7929   memcpy (mp->name, name, vec_len (name));
7930   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7931
7932   vec_free (segments);
7933   vec_free (tags);
7934
7935   S;
7936   W;
7937   /* NOTREACHED */
7938 }
7939
7940 static int
7941 api_sr_policy_add_del (vat_main_t * vam)
7942 {
7943   unformat_input_t *input = vam->input;
7944   vl_api_sr_policy_add_del_t *mp;
7945   f64 timeout;
7946   int is_del = 0;
7947   u8 *name = 0;
7948   u8 *tunnel_name = 0;
7949   u8 **tunnel_names = 0;
7950
7951   int name_set = 0;
7952   int tunnel_set = 0;
7953   int j = 0;
7954   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7955   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7956
7957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7958     {
7959       if (unformat (input, "del"))
7960         is_del = 1;
7961       else if (unformat (input, "name %s", &name))
7962         name_set = 1;
7963       else if (unformat (input, "tunnel %s", &tunnel_name))
7964         {
7965           if (tunnel_name)
7966             {
7967               vec_add1 (tunnel_names, tunnel_name);
7968               /* For serializer:
7969                  - length = #bytes to store in serial vector
7970                  - +1 = byte to store that length
7971                */
7972               tunnel_names_length += (vec_len (tunnel_name) + 1);
7973               tunnel_set = 1;
7974               tunnel_name = 0;
7975             }
7976         }
7977       else
7978         break;
7979     }
7980
7981   if (!name_set)
7982     {
7983       errmsg ("policy name required\n");
7984       return -99;
7985     }
7986
7987   if ((!tunnel_set) && (!is_del))
7988     {
7989       errmsg ("tunnel name required\n");
7990       return -99;
7991     }
7992
7993   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7994
7995
7996
7997   mp->is_add = !is_del;
7998
7999   memcpy (mp->name, name, vec_len (name));
8000   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8001   u8 *serial_orig = 0;
8002   vec_validate (serial_orig, tunnel_names_length);
8003   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8004   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8005
8006   for (j = 0; j < vec_len (tunnel_names); j++)
8007     {
8008       tun_name_len = vec_len (tunnel_names[j]);
8009       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8010       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8011       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8012       serial_orig += tun_name_len;      // Advance past the copy
8013     }
8014   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8015
8016   vec_free (tunnel_names);
8017   vec_free (tunnel_name);
8018
8019   S;
8020   W;
8021   /* NOTREACHED */
8022 }
8023
8024 static int
8025 api_sr_multicast_map_add_del (vat_main_t * vam)
8026 {
8027   unformat_input_t *input = vam->input;
8028   vl_api_sr_multicast_map_add_del_t *mp;
8029   f64 timeout;
8030   int is_del = 0;
8031   ip6_address_t multicast_address;
8032   u8 *policy_name = 0;
8033   int multicast_address_set = 0;
8034
8035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8036     {
8037       if (unformat (input, "del"))
8038         is_del = 1;
8039       else
8040         if (unformat
8041             (input, "address %U", unformat_ip6_address, &multicast_address))
8042         multicast_address_set = 1;
8043       else if (unformat (input, "sr-policy %s", &policy_name))
8044         ;
8045       else
8046         break;
8047     }
8048
8049   if (!is_del && !policy_name)
8050     {
8051       errmsg ("sr-policy name required\n");
8052       return -99;
8053     }
8054
8055
8056   if (!multicast_address_set)
8057     {
8058       errmsg ("address required\n");
8059       return -99;
8060     }
8061
8062   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8063
8064   mp->is_add = !is_del;
8065   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8066   clib_memcpy (mp->multicast_address, &multicast_address,
8067                sizeof (mp->multicast_address));
8068
8069
8070   vec_free (policy_name);
8071
8072   S;
8073   W;
8074   /* NOTREACHED */
8075 }
8076
8077
8078 #define foreach_tcp_proto_field                 \
8079 _(src_port)                                     \
8080 _(dst_port)
8081
8082 #define foreach_udp_proto_field                 \
8083 _(src_port)                                     \
8084 _(dst_port)
8085
8086 #define foreach_ip4_proto_field                 \
8087 _(src_address)                                  \
8088 _(dst_address)                                  \
8089 _(tos)                                          \
8090 _(length)                                       \
8091 _(fragment_id)                                  \
8092 _(ttl)                                          \
8093 _(protocol)                                     \
8094 _(checksum)
8095
8096 uword
8097 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8098 {
8099   u8 **maskp = va_arg (*args, u8 **);
8100   u8 *mask = 0;
8101   u8 found_something = 0;
8102   tcp_header_t *tcp;
8103
8104 #define _(a) u8 a=0;
8105   foreach_tcp_proto_field;
8106 #undef _
8107
8108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8109     {
8110       if (0);
8111 #define _(a) else if (unformat (input, #a)) a=1;
8112       foreach_tcp_proto_field
8113 #undef _
8114         else
8115         break;
8116     }
8117
8118 #define _(a) found_something += a;
8119   foreach_tcp_proto_field;
8120 #undef _
8121
8122   if (found_something == 0)
8123     return 0;
8124
8125   vec_validate (mask, sizeof (*tcp) - 1);
8126
8127   tcp = (tcp_header_t *) mask;
8128
8129 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8130   foreach_tcp_proto_field;
8131 #undef _
8132
8133   *maskp = mask;
8134   return 1;
8135 }
8136
8137 uword
8138 unformat_udp_mask (unformat_input_t * input, va_list * args)
8139 {
8140   u8 **maskp = va_arg (*args, u8 **);
8141   u8 *mask = 0;
8142   u8 found_something = 0;
8143   udp_header_t *udp;
8144
8145 #define _(a) u8 a=0;
8146   foreach_udp_proto_field;
8147 #undef _
8148
8149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8150     {
8151       if (0);
8152 #define _(a) else if (unformat (input, #a)) a=1;
8153       foreach_udp_proto_field
8154 #undef _
8155         else
8156         break;
8157     }
8158
8159 #define _(a) found_something += a;
8160   foreach_udp_proto_field;
8161 #undef _
8162
8163   if (found_something == 0)
8164     return 0;
8165
8166   vec_validate (mask, sizeof (*udp) - 1);
8167
8168   udp = (udp_header_t *) mask;
8169
8170 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8171   foreach_udp_proto_field;
8172 #undef _
8173
8174   *maskp = mask;
8175   return 1;
8176 }
8177
8178 typedef struct
8179 {
8180   u16 src_port, dst_port;
8181 } tcpudp_header_t;
8182
8183 uword
8184 unformat_l4_mask (unformat_input_t * input, va_list * args)
8185 {
8186   u8 **maskp = va_arg (*args, u8 **);
8187   u16 src_port = 0, dst_port = 0;
8188   tcpudp_header_t *tcpudp;
8189
8190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8191     {
8192       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8193         return 1;
8194       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8195         return 1;
8196       else if (unformat (input, "src_port"))
8197         src_port = 0xFFFF;
8198       else if (unformat (input, "dst_port"))
8199         dst_port = 0xFFFF;
8200       else
8201         return 0;
8202     }
8203
8204   if (!src_port && !dst_port)
8205     return 0;
8206
8207   u8 *mask = 0;
8208   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8209
8210   tcpudp = (tcpudp_header_t *) mask;
8211   tcpudp->src_port = src_port;
8212   tcpudp->dst_port = dst_port;
8213
8214   *maskp = mask;
8215
8216   return 1;
8217 }
8218
8219 uword
8220 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8221 {
8222   u8 **maskp = va_arg (*args, u8 **);
8223   u8 *mask = 0;
8224   u8 found_something = 0;
8225   ip4_header_t *ip;
8226
8227 #define _(a) u8 a=0;
8228   foreach_ip4_proto_field;
8229 #undef _
8230   u8 version = 0;
8231   u8 hdr_length = 0;
8232
8233
8234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8235     {
8236       if (unformat (input, "version"))
8237         version = 1;
8238       else if (unformat (input, "hdr_length"))
8239         hdr_length = 1;
8240       else if (unformat (input, "src"))
8241         src_address = 1;
8242       else if (unformat (input, "dst"))
8243         dst_address = 1;
8244       else if (unformat (input, "proto"))
8245         protocol = 1;
8246
8247 #define _(a) else if (unformat (input, #a)) a=1;
8248       foreach_ip4_proto_field
8249 #undef _
8250         else
8251         break;
8252     }
8253
8254 #define _(a) found_something += a;
8255   foreach_ip4_proto_field;
8256 #undef _
8257
8258   if (found_something == 0)
8259     return 0;
8260
8261   vec_validate (mask, sizeof (*ip) - 1);
8262
8263   ip = (ip4_header_t *) mask;
8264
8265 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8266   foreach_ip4_proto_field;
8267 #undef _
8268
8269   ip->ip_version_and_header_length = 0;
8270
8271   if (version)
8272     ip->ip_version_and_header_length |= 0xF0;
8273
8274   if (hdr_length)
8275     ip->ip_version_and_header_length |= 0x0F;
8276
8277   *maskp = mask;
8278   return 1;
8279 }
8280
8281 #define foreach_ip6_proto_field                 \
8282 _(src_address)                                  \
8283 _(dst_address)                                  \
8284 _(payload_length)                               \
8285 _(hop_limit)                                    \
8286 _(protocol)
8287
8288 uword
8289 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8290 {
8291   u8 **maskp = va_arg (*args, u8 **);
8292   u8 *mask = 0;
8293   u8 found_something = 0;
8294   ip6_header_t *ip;
8295   u32 ip_version_traffic_class_and_flow_label;
8296
8297 #define _(a) u8 a=0;
8298   foreach_ip6_proto_field;
8299 #undef _
8300   u8 version = 0;
8301   u8 traffic_class = 0;
8302   u8 flow_label = 0;
8303
8304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8305     {
8306       if (unformat (input, "version"))
8307         version = 1;
8308       else if (unformat (input, "traffic-class"))
8309         traffic_class = 1;
8310       else if (unformat (input, "flow-label"))
8311         flow_label = 1;
8312       else if (unformat (input, "src"))
8313         src_address = 1;
8314       else if (unformat (input, "dst"))
8315         dst_address = 1;
8316       else if (unformat (input, "proto"))
8317         protocol = 1;
8318
8319 #define _(a) else if (unformat (input, #a)) a=1;
8320       foreach_ip6_proto_field
8321 #undef _
8322         else
8323         break;
8324     }
8325
8326 #define _(a) found_something += a;
8327   foreach_ip6_proto_field;
8328 #undef _
8329
8330   if (found_something == 0)
8331     return 0;
8332
8333   vec_validate (mask, sizeof (*ip) - 1);
8334
8335   ip = (ip6_header_t *) mask;
8336
8337 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8338   foreach_ip6_proto_field;
8339 #undef _
8340
8341   ip_version_traffic_class_and_flow_label = 0;
8342
8343   if (version)
8344     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8345
8346   if (traffic_class)
8347     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8348
8349   if (flow_label)
8350     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8351
8352   ip->ip_version_traffic_class_and_flow_label =
8353     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8354
8355   *maskp = mask;
8356   return 1;
8357 }
8358
8359 uword
8360 unformat_l3_mask (unformat_input_t * input, va_list * args)
8361 {
8362   u8 **maskp = va_arg (*args, u8 **);
8363
8364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8367         return 1;
8368       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8369         return 1;
8370       else
8371         break;
8372     }
8373   return 0;
8374 }
8375
8376 uword
8377 unformat_l2_mask (unformat_input_t * input, va_list * args)
8378 {
8379   u8 **maskp = va_arg (*args, u8 **);
8380   u8 *mask = 0;
8381   u8 src = 0;
8382   u8 dst = 0;
8383   u8 proto = 0;
8384   u8 tag1 = 0;
8385   u8 tag2 = 0;
8386   u8 ignore_tag1 = 0;
8387   u8 ignore_tag2 = 0;
8388   u8 cos1 = 0;
8389   u8 cos2 = 0;
8390   u8 dot1q = 0;
8391   u8 dot1ad = 0;
8392   int len = 14;
8393
8394   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8395     {
8396       if (unformat (input, "src"))
8397         src = 1;
8398       else if (unformat (input, "dst"))
8399         dst = 1;
8400       else if (unformat (input, "proto"))
8401         proto = 1;
8402       else if (unformat (input, "tag1"))
8403         tag1 = 1;
8404       else if (unformat (input, "tag2"))
8405         tag2 = 1;
8406       else if (unformat (input, "ignore-tag1"))
8407         ignore_tag1 = 1;
8408       else if (unformat (input, "ignore-tag2"))
8409         ignore_tag2 = 1;
8410       else if (unformat (input, "cos1"))
8411         cos1 = 1;
8412       else if (unformat (input, "cos2"))
8413         cos2 = 1;
8414       else if (unformat (input, "dot1q"))
8415         dot1q = 1;
8416       else if (unformat (input, "dot1ad"))
8417         dot1ad = 1;
8418       else
8419         break;
8420     }
8421   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8422        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8423     return 0;
8424
8425   if (tag1 || ignore_tag1 || cos1 || dot1q)
8426     len = 18;
8427   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8428     len = 22;
8429
8430   vec_validate (mask, len - 1);
8431
8432   if (dst)
8433     memset (mask, 0xff, 6);
8434
8435   if (src)
8436     memset (mask + 6, 0xff, 6);
8437
8438   if (tag2 || dot1ad)
8439     {
8440       /* inner vlan tag */
8441       if (tag2)
8442         {
8443           mask[19] = 0xff;
8444           mask[18] = 0x0f;
8445         }
8446       if (cos2)
8447         mask[18] |= 0xe0;
8448       if (proto)
8449         mask[21] = mask[20] = 0xff;
8450       if (tag1)
8451         {
8452           mask[15] = 0xff;
8453           mask[14] = 0x0f;
8454         }
8455       if (cos1)
8456         mask[14] |= 0xe0;
8457       *maskp = mask;
8458       return 1;
8459     }
8460   if (tag1 | dot1q)
8461     {
8462       if (tag1)
8463         {
8464           mask[15] = 0xff;
8465           mask[14] = 0x0f;
8466         }
8467       if (cos1)
8468         mask[14] |= 0xe0;
8469       if (proto)
8470         mask[16] = mask[17] = 0xff;
8471
8472       *maskp = mask;
8473       return 1;
8474     }
8475   if (cos2)
8476     mask[18] |= 0xe0;
8477   if (cos1)
8478     mask[14] |= 0xe0;
8479   if (proto)
8480     mask[12] = mask[13] = 0xff;
8481
8482   *maskp = mask;
8483   return 1;
8484 }
8485
8486 uword
8487 unformat_classify_mask (unformat_input_t * input, va_list * args)
8488 {
8489   u8 **maskp = va_arg (*args, u8 **);
8490   u32 *skipp = va_arg (*args, u32 *);
8491   u32 *matchp = va_arg (*args, u32 *);
8492   u32 match;
8493   u8 *mask = 0;
8494   u8 *l2 = 0;
8495   u8 *l3 = 0;
8496   u8 *l4 = 0;
8497   int i;
8498
8499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8500     {
8501       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8502         ;
8503       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8504         ;
8505       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8506         ;
8507       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8508         ;
8509       else
8510         break;
8511     }
8512
8513   if (l4 && !l3)
8514     {
8515       vec_free (mask);
8516       vec_free (l2);
8517       vec_free (l4);
8518       return 0;
8519     }
8520
8521   if (mask || l2 || l3 || l4)
8522     {
8523       if (l2 || l3 || l4)
8524         {
8525           /* "With a free Ethernet header in every package" */
8526           if (l2 == 0)
8527             vec_validate (l2, 13);
8528           mask = l2;
8529           if (vec_len (l3))
8530             {
8531               vec_append (mask, l3);
8532               vec_free (l3);
8533             }
8534           if (vec_len (l4))
8535             {
8536               vec_append (mask, l4);
8537               vec_free (l4);
8538             }
8539         }
8540
8541       /* Scan forward looking for the first significant mask octet */
8542       for (i = 0; i < vec_len (mask); i++)
8543         if (mask[i])
8544           break;
8545
8546       /* compute (skip, match) params */
8547       *skipp = i / sizeof (u32x4);
8548       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8549
8550       /* Pad mask to an even multiple of the vector size */
8551       while (vec_len (mask) % sizeof (u32x4))
8552         vec_add1 (mask, 0);
8553
8554       match = vec_len (mask) / sizeof (u32x4);
8555
8556       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8557         {
8558           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8559           if (*tmp || *(tmp + 1))
8560             break;
8561           match--;
8562         }
8563       if (match == 0)
8564         clib_warning ("BUG: match 0");
8565
8566       _vec_len (mask) = match * sizeof (u32x4);
8567
8568       *matchp = match;
8569       *maskp = mask;
8570
8571       return 1;
8572     }
8573
8574   return 0;
8575 }
8576
8577 #define foreach_l2_next                         \
8578 _(drop, DROP)                                   \
8579 _(ethernet, ETHERNET_INPUT)                     \
8580 _(ip4, IP4_INPUT)                               \
8581 _(ip6, IP6_INPUT)
8582
8583 uword
8584 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8585 {
8586   u32 *miss_next_indexp = va_arg (*args, u32 *);
8587   u32 next_index = 0;
8588   u32 tmp;
8589
8590 #define _(n,N) \
8591   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8592   foreach_l2_next;
8593 #undef _
8594
8595   if (unformat (input, "%d", &tmp))
8596     {
8597       next_index = tmp;
8598       goto out;
8599     }
8600
8601   return 0;
8602
8603 out:
8604   *miss_next_indexp = next_index;
8605   return 1;
8606 }
8607
8608 #define foreach_ip_next                         \
8609 _(drop, DROP)                                   \
8610 _(local, LOCAL)                                 \
8611 _(rewrite, REWRITE)
8612
8613 uword
8614 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8615 {
8616   u32 *miss_next_indexp = va_arg (*args, u32 *);
8617   u32 next_index = 0;
8618   u32 tmp;
8619
8620 #define _(n,N) \
8621   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8622   foreach_ip_next;
8623 #undef _
8624
8625   if (unformat (input, "%d", &tmp))
8626     {
8627       next_index = tmp;
8628       goto out;
8629     }
8630
8631   return 0;
8632
8633 out:
8634   *miss_next_indexp = next_index;
8635   return 1;
8636 }
8637
8638 #define foreach_acl_next                        \
8639 _(deny, DENY)
8640
8641 uword
8642 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8643 {
8644   u32 *miss_next_indexp = va_arg (*args, u32 *);
8645   u32 next_index = 0;
8646   u32 tmp;
8647
8648 #define _(n,N) \
8649   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8650   foreach_acl_next;
8651 #undef _
8652
8653   if (unformat (input, "permit"))
8654     {
8655       next_index = ~0;
8656       goto out;
8657     }
8658   else if (unformat (input, "%d", &tmp))
8659     {
8660       next_index = tmp;
8661       goto out;
8662     }
8663
8664   return 0;
8665
8666 out:
8667   *miss_next_indexp = next_index;
8668   return 1;
8669 }
8670
8671 uword
8672 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8673 {
8674   u32 *r = va_arg (*args, u32 *);
8675
8676   if (unformat (input, "conform-color"))
8677     *r = POLICE_CONFORM;
8678   else if (unformat (input, "exceed-color"))
8679     *r = POLICE_EXCEED;
8680   else
8681     return 0;
8682
8683   return 1;
8684 }
8685
8686 static int
8687 api_classify_add_del_table (vat_main_t * vam)
8688 {
8689   unformat_input_t *i = vam->input;
8690   vl_api_classify_add_del_table_t *mp;
8691
8692   u32 nbuckets = 2;
8693   u32 skip = ~0;
8694   u32 match = ~0;
8695   int is_add = 1;
8696   u32 table_index = ~0;
8697   u32 next_table_index = ~0;
8698   u32 miss_next_index = ~0;
8699   u32 memory_size = 32 << 20;
8700   u8 *mask = 0;
8701   f64 timeout;
8702   u32 current_data_flag = 0;
8703   int current_data_offset = 0;
8704
8705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8706     {
8707       if (unformat (i, "del"))
8708         is_add = 0;
8709       else if (unformat (i, "buckets %d", &nbuckets))
8710         ;
8711       else if (unformat (i, "memory_size %d", &memory_size))
8712         ;
8713       else if (unformat (i, "skip %d", &skip))
8714         ;
8715       else if (unformat (i, "match %d", &match))
8716         ;
8717       else if (unformat (i, "table %d", &table_index))
8718         ;
8719       else if (unformat (i, "mask %U", unformat_classify_mask,
8720                          &mask, &skip, &match))
8721         ;
8722       else if (unformat (i, "next-table %d", &next_table_index))
8723         ;
8724       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8725                          &miss_next_index))
8726         ;
8727       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8728                          &miss_next_index))
8729         ;
8730       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8731                          &miss_next_index))
8732         ;
8733       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8734         ;
8735       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8736         ;
8737       else
8738         break;
8739     }
8740
8741   if (is_add && mask == 0)
8742     {
8743       errmsg ("Mask required\n");
8744       return -99;
8745     }
8746
8747   if (is_add && skip == ~0)
8748     {
8749       errmsg ("skip count required\n");
8750       return -99;
8751     }
8752
8753   if (is_add && match == ~0)
8754     {
8755       errmsg ("match count required\n");
8756       return -99;
8757     }
8758
8759   if (!is_add && table_index == ~0)
8760     {
8761       errmsg ("table index required for delete\n");
8762       return -99;
8763     }
8764
8765   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8766
8767   mp->is_add = is_add;
8768   mp->table_index = ntohl (table_index);
8769   mp->nbuckets = ntohl (nbuckets);
8770   mp->memory_size = ntohl (memory_size);
8771   mp->skip_n_vectors = ntohl (skip);
8772   mp->match_n_vectors = ntohl (match);
8773   mp->next_table_index = ntohl (next_table_index);
8774   mp->miss_next_index = ntohl (miss_next_index);
8775   mp->current_data_flag = ntohl (current_data_flag);
8776   mp->current_data_offset = ntohl (current_data_offset);
8777   clib_memcpy (mp->mask, mask, vec_len (mask));
8778
8779   vec_free (mask);
8780
8781   S;
8782   W;
8783   /* NOTREACHED */
8784 }
8785
8786 uword
8787 unformat_l4_match (unformat_input_t * input, va_list * args)
8788 {
8789   u8 **matchp = va_arg (*args, u8 **);
8790
8791   u8 *proto_header = 0;
8792   int src_port = 0;
8793   int dst_port = 0;
8794
8795   tcpudp_header_t h;
8796
8797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8798     {
8799       if (unformat (input, "src_port %d", &src_port))
8800         ;
8801       else if (unformat (input, "dst_port %d", &dst_port))
8802         ;
8803       else
8804         return 0;
8805     }
8806
8807   h.src_port = clib_host_to_net_u16 (src_port);
8808   h.dst_port = clib_host_to_net_u16 (dst_port);
8809   vec_validate (proto_header, sizeof (h) - 1);
8810   memcpy (proto_header, &h, sizeof (h));
8811
8812   *matchp = proto_header;
8813
8814   return 1;
8815 }
8816
8817 uword
8818 unformat_ip4_match (unformat_input_t * input, va_list * args)
8819 {
8820   u8 **matchp = va_arg (*args, u8 **);
8821   u8 *match = 0;
8822   ip4_header_t *ip;
8823   int version = 0;
8824   u32 version_val;
8825   int hdr_length = 0;
8826   u32 hdr_length_val;
8827   int src = 0, dst = 0;
8828   ip4_address_t src_val, dst_val;
8829   int proto = 0;
8830   u32 proto_val;
8831   int tos = 0;
8832   u32 tos_val;
8833   int length = 0;
8834   u32 length_val;
8835   int fragment_id = 0;
8836   u32 fragment_id_val;
8837   int ttl = 0;
8838   int ttl_val;
8839   int checksum = 0;
8840   u32 checksum_val;
8841
8842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (input, "version %d", &version_val))
8845         version = 1;
8846       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8847         hdr_length = 1;
8848       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8849         src = 1;
8850       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8851         dst = 1;
8852       else if (unformat (input, "proto %d", &proto_val))
8853         proto = 1;
8854       else if (unformat (input, "tos %d", &tos_val))
8855         tos = 1;
8856       else if (unformat (input, "length %d", &length_val))
8857         length = 1;
8858       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8859         fragment_id = 1;
8860       else if (unformat (input, "ttl %d", &ttl_val))
8861         ttl = 1;
8862       else if (unformat (input, "checksum %d", &checksum_val))
8863         checksum = 1;
8864       else
8865         break;
8866     }
8867
8868   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8869       + ttl + checksum == 0)
8870     return 0;
8871
8872   /*
8873    * Aligned because we use the real comparison functions
8874    */
8875   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8876
8877   ip = (ip4_header_t *) match;
8878
8879   /* These are realistically matched in practice */
8880   if (src)
8881     ip->src_address.as_u32 = src_val.as_u32;
8882
8883   if (dst)
8884     ip->dst_address.as_u32 = dst_val.as_u32;
8885
8886   if (proto)
8887     ip->protocol = proto_val;
8888
8889
8890   /* These are not, but they're included for completeness */
8891   if (version)
8892     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8893
8894   if (hdr_length)
8895     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8896
8897   if (tos)
8898     ip->tos = tos_val;
8899
8900   if (length)
8901     ip->length = clib_host_to_net_u16 (length_val);
8902
8903   if (ttl)
8904     ip->ttl = ttl_val;
8905
8906   if (checksum)
8907     ip->checksum = clib_host_to_net_u16 (checksum_val);
8908
8909   *matchp = match;
8910   return 1;
8911 }
8912
8913 uword
8914 unformat_ip6_match (unformat_input_t * input, va_list * args)
8915 {
8916   u8 **matchp = va_arg (*args, u8 **);
8917   u8 *match = 0;
8918   ip6_header_t *ip;
8919   int version = 0;
8920   u32 version_val;
8921   u8 traffic_class = 0;
8922   u32 traffic_class_val = 0;
8923   u8 flow_label = 0;
8924   u8 flow_label_val;
8925   int src = 0, dst = 0;
8926   ip6_address_t src_val, dst_val;
8927   int proto = 0;
8928   u32 proto_val;
8929   int payload_length = 0;
8930   u32 payload_length_val;
8931   int hop_limit = 0;
8932   int hop_limit_val;
8933   u32 ip_version_traffic_class_and_flow_label;
8934
8935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8936     {
8937       if (unformat (input, "version %d", &version_val))
8938         version = 1;
8939       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8940         traffic_class = 1;
8941       else if (unformat (input, "flow_label %d", &flow_label_val))
8942         flow_label = 1;
8943       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8944         src = 1;
8945       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8946         dst = 1;
8947       else if (unformat (input, "proto %d", &proto_val))
8948         proto = 1;
8949       else if (unformat (input, "payload_length %d", &payload_length_val))
8950         payload_length = 1;
8951       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8952         hop_limit = 1;
8953       else
8954         break;
8955     }
8956
8957   if (version + traffic_class + flow_label + src + dst + proto +
8958       payload_length + hop_limit == 0)
8959     return 0;
8960
8961   /*
8962    * Aligned because we use the real comparison functions
8963    */
8964   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8965
8966   ip = (ip6_header_t *) match;
8967
8968   if (src)
8969     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8970
8971   if (dst)
8972     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8973
8974   if (proto)
8975     ip->protocol = proto_val;
8976
8977   ip_version_traffic_class_and_flow_label = 0;
8978
8979   if (version)
8980     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8981
8982   if (traffic_class)
8983     ip_version_traffic_class_and_flow_label |=
8984       (traffic_class_val & 0xFF) << 20;
8985
8986   if (flow_label)
8987     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8988
8989   ip->ip_version_traffic_class_and_flow_label =
8990     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8991
8992   if (payload_length)
8993     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8994
8995   if (hop_limit)
8996     ip->hop_limit = hop_limit_val;
8997
8998   *matchp = match;
8999   return 1;
9000 }
9001
9002 uword
9003 unformat_l3_match (unformat_input_t * input, va_list * args)
9004 {
9005   u8 **matchp = va_arg (*args, u8 **);
9006
9007   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9008     {
9009       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9010         return 1;
9011       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9012         return 1;
9013       else
9014         break;
9015     }
9016   return 0;
9017 }
9018
9019 uword
9020 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9021 {
9022   u8 *tagp = va_arg (*args, u8 *);
9023   u32 tag;
9024
9025   if (unformat (input, "%d", &tag))
9026     {
9027       tagp[0] = (tag >> 8) & 0x0F;
9028       tagp[1] = tag & 0xFF;
9029       return 1;
9030     }
9031
9032   return 0;
9033 }
9034
9035 uword
9036 unformat_l2_match (unformat_input_t * input, va_list * args)
9037 {
9038   u8 **matchp = va_arg (*args, u8 **);
9039   u8 *match = 0;
9040   u8 src = 0;
9041   u8 src_val[6];
9042   u8 dst = 0;
9043   u8 dst_val[6];
9044   u8 proto = 0;
9045   u16 proto_val;
9046   u8 tag1 = 0;
9047   u8 tag1_val[2];
9048   u8 tag2 = 0;
9049   u8 tag2_val[2];
9050   int len = 14;
9051   u8 ignore_tag1 = 0;
9052   u8 ignore_tag2 = 0;
9053   u8 cos1 = 0;
9054   u8 cos2 = 0;
9055   u32 cos1_val = 0;
9056   u32 cos2_val = 0;
9057
9058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9059     {
9060       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9061         src = 1;
9062       else
9063         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9064         dst = 1;
9065       else if (unformat (input, "proto %U",
9066                          unformat_ethernet_type_host_byte_order, &proto_val))
9067         proto = 1;
9068       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9069         tag1 = 1;
9070       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9071         tag2 = 1;
9072       else if (unformat (input, "ignore-tag1"))
9073         ignore_tag1 = 1;
9074       else if (unformat (input, "ignore-tag2"))
9075         ignore_tag2 = 1;
9076       else if (unformat (input, "cos1 %d", &cos1_val))
9077         cos1 = 1;
9078       else if (unformat (input, "cos2 %d", &cos2_val))
9079         cos2 = 1;
9080       else
9081         break;
9082     }
9083   if ((src + dst + proto + tag1 + tag2 +
9084        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9085     return 0;
9086
9087   if (tag1 || ignore_tag1 || cos1)
9088     len = 18;
9089   if (tag2 || ignore_tag2 || cos2)
9090     len = 22;
9091
9092   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9093
9094   if (dst)
9095     clib_memcpy (match, dst_val, 6);
9096
9097   if (src)
9098     clib_memcpy (match + 6, src_val, 6);
9099
9100   if (tag2)
9101     {
9102       /* inner vlan tag */
9103       match[19] = tag2_val[1];
9104       match[18] = tag2_val[0];
9105       if (cos2)
9106         match[18] |= (cos2_val & 0x7) << 5;
9107       if (proto)
9108         {
9109           match[21] = proto_val & 0xff;
9110           match[20] = proto_val >> 8;
9111         }
9112       if (tag1)
9113         {
9114           match[15] = tag1_val[1];
9115           match[14] = tag1_val[0];
9116         }
9117       if (cos1)
9118         match[14] |= (cos1_val & 0x7) << 5;
9119       *matchp = match;
9120       return 1;
9121     }
9122   if (tag1)
9123     {
9124       match[15] = tag1_val[1];
9125       match[14] = tag1_val[0];
9126       if (proto)
9127         {
9128           match[17] = proto_val & 0xff;
9129           match[16] = proto_val >> 8;
9130         }
9131       if (cos1)
9132         match[14] |= (cos1_val & 0x7) << 5;
9133
9134       *matchp = match;
9135       return 1;
9136     }
9137   if (cos2)
9138     match[18] |= (cos2_val & 0x7) << 5;
9139   if (cos1)
9140     match[14] |= (cos1_val & 0x7) << 5;
9141   if (proto)
9142     {
9143       match[13] = proto_val & 0xff;
9144       match[12] = proto_val >> 8;
9145     }
9146
9147   *matchp = match;
9148   return 1;
9149 }
9150
9151
9152 uword
9153 unformat_classify_match (unformat_input_t * input, va_list * args)
9154 {
9155   u8 **matchp = va_arg (*args, u8 **);
9156   u32 skip_n_vectors = va_arg (*args, u32);
9157   u32 match_n_vectors = va_arg (*args, u32);
9158
9159   u8 *match = 0;
9160   u8 *l2 = 0;
9161   u8 *l3 = 0;
9162   u8 *l4 = 0;
9163
9164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9165     {
9166       if (unformat (input, "hex %U", unformat_hex_string, &match))
9167         ;
9168       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9169         ;
9170       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9171         ;
9172       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9173         ;
9174       else
9175         break;
9176     }
9177
9178   if (l4 && !l3)
9179     {
9180       vec_free (match);
9181       vec_free (l2);
9182       vec_free (l4);
9183       return 0;
9184     }
9185
9186   if (match || l2 || l3 || l4)
9187     {
9188       if (l2 || l3 || l4)
9189         {
9190           /* "Win a free Ethernet header in every packet" */
9191           if (l2 == 0)
9192             vec_validate_aligned (l2, 13, sizeof (u32x4));
9193           match = l2;
9194           if (vec_len (l3))
9195             {
9196               vec_append_aligned (match, l3, sizeof (u32x4));
9197               vec_free (l3);
9198             }
9199           if (vec_len (l4))
9200             {
9201               vec_append_aligned (match, l4, sizeof (u32x4));
9202               vec_free (l4);
9203             }
9204         }
9205
9206       /* Make sure the vector is big enough even if key is all 0's */
9207       vec_validate_aligned
9208         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9209          sizeof (u32x4));
9210
9211       /* Set size, include skipped vectors */
9212       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9213
9214       *matchp = match;
9215
9216       return 1;
9217     }
9218
9219   return 0;
9220 }
9221
9222 static int
9223 api_classify_add_del_session (vat_main_t * vam)
9224 {
9225   unformat_input_t *i = vam->input;
9226   vl_api_classify_add_del_session_t *mp;
9227   int is_add = 1;
9228   u32 table_index = ~0;
9229   u32 hit_next_index = ~0;
9230   u32 opaque_index = ~0;
9231   u8 *match = 0;
9232   i32 advance = 0;
9233   f64 timeout;
9234   u32 skip_n_vectors = 0;
9235   u32 match_n_vectors = 0;
9236   u32 action = 0;
9237   u32 metadata = 0;
9238
9239   /*
9240    * Warning: you have to supply skip_n and match_n
9241    * because the API client cant simply look at the classify
9242    * table object.
9243    */
9244
9245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9246     {
9247       if (unformat (i, "del"))
9248         is_add = 0;
9249       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9250                          &hit_next_index))
9251         ;
9252       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9253                          &hit_next_index))
9254         ;
9255       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9256                          &hit_next_index))
9257         ;
9258       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9259         ;
9260       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9261         ;
9262       else if (unformat (i, "opaque-index %d", &opaque_index))
9263         ;
9264       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9265         ;
9266       else if (unformat (i, "match_n %d", &match_n_vectors))
9267         ;
9268       else if (unformat (i, "match %U", unformat_classify_match,
9269                          &match, skip_n_vectors, match_n_vectors))
9270         ;
9271       else if (unformat (i, "advance %d", &advance))
9272         ;
9273       else if (unformat (i, "table-index %d", &table_index))
9274         ;
9275       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9276         action = 1;
9277       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9278         action = 2;
9279       else if (unformat (i, "action %d", &action))
9280         ;
9281       else if (unformat (i, "metadata %d", &metadata))
9282         ;
9283       else
9284         break;
9285     }
9286
9287   if (table_index == ~0)
9288     {
9289       errmsg ("Table index required\n");
9290       return -99;
9291     }
9292
9293   if (is_add && match == 0)
9294     {
9295       errmsg ("Match value required\n");
9296       return -99;
9297     }
9298
9299   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9300
9301   mp->is_add = is_add;
9302   mp->table_index = ntohl (table_index);
9303   mp->hit_next_index = ntohl (hit_next_index);
9304   mp->opaque_index = ntohl (opaque_index);
9305   mp->advance = ntohl (advance);
9306   mp->action = action;
9307   mp->metadata = ntohl (metadata);
9308   clib_memcpy (mp->match, match, vec_len (match));
9309   vec_free (match);
9310
9311   S;
9312   W;
9313   /* NOTREACHED */
9314 }
9315
9316 static int
9317 api_classify_set_interface_ip_table (vat_main_t * vam)
9318 {
9319   unformat_input_t *i = vam->input;
9320   vl_api_classify_set_interface_ip_table_t *mp;
9321   f64 timeout;
9322   u32 sw_if_index;
9323   int sw_if_index_set;
9324   u32 table_index = ~0;
9325   u8 is_ipv6 = 0;
9326
9327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9328     {
9329       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9330         sw_if_index_set = 1;
9331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9332         sw_if_index_set = 1;
9333       else if (unformat (i, "table %d", &table_index))
9334         ;
9335       else
9336         {
9337           clib_warning ("parse error '%U'", format_unformat_error, i);
9338           return -99;
9339         }
9340     }
9341
9342   if (sw_if_index_set == 0)
9343     {
9344       errmsg ("missing interface name or sw_if_index\n");
9345       return -99;
9346     }
9347
9348
9349   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9350
9351   mp->sw_if_index = ntohl (sw_if_index);
9352   mp->table_index = ntohl (table_index);
9353   mp->is_ipv6 = is_ipv6;
9354
9355   S;
9356   W;
9357   /* NOTREACHED */
9358   return 0;
9359 }
9360
9361 static int
9362 api_classify_set_interface_l2_tables (vat_main_t * vam)
9363 {
9364   unformat_input_t *i = vam->input;
9365   vl_api_classify_set_interface_l2_tables_t *mp;
9366   f64 timeout;
9367   u32 sw_if_index;
9368   int sw_if_index_set;
9369   u32 ip4_table_index = ~0;
9370   u32 ip6_table_index = ~0;
9371   u32 other_table_index = ~0;
9372   u32 is_input = 1;
9373
9374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9375     {
9376       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9377         sw_if_index_set = 1;
9378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9379         sw_if_index_set = 1;
9380       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9381         ;
9382       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9383         ;
9384       else if (unformat (i, "other-table %d", &other_table_index))
9385         ;
9386       else if (unformat (i, "is-input %d", &is_input))
9387         ;
9388       else
9389         {
9390           clib_warning ("parse error '%U'", format_unformat_error, i);
9391           return -99;
9392         }
9393     }
9394
9395   if (sw_if_index_set == 0)
9396     {
9397       errmsg ("missing interface name or sw_if_index\n");
9398       return -99;
9399     }
9400
9401
9402   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9403
9404   mp->sw_if_index = ntohl (sw_if_index);
9405   mp->ip4_table_index = ntohl (ip4_table_index);
9406   mp->ip6_table_index = ntohl (ip6_table_index);
9407   mp->other_table_index = ntohl (other_table_index);
9408   mp->is_input = (u8) is_input;
9409
9410   S;
9411   W;
9412   /* NOTREACHED */
9413   return 0;
9414 }
9415
9416 static int
9417 api_set_ipfix_exporter (vat_main_t * vam)
9418 {
9419   unformat_input_t *i = vam->input;
9420   vl_api_set_ipfix_exporter_t *mp;
9421   ip4_address_t collector_address;
9422   u8 collector_address_set = 0;
9423   u32 collector_port = ~0;
9424   ip4_address_t src_address;
9425   u8 src_address_set = 0;
9426   u32 vrf_id = ~0;
9427   u32 path_mtu = ~0;
9428   u32 template_interval = ~0;
9429   u8 udp_checksum = 0;
9430   f64 timeout;
9431
9432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9433     {
9434       if (unformat (i, "collector_address %U", unformat_ip4_address,
9435                     &collector_address))
9436         collector_address_set = 1;
9437       else if (unformat (i, "collector_port %d", &collector_port))
9438         ;
9439       else if (unformat (i, "src_address %U", unformat_ip4_address,
9440                          &src_address))
9441         src_address_set = 1;
9442       else if (unformat (i, "vrf_id %d", &vrf_id))
9443         ;
9444       else if (unformat (i, "path_mtu %d", &path_mtu))
9445         ;
9446       else if (unformat (i, "template_interval %d", &template_interval))
9447         ;
9448       else if (unformat (i, "udp_checksum"))
9449         udp_checksum = 1;
9450       else
9451         break;
9452     }
9453
9454   if (collector_address_set == 0)
9455     {
9456       errmsg ("collector_address required\n");
9457       return -99;
9458     }
9459
9460   if (src_address_set == 0)
9461     {
9462       errmsg ("src_address required\n");
9463       return -99;
9464     }
9465
9466   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9467
9468   memcpy (mp->collector_address, collector_address.data,
9469           sizeof (collector_address.data));
9470   mp->collector_port = htons ((u16) collector_port);
9471   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9472   mp->vrf_id = htonl (vrf_id);
9473   mp->path_mtu = htonl (path_mtu);
9474   mp->template_interval = htonl (template_interval);
9475   mp->udp_checksum = udp_checksum;
9476
9477   S;
9478   W;
9479   /* NOTREACHED */
9480 }
9481
9482 static int
9483 api_set_ipfix_classify_stream (vat_main_t * vam)
9484 {
9485   unformat_input_t *i = vam->input;
9486   vl_api_set_ipfix_classify_stream_t *mp;
9487   u32 domain_id = 0;
9488   u32 src_port = UDP_DST_PORT_ipfix;
9489   f64 timeout;
9490
9491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (i, "domain %d", &domain_id))
9494         ;
9495       else if (unformat (i, "src_port %d", &src_port))
9496         ;
9497       else
9498         {
9499           errmsg ("unknown input `%U'", format_unformat_error, i);
9500           return -99;
9501         }
9502     }
9503
9504   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9505
9506   mp->domain_id = htonl (domain_id);
9507   mp->src_port = htons ((u16) src_port);
9508
9509   S;
9510   W;
9511   /* NOTREACHED */
9512 }
9513
9514 static int
9515 api_ipfix_classify_table_add_del (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_ipfix_classify_table_add_del_t *mp;
9519   int is_add = -1;
9520   u32 classify_table_index = ~0;
9521   u8 ip_version = 0;
9522   u8 transport_protocol = 255;
9523   f64 timeout;
9524
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "add"))
9528         is_add = 1;
9529       else if (unformat (i, "del"))
9530         is_add = 0;
9531       else if (unformat (i, "table %d", &classify_table_index))
9532         ;
9533       else if (unformat (i, "ip4"))
9534         ip_version = 4;
9535       else if (unformat (i, "ip6"))
9536         ip_version = 6;
9537       else if (unformat (i, "tcp"))
9538         transport_protocol = 6;
9539       else if (unformat (i, "udp"))
9540         transport_protocol = 17;
9541       else
9542         {
9543           errmsg ("unknown input `%U'", format_unformat_error, i);
9544           return -99;
9545         }
9546     }
9547
9548   if (is_add == -1)
9549     {
9550       errmsg ("expecting: add|del");
9551       return -99;
9552     }
9553   if (classify_table_index == ~0)
9554     {
9555       errmsg ("classifier table not specified");
9556       return -99;
9557     }
9558   if (ip_version == 0)
9559     {
9560       errmsg ("IP version not specified");
9561       return -99;
9562     }
9563
9564   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9565
9566   mp->is_add = is_add;
9567   mp->table_id = htonl (classify_table_index);
9568   mp->ip_version = ip_version;
9569   mp->transport_protocol = transport_protocol;
9570
9571   S;
9572   W;
9573   /* NOTREACHED */
9574 }
9575
9576 static int
9577 api_get_node_index (vat_main_t * vam)
9578 {
9579   unformat_input_t *i = vam->input;
9580   vl_api_get_node_index_t *mp;
9581   f64 timeout;
9582   u8 *name = 0;
9583
9584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9585     {
9586       if (unformat (i, "node %s", &name))
9587         ;
9588       else
9589         break;
9590     }
9591   if (name == 0)
9592     {
9593       errmsg ("node name required\n");
9594       return -99;
9595     }
9596   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9597     {
9598       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9599       return -99;
9600     }
9601
9602   M (GET_NODE_INDEX, get_node_index);
9603   clib_memcpy (mp->node_name, name, vec_len (name));
9604   vec_free (name);
9605
9606   S;
9607   W;
9608   /* NOTREACHED */
9609   return 0;
9610 }
9611
9612 static int
9613 api_get_next_index (vat_main_t * vam)
9614 {
9615   unformat_input_t *i = vam->input;
9616   vl_api_get_next_index_t *mp;
9617   f64 timeout;
9618   u8 *node_name = 0, *next_node_name = 0;
9619
9620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9621     {
9622       if (unformat (i, "node-name %s", &node_name))
9623         ;
9624       else if (unformat (i, "next-node-name %s", &next_node_name))
9625         break;
9626     }
9627
9628   if (node_name == 0)
9629     {
9630       errmsg ("node name required\n");
9631       return -99;
9632     }
9633   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9634     {
9635       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9636       return -99;
9637     }
9638
9639   if (next_node_name == 0)
9640     {
9641       errmsg ("next node name required\n");
9642       return -99;
9643     }
9644   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9645     {
9646       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9647       return -99;
9648     }
9649
9650   M (GET_NEXT_INDEX, get_next_index);
9651   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9652   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9653   vec_free (node_name);
9654   vec_free (next_node_name);
9655
9656   S;
9657   W;
9658   /* NOTREACHED */
9659   return 0;
9660 }
9661
9662 static int
9663 api_add_node_next (vat_main_t * vam)
9664 {
9665   unformat_input_t *i = vam->input;
9666   vl_api_add_node_next_t *mp;
9667   f64 timeout;
9668   u8 *name = 0;
9669   u8 *next = 0;
9670
9671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9672     {
9673       if (unformat (i, "node %s", &name))
9674         ;
9675       else if (unformat (i, "next %s", &next))
9676         ;
9677       else
9678         break;
9679     }
9680   if (name == 0)
9681     {
9682       errmsg ("node name required\n");
9683       return -99;
9684     }
9685   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9686     {
9687       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9688       return -99;
9689     }
9690   if (next == 0)
9691     {
9692       errmsg ("next node required\n");
9693       return -99;
9694     }
9695   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9696     {
9697       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9698       return -99;
9699     }
9700
9701   M (ADD_NODE_NEXT, add_node_next);
9702   clib_memcpy (mp->node_name, name, vec_len (name));
9703   clib_memcpy (mp->next_name, next, vec_len (next));
9704   vec_free (name);
9705   vec_free (next);
9706
9707   S;
9708   W;
9709   /* NOTREACHED */
9710   return 0;
9711 }
9712
9713 static int
9714 api_l2tpv3_create_tunnel (vat_main_t * vam)
9715 {
9716   unformat_input_t *i = vam->input;
9717   ip6_address_t client_address, our_address;
9718   int client_address_set = 0;
9719   int our_address_set = 0;
9720   u32 local_session_id = 0;
9721   u32 remote_session_id = 0;
9722   u64 local_cookie = 0;
9723   u64 remote_cookie = 0;
9724   u8 l2_sublayer_present = 0;
9725   vl_api_l2tpv3_create_tunnel_t *mp;
9726   f64 timeout;
9727
9728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9729     {
9730       if (unformat (i, "client_address %U", unformat_ip6_address,
9731                     &client_address))
9732         client_address_set = 1;
9733       else if (unformat (i, "our_address %U", unformat_ip6_address,
9734                          &our_address))
9735         our_address_set = 1;
9736       else if (unformat (i, "local_session_id %d", &local_session_id))
9737         ;
9738       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9739         ;
9740       else if (unformat (i, "local_cookie %lld", &local_cookie))
9741         ;
9742       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9743         ;
9744       else if (unformat (i, "l2-sublayer-present"))
9745         l2_sublayer_present = 1;
9746       else
9747         break;
9748     }
9749
9750   if (client_address_set == 0)
9751     {
9752       errmsg ("client_address required\n");
9753       return -99;
9754     }
9755
9756   if (our_address_set == 0)
9757     {
9758       errmsg ("our_address required\n");
9759       return -99;
9760     }
9761
9762   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9763
9764   clib_memcpy (mp->client_address, client_address.as_u8,
9765                sizeof (mp->client_address));
9766
9767   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9768
9769   mp->local_session_id = ntohl (local_session_id);
9770   mp->remote_session_id = ntohl (remote_session_id);
9771   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9772   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9773   mp->l2_sublayer_present = l2_sublayer_present;
9774   mp->is_ipv6 = 1;
9775
9776   S;
9777   W;
9778   /* NOTREACHED */
9779   return 0;
9780 }
9781
9782 static int
9783 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9784 {
9785   unformat_input_t *i = vam->input;
9786   u32 sw_if_index;
9787   u8 sw_if_index_set = 0;
9788   u64 new_local_cookie = 0;
9789   u64 new_remote_cookie = 0;
9790   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9791   f64 timeout;
9792
9793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9794     {
9795       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9796         sw_if_index_set = 1;
9797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9798         sw_if_index_set = 1;
9799       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9800         ;
9801       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9802         ;
9803       else
9804         break;
9805     }
9806
9807   if (sw_if_index_set == 0)
9808     {
9809       errmsg ("missing interface name or sw_if_index\n");
9810       return -99;
9811     }
9812
9813   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9814
9815   mp->sw_if_index = ntohl (sw_if_index);
9816   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9817   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9818
9819   S;
9820   W;
9821   /* NOTREACHED */
9822   return 0;
9823 }
9824
9825 static int
9826 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9827 {
9828   unformat_input_t *i = vam->input;
9829   vl_api_l2tpv3_interface_enable_disable_t *mp;
9830   f64 timeout;
9831   u32 sw_if_index;
9832   u8 sw_if_index_set = 0;
9833   u8 enable_disable = 1;
9834
9835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9838         sw_if_index_set = 1;
9839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9840         sw_if_index_set = 1;
9841       else if (unformat (i, "enable"))
9842         enable_disable = 1;
9843       else if (unformat (i, "disable"))
9844         enable_disable = 0;
9845       else
9846         break;
9847     }
9848
9849   if (sw_if_index_set == 0)
9850     {
9851       errmsg ("missing interface name or sw_if_index\n");
9852       return -99;
9853     }
9854
9855   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9856
9857   mp->sw_if_index = ntohl (sw_if_index);
9858   mp->enable_disable = enable_disable;
9859
9860   S;
9861   W;
9862   /* NOTREACHED */
9863   return 0;
9864 }
9865
9866 static int
9867 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9868 {
9869   unformat_input_t *i = vam->input;
9870   vl_api_l2tpv3_set_lookup_key_t *mp;
9871   f64 timeout;
9872   u8 key = ~0;
9873
9874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9875     {
9876       if (unformat (i, "lookup_v6_src"))
9877         key = L2T_LOOKUP_SRC_ADDRESS;
9878       else if (unformat (i, "lookup_v6_dst"))
9879         key = L2T_LOOKUP_DST_ADDRESS;
9880       else if (unformat (i, "lookup_session_id"))
9881         key = L2T_LOOKUP_SESSION_ID;
9882       else
9883         break;
9884     }
9885
9886   if (key == (u8) ~ 0)
9887     {
9888       errmsg ("l2tp session lookup key unset\n");
9889       return -99;
9890     }
9891
9892   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9893
9894   mp->key = key;
9895
9896   S;
9897   W;
9898   /* NOTREACHED */
9899   return 0;
9900 }
9901
9902 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9903   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9904 {
9905   vat_main_t *vam = &vat_main;
9906
9907   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9908            format_ip6_address, mp->our_address,
9909            format_ip6_address, mp->client_address,
9910            clib_net_to_host_u32 (mp->sw_if_index));
9911
9912   fformat (vam->ofp,
9913            "   local cookies %016llx %016llx remote cookie %016llx\n",
9914            clib_net_to_host_u64 (mp->local_cookie[0]),
9915            clib_net_to_host_u64 (mp->local_cookie[1]),
9916            clib_net_to_host_u64 (mp->remote_cookie));
9917
9918   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9919            clib_net_to_host_u32 (mp->local_session_id),
9920            clib_net_to_host_u32 (mp->remote_session_id));
9921
9922   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9923            mp->l2_sublayer_present ? "preset" : "absent");
9924
9925 }
9926
9927 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9928   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9929 {
9930   vat_main_t *vam = &vat_main;
9931   vat_json_node_t *node = NULL;
9932   struct in6_addr addr;
9933
9934   if (VAT_JSON_ARRAY != vam->json_tree.type)
9935     {
9936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9937       vat_json_init_array (&vam->json_tree);
9938     }
9939   node = vat_json_array_add (&vam->json_tree);
9940
9941   vat_json_init_object (node);
9942
9943   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9944   vat_json_object_add_ip6 (node, "our_address", addr);
9945   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9946   vat_json_object_add_ip6 (node, "client_address", addr);
9947
9948   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9949   vat_json_init_array (lc);
9950   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9951   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9952   vat_json_object_add_uint (node, "remote_cookie",
9953                             clib_net_to_host_u64 (mp->remote_cookie));
9954
9955   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9956   vat_json_object_add_uint (node, "local_session_id",
9957                             clib_net_to_host_u32 (mp->local_session_id));
9958   vat_json_object_add_uint (node, "remote_session_id",
9959                             clib_net_to_host_u32 (mp->remote_session_id));
9960   vat_json_object_add_string_copy (node, "l2_sublayer",
9961                                    mp->l2_sublayer_present ? (u8 *) "present"
9962                                    : (u8 *) "absent");
9963 }
9964
9965 static int
9966 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9967 {
9968   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9969   f64 timeout;
9970
9971   /* Get list of l2tpv3-tunnel interfaces */
9972   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9973   S;
9974
9975   /* Use a control ping for synchronization */
9976   {
9977     vl_api_control_ping_t *mp;
9978     M (CONTROL_PING, control_ping);
9979     S;
9980   }
9981   W;
9982 }
9983
9984
9985 static void vl_api_sw_interface_tap_details_t_handler
9986   (vl_api_sw_interface_tap_details_t * mp)
9987 {
9988   vat_main_t *vam = &vat_main;
9989
9990   fformat (vam->ofp, "%-16s %d\n",
9991            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9992 }
9993
9994 static void vl_api_sw_interface_tap_details_t_handler_json
9995   (vl_api_sw_interface_tap_details_t * mp)
9996 {
9997   vat_main_t *vam = &vat_main;
9998   vat_json_node_t *node = NULL;
9999
10000   if (VAT_JSON_ARRAY != vam->json_tree.type)
10001     {
10002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10003       vat_json_init_array (&vam->json_tree);
10004     }
10005   node = vat_json_array_add (&vam->json_tree);
10006
10007   vat_json_init_object (node);
10008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10009   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10010 }
10011
10012 static int
10013 api_sw_interface_tap_dump (vat_main_t * vam)
10014 {
10015   vl_api_sw_interface_tap_dump_t *mp;
10016   f64 timeout;
10017
10018   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10019   /* Get list of tap interfaces */
10020   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10021   S;
10022
10023   /* Use a control ping for synchronization */
10024   {
10025     vl_api_control_ping_t *mp;
10026     M (CONTROL_PING, control_ping);
10027     S;
10028   }
10029   W;
10030 }
10031
10032 static uword unformat_vxlan_decap_next
10033   (unformat_input_t * input, va_list * args)
10034 {
10035   u32 *result = va_arg (*args, u32 *);
10036   u32 tmp;
10037
10038   if (unformat (input, "l2"))
10039     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10040   else if (unformat (input, "%d", &tmp))
10041     *result = tmp;
10042   else
10043     return 0;
10044   return 1;
10045 }
10046
10047 static int
10048 api_vxlan_add_del_tunnel (vat_main_t * vam)
10049 {
10050   unformat_input_t *line_input = vam->input;
10051   vl_api_vxlan_add_del_tunnel_t *mp;
10052   f64 timeout;
10053   ip46_address_t src, dst;
10054   u8 is_add = 1;
10055   u8 ipv4_set = 0, ipv6_set = 0;
10056   u8 src_set = 0;
10057   u8 dst_set = 0;
10058   u8 grp_set = 0;
10059   u32 mcast_sw_if_index = ~0;
10060   u32 encap_vrf_id = 0;
10061   u32 decap_next_index = ~0;
10062   u32 vni = 0;
10063
10064   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10065   memset (&src, 0, sizeof src);
10066   memset (&dst, 0, sizeof dst);
10067
10068   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10069     {
10070       if (unformat (line_input, "del"))
10071         is_add = 0;
10072       else
10073         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10074         {
10075           ipv4_set = 1;
10076           src_set = 1;
10077         }
10078       else
10079         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10080         {
10081           ipv4_set = 1;
10082           dst_set = 1;
10083         }
10084       else
10085         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10086         {
10087           ipv6_set = 1;
10088           src_set = 1;
10089         }
10090       else
10091         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10092         {
10093           ipv6_set = 1;
10094           dst_set = 1;
10095         }
10096       else if (unformat (line_input, "group %U %U",
10097                          unformat_ip4_address, &dst.ip4,
10098                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10099         {
10100           grp_set = dst_set = 1;
10101           ipv4_set = 1;
10102         }
10103       else if (unformat (line_input, "group %U",
10104                          unformat_ip4_address, &dst.ip4))
10105         {
10106           grp_set = dst_set = 1;
10107           ipv4_set = 1;
10108         }
10109       else if (unformat (line_input, "group %U %U",
10110                          unformat_ip6_address, &dst.ip6,
10111                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10112         {
10113           grp_set = dst_set = 1;
10114           ipv6_set = 1;
10115         }
10116       else if (unformat (line_input, "group %U",
10117                          unformat_ip6_address, &dst.ip6))
10118         {
10119           grp_set = dst_set = 1;
10120           ipv6_set = 1;
10121         }
10122       else
10123         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10124         ;
10125       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10126         ;
10127       else if (unformat (line_input, "decap-next %U",
10128                          unformat_vxlan_decap_next, &decap_next_index))
10129         ;
10130       else if (unformat (line_input, "vni %d", &vni))
10131         ;
10132       else
10133         {
10134           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10135           return -99;
10136         }
10137     }
10138
10139   if (src_set == 0)
10140     {
10141       errmsg ("tunnel src address not specified\n");
10142       return -99;
10143     }
10144   if (dst_set == 0)
10145     {
10146       errmsg ("tunnel dst address not specified\n");
10147       return -99;
10148     }
10149
10150   if (grp_set && !ip46_address_is_multicast (&dst))
10151     {
10152       errmsg ("tunnel group address not multicast\n");
10153       return -99;
10154     }
10155   if (grp_set && mcast_sw_if_index == ~0)
10156     {
10157       errmsg ("tunnel nonexistent multicast device\n");
10158       return -99;
10159     }
10160
10161
10162   if (ipv4_set && ipv6_set)
10163     {
10164       errmsg ("both IPv4 and IPv6 addresses specified");
10165       return -99;
10166     }
10167
10168   if ((vni == 0) || (vni >> 24))
10169     {
10170       errmsg ("vni not specified or out of range\n");
10171       return -99;
10172     }
10173
10174   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10175
10176   if (ipv6_set)
10177     {
10178       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10179       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10180     }
10181   else
10182     {
10183       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10184       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10185     }
10186   mp->encap_vrf_id = ntohl (encap_vrf_id);
10187   mp->decap_next_index = ntohl (decap_next_index);
10188   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10189   mp->vni = ntohl (vni);
10190   mp->is_add = is_add;
10191   mp->is_ipv6 = ipv6_set;
10192
10193   S;
10194   W;
10195   /* NOTREACHED */
10196   return 0;
10197 }
10198
10199 static void vl_api_vxlan_tunnel_details_t_handler
10200   (vl_api_vxlan_tunnel_details_t * mp)
10201 {
10202   vat_main_t *vam = &vat_main;
10203   ip46_address_t src, dst;
10204
10205   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10206   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10207
10208   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10209            ntohl (mp->sw_if_index),
10210            format_ip46_address, &src, IP46_TYPE_ANY,
10211            format_ip46_address, &dst, IP46_TYPE_ANY,
10212            ntohl (mp->encap_vrf_id),
10213            ntohl (mp->decap_next_index), ntohl (mp->vni),
10214            ntohl (mp->mcast_sw_if_index));
10215 }
10216
10217 static void vl_api_vxlan_tunnel_details_t_handler_json
10218   (vl_api_vxlan_tunnel_details_t * mp)
10219 {
10220   vat_main_t *vam = &vat_main;
10221   vat_json_node_t *node = NULL;
10222
10223   if (VAT_JSON_ARRAY != vam->json_tree.type)
10224     {
10225       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10226       vat_json_init_array (&vam->json_tree);
10227     }
10228   node = vat_json_array_add (&vam->json_tree);
10229
10230   vat_json_init_object (node);
10231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10232   if (mp->is_ipv6)
10233     {
10234       struct in6_addr ip6;
10235
10236       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10237       vat_json_object_add_ip6 (node, "src_address", ip6);
10238       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10239       vat_json_object_add_ip6 (node, "dst_address", ip6);
10240     }
10241   else
10242     {
10243       struct in_addr ip4;
10244
10245       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10246       vat_json_object_add_ip4 (node, "src_address", ip4);
10247       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10248       vat_json_object_add_ip4 (node, "dst_address", ip4);
10249     }
10250   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10251   vat_json_object_add_uint (node, "decap_next_index",
10252                             ntohl (mp->decap_next_index));
10253   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10254   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10255   vat_json_object_add_uint (node, "mcast_sw_if_index",
10256                             ntohl (mp->mcast_sw_if_index));
10257 }
10258
10259 static int
10260 api_vxlan_tunnel_dump (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   vl_api_vxlan_tunnel_dump_t *mp;
10264   f64 timeout;
10265   u32 sw_if_index;
10266   u8 sw_if_index_set = 0;
10267
10268   /* Parse args required to build the message */
10269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10270     {
10271       if (unformat (i, "sw_if_index %d", &sw_if_index))
10272         sw_if_index_set = 1;
10273       else
10274         break;
10275     }
10276
10277   if (sw_if_index_set == 0)
10278     {
10279       sw_if_index = ~0;
10280     }
10281
10282   if (!vam->json_output)
10283     {
10284       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10285                "sw_if_index", "src_address", "dst_address",
10286                "encap_vrf_id", "decap_next_index", "vni",
10287                "mcast_sw_if_index");
10288     }
10289
10290   /* Get list of vxlan-tunnel interfaces */
10291   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10292
10293   mp->sw_if_index = htonl (sw_if_index);
10294
10295   S;
10296
10297   /* Use a control ping for synchronization */
10298   {
10299     vl_api_control_ping_t *mp;
10300     M (CONTROL_PING, control_ping);
10301     S;
10302   }
10303   W;
10304 }
10305
10306 static int
10307 api_gre_add_del_tunnel (vat_main_t * vam)
10308 {
10309   unformat_input_t *line_input = vam->input;
10310   vl_api_gre_add_del_tunnel_t *mp;
10311   f64 timeout;
10312   ip4_address_t src4, dst4;
10313   u8 is_add = 1;
10314   u8 teb = 0;
10315   u8 src_set = 0;
10316   u8 dst_set = 0;
10317   u32 outer_fib_id = 0;
10318
10319   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10320     {
10321       if (unformat (line_input, "del"))
10322         is_add = 0;
10323       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10324         src_set = 1;
10325       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10326         dst_set = 1;
10327       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10328         ;
10329       else if (unformat (line_input, "teb"))
10330         teb = 1;
10331       else
10332         {
10333           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10334           return -99;
10335         }
10336     }
10337
10338   if (src_set == 0)
10339     {
10340       errmsg ("tunnel src address not specified\n");
10341       return -99;
10342     }
10343   if (dst_set == 0)
10344     {
10345       errmsg ("tunnel dst address not specified\n");
10346       return -99;
10347     }
10348
10349
10350   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10351
10352   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10353   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10354   mp->outer_fib_id = ntohl (outer_fib_id);
10355   mp->is_add = is_add;
10356   mp->teb = teb;
10357
10358   S;
10359   W;
10360   /* NOTREACHED */
10361   return 0;
10362 }
10363
10364 static void vl_api_gre_tunnel_details_t_handler
10365   (vl_api_gre_tunnel_details_t * mp)
10366 {
10367   vat_main_t *vam = &vat_main;
10368
10369   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10370            ntohl (mp->sw_if_index),
10371            format_ip4_address, &mp->src_address,
10372            format_ip4_address, &mp->dst_address,
10373            mp->teb, ntohl (mp->outer_fib_id));
10374 }
10375
10376 static void vl_api_gre_tunnel_details_t_handler_json
10377   (vl_api_gre_tunnel_details_t * mp)
10378 {
10379   vat_main_t *vam = &vat_main;
10380   vat_json_node_t *node = NULL;
10381   struct in_addr ip4;
10382
10383   if (VAT_JSON_ARRAY != vam->json_tree.type)
10384     {
10385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10386       vat_json_init_array (&vam->json_tree);
10387     }
10388   node = vat_json_array_add (&vam->json_tree);
10389
10390   vat_json_init_object (node);
10391   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10392   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10393   vat_json_object_add_ip4 (node, "src_address", ip4);
10394   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10395   vat_json_object_add_ip4 (node, "dst_address", ip4);
10396   vat_json_object_add_uint (node, "teb", mp->teb);
10397   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10398 }
10399
10400 static int
10401 api_gre_tunnel_dump (vat_main_t * vam)
10402 {
10403   unformat_input_t *i = vam->input;
10404   vl_api_gre_tunnel_dump_t *mp;
10405   f64 timeout;
10406   u32 sw_if_index;
10407   u8 sw_if_index_set = 0;
10408
10409   /* Parse args required to build the message */
10410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10411     {
10412       if (unformat (i, "sw_if_index %d", &sw_if_index))
10413         sw_if_index_set = 1;
10414       else
10415         break;
10416     }
10417
10418   if (sw_if_index_set == 0)
10419     {
10420       sw_if_index = ~0;
10421     }
10422
10423   if (!vam->json_output)
10424     {
10425       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10426                "sw_if_index", "src_address", "dst_address", "teb",
10427                "outer_fib_id");
10428     }
10429
10430   /* Get list of gre-tunnel interfaces */
10431   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10432
10433   mp->sw_if_index = htonl (sw_if_index);
10434
10435   S;
10436
10437   /* Use a control ping for synchronization */
10438   {
10439     vl_api_control_ping_t *mp;
10440     M (CONTROL_PING, control_ping);
10441     S;
10442   }
10443   W;
10444 }
10445
10446 static int
10447 api_l2_fib_clear_table (vat_main_t * vam)
10448 {
10449 //  unformat_input_t * i = vam->input;
10450   vl_api_l2_fib_clear_table_t *mp;
10451   f64 timeout;
10452
10453   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10454
10455   S;
10456   W;
10457   /* NOTREACHED */
10458   return 0;
10459 }
10460
10461 static int
10462 api_l2_interface_efp_filter (vat_main_t * vam)
10463 {
10464   unformat_input_t *i = vam->input;
10465   vl_api_l2_interface_efp_filter_t *mp;
10466   f64 timeout;
10467   u32 sw_if_index;
10468   u8 enable = 1;
10469   u8 sw_if_index_set = 0;
10470
10471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10472     {
10473       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10474         sw_if_index_set = 1;
10475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10476         sw_if_index_set = 1;
10477       else if (unformat (i, "enable"))
10478         enable = 1;
10479       else if (unformat (i, "disable"))
10480         enable = 0;
10481       else
10482         {
10483           clib_warning ("parse error '%U'", format_unformat_error, i);
10484           return -99;
10485         }
10486     }
10487
10488   if (sw_if_index_set == 0)
10489     {
10490       errmsg ("missing sw_if_index\n");
10491       return -99;
10492     }
10493
10494   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10495
10496   mp->sw_if_index = ntohl (sw_if_index);
10497   mp->enable_disable = enable;
10498
10499   S;
10500   W;
10501   /* NOTREACHED */
10502   return 0;
10503 }
10504
10505 #define foreach_vtr_op                          \
10506 _("disable",  L2_VTR_DISABLED)                  \
10507 _("push-1",  L2_VTR_PUSH_1)                     \
10508 _("push-2",  L2_VTR_PUSH_2)                     \
10509 _("pop-1",  L2_VTR_POP_1)                       \
10510 _("pop-2",  L2_VTR_POP_2)                       \
10511 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10512 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10513 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10514 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10515
10516 static int
10517 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10518 {
10519   unformat_input_t *i = vam->input;
10520   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10521   f64 timeout;
10522   u32 sw_if_index;
10523   u8 sw_if_index_set = 0;
10524   u8 vtr_op_set = 0;
10525   u32 vtr_op = 0;
10526   u32 push_dot1q = 1;
10527   u32 tag1 = ~0;
10528   u32 tag2 = ~0;
10529
10530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10531     {
10532       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10533         sw_if_index_set = 1;
10534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10535         sw_if_index_set = 1;
10536       else if (unformat (i, "vtr_op %d", &vtr_op))
10537         vtr_op_set = 1;
10538 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10539       foreach_vtr_op
10540 #undef _
10541         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10542         ;
10543       else if (unformat (i, "tag1 %d", &tag1))
10544         ;
10545       else if (unformat (i, "tag2 %d", &tag2))
10546         ;
10547       else
10548         {
10549           clib_warning ("parse error '%U'", format_unformat_error, i);
10550           return -99;
10551         }
10552     }
10553
10554   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10555     {
10556       errmsg ("missing vtr operation or sw_if_index\n");
10557       return -99;
10558     }
10559
10560   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10561     mp->sw_if_index = ntohl (sw_if_index);
10562   mp->vtr_op = ntohl (vtr_op);
10563   mp->push_dot1q = ntohl (push_dot1q);
10564   mp->tag1 = ntohl (tag1);
10565   mp->tag2 = ntohl (tag2);
10566
10567   S;
10568   W;
10569   /* NOTREACHED */
10570   return 0;
10571 }
10572
10573 static int
10574 api_create_vhost_user_if (vat_main_t * vam)
10575 {
10576   unformat_input_t *i = vam->input;
10577   vl_api_create_vhost_user_if_t *mp;
10578   f64 timeout;
10579   u8 *file_name;
10580   u8 is_server = 0;
10581   u8 file_name_set = 0;
10582   u32 custom_dev_instance = ~0;
10583   u8 hwaddr[6];
10584   u8 use_custom_mac = 0;
10585   u8 *tag = 0;
10586
10587   /* Shut up coverity */
10588   memset (hwaddr, 0, sizeof (hwaddr));
10589
10590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (i, "socket %s", &file_name))
10593         {
10594           file_name_set = 1;
10595         }
10596       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10597         ;
10598       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10599         use_custom_mac = 1;
10600       else if (unformat (i, "server"))
10601         is_server = 1;
10602       else if (unformat (i, "tag %s", &tag))
10603         ;
10604       else
10605         break;
10606     }
10607
10608   if (file_name_set == 0)
10609     {
10610       errmsg ("missing socket file name\n");
10611       return -99;
10612     }
10613
10614   if (vec_len (file_name) > 255)
10615     {
10616       errmsg ("socket file name too long\n");
10617       return -99;
10618     }
10619   vec_add1 (file_name, 0);
10620
10621   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10622
10623   mp->is_server = is_server;
10624   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10625   vec_free (file_name);
10626   if (custom_dev_instance != ~0)
10627     {
10628       mp->renumber = 1;
10629       mp->custom_dev_instance = ntohl (custom_dev_instance);
10630     }
10631   mp->use_custom_mac = use_custom_mac;
10632   clib_memcpy (mp->mac_address, hwaddr, 6);
10633   if (tag)
10634     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10635   vec_free (tag);
10636
10637   S;
10638   W;
10639   /* NOTREACHED */
10640   return 0;
10641 }
10642
10643 static int
10644 api_modify_vhost_user_if (vat_main_t * vam)
10645 {
10646   unformat_input_t *i = vam->input;
10647   vl_api_modify_vhost_user_if_t *mp;
10648   f64 timeout;
10649   u8 *file_name;
10650   u8 is_server = 0;
10651   u8 file_name_set = 0;
10652   u32 custom_dev_instance = ~0;
10653   u8 sw_if_index_set = 0;
10654   u32 sw_if_index = (u32) ~ 0;
10655
10656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10657     {
10658       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10659         sw_if_index_set = 1;
10660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10661         sw_if_index_set = 1;
10662       else if (unformat (i, "socket %s", &file_name))
10663         {
10664           file_name_set = 1;
10665         }
10666       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10667         ;
10668       else if (unformat (i, "server"))
10669         is_server = 1;
10670       else
10671         break;
10672     }
10673
10674   if (sw_if_index_set == 0)
10675     {
10676       errmsg ("missing sw_if_index or interface name\n");
10677       return -99;
10678     }
10679
10680   if (file_name_set == 0)
10681     {
10682       errmsg ("missing socket file name\n");
10683       return -99;
10684     }
10685
10686   if (vec_len (file_name) > 255)
10687     {
10688       errmsg ("socket file name too long\n");
10689       return -99;
10690     }
10691   vec_add1 (file_name, 0);
10692
10693   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10694
10695   mp->sw_if_index = ntohl (sw_if_index);
10696   mp->is_server = is_server;
10697   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10698   vec_free (file_name);
10699   if (custom_dev_instance != ~0)
10700     {
10701       mp->renumber = 1;
10702       mp->custom_dev_instance = ntohl (custom_dev_instance);
10703     }
10704
10705   S;
10706   W;
10707   /* NOTREACHED */
10708   return 0;
10709 }
10710
10711 static int
10712 api_delete_vhost_user_if (vat_main_t * vam)
10713 {
10714   unformat_input_t *i = vam->input;
10715   vl_api_delete_vhost_user_if_t *mp;
10716   f64 timeout;
10717   u32 sw_if_index = ~0;
10718   u8 sw_if_index_set = 0;
10719
10720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10721     {
10722       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10723         sw_if_index_set = 1;
10724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10725         sw_if_index_set = 1;
10726       else
10727         break;
10728     }
10729
10730   if (sw_if_index_set == 0)
10731     {
10732       errmsg ("missing sw_if_index or interface name\n");
10733       return -99;
10734     }
10735
10736
10737   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10738
10739   mp->sw_if_index = ntohl (sw_if_index);
10740
10741   S;
10742   W;
10743   /* NOTREACHED */
10744   return 0;
10745 }
10746
10747 static void vl_api_sw_interface_vhost_user_details_t_handler
10748   (vl_api_sw_interface_vhost_user_details_t * mp)
10749 {
10750   vat_main_t *vam = &vat_main;
10751
10752   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10753            (char *) mp->interface_name,
10754            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10755            clib_net_to_host_u64 (mp->features), mp->is_server,
10756            ntohl (mp->num_regions), (char *) mp->sock_filename);
10757   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10758 }
10759
10760 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10761   (vl_api_sw_interface_vhost_user_details_t * mp)
10762 {
10763   vat_main_t *vam = &vat_main;
10764   vat_json_node_t *node = NULL;
10765
10766   if (VAT_JSON_ARRAY != vam->json_tree.type)
10767     {
10768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10769       vat_json_init_array (&vam->json_tree);
10770     }
10771   node = vat_json_array_add (&vam->json_tree);
10772
10773   vat_json_init_object (node);
10774   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10775   vat_json_object_add_string_copy (node, "interface_name",
10776                                    mp->interface_name);
10777   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10778                             ntohl (mp->virtio_net_hdr_sz));
10779   vat_json_object_add_uint (node, "features",
10780                             clib_net_to_host_u64 (mp->features));
10781   vat_json_object_add_uint (node, "is_server", mp->is_server);
10782   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10783   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10784   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10785 }
10786
10787 static int
10788 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10789 {
10790   vl_api_sw_interface_vhost_user_dump_t *mp;
10791   f64 timeout;
10792   fformat (vam->ofp,
10793            "Interface name           idx hdr_sz features server regions filename\n");
10794
10795   /* Get list of vhost-user interfaces */
10796   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10797   S;
10798
10799   /* Use a control ping for synchronization */
10800   {
10801     vl_api_control_ping_t *mp;
10802     M (CONTROL_PING, control_ping);
10803     S;
10804   }
10805   W;
10806 }
10807
10808 static int
10809 api_show_version (vat_main_t * vam)
10810 {
10811   vl_api_show_version_t *mp;
10812   f64 timeout;
10813
10814   M (SHOW_VERSION, show_version);
10815
10816   S;
10817   W;
10818   /* NOTREACHED */
10819   return 0;
10820 }
10821
10822
10823 static int
10824 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10825 {
10826   unformat_input_t *line_input = vam->input;
10827   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10828   f64 timeout;
10829   ip4_address_t local4, remote4;
10830   ip6_address_t local6, remote6;
10831   u8 is_add = 1;
10832   u8 ipv4_set = 0, ipv6_set = 0;
10833   u8 local_set = 0;
10834   u8 remote_set = 0;
10835   u32 encap_vrf_id = 0;
10836   u32 decap_vrf_id = 0;
10837   u8 protocol = ~0;
10838   u32 vni;
10839   u8 vni_set = 0;
10840
10841   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10842     {
10843       if (unformat (line_input, "del"))
10844         is_add = 0;
10845       else if (unformat (line_input, "local %U",
10846                          unformat_ip4_address, &local4))
10847         {
10848           local_set = 1;
10849           ipv4_set = 1;
10850         }
10851       else if (unformat (line_input, "remote %U",
10852                          unformat_ip4_address, &remote4))
10853         {
10854           remote_set = 1;
10855           ipv4_set = 1;
10856         }
10857       else if (unformat (line_input, "local %U",
10858                          unformat_ip6_address, &local6))
10859         {
10860           local_set = 1;
10861           ipv6_set = 1;
10862         }
10863       else if (unformat (line_input, "remote %U",
10864                          unformat_ip6_address, &remote6))
10865         {
10866           remote_set = 1;
10867           ipv6_set = 1;
10868         }
10869       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10870         ;
10871       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10872         ;
10873       else if (unformat (line_input, "vni %d", &vni))
10874         vni_set = 1;
10875       else if (unformat (line_input, "next-ip4"))
10876         protocol = 1;
10877       else if (unformat (line_input, "next-ip6"))
10878         protocol = 2;
10879       else if (unformat (line_input, "next-ethernet"))
10880         protocol = 3;
10881       else if (unformat (line_input, "next-nsh"))
10882         protocol = 4;
10883       else
10884         {
10885           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10886           return -99;
10887         }
10888     }
10889
10890   if (local_set == 0)
10891     {
10892       errmsg ("tunnel local address not specified\n");
10893       return -99;
10894     }
10895   if (remote_set == 0)
10896     {
10897       errmsg ("tunnel remote address not specified\n");
10898       return -99;
10899     }
10900   if (ipv4_set && ipv6_set)
10901     {
10902       errmsg ("both IPv4 and IPv6 addresses specified");
10903       return -99;
10904     }
10905
10906   if (vni_set == 0)
10907     {
10908       errmsg ("vni not specified\n");
10909       return -99;
10910     }
10911
10912   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10913
10914
10915   if (ipv6_set)
10916     {
10917       clib_memcpy (&mp->local, &local6, sizeof (local6));
10918       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10919     }
10920   else
10921     {
10922       clib_memcpy (&mp->local, &local4, sizeof (local4));
10923       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10924     }
10925
10926   mp->encap_vrf_id = ntohl (encap_vrf_id);
10927   mp->decap_vrf_id = ntohl (decap_vrf_id);
10928   mp->protocol = ntohl (protocol);
10929   mp->vni = ntohl (vni);
10930   mp->is_add = is_add;
10931   mp->is_ipv6 = ipv6_set;
10932
10933   S;
10934   W;
10935   /* NOTREACHED */
10936   return 0;
10937 }
10938
10939 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10940   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10941 {
10942   vat_main_t *vam = &vat_main;
10943
10944   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10945            ntohl (mp->sw_if_index),
10946            format_ip46_address, &(mp->local[0]),
10947            format_ip46_address, &(mp->remote[0]),
10948            ntohl (mp->vni),
10949            ntohl (mp->protocol),
10950            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10951 }
10952
10953 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10954   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10955 {
10956   vat_main_t *vam = &vat_main;
10957   vat_json_node_t *node = NULL;
10958   struct in_addr ip4;
10959   struct in6_addr ip6;
10960
10961   if (VAT_JSON_ARRAY != vam->json_tree.type)
10962     {
10963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10964       vat_json_init_array (&vam->json_tree);
10965     }
10966   node = vat_json_array_add (&vam->json_tree);
10967
10968   vat_json_init_object (node);
10969   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10970   if (mp->is_ipv6)
10971     {
10972       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10973       vat_json_object_add_ip6 (node, "local", ip6);
10974       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10975       vat_json_object_add_ip6 (node, "remote", ip6);
10976     }
10977   else
10978     {
10979       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10980       vat_json_object_add_ip4 (node, "local", ip4);
10981       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10982       vat_json_object_add_ip4 (node, "remote", ip4);
10983     }
10984   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10985   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10986   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10987   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10988   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10989 }
10990
10991 static int
10992 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10993 {
10994   unformat_input_t *i = vam->input;
10995   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10996   f64 timeout;
10997   u32 sw_if_index;
10998   u8 sw_if_index_set = 0;
10999
11000   /* Parse args required to build the message */
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "sw_if_index %d", &sw_if_index))
11004         sw_if_index_set = 1;
11005       else
11006         break;
11007     }
11008
11009   if (sw_if_index_set == 0)
11010     {
11011       sw_if_index = ~0;
11012     }
11013
11014   if (!vam->json_output)
11015     {
11016       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11017                "sw_if_index", "local", "remote", "vni",
11018                "protocol", "encap_vrf_id", "decap_vrf_id");
11019     }
11020
11021   /* Get list of vxlan-tunnel interfaces */
11022   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11023
11024   mp->sw_if_index = htonl (sw_if_index);
11025
11026   S;
11027
11028   /* Use a control ping for synchronization */
11029   {
11030     vl_api_control_ping_t *mp;
11031     M (CONTROL_PING, control_ping);
11032     S;
11033   }
11034   W;
11035 }
11036
11037 u8 *
11038 format_l2_fib_mac_address (u8 * s, va_list * args)
11039 {
11040   u8 *a = va_arg (*args, u8 *);
11041
11042   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11043                  a[2], a[3], a[4], a[5], a[6], a[7]);
11044 }
11045
11046 static void vl_api_l2_fib_table_entry_t_handler
11047   (vl_api_l2_fib_table_entry_t * mp)
11048 {
11049   vat_main_t *vam = &vat_main;
11050
11051   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11052            "       %d       %d     %d\n",
11053            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11054            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11055            mp->bvi_mac);
11056 }
11057
11058 static void vl_api_l2_fib_table_entry_t_handler_json
11059   (vl_api_l2_fib_table_entry_t * mp)
11060 {
11061   vat_main_t *vam = &vat_main;
11062   vat_json_node_t *node = NULL;
11063
11064   if (VAT_JSON_ARRAY != vam->json_tree.type)
11065     {
11066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11067       vat_json_init_array (&vam->json_tree);
11068     }
11069   node = vat_json_array_add (&vam->json_tree);
11070
11071   vat_json_init_object (node);
11072   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11073   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11074   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11075   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11076   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11077   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11078 }
11079
11080 static int
11081 api_l2_fib_table_dump (vat_main_t * vam)
11082 {
11083   unformat_input_t *i = vam->input;
11084   vl_api_l2_fib_table_dump_t *mp;
11085   f64 timeout;
11086   u32 bd_id;
11087   u8 bd_id_set = 0;
11088
11089   /* Parse args required to build the message */
11090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11091     {
11092       if (unformat (i, "bd_id %d", &bd_id))
11093         bd_id_set = 1;
11094       else
11095         break;
11096     }
11097
11098   if (bd_id_set == 0)
11099     {
11100       errmsg ("missing bridge domain\n");
11101       return -99;
11102     }
11103
11104   fformat (vam->ofp,
11105            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11106
11107   /* Get list of l2 fib entries */
11108   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11109
11110   mp->bd_id = ntohl (bd_id);
11111   S;
11112
11113   /* Use a control ping for synchronization */
11114   {
11115     vl_api_control_ping_t *mp;
11116     M (CONTROL_PING, control_ping);
11117     S;
11118   }
11119   W;
11120 }
11121
11122
11123 static int
11124 api_interface_name_renumber (vat_main_t * vam)
11125 {
11126   unformat_input_t *line_input = vam->input;
11127   vl_api_interface_name_renumber_t *mp;
11128   u32 sw_if_index = ~0;
11129   f64 timeout;
11130   u32 new_show_dev_instance = ~0;
11131
11132   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11133     {
11134       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11135                     &sw_if_index))
11136         ;
11137       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11138         ;
11139       else if (unformat (line_input, "new_show_dev_instance %d",
11140                          &new_show_dev_instance))
11141         ;
11142       else
11143         break;
11144     }
11145
11146   if (sw_if_index == ~0)
11147     {
11148       errmsg ("missing interface name or sw_if_index\n");
11149       return -99;
11150     }
11151
11152   if (new_show_dev_instance == ~0)
11153     {
11154       errmsg ("missing new_show_dev_instance\n");
11155       return -99;
11156     }
11157
11158   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11159
11160   mp->sw_if_index = ntohl (sw_if_index);
11161   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11162
11163   S;
11164   W;
11165 }
11166
11167 static int
11168 api_want_ip4_arp_events (vat_main_t * vam)
11169 {
11170   unformat_input_t *line_input = vam->input;
11171   vl_api_want_ip4_arp_events_t *mp;
11172   f64 timeout;
11173   ip4_address_t address;
11174   int address_set = 0;
11175   u32 enable_disable = 1;
11176
11177   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11180         address_set = 1;
11181       else if (unformat (line_input, "del"))
11182         enable_disable = 0;
11183       else
11184         break;
11185     }
11186
11187   if (address_set == 0)
11188     {
11189       errmsg ("missing addresses\n");
11190       return -99;
11191     }
11192
11193   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11194   mp->enable_disable = enable_disable;
11195   mp->pid = getpid ();
11196   mp->address = address.as_u32;
11197
11198   S;
11199   W;
11200 }
11201
11202 static int
11203 api_want_ip6_nd_events (vat_main_t * vam)
11204 {
11205   unformat_input_t *line_input = vam->input;
11206   vl_api_want_ip6_nd_events_t *mp;
11207   f64 timeout;
11208   ip6_address_t address;
11209   int address_set = 0;
11210   u32 enable_disable = 1;
11211
11212   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11213     {
11214       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11215         address_set = 1;
11216       else if (unformat (line_input, "del"))
11217         enable_disable = 0;
11218       else
11219         break;
11220     }
11221
11222   if (address_set == 0)
11223     {
11224       errmsg ("missing addresses\n");
11225       return -99;
11226     }
11227
11228   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11229   mp->enable_disable = enable_disable;
11230   mp->pid = getpid ();
11231   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11232
11233   S;
11234   W;
11235 }
11236
11237 static int
11238 api_input_acl_set_interface (vat_main_t * vam)
11239 {
11240   unformat_input_t *i = vam->input;
11241   vl_api_input_acl_set_interface_t *mp;
11242   f64 timeout;
11243   u32 sw_if_index;
11244   int sw_if_index_set;
11245   u32 ip4_table_index = ~0;
11246   u32 ip6_table_index = ~0;
11247   u32 l2_table_index = ~0;
11248   u8 is_add = 1;
11249
11250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11251     {
11252       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11253         sw_if_index_set = 1;
11254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11255         sw_if_index_set = 1;
11256       else if (unformat (i, "del"))
11257         is_add = 0;
11258       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11259         ;
11260       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11261         ;
11262       else if (unformat (i, "l2-table %d", &l2_table_index))
11263         ;
11264       else
11265         {
11266           clib_warning ("parse error '%U'", format_unformat_error, i);
11267           return -99;
11268         }
11269     }
11270
11271   if (sw_if_index_set == 0)
11272     {
11273       errmsg ("missing interface name or sw_if_index\n");
11274       return -99;
11275     }
11276
11277   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11278
11279   mp->sw_if_index = ntohl (sw_if_index);
11280   mp->ip4_table_index = ntohl (ip4_table_index);
11281   mp->ip6_table_index = ntohl (ip6_table_index);
11282   mp->l2_table_index = ntohl (l2_table_index);
11283   mp->is_add = is_add;
11284
11285   S;
11286   W;
11287   /* NOTREACHED */
11288   return 0;
11289 }
11290
11291 static int
11292 api_ip_address_dump (vat_main_t * vam)
11293 {
11294   unformat_input_t *i = vam->input;
11295   vl_api_ip_address_dump_t *mp;
11296   u32 sw_if_index = ~0;
11297   u8 sw_if_index_set = 0;
11298   u8 ipv4_set = 0;
11299   u8 ipv6_set = 0;
11300   f64 timeout;
11301
11302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11303     {
11304       if (unformat (i, "sw_if_index %d", &sw_if_index))
11305         sw_if_index_set = 1;
11306       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11307         sw_if_index_set = 1;
11308       else if (unformat (i, "ipv4"))
11309         ipv4_set = 1;
11310       else if (unformat (i, "ipv6"))
11311         ipv6_set = 1;
11312       else
11313         break;
11314     }
11315
11316   if (ipv4_set && ipv6_set)
11317     {
11318       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11319       return -99;
11320     }
11321
11322   if ((!ipv4_set) && (!ipv6_set))
11323     {
11324       errmsg ("no ipv4 nor ipv6 flag set\n");
11325       return -99;
11326     }
11327
11328   if (sw_if_index_set == 0)
11329     {
11330       errmsg ("missing interface name or sw_if_index\n");
11331       return -99;
11332     }
11333
11334   vam->current_sw_if_index = sw_if_index;
11335   vam->is_ipv6 = ipv6_set;
11336
11337   M (IP_ADDRESS_DUMP, ip_address_dump);
11338   mp->sw_if_index = ntohl (sw_if_index);
11339   mp->is_ipv6 = ipv6_set;
11340   S;
11341
11342   /* Use a control ping for synchronization */
11343   {
11344     vl_api_control_ping_t *mp;
11345     M (CONTROL_PING, control_ping);
11346     S;
11347   }
11348   W;
11349 }
11350
11351 static int
11352 api_ip_dump (vat_main_t * vam)
11353 {
11354   vl_api_ip_dump_t *mp;
11355   unformat_input_t *in = vam->input;
11356   int ipv4_set = 0;
11357   int ipv6_set = 0;
11358   int is_ipv6;
11359   f64 timeout;
11360   int i;
11361
11362   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11363     {
11364       if (unformat (in, "ipv4"))
11365         ipv4_set = 1;
11366       else if (unformat (in, "ipv6"))
11367         ipv6_set = 1;
11368       else
11369         break;
11370     }
11371
11372   if (ipv4_set && ipv6_set)
11373     {
11374       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11375       return -99;
11376     }
11377
11378   if ((!ipv4_set) && (!ipv6_set))
11379     {
11380       errmsg ("no ipv4 nor ipv6 flag set\n");
11381       return -99;
11382     }
11383
11384   is_ipv6 = ipv6_set;
11385   vam->is_ipv6 = is_ipv6;
11386
11387   /* free old data */
11388   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11389     {
11390       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11391     }
11392   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11393
11394   M (IP_DUMP, ip_dump);
11395   mp->is_ipv6 = ipv6_set;
11396   S;
11397
11398   /* Use a control ping for synchronization */
11399   {
11400     vl_api_control_ping_t *mp;
11401     M (CONTROL_PING, control_ping);
11402     S;
11403   }
11404   W;
11405 }
11406
11407 static int
11408 api_ipsec_spd_add_del (vat_main_t * vam)
11409 {
11410   unformat_input_t *i = vam->input;
11411   vl_api_ipsec_spd_add_del_t *mp;
11412   f64 timeout;
11413   u32 spd_id = ~0;
11414   u8 is_add = 1;
11415
11416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11417     {
11418       if (unformat (i, "spd_id %d", &spd_id))
11419         ;
11420       else if (unformat (i, "del"))
11421         is_add = 0;
11422       else
11423         {
11424           clib_warning ("parse error '%U'", format_unformat_error, i);
11425           return -99;
11426         }
11427     }
11428   if (spd_id == ~0)
11429     {
11430       errmsg ("spd_id must be set\n");
11431       return -99;
11432     }
11433
11434   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11435
11436   mp->spd_id = ntohl (spd_id);
11437   mp->is_add = is_add;
11438
11439   S;
11440   W;
11441   /* NOTREACHED */
11442   return 0;
11443 }
11444
11445 static int
11446 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11447 {
11448   unformat_input_t *i = vam->input;
11449   vl_api_ipsec_interface_add_del_spd_t *mp;
11450   f64 timeout;
11451   u32 sw_if_index;
11452   u8 sw_if_index_set = 0;
11453   u32 spd_id = (u32) ~ 0;
11454   u8 is_add = 1;
11455
11456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11457     {
11458       if (unformat (i, "del"))
11459         is_add = 0;
11460       else if (unformat (i, "spd_id %d", &spd_id))
11461         ;
11462       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11463         sw_if_index_set = 1;
11464       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11465         sw_if_index_set = 1;
11466       else
11467         {
11468           clib_warning ("parse error '%U'", format_unformat_error, i);
11469           return -99;
11470         }
11471
11472     }
11473
11474   if (spd_id == (u32) ~ 0)
11475     {
11476       errmsg ("spd_id must be set\n");
11477       return -99;
11478     }
11479
11480   if (sw_if_index_set == 0)
11481     {
11482       errmsg ("missing interface name or sw_if_index\n");
11483       return -99;
11484     }
11485
11486   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11487
11488   mp->spd_id = ntohl (spd_id);
11489   mp->sw_if_index = ntohl (sw_if_index);
11490   mp->is_add = is_add;
11491
11492   S;
11493   W;
11494   /* NOTREACHED */
11495   return 0;
11496 }
11497
11498 static int
11499 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11500 {
11501   unformat_input_t *i = vam->input;
11502   vl_api_ipsec_spd_add_del_entry_t *mp;
11503   f64 timeout;
11504   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11505   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11506   i32 priority = 0;
11507   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11508   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11509   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11510   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11511
11512   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11513   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11514   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11515   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11516   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11517   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11518
11519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11520     {
11521       if (unformat (i, "del"))
11522         is_add = 0;
11523       if (unformat (i, "outbound"))
11524         is_outbound = 1;
11525       if (unformat (i, "inbound"))
11526         is_outbound = 0;
11527       else if (unformat (i, "spd_id %d", &spd_id))
11528         ;
11529       else if (unformat (i, "sa_id %d", &sa_id))
11530         ;
11531       else if (unformat (i, "priority %d", &priority))
11532         ;
11533       else if (unformat (i, "protocol %d", &protocol))
11534         ;
11535       else if (unformat (i, "lport_start %d", &lport_start))
11536         ;
11537       else if (unformat (i, "lport_stop %d", &lport_stop))
11538         ;
11539       else if (unformat (i, "rport_start %d", &rport_start))
11540         ;
11541       else if (unformat (i, "rport_stop %d", &rport_stop))
11542         ;
11543       else
11544         if (unformat
11545             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11546         {
11547           is_ipv6 = 0;
11548           is_ip_any = 0;
11549         }
11550       else
11551         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11552         {
11553           is_ipv6 = 0;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat
11558             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11559         {
11560           is_ipv6 = 0;
11561           is_ip_any = 0;
11562         }
11563       else
11564         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11565         {
11566           is_ipv6 = 0;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat
11571             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11572         {
11573           is_ipv6 = 1;
11574           is_ip_any = 0;
11575         }
11576       else
11577         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11578         {
11579           is_ipv6 = 1;
11580           is_ip_any = 0;
11581         }
11582       else
11583         if (unformat
11584             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11585         {
11586           is_ipv6 = 1;
11587           is_ip_any = 0;
11588         }
11589       else
11590         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11591         {
11592           is_ipv6 = 1;
11593           is_ip_any = 0;
11594         }
11595       else
11596         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11597         {
11598           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11599             {
11600               clib_warning ("unsupported action: 'resolve'");
11601               return -99;
11602             }
11603         }
11604       else
11605         {
11606           clib_warning ("parse error '%U'", format_unformat_error, i);
11607           return -99;
11608         }
11609
11610     }
11611
11612   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11613
11614   mp->spd_id = ntohl (spd_id);
11615   mp->priority = ntohl (priority);
11616   mp->is_outbound = is_outbound;
11617
11618   mp->is_ipv6 = is_ipv6;
11619   if (is_ipv6 || is_ip_any)
11620     {
11621       clib_memcpy (mp->remote_address_start, &raddr6_start,
11622                    sizeof (ip6_address_t));
11623       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11624                    sizeof (ip6_address_t));
11625       clib_memcpy (mp->local_address_start, &laddr6_start,
11626                    sizeof (ip6_address_t));
11627       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11628                    sizeof (ip6_address_t));
11629     }
11630   else
11631     {
11632       clib_memcpy (mp->remote_address_start, &raddr4_start,
11633                    sizeof (ip4_address_t));
11634       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11635                    sizeof (ip4_address_t));
11636       clib_memcpy (mp->local_address_start, &laddr4_start,
11637                    sizeof (ip4_address_t));
11638       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11639                    sizeof (ip4_address_t));
11640     }
11641   mp->protocol = (u8) protocol;
11642   mp->local_port_start = ntohs ((u16) lport_start);
11643   mp->local_port_stop = ntohs ((u16) lport_stop);
11644   mp->remote_port_start = ntohs ((u16) rport_start);
11645   mp->remote_port_stop = ntohs ((u16) rport_stop);
11646   mp->policy = (u8) policy;
11647   mp->sa_id = ntohl (sa_id);
11648   mp->is_add = is_add;
11649   mp->is_ip_any = is_ip_any;
11650   S;
11651   W;
11652   /* NOTREACHED */
11653   return 0;
11654 }
11655
11656 static int
11657 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11658 {
11659   unformat_input_t *i = vam->input;
11660   vl_api_ipsec_sad_add_del_entry_t *mp;
11661   f64 timeout;
11662   u32 sad_id = 0, spi = 0;
11663   u8 *ck = 0, *ik = 0;
11664   u8 is_add = 1;
11665
11666   u8 protocol = IPSEC_PROTOCOL_AH;
11667   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11668   u32 crypto_alg = 0, integ_alg = 0;
11669   ip4_address_t tun_src4;
11670   ip4_address_t tun_dst4;
11671   ip6_address_t tun_src6;
11672   ip6_address_t tun_dst6;
11673
11674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11675     {
11676       if (unformat (i, "del"))
11677         is_add = 0;
11678       else if (unformat (i, "sad_id %d", &sad_id))
11679         ;
11680       else if (unformat (i, "spi %d", &spi))
11681         ;
11682       else if (unformat (i, "esp"))
11683         protocol = IPSEC_PROTOCOL_ESP;
11684       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11685         {
11686           is_tunnel = 1;
11687           is_tunnel_ipv6 = 0;
11688         }
11689       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11690         {
11691           is_tunnel = 1;
11692           is_tunnel_ipv6 = 0;
11693         }
11694       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11695         {
11696           is_tunnel = 1;
11697           is_tunnel_ipv6 = 1;
11698         }
11699       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11700         {
11701           is_tunnel = 1;
11702           is_tunnel_ipv6 = 1;
11703         }
11704       else
11705         if (unformat
11706             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11707         {
11708           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11709               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11710             {
11711               clib_warning ("unsupported crypto-alg: '%U'",
11712                             format_ipsec_crypto_alg, crypto_alg);
11713               return -99;
11714             }
11715         }
11716       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11717         ;
11718       else
11719         if (unformat
11720             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11721         {
11722 #if DPDK_CRYPTO==1
11723           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11724 #else
11725           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11726 #endif
11727               integ_alg >= IPSEC_INTEG_N_ALG)
11728             {
11729               clib_warning ("unsupported integ-alg: '%U'",
11730                             format_ipsec_integ_alg, integ_alg);
11731               return -99;
11732             }
11733         }
11734       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11735         ;
11736       else
11737         {
11738           clib_warning ("parse error '%U'", format_unformat_error, i);
11739           return -99;
11740         }
11741
11742     }
11743
11744 #if DPDK_CRYPTO==1
11745   /*Special cases, aes-gcm-128 encryption */
11746   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11747     {
11748       if (integ_alg != IPSEC_INTEG_ALG_NONE
11749           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11750         {
11751           clib_warning
11752             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11753           return -99;
11754         }
11755       else                      /*set integ-alg internally to aes-gcm-128 */
11756         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11757     }
11758   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11759     {
11760       clib_warning ("unsupported integ-alg: aes-gcm-128");
11761       return -99;
11762     }
11763   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11764     {
11765       clib_warning ("unsupported integ-alg: none");
11766       return -99;
11767     }
11768 #endif
11769
11770
11771   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11772
11773   mp->sad_id = ntohl (sad_id);
11774   mp->is_add = is_add;
11775   mp->protocol = protocol;
11776   mp->spi = ntohl (spi);
11777   mp->is_tunnel = is_tunnel;
11778   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11779   mp->crypto_algorithm = crypto_alg;
11780   mp->integrity_algorithm = integ_alg;
11781   mp->crypto_key_length = vec_len (ck);
11782   mp->integrity_key_length = vec_len (ik);
11783
11784   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11785     mp->crypto_key_length = sizeof (mp->crypto_key);
11786
11787   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11788     mp->integrity_key_length = sizeof (mp->integrity_key);
11789
11790   if (ck)
11791     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11792   if (ik)
11793     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11794
11795   if (is_tunnel)
11796     {
11797       if (is_tunnel_ipv6)
11798         {
11799           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11800                        sizeof (ip6_address_t));
11801           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11802                        sizeof (ip6_address_t));
11803         }
11804       else
11805         {
11806           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11807                        sizeof (ip4_address_t));
11808           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11809                        sizeof (ip4_address_t));
11810         }
11811     }
11812
11813   S;
11814   W;
11815   /* NOTREACHED */
11816   return 0;
11817 }
11818
11819 static int
11820 api_ipsec_sa_set_key (vat_main_t * vam)
11821 {
11822   unformat_input_t *i = vam->input;
11823   vl_api_ipsec_sa_set_key_t *mp;
11824   f64 timeout;
11825   u32 sa_id;
11826   u8 *ck = 0, *ik = 0;
11827
11828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11829     {
11830       if (unformat (i, "sa_id %d", &sa_id))
11831         ;
11832       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11833         ;
11834       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11835         ;
11836       else
11837         {
11838           clib_warning ("parse error '%U'", format_unformat_error, i);
11839           return -99;
11840         }
11841     }
11842
11843   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11844
11845   mp->sa_id = ntohl (sa_id);
11846   mp->crypto_key_length = vec_len (ck);
11847   mp->integrity_key_length = vec_len (ik);
11848
11849   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11850     mp->crypto_key_length = sizeof (mp->crypto_key);
11851
11852   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11853     mp->integrity_key_length = sizeof (mp->integrity_key);
11854
11855   if (ck)
11856     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11857   if (ik)
11858     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11859
11860   S;
11861   W;
11862   /* NOTREACHED */
11863   return 0;
11864 }
11865
11866 static int
11867 api_ikev2_profile_add_del (vat_main_t * vam)
11868 {
11869   unformat_input_t *i = vam->input;
11870   vl_api_ikev2_profile_add_del_t *mp;
11871   f64 timeout;
11872   u8 is_add = 1;
11873   u8 *name = 0;
11874
11875   const char *valid_chars = "a-zA-Z0-9_";
11876
11877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11878     {
11879       if (unformat (i, "del"))
11880         is_add = 0;
11881       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11882         vec_add1 (name, 0);
11883       else
11884         {
11885           errmsg ("parse error '%U'", format_unformat_error, i);
11886           return -99;
11887         }
11888     }
11889
11890   if (!vec_len (name))
11891     {
11892       errmsg ("profile name must be specified");
11893       return -99;
11894     }
11895
11896   if (vec_len (name) > 64)
11897     {
11898       errmsg ("profile name too long");
11899       return -99;
11900     }
11901
11902   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11903
11904   clib_memcpy (mp->name, name, vec_len (name));
11905   mp->is_add = is_add;
11906   vec_free (name);
11907
11908   S;
11909   W;
11910   /* NOTREACHED */
11911   return 0;
11912 }
11913
11914 static int
11915 api_ikev2_profile_set_auth (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   vl_api_ikev2_profile_set_auth_t *mp;
11919   f64 timeout;
11920   u8 *name = 0;
11921   u8 *data = 0;
11922   u32 auth_method = 0;
11923   u8 is_hex = 0;
11924
11925   const char *valid_chars = "a-zA-Z0-9_";
11926
11927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11928     {
11929       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11930         vec_add1 (name, 0);
11931       else if (unformat (i, "auth_method %U",
11932                          unformat_ikev2_auth_method, &auth_method))
11933         ;
11934       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11935         is_hex = 1;
11936       else if (unformat (i, "auth_data %v", &data))
11937         ;
11938       else
11939         {
11940           errmsg ("parse error '%U'", format_unformat_error, i);
11941           return -99;
11942         }
11943     }
11944
11945   if (!vec_len (name))
11946     {
11947       errmsg ("profile name must be specified");
11948       return -99;
11949     }
11950
11951   if (vec_len (name) > 64)
11952     {
11953       errmsg ("profile name too long");
11954       return -99;
11955     }
11956
11957   if (!vec_len (data))
11958     {
11959       errmsg ("auth_data must be specified");
11960       return -99;
11961     }
11962
11963   if (!auth_method)
11964     {
11965       errmsg ("auth_method must be specified");
11966       return -99;
11967     }
11968
11969   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11970
11971   mp->is_hex = is_hex;
11972   mp->auth_method = (u8) auth_method;
11973   mp->data_len = vec_len (data);
11974   clib_memcpy (mp->name, name, vec_len (name));
11975   clib_memcpy (mp->data, data, vec_len (data));
11976   vec_free (name);
11977   vec_free (data);
11978
11979   S;
11980   W;
11981   /* NOTREACHED */
11982   return 0;
11983 }
11984
11985 static int
11986 api_ikev2_profile_set_id (vat_main_t * vam)
11987 {
11988   unformat_input_t *i = vam->input;
11989   vl_api_ikev2_profile_set_id_t *mp;
11990   f64 timeout;
11991   u8 *name = 0;
11992   u8 *data = 0;
11993   u8 is_local = 0;
11994   u32 id_type = 0;
11995   ip4_address_t ip4;
11996
11997   const char *valid_chars = "a-zA-Z0-9_";
11998
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12002         vec_add1 (name, 0);
12003       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12004         ;
12005       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12006         {
12007           data = vec_new (u8, 4);
12008           clib_memcpy (data, ip4.as_u8, 4);
12009         }
12010       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12011         ;
12012       else if (unformat (i, "id_data %v", &data))
12013         ;
12014       else if (unformat (i, "local"))
12015         is_local = 1;
12016       else if (unformat (i, "remote"))
12017         is_local = 0;
12018       else
12019         {
12020           errmsg ("parse error '%U'", format_unformat_error, i);
12021           return -99;
12022         }
12023     }
12024
12025   if (!vec_len (name))
12026     {
12027       errmsg ("profile name must be specified");
12028       return -99;
12029     }
12030
12031   if (vec_len (name) > 64)
12032     {
12033       errmsg ("profile name too long");
12034       return -99;
12035     }
12036
12037   if (!vec_len (data))
12038     {
12039       errmsg ("id_data must be specified");
12040       return -99;
12041     }
12042
12043   if (!id_type)
12044     {
12045       errmsg ("id_type must be specified");
12046       return -99;
12047     }
12048
12049   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12050
12051   mp->is_local = is_local;
12052   mp->id_type = (u8) id_type;
12053   mp->data_len = vec_len (data);
12054   clib_memcpy (mp->name, name, vec_len (name));
12055   clib_memcpy (mp->data, data, vec_len (data));
12056   vec_free (name);
12057   vec_free (data);
12058
12059   S;
12060   W;
12061   /* NOTREACHED */
12062   return 0;
12063 }
12064
12065 static int
12066 api_ikev2_profile_set_ts (vat_main_t * vam)
12067 {
12068   unformat_input_t *i = vam->input;
12069   vl_api_ikev2_profile_set_ts_t *mp;
12070   f64 timeout;
12071   u8 *name = 0;
12072   u8 is_local = 0;
12073   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12074   ip4_address_t start_addr, end_addr;
12075
12076   const char *valid_chars = "a-zA-Z0-9_";
12077
12078   start_addr.as_u32 = 0;
12079   end_addr.as_u32 = (u32) ~ 0;
12080
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12084         vec_add1 (name, 0);
12085       else if (unformat (i, "protocol %d", &proto))
12086         ;
12087       else if (unformat (i, "start_port %d", &start_port))
12088         ;
12089       else if (unformat (i, "end_port %d", &end_port))
12090         ;
12091       else
12092         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12093         ;
12094       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12095         ;
12096       else if (unformat (i, "local"))
12097         is_local = 1;
12098       else if (unformat (i, "remote"))
12099         is_local = 0;
12100       else
12101         {
12102           errmsg ("parse error '%U'", format_unformat_error, i);
12103           return -99;
12104         }
12105     }
12106
12107   if (!vec_len (name))
12108     {
12109       errmsg ("profile name must be specified");
12110       return -99;
12111     }
12112
12113   if (vec_len (name) > 64)
12114     {
12115       errmsg ("profile name too long");
12116       return -99;
12117     }
12118
12119   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12120
12121   mp->is_local = is_local;
12122   mp->proto = (u8) proto;
12123   mp->start_port = (u16) start_port;
12124   mp->end_port = (u16) end_port;
12125   mp->start_addr = start_addr.as_u32;
12126   mp->end_addr = end_addr.as_u32;
12127   clib_memcpy (mp->name, name, vec_len (name));
12128   vec_free (name);
12129
12130   S;
12131   W;
12132   /* NOTREACHED */
12133   return 0;
12134 }
12135
12136 static int
12137 api_ikev2_set_local_key (vat_main_t * vam)
12138 {
12139   unformat_input_t *i = vam->input;
12140   vl_api_ikev2_set_local_key_t *mp;
12141   f64 timeout;
12142   u8 *file = 0;
12143
12144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12145     {
12146       if (unformat (i, "file %v", &file))
12147         vec_add1 (file, 0);
12148       else
12149         {
12150           errmsg ("parse error '%U'", format_unformat_error, i);
12151           return -99;
12152         }
12153     }
12154
12155   if (!vec_len (file))
12156     {
12157       errmsg ("RSA key file must be specified");
12158       return -99;
12159     }
12160
12161   if (vec_len (file) > 256)
12162     {
12163       errmsg ("file name too long");
12164       return -99;
12165     }
12166
12167   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12168
12169   clib_memcpy (mp->key_file, file, vec_len (file));
12170   vec_free (file);
12171
12172   S;
12173   W;
12174   /* NOTREACHED */
12175   return 0;
12176 }
12177
12178 /*
12179  * MAP
12180  */
12181 static int
12182 api_map_add_domain (vat_main_t * vam)
12183 {
12184   unformat_input_t *i = vam->input;
12185   vl_api_map_add_domain_t *mp;
12186   f64 timeout;
12187
12188   ip4_address_t ip4_prefix;
12189   ip6_address_t ip6_prefix;
12190   ip6_address_t ip6_src;
12191   u32 num_m_args = 0;
12192   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12193     0, psid_length = 0;
12194   u8 is_translation = 0;
12195   u32 mtu = 0;
12196   u32 ip6_src_len = 128;
12197
12198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12201                     &ip4_prefix, &ip4_prefix_len))
12202         num_m_args++;
12203       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12204                          &ip6_prefix, &ip6_prefix_len))
12205         num_m_args++;
12206       else
12207         if (unformat
12208             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12209              &ip6_src_len))
12210         num_m_args++;
12211       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12212         num_m_args++;
12213       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12214         num_m_args++;
12215       else if (unformat (i, "psid-offset %d", &psid_offset))
12216         num_m_args++;
12217       else if (unformat (i, "psid-len %d", &psid_length))
12218         num_m_args++;
12219       else if (unformat (i, "mtu %d", &mtu))
12220         num_m_args++;
12221       else if (unformat (i, "map-t"))
12222         is_translation = 1;
12223       else
12224         {
12225           clib_warning ("parse error '%U'", format_unformat_error, i);
12226           return -99;
12227         }
12228     }
12229
12230   if (num_m_args < 3)
12231     {
12232       errmsg ("mandatory argument(s) missing\n");
12233       return -99;
12234     }
12235
12236   /* Construct the API message */
12237   M (MAP_ADD_DOMAIN, map_add_domain);
12238
12239   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12240   mp->ip4_prefix_len = ip4_prefix_len;
12241
12242   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12243   mp->ip6_prefix_len = ip6_prefix_len;
12244
12245   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12246   mp->ip6_src_prefix_len = ip6_src_len;
12247
12248   mp->ea_bits_len = ea_bits_len;
12249   mp->psid_offset = psid_offset;
12250   mp->psid_length = psid_length;
12251   mp->is_translation = is_translation;
12252   mp->mtu = htons (mtu);
12253
12254   /* send it... */
12255   S;
12256
12257   /* Wait for a reply, return good/bad news  */
12258   W;
12259 }
12260
12261 static int
12262 api_map_del_domain (vat_main_t * vam)
12263 {
12264   unformat_input_t *i = vam->input;
12265   vl_api_map_del_domain_t *mp;
12266   f64 timeout;
12267
12268   u32 num_m_args = 0;
12269   u32 index;
12270
12271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12272     {
12273       if (unformat (i, "index %d", &index))
12274         num_m_args++;
12275       else
12276         {
12277           clib_warning ("parse error '%U'", format_unformat_error, i);
12278           return -99;
12279         }
12280     }
12281
12282   if (num_m_args != 1)
12283     {
12284       errmsg ("mandatory argument(s) missing\n");
12285       return -99;
12286     }
12287
12288   /* Construct the API message */
12289   M (MAP_DEL_DOMAIN, map_del_domain);
12290
12291   mp->index = ntohl (index);
12292
12293   /* send it... */
12294   S;
12295
12296   /* Wait for a reply, return good/bad news  */
12297   W;
12298 }
12299
12300 static int
12301 api_map_add_del_rule (vat_main_t * vam)
12302 {
12303   unformat_input_t *i = vam->input;
12304   vl_api_map_add_del_rule_t *mp;
12305   f64 timeout;
12306   u8 is_add = 1;
12307   ip6_address_t ip6_dst;
12308   u32 num_m_args = 0, index, psid = 0;
12309
12310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12311     {
12312       if (unformat (i, "index %d", &index))
12313         num_m_args++;
12314       else if (unformat (i, "psid %d", &psid))
12315         num_m_args++;
12316       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12317         num_m_args++;
12318       else if (unformat (i, "del"))
12319         {
12320           is_add = 0;
12321         }
12322       else
12323         {
12324           clib_warning ("parse error '%U'", format_unformat_error, i);
12325           return -99;
12326         }
12327     }
12328
12329   /* Construct the API message */
12330   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12331
12332   mp->index = ntohl (index);
12333   mp->is_add = is_add;
12334   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12335   mp->psid = ntohs (psid);
12336
12337   /* send it... */
12338   S;
12339
12340   /* Wait for a reply, return good/bad news  */
12341   W;
12342 }
12343
12344 static int
12345 api_map_domain_dump (vat_main_t * vam)
12346 {
12347   vl_api_map_domain_dump_t *mp;
12348   f64 timeout;
12349
12350   /* Construct the API message */
12351   M (MAP_DOMAIN_DUMP, map_domain_dump);
12352
12353   /* send it... */
12354   S;
12355
12356   /* Use a control ping for synchronization */
12357   {
12358     vl_api_control_ping_t *mp;
12359     M (CONTROL_PING, control_ping);
12360     S;
12361   }
12362   W;
12363 }
12364
12365 static int
12366 api_map_rule_dump (vat_main_t * vam)
12367 {
12368   unformat_input_t *i = vam->input;
12369   vl_api_map_rule_dump_t *mp;
12370   f64 timeout;
12371   u32 domain_index = ~0;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "index %u", &domain_index))
12376         ;
12377       else
12378         break;
12379     }
12380
12381   if (domain_index == ~0)
12382     {
12383       clib_warning ("parse error: domain index expected");
12384       return -99;
12385     }
12386
12387   /* Construct the API message */
12388   M (MAP_RULE_DUMP, map_rule_dump);
12389
12390   mp->domain_index = htonl (domain_index);
12391
12392   /* send it... */
12393   S;
12394
12395   /* Use a control ping for synchronization */
12396   {
12397     vl_api_control_ping_t *mp;
12398     M (CONTROL_PING, control_ping);
12399     S;
12400   }
12401   W;
12402 }
12403
12404 static void vl_api_map_add_domain_reply_t_handler
12405   (vl_api_map_add_domain_reply_t * mp)
12406 {
12407   vat_main_t *vam = &vat_main;
12408   i32 retval = ntohl (mp->retval);
12409
12410   if (vam->async_mode)
12411     {
12412       vam->async_errors += (retval < 0);
12413     }
12414   else
12415     {
12416       vam->retval = retval;
12417       vam->result_ready = 1;
12418     }
12419 }
12420
12421 static void vl_api_map_add_domain_reply_t_handler_json
12422   (vl_api_map_add_domain_reply_t * mp)
12423 {
12424   vat_main_t *vam = &vat_main;
12425   vat_json_node_t node;
12426
12427   vat_json_init_object (&node);
12428   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12429   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12430
12431   vat_json_print (vam->ofp, &node);
12432   vat_json_free (&node);
12433
12434   vam->retval = ntohl (mp->retval);
12435   vam->result_ready = 1;
12436 }
12437
12438 static int
12439 api_get_first_msg_id (vat_main_t * vam)
12440 {
12441   vl_api_get_first_msg_id_t *mp;
12442   f64 timeout;
12443   unformat_input_t *i = vam->input;
12444   u8 *name;
12445   u8 name_set = 0;
12446
12447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12448     {
12449       if (unformat (i, "client %s", &name))
12450         name_set = 1;
12451       else
12452         break;
12453     }
12454
12455   if (name_set == 0)
12456     {
12457       errmsg ("missing client name\n");
12458       return -99;
12459     }
12460   vec_add1 (name, 0);
12461
12462   if (vec_len (name) > 63)
12463     {
12464       errmsg ("client name too long\n");
12465       return -99;
12466     }
12467
12468   M (GET_FIRST_MSG_ID, get_first_msg_id);
12469   clib_memcpy (mp->name, name, vec_len (name));
12470   S;
12471   W;
12472   /* NOTREACHED */
12473   return 0;
12474 }
12475
12476 static int
12477 api_cop_interface_enable_disable (vat_main_t * vam)
12478 {
12479   unformat_input_t *line_input = vam->input;
12480   vl_api_cop_interface_enable_disable_t *mp;
12481   f64 timeout;
12482   u32 sw_if_index = ~0;
12483   u8 enable_disable = 1;
12484
12485   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (line_input, "disable"))
12488         enable_disable = 0;
12489       if (unformat (line_input, "enable"))
12490         enable_disable = 1;
12491       else if (unformat (line_input, "%U", unformat_sw_if_index,
12492                          vam, &sw_if_index))
12493         ;
12494       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12495         ;
12496       else
12497         break;
12498     }
12499
12500   if (sw_if_index == ~0)
12501     {
12502       errmsg ("missing interface name or sw_if_index\n");
12503       return -99;
12504     }
12505
12506   /* Construct the API message */
12507   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12508   mp->sw_if_index = ntohl (sw_if_index);
12509   mp->enable_disable = enable_disable;
12510
12511   /* send it... */
12512   S;
12513   /* Wait for the reply */
12514   W;
12515 }
12516
12517 static int
12518 api_cop_whitelist_enable_disable (vat_main_t * vam)
12519 {
12520   unformat_input_t *line_input = vam->input;
12521   vl_api_cop_whitelist_enable_disable_t *mp;
12522   f64 timeout;
12523   u32 sw_if_index = ~0;
12524   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12525   u32 fib_id = 0;
12526
12527   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (line_input, "ip4"))
12530         ip4 = 1;
12531       else if (unformat (line_input, "ip6"))
12532         ip6 = 1;
12533       else if (unformat (line_input, "default"))
12534         default_cop = 1;
12535       else if (unformat (line_input, "%U", unformat_sw_if_index,
12536                          vam, &sw_if_index))
12537         ;
12538       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12539         ;
12540       else if (unformat (line_input, "fib-id %d", &fib_id))
12541         ;
12542       else
12543         break;
12544     }
12545
12546   if (sw_if_index == ~0)
12547     {
12548       errmsg ("missing interface name or sw_if_index\n");
12549       return -99;
12550     }
12551
12552   /* Construct the API message */
12553   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12554   mp->sw_if_index = ntohl (sw_if_index);
12555   mp->fib_id = ntohl (fib_id);
12556   mp->ip4 = ip4;
12557   mp->ip6 = ip6;
12558   mp->default_cop = default_cop;
12559
12560   /* send it... */
12561   S;
12562   /* Wait for the reply */
12563   W;
12564 }
12565
12566 static int
12567 api_get_node_graph (vat_main_t * vam)
12568 {
12569   vl_api_get_node_graph_t *mp;
12570   f64 timeout;
12571
12572   M (GET_NODE_GRAPH, get_node_graph);
12573
12574   /* send it... */
12575   S;
12576   /* Wait for the reply */
12577   W;
12578 }
12579
12580 /* *INDENT-OFF* */
12581 /** Used for parsing LISP eids */
12582 typedef CLIB_PACKED(struct{
12583   u8 addr[16];   /**< eid address */
12584   u32 len;       /**< prefix length if IP */
12585   u8 type;      /**< type of eid */
12586 }) lisp_eid_vat_t;
12587 /* *INDENT-ON* */
12588
12589 static uword
12590 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12591 {
12592   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12593
12594   memset (a, 0, sizeof (a[0]));
12595
12596   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12597     {
12598       a->type = 0;              /* ipv4 type */
12599     }
12600   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12601     {
12602       a->type = 1;              /* ipv6 type */
12603     }
12604   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12605     {
12606       a->type = 2;              /* mac type */
12607     }
12608   else
12609     {
12610       return 0;
12611     }
12612
12613   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12614     {
12615       return 0;
12616     }
12617
12618   return 1;
12619 }
12620
12621 static int
12622 lisp_eid_size_vat (u8 type)
12623 {
12624   switch (type)
12625     {
12626     case 0:
12627       return 4;
12628     case 1:
12629       return 16;
12630     case 2:
12631       return 6;
12632     }
12633   return 0;
12634 }
12635
12636 static void
12637 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12638 {
12639   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12640 }
12641
12642 /* *INDENT-OFF* */
12643 /** Used for transferring locators via VPP API */
12644 typedef CLIB_PACKED(struct
12645 {
12646   u32 sw_if_index; /**< locator sw_if_index */
12647   u8 priority; /**< locator priority */
12648   u8 weight;   /**< locator weight */
12649 }) ls_locator_t;
12650 /* *INDENT-ON* */
12651
12652 static int
12653 api_lisp_add_del_locator_set (vat_main_t * vam)
12654 {
12655   unformat_input_t *input = vam->input;
12656   vl_api_lisp_add_del_locator_set_t *mp;
12657   f64 timeout = ~0;
12658   u8 is_add = 1;
12659   u8 *locator_set_name = NULL;
12660   u8 locator_set_name_set = 0;
12661   ls_locator_t locator, *locators = 0;
12662   u32 sw_if_index, priority, weight;
12663   u32 data_len = 0;
12664
12665   /* Parse args required to build the message */
12666   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12667     {
12668       if (unformat (input, "del"))
12669         {
12670           is_add = 0;
12671         }
12672       else if (unformat (input, "locator-set %s", &locator_set_name))
12673         {
12674           locator_set_name_set = 1;
12675         }
12676       else if (unformat (input, "sw_if_index %u p %u w %u",
12677                          &sw_if_index, &priority, &weight))
12678         {
12679           locator.sw_if_index = htonl (sw_if_index);
12680           locator.priority = priority;
12681           locator.weight = weight;
12682           vec_add1 (locators, locator);
12683         }
12684       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12685                          vam, &sw_if_index, &priority, &weight))
12686         {
12687           locator.sw_if_index = htonl (sw_if_index);
12688           locator.priority = priority;
12689           locator.weight = weight;
12690           vec_add1 (locators, locator);
12691         }
12692       else
12693         break;
12694     }
12695
12696   if (locator_set_name_set == 0)
12697     {
12698       errmsg ("missing locator-set name");
12699       vec_free (locators);
12700       return -99;
12701     }
12702
12703   if (vec_len (locator_set_name) > 64)
12704     {
12705       errmsg ("locator-set name too long\n");
12706       vec_free (locator_set_name);
12707       vec_free (locators);
12708       return -99;
12709     }
12710   vec_add1 (locator_set_name, 0);
12711
12712   data_len = sizeof (ls_locator_t) * vec_len (locators);
12713
12714   /* Construct the API message */
12715   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12716
12717   mp->is_add = is_add;
12718   clib_memcpy (mp->locator_set_name, locator_set_name,
12719                vec_len (locator_set_name));
12720   vec_free (locator_set_name);
12721
12722   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12723   if (locators)
12724     clib_memcpy (mp->locators, locators, data_len);
12725   vec_free (locators);
12726
12727   /* send it... */
12728   S;
12729
12730   /* Wait for a reply... */
12731   W;
12732
12733   /* NOTREACHED */
12734   return 0;
12735 }
12736
12737 static int
12738 api_lisp_add_del_locator (vat_main_t * vam)
12739 {
12740   unformat_input_t *input = vam->input;
12741   vl_api_lisp_add_del_locator_t *mp;
12742   f64 timeout = ~0;
12743   u32 tmp_if_index = ~0;
12744   u32 sw_if_index = ~0;
12745   u8 sw_if_index_set = 0;
12746   u8 sw_if_index_if_name_set = 0;
12747   u32 priority = ~0;
12748   u8 priority_set = 0;
12749   u32 weight = ~0;
12750   u8 weight_set = 0;
12751   u8 is_add = 1;
12752   u8 *locator_set_name = NULL;
12753   u8 locator_set_name_set = 0;
12754
12755   /* Parse args required to build the message */
12756   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12757     {
12758       if (unformat (input, "del"))
12759         {
12760           is_add = 0;
12761         }
12762       else if (unformat (input, "locator-set %s", &locator_set_name))
12763         {
12764           locator_set_name_set = 1;
12765         }
12766       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12767                          &tmp_if_index))
12768         {
12769           sw_if_index_if_name_set = 1;
12770           sw_if_index = tmp_if_index;
12771         }
12772       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12773         {
12774           sw_if_index_set = 1;
12775           sw_if_index = tmp_if_index;
12776         }
12777       else if (unformat (input, "p %d", &priority))
12778         {
12779           priority_set = 1;
12780         }
12781       else if (unformat (input, "w %d", &weight))
12782         {
12783           weight_set = 1;
12784         }
12785       else
12786         break;
12787     }
12788
12789   if (locator_set_name_set == 0)
12790     {
12791       errmsg ("missing locator-set name");
12792       return -99;
12793     }
12794
12795   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12796     {
12797       errmsg ("missing sw_if_index");
12798       vec_free (locator_set_name);
12799       return -99;
12800     }
12801
12802   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12803     {
12804       errmsg ("cannot use both params interface name and sw_if_index");
12805       vec_free (locator_set_name);
12806       return -99;
12807     }
12808
12809   if (priority_set == 0)
12810     {
12811       errmsg ("missing locator-set priority\n");
12812       vec_free (locator_set_name);
12813       return -99;
12814     }
12815
12816   if (weight_set == 0)
12817     {
12818       errmsg ("missing locator-set weight\n");
12819       vec_free (locator_set_name);
12820       return -99;
12821     }
12822
12823   if (vec_len (locator_set_name) > 64)
12824     {
12825       errmsg ("locator-set name too long\n");
12826       vec_free (locator_set_name);
12827       return -99;
12828     }
12829   vec_add1 (locator_set_name, 0);
12830
12831   /* Construct the API message */
12832   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12833
12834   mp->is_add = is_add;
12835   mp->sw_if_index = ntohl (sw_if_index);
12836   mp->priority = priority;
12837   mp->weight = weight;
12838   clib_memcpy (mp->locator_set_name, locator_set_name,
12839                vec_len (locator_set_name));
12840   vec_free (locator_set_name);
12841
12842   /* send it... */
12843   S;
12844
12845   /* Wait for a reply... */
12846   W;
12847
12848   /* NOTREACHED */
12849   return 0;
12850 }
12851
12852 static int
12853 api_lisp_add_del_local_eid (vat_main_t * vam)
12854 {
12855   unformat_input_t *input = vam->input;
12856   vl_api_lisp_add_del_local_eid_t *mp;
12857   f64 timeout = ~0;
12858   u8 is_add = 1;
12859   u8 eid_set = 0;
12860   lisp_eid_vat_t _eid, *eid = &_eid;
12861   u8 *locator_set_name = 0;
12862   u8 locator_set_name_set = 0;
12863   u32 vni = 0;
12864
12865   /* Parse args required to build the message */
12866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12867     {
12868       if (unformat (input, "del"))
12869         {
12870           is_add = 0;
12871         }
12872       else if (unformat (input, "vni %d", &vni))
12873         {
12874           ;
12875         }
12876       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12877         {
12878           eid_set = 1;
12879         }
12880       else if (unformat (input, "locator-set %s", &locator_set_name))
12881         {
12882           locator_set_name_set = 1;
12883         }
12884       else
12885         break;
12886     }
12887
12888   if (locator_set_name_set == 0)
12889     {
12890       errmsg ("missing locator-set name\n");
12891       return -99;
12892     }
12893
12894   if (0 == eid_set)
12895     {
12896       errmsg ("EID address not set!");
12897       vec_free (locator_set_name);
12898       return -99;
12899     }
12900
12901   if (vec_len (locator_set_name) > 64)
12902     {
12903       errmsg ("locator-set name too long\n");
12904       vec_free (locator_set_name);
12905       return -99;
12906     }
12907   vec_add1 (locator_set_name, 0);
12908
12909   /* Construct the API message */
12910   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12911
12912   mp->is_add = is_add;
12913   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12914   mp->eid_type = eid->type;
12915   mp->prefix_len = eid->len;
12916   mp->vni = clib_host_to_net_u32 (vni);
12917   clib_memcpy (mp->locator_set_name, locator_set_name,
12918                vec_len (locator_set_name));
12919
12920   vec_free (locator_set_name);
12921
12922   /* send it... */
12923   S;
12924
12925   /* Wait for a reply... */
12926   W;
12927
12928   /* NOTREACHED */
12929   return 0;
12930 }
12931
12932 /* *INDENT-OFF* */
12933 /** Used for transferring locators via VPP API */
12934 typedef CLIB_PACKED(struct
12935 {
12936   u8 is_ip4; /**< is locator an IPv4 address? */
12937   u8 priority; /**< locator priority */
12938   u8 weight;   /**< locator weight */
12939   u8 addr[16]; /**< IPv4/IPv6 address */
12940 }) rloc_t;
12941 /* *INDENT-ON* */
12942
12943 static int
12944 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12945 {
12946   unformat_input_t *input = vam->input;
12947   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12948   f64 timeout = ~0;
12949   u8 is_add = 1;
12950   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12951   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12952   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12953   u32 action = ~0, p, w;
12954   ip4_address_t rmt_rloc4, lcl_rloc4;
12955   ip6_address_t rmt_rloc6, lcl_rloc6;
12956   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12957
12958   memset (&rloc, 0, sizeof (rloc));
12959
12960   /* Parse args required to build the message */
12961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12962     {
12963       if (unformat (input, "del"))
12964         {
12965           is_add = 0;
12966         }
12967       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12968         {
12969           rmt_eid_set = 1;
12970         }
12971       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12972         {
12973           lcl_eid_set = 1;
12974         }
12975       else if (unformat (input, "p %d w %d", &p, &w))
12976         {
12977           if (!curr_rloc)
12978             {
12979               errmsg ("No RLOC configured for setting priority/weight!");
12980               return -99;
12981             }
12982           curr_rloc->priority = p;
12983           curr_rloc->weight = w;
12984         }
12985       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12986                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12987         {
12988           rloc.is_ip4 = 1;
12989
12990           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12991           rloc.priority = rloc.weight = 0;
12992           vec_add1 (lcl_locs, rloc);
12993
12994           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12995           vec_add1 (rmt_locs, rloc);
12996           /* priority and weight saved in rmt loc */
12997           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12998         }
12999       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13000                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13001         {
13002           rloc.is_ip4 = 0;
13003           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13004           rloc.priority = rloc.weight = 0;
13005           vec_add1 (lcl_locs, rloc);
13006
13007           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13008           vec_add1 (rmt_locs, rloc);
13009           /* priority and weight saved in rmt loc */
13010           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13011         }
13012       else if (unformat (input, "action %d", &action))
13013         {
13014           ;
13015         }
13016       else
13017         {
13018           clib_warning ("parse error '%U'", format_unformat_error, input);
13019           return -99;
13020         }
13021     }
13022
13023   if (!rmt_eid_set)
13024     {
13025       errmsg ("remote eid addresses not set\n");
13026       return -99;
13027     }
13028
13029   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13030     {
13031       errmsg ("eid types don't match\n");
13032       return -99;
13033     }
13034
13035   if (0 == rmt_locs && (u32) ~ 0 == action)
13036     {
13037       errmsg ("action not set for negative mapping\n");
13038       return -99;
13039     }
13040
13041   /* Construct the API message */
13042   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13043
13044   mp->is_add = is_add;
13045   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13046   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13047   mp->eid_type = rmt_eid->type;
13048   mp->rmt_len = rmt_eid->len;
13049   mp->lcl_len = lcl_eid->len;
13050   mp->action = action;
13051
13052   if (0 != rmt_locs && 0 != lcl_locs)
13053     {
13054       mp->loc_num = vec_len (rmt_locs);
13055       clib_memcpy (mp->lcl_locs, lcl_locs,
13056                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13057       clib_memcpy (mp->rmt_locs, rmt_locs,
13058                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13059     }
13060   vec_free (lcl_locs);
13061   vec_free (rmt_locs);
13062
13063   /* send it... */
13064   S;
13065
13066   /* Wait for a reply... */
13067   W;
13068
13069   /* NOTREACHED */
13070   return 0;
13071 }
13072
13073 static int
13074 api_lisp_add_del_map_resolver (vat_main_t * vam)
13075 {
13076   unformat_input_t *input = vam->input;
13077   vl_api_lisp_add_del_map_resolver_t *mp;
13078   f64 timeout = ~0;
13079   u8 is_add = 1;
13080   u8 ipv4_set = 0;
13081   u8 ipv6_set = 0;
13082   ip4_address_t ipv4;
13083   ip6_address_t ipv6;
13084
13085   /* Parse args required to build the message */
13086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13087     {
13088       if (unformat (input, "del"))
13089         {
13090           is_add = 0;
13091         }
13092       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13093         {
13094           ipv4_set = 1;
13095         }
13096       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13097         {
13098           ipv6_set = 1;
13099         }
13100       else
13101         break;
13102     }
13103
13104   if (ipv4_set && ipv6_set)
13105     {
13106       errmsg ("both eid v4 and v6 addresses set\n");
13107       return -99;
13108     }
13109
13110   if (!ipv4_set && !ipv6_set)
13111     {
13112       errmsg ("eid addresses not set\n");
13113       return -99;
13114     }
13115
13116   /* Construct the API message */
13117   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13118
13119   mp->is_add = is_add;
13120   if (ipv6_set)
13121     {
13122       mp->is_ipv6 = 1;
13123       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13124     }
13125   else
13126     {
13127       mp->is_ipv6 = 0;
13128       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13129     }
13130
13131   /* send it... */
13132   S;
13133
13134   /* Wait for a reply... */
13135   W;
13136
13137   /* NOTREACHED */
13138   return 0;
13139 }
13140
13141 static int
13142 api_lisp_gpe_enable_disable (vat_main_t * vam)
13143 {
13144   unformat_input_t *input = vam->input;
13145   vl_api_lisp_gpe_enable_disable_t *mp;
13146   f64 timeout = ~0;
13147   u8 is_set = 0;
13148   u8 is_en = 1;
13149
13150   /* Parse args required to build the message */
13151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13152     {
13153       if (unformat (input, "enable"))
13154         {
13155           is_set = 1;
13156           is_en = 1;
13157         }
13158       else if (unformat (input, "disable"))
13159         {
13160           is_set = 1;
13161           is_en = 0;
13162         }
13163       else
13164         break;
13165     }
13166
13167   if (is_set == 0)
13168     {
13169       errmsg ("Value not set\n");
13170       return -99;
13171     }
13172
13173   /* Construct the API message */
13174   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13175
13176   mp->is_en = is_en;
13177
13178   /* send it... */
13179   S;
13180
13181   /* Wait for a reply... */
13182   W;
13183
13184   /* NOTREACHED */
13185   return 0;
13186 }
13187
13188 static int
13189 api_lisp_enable_disable (vat_main_t * vam)
13190 {
13191   unformat_input_t *input = vam->input;
13192   vl_api_lisp_enable_disable_t *mp;
13193   f64 timeout = ~0;
13194   u8 is_set = 0;
13195   u8 is_en = 0;
13196
13197   /* Parse args required to build the message */
13198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13199     {
13200       if (unformat (input, "enable"))
13201         {
13202           is_set = 1;
13203           is_en = 1;
13204         }
13205       else if (unformat (input, "disable"))
13206         {
13207           is_set = 1;
13208         }
13209       else
13210         break;
13211     }
13212
13213   if (!is_set)
13214     {
13215       errmsg ("Value not set\n");
13216       return -99;
13217     }
13218
13219   /* Construct the API message */
13220   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13221
13222   mp->is_en = is_en;
13223
13224   /* send it... */
13225   S;
13226
13227   /* Wait for a reply... */
13228   W;
13229
13230   /* NOTREACHED */
13231   return 0;
13232 }
13233
13234 static int
13235 api_show_lisp_map_request_mode (vat_main_t * vam)
13236 {
13237   f64 timeout = ~0;
13238   vl_api_show_lisp_map_request_mode_t *mp;
13239
13240   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13241
13242   /* send */
13243   S;
13244
13245   /* wait for reply */
13246   W;
13247
13248   return 0;
13249 }
13250
13251 static int
13252 api_lisp_map_request_mode (vat_main_t * vam)
13253 {
13254   f64 timeout = ~0;
13255   unformat_input_t *input = vam->input;
13256   vl_api_lisp_map_request_mode_t *mp;
13257   u8 mode = 0;
13258
13259   /* Parse args required to build the message */
13260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13261     {
13262       if (unformat (input, "dst-only"))
13263         mode = 0;
13264       else if (unformat (input, "src-dst"))
13265         mode = 1;
13266       else
13267         {
13268           errmsg ("parse error '%U'", format_unformat_error, input);
13269           return -99;
13270         }
13271     }
13272
13273   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13274
13275   mp->mode = mode;
13276
13277   /* send */
13278   S;
13279
13280   /* wait for reply */
13281   W;
13282
13283   /* notreached */
13284   return 0;
13285 }
13286
13287 /**
13288  * Enable/disable LISP proxy ITR.
13289  *
13290  * @param vam vpp API test context
13291  * @return return code
13292  */
13293 static int
13294 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13295 {
13296   f64 timeout = ~0;
13297   u8 ls_name_set = 0;
13298   unformat_input_t *input = vam->input;
13299   vl_api_lisp_pitr_set_locator_set_t *mp;
13300   u8 is_add = 1;
13301   u8 *ls_name = 0;
13302
13303   /* Parse args required to build the message */
13304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13305     {
13306       if (unformat (input, "del"))
13307         is_add = 0;
13308       else if (unformat (input, "locator-set %s", &ls_name))
13309         ls_name_set = 1;
13310       else
13311         {
13312           errmsg ("parse error '%U'", format_unformat_error, input);
13313           return -99;
13314         }
13315     }
13316
13317   if (!ls_name_set)
13318     {
13319       errmsg ("locator-set name not set!");
13320       return -99;
13321     }
13322
13323   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13324
13325   mp->is_add = is_add;
13326   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13327   vec_free (ls_name);
13328
13329   /* send */
13330   S;
13331
13332   /* wait for reply */
13333   W;
13334
13335   /* notreached */
13336   return 0;
13337 }
13338
13339 static int
13340 api_show_lisp_pitr (vat_main_t * vam)
13341 {
13342   vl_api_show_lisp_pitr_t *mp;
13343   f64 timeout = ~0;
13344
13345   if (!vam->json_output)
13346     {
13347       fformat (vam->ofp, "%=20s\n", "lisp status:");
13348     }
13349
13350   M (SHOW_LISP_PITR, show_lisp_pitr);
13351   /* send it... */
13352   S;
13353
13354   /* Wait for a reply... */
13355   W;
13356
13357   /* NOTREACHED */
13358   return 0;
13359 }
13360
13361 /**
13362  * Add/delete mapping between vni and vrf
13363  */
13364 static int
13365 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13366 {
13367   f64 timeout = ~0;
13368   unformat_input_t *input = vam->input;
13369   vl_api_lisp_eid_table_add_del_map_t *mp;
13370   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13371   u32 vni, vrf, bd_index;
13372
13373   /* Parse args required to build the message */
13374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13375     {
13376       if (unformat (input, "del"))
13377         is_add = 0;
13378       else if (unformat (input, "vrf %d", &vrf))
13379         vrf_set = 1;
13380       else if (unformat (input, "bd_index %d", &bd_index))
13381         bd_index_set = 1;
13382       else if (unformat (input, "vni %d", &vni))
13383         vni_set = 1;
13384       else
13385         break;
13386     }
13387
13388   if (!vni_set || (!vrf_set && !bd_index_set))
13389     {
13390       errmsg ("missing arguments!");
13391       return -99;
13392     }
13393
13394   if (vrf_set && bd_index_set)
13395     {
13396       errmsg ("error: both vrf and bd entered!");
13397       return -99;
13398     }
13399
13400   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13401
13402   mp->is_add = is_add;
13403   mp->vni = htonl (vni);
13404   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13405   mp->is_l2 = bd_index_set;
13406
13407   /* send */
13408   S;
13409
13410   /* wait for reply */
13411   W;
13412
13413   /* notreached */
13414   return 0;
13415 }
13416
13417 uword
13418 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13419 {
13420   u32 *action = va_arg (*args, u32 *);
13421   u8 *s = 0;
13422
13423   if (unformat (input, "%s", &s))
13424     {
13425       if (!strcmp ((char *) s, "no-action"))
13426         action[0] = 0;
13427       else if (!strcmp ((char *) s, "natively-forward"))
13428         action[0] = 1;
13429       else if (!strcmp ((char *) s, "send-map-request"))
13430         action[0] = 2;
13431       else if (!strcmp ((char *) s, "drop"))
13432         action[0] = 3;
13433       else
13434         {
13435           clib_warning ("invalid action: '%s'", s);
13436           action[0] = 3;
13437         }
13438     }
13439   else
13440     return 0;
13441
13442   vec_free (s);
13443   return 1;
13444 }
13445
13446 /**
13447  * Add/del remote mapping to/from LISP control plane
13448  *
13449  * @param vam vpp API test context
13450  * @return return code
13451  */
13452 static int
13453 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13454 {
13455   unformat_input_t *input = vam->input;
13456   vl_api_lisp_add_del_remote_mapping_t *mp;
13457   f64 timeout = ~0;
13458   u32 vni = 0;
13459   lisp_eid_vat_t _eid, *eid = &_eid;
13460   lisp_eid_vat_t _seid, *seid = &_seid;
13461   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13462   u32 action = ~0, p, w, data_len;
13463   ip4_address_t rloc4;
13464   ip6_address_t rloc6;
13465   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13466
13467   memset (&rloc, 0, sizeof (rloc));
13468
13469   /* Parse args required to build the message */
13470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13471     {
13472       if (unformat (input, "del-all"))
13473         {
13474           del_all = 1;
13475         }
13476       else if (unformat (input, "del"))
13477         {
13478           is_add = 0;
13479         }
13480       else if (unformat (input, "add"))
13481         {
13482           is_add = 1;
13483         }
13484       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13485         {
13486           eid_set = 1;
13487         }
13488       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13489         {
13490           seid_set = 1;
13491         }
13492       else if (unformat (input, "vni %d", &vni))
13493         {
13494           ;
13495         }
13496       else if (unformat (input, "p %d w %d", &p, &w))
13497         {
13498           if (!curr_rloc)
13499             {
13500               errmsg ("No RLOC configured for setting priority/weight!");
13501               return -99;
13502             }
13503           curr_rloc->priority = p;
13504           curr_rloc->weight = w;
13505         }
13506       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13507         {
13508           rloc.is_ip4 = 1;
13509           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13510           vec_add1 (rlocs, rloc);
13511           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13512         }
13513       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13514         {
13515           rloc.is_ip4 = 0;
13516           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13517           vec_add1 (rlocs, rloc);
13518           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13519         }
13520       else if (unformat (input, "action %U",
13521                          unformat_negative_mapping_action, &action))
13522         {
13523           ;
13524         }
13525       else
13526         {
13527           clib_warning ("parse error '%U'", format_unformat_error, input);
13528           return -99;
13529         }
13530     }
13531
13532   if (0 == eid_set)
13533     {
13534       errmsg ("missing params!");
13535       return -99;
13536     }
13537
13538   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13539     {
13540       errmsg ("no action set for negative map-reply!");
13541       return -99;
13542     }
13543
13544   data_len = vec_len (rlocs) * sizeof (rloc_t);
13545
13546   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13547   mp->is_add = is_add;
13548   mp->vni = htonl (vni);
13549   mp->action = (u8) action;
13550   mp->is_src_dst = seid_set;
13551   mp->eid_len = eid->len;
13552   mp->seid_len = seid->len;
13553   mp->del_all = del_all;
13554   mp->eid_type = eid->type;
13555   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13556   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13557
13558   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13559   clib_memcpy (mp->rlocs, rlocs, data_len);
13560   vec_free (rlocs);
13561
13562   /* send it... */
13563   S;
13564
13565   /* Wait for a reply... */
13566   W;
13567
13568   /* NOTREACHED */
13569   return 0;
13570 }
13571
13572 /**
13573  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13574  * forwarding entries in data-plane accordingly.
13575  *
13576  * @param vam vpp API test context
13577  * @return return code
13578  */
13579 static int
13580 api_lisp_add_del_adjacency (vat_main_t * vam)
13581 {
13582   unformat_input_t *input = vam->input;
13583   vl_api_lisp_add_del_adjacency_t *mp;
13584   f64 timeout = ~0;
13585   u32 vni = 0;
13586   ip4_address_t leid4, reid4;
13587   ip6_address_t leid6, reid6;
13588   u8 reid_mac[6] = { 0 };
13589   u8 leid_mac[6] = { 0 };
13590   u8 reid_type, leid_type;
13591   u32 leid_len = 0, reid_len = 0, len;
13592   u8 is_add = 1;
13593
13594   leid_type = reid_type = (u8) ~ 0;
13595
13596   /* Parse args required to build the message */
13597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13598     {
13599       if (unformat (input, "del"))
13600         {
13601           is_add = 0;
13602         }
13603       else if (unformat (input, "add"))
13604         {
13605           is_add = 1;
13606         }
13607       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13608                          &reid4, &len))
13609         {
13610           reid_type = 0;        /* ipv4 */
13611           reid_len = len;
13612         }
13613       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13614                          &reid6, &len))
13615         {
13616           reid_type = 1;        /* ipv6 */
13617           reid_len = len;
13618         }
13619       else if (unformat (input, "reid %U", unformat_ethernet_address,
13620                          reid_mac))
13621         {
13622           reid_type = 2;        /* mac */
13623         }
13624       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13625                          &leid4, &len))
13626         {
13627           leid_type = 0;        /* ipv4 */
13628           leid_len = len;
13629         }
13630       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13631                          &leid6, &len))
13632         {
13633           leid_type = 1;        /* ipv6 */
13634           leid_len = len;
13635         }
13636       else if (unformat (input, "leid %U", unformat_ethernet_address,
13637                          leid_mac))
13638         {
13639           leid_type = 2;        /* mac */
13640         }
13641       else if (unformat (input, "vni %d", &vni))
13642         {
13643           ;
13644         }
13645       else
13646         {
13647           errmsg ("parse error '%U'", format_unformat_error, input);
13648           return -99;
13649         }
13650     }
13651
13652   if ((u8) ~ 0 == reid_type)
13653     {
13654       errmsg ("missing params!");
13655       return -99;
13656     }
13657
13658   if (leid_type != reid_type)
13659     {
13660       errmsg ("remote and local EIDs are of different types!");
13661       return -99;
13662     }
13663
13664   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13665   mp->is_add = is_add;
13666   mp->vni = htonl (vni);
13667   mp->leid_len = leid_len;
13668   mp->reid_len = reid_len;
13669   mp->eid_type = reid_type;
13670
13671   switch (mp->eid_type)
13672     {
13673     case 0:
13674       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13675       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13676       break;
13677     case 1:
13678       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13679       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13680       break;
13681     case 2:
13682       clib_memcpy (mp->leid, leid_mac, 6);
13683       clib_memcpy (mp->reid, reid_mac, 6);
13684       break;
13685     default:
13686       errmsg ("unknown EID type %d!", mp->eid_type);
13687       return 0;
13688     }
13689
13690   /* send it... */
13691   S;
13692
13693   /* Wait for a reply... */
13694   W;
13695
13696   /* NOTREACHED */
13697   return 0;
13698 }
13699
13700 static int
13701 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13702 {
13703   unformat_input_t *input = vam->input;
13704   vl_api_lisp_gpe_add_del_iface_t *mp;
13705   f64 timeout = ~0;
13706   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13707   u32 dp_table = 0, vni = 0;
13708
13709   /* Parse args required to build the message */
13710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (input, "up"))
13713         {
13714           action_set = 1;
13715           is_add = 1;
13716         }
13717       else if (unformat (input, "down"))
13718         {
13719           action_set = 1;
13720           is_add = 0;
13721         }
13722       else if (unformat (input, "table_id %d", &dp_table))
13723         {
13724           dp_table_set = 1;
13725         }
13726       else if (unformat (input, "bd_id %d", &dp_table))
13727         {
13728           dp_table_set = 1;
13729           is_l2 = 1;
13730         }
13731       else if (unformat (input, "vni %d", &vni))
13732         {
13733           vni_set = 1;
13734         }
13735       else
13736         break;
13737     }
13738
13739   if (action_set == 0)
13740     {
13741       errmsg ("Action not set\n");
13742       return -99;
13743     }
13744   if (dp_table_set == 0 || vni_set == 0)
13745     {
13746       errmsg ("vni and dp_table must be set\n");
13747       return -99;
13748     }
13749
13750   /* Construct the API message */
13751   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13752
13753   mp->is_add = is_add;
13754   mp->dp_table = dp_table;
13755   mp->is_l2 = is_l2;
13756   mp->vni = vni;
13757
13758   /* send it... */
13759   S;
13760
13761   /* Wait for a reply... */
13762   W;
13763
13764   /* NOTREACHED */
13765   return 0;
13766 }
13767
13768 /**
13769  * Add/del map request itr rlocs from LISP control plane and updates
13770  *
13771  * @param vam vpp API test context
13772  * @return return code
13773  */
13774 static int
13775 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13776 {
13777   unformat_input_t *input = vam->input;
13778   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13779   f64 timeout = ~0;
13780   u8 *locator_set_name = 0;
13781   u8 locator_set_name_set = 0;
13782   u8 is_add = 1;
13783
13784   /* Parse args required to build the message */
13785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13786     {
13787       if (unformat (input, "del"))
13788         {
13789           is_add = 0;
13790         }
13791       else if (unformat (input, "%_%v%_", &locator_set_name))
13792         {
13793           locator_set_name_set = 1;
13794         }
13795       else
13796         {
13797           clib_warning ("parse error '%U'", format_unformat_error, input);
13798           return -99;
13799         }
13800     }
13801
13802   if (is_add && !locator_set_name_set)
13803     {
13804       errmsg ("itr-rloc is not set!");
13805       return -99;
13806     }
13807
13808   if (is_add && vec_len (locator_set_name) > 64)
13809     {
13810       errmsg ("itr-rloc locator-set name too long\n");
13811       vec_free (locator_set_name);
13812       return -99;
13813     }
13814
13815   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13816   mp->is_add = is_add;
13817   if (is_add)
13818     {
13819       clib_memcpy (mp->locator_set_name, locator_set_name,
13820                    vec_len (locator_set_name));
13821     }
13822   else
13823     {
13824       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13825     }
13826   vec_free (locator_set_name);
13827
13828   /* send it... */
13829   S;
13830
13831   /* Wait for a reply... */
13832   W;
13833
13834   /* NOTREACHED */
13835   return 0;
13836 }
13837
13838 static int
13839 api_lisp_locator_dump (vat_main_t * vam)
13840 {
13841   unformat_input_t *input = vam->input;
13842   vl_api_lisp_locator_dump_t *mp;
13843   f64 timeout = ~0;
13844   u8 is_index_set = 0, is_name_set = 0;
13845   u8 *ls_name = 0;
13846   u32 ls_index = ~0;
13847
13848   /* Parse args required to build the message */
13849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13850     {
13851       if (unformat (input, "ls_name %_%v%_", &ls_name))
13852         {
13853           is_name_set = 1;
13854         }
13855       else if (unformat (input, "ls_index %d", &ls_index))
13856         {
13857           is_index_set = 1;
13858         }
13859       else
13860         {
13861           errmsg ("parse error '%U'", format_unformat_error, input);
13862           return -99;
13863         }
13864     }
13865
13866   if (!is_index_set && !is_name_set)
13867     {
13868       errmsg ("error: expected one of index or name!\n");
13869       return -99;
13870     }
13871
13872   if (is_index_set && is_name_set)
13873     {
13874       errmsg ("error: only one param expected!\n");
13875       return -99;
13876     }
13877
13878   if (vec_len (ls_name) > 62)
13879     {
13880       errmsg ("error: locator set name too long!");
13881       return -99;
13882     }
13883
13884   if (!vam->json_output)
13885     {
13886       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13887                "weight");
13888     }
13889
13890   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13891   mp->is_index_set = is_index_set;
13892
13893   if (is_index_set)
13894     mp->ls_index = clib_host_to_net_u32 (ls_index);
13895   else
13896     {
13897       vec_add1 (ls_name, 0);
13898       strncpy ((char *) mp->ls_name, (char *) ls_name,
13899                sizeof (mp->ls_name) - 1);
13900     }
13901
13902   /* send it... */
13903   S;
13904
13905   /* Use a control ping for synchronization */
13906   {
13907     vl_api_control_ping_t *mp;
13908     M (CONTROL_PING, control_ping);
13909     S;
13910   }
13911   /* Wait for a reply... */
13912   W;
13913
13914   /* NOTREACHED */
13915   return 0;
13916 }
13917
13918 static int
13919 api_lisp_locator_set_dump (vat_main_t * vam)
13920 {
13921   vl_api_lisp_locator_set_dump_t *mp;
13922   unformat_input_t *input = vam->input;
13923   f64 timeout = ~0;
13924   u8 filter = 0;
13925
13926   /* Parse args required to build the message */
13927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (input, "local"))
13930         {
13931           filter = 1;
13932         }
13933       else if (unformat (input, "remote"))
13934         {
13935           filter = 2;
13936         }
13937       else
13938         {
13939           errmsg ("parse error '%U'", format_unformat_error, input);
13940           return -99;
13941         }
13942     }
13943
13944   if (!vam->json_output)
13945     {
13946       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13947     }
13948
13949   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13950
13951   mp->filter = filter;
13952
13953   /* send it... */
13954   S;
13955
13956   /* Use a control ping for synchronization */
13957   {
13958     vl_api_control_ping_t *mp;
13959     M (CONTROL_PING, control_ping);
13960     S;
13961   }
13962   /* Wait for a reply... */
13963   W;
13964
13965   /* NOTREACHED */
13966   return 0;
13967 }
13968
13969 static int
13970 api_lisp_eid_table_map_dump (vat_main_t * vam)
13971 {
13972   u8 is_l2 = 0;
13973   u8 mode_set = 0;
13974   unformat_input_t *input = vam->input;
13975   vl_api_lisp_eid_table_map_dump_t *mp;
13976   f64 timeout = ~0;
13977
13978   /* Parse args required to build the message */
13979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13980     {
13981       if (unformat (input, "l2"))
13982         {
13983           is_l2 = 1;
13984           mode_set = 1;
13985         }
13986       else if (unformat (input, "l3"))
13987         {
13988           is_l2 = 0;
13989           mode_set = 1;
13990         }
13991       else
13992         {
13993           errmsg ("parse error '%U'", format_unformat_error, input);
13994           return -99;
13995         }
13996     }
13997
13998   if (!mode_set)
13999     {
14000       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14001       return -99;
14002     }
14003
14004   if (!vam->json_output)
14005     {
14006       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14007     }
14008
14009   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14010   mp->is_l2 = is_l2;
14011
14012   /* send it... */
14013   S;
14014
14015   /* Use a control ping for synchronization */
14016   {
14017     vl_api_control_ping_t *mp;
14018     M (CONTROL_PING, control_ping);
14019     S;
14020   }
14021   /* Wait for a reply... */
14022   W;
14023
14024   /* NOTREACHED */
14025   return 0;
14026 }
14027
14028 static int
14029 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14030 {
14031   vl_api_lisp_eid_table_vni_dump_t *mp;
14032   f64 timeout = ~0;
14033
14034   if (!vam->json_output)
14035     {
14036       fformat (vam->ofp, "VNI\n");
14037     }
14038
14039   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14040
14041   /* send it... */
14042   S;
14043
14044   /* Use a control ping for synchronization */
14045   {
14046     vl_api_control_ping_t *mp;
14047     M (CONTROL_PING, control_ping);
14048     S;
14049   }
14050   /* Wait for a reply... */
14051   W;
14052
14053   /* NOTREACHED */
14054   return 0;
14055 }
14056
14057 static int
14058 api_lisp_eid_table_dump (vat_main_t * vam)
14059 {
14060   unformat_input_t *i = vam->input;
14061   vl_api_lisp_eid_table_dump_t *mp;
14062   f64 timeout = ~0;
14063   struct in_addr ip4;
14064   struct in6_addr ip6;
14065   u8 mac[6];
14066   u8 eid_type = ~0, eid_set = 0;
14067   u32 prefix_length = ~0, t, vni = 0;
14068   u8 filter = 0;
14069
14070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14071     {
14072       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14073         {
14074           eid_set = 1;
14075           eid_type = 0;
14076           prefix_length = t;
14077         }
14078       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14079         {
14080           eid_set = 1;
14081           eid_type = 1;
14082           prefix_length = t;
14083         }
14084       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14085         {
14086           eid_set = 1;
14087           eid_type = 2;
14088         }
14089       else if (unformat (i, "vni %d", &t))
14090         {
14091           vni = t;
14092         }
14093       else if (unformat (i, "local"))
14094         {
14095           filter = 1;
14096         }
14097       else if (unformat (i, "remote"))
14098         {
14099           filter = 2;
14100         }
14101       else
14102         {
14103           errmsg ("parse error '%U'", format_unformat_error, i);
14104           return -99;
14105         }
14106     }
14107
14108   if (!vam->json_output)
14109     {
14110       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14111                "ls_index", "ttl", "authoritative");
14112     }
14113
14114   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14115
14116   mp->filter = filter;
14117   if (eid_set)
14118     {
14119       mp->eid_set = 1;
14120       mp->vni = htonl (vni);
14121       mp->eid_type = eid_type;
14122       switch (eid_type)
14123         {
14124         case 0:
14125           mp->prefix_length = prefix_length;
14126           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14127           break;
14128         case 1:
14129           mp->prefix_length = prefix_length;
14130           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14131           break;
14132         case 2:
14133           clib_memcpy (mp->eid, mac, sizeof (mac));
14134           break;
14135         default:
14136           errmsg ("unknown EID type %d!", eid_type);
14137           return -99;
14138         }
14139     }
14140
14141   /* send it... */
14142   S;
14143
14144   /* Use a control ping for synchronization */
14145   {
14146     vl_api_control_ping_t *mp;
14147     M (CONTROL_PING, control_ping);
14148     S;
14149   }
14150
14151   /* Wait for a reply... */
14152   W;
14153
14154   /* NOTREACHED */
14155   return 0;
14156 }
14157
14158 static int
14159 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14160 {
14161   vl_api_lisp_gpe_tunnel_dump_t *mp;
14162   f64 timeout = ~0;
14163
14164   if (!vam->json_output)
14165     {
14166       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14167                "%=16s%=16s%=16s%=16s%=16s\n",
14168                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14169                "Decap next", "Lisp version", "Flags", "Next protocol",
14170                "ver_res", "res", "iid");
14171     }
14172
14173   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14174   /* send it... */
14175   S;
14176
14177   /* Use a control ping for synchronization */
14178   {
14179     vl_api_control_ping_t *mp;
14180     M (CONTROL_PING, control_ping);
14181     S;
14182   }
14183   /* Wait for a reply... */
14184   W;
14185
14186   /* NOTREACHED */
14187   return 0;
14188 }
14189
14190 static int
14191 api_lisp_adjacencies_get (vat_main_t * vam)
14192 {
14193   unformat_input_t *i = vam->input;
14194   vl_api_lisp_adjacencies_get_t *mp;
14195   f64 timeout = ~0;
14196   u8 vni_set = 0;
14197   u32 vni = ~0;
14198
14199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14200     {
14201       if (unformat (i, "vni %d", &vni))
14202         {
14203           vni_set = 1;
14204         }
14205       else
14206         {
14207           errmsg ("parse error '%U'\n", format_unformat_error, i);
14208           return -99;
14209         }
14210     }
14211
14212   if (!vni_set)
14213     {
14214       errmsg ("vni not set!\n");
14215       return -99;
14216     }
14217
14218   if (!vam->json_output)
14219     {
14220       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14221     }
14222
14223   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14224   mp->vni = clib_host_to_net_u32 (vni);
14225
14226   /* send it... */
14227   S;
14228
14229   /* Wait for a reply... */
14230   W;
14231
14232   /* NOTREACHED */
14233   return 0;
14234 }
14235
14236 static int
14237 api_lisp_map_resolver_dump (vat_main_t * vam)
14238 {
14239   vl_api_lisp_map_resolver_dump_t *mp;
14240   f64 timeout = ~0;
14241
14242   if (!vam->json_output)
14243     {
14244       fformat (vam->ofp, "%=20s\n", "Map resolver");
14245     }
14246
14247   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14248   /* send it... */
14249   S;
14250
14251   /* Use a control ping for synchronization */
14252   {
14253     vl_api_control_ping_t *mp;
14254     M (CONTROL_PING, control_ping);
14255     S;
14256   }
14257   /* Wait for a reply... */
14258   W;
14259
14260   /* NOTREACHED */
14261   return 0;
14262 }
14263
14264 static int
14265 api_show_lisp_status (vat_main_t * vam)
14266 {
14267   vl_api_show_lisp_status_t *mp;
14268   f64 timeout = ~0;
14269
14270   if (!vam->json_output)
14271     {
14272       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14273     }
14274
14275   M (SHOW_LISP_STATUS, show_lisp_status);
14276   /* send it... */
14277   S;
14278   /* Wait for a reply... */
14279   W;
14280
14281   /* NOTREACHED */
14282   return 0;
14283 }
14284
14285 static int
14286 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14287 {
14288   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14289   f64 timeout = ~0;
14290
14291   if (!vam->json_output)
14292     {
14293       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14294     }
14295
14296   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14297   /* send it... */
14298   S;
14299   /* Wait for a reply... */
14300   W;
14301
14302   /* NOTREACHED */
14303   return 0;
14304 }
14305
14306 static int
14307 api_af_packet_create (vat_main_t * vam)
14308 {
14309   unformat_input_t *i = vam->input;
14310   vl_api_af_packet_create_t *mp;
14311   f64 timeout;
14312   u8 *host_if_name = 0;
14313   u8 hw_addr[6];
14314   u8 random_hw_addr = 1;
14315
14316   memset (hw_addr, 0, sizeof (hw_addr));
14317
14318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14319     {
14320       if (unformat (i, "name %s", &host_if_name))
14321         vec_add1 (host_if_name, 0);
14322       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14323         random_hw_addr = 0;
14324       else
14325         break;
14326     }
14327
14328   if (!vec_len (host_if_name))
14329     {
14330       errmsg ("host-interface name must be specified");
14331       return -99;
14332     }
14333
14334   if (vec_len (host_if_name) > 64)
14335     {
14336       errmsg ("host-interface name too long");
14337       return -99;
14338     }
14339
14340   M (AF_PACKET_CREATE, af_packet_create);
14341
14342   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14343   clib_memcpy (mp->hw_addr, hw_addr, 6);
14344   mp->use_random_hw_addr = random_hw_addr;
14345   vec_free (host_if_name);
14346
14347   S;
14348   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14349   /* NOTREACHED */
14350   return 0;
14351 }
14352
14353 static int
14354 api_af_packet_delete (vat_main_t * vam)
14355 {
14356   unformat_input_t *i = vam->input;
14357   vl_api_af_packet_delete_t *mp;
14358   f64 timeout;
14359   u8 *host_if_name = 0;
14360
14361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14362     {
14363       if (unformat (i, "name %s", &host_if_name))
14364         vec_add1 (host_if_name, 0);
14365       else
14366         break;
14367     }
14368
14369   if (!vec_len (host_if_name))
14370     {
14371       errmsg ("host-interface name must be specified");
14372       return -99;
14373     }
14374
14375   if (vec_len (host_if_name) > 64)
14376     {
14377       errmsg ("host-interface name too long");
14378       return -99;
14379     }
14380
14381   M (AF_PACKET_DELETE, af_packet_delete);
14382
14383   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14384   vec_free (host_if_name);
14385
14386   S;
14387   W;
14388   /* NOTREACHED */
14389   return 0;
14390 }
14391
14392 static int
14393 api_policer_add_del (vat_main_t * vam)
14394 {
14395   unformat_input_t *i = vam->input;
14396   vl_api_policer_add_del_t *mp;
14397   f64 timeout;
14398   u8 is_add = 1;
14399   u8 *name = 0;
14400   u32 cir = 0;
14401   u32 eir = 0;
14402   u64 cb = 0;
14403   u64 eb = 0;
14404   u8 rate_type = 0;
14405   u8 round_type = 0;
14406   u8 type = 0;
14407   u8 color_aware = 0;
14408   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14409
14410   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14411   conform_action.dscp = 0;
14412   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14413   exceed_action.dscp = 0;
14414   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14415   violate_action.dscp = 0;
14416
14417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14418     {
14419       if (unformat (i, "del"))
14420         is_add = 0;
14421       else if (unformat (i, "name %s", &name))
14422         vec_add1 (name, 0);
14423       else if (unformat (i, "cir %u", &cir))
14424         ;
14425       else if (unformat (i, "eir %u", &eir))
14426         ;
14427       else if (unformat (i, "cb %u", &cb))
14428         ;
14429       else if (unformat (i, "eb %u", &eb))
14430         ;
14431       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14432                          &rate_type))
14433         ;
14434       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14435                          &round_type))
14436         ;
14437       else if (unformat (i, "type %U", unformat_policer_type, &type))
14438         ;
14439       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14440                          &conform_action))
14441         ;
14442       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14443                          &exceed_action))
14444         ;
14445       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14446                          &violate_action))
14447         ;
14448       else if (unformat (i, "color-aware"))
14449         color_aware = 1;
14450       else
14451         break;
14452     }
14453
14454   if (!vec_len (name))
14455     {
14456       errmsg ("policer name must be specified");
14457       return -99;
14458     }
14459
14460   if (vec_len (name) > 64)
14461     {
14462       errmsg ("policer name too long");
14463       return -99;
14464     }
14465
14466   M (POLICER_ADD_DEL, policer_add_del);
14467
14468   clib_memcpy (mp->name, name, vec_len (name));
14469   vec_free (name);
14470   mp->is_add = is_add;
14471   mp->cir = cir;
14472   mp->eir = eir;
14473   mp->cb = cb;
14474   mp->eb = eb;
14475   mp->rate_type = rate_type;
14476   mp->round_type = round_type;
14477   mp->type = type;
14478   mp->conform_action_type = conform_action.action_type;
14479   mp->conform_dscp = conform_action.dscp;
14480   mp->exceed_action_type = exceed_action.action_type;
14481   mp->exceed_dscp = exceed_action.dscp;
14482   mp->violate_action_type = violate_action.action_type;
14483   mp->violate_dscp = violate_action.dscp;
14484   mp->color_aware = color_aware;
14485
14486   S;
14487   W;
14488   /* NOTREACHED */
14489   return 0;
14490 }
14491
14492 static int
14493 api_policer_dump (vat_main_t * vam)
14494 {
14495   unformat_input_t *i = vam->input;
14496   vl_api_policer_dump_t *mp;
14497   f64 timeout = ~0;
14498   u8 *match_name = 0;
14499   u8 match_name_valid = 0;
14500
14501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14502     {
14503       if (unformat (i, "name %s", &match_name))
14504         {
14505           vec_add1 (match_name, 0);
14506           match_name_valid = 1;
14507         }
14508       else
14509         break;
14510     }
14511
14512   M (POLICER_DUMP, policer_dump);
14513   mp->match_name_valid = match_name_valid;
14514   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14515   vec_free (match_name);
14516   /* send it... */
14517   S;
14518
14519   /* Use a control ping for synchronization */
14520   {
14521     vl_api_control_ping_t *mp;
14522     M (CONTROL_PING, control_ping);
14523     S;
14524   }
14525   /* Wait for a reply... */
14526   W;
14527
14528   /* NOTREACHED */
14529   return 0;
14530 }
14531
14532 static int
14533 api_policer_classify_set_interface (vat_main_t * vam)
14534 {
14535   unformat_input_t *i = vam->input;
14536   vl_api_policer_classify_set_interface_t *mp;
14537   f64 timeout;
14538   u32 sw_if_index;
14539   int sw_if_index_set;
14540   u32 ip4_table_index = ~0;
14541   u32 ip6_table_index = ~0;
14542   u32 l2_table_index = ~0;
14543   u8 is_add = 1;
14544
14545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14546     {
14547       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14548         sw_if_index_set = 1;
14549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14550         sw_if_index_set = 1;
14551       else if (unformat (i, "del"))
14552         is_add = 0;
14553       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14554         ;
14555       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14556         ;
14557       else if (unformat (i, "l2-table %d", &l2_table_index))
14558         ;
14559       else
14560         {
14561           clib_warning ("parse error '%U'", format_unformat_error, i);
14562           return -99;
14563         }
14564     }
14565
14566   if (sw_if_index_set == 0)
14567     {
14568       errmsg ("missing interface name or sw_if_index\n");
14569       return -99;
14570     }
14571
14572   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14573
14574   mp->sw_if_index = ntohl (sw_if_index);
14575   mp->ip4_table_index = ntohl (ip4_table_index);
14576   mp->ip6_table_index = ntohl (ip6_table_index);
14577   mp->l2_table_index = ntohl (l2_table_index);
14578   mp->is_add = is_add;
14579
14580   S;
14581   W;
14582   /* NOTREACHED */
14583   return 0;
14584 }
14585
14586 static int
14587 api_policer_classify_dump (vat_main_t * vam)
14588 {
14589   unformat_input_t *i = vam->input;
14590   vl_api_policer_classify_dump_t *mp;
14591   f64 timeout = ~0;
14592   u8 type = POLICER_CLASSIFY_N_TABLES;
14593
14594   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14595     ;
14596   else
14597     {
14598       errmsg ("classify table type must be specified\n");
14599       return -99;
14600     }
14601
14602   if (!vam->json_output)
14603     {
14604       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14605     }
14606
14607   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14608   mp->type = type;
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_netmap_create (vat_main_t * vam)
14627 {
14628   unformat_input_t *i = vam->input;
14629   vl_api_netmap_create_t *mp;
14630   f64 timeout;
14631   u8 *if_name = 0;
14632   u8 hw_addr[6];
14633   u8 random_hw_addr = 1;
14634   u8 is_pipe = 0;
14635   u8 is_master = 0;
14636
14637   memset (hw_addr, 0, sizeof (hw_addr));
14638
14639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14640     {
14641       if (unformat (i, "name %s", &if_name))
14642         vec_add1 (if_name, 0);
14643       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14644         random_hw_addr = 0;
14645       else if (unformat (i, "pipe"))
14646         is_pipe = 1;
14647       else if (unformat (i, "master"))
14648         is_master = 1;
14649       else if (unformat (i, "slave"))
14650         is_master = 0;
14651       else
14652         break;
14653     }
14654
14655   if (!vec_len (if_name))
14656     {
14657       errmsg ("interface name must be specified");
14658       return -99;
14659     }
14660
14661   if (vec_len (if_name) > 64)
14662     {
14663       errmsg ("interface name too long");
14664       return -99;
14665     }
14666
14667   M (NETMAP_CREATE, netmap_create);
14668
14669   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14670   clib_memcpy (mp->hw_addr, hw_addr, 6);
14671   mp->use_random_hw_addr = random_hw_addr;
14672   mp->is_pipe = is_pipe;
14673   mp->is_master = is_master;
14674   vec_free (if_name);
14675
14676   S;
14677   W;
14678   /* NOTREACHED */
14679   return 0;
14680 }
14681
14682 static int
14683 api_netmap_delete (vat_main_t * vam)
14684 {
14685   unformat_input_t *i = vam->input;
14686   vl_api_netmap_delete_t *mp;
14687   f64 timeout;
14688   u8 *if_name = 0;
14689
14690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14691     {
14692       if (unformat (i, "name %s", &if_name))
14693         vec_add1 (if_name, 0);
14694       else
14695         break;
14696     }
14697
14698   if (!vec_len (if_name))
14699     {
14700       errmsg ("interface name must be specified");
14701       return -99;
14702     }
14703
14704   if (vec_len (if_name) > 64)
14705     {
14706       errmsg ("interface name too long");
14707       return -99;
14708     }
14709
14710   M (NETMAP_DELETE, netmap_delete);
14711
14712   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14713   vec_free (if_name);
14714
14715   S;
14716   W;
14717   /* NOTREACHED */
14718   return 0;
14719 }
14720
14721 static void vl_api_mpls_tunnel_details_t_handler
14722   (vl_api_mpls_tunnel_details_t * mp)
14723 {
14724   vat_main_t *vam = &vat_main;
14725   i32 len = mp->mt_next_hop_n_labels;
14726   i32 i;
14727
14728   fformat (vam->ofp, "[%d]: via %U %d labels ",
14729            mp->tunnel_index,
14730            format_ip4_address, mp->mt_next_hop,
14731            ntohl (mp->mt_next_hop_sw_if_index));
14732   for (i = 0; i < len; i++)
14733     {
14734       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
14735     }
14736   fformat (vam->ofp, "\n");
14737 }
14738
14739 static void vl_api_mpls_tunnel_details_t_handler_json
14740   (vl_api_mpls_tunnel_details_t * mp)
14741 {
14742   vat_main_t *vam = &vat_main;
14743   vat_json_node_t *node = NULL;
14744   struct in_addr ip4;
14745   i32 i;
14746   i32 len = mp->mt_next_hop_n_labels;
14747
14748   if (VAT_JSON_ARRAY != vam->json_tree.type)
14749     {
14750       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14751       vat_json_init_array (&vam->json_tree);
14752     }
14753   node = vat_json_array_add (&vam->json_tree);
14754
14755   vat_json_init_object (node);
14756   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14757   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
14758   vat_json_object_add_ip4 (node, "next_hop", ip4);
14759   vat_json_object_add_uint (node, "next_hop_sw_if_index",
14760                             ntohl (mp->mt_next_hop_sw_if_index));
14761   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
14762   vat_json_object_add_uint (node, "label_count", len);
14763   for (i = 0; i < len; i++)
14764     {
14765       vat_json_object_add_uint (node, "label",
14766                                 ntohl (mp->mt_next_hop_out_labels[i]));
14767     }
14768 }
14769
14770 static int
14771 api_mpls_tunnel_dump (vat_main_t * vam)
14772 {
14773   vl_api_mpls_tunnel_dump_t *mp;
14774   f64 timeout;
14775   i32 index = -1;
14776
14777   /* Parse args required to build the message */
14778   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14779     {
14780       if (!unformat (vam->input, "tunnel_index %d", &index))
14781         {
14782           index = -1;
14783           break;
14784         }
14785     }
14786
14787   fformat (vam->ofp, "  tunnel_index %d\n", index);
14788
14789   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
14790   mp->tunnel_index = htonl (index);
14791   S;
14792
14793   /* Use a control ping for synchronization */
14794   {
14795     vl_api_control_ping_t *mp;
14796     M (CONTROL_PING, control_ping);
14797     S;
14798   }
14799   W;
14800 }
14801
14802 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14803 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14804
14805 static void
14806 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14807 {
14808   vat_main_t *vam = &vat_main;
14809   int count = ntohl (mp->count);
14810   vl_api_fib_path_t *fp;
14811   int i;
14812
14813   fformat (vam->ofp,
14814            "table-id %d, label %u, ess_bit %u\n",
14815            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14816   fp = mp->path;
14817   for (i = 0; i < count; i++)
14818     {
14819       if (fp->afi == IP46_TYPE_IP6)
14820         fformat (vam->ofp,
14821                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14822                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14823                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14824                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14825                  format_ip6_address, fp->next_hop);
14826       else if (fp->afi == IP46_TYPE_IP4)
14827         fformat (vam->ofp,
14828                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14829                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14830                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14831                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14832                  format_ip4_address, fp->next_hop);
14833       fp++;
14834     }
14835 }
14836
14837 static void vl_api_mpls_fib_details_t_handler_json
14838   (vl_api_mpls_fib_details_t * mp)
14839 {
14840   vat_main_t *vam = &vat_main;
14841   int count = ntohl (mp->count);
14842   vat_json_node_t *node = NULL;
14843   struct in_addr ip4;
14844   struct in6_addr ip6;
14845   vl_api_fib_path_t *fp;
14846   int i;
14847
14848   if (VAT_JSON_ARRAY != vam->json_tree.type)
14849     {
14850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14851       vat_json_init_array (&vam->json_tree);
14852     }
14853   node = vat_json_array_add (&vam->json_tree);
14854
14855   vat_json_init_object (node);
14856   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14857   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14858   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14859   vat_json_object_add_uint (node, "path_count", count);
14860   fp = mp->path;
14861   for (i = 0; i < count; i++)
14862     {
14863       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14864       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14865       vat_json_object_add_uint (node, "is_local", fp->is_local);
14866       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14867       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14868       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14869       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14870       if (fp->afi == IP46_TYPE_IP4)
14871         {
14872           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14873           vat_json_object_add_ip4 (node, "next_hop", ip4);
14874         }
14875       else if (fp->afi == IP46_TYPE_IP6)
14876         {
14877           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14878           vat_json_object_add_ip6 (node, "next_hop", ip6);
14879         }
14880     }
14881 }
14882
14883 static int
14884 api_mpls_fib_dump (vat_main_t * vam)
14885 {
14886   vl_api_mpls_fib_dump_t *mp;
14887   f64 timeout;
14888
14889   M (MPLS_FIB_DUMP, mpls_fib_dump);
14890   S;
14891
14892   /* Use a control ping for synchronization */
14893   {
14894     vl_api_control_ping_t *mp;
14895     M (CONTROL_PING, control_ping);
14896     S;
14897   }
14898   W;
14899 }
14900
14901 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14902 #define vl_api_ip_fib_details_t_print vl_noop_handler
14903
14904 static void
14905 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14906 {
14907   vat_main_t *vam = &vat_main;
14908   int count = ntohl (mp->count);
14909   vl_api_fib_path_t *fp;
14910   int i;
14911
14912   fformat (vam->ofp,
14913            "table-id %d, prefix %U/%d\n",
14914            ntohl (mp->table_id), format_ip4_address, mp->address,
14915            mp->address_length);
14916   fp = mp->path;
14917   for (i = 0; i < count; i++)
14918     {
14919       if (fp->afi == IP46_TYPE_IP6)
14920         fformat (vam->ofp,
14921                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14922                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14923                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14924                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14925                  format_ip6_address, fp->next_hop);
14926       else if (fp->afi == IP46_TYPE_IP4)
14927         fformat (vam->ofp,
14928                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14929                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14930                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14931                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14932                  format_ip4_address, fp->next_hop);
14933       fp++;
14934     }
14935 }
14936
14937 static void vl_api_ip_fib_details_t_handler_json
14938   (vl_api_ip_fib_details_t * mp)
14939 {
14940   vat_main_t *vam = &vat_main;
14941   int count = ntohl (mp->count);
14942   vat_json_node_t *node = NULL;
14943   struct in_addr ip4;
14944   struct in6_addr ip6;
14945   vl_api_fib_path_t *fp;
14946   int i;
14947
14948   if (VAT_JSON_ARRAY != vam->json_tree.type)
14949     {
14950       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14951       vat_json_init_array (&vam->json_tree);
14952     }
14953   node = vat_json_array_add (&vam->json_tree);
14954
14955   vat_json_init_object (node);
14956   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14957   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
14958   vat_json_object_add_ip4 (node, "prefix", ip4);
14959   vat_json_object_add_uint (node, "mask_length", mp->address_length);
14960   vat_json_object_add_uint (node, "path_count", count);
14961   fp = mp->path;
14962   for (i = 0; i < count; i++)
14963     {
14964       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14965       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14966       vat_json_object_add_uint (node, "is_local", fp->is_local);
14967       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14968       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14969       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14970       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14971       if (fp->afi == IP46_TYPE_IP4)
14972         {
14973           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14974           vat_json_object_add_ip4 (node, "next_hop", ip4);
14975         }
14976       else if (fp->afi == IP46_TYPE_IP6)
14977         {
14978           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14979           vat_json_object_add_ip6 (node, "next_hop", ip6);
14980         }
14981     }
14982 }
14983
14984 static int
14985 api_ip_fib_dump (vat_main_t * vam)
14986 {
14987   vl_api_ip_fib_dump_t *mp;
14988   f64 timeout;
14989
14990   M (IP_FIB_DUMP, ip_fib_dump);
14991   S;
14992
14993   /* Use a control ping for synchronization */
14994   {
14995     vl_api_control_ping_t *mp;
14996     M (CONTROL_PING, control_ping);
14997     S;
14998   }
14999   W;
15000 }
15001
15002 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15003 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15004
15005 static void
15006 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15007 {
15008   vat_main_t *vam = &vat_main;
15009   int count = ntohl (mp->count);
15010   vl_api_fib_path_t *fp;
15011   int i;
15012
15013   fformat (vam->ofp,
15014            "table-id %d, prefix %U/%d\n",
15015            ntohl (mp->table_id), format_ip6_address, mp->address,
15016            mp->address_length);
15017   fp = mp->path;
15018   for (i = 0; i < count; i++)
15019     {
15020       if (fp->afi == IP46_TYPE_IP6)
15021         fformat (vam->ofp,
15022                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15023                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15024                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15025                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15026                  format_ip6_address, fp->next_hop);
15027       else if (fp->afi == IP46_TYPE_IP4)
15028         fformat (vam->ofp,
15029                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15030                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15031                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15032                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15033                  format_ip4_address, fp->next_hop);
15034       fp++;
15035     }
15036 }
15037
15038 static void vl_api_ip6_fib_details_t_handler_json
15039   (vl_api_ip6_fib_details_t * mp)
15040 {
15041   vat_main_t *vam = &vat_main;
15042   int count = ntohl (mp->count);
15043   vat_json_node_t *node = NULL;
15044   struct in_addr ip4;
15045   struct in6_addr ip6;
15046   vl_api_fib_path_t *fp;
15047   int i;
15048
15049   if (VAT_JSON_ARRAY != vam->json_tree.type)
15050     {
15051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15052       vat_json_init_array (&vam->json_tree);
15053     }
15054   node = vat_json_array_add (&vam->json_tree);
15055
15056   vat_json_init_object (node);
15057   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15058   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15059   vat_json_object_add_ip6 (node, "prefix", ip6);
15060   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15061   vat_json_object_add_uint (node, "path_count", count);
15062   fp = mp->path;
15063   for (i = 0; i < count; i++)
15064     {
15065       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15066       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15067       vat_json_object_add_uint (node, "is_local", fp->is_local);
15068       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15069       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15070       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15071       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15072       if (fp->afi == IP46_TYPE_IP4)
15073         {
15074           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15075           vat_json_object_add_ip4 (node, "next_hop", ip4);
15076         }
15077       else if (fp->afi == IP46_TYPE_IP6)
15078         {
15079           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15080           vat_json_object_add_ip6 (node, "next_hop", ip6);
15081         }
15082     }
15083 }
15084
15085 static int
15086 api_ip6_fib_dump (vat_main_t * vam)
15087 {
15088   vl_api_ip6_fib_dump_t *mp;
15089   f64 timeout;
15090
15091   M (IP6_FIB_DUMP, ip6_fib_dump);
15092   S;
15093
15094   /* Use a control ping for synchronization */
15095   {
15096     vl_api_control_ping_t *mp;
15097     M (CONTROL_PING, control_ping);
15098     S;
15099   }
15100   W;
15101 }
15102
15103 int
15104 api_classify_table_ids (vat_main_t * vam)
15105 {
15106   vl_api_classify_table_ids_t *mp;
15107   f64 timeout;
15108
15109   /* Construct the API message */
15110   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15111   mp->context = 0;
15112
15113   S;
15114   W;
15115   /* NOTREACHED */
15116   return 0;
15117 }
15118
15119 int
15120 api_classify_table_by_interface (vat_main_t * vam)
15121 {
15122   unformat_input_t *input = vam->input;
15123   vl_api_classify_table_by_interface_t *mp;
15124   f64 timeout;
15125
15126   u32 sw_if_index = ~0;
15127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15128     {
15129       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15130         ;
15131       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15132         ;
15133       else
15134         break;
15135     }
15136   if (sw_if_index == ~0)
15137     {
15138       errmsg ("missing interface name or sw_if_index\n");
15139       return -99;
15140     }
15141
15142   /* Construct the API message */
15143   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15144   mp->context = 0;
15145   mp->sw_if_index = ntohl (sw_if_index);
15146
15147   S;
15148   W;
15149   /* NOTREACHED */
15150   return 0;
15151 }
15152
15153 int
15154 api_classify_table_info (vat_main_t * vam)
15155 {
15156   unformat_input_t *input = vam->input;
15157   vl_api_classify_table_info_t *mp;
15158   f64 timeout;
15159
15160   u32 table_id = ~0;
15161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15162     {
15163       if (unformat (input, "table_id %d", &table_id))
15164         ;
15165       else
15166         break;
15167     }
15168   if (table_id == ~0)
15169     {
15170       errmsg ("missing table id\n");
15171       return -99;
15172     }
15173
15174   /* Construct the API message */
15175   M (CLASSIFY_TABLE_INFO, classify_table_info);
15176   mp->context = 0;
15177   mp->table_id = ntohl (table_id);
15178
15179   S;
15180   W;
15181   /* NOTREACHED */
15182   return 0;
15183 }
15184
15185 int
15186 api_classify_session_dump (vat_main_t * vam)
15187 {
15188   unformat_input_t *input = vam->input;
15189   vl_api_classify_session_dump_t *mp;
15190   f64 timeout;
15191
15192   u32 table_id = ~0;
15193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15194     {
15195       if (unformat (input, "table_id %d", &table_id))
15196         ;
15197       else
15198         break;
15199     }
15200   if (table_id == ~0)
15201     {
15202       errmsg ("missing table id\n");
15203       return -99;
15204     }
15205
15206   /* Construct the API message */
15207   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15208   mp->context = 0;
15209   mp->table_id = ntohl (table_id);
15210   S;
15211
15212   /* Use a control ping for synchronization */
15213   {
15214     vl_api_control_ping_t *mp;
15215     M (CONTROL_PING, control_ping);
15216     S;
15217   }
15218   W;
15219   /* NOTREACHED */
15220   return 0;
15221 }
15222
15223 static void
15224 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15225 {
15226   vat_main_t *vam = &vat_main;
15227
15228   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15229            "src_address %U, vrf_id %d, path_mtu %u, "
15230            "template_interval %u, udp_checksum %d\n",
15231            format_ip4_address, mp->collector_address,
15232            ntohs (mp->collector_port),
15233            format_ip4_address, mp->src_address,
15234            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15235            ntohl (mp->template_interval), mp->udp_checksum);
15236
15237   vam->retval = 0;
15238   vam->result_ready = 1;
15239 }
15240
15241 static void
15242   vl_api_ipfix_exporter_details_t_handler_json
15243   (vl_api_ipfix_exporter_details_t * mp)
15244 {
15245   vat_main_t *vam = &vat_main;
15246   vat_json_node_t node;
15247   struct in_addr collector_address;
15248   struct in_addr src_address;
15249
15250   vat_json_init_object (&node);
15251   clib_memcpy (&collector_address, &mp->collector_address,
15252                sizeof (collector_address));
15253   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15254   vat_json_object_add_uint (&node, "collector_port",
15255                             ntohs (mp->collector_port));
15256   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15257   vat_json_object_add_ip4 (&node, "src_address", src_address);
15258   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15259   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15260   vat_json_object_add_uint (&node, "template_interval",
15261                             ntohl (mp->template_interval));
15262   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15263
15264   vat_json_print (vam->ofp, &node);
15265   vat_json_free (&node);
15266   vam->retval = 0;
15267   vam->result_ready = 1;
15268 }
15269
15270 int
15271 api_ipfix_exporter_dump (vat_main_t * vam)
15272 {
15273   vl_api_ipfix_exporter_dump_t *mp;
15274   f64 timeout;
15275
15276   /* Construct the API message */
15277   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15278   mp->context = 0;
15279
15280   S;
15281   W;
15282   /* NOTREACHED */
15283   return 0;
15284 }
15285
15286 static int
15287 api_ipfix_classify_stream_dump (vat_main_t * vam)
15288 {
15289   vl_api_ipfix_classify_stream_dump_t *mp;
15290   f64 timeout;
15291
15292   /* Construct the API message */
15293   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15294   mp->context = 0;
15295
15296   S;
15297   W;
15298   /* NOTREACHED */
15299   return 0;
15300 }
15301
15302 static void
15303   vl_api_ipfix_classify_stream_details_t_handler
15304   (vl_api_ipfix_classify_stream_details_t * mp)
15305 {
15306   vat_main_t *vam = &vat_main;
15307   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15308            ntohl (mp->domain_id), ntohs (mp->src_port));
15309   vam->retval = 0;
15310   vam->result_ready = 1;
15311 }
15312
15313 static void
15314   vl_api_ipfix_classify_stream_details_t_handler_json
15315   (vl_api_ipfix_classify_stream_details_t * mp)
15316 {
15317   vat_main_t *vam = &vat_main;
15318   vat_json_node_t node;
15319
15320   vat_json_init_object (&node);
15321   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15322   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15323
15324   vat_json_print (vam->ofp, &node);
15325   vat_json_free (&node);
15326   vam->retval = 0;
15327   vam->result_ready = 1;
15328 }
15329
15330 static int
15331 api_ipfix_classify_table_dump (vat_main_t * vam)
15332 {
15333   vl_api_ipfix_classify_table_dump_t *mp;
15334   f64 timeout;
15335
15336   if (!vam->json_output)
15337     {
15338       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15339                "transport_protocol");
15340     }
15341
15342   /* Construct the API message */
15343   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15344
15345   /* send it... */
15346   S;
15347
15348   /* Use a control ping for synchronization */
15349   {
15350     vl_api_control_ping_t *mp;
15351     M (CONTROL_PING, control_ping);
15352     S;
15353   }
15354   W;
15355 }
15356
15357 static void
15358   vl_api_ipfix_classify_table_details_t_handler
15359   (vl_api_ipfix_classify_table_details_t * mp)
15360 {
15361   vat_main_t *vam = &vat_main;
15362   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15363            mp->transport_protocol);
15364 }
15365
15366 static void
15367   vl_api_ipfix_classify_table_details_t_handler_json
15368   (vl_api_ipfix_classify_table_details_t * mp)
15369 {
15370   vat_json_node_t *node = NULL;
15371   vat_main_t *vam = &vat_main;
15372
15373   if (VAT_JSON_ARRAY != vam->json_tree.type)
15374     {
15375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15376       vat_json_init_array (&vam->json_tree);
15377     }
15378
15379   node = vat_json_array_add (&vam->json_tree);
15380   vat_json_init_object (node);
15381
15382   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15383   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15384   vat_json_object_add_uint (node, "transport_protocol",
15385                             mp->transport_protocol);
15386 }
15387
15388 static int
15389 api_sw_interface_span_enable_disable (vat_main_t * vam)
15390 {
15391   unformat_input_t *i = vam->input;
15392   vl_api_sw_interface_span_enable_disable_t *mp;
15393   f64 timeout;
15394   u32 src_sw_if_index = ~0;
15395   u32 dst_sw_if_index = ~0;
15396   u8 enable = 1;
15397
15398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15399     {
15400       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15401         ;
15402       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15403         ;
15404       else
15405         if (unformat
15406             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15407         ;
15408       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15409         ;
15410       else if (unformat (i, "disable"))
15411         enable = 0;
15412       else
15413         break;
15414     }
15415
15416   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15417
15418   mp->sw_if_index_from = htonl (src_sw_if_index);
15419   mp->sw_if_index_to = htonl (dst_sw_if_index);
15420   mp->enable = enable;
15421
15422   S;
15423   W;
15424   /* NOTREACHED */
15425   return 0;
15426 }
15427
15428 static void
15429 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15430                                             * mp)
15431 {
15432   vat_main_t *vam = &vat_main;
15433
15434   fformat (vam->ofp, "%u => %u\n",
15435            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15436 }
15437
15438 static void
15439   vl_api_sw_interface_span_details_t_handler_json
15440   (vl_api_sw_interface_span_details_t * mp)
15441 {
15442   vat_main_t *vam = &vat_main;
15443   vat_json_node_t *node = NULL;
15444
15445   if (VAT_JSON_ARRAY != vam->json_tree.type)
15446     {
15447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15448       vat_json_init_array (&vam->json_tree);
15449     }
15450   node = vat_json_array_add (&vam->json_tree);
15451
15452   vat_json_init_object (node);
15453   vat_json_object_add_uint (node, "src-if-index",
15454                             ntohl (mp->sw_if_index_from));
15455   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15456 }
15457
15458 static int
15459 api_sw_interface_span_dump (vat_main_t * vam)
15460 {
15461   vl_api_sw_interface_span_dump_t *mp;
15462   f64 timeout;
15463
15464   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15465   S;
15466
15467   /* Use a control ping for synchronization */
15468   {
15469     vl_api_control_ping_t *mp;
15470     M (CONTROL_PING, control_ping);
15471     S;
15472   }
15473   W;
15474 }
15475
15476 int
15477 api_pg_create_interface (vat_main_t * vam)
15478 {
15479   unformat_input_t *input = vam->input;
15480   vl_api_pg_create_interface_t *mp;
15481   f64 timeout;
15482
15483   u32 if_id = ~0;
15484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15485     {
15486       if (unformat (input, "if_id %d", &if_id))
15487         ;
15488       else
15489         break;
15490     }
15491   if (if_id == ~0)
15492     {
15493       errmsg ("missing pg interface index\n");
15494       return -99;
15495     }
15496
15497   /* Construct the API message */
15498   M (PG_CREATE_INTERFACE, pg_create_interface);
15499   mp->context = 0;
15500   mp->interface_id = ntohl (if_id);
15501
15502   S;
15503   W;
15504   /* NOTREACHED */
15505   return 0;
15506 }
15507
15508 int
15509 api_pg_capture (vat_main_t * vam)
15510 {
15511   unformat_input_t *input = vam->input;
15512   vl_api_pg_capture_t *mp;
15513   f64 timeout;
15514
15515   u32 if_id = ~0;
15516   u8 enable = 1;
15517   u32 count = 1;
15518   u8 pcap_file_set = 0;
15519   u8 *pcap_file = 0;
15520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15521     {
15522       if (unformat (input, "if_id %d", &if_id))
15523         ;
15524       else if (unformat (input, "pcap %s", &pcap_file))
15525         pcap_file_set = 1;
15526       else if (unformat (input, "count %d", &count))
15527         ;
15528       else if (unformat (input, "disable"))
15529         enable = 0;
15530       else
15531         break;
15532     }
15533   if (if_id == ~0)
15534     {
15535       errmsg ("missing pg interface index\n");
15536       return -99;
15537     }
15538   if (pcap_file_set > 0)
15539     {
15540       if (vec_len (pcap_file) > 255)
15541         {
15542           errmsg ("pcap file name is too long\n");
15543           return -99;
15544         }
15545     }
15546
15547   u32 name_len = vec_len (pcap_file);
15548   /* Construct the API message */
15549   M (PG_CAPTURE, pg_capture);
15550   mp->context = 0;
15551   mp->interface_id = ntohl (if_id);
15552   mp->is_enabled = enable;
15553   mp->count = ntohl (count);
15554   mp->pcap_name_length = ntohl (name_len);
15555   if (pcap_file_set != 0)
15556     {
15557       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15558     }
15559   vec_free (pcap_file);
15560
15561   S;
15562   W;
15563   /* NOTREACHED */
15564   return 0;
15565 }
15566
15567 int
15568 api_pg_enable_disable (vat_main_t * vam)
15569 {
15570   unformat_input_t *input = vam->input;
15571   vl_api_pg_enable_disable_t *mp;
15572   f64 timeout;
15573
15574   u8 enable = 1;
15575   u8 stream_name_set = 0;
15576   u8 *stream_name = 0;
15577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15578     {
15579       if (unformat (input, "stream %s", &stream_name))
15580         stream_name_set = 1;
15581       else if (unformat (input, "disable"))
15582         enable = 0;
15583       else
15584         break;
15585     }
15586
15587   if (stream_name_set > 0)
15588     {
15589       if (vec_len (stream_name) > 255)
15590         {
15591           errmsg ("stream name too long\n");
15592           return -99;
15593         }
15594     }
15595
15596   u32 name_len = vec_len (stream_name);
15597   /* Construct the API message */
15598   M (PG_ENABLE_DISABLE, pg_enable_disable);
15599   mp->context = 0;
15600   mp->is_enabled = enable;
15601   if (stream_name_set != 0)
15602     {
15603       mp->stream_name_length = ntohl (name_len);
15604       clib_memcpy (mp->stream_name, stream_name, name_len);
15605     }
15606   vec_free (stream_name);
15607
15608   S;
15609   W;
15610   /* NOTREACHED */
15611   return 0;
15612 }
15613
15614 int
15615 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15616 {
15617   unformat_input_t *input = vam->input;
15618   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15619   f64 timeout;
15620
15621   u16 *low_ports = 0;
15622   u16 *high_ports = 0;
15623   u16 this_low;
15624   u16 this_hi;
15625   ip4_address_t ip4_addr;
15626   ip6_address_t ip6_addr;
15627   u32 length;
15628   u32 tmp, tmp2;
15629   u8 prefix_set = 0;
15630   u32 vrf_id = ~0;
15631   u8 is_add = 1;
15632   u8 is_ipv6 = 0;
15633
15634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15635     {
15636       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15637         {
15638           prefix_set = 1;
15639         }
15640       else
15641         if (unformat
15642             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15643         {
15644           prefix_set = 1;
15645           is_ipv6 = 1;
15646         }
15647       else if (unformat (input, "vrf %d", &vrf_id))
15648         ;
15649       else if (unformat (input, "del"))
15650         is_add = 0;
15651       else if (unformat (input, "port %d", &tmp))
15652         {
15653           if (tmp == 0 || tmp > 65535)
15654             {
15655               errmsg ("port %d out of range", tmp);
15656               return -99;
15657             }
15658           this_low = tmp;
15659           this_hi = this_low + 1;
15660           vec_add1 (low_ports, this_low);
15661           vec_add1 (high_ports, this_hi);
15662         }
15663       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15664         {
15665           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15666             {
15667               errmsg ("incorrect range parameters\n");
15668               return -99;
15669             }
15670           this_low = tmp;
15671           /* Note: in debug CLI +1 is added to high before
15672              passing to real fn that does "the work"
15673              (ip_source_and_port_range_check_add_del).
15674              This fn is a wrapper around the binary API fn a
15675              control plane will call, which expects this increment
15676              to have occurred. Hence letting the binary API control
15677              plane fn do the increment for consistency between VAT
15678              and other control planes.
15679            */
15680           this_hi = tmp2;
15681           vec_add1 (low_ports, this_low);
15682           vec_add1 (high_ports, this_hi);
15683         }
15684       else
15685         break;
15686     }
15687
15688   if (prefix_set == 0)
15689     {
15690       errmsg ("<address>/<mask> not specified\n");
15691       return -99;
15692     }
15693
15694   if (vrf_id == ~0)
15695     {
15696       errmsg ("VRF ID required, not specified\n");
15697       return -99;
15698     }
15699
15700   if (vrf_id == 0)
15701     {
15702       errmsg
15703         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15704       return -99;
15705     }
15706
15707   if (vec_len (low_ports) == 0)
15708     {
15709       errmsg ("At least one port or port range required\n");
15710       return -99;
15711     }
15712
15713   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15714      ip_source_and_port_range_check_add_del);
15715
15716   mp->is_add = is_add;
15717
15718   if (is_ipv6)
15719     {
15720       mp->is_ipv6 = 1;
15721       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15722     }
15723   else
15724     {
15725       mp->is_ipv6 = 0;
15726       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15727     }
15728
15729   mp->mask_length = length;
15730   mp->number_of_ranges = vec_len (low_ports);
15731
15732   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15733   vec_free (low_ports);
15734
15735   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15736   vec_free (high_ports);
15737
15738   mp->vrf_id = ntohl (vrf_id);
15739
15740   S;
15741   W;
15742   /* NOTREACHED */
15743   return 0;
15744 }
15745
15746 int
15747 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15748 {
15749   unformat_input_t *input = vam->input;
15750   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15751   f64 timeout;
15752   u32 sw_if_index = ~0;
15753   int vrf_set = 0;
15754   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15755   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15756   u8 is_add = 1;
15757
15758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15759     {
15760       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15761         ;
15762       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15763         ;
15764       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15765         vrf_set = 1;
15766       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15767         vrf_set = 1;
15768       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15769         vrf_set = 1;
15770       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15771         vrf_set = 1;
15772       else if (unformat (input, "del"))
15773         is_add = 0;
15774       else
15775         break;
15776     }
15777
15778   if (sw_if_index == ~0)
15779     {
15780       errmsg ("Interface required but not specified\n");
15781       return -99;
15782     }
15783
15784   if (vrf_set == 0)
15785     {
15786       errmsg ("VRF ID required but not specified\n");
15787       return -99;
15788     }
15789
15790   if (tcp_out_vrf_id == 0
15791       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15792     {
15793       errmsg
15794         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15795       return -99;
15796     }
15797
15798   /* Construct the API message */
15799   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15800      ip_source_and_port_range_check_interface_add_del);
15801
15802   mp->sw_if_index = ntohl (sw_if_index);
15803   mp->is_add = is_add;
15804   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15805   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15806   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15807   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15808
15809   /* send it... */
15810   S;
15811
15812   /* Wait for a reply... */
15813   W;
15814 }
15815
15816 static int
15817 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15818 {
15819   unformat_input_t *i = vam->input;
15820   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15821   f64 timeout;
15822   u32 local_sa_id = 0;
15823   u32 remote_sa_id = 0;
15824   ip4_address_t src_address;
15825   ip4_address_t dst_address;
15826   u8 is_add = 1;
15827
15828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15829     {
15830       if (unformat (i, "local_sa %d", &local_sa_id))
15831         ;
15832       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15833         ;
15834       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15835         ;
15836       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15837         ;
15838       else if (unformat (i, "del"))
15839         is_add = 0;
15840       else
15841         {
15842           clib_warning ("parse error '%U'", format_unformat_error, i);
15843           return -99;
15844         }
15845     }
15846
15847   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15848
15849   mp->local_sa_id = ntohl (local_sa_id);
15850   mp->remote_sa_id = ntohl (remote_sa_id);
15851   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15852   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15853   mp->is_add = is_add;
15854
15855   S;
15856   W;
15857   /* NOTREACHED */
15858   return 0;
15859 }
15860
15861 static int
15862 api_punt (vat_main_t * vam)
15863 {
15864   unformat_input_t *i = vam->input;
15865   vl_api_punt_t *mp;
15866   f64 timeout;
15867   u32 ipv = ~0;
15868   u32 protocol = ~0;
15869   u32 port = ~0;
15870   int is_add = 1;
15871
15872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15873     {
15874       if (unformat (i, "ip %d", &ipv))
15875         ;
15876       else if (unformat (i, "protocol %d", &protocol))
15877         ;
15878       else if (unformat (i, "port %d", &port))
15879         ;
15880       else if (unformat (i, "del"))
15881         is_add = 0;
15882       else
15883         {
15884           clib_warning ("parse error '%U'", format_unformat_error, i);
15885           return -99;
15886         }
15887     }
15888
15889   M (PUNT, punt);
15890
15891   mp->is_add = (u8) is_add;
15892   mp->ipv = (u8) ipv;
15893   mp->l4_protocol = (u8) protocol;
15894   mp->l4_port = htons ((u16) port);
15895
15896   S;
15897   W;
15898   /* NOTREACHED */
15899   return 0;
15900 }
15901
15902 static void vl_api_ipsec_gre_tunnel_details_t_handler
15903   (vl_api_ipsec_gre_tunnel_details_t * mp)
15904 {
15905   vat_main_t *vam = &vat_main;
15906
15907   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15908            ntohl (mp->sw_if_index),
15909            format_ip4_address, &mp->src_address,
15910            format_ip4_address, &mp->dst_address,
15911            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15912 }
15913
15914 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15915   (vl_api_ipsec_gre_tunnel_details_t * mp)
15916 {
15917   vat_main_t *vam = &vat_main;
15918   vat_json_node_t *node = NULL;
15919   struct in_addr ip4;
15920
15921   if (VAT_JSON_ARRAY != vam->json_tree.type)
15922     {
15923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15924       vat_json_init_array (&vam->json_tree);
15925     }
15926   node = vat_json_array_add (&vam->json_tree);
15927
15928   vat_json_init_object (node);
15929   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15930   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15931   vat_json_object_add_ip4 (node, "src_address", ip4);
15932   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15933   vat_json_object_add_ip4 (node, "dst_address", ip4);
15934   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15935   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15936 }
15937
15938 static int
15939 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15940 {
15941   unformat_input_t *i = vam->input;
15942   vl_api_ipsec_gre_tunnel_dump_t *mp;
15943   f64 timeout;
15944   u32 sw_if_index;
15945   u8 sw_if_index_set = 0;
15946
15947   /* Parse args required to build the message */
15948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat (i, "sw_if_index %d", &sw_if_index))
15951         sw_if_index_set = 1;
15952       else
15953         break;
15954     }
15955
15956   if (sw_if_index_set == 0)
15957     {
15958       sw_if_index = ~0;
15959     }
15960
15961   if (!vam->json_output)
15962     {
15963       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15964                "sw_if_index", "src_address", "dst_address",
15965                "local_sa_id", "remote_sa_id");
15966     }
15967
15968   /* Get list of gre-tunnel interfaces */
15969   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15970
15971   mp->sw_if_index = htonl (sw_if_index);
15972
15973   S;
15974
15975   /* Use a control ping for synchronization */
15976   {
15977     vl_api_control_ping_t *mp;
15978     M (CONTROL_PING, control_ping);
15979     S;
15980   }
15981   W;
15982 }
15983
15984 static int
15985 api_delete_subif (vat_main_t * vam)
15986 {
15987   unformat_input_t *i = vam->input;
15988   vl_api_delete_subif_t *mp;
15989   f64 timeout;
15990   u32 sw_if_index = ~0;
15991
15992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15993     {
15994       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15995         ;
15996       if (unformat (i, "sw_if_index %d", &sw_if_index))
15997         ;
15998       else
15999         break;
16000     }
16001
16002   if (sw_if_index == ~0)
16003     {
16004       errmsg ("missing sw_if_index\n");
16005       return -99;
16006     }
16007
16008   /* Construct the API message */
16009   M (DELETE_SUBIF, delete_subif);
16010   mp->sw_if_index = ntohl (sw_if_index);
16011
16012   S;
16013   W;
16014 }
16015
16016 #define foreach_pbb_vtr_op      \
16017 _("disable",  L2_VTR_DISABLED)  \
16018 _("pop",  L2_VTR_POP_2)         \
16019 _("push",  L2_VTR_PUSH_2)
16020
16021 static int
16022 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16023 {
16024   unformat_input_t *i = vam->input;
16025   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16026   f64 timeout;
16027   u32 sw_if_index = ~0, vtr_op = ~0;
16028   u16 outer_tag = ~0;
16029   u8 dmac[6], smac[6];
16030   u8 dmac_set = 0, smac_set = 0;
16031   u16 vlanid = 0;
16032   u32 sid = ~0;
16033   u32 tmp;
16034
16035   /* Shut up coverity */
16036   memset (dmac, 0, sizeof (dmac));
16037   memset (smac, 0, sizeof (smac));
16038
16039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16040     {
16041       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16042         ;
16043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16044         ;
16045       else if (unformat (i, "vtr_op %d", &vtr_op))
16046         ;
16047 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16048       foreach_pbb_vtr_op
16049 #undef _
16050         else if (unformat (i, "translate_pbb_stag"))
16051         {
16052           if (unformat (i, "%d", &tmp))
16053             {
16054               vtr_op = L2_VTR_TRANSLATE_2_1;
16055               outer_tag = tmp;
16056             }
16057           else
16058             {
16059               errmsg
16060                 ("translate_pbb_stag operation requires outer tag definition\n");
16061               return -99;
16062             }
16063         }
16064       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16065         dmac_set++;
16066       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16067         smac_set++;
16068       else if (unformat (i, "sid %d", &sid))
16069         ;
16070       else if (unformat (i, "vlanid %d", &tmp))
16071         vlanid = tmp;
16072       else
16073         {
16074           clib_warning ("parse error '%U'", format_unformat_error, i);
16075           return -99;
16076         }
16077     }
16078
16079   if ((sw_if_index == ~0) || (vtr_op == ~0))
16080     {
16081       errmsg ("missing sw_if_index or vtr operation\n");
16082       return -99;
16083     }
16084   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16085       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16086     {
16087       errmsg
16088         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16089       return -99;
16090     }
16091
16092   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16093   mp->sw_if_index = ntohl (sw_if_index);
16094   mp->vtr_op = ntohl (vtr_op);
16095   mp->outer_tag = ntohs (outer_tag);
16096   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16097   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16098   mp->b_vlanid = ntohs (vlanid);
16099   mp->i_sid = ntohl (sid);
16100
16101   S;
16102   W;
16103   /* NOTREACHED */
16104   return 0;
16105 }
16106
16107 static int
16108 api_flow_classify_set_interface (vat_main_t * vam)
16109 {
16110   unformat_input_t *i = vam->input;
16111   vl_api_flow_classify_set_interface_t *mp;
16112   f64 timeout;
16113   u32 sw_if_index;
16114   int sw_if_index_set;
16115   u32 ip4_table_index = ~0;
16116   u32 ip6_table_index = ~0;
16117   u8 is_add = 1;
16118
16119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16120     {
16121       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16122         sw_if_index_set = 1;
16123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16124         sw_if_index_set = 1;
16125       else if (unformat (i, "del"))
16126         is_add = 0;
16127       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16128         ;
16129       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16130         ;
16131       else
16132         {
16133           clib_warning ("parse error '%U'", format_unformat_error, i);
16134           return -99;
16135         }
16136     }
16137
16138   if (sw_if_index_set == 0)
16139     {
16140       errmsg ("missing interface name or sw_if_index\n");
16141       return -99;
16142     }
16143
16144   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16145
16146   mp->sw_if_index = ntohl (sw_if_index);
16147   mp->ip4_table_index = ntohl (ip4_table_index);
16148   mp->ip6_table_index = ntohl (ip6_table_index);
16149   mp->is_add = is_add;
16150
16151   S;
16152   W;
16153   /* NOTREACHED */
16154   return 0;
16155 }
16156
16157 static int
16158 api_flow_classify_dump (vat_main_t * vam)
16159 {
16160   unformat_input_t *i = vam->input;
16161   vl_api_flow_classify_dump_t *mp;
16162   f64 timeout = ~0;
16163   u8 type = FLOW_CLASSIFY_N_TABLES;
16164
16165   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16166     ;
16167   else
16168     {
16169       errmsg ("classify table type must be specified\n");
16170       return -99;
16171     }
16172
16173   if (!vam->json_output)
16174     {
16175       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16176     }
16177
16178   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16179   mp->type = type;
16180   /* send it... */
16181   S;
16182
16183   /* Use a control ping for synchronization */
16184   {
16185     vl_api_control_ping_t *mp;
16186     M (CONTROL_PING, control_ping);
16187     S;
16188   }
16189   /* Wait for a reply... */
16190   W;
16191
16192   /* NOTREACHED */
16193   return 0;
16194 }
16195
16196 static int
16197 api_feature_enable_disable (vat_main_t * vam)
16198 {
16199   unformat_input_t *i = vam->input;
16200   vl_api_feature_enable_disable_t *mp;
16201   f64 timeout;
16202   u8 *arc_name = 0;
16203   u8 *feature_name = 0;
16204   u32 sw_if_index = ~0;
16205   u8 enable = 1;
16206
16207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (i, "arc_name %s", &arc_name))
16210         ;
16211       else if (unformat (i, "feature_name %s", &feature_name))
16212         ;
16213       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16214         ;
16215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16216         ;
16217       else if (unformat (i, "disable"))
16218         enable = 0;
16219       else
16220         break;
16221     }
16222
16223   if (arc_name == 0)
16224     {
16225       errmsg ("missing arc name\n");
16226       return -99;
16227     }
16228   if (vec_len (arc_name) > 63)
16229     {
16230       errmsg ("arc name too long\n");
16231     }
16232
16233   if (feature_name == 0)
16234     {
16235       errmsg ("missing feature name\n");
16236       return -99;
16237     }
16238   if (vec_len (feature_name) > 63)
16239     {
16240       errmsg ("feature name too long\n");
16241     }
16242
16243   if (sw_if_index == ~0)
16244     {
16245       errmsg ("missing interface name or sw_if_index\n");
16246       return -99;
16247     }
16248
16249   /* Construct the API message */
16250   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16251   mp->sw_if_index = ntohl (sw_if_index);
16252   mp->enable = enable;
16253   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16254   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16255   vec_free (arc_name);
16256   vec_free (feature_name);
16257
16258   S;
16259   W;
16260 }
16261
16262 static int
16263 api_sw_interface_tag_add_del (vat_main_t * vam)
16264 {
16265   unformat_input_t *i = vam->input;
16266   vl_api_sw_interface_tag_add_del_t *mp;
16267   f64 timeout;
16268   u32 sw_if_index = ~0;
16269   u8 *tag = 0;
16270   u8 enable = 1;
16271
16272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16273     {
16274       if (unformat (i, "tag %s", &tag))
16275         ;
16276       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16277         ;
16278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16279         ;
16280       else if (unformat (i, "del"))
16281         enable = 0;
16282       else
16283         break;
16284     }
16285
16286   if (sw_if_index == ~0)
16287     {
16288       errmsg ("missing interface name or sw_if_index\n");
16289       return -99;
16290     }
16291
16292   if (enable && (tag == 0))
16293     {
16294       errmsg ("no tag specified\n");
16295       return -99;
16296     }
16297
16298   /* Construct the API message */
16299   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16300   mp->sw_if_index = ntohl (sw_if_index);
16301   mp->is_add = enable;
16302   if (enable)
16303     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16304   vec_free (tag);
16305
16306   S;
16307   W;
16308 }
16309
16310 static void vl_api_l2_xconnect_details_t_handler
16311   (vl_api_l2_xconnect_details_t * mp)
16312 {
16313   vat_main_t *vam = &vat_main;
16314
16315   fformat (vam->ofp, "%15d%15d\n",
16316            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16317 }
16318
16319 static void vl_api_l2_xconnect_details_t_handler_json
16320   (vl_api_l2_xconnect_details_t * mp)
16321 {
16322   vat_main_t *vam = &vat_main;
16323   vat_json_node_t *node = NULL;
16324
16325   if (VAT_JSON_ARRAY != vam->json_tree.type)
16326     {
16327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16328       vat_json_init_array (&vam->json_tree);
16329     }
16330   node = vat_json_array_add (&vam->json_tree);
16331
16332   vat_json_init_object (node);
16333   vat_json_object_add_uint (node, "rx_sw_if_index",
16334                             ntohl (mp->rx_sw_if_index));
16335   vat_json_object_add_uint (node, "tx_sw_if_index",
16336                             ntohl (mp->tx_sw_if_index));
16337 }
16338
16339 static int
16340 api_l2_xconnect_dump (vat_main_t * vam)
16341 {
16342   vl_api_l2_xconnect_dump_t *mp;
16343   f64 timeout;
16344
16345   if (!vam->json_output)
16346     {
16347       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16348     }
16349
16350   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16351
16352   S;
16353
16354   /* Use a control ping for synchronization */
16355   {
16356     vl_api_control_ping_t *mp;
16357     M (CONTROL_PING, control_ping);
16358     S;
16359   }
16360   W;
16361 }
16362
16363 static int
16364 api_sw_interface_set_mtu (vat_main_t * vam)
16365 {
16366   unformat_input_t *i = vam->input;
16367   vl_api_sw_interface_set_mtu_t *mp;
16368   f64 timeout;
16369   u32 sw_if_index = ~0;
16370   u32 mtu = 0;
16371
16372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16373     {
16374       if (unformat (i, "mtu %d", &mtu))
16375         ;
16376       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16377         ;
16378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16379         ;
16380       else
16381         break;
16382     }
16383
16384   if (sw_if_index == ~0)
16385     {
16386       errmsg ("missing interface name or sw_if_index\n");
16387       return -99;
16388     }
16389
16390   if (mtu == 0)
16391     {
16392       errmsg ("no mtu specified\n");
16393       return -99;
16394     }
16395
16396   /* Construct the API message */
16397   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16398   mp->sw_if_index = ntohl (sw_if_index);
16399   mp->mtu = ntohs ((u16) mtu);
16400
16401   S;
16402   W;
16403 }
16404
16405
16406 static int
16407 q_or_quit (vat_main_t * vam)
16408 {
16409   longjmp (vam->jump_buf, 1);
16410   return 0;                     /* not so much */
16411 }
16412
16413 static int
16414 q (vat_main_t * vam)
16415 {
16416   return q_or_quit (vam);
16417 }
16418
16419 static int
16420 quit (vat_main_t * vam)
16421 {
16422   return q_or_quit (vam);
16423 }
16424
16425 static int
16426 comment (vat_main_t * vam)
16427 {
16428   return 0;
16429 }
16430
16431 static int
16432 cmd_cmp (void *a1, void *a2)
16433 {
16434   u8 **c1 = a1;
16435   u8 **c2 = a2;
16436
16437   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16438 }
16439
16440 static int
16441 help (vat_main_t * vam)
16442 {
16443   u8 **cmds = 0;
16444   u8 *name = 0;
16445   hash_pair_t *p;
16446   unformat_input_t *i = vam->input;
16447   int j;
16448
16449   if (unformat (i, "%s", &name))
16450     {
16451       uword *hs;
16452
16453       vec_add1 (name, 0);
16454
16455       hs = hash_get_mem (vam->help_by_name, name);
16456       if (hs)
16457         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16458       else
16459         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16460       vec_free (name);
16461       return 0;
16462     }
16463
16464   fformat (vam->ofp, "Help is available for the following:\n");
16465
16466     /* *INDENT-OFF* */
16467     hash_foreach_pair (p, vam->function_by_name,
16468     ({
16469       vec_add1 (cmds, (u8 *)(p->key));
16470     }));
16471     /* *INDENT-ON* */
16472
16473   vec_sort_with_function (cmds, cmd_cmp);
16474
16475   for (j = 0; j < vec_len (cmds); j++)
16476     fformat (vam->ofp, "%s\n", cmds[j]);
16477
16478   vec_free (cmds);
16479   return 0;
16480 }
16481
16482 static int
16483 set (vat_main_t * vam)
16484 {
16485   u8 *name = 0, *value = 0;
16486   unformat_input_t *i = vam->input;
16487
16488   if (unformat (i, "%s", &name))
16489     {
16490       /* The input buffer is a vector, not a string. */
16491       value = vec_dup (i->buffer);
16492       vec_delete (value, i->index, 0);
16493       /* Almost certainly has a trailing newline */
16494       if (value[vec_len (value) - 1] == '\n')
16495         value[vec_len (value) - 1] = 0;
16496       /* Make sure it's a proper string, one way or the other */
16497       vec_add1 (value, 0);
16498       (void) clib_macro_set_value (&vam->macro_main,
16499                                    (char *) name, (char *) value);
16500     }
16501   else
16502     errmsg ("usage: set <name> <value>\n");
16503
16504   vec_free (name);
16505   vec_free (value);
16506   return 0;
16507 }
16508
16509 static int
16510 unset (vat_main_t * vam)
16511 {
16512   u8 *name = 0;
16513
16514   if (unformat (vam->input, "%s", &name))
16515     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16516       errmsg ("unset: %s wasn't set\n", name);
16517   vec_free (name);
16518   return 0;
16519 }
16520
16521 typedef struct
16522 {
16523   u8 *name;
16524   u8 *value;
16525 } macro_sort_t;
16526
16527
16528 static int
16529 macro_sort_cmp (void *a1, void *a2)
16530 {
16531   macro_sort_t *s1 = a1;
16532   macro_sort_t *s2 = a2;
16533
16534   return strcmp ((char *) (s1->name), (char *) (s2->name));
16535 }
16536
16537 static int
16538 dump_macro_table (vat_main_t * vam)
16539 {
16540   macro_sort_t *sort_me = 0, *sm;
16541   int i;
16542   hash_pair_t *p;
16543
16544     /* *INDENT-OFF* */
16545     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16546     ({
16547       vec_add2 (sort_me, sm, 1);
16548       sm->name = (u8 *)(p->key);
16549       sm->value = (u8 *) (p->value[0]);
16550     }));
16551     /* *INDENT-ON* */
16552
16553   vec_sort_with_function (sort_me, macro_sort_cmp);
16554
16555   if (vec_len (sort_me))
16556     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16557   else
16558     fformat (vam->ofp, "The macro table is empty...\n");
16559
16560   for (i = 0; i < vec_len (sort_me); i++)
16561     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16562   return 0;
16563 }
16564
16565 static int
16566 dump_node_table (vat_main_t * vam)
16567 {
16568   int i, j;
16569   vlib_node_t *node, *next_node;
16570
16571   if (vec_len (vam->graph_nodes) == 0)
16572     {
16573       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16574       return 0;
16575     }
16576
16577   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16578     {
16579       node = vam->graph_nodes[i];
16580       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16581       for (j = 0; j < vec_len (node->next_nodes); j++)
16582         {
16583           if (node->next_nodes[j] != ~0)
16584             {
16585               next_node = vam->graph_nodes[node->next_nodes[j]];
16586               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16587             }
16588         }
16589     }
16590   return 0;
16591 }
16592
16593 static int
16594 value_sort_cmp (void *a1, void *a2)
16595 {
16596   name_sort_t *n1 = a1;
16597   name_sort_t *n2 = a2;
16598
16599   if (n1->value < n2->value)
16600     return -1;
16601   if (n1->value > n2->value)
16602     return 1;
16603   return 0;
16604 }
16605
16606
16607 static int
16608 dump_msg_api_table (vat_main_t * vam)
16609 {
16610   api_main_t *am = &api_main;
16611   name_sort_t *nses = 0, *ns;
16612   hash_pair_t *hp;
16613   int i;
16614
16615   /* *INDENT-OFF* */
16616   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16617   ({
16618     vec_add2 (nses, ns, 1);
16619     ns->name = (u8 *)(hp->key);
16620     ns->value = (u32) hp->value[0];
16621   }));
16622   /* *INDENT-ON* */
16623
16624   vec_sort_with_function (nses, value_sort_cmp);
16625
16626   for (i = 0; i < vec_len (nses); i++)
16627     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16628   vec_free (nses);
16629   return 0;
16630 }
16631
16632 static int
16633 get_msg_id (vat_main_t * vam)
16634 {
16635   u8 *name_and_crc;
16636   u32 message_index;
16637
16638   if (unformat (vam->input, "%s", &name_and_crc))
16639     {
16640       message_index = vl_api_get_msg_index (name_and_crc);
16641       if (message_index == ~0)
16642         {
16643           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16644           return 0;
16645         }
16646       fformat (vam->ofp, " '%s' has message index %d\n",
16647                name_and_crc, message_index);
16648       return 0;
16649     }
16650   errmsg ("name_and_crc required...\n");
16651   return 0;
16652 }
16653
16654 static int
16655 search_node_table (vat_main_t * vam)
16656 {
16657   unformat_input_t *line_input = vam->input;
16658   u8 *node_to_find;
16659   int j;
16660   vlib_node_t *node, *next_node;
16661   uword *p;
16662
16663   if (vam->graph_node_index_by_name == 0)
16664     {
16665       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16666       return 0;
16667     }
16668
16669   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (line_input, "%s", &node_to_find))
16672         {
16673           vec_add1 (node_to_find, 0);
16674           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16675           if (p == 0)
16676             {
16677               fformat (vam->ofp, "%s not found...\n", node_to_find);
16678               goto out;
16679             }
16680           node = vam->graph_nodes[p[0]];
16681           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16682           for (j = 0; j < vec_len (node->next_nodes); j++)
16683             {
16684               if (node->next_nodes[j] != ~0)
16685                 {
16686                   next_node = vam->graph_nodes[node->next_nodes[j]];
16687                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16688                 }
16689             }
16690         }
16691
16692       else
16693         {
16694           clib_warning ("parse error '%U'", format_unformat_error,
16695                         line_input);
16696           return -99;
16697         }
16698
16699     out:
16700       vec_free (node_to_find);
16701
16702     }
16703
16704   return 0;
16705 }
16706
16707
16708 static int
16709 script (vat_main_t * vam)
16710 {
16711   u8 *s = 0;
16712   char *save_current_file;
16713   unformat_input_t save_input;
16714   jmp_buf save_jump_buf;
16715   u32 save_line_number;
16716
16717   FILE *new_fp, *save_ifp;
16718
16719   if (unformat (vam->input, "%s", &s))
16720     {
16721       new_fp = fopen ((char *) s, "r");
16722       if (new_fp == 0)
16723         {
16724           errmsg ("Couldn't open script file %s\n", s);
16725           vec_free (s);
16726           return -99;
16727         }
16728     }
16729   else
16730     {
16731       errmsg ("Missing script name\n");
16732       return -99;
16733     }
16734
16735   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16736   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16737   save_ifp = vam->ifp;
16738   save_line_number = vam->input_line_number;
16739   save_current_file = (char *) vam->current_file;
16740
16741   vam->input_line_number = 0;
16742   vam->ifp = new_fp;
16743   vam->current_file = s;
16744   do_one_file (vam);
16745
16746   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16747   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16748   vam->ifp = save_ifp;
16749   vam->input_line_number = save_line_number;
16750   vam->current_file = (u8 *) save_current_file;
16751   vec_free (s);
16752
16753   return 0;
16754 }
16755
16756 static int
16757 echo (vat_main_t * vam)
16758 {
16759   fformat (vam->ofp, "%v", vam->input->buffer);
16760   return 0;
16761 }
16762
16763 /* List of API message constructors, CLI names map to api_xxx */
16764 #define foreach_vpe_api_msg                                             \
16765 _(create_loopback,"[mac <mac-addr>]")                                   \
16766 _(sw_interface_dump,"")                                                 \
16767 _(sw_interface_set_flags,                                               \
16768   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16769 _(sw_interface_add_del_address,                                         \
16770   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16771 _(sw_interface_set_table,                                               \
16772   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16773 _(sw_interface_set_mpls_enable,                                                \
16774   "<intfc> | sw_if_index [disable | dis]")                                \
16775 _(sw_interface_set_vpath,                                               \
16776   "<intfc> | sw_if_index <id> enable | disable")                        \
16777 _(sw_interface_set_vxlan_bypass,                                               \
16778   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
16779 _(sw_interface_set_l2_xconnect,                                         \
16780   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16781   "enable | disable")                                                   \
16782 _(sw_interface_set_l2_bridge,                                           \
16783   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16784   "[shg <split-horizon-group>] [bvi]\n"                                 \
16785   "enable | disable")                                                   \
16786 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16787   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16788   "profile <profile-id>\n")                                             \
16789 _(sw_interface_set_dpdk_hqos_subport,                                   \
16790   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16791   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16792 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16793   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16794 _(bridge_domain_add_del,                                                \
16795   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16796 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16797 _(l2fib_add_del,                                                        \
16798   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16799 _(l2_flags,                                                             \
16800   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16801 _(bridge_flags,                                                         \
16802   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16803 _(tap_connect,                                                          \
16804   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
16805 _(tap_modify,                                                           \
16806   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16807 _(tap_delete,                                                           \
16808   "<vpp-if-name> | sw_if_index <id>")                                   \
16809 _(sw_interface_tap_dump, "")                                            \
16810 _(ip_add_del_route,                                                     \
16811   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16812   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16813   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16814   "[multipath] [count <n>]")                                            \
16815 _(mpls_route_add_del,                                                   \
16816   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16817   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16818   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16819   "[multipath] [count <n>]")                                            \
16820 _(mpls_ip_bind_unbind,                                                  \
16821   "<label> <addr/len>")                                                 \
16822 _(mpls_tunnel_add_del,                                                  \
16823   " via <addr> [table-id <n>]\n"                                        \
16824   "sw_if_index <id>] [l2]  [del]")                                      \
16825 _(proxy_arp_add_del,                                                    \
16826   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16827 _(proxy_arp_intfc_enable_disable,                                       \
16828   "<intfc> | sw_if_index <id> enable | disable")                        \
16829 _(sw_interface_set_unnumbered,                                          \
16830   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16831 _(ip_neighbor_add_del,                                                  \
16832   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16833   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16834 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16835 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16836 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16837   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16838   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16839   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16840 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16841 _(reset_fib, "vrf <n> [ipv6]")                                          \
16842 _(dhcp_proxy_config,                                                    \
16843   "svr <v46-address> src <v46-address>\n"                               \
16844    "insert-cid <n> [del]")                                              \
16845 _(dhcp_proxy_config_2,                                                  \
16846   "svr <v46-address> src <v46-address>\n"                               \
16847    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16848 _(dhcp_proxy_set_vss,                                                   \
16849   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16850 _(dhcp_client_config,                                                   \
16851   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16852 _(set_ip_flow_hash,                                                     \
16853   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16854 _(sw_interface_ip6_enable_disable,                                      \
16855   "<intfc> | sw_if_index <id> enable | disable")                        \
16856 _(sw_interface_ip6_set_link_local_address,                              \
16857   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16858 _(sw_interface_ip6nd_ra_prefix,                                         \
16859   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16860   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16861   "[nolink] [isno]")                                                    \
16862 _(sw_interface_ip6nd_ra_config,                                         \
16863   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16864   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16865   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16866 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16867 _(l2_patch_add_del,                                                     \
16868   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16869   "enable | disable")                                                   \
16870 _(sr_tunnel_add_del,                                                    \
16871   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16872   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16873   "[policy <policy_name>]")                                             \
16874 _(sr_policy_add_del,                                                    \
16875   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16876 _(sr_multicast_map_add_del,                                             \
16877   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16878 _(classify_add_del_table,                                               \
16879   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16880   " [del] mask <mask-value>\n"                                          \
16881   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16882   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16883 _(classify_add_del_session,                                             \
16884   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16885   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16886   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16887   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16888 _(classify_set_interface_ip_table,                                      \
16889   "<intfc> | sw_if_index <nn> table <nn>")                              \
16890 _(classify_set_interface_l2_tables,                                     \
16891   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16892   "  [other-table <nn>]")                                               \
16893 _(get_node_index, "node <node-name")                                    \
16894 _(add_node_next, "node <node-name> next <next-node-name>")              \
16895 _(l2tpv3_create_tunnel,                                                 \
16896   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16897   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16898   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16899 _(l2tpv3_set_tunnel_cookies,                                            \
16900   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16901   "[new_remote_cookie <nn>]\n")                                         \
16902 _(l2tpv3_interface_enable_disable,                                      \
16903   "<intfc> | sw_if_index <nn> enable | disable")                        \
16904 _(l2tpv3_set_lookup_key,                                                \
16905   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16906 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16907 _(vxlan_add_del_tunnel,                                                 \
16908   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16909   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16910   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
16911 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16912 _(gre_add_del_tunnel,                                                   \
16913   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16914 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16915 _(l2_fib_clear_table, "")                                               \
16916 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16917 _(l2_interface_vlan_tag_rewrite,                                        \
16918   "<intfc> | sw_if_index <nn> \n"                                       \
16919   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16920   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16921 _(create_vhost_user_if,                                                 \
16922         "socket <filename> [server] [renumber <dev_instance>] "         \
16923         "[mac <mac_address>]")                                          \
16924 _(modify_vhost_user_if,                                                 \
16925         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16926         "[server] [renumber <dev_instance>]")                           \
16927 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16928 _(sw_interface_vhost_user_dump, "")                                     \
16929 _(show_version, "")                                                     \
16930 _(vxlan_gpe_add_del_tunnel,                                             \
16931   "local <addr> remote <addr> vni <nn>\n"                               \
16932     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16933   "[next-ethernet] [next-nsh]\n")                                       \
16934 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16935 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16936 _(interface_name_renumber,                                              \
16937   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16938 _(input_acl_set_interface,                                              \
16939   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16940   "  [l2-table <nn>] [del]")                                            \
16941 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16942 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16943 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16944 _(ip_dump, "ipv4 | ipv6")                                               \
16945 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16946 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16947   "  spid_id <n> ")                                                     \
16948 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16949   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16950   "  integ_alg <alg> integ_key <hex>")                                  \
16951 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16952   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16953   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16954   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16955 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16956 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16957 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16958   "(auth_data 0x<data> | auth_data <data>)")                            \
16959 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16960   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16961 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16962   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16963   "(local|remote)")                                                     \
16964 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16965 _(delete_loopback,"sw_if_index <nn>")                                   \
16966 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16967 _(map_add_domain,                                                       \
16968   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16969   "ip6-src <ip6addr> "                                                  \
16970   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16971 _(map_del_domain, "index <n>")                                          \
16972 _(map_add_del_rule,                                                     \
16973   "index <n> psid <n> dst <ip6addr> [del]")                             \
16974 _(map_domain_dump, "")                                                  \
16975 _(map_rule_dump, "index <map-domain>")                                  \
16976 _(want_interface_events,  "enable|disable")                             \
16977 _(want_stats,"enable|disable")                                          \
16978 _(get_first_msg_id, "client <name>")                                    \
16979 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16980 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16981   "fib-id <nn> [ip4][ip6][default]")                                    \
16982 _(get_node_graph, " ")                                                  \
16983 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16984 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16985 _(ioam_disable, "")                                                \
16986 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16987                             " sw_if_index <sw_if_index> p <priority> "  \
16988                             "w <weight>] [del]")                        \
16989 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16990                         "iface <intf> | sw_if_index <sw_if_index> "     \
16991                         "p <priority> w <weight> [del]")                \
16992 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16993                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16994                           "locator-set <locator_name> [del]")           \
16995 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16996   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16997 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16998 _(lisp_gpe_enable_disable, "enable|disable")                            \
16999 _(lisp_enable_disable, "enable|disable")                                \
17000 _(lisp_gpe_add_del_iface, "up|down")                                    \
17001 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17002                                "[seid <seid>] "                         \
17003                                "rloc <locator> p <prio> "               \
17004                                "w <weight> [rloc <loc> ... ] "          \
17005                                "action <action> [del-all]")             \
17006 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17007                           "<local-eid>")                                \
17008 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17009 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17010 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17011 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17012 _(lisp_locator_set_dump, "[local | remote]")                            \
17013 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17014 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17015                        "[local] | [remote]")                            \
17016 _(lisp_eid_table_vni_dump, "")                                          \
17017 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17018 _(lisp_gpe_tunnel_dump, "")                                             \
17019 _(lisp_map_resolver_dump, "")                                           \
17020 _(lisp_adjacencies_get, "vni <vni>")                                    \
17021 _(show_lisp_status, "")                                                 \
17022 _(lisp_get_map_request_itr_rlocs, "")                                   \
17023 _(show_lisp_pitr, "")                                                   \
17024 _(show_lisp_map_request_mode, "")                                       \
17025 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17026 _(af_packet_delete, "name <host interface name>")                       \
17027 _(policer_add_del, "name <policer name> <params> [del]")                \
17028 _(policer_dump, "[name <policer name>]")                                \
17029 _(policer_classify_set_interface,                                       \
17030   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17031   "  [l2-table <nn>] [del]")                                            \
17032 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17033 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17034     "[master|slave]")                                                   \
17035 _(netmap_delete, "name <interface name>")                               \
17036 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17037 _(mpls_fib_dump, "")                                                    \
17038 _(classify_table_ids, "")                                               \
17039 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17040 _(classify_table_info, "table_id <nn>")                                 \
17041 _(classify_session_dump, "table_id <nn>")                               \
17042 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17043     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17044     "[template_interval <nn>] [udp_checksum]")                          \
17045 _(ipfix_exporter_dump, "")                                              \
17046 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17047 _(ipfix_classify_stream_dump, "")                                       \
17048 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17049 _(ipfix_classify_table_dump, "")                                        \
17050 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17051 _(sw_interface_span_dump, "")                                           \
17052 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17053 _(pg_create_interface, "if_id <nn>")                                    \
17054 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17055 _(pg_enable_disable, "[stream <id>] disable")                           \
17056 _(ip_source_and_port_range_check_add_del,                               \
17057   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17058 _(ip_source_and_port_range_check_interface_add_del,                     \
17059   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17060   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17061 _(ipsec_gre_add_del_tunnel,                                             \
17062   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17063 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17064 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17065 _(l2_interface_pbb_tag_rewrite,                                         \
17066   "<intfc> | sw_if_index <nn> \n"                                       \
17067   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17068   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17069 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17070 _(flow_classify_set_interface,                                          \
17071   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17072 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17073 _(ip_fib_dump, "")                                                      \
17074 _(ip6_fib_dump, "")                                                     \
17075 _(feature_enable_disable, "arc_name <arc_name> "                        \
17076   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17077 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17078 "[disable]")                                                            \
17079 _(l2_xconnect_dump, "")                                                 \
17080 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")
17081
17082 /* List of command functions, CLI names map directly to functions */
17083 #define foreach_cli_function                                    \
17084 _(comment, "usage: comment <ignore-rest-of-line>")              \
17085 _(dump_interface_table, "usage: dump_interface_table")          \
17086 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17087 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17088 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17089 _(dump_stats_table, "usage: dump_stats_table")                  \
17090 _(dump_macro_table, "usage: dump_macro_table ")                 \
17091 _(dump_node_table, "usage: dump_node_table")                    \
17092 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17093 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17094 _(echo, "usage: echo <message>")                                \
17095 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17096 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17097 _(help, "usage: help")                                          \
17098 _(q, "usage: quit")                                             \
17099 _(quit, "usage: quit")                                          \
17100 _(search_node_table, "usage: search_node_table <name>...")      \
17101 _(set, "usage: set <variable-name> <value>")                    \
17102 _(script, "usage: script <file-name>")                          \
17103 _(unset, "usage: unset <variable-name>")
17104
17105 #define _(N,n)                                  \
17106     static void vl_api_##n##_t_handler_uni      \
17107     (vl_api_##n##_t * mp)                       \
17108     {                                           \
17109         vat_main_t * vam = &vat_main;           \
17110         if (vam->json_output) {                 \
17111             vl_api_##n##_t_handler_json(mp);    \
17112         } else {                                \
17113             vl_api_##n##_t_handler(mp);         \
17114         }                                       \
17115     }
17116 foreach_vpe_api_reply_msg;
17117 #undef _
17118
17119 void
17120 vat_api_hookup (vat_main_t * vam)
17121 {
17122 #define _(N,n)                                                  \
17123     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17124                            vl_api_##n##_t_handler_uni,          \
17125                            vl_noop_handler,                     \
17126                            vl_api_##n##_t_endian,               \
17127                            vl_api_##n##_t_print,                \
17128                            sizeof(vl_api_##n##_t), 1);
17129   foreach_vpe_api_reply_msg;
17130 #undef _
17131
17132   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17133
17134   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17135
17136   vam->function_by_name = hash_create_string (0, sizeof (uword));
17137
17138   vam->help_by_name = hash_create_string (0, sizeof (uword));
17139
17140   /* API messages we can send */
17141 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17142   foreach_vpe_api_msg;
17143 #undef _
17144
17145   /* Help strings */
17146 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17147   foreach_vpe_api_msg;
17148 #undef _
17149
17150   /* CLI functions */
17151 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17152   foreach_cli_function;
17153 #undef _
17154
17155   /* Help strings */
17156 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17157   foreach_cli_function;
17158 #undef _
17159 }
17160
17161 #undef vl_api_version
17162 #define vl_api_version(n,v) static u32 memory_api_version = v;
17163 #include <vlibmemory/vl_memory_api_h.h>
17164 #undef vl_api_version
17165
17166 #undef vl_api_version
17167 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17168 #include <vnet/interface.api.h>
17169 #undef vl_api_version
17170
17171 #undef vl_api_version
17172 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17173 #include <vpp-api/vpe.api.h>
17174 #undef vl_api_version
17175
17176 static u32 *api_versions[] = {
17177   &memory_api_version,
17178   &vnet_interface_api_version,
17179   &vpp_api_version,
17180 };
17181
17182 void
17183 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17184 {
17185   int i;
17186
17187   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17188
17189   /*
17190    * Send the API signatures. This bit of code must
17191    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17192    */
17193
17194   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17195     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17196 }
17197
17198 /*
17199  * fd.io coding-style-patch-verification: ON
17200  *
17201  * Local Variables:
17202  * eval: (c-set-style "gnu")
17203  * End:
17204  */