VXLAN multicast dst (remote) address support
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1444   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1460   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->tunnel_sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_l2_bridge_reply)                     \
3452 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3453 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3454 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3455 _(bridge_domain_add_del_reply)                          \
3456 _(sw_interface_set_l2_xconnect_reply)                   \
3457 _(l2fib_add_del_reply)                                  \
3458 _(ip_add_del_route_reply)                               \
3459 _(mpls_route_add_del_reply)                             \
3460 _(mpls_ip_bind_unbind_reply)                            \
3461 _(proxy_arp_add_del_reply)                              \
3462 _(proxy_arp_intfc_enable_disable_reply)                 \
3463 _(mpls_add_del_encap_reply)                             \
3464 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3465 _(sw_interface_set_unnumbered_reply)                    \
3466 _(ip_neighbor_add_del_reply)                            \
3467 _(reset_vrf_reply)                                      \
3468 _(oam_add_del_reply)                                    \
3469 _(reset_fib_reply)                                      \
3470 _(dhcp_proxy_config_reply)                              \
3471 _(dhcp_proxy_config_2_reply)                            \
3472 _(dhcp_proxy_set_vss_reply)                             \
3473 _(dhcp_client_config_reply)                             \
3474 _(set_ip_flow_hash_reply)                               \
3475 _(sw_interface_ip6_enable_disable_reply)                \
3476 _(sw_interface_ip6_set_link_local_address_reply)        \
3477 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3478 _(sw_interface_ip6nd_ra_config_reply)                   \
3479 _(set_arp_neighbor_limit_reply)                         \
3480 _(l2_patch_add_del_reply)                               \
3481 _(sr_tunnel_add_del_reply)                              \
3482 _(sr_policy_add_del_reply)                              \
3483 _(sr_multicast_map_add_del_reply)                       \
3484 _(classify_add_del_session_reply)                       \
3485 _(classify_set_interface_ip_table_reply)                \
3486 _(classify_set_interface_l2_tables_reply)               \
3487 _(l2tpv3_set_tunnel_cookies_reply)                      \
3488 _(l2tpv3_interface_enable_disable_reply)                \
3489 _(l2tpv3_set_lookup_key_reply)                          \
3490 _(l2_fib_clear_table_reply)                             \
3491 _(l2_interface_efp_filter_reply)                        \
3492 _(l2_interface_vlan_tag_rewrite_reply)                  \
3493 _(modify_vhost_user_if_reply)                           \
3494 _(delete_vhost_user_if_reply)                           \
3495 _(want_ip4_arp_events_reply)                            \
3496 _(want_ip6_nd_events_reply)                             \
3497 _(input_acl_set_interface_reply)                        \
3498 _(ipsec_spd_add_del_reply)                              \
3499 _(ipsec_interface_add_del_spd_reply)                    \
3500 _(ipsec_spd_add_del_entry_reply)                        \
3501 _(ipsec_sad_add_del_entry_reply)                        \
3502 _(ipsec_sa_set_key_reply)                               \
3503 _(ikev2_profile_add_del_reply)                          \
3504 _(ikev2_profile_set_auth_reply)                         \
3505 _(ikev2_profile_set_id_reply)                           \
3506 _(ikev2_profile_set_ts_reply)                           \
3507 _(ikev2_set_local_key_reply)                            \
3508 _(delete_loopback_reply)                                \
3509 _(bd_ip_mac_add_del_reply)                              \
3510 _(map_del_domain_reply)                                 \
3511 _(map_add_del_rule_reply)                               \
3512 _(want_interface_events_reply)                          \
3513 _(want_stats_reply)                                     \
3514 _(cop_interface_enable_disable_reply)                   \
3515 _(cop_whitelist_enable_disable_reply)                   \
3516 _(sw_interface_clear_stats_reply)                       \
3517 _(ioam_enable_reply)                              \
3518 _(ioam_disable_reply)                              \
3519 _(lisp_add_del_locator_reply)                           \
3520 _(lisp_add_del_local_eid_reply)                         \
3521 _(lisp_add_del_remote_mapping_reply)                    \
3522 _(lisp_add_del_adjacency_reply)                         \
3523 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3524 _(lisp_add_del_map_resolver_reply)                      \
3525 _(lisp_gpe_enable_disable_reply)                        \
3526 _(lisp_gpe_add_del_iface_reply)                         \
3527 _(lisp_enable_disable_reply)                            \
3528 _(lisp_pitr_set_locator_set_reply)                      \
3529 _(lisp_map_request_mode_reply)                          \
3530 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3531 _(lisp_eid_table_add_del_map_reply)                     \
3532 _(vxlan_gpe_add_del_tunnel_reply)                       \
3533 _(af_packet_delete_reply)                               \
3534 _(policer_classify_set_interface_reply)                 \
3535 _(netmap_create_reply)                                  \
3536 _(netmap_delete_reply)                                  \
3537 _(set_ipfix_exporter_reply)                             \
3538 _(set_ipfix_classify_stream_reply)                      \
3539 _(ipfix_classify_table_add_del_reply)                   \
3540 _(flow_classify_set_interface_reply)                    \
3541 _(sw_interface_span_enable_disable_reply)               \
3542 _(pg_capture_reply)                                     \
3543 _(pg_enable_disable_reply)                              \
3544 _(ip_source_and_port_range_check_add_del_reply)         \
3545 _(ip_source_and_port_range_check_interface_add_del_reply)\
3546 _(delete_subif_reply)                                   \
3547 _(l2_interface_pbb_tag_rewrite_reply)                   \
3548 _(punt_reply)                                           \
3549 _(feature_enable_disable_reply)
3550
3551 #define _(n)                                    \
3552     static void vl_api_##n##_t_handler          \
3553     (vl_api_##n##_t * mp)                       \
3554     {                                           \
3555         vat_main_t * vam = &vat_main;           \
3556         i32 retval = ntohl(mp->retval);         \
3557         if (vam->async_mode) {                  \
3558             vam->async_errors += (retval < 0);  \
3559         } else {                                \
3560             vam->retval = retval;               \
3561             vam->result_ready = 1;              \
3562         }                                       \
3563     }
3564 foreach_standard_reply_retval_handler;
3565 #undef _
3566
3567 #define _(n)                                    \
3568     static void vl_api_##n##_t_handler_json     \
3569     (vl_api_##n##_t * mp)                       \
3570     {                                           \
3571         vat_main_t * vam = &vat_main;           \
3572         vat_json_node_t node;                   \
3573         vat_json_init_object(&node);            \
3574         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3575         vat_json_print(vam->ofp, &node);        \
3576         vam->retval = ntohl(mp->retval);        \
3577         vam->result_ready = 1;                  \
3578     }
3579 foreach_standard_reply_retval_handler;
3580 #undef _
3581
3582 /*
3583  * Table of message reply handlers, must include boilerplate handlers
3584  * we just generated
3585  */
3586
3587 #define foreach_vpe_api_reply_msg                                       \
3588 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3589 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3590 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3591 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3592 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3593 _(CLI_REPLY, cli_reply)                                                 \
3594 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3595 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3596   sw_interface_add_del_address_reply)                                   \
3597 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3598 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3599 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3600 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3601   sw_interface_set_l2_xconnect_reply)                                   \
3602 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3603   sw_interface_set_l2_bridge_reply)                                     \
3604 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3605   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3606 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3607   sw_interface_set_dpdk_hqos_subport_reply)                             \
3608 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3609   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3610 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3611 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3612 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3613 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3614 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3615 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3616 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3617 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3618 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3619 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3620 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3621 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3622 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3623 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3624 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3625   proxy_arp_intfc_enable_disable_reply)                                 \
3626 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3627 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3628   mpls_ethernet_add_del_tunnel_reply)                                   \
3629 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3630   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3631 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3632   sw_interface_set_unnumbered_reply)                                    \
3633 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3634 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3635 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3636 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3637 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3638 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3639 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3640 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3641 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3642 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3643 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3644 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3645   sw_interface_ip6_enable_disable_reply)                                \
3646 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3647   sw_interface_ip6_set_link_local_address_reply)                        \
3648 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3649   sw_interface_ip6nd_ra_prefix_reply)                                   \
3650 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3651   sw_interface_ip6nd_ra_config_reply)                                   \
3652 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3653 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3654 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3655 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3656 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3657 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3658 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3659 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3660 classify_set_interface_ip_table_reply)                                  \
3661 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3662   classify_set_interface_l2_tables_reply)                               \
3663 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3664 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3665 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3666 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3667 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3668   l2tpv3_interface_enable_disable_reply)                                \
3669 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3670 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3671 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3672 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3673 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3674 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3675 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3676 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3677 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3678 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3679 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3680 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3681 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3682 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3683 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3684 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3685 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3686 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3687 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3688 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3689 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3690 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3691 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3692 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3693 _(IP_DETAILS, ip_details)                                               \
3694 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3695 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3696 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3697 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3698 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3699 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3700 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3701 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3702 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3703 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3704 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3705 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3706 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3707 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3708 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3709 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3710 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3711 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3712 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3713 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3714 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3715 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3716 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3717 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3718 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3719 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3720 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3721 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3722 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3723 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3724 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3725 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3726 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3727 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3728 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3729 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3730 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3731 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3732 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3733 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3734 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3735 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3736 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3737 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3738 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3739 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3740 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3741 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3742 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3743 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3744 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3745 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3746 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3747   lisp_add_del_map_request_itr_rlocs_reply)                             \
3748 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3749   lisp_get_map_request_itr_rlocs_reply)                                 \
3750 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3751 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3752 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3753 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3754 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3755 _(POLICER_DETAILS, policer_details)                                     \
3756 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3757 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3758 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3759 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3760 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3761 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3762 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3763 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3764 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3765 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3766 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3767 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3768 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3769 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3770 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3771 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3772 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3773 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3774 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3775 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3776 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3777 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3778 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3779 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3780 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3781 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3782  ip_source_and_port_range_check_add_del_reply)                          \
3783 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3784  ip_source_and_port_range_check_interface_add_del_reply)                \
3785 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3786 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3787 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3788 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3789 _(PUNT_REPLY, punt_reply)                                               \
3790 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3791 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3792 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3793
3794 /* M: construct, but don't yet send a message */
3795
3796 #define M(T,t)                                  \
3797 do {                                            \
3798     vam->result_ready = 0;                      \
3799     mp = vl_msg_api_alloc(sizeof(*mp));         \
3800     memset (mp, 0, sizeof (*mp));               \
3801     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3802     mp->client_index = vam->my_client_index;    \
3803 } while(0);
3804
3805 #define M2(T,t,n)                               \
3806 do {                                            \
3807     vam->result_ready = 0;                      \
3808     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3809     memset (mp, 0, sizeof (*mp));               \
3810     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3811     mp->client_index = vam->my_client_index;    \
3812 } while(0);
3813
3814
3815 /* S: send a message */
3816 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3817
3818 /* W: wait for results, with timeout */
3819 #define W                                       \
3820 do {                                            \
3821     timeout = vat_time_now (vam) + 1.0;         \
3822                                                 \
3823     while (vat_time_now (vam) < timeout) {      \
3824         if (vam->result_ready == 1) {           \
3825             return (vam->retval);               \
3826         }                                       \
3827     }                                           \
3828     return -99;                                 \
3829 } while(0);
3830
3831 /* W2: wait for results, with timeout */
3832 #define W2(body)                                \
3833 do {                                            \
3834     timeout = vat_time_now (vam) + 1.0;         \
3835                                                 \
3836     while (vat_time_now (vam) < timeout) {      \
3837         if (vam->result_ready == 1) {           \
3838           (body);                               \
3839           return (vam->retval);                 \
3840         }                                       \
3841     }                                           \
3842     return -99;                                 \
3843 } while(0);
3844
3845 typedef struct
3846 {
3847   u8 *name;
3848   u32 value;
3849 } name_sort_t;
3850
3851
3852 #define STR_VTR_OP_CASE(op)     \
3853     case L2_VTR_ ## op:         \
3854         return "" # op;
3855
3856 static const char *
3857 str_vtr_op (u32 vtr_op)
3858 {
3859   switch (vtr_op)
3860     {
3861       STR_VTR_OP_CASE (DISABLED);
3862       STR_VTR_OP_CASE (PUSH_1);
3863       STR_VTR_OP_CASE (PUSH_2);
3864       STR_VTR_OP_CASE (POP_1);
3865       STR_VTR_OP_CASE (POP_2);
3866       STR_VTR_OP_CASE (TRANSLATE_1_1);
3867       STR_VTR_OP_CASE (TRANSLATE_1_2);
3868       STR_VTR_OP_CASE (TRANSLATE_2_1);
3869       STR_VTR_OP_CASE (TRANSLATE_2_2);
3870     }
3871
3872   return "UNKNOWN";
3873 }
3874
3875 static int
3876 dump_sub_interface_table (vat_main_t * vam)
3877 {
3878   const sw_interface_subif_t *sub = NULL;
3879
3880   if (vam->json_output)
3881     {
3882       clib_warning
3883         ("JSON output supported only for VPE API calls and dump_stats_table");
3884       return -99;
3885     }
3886
3887   fformat (vam->ofp,
3888            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3889            "Interface", "sw_if_index",
3890            "sub id", "dot1ad", "tags", "outer id",
3891            "inner id", "exact", "default", "outer any", "inner any");
3892
3893   vec_foreach (sub, vam->sw_if_subif_table)
3894   {
3895     fformat (vam->ofp,
3896              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3897              sub->interface_name,
3898              sub->sw_if_index,
3899              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3900              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3901              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3902              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3903     if (sub->vtr_op != L2_VTR_DISABLED)
3904       {
3905         fformat (vam->ofp,
3906                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3907                  "tag1: %d tag2: %d ]\n",
3908                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3909                  sub->vtr_tag1, sub->vtr_tag2);
3910       }
3911   }
3912
3913   return 0;
3914 }
3915
3916 static int
3917 name_sort_cmp (void *a1, void *a2)
3918 {
3919   name_sort_t *n1 = a1;
3920   name_sort_t *n2 = a2;
3921
3922   return strcmp ((char *) n1->name, (char *) n2->name);
3923 }
3924
3925 static int
3926 dump_interface_table (vat_main_t * vam)
3927 {
3928   hash_pair_t *p;
3929   name_sort_t *nses = 0, *ns;
3930
3931   if (vam->json_output)
3932     {
3933       clib_warning
3934         ("JSON output supported only for VPE API calls and dump_stats_table");
3935       return -99;
3936     }
3937
3938   /* *INDENT-OFF* */
3939   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3940   ({
3941     vec_add2 (nses, ns, 1);
3942     ns->name = (u8 *)(p->key);
3943     ns->value = (u32) p->value[0];
3944   }));
3945   /* *INDENT-ON* */
3946
3947   vec_sort_with_function (nses, name_sort_cmp);
3948
3949   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3950   vec_foreach (ns, nses)
3951   {
3952     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3953   }
3954   vec_free (nses);
3955   return 0;
3956 }
3957
3958 static int
3959 dump_ip_table (vat_main_t * vam, int is_ipv6)
3960 {
3961   const ip_details_t *det = NULL;
3962   const ip_address_details_t *address = NULL;
3963   u32 i = ~0;
3964
3965   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3966
3967   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3968   {
3969     i++;
3970     if (!det->present)
3971       {
3972         continue;
3973       }
3974     fformat (vam->ofp, "%-12d\n", i);
3975     fformat (vam->ofp,
3976              "            %-30s%-13s\n", "Address", "Prefix length");
3977     if (!det->addr)
3978       {
3979         continue;
3980       }
3981     vec_foreach (address, det->addr)
3982     {
3983       fformat (vam->ofp,
3984                "            %-30U%-13d\n",
3985                is_ipv6 ? format_ip6_address : format_ip4_address,
3986                address->ip, address->prefix_length);
3987     }
3988   }
3989
3990   return 0;
3991 }
3992
3993 static int
3994 dump_ipv4_table (vat_main_t * vam)
3995 {
3996   if (vam->json_output)
3997     {
3998       clib_warning
3999         ("JSON output supported only for VPE API calls and dump_stats_table");
4000       return -99;
4001     }
4002
4003   return dump_ip_table (vam, 0);
4004 }
4005
4006 static int
4007 dump_ipv6_table (vat_main_t * vam)
4008 {
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   return dump_ip_table (vam, 1);
4017 }
4018
4019 static char *
4020 counter_type_to_str (u8 counter_type, u8 is_combined)
4021 {
4022   if (!is_combined)
4023     {
4024       switch (counter_type)
4025         {
4026         case VNET_INTERFACE_COUNTER_DROP:
4027           return "drop";
4028         case VNET_INTERFACE_COUNTER_PUNT:
4029           return "punt";
4030         case VNET_INTERFACE_COUNTER_IP4:
4031           return "ip4";
4032         case VNET_INTERFACE_COUNTER_IP6:
4033           return "ip6";
4034         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4035           return "rx-no-buf";
4036         case VNET_INTERFACE_COUNTER_RX_MISS:
4037           return "rx-miss";
4038         case VNET_INTERFACE_COUNTER_RX_ERROR:
4039           return "rx-error";
4040         case VNET_INTERFACE_COUNTER_TX_ERROR:
4041           return "tx-error";
4042         default:
4043           return "INVALID-COUNTER-TYPE";
4044         }
4045     }
4046   else
4047     {
4048       switch (counter_type)
4049         {
4050         case VNET_INTERFACE_COUNTER_RX:
4051           return "rx";
4052         case VNET_INTERFACE_COUNTER_TX:
4053           return "tx";
4054         default:
4055           return "INVALID-COUNTER-TYPE";
4056         }
4057     }
4058 }
4059
4060 static int
4061 dump_stats_table (vat_main_t * vam)
4062 {
4063   vat_json_node_t node;
4064   vat_json_node_t *msg_array;
4065   vat_json_node_t *msg;
4066   vat_json_node_t *counter_array;
4067   vat_json_node_t *counter;
4068   interface_counter_t c;
4069   u64 packets;
4070   ip4_fib_counter_t *c4;
4071   ip6_fib_counter_t *c6;
4072   int i, j;
4073
4074   if (!vam->json_output)
4075     {
4076       clib_warning ("dump_stats_table supported only in JSON format");
4077       return -99;
4078     }
4079
4080   vat_json_init_object (&node);
4081
4082   /* interface counters */
4083   msg_array = vat_json_object_add (&node, "interface_counters");
4084   vat_json_init_array (msg_array);
4085   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4086     {
4087       msg = vat_json_array_add (msg_array);
4088       vat_json_init_object (msg);
4089       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4090                                        (u8 *) counter_type_to_str (i, 0));
4091       vat_json_object_add_int (msg, "is_combined", 0);
4092       counter_array = vat_json_object_add (msg, "data");
4093       vat_json_init_array (counter_array);
4094       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4095         {
4096           packets = vam->simple_interface_counters[i][j];
4097           vat_json_array_add_uint (counter_array, packets);
4098         }
4099     }
4100   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4101     {
4102       msg = vat_json_array_add (msg_array);
4103       vat_json_init_object (msg);
4104       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4105                                        (u8 *) counter_type_to_str (i, 1));
4106       vat_json_object_add_int (msg, "is_combined", 1);
4107       counter_array = vat_json_object_add (msg, "data");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4110         {
4111           c = vam->combined_interface_counters[i][j];
4112           counter = vat_json_array_add (counter_array);
4113           vat_json_init_object (counter);
4114           vat_json_object_add_uint (counter, "packets", c.packets);
4115           vat_json_object_add_uint (counter, "bytes", c.bytes);
4116         }
4117     }
4118
4119   /* ip4 fib counters */
4120   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4121   vat_json_init_array (msg_array);
4122   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_uint (msg, "vrf_id",
4127                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4128       counter_array = vat_json_object_add (msg, "c");
4129       vat_json_init_array (counter_array);
4130       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4131         {
4132           counter = vat_json_array_add (counter_array);
4133           vat_json_init_object (counter);
4134           c4 = &vam->ip4_fib_counters[i][j];
4135           vat_json_object_add_ip4 (counter, "address", c4->address);
4136           vat_json_object_add_uint (counter, "address_length",
4137                                     c4->address_length);
4138           vat_json_object_add_uint (counter, "packets", c4->packets);
4139           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4140         }
4141     }
4142
4143   /* ip6 fib counters */
4144   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4145   vat_json_init_array (msg_array);
4146   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4147     {
4148       msg = vat_json_array_add (msg_array);
4149       vat_json_init_object (msg);
4150       vat_json_object_add_uint (msg, "vrf_id",
4151                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4152       counter_array = vat_json_object_add (msg, "c");
4153       vat_json_init_array (counter_array);
4154       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4155         {
4156           counter = vat_json_array_add (counter_array);
4157           vat_json_init_object (counter);
4158           c6 = &vam->ip6_fib_counters[i][j];
4159           vat_json_object_add_ip6 (counter, "address", c6->address);
4160           vat_json_object_add_uint (counter, "address_length",
4161                                     c6->address_length);
4162           vat_json_object_add_uint (counter, "packets", c6->packets);
4163           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4164         }
4165     }
4166
4167   vat_json_print (vam->ofp, &node);
4168   vat_json_free (&node);
4169
4170   return 0;
4171 }
4172
4173 int
4174 exec (vat_main_t * vam)
4175 {
4176   api_main_t *am = &api_main;
4177   vl_api_cli_request_t *mp;
4178   f64 timeout;
4179   void *oldheap;
4180   u8 *cmd = 0;
4181   unformat_input_t *i = vam->input;
4182
4183   if (vec_len (i->buffer) == 0)
4184     return -1;
4185
4186   if (vam->exec_mode == 0 && unformat (i, "mode"))
4187     {
4188       vam->exec_mode = 1;
4189       return 0;
4190     }
4191   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4192     {
4193       vam->exec_mode = 0;
4194       return 0;
4195     }
4196
4197
4198   M (CLI_REQUEST, cli_request);
4199
4200   /*
4201    * Copy cmd into shared memory.
4202    * In order for the CLI command to work, it
4203    * must be a vector ending in \n, not a C-string ending
4204    * in \n\0.
4205    */
4206   pthread_mutex_lock (&am->vlib_rp->mutex);
4207   oldheap = svm_push_data_heap (am->vlib_rp);
4208
4209   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4210   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4211
4212   svm_pop_heap (oldheap);
4213   pthread_mutex_unlock (&am->vlib_rp->mutex);
4214
4215   mp->cmd_in_shmem = (u64) cmd;
4216   S;
4217   timeout = vat_time_now (vam) + 10.0;
4218
4219   while (vat_time_now (vam) < timeout)
4220     {
4221       if (vam->result_ready == 1)
4222         {
4223           u8 *free_me;
4224           if (vam->shmem_result != NULL)
4225             fformat (vam->ofp, "%s", vam->shmem_result);
4226           pthread_mutex_lock (&am->vlib_rp->mutex);
4227           oldheap = svm_push_data_heap (am->vlib_rp);
4228
4229           free_me = (u8 *) vam->shmem_result;
4230           vec_free (free_me);
4231
4232           svm_pop_heap (oldheap);
4233           pthread_mutex_unlock (&am->vlib_rp->mutex);
4234           return 0;
4235         }
4236     }
4237   return -99;
4238 }
4239
4240 /*
4241  * Future replacement of exec() that passes CLI buffers directly in
4242  * the API messages instead of an additional shared memory area.
4243  */
4244 static int
4245 exec_inband (vat_main_t * vam)
4246 {
4247   vl_api_cli_inband_t *mp;
4248   f64 timeout;
4249   unformat_input_t *i = vam->input;
4250
4251   if (vec_len (i->buffer) == 0)
4252     return -1;
4253
4254   if (vam->exec_mode == 0 && unformat (i, "mode"))
4255     {
4256       vam->exec_mode = 1;
4257       return 0;
4258     }
4259   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4260     {
4261       vam->exec_mode = 0;
4262       return 0;
4263     }
4264
4265   /*
4266    * In order for the CLI command to work, it
4267    * must be a vector ending in \n, not a C-string ending
4268    * in \n\0.
4269    */
4270   u32 len = vec_len (vam->input->buffer);
4271   M2 (CLI_INBAND, cli_inband, len);
4272   clib_memcpy (mp->cmd, vam->input->buffer, len);
4273   mp->length = htonl (len);
4274
4275   S;
4276   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4277 }
4278
4279 static int
4280 api_create_loopback (vat_main_t * vam)
4281 {
4282   unformat_input_t *i = vam->input;
4283   vl_api_create_loopback_t *mp;
4284   f64 timeout;
4285   u8 mac_address[6];
4286   u8 mac_set = 0;
4287
4288   memset (mac_address, 0, sizeof (mac_address));
4289
4290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4291     {
4292       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4293         mac_set = 1;
4294       else
4295         break;
4296     }
4297
4298   /* Construct the API message */
4299   M (CREATE_LOOPBACK, create_loopback);
4300   if (mac_set)
4301     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4302
4303   S;
4304   W;
4305 }
4306
4307 static int
4308 api_delete_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_delete_loopback_t *mp;
4312   f64 timeout;
4313   u32 sw_if_index = ~0;
4314
4315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4316     {
4317       if (unformat (i, "sw_if_index %d", &sw_if_index))
4318         ;
4319       else
4320         break;
4321     }
4322
4323   if (sw_if_index == ~0)
4324     {
4325       errmsg ("missing sw_if_index\n");
4326       return -99;
4327     }
4328
4329   /* Construct the API message */
4330   M (DELETE_LOOPBACK, delete_loopback);
4331   mp->sw_if_index = ntohl (sw_if_index);
4332
4333   S;
4334   W;
4335 }
4336
4337 static int
4338 api_want_stats (vat_main_t * vam)
4339 {
4340   unformat_input_t *i = vam->input;
4341   vl_api_want_stats_t *mp;
4342   f64 timeout;
4343   int enable = -1;
4344
4345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4346     {
4347       if (unformat (i, "enable"))
4348         enable = 1;
4349       else if (unformat (i, "disable"))
4350         enable = 0;
4351       else
4352         break;
4353     }
4354
4355   if (enable == -1)
4356     {
4357       errmsg ("missing enable|disable\n");
4358       return -99;
4359     }
4360
4361   M (WANT_STATS, want_stats);
4362   mp->enable_disable = enable;
4363
4364   S;
4365   W;
4366 }
4367
4368 static int
4369 api_want_interface_events (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_want_interface_events_t *mp;
4373   f64 timeout;
4374   int enable = -1;
4375
4376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4377     {
4378       if (unformat (i, "enable"))
4379         enable = 1;
4380       else if (unformat (i, "disable"))
4381         enable = 0;
4382       else
4383         break;
4384     }
4385
4386   if (enable == -1)
4387     {
4388       errmsg ("missing enable|disable\n");
4389       return -99;
4390     }
4391
4392   M (WANT_INTERFACE_EVENTS, want_interface_events);
4393   mp->enable_disable = enable;
4394
4395   vam->interface_event_display = enable;
4396
4397   S;
4398   W;
4399 }
4400
4401
4402 /* Note: non-static, called once to set up the initial intfc table */
4403 int
4404 api_sw_interface_dump (vat_main_t * vam)
4405 {
4406   vl_api_sw_interface_dump_t *mp;
4407   f64 timeout;
4408   hash_pair_t *p;
4409   name_sort_t *nses = 0, *ns;
4410   sw_interface_subif_t *sub = NULL;
4411
4412   /* Toss the old name table */
4413   /* *INDENT-OFF* */
4414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4415   ({
4416     vec_add2 (nses, ns, 1);
4417     ns->name = (u8 *)(p->key);
4418     ns->value = (u32) p->value[0];
4419   }));
4420   /* *INDENT-ON* */
4421
4422   hash_free (vam->sw_if_index_by_interface_name);
4423
4424   vec_foreach (ns, nses) vec_free (ns->name);
4425
4426   vec_free (nses);
4427
4428   vec_foreach (sub, vam->sw_if_subif_table)
4429   {
4430     vec_free (sub->interface_name);
4431   }
4432   vec_free (vam->sw_if_subif_table);
4433
4434   /* recreate the interface name hash table */
4435   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4436
4437   /* Get list of ethernets */
4438   M (SW_INTERFACE_DUMP, sw_interface_dump);
4439   mp->name_filter_valid = 1;
4440   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4441   S;
4442
4443   /* and local / loopback interfaces */
4444   M (SW_INTERFACE_DUMP, sw_interface_dump);
4445   mp->name_filter_valid = 1;
4446   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4447   S;
4448
4449   /* and packet-generator interfaces */
4450   M (SW_INTERFACE_DUMP, sw_interface_dump);
4451   mp->name_filter_valid = 1;
4452   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4453   S;
4454
4455   /* and vxlan-gpe tunnel interfaces */
4456   M (SW_INTERFACE_DUMP, sw_interface_dump);
4457   mp->name_filter_valid = 1;
4458   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4459            sizeof (mp->name_filter) - 1);
4460   S;
4461
4462   /* and vxlan tunnel interfaces */
4463   M (SW_INTERFACE_DUMP, sw_interface_dump);
4464   mp->name_filter_valid = 1;
4465   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4466   S;
4467
4468   /* and host (af_packet) interfaces */
4469   M (SW_INTERFACE_DUMP, sw_interface_dump);
4470   mp->name_filter_valid = 1;
4471   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4472   S;
4473
4474   /* and l2tpv3 tunnel interfaces */
4475   M (SW_INTERFACE_DUMP, sw_interface_dump);
4476   mp->name_filter_valid = 1;
4477   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4478            sizeof (mp->name_filter) - 1);
4479   S;
4480
4481   /* and GRE tunnel interfaces */
4482   M (SW_INTERFACE_DUMP, sw_interface_dump);
4483   mp->name_filter_valid = 1;
4484   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4485   S;
4486
4487   /* and LISP-GPE interfaces */
4488   M (SW_INTERFACE_DUMP, sw_interface_dump);
4489   mp->name_filter_valid = 1;
4490   strncpy ((char *) mp->name_filter, "lisp_gpe",
4491            sizeof (mp->name_filter) - 1);
4492   S;
4493
4494   /* and IPSEC tunnel interfaces */
4495   M (SW_INTERFACE_DUMP, sw_interface_dump);
4496   mp->name_filter_valid = 1;
4497   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4498   S;
4499
4500   /* Use a control ping for synchronization */
4501   {
4502     vl_api_control_ping_t *mp;
4503     M (CONTROL_PING, control_ping);
4504     S;
4505   }
4506   W;
4507 }
4508
4509 static int
4510 api_sw_interface_set_flags (vat_main_t * vam)
4511 {
4512   unformat_input_t *i = vam->input;
4513   vl_api_sw_interface_set_flags_t *mp;
4514   f64 timeout;
4515   u32 sw_if_index;
4516   u8 sw_if_index_set = 0;
4517   u8 admin_up = 0, link_up = 0;
4518
4519   /* Parse args required to build the message */
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "admin-up"))
4523         admin_up = 1;
4524       else if (unformat (i, "admin-down"))
4525         admin_up = 0;
4526       else if (unformat (i, "link-up"))
4527         link_up = 1;
4528       else if (unformat (i, "link-down"))
4529         link_up = 0;
4530       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4531         sw_if_index_set = 1;
4532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4533         sw_if_index_set = 1;
4534       else
4535         break;
4536     }
4537
4538   if (sw_if_index_set == 0)
4539     {
4540       errmsg ("missing interface name or sw_if_index\n");
4541       return -99;
4542     }
4543
4544   /* Construct the API message */
4545   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4546   mp->sw_if_index = ntohl (sw_if_index);
4547   mp->admin_up_down = admin_up;
4548   mp->link_up_down = link_up;
4549
4550   /* send it... */
4551   S;
4552
4553   /* Wait for a reply, return the good/bad news... */
4554   W;
4555 }
4556
4557 static int
4558 api_sw_interface_clear_stats (vat_main_t * vam)
4559 {
4560   unformat_input_t *i = vam->input;
4561   vl_api_sw_interface_clear_stats_t *mp;
4562   f64 timeout;
4563   u32 sw_if_index;
4564   u8 sw_if_index_set = 0;
4565
4566   /* Parse args required to build the message */
4567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4568     {
4569       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4570         sw_if_index_set = 1;
4571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4572         sw_if_index_set = 1;
4573       else
4574         break;
4575     }
4576
4577   /* Construct the API message */
4578   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4579
4580   if (sw_if_index_set == 1)
4581     mp->sw_if_index = ntohl (sw_if_index);
4582   else
4583     mp->sw_if_index = ~0;
4584
4585   /* send it... */
4586   S;
4587
4588   /* Wait for a reply, return the good/bad news... */
4589   W;
4590 }
4591
4592 static int
4593 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4594 {
4595   unformat_input_t *i = vam->input;
4596   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4597   f64 timeout;
4598   u32 sw_if_index;
4599   u8 sw_if_index_set = 0;
4600   u32 subport;
4601   u8 subport_set = 0;
4602   u32 pipe;
4603   u8 pipe_set = 0;
4604   u32 profile;
4605   u8 profile_set = 0;
4606
4607   /* Parse args required to build the message */
4608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4609     {
4610       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4611         sw_if_index_set = 1;
4612       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4613         sw_if_index_set = 1;
4614       else if (unformat (i, "subport %u", &subport))
4615         subport_set = 1;
4616       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4617         sw_if_index_set = 1;
4618       else if (unformat (i, "pipe %u", &pipe))
4619         pipe_set = 1;
4620       else if (unformat (i, "profile %u", &profile))
4621         profile_set = 1;
4622       else
4623         break;
4624     }
4625
4626   if (sw_if_index_set == 0)
4627     {
4628       errmsg ("missing interface name or sw_if_index\n");
4629       return -99;
4630     }
4631
4632   if (subport_set == 0)
4633     {
4634       errmsg ("missing subport \n");
4635       return -99;
4636     }
4637
4638   if (pipe_set == 0)
4639     {
4640       errmsg ("missing pipe\n");
4641       return -99;
4642     }
4643
4644   if (profile_set == 0)
4645     {
4646       errmsg ("missing profile\n");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4651
4652   mp->sw_if_index = ntohl (sw_if_index);
4653   mp->subport = ntohl (subport);
4654   mp->pipe = ntohl (pipe);
4655   mp->profile = ntohl (profile);
4656
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4669   f64 timeout;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u32 subport;
4673   u8 subport_set = 0;
4674   u32 tb_rate = 1250000000;     /* 10GbE */
4675   u32 tb_size = 1000000;
4676   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4677   u32 tc_period = 10;
4678
4679   /* Parse args required to build the message */
4680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4681     {
4682       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4683         sw_if_index_set = 1;
4684       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4685         sw_if_index_set = 1;
4686       else if (unformat (i, "subport %u", &subport))
4687         subport_set = 1;
4688       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4689         sw_if_index_set = 1;
4690       else if (unformat (i, "rate %u", &tb_rate))
4691         {
4692           u32 tc_id;
4693
4694           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4695                tc_id++)
4696             tc_rate[tc_id] = tb_rate;
4697         }
4698       else if (unformat (i, "bktsize %u", &tb_size))
4699         ;
4700       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4701         ;
4702       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4703         ;
4704       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4705         ;
4706       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4707         ;
4708       else if (unformat (i, "period %u", &tc_period))
4709         ;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index\n");
4717       return -99;
4718     }
4719
4720   if (subport_set == 0)
4721     {
4722       errmsg ("missing subport \n");
4723       return -99;
4724     }
4725
4726   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4727
4728   mp->sw_if_index = ntohl (sw_if_index);
4729   mp->subport = ntohl (subport);
4730   mp->tb_rate = ntohl (tb_rate);
4731   mp->tb_size = ntohl (tb_size);
4732   mp->tc_rate[0] = ntohl (tc_rate[0]);
4733   mp->tc_rate[1] = ntohl (tc_rate[1]);
4734   mp->tc_rate[2] = ntohl (tc_rate[2]);
4735   mp->tc_rate[3] = ntohl (tc_rate[3]);
4736   mp->tc_period = ntohl (tc_period);
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u8 entry_set = 0;
4753   u8 tc_set = 0;
4754   u8 queue_set = 0;
4755   u32 entry, tc, queue;
4756
4757   /* Parse args required to build the message */
4758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759     {
4760       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4761         sw_if_index_set = 1;
4762       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "entry %d", &entry))
4765         entry_set = 1;
4766       else if (unformat (i, "tc %d", &tc))
4767         tc_set = 1;
4768       else if (unformat (i, "queue %d", &queue))
4769         queue_set = 1;
4770       else
4771         break;
4772     }
4773
4774   if (sw_if_index_set == 0)
4775     {
4776       errmsg ("missing interface name or sw_if_index\n");
4777       return -99;
4778     }
4779
4780   if (entry_set == 0)
4781     {
4782       errmsg ("missing entry \n");
4783       return -99;
4784     }
4785
4786   if (tc_set == 0)
4787     {
4788       errmsg ("missing traffic class \n");
4789       return -99;
4790     }
4791
4792   if (queue_set == 0)
4793     {
4794       errmsg ("missing queue \n");
4795       return -99;
4796     }
4797
4798   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4799
4800   mp->sw_if_index = ntohl (sw_if_index);
4801   mp->entry = ntohl (entry);
4802   mp->tc = ntohl (tc);
4803   mp->queue = ntohl (queue);
4804
4805   S;
4806   W;
4807   /* NOTREACHED */
4808   return 0;
4809 }
4810
4811 static int
4812 api_sw_interface_add_del_address (vat_main_t * vam)
4813 {
4814   unformat_input_t *i = vam->input;
4815   vl_api_sw_interface_add_del_address_t *mp;
4816   f64 timeout;
4817   u32 sw_if_index;
4818   u8 sw_if_index_set = 0;
4819   u8 is_add = 1, del_all = 0;
4820   u32 address_length = 0;
4821   u8 v4_address_set = 0;
4822   u8 v6_address_set = 0;
4823   ip4_address_t v4address;
4824   ip6_address_t v6address;
4825
4826   /* Parse args required to build the message */
4827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4828     {
4829       if (unformat (i, "del-all"))
4830         del_all = 1;
4831       else if (unformat (i, "del"))
4832         is_add = 0;
4833       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4834         sw_if_index_set = 1;
4835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4836         sw_if_index_set = 1;
4837       else if (unformat (i, "%U/%d",
4838                          unformat_ip4_address, &v4address, &address_length))
4839         v4_address_set = 1;
4840       else if (unformat (i, "%U/%d",
4841                          unformat_ip6_address, &v6address, &address_length))
4842         v6_address_set = 1;
4843       else
4844         break;
4845     }
4846
4847   if (sw_if_index_set == 0)
4848     {
4849       errmsg ("missing interface name or sw_if_index\n");
4850       return -99;
4851     }
4852   if (v4_address_set && v6_address_set)
4853     {
4854       errmsg ("both v4 and v6 addresses set\n");
4855       return -99;
4856     }
4857   if (!v4_address_set && !v6_address_set && !del_all)
4858     {
4859       errmsg ("no addresses set\n");
4860       return -99;
4861     }
4862
4863   /* Construct the API message */
4864   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4865
4866   mp->sw_if_index = ntohl (sw_if_index);
4867   mp->is_add = is_add;
4868   mp->del_all = del_all;
4869   if (v6_address_set)
4870     {
4871       mp->is_ipv6 = 1;
4872       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4873     }
4874   else
4875     {
4876       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4877     }
4878   mp->address_length = address_length;
4879
4880   /* send it... */
4881   S;
4882
4883   /* Wait for a reply, return good/bad news  */
4884   W;
4885 }
4886
4887 static int
4888 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4889 {
4890   unformat_input_t *i = vam->input;
4891   vl_api_sw_interface_set_mpls_enable_t *mp;
4892   f64 timeout;
4893   u32 sw_if_index;
4894   u8 sw_if_index_set = 0;
4895   u8 enable = 1;
4896
4897   /* Parse args required to build the message */
4898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4899     {
4900       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4901         sw_if_index_set = 1;
4902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4903         sw_if_index_set = 1;
4904       else if (unformat (i, "disable"))
4905         enable = 0;
4906       else if (unformat (i, "dis"))
4907         enable = 0;
4908       else
4909         break;
4910     }
4911
4912   if (sw_if_index_set == 0)
4913     {
4914       errmsg ("missing interface name or sw_if_index\n");
4915       return -99;
4916     }
4917
4918   /* Construct the API message */
4919   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4920
4921   mp->sw_if_index = ntohl (sw_if_index);
4922   mp->enable = enable;
4923
4924   /* send it... */
4925   S;
4926
4927   /* Wait for a reply... */
4928   W;
4929 }
4930
4931 static int
4932 api_sw_interface_set_table (vat_main_t * vam)
4933 {
4934   unformat_input_t *i = vam->input;
4935   vl_api_sw_interface_set_table_t *mp;
4936   f64 timeout;
4937   u32 sw_if_index, vrf_id = 0;
4938   u8 sw_if_index_set = 0;
4939   u8 is_ipv6 = 0;
4940
4941   /* Parse args required to build the message */
4942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4943     {
4944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4945         sw_if_index_set = 1;
4946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4947         sw_if_index_set = 1;
4948       else if (unformat (i, "vrf %d", &vrf_id))
4949         ;
4950       else if (unformat (i, "ipv6"))
4951         is_ipv6 = 1;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   /* Construct the API message */
4963   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4964
4965   mp->sw_if_index = ntohl (sw_if_index);
4966   mp->is_ipv6 = is_ipv6;
4967   mp->vrf_id = ntohl (vrf_id);
4968
4969   /* send it... */
4970   S;
4971
4972   /* Wait for a reply... */
4973   W;
4974 }
4975
4976 static int
4977 api_sw_interface_set_vpath (vat_main_t * vam)
4978 {
4979   unformat_input_t *i = vam->input;
4980   vl_api_sw_interface_set_vpath_t *mp;
4981   f64 timeout;
4982   u32 sw_if_index = 0;
4983   u8 sw_if_index_set = 0;
4984   u8 is_enable = 0;
4985
4986   /* Parse args required to build the message */
4987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988     {
4989       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4990         sw_if_index_set = 1;
4991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "enable"))
4994         is_enable = 1;
4995       else if (unformat (i, "disable"))
4996         is_enable = 0;
4997       else
4998         break;
4999     }
5000
5001   if (sw_if_index_set == 0)
5002     {
5003       errmsg ("missing interface name or sw_if_index\n");
5004       return -99;
5005     }
5006
5007   /* Construct the API message */
5008   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5009
5010   mp->sw_if_index = ntohl (sw_if_index);
5011   mp->enable = is_enable;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply... */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_l2_xconnect_t *mp;
5025   f64 timeout;
5026   u32 rx_sw_if_index;
5027   u8 rx_sw_if_index_set = 0;
5028   u32 tx_sw_if_index;
5029   u8 tx_sw_if_index_set = 0;
5030   u8 enable = 1;
5031
5032   /* Parse args required to build the message */
5033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5034     {
5035       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5036         rx_sw_if_index_set = 1;
5037       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5038         tx_sw_if_index_set = 1;
5039       else if (unformat (i, "rx"))
5040         {
5041           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5042             {
5043               if (unformat (i, "%U", unformat_sw_if_index, vam,
5044                             &rx_sw_if_index))
5045                 rx_sw_if_index_set = 1;
5046             }
5047           else
5048             break;
5049         }
5050       else if (unformat (i, "tx"))
5051         {
5052           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5053             {
5054               if (unformat (i, "%U", unformat_sw_if_index, vam,
5055                             &tx_sw_if_index))
5056                 tx_sw_if_index_set = 1;
5057             }
5058           else
5059             break;
5060         }
5061       else if (unformat (i, "enable"))
5062         enable = 1;
5063       else if (unformat (i, "disable"))
5064         enable = 0;
5065       else
5066         break;
5067     }
5068
5069   if (rx_sw_if_index_set == 0)
5070     {
5071       errmsg ("missing rx interface name or rx_sw_if_index\n");
5072       return -99;
5073     }
5074
5075   if (enable && (tx_sw_if_index_set == 0))
5076     {
5077       errmsg ("missing tx interface name or tx_sw_if_index\n");
5078       return -99;
5079     }
5080
5081   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5082
5083   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5084   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5085   mp->enable = enable;
5086
5087   S;
5088   W;
5089   /* NOTREACHED */
5090   return 0;
5091 }
5092
5093 static int
5094 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_sw_interface_set_l2_bridge_t *mp;
5098   f64 timeout;
5099   u32 rx_sw_if_index;
5100   u8 rx_sw_if_index_set = 0;
5101   u32 bd_id;
5102   u8 bd_id_set = 0;
5103   u8 bvi = 0;
5104   u32 shg = 0;
5105   u8 enable = 1;
5106
5107   /* Parse args required to build the message */
5108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5109     {
5110       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5111         rx_sw_if_index_set = 1;
5112       else if (unformat (i, "bd_id %d", &bd_id))
5113         bd_id_set = 1;
5114       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5115         rx_sw_if_index_set = 1;
5116       else if (unformat (i, "shg %d", &shg))
5117         ;
5118       else if (unformat (i, "bvi"))
5119         bvi = 1;
5120       else if (unformat (i, "enable"))
5121         enable = 1;
5122       else if (unformat (i, "disable"))
5123         enable = 0;
5124       else
5125         break;
5126     }
5127
5128   if (rx_sw_if_index_set == 0)
5129     {
5130       errmsg ("missing rx interface name or sw_if_index\n");
5131       return -99;
5132     }
5133
5134   if (enable && (bd_id_set == 0))
5135     {
5136       errmsg ("missing bridge domain\n");
5137       return -99;
5138     }
5139
5140   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5141
5142   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5143   mp->bd_id = ntohl (bd_id);
5144   mp->shg = (u8) shg;
5145   mp->bvi = bvi;
5146   mp->enable = enable;
5147
5148   S;
5149   W;
5150   /* NOTREACHED */
5151   return 0;
5152 }
5153
5154 static int
5155 api_bridge_domain_dump (vat_main_t * vam)
5156 {
5157   unformat_input_t *i = vam->input;
5158   vl_api_bridge_domain_dump_t *mp;
5159   f64 timeout;
5160   u32 bd_id = ~0;
5161
5162   /* Parse args required to build the message */
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "bd_id %d", &bd_id))
5166         ;
5167       else
5168         break;
5169     }
5170
5171   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5172   mp->bd_id = ntohl (bd_id);
5173   S;
5174
5175   /* Use a control ping for synchronization */
5176   {
5177     vl_api_control_ping_t *mp;
5178     M (CONTROL_PING, control_ping);
5179     S;
5180   }
5181
5182   W;
5183   /* NOTREACHED */
5184   return 0;
5185 }
5186
5187 static int
5188 api_bridge_domain_add_del (vat_main_t * vam)
5189 {
5190   unformat_input_t *i = vam->input;
5191   vl_api_bridge_domain_add_del_t *mp;
5192   f64 timeout;
5193   u32 bd_id = ~0;
5194   u8 is_add = 1;
5195   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5196
5197   /* Parse args required to build the message */
5198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5199     {
5200       if (unformat (i, "bd_id %d", &bd_id))
5201         ;
5202       else if (unformat (i, "flood %d", &flood))
5203         ;
5204       else if (unformat (i, "uu-flood %d", &uu_flood))
5205         ;
5206       else if (unformat (i, "forward %d", &forward))
5207         ;
5208       else if (unformat (i, "learn %d", &learn))
5209         ;
5210       else if (unformat (i, "arp-term %d", &arp_term))
5211         ;
5212       else if (unformat (i, "del"))
5213         {
5214           is_add = 0;
5215           flood = uu_flood = forward = learn = 0;
5216         }
5217       else
5218         break;
5219     }
5220
5221   if (bd_id == ~0)
5222     {
5223       errmsg ("missing bridge domain\n");
5224       return -99;
5225     }
5226
5227   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5228
5229   mp->bd_id = ntohl (bd_id);
5230   mp->flood = flood;
5231   mp->uu_flood = uu_flood;
5232   mp->forward = forward;
5233   mp->learn = learn;
5234   mp->arp_term = arp_term;
5235   mp->is_add = is_add;
5236
5237   S;
5238   W;
5239   /* NOTREACHED */
5240   return 0;
5241 }
5242
5243 static int
5244 api_l2fib_add_del (vat_main_t * vam)
5245 {
5246   unformat_input_t *i = vam->input;
5247   vl_api_l2fib_add_del_t *mp;
5248   f64 timeout;
5249   u64 mac = 0;
5250   u8 mac_set = 0;
5251   u32 bd_id;
5252   u8 bd_id_set = 0;
5253   u32 sw_if_index;
5254   u8 sw_if_index_set = 0;
5255   u8 is_add = 1;
5256   u8 static_mac = 0;
5257   u8 filter_mac = 0;
5258   u8 bvi_mac = 0;
5259   int count = 1;
5260   f64 before = 0;
5261   int j;
5262
5263   /* Parse args required to build the message */
5264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5265     {
5266       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5267         mac_set = 1;
5268       else if (unformat (i, "bd_id %d", &bd_id))
5269         bd_id_set = 1;
5270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5271         sw_if_index_set = 1;
5272       else if (unformat (i, "sw_if"))
5273         {
5274           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275             {
5276               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5277                 sw_if_index_set = 1;
5278             }
5279           else
5280             break;
5281         }
5282       else if (unformat (i, "static"))
5283         static_mac = 1;
5284       else if (unformat (i, "filter"))
5285         {
5286           filter_mac = 1;
5287           static_mac = 1;
5288         }
5289       else if (unformat (i, "bvi"))
5290         {
5291           bvi_mac = 1;
5292           static_mac = 1;
5293         }
5294       else if (unformat (i, "del"))
5295         is_add = 0;
5296       else if (unformat (i, "count %d", &count))
5297         ;
5298       else
5299         break;
5300     }
5301
5302   if (mac_set == 0)
5303     {
5304       errmsg ("missing mac address\n");
5305       return -99;
5306     }
5307
5308   if (bd_id_set == 0)
5309     {
5310       errmsg ("missing bridge domain\n");
5311       return -99;
5312     }
5313
5314   if (is_add && (sw_if_index_set == 0))
5315     {
5316       errmsg ("missing interface name or sw_if_index\n");
5317       return -99;
5318     }
5319
5320   if (count > 1)
5321     {
5322       /* Turn on async mode */
5323       vam->async_mode = 1;
5324       vam->async_errors = 0;
5325       before = vat_time_now (vam);
5326     }
5327
5328   for (j = 0; j < count; j++)
5329     {
5330       M (L2FIB_ADD_DEL, l2fib_add_del);
5331
5332       mp->mac = mac;
5333       mp->bd_id = ntohl (bd_id);
5334       mp->is_add = is_add;
5335
5336       if (is_add)
5337         {
5338           mp->sw_if_index = ntohl (sw_if_index);
5339           mp->static_mac = static_mac;
5340           mp->filter_mac = filter_mac;
5341           mp->bvi_mac = bvi_mac;
5342         }
5343       increment_mac_address (&mac);
5344       /* send it... */
5345       S;
5346     }
5347
5348   if (count > 1)
5349     {
5350       vl_api_control_ping_t *mp;
5351       f64 after;
5352
5353       /* Shut off async mode */
5354       vam->async_mode = 0;
5355
5356       M (CONTROL_PING, control_ping);
5357       S;
5358
5359       timeout = vat_time_now (vam) + 1.0;
5360       while (vat_time_now (vam) < timeout)
5361         if (vam->result_ready == 1)
5362           goto out;
5363       vam->retval = -99;
5364
5365     out:
5366       if (vam->retval == -99)
5367         errmsg ("timeout\n");
5368
5369       if (vam->async_errors > 0)
5370         {
5371           errmsg ("%d asynchronous errors\n", vam->async_errors);
5372           vam->retval = -98;
5373         }
5374       vam->async_errors = 0;
5375       after = vat_time_now (vam);
5376
5377       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5378                count, after - before, count / (after - before));
5379     }
5380   else
5381     {
5382       /* Wait for a reply... */
5383       W;
5384     }
5385   /* Return the good/bad news */
5386   return (vam->retval);
5387 }
5388
5389 static int
5390 api_l2_flags (vat_main_t * vam)
5391 {
5392   unformat_input_t *i = vam->input;
5393   vl_api_l2_flags_t *mp;
5394   f64 timeout;
5395   u32 sw_if_index;
5396   u32 feature_bitmap = 0;
5397   u8 sw_if_index_set = 0;
5398
5399   /* Parse args required to build the message */
5400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5401     {
5402       if (unformat (i, "sw_if_index %d", &sw_if_index))
5403         sw_if_index_set = 1;
5404       else if (unformat (i, "sw_if"))
5405         {
5406           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5407             {
5408               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5409                 sw_if_index_set = 1;
5410             }
5411           else
5412             break;
5413         }
5414       else if (unformat (i, "learn"))
5415         feature_bitmap |= L2INPUT_FEAT_LEARN;
5416       else if (unformat (i, "forward"))
5417         feature_bitmap |= L2INPUT_FEAT_FWD;
5418       else if (unformat (i, "flood"))
5419         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5420       else if (unformat (i, "uu-flood"))
5421         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5422       else
5423         break;
5424     }
5425
5426   if (sw_if_index_set == 0)
5427     {
5428       errmsg ("missing interface name or sw_if_index\n");
5429       return -99;
5430     }
5431
5432   M (L2_FLAGS, l2_flags);
5433
5434   mp->sw_if_index = ntohl (sw_if_index);
5435   mp->feature_bitmap = ntohl (feature_bitmap);
5436
5437   S;
5438   W;
5439   /* NOTREACHED */
5440   return 0;
5441 }
5442
5443 static int
5444 api_bridge_flags (vat_main_t * vam)
5445 {
5446   unformat_input_t *i = vam->input;
5447   vl_api_bridge_flags_t *mp;
5448   f64 timeout;
5449   u32 bd_id;
5450   u8 bd_id_set = 0;
5451   u8 is_set = 1;
5452   u32 flags = 0;
5453
5454   /* Parse args required to build the message */
5455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5456     {
5457       if (unformat (i, "bd_id %d", &bd_id))
5458         bd_id_set = 1;
5459       else if (unformat (i, "learn"))
5460         flags |= L2_LEARN;
5461       else if (unformat (i, "forward"))
5462         flags |= L2_FWD;
5463       else if (unformat (i, "flood"))
5464         flags |= L2_FLOOD;
5465       else if (unformat (i, "uu-flood"))
5466         flags |= L2_UU_FLOOD;
5467       else if (unformat (i, "arp-term"))
5468         flags |= L2_ARP_TERM;
5469       else if (unformat (i, "off"))
5470         is_set = 0;
5471       else if (unformat (i, "disable"))
5472         is_set = 0;
5473       else
5474         break;
5475     }
5476
5477   if (bd_id_set == 0)
5478     {
5479       errmsg ("missing bridge domain\n");
5480       return -99;
5481     }
5482
5483   M (BRIDGE_FLAGS, bridge_flags);
5484
5485   mp->bd_id = ntohl (bd_id);
5486   mp->feature_bitmap = ntohl (flags);
5487   mp->is_set = is_set;
5488
5489   S;
5490   W;
5491   /* NOTREACHED */
5492   return 0;
5493 }
5494
5495 static int
5496 api_bd_ip_mac_add_del (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_bd_ip_mac_add_del_t *mp;
5500   f64 timeout;
5501   u32 bd_id;
5502   u8 is_ipv6 = 0;
5503   u8 is_add = 1;
5504   u8 bd_id_set = 0;
5505   u8 ip_set = 0;
5506   u8 mac_set = 0;
5507   ip4_address_t v4addr;
5508   ip6_address_t v6addr;
5509   u8 macaddr[6];
5510
5511
5512   /* Parse args required to build the message */
5513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5514     {
5515       if (unformat (i, "bd_id %d", &bd_id))
5516         {
5517           bd_id_set++;
5518         }
5519       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5520         {
5521           ip_set++;
5522         }
5523       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5524         {
5525           ip_set++;
5526           is_ipv6++;
5527         }
5528       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5529         {
5530           mac_set++;
5531         }
5532       else if (unformat (i, "del"))
5533         is_add = 0;
5534       else
5535         break;
5536     }
5537
5538   if (bd_id_set == 0)
5539     {
5540       errmsg ("missing bridge domain\n");
5541       return -99;
5542     }
5543   else if (ip_set == 0)
5544     {
5545       errmsg ("missing IP address\n");
5546       return -99;
5547     }
5548   else if (mac_set == 0)
5549     {
5550       errmsg ("missing MAC address\n");
5551       return -99;
5552     }
5553
5554   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5555
5556   mp->bd_id = ntohl (bd_id);
5557   mp->is_ipv6 = is_ipv6;
5558   mp->is_add = is_add;
5559   if (is_ipv6)
5560     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5561   else
5562     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5563   clib_memcpy (mp->mac_address, macaddr, 6);
5564   S;
5565   W;
5566   /* NOTREACHED */
5567   return 0;
5568 }
5569
5570 static int
5571 api_tap_connect (vat_main_t * vam)
5572 {
5573   unformat_input_t *i = vam->input;
5574   vl_api_tap_connect_t *mp;
5575   f64 timeout;
5576   u8 mac_address[6];
5577   u8 random_mac = 1;
5578   u8 name_set = 0;
5579   u8 *tap_name;
5580
5581   memset (mac_address, 0, sizeof (mac_address));
5582
5583   /* Parse args required to build the message */
5584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5585     {
5586       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5587         {
5588           random_mac = 0;
5589         }
5590       else if (unformat (i, "random-mac"))
5591         random_mac = 1;
5592       else if (unformat (i, "tapname %s", &tap_name))
5593         name_set = 1;
5594       else
5595         break;
5596     }
5597
5598   if (name_set == 0)
5599     {
5600       errmsg ("missing tap name\n");
5601       return -99;
5602     }
5603   if (vec_len (tap_name) > 63)
5604     {
5605       errmsg ("tap name too long\n");
5606     }
5607   vec_add1 (tap_name, 0);
5608
5609   /* Construct the API message */
5610   M (TAP_CONNECT, tap_connect);
5611
5612   mp->use_random_mac = random_mac;
5613   clib_memcpy (mp->mac_address, mac_address, 6);
5614   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5615   vec_free (tap_name);
5616
5617   /* send it... */
5618   S;
5619
5620   /* Wait for a reply... */
5621   W;
5622 }
5623
5624 static int
5625 api_tap_modify (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_tap_modify_t *mp;
5629   f64 timeout;
5630   u8 mac_address[6];
5631   u8 random_mac = 1;
5632   u8 name_set = 0;
5633   u8 *tap_name;
5634   u32 sw_if_index = ~0;
5635   u8 sw_if_index_set = 0;
5636
5637   memset (mac_address, 0, sizeof (mac_address));
5638
5639   /* Parse args required to build the message */
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5643         sw_if_index_set = 1;
5644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5647         {
5648           random_mac = 0;
5649         }
5650       else if (unformat (i, "random-mac"))
5651         random_mac = 1;
5652       else if (unformat (i, "tapname %s", &tap_name))
5653         name_set = 1;
5654       else
5655         break;
5656     }
5657
5658   if (sw_if_index_set == 0)
5659     {
5660       errmsg ("missing vpp interface name");
5661       return -99;
5662     }
5663   if (name_set == 0)
5664     {
5665       errmsg ("missing tap name\n");
5666       return -99;
5667     }
5668   if (vec_len (tap_name) > 63)
5669     {
5670       errmsg ("tap name too long\n");
5671     }
5672   vec_add1 (tap_name, 0);
5673
5674   /* Construct the API message */
5675   M (TAP_MODIFY, tap_modify);
5676
5677   mp->use_random_mac = random_mac;
5678   mp->sw_if_index = ntohl (sw_if_index);
5679   clib_memcpy (mp->mac_address, mac_address, 6);
5680   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5681   vec_free (tap_name);
5682
5683   /* send it... */
5684   S;
5685
5686   /* Wait for a reply... */
5687   W;
5688 }
5689
5690 static int
5691 api_tap_delete (vat_main_t * vam)
5692 {
5693   unformat_input_t *i = vam->input;
5694   vl_api_tap_delete_t *mp;
5695   f64 timeout;
5696   u32 sw_if_index = ~0;
5697   u8 sw_if_index_set = 0;
5698
5699   /* Parse args required to build the message */
5700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5701     {
5702       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5703         sw_if_index_set = 1;
5704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5705         sw_if_index_set = 1;
5706       else
5707         break;
5708     }
5709
5710   if (sw_if_index_set == 0)
5711     {
5712       errmsg ("missing vpp interface name");
5713       return -99;
5714     }
5715
5716   /* Construct the API message */
5717   M (TAP_DELETE, tap_delete);
5718
5719   mp->sw_if_index = ntohl (sw_if_index);
5720
5721   /* send it... */
5722   S;
5723
5724   /* Wait for a reply... */
5725   W;
5726 }
5727
5728 static int
5729 api_ip_add_del_route (vat_main_t * vam)
5730 {
5731   unformat_input_t *i = vam->input;
5732   vl_api_ip_add_del_route_t *mp;
5733   f64 timeout;
5734   u32 sw_if_index = ~0, vrf_id = 0;
5735   u8 sw_if_index_set = 0;
5736   u8 is_ipv6 = 0;
5737   u8 is_local = 0, is_drop = 0;
5738   u8 is_unreach = 0, is_prohibit = 0;
5739   u8 create_vrf_if_needed = 0;
5740   u8 is_add = 1;
5741   u32 next_hop_weight = 1;
5742   u8 not_last = 0;
5743   u8 is_multipath = 0;
5744   u8 address_set = 0;
5745   u8 address_length_set = 0;
5746   u32 next_hop_table_id = 0;
5747   u32 resolve_attempts = 0;
5748   u32 dst_address_length = 0;
5749   u8 next_hop_set = 0;
5750   ip4_address_t v4_dst_address, v4_next_hop_address;
5751   ip6_address_t v6_dst_address, v6_next_hop_address;
5752   int count = 1;
5753   int j;
5754   f64 before = 0;
5755   u32 random_add_del = 0;
5756   u32 *random_vector = 0;
5757   uword *random_hash;
5758   u32 random_seed = 0xdeaddabe;
5759   u32 classify_table_index = ~0;
5760   u8 is_classify = 0;
5761   u8 resolve_host = 0, resolve_attached = 0;
5762   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5768         sw_if_index_set = 1;
5769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5770         sw_if_index_set = 1;
5771       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5772         {
5773           address_set = 1;
5774           is_ipv6 = 0;
5775         }
5776       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5777         {
5778           address_set = 1;
5779           is_ipv6 = 1;
5780         }
5781       else if (unformat (i, "/%d", &dst_address_length))
5782         {
5783           address_length_set = 1;
5784         }
5785
5786       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5787                                          &v4_next_hop_address))
5788         {
5789           next_hop_set = 1;
5790         }
5791       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5792                                          &v6_next_hop_address))
5793         {
5794           next_hop_set = 1;
5795         }
5796       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5797         ;
5798       else if (unformat (i, "weight %d", &next_hop_weight))
5799         ;
5800       else if (unformat (i, "drop"))
5801         {
5802           is_drop = 1;
5803         }
5804       else if (unformat (i, "null-send-unreach"))
5805         {
5806           is_unreach = 1;
5807         }
5808       else if (unformat (i, "null-send-prohibit"))
5809         {
5810           is_prohibit = 1;
5811         }
5812       else if (unformat (i, "local"))
5813         {
5814           is_local = 1;
5815         }
5816       else if (unformat (i, "classify %d", &classify_table_index))
5817         {
5818           is_classify = 1;
5819         }
5820       else if (unformat (i, "del"))
5821         is_add = 0;
5822       else if (unformat (i, "add"))
5823         is_add = 1;
5824       else if (unformat (i, "not-last"))
5825         not_last = 1;
5826       else if (unformat (i, "resolve-via-host"))
5827         resolve_host = 1;
5828       else if (unformat (i, "resolve-via-attached"))
5829         resolve_attached = 1;
5830       else if (unformat (i, "multipath"))
5831         is_multipath = 1;
5832       else if (unformat (i, "vrf %d", &vrf_id))
5833         ;
5834       else if (unformat (i, "create-vrf"))
5835         create_vrf_if_needed = 1;
5836       else if (unformat (i, "count %d", &count))
5837         ;
5838       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5839         ;
5840       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5841         ;
5842       else if (unformat (i, "out-label %d", &next_hop_out_label))
5843         ;
5844       else if (unformat (i, "random"))
5845         random_add_del = 1;
5846       else if (unformat (i, "seed %d", &random_seed))
5847         ;
5848       else
5849         {
5850           clib_warning ("parse error '%U'", format_unformat_error, i);
5851           return -99;
5852         }
5853     }
5854
5855   if (resolve_attempts > 0 && sw_if_index_set == 0)
5856     {
5857       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5858       return -99;
5859     }
5860
5861   if (!next_hop_set && !is_drop && !is_local &&
5862       !is_classify && !is_unreach && !is_prohibit)
5863     {
5864       errmsg
5865         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5866       return -99;
5867     }
5868
5869   if (address_set == 0)
5870     {
5871       errmsg ("missing addresses\n");
5872       return -99;
5873     }
5874
5875   if (address_length_set == 0)
5876     {
5877       errmsg ("missing address length\n");
5878       return -99;
5879     }
5880
5881   /* Generate a pile of unique, random routes */
5882   if (random_add_del)
5883     {
5884       u32 this_random_address;
5885       random_hash = hash_create (count, sizeof (uword));
5886
5887       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5888       for (j = 0; j <= count; j++)
5889         {
5890           do
5891             {
5892               this_random_address = random_u32 (&random_seed);
5893               this_random_address =
5894                 clib_host_to_net_u32 (this_random_address);
5895             }
5896           while (hash_get (random_hash, this_random_address));
5897           vec_add1 (random_vector, this_random_address);
5898           hash_set (random_hash, this_random_address, 1);
5899         }
5900       hash_free (random_hash);
5901       v4_dst_address.as_u32 = random_vector[0];
5902     }
5903
5904   if (count > 1)
5905     {
5906       /* Turn on async mode */
5907       vam->async_mode = 1;
5908       vam->async_errors = 0;
5909       before = vat_time_now (vam);
5910     }
5911
5912   for (j = 0; j < count; j++)
5913     {
5914       /* Construct the API message */
5915       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5916
5917       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5918       mp->table_id = ntohl (vrf_id);
5919       if (resolve_attempts > 0)
5920         {
5921           mp->resolve_attempts = ntohl (resolve_attempts);
5922           mp->resolve_if_needed = 1;
5923         }
5924       mp->create_vrf_if_needed = create_vrf_if_needed;
5925
5926       mp->is_add = is_add;
5927       mp->is_drop = is_drop;
5928       mp->is_unreach = is_unreach;
5929       mp->is_prohibit = is_prohibit;
5930       mp->is_ipv6 = is_ipv6;
5931       mp->is_local = is_local;
5932       mp->is_classify = is_classify;
5933       mp->is_multipath = is_multipath;
5934       mp->is_resolve_host = resolve_host;
5935       mp->is_resolve_attached = resolve_attached;
5936       mp->not_last = not_last;
5937       mp->next_hop_weight = next_hop_weight;
5938       mp->dst_address_length = dst_address_length;
5939       mp->next_hop_table_id = ntohl (next_hop_table_id);
5940       mp->classify_table_index = ntohl (classify_table_index);
5941       mp->next_hop_out_label = ntohl (next_hop_out_label);
5942
5943       if (is_ipv6)
5944         {
5945           clib_memcpy (mp->dst_address, &v6_dst_address,
5946                        sizeof (v6_dst_address));
5947           if (next_hop_set)
5948             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5949                          sizeof (v6_next_hop_address));
5950           increment_v6_address (&v6_dst_address);
5951         }
5952       else
5953         {
5954           clib_memcpy (mp->dst_address, &v4_dst_address,
5955                        sizeof (v4_dst_address));
5956           if (next_hop_set)
5957             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5958                          sizeof (v4_next_hop_address));
5959           if (random_add_del)
5960             v4_dst_address.as_u32 = random_vector[j + 1];
5961           else
5962             increment_v4_address (&v4_dst_address);
5963         }
5964       /* send it... */
5965       S;
5966       /* If we receive SIGTERM, stop now... */
5967       if (vam->do_exit)
5968         break;
5969     }
5970
5971   /* When testing multiple add/del ops, use a control-ping to sync */
5972   if (count > 1)
5973     {
5974       vl_api_control_ping_t *mp;
5975       f64 after;
5976
5977       /* Shut off async mode */
5978       vam->async_mode = 0;
5979
5980       M (CONTROL_PING, control_ping);
5981       S;
5982
5983       timeout = vat_time_now (vam) + 1.0;
5984       while (vat_time_now (vam) < timeout)
5985         if (vam->result_ready == 1)
5986           goto out;
5987       vam->retval = -99;
5988
5989     out:
5990       if (vam->retval == -99)
5991         errmsg ("timeout\n");
5992
5993       if (vam->async_errors > 0)
5994         {
5995           errmsg ("%d asynchronous errors\n", vam->async_errors);
5996           vam->retval = -98;
5997         }
5998       vam->async_errors = 0;
5999       after = vat_time_now (vam);
6000
6001       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6002       if (j > 0)
6003         count = j;
6004
6005       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6006                count, after - before, count / (after - before));
6007     }
6008   else
6009     {
6010       /* Wait for a reply... */
6011       W;
6012     }
6013
6014   /* Return the good/bad news */
6015   return (vam->retval);
6016 }
6017
6018 static int
6019 api_mpls_route_add_del (vat_main_t * vam)
6020 {
6021   unformat_input_t *i = vam->input;
6022   vl_api_mpls_route_add_del_t *mp;
6023   f64 timeout;
6024   u32 sw_if_index = ~0, table_id = 0;
6025   u8 create_table_if_needed = 0;
6026   u8 is_add = 1;
6027   u32 next_hop_weight = 1;
6028   u8 is_multipath = 0;
6029   u32 next_hop_table_id = 0;
6030   u8 next_hop_set = 0;
6031   ip4_address_t v4_next_hop_address = {
6032     .as_u32 = 0,
6033   };
6034   ip6_address_t v6_next_hop_address = { {0} };
6035   int count = 1;
6036   int j;
6037   f64 before = 0;
6038   u32 classify_table_index = ~0;
6039   u8 is_classify = 0;
6040   u8 resolve_host = 0, resolve_attached = 0;
6041   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6042   mpls_label_t local_label = MPLS_LABEL_INVALID;
6043   u8 is_eos = 1;
6044   u8 next_hop_proto_is_ip4 = 1;
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6050         ;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         ;
6053       else if (unformat (i, "%d", &local_label))
6054         ;
6055       else if (unformat (i, "eos"))
6056         is_eos = 1;
6057       else if (unformat (i, "non-eos"))
6058         is_eos = 0;
6059       else if (unformat (i, "via %U", unformat_ip4_address,
6060                          &v4_next_hop_address))
6061         {
6062           next_hop_set = 1;
6063           next_hop_proto_is_ip4 = 1;
6064         }
6065       else if (unformat (i, "via %U", unformat_ip6_address,
6066                          &v6_next_hop_address))
6067         {
6068           next_hop_set = 1;
6069           next_hop_proto_is_ip4 = 0;
6070         }
6071       else if (unformat (i, "weight %d", &next_hop_weight))
6072         ;
6073       else if (unformat (i, "create-table"))
6074         create_table_if_needed = 1;
6075       else if (unformat (i, "classify %d", &classify_table_index))
6076         {
6077           is_classify = 1;
6078         }
6079       else if (unformat (i, "del"))
6080         is_add = 0;
6081       else if (unformat (i, "add"))
6082         is_add = 1;
6083       else if (unformat (i, "resolve-via-host"))
6084         resolve_host = 1;
6085       else if (unformat (i, "resolve-via-attached"))
6086         resolve_attached = 1;
6087       else if (unformat (i, "multipath"))
6088         is_multipath = 1;
6089       else if (unformat (i, "count %d", &count))
6090         ;
6091       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6092         {
6093           next_hop_set = 1;
6094           next_hop_proto_is_ip4 = 1;
6095         }
6096       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6097         {
6098           next_hop_set = 1;
6099           next_hop_proto_is_ip4 = 0;
6100         }
6101       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6102         ;
6103       else if (unformat (i, "out-label %d", &next_hop_out_label))
6104         ;
6105       else
6106         {
6107           clib_warning ("parse error '%U'", format_unformat_error, i);
6108           return -99;
6109         }
6110     }
6111
6112   if (!next_hop_set && !is_classify)
6113     {
6114       errmsg ("next hop / classify not set\n");
6115       return -99;
6116     }
6117
6118   if (MPLS_LABEL_INVALID == local_label)
6119     {
6120       errmsg ("missing label\n");
6121       return -99;
6122     }
6123
6124   if (count > 1)
6125     {
6126       /* Turn on async mode */
6127       vam->async_mode = 1;
6128       vam->async_errors = 0;
6129       before = vat_time_now (vam);
6130     }
6131
6132   for (j = 0; j < count; j++)
6133     {
6134       /* Construct the API message */
6135       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6136
6137       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6138       mp->mr_table_id = ntohl (table_id);
6139       mp->mr_create_table_if_needed = create_table_if_needed;
6140
6141       mp->mr_is_add = is_add;
6142       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6143       mp->mr_is_classify = is_classify;
6144       mp->mr_is_multipath = is_multipath;
6145       mp->mr_is_resolve_host = resolve_host;
6146       mp->mr_is_resolve_attached = resolve_attached;
6147       mp->mr_next_hop_weight = next_hop_weight;
6148       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6149       mp->mr_classify_table_index = ntohl (classify_table_index);
6150       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6151       mp->mr_label = ntohl (local_label);
6152       mp->mr_eos = is_eos;
6153
6154       if (next_hop_set)
6155         {
6156           if (next_hop_proto_is_ip4)
6157             {
6158               clib_memcpy (mp->mr_next_hop,
6159                            &v4_next_hop_address,
6160                            sizeof (v4_next_hop_address));
6161             }
6162           else
6163             {
6164               clib_memcpy (mp->mr_next_hop,
6165                            &v6_next_hop_address,
6166                            sizeof (v6_next_hop_address));
6167             }
6168         }
6169       local_label++;
6170
6171       /* send it... */
6172       S;
6173       /* If we receive SIGTERM, stop now... */
6174       if (vam->do_exit)
6175         break;
6176     }
6177
6178   /* When testing multiple add/del ops, use a control-ping to sync */
6179   if (count > 1)
6180     {
6181       vl_api_control_ping_t *mp;
6182       f64 after;
6183
6184       /* Shut off async mode */
6185       vam->async_mode = 0;
6186
6187       M (CONTROL_PING, control_ping);
6188       S;
6189
6190       timeout = vat_time_now (vam) + 1.0;
6191       while (vat_time_now (vam) < timeout)
6192         if (vam->result_ready == 1)
6193           goto out;
6194       vam->retval = -99;
6195
6196     out:
6197       if (vam->retval == -99)
6198         errmsg ("timeout\n");
6199
6200       if (vam->async_errors > 0)
6201         {
6202           errmsg ("%d asynchronous errors\n", vam->async_errors);
6203           vam->retval = -98;
6204         }
6205       vam->async_errors = 0;
6206       after = vat_time_now (vam);
6207
6208       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6209       if (j > 0)
6210         count = j;
6211
6212       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6213                count, after - before, count / (after - before));
6214     }
6215   else
6216     {
6217       /* Wait for a reply... */
6218       W;
6219     }
6220
6221   /* Return the good/bad news */
6222   return (vam->retval);
6223 }
6224
6225 static int
6226 api_mpls_ip_bind_unbind (vat_main_t * vam)
6227 {
6228   unformat_input_t *i = vam->input;
6229   vl_api_mpls_ip_bind_unbind_t *mp;
6230   f64 timeout;
6231   u32 ip_table_id = 0;
6232   u8 create_table_if_needed = 0;
6233   u8 is_bind = 1;
6234   u8 is_ip4 = 1;
6235   ip4_address_t v4_address;
6236   ip6_address_t v6_address;
6237   u32 address_length;
6238   u8 address_set = 0;
6239   mpls_label_t local_label = MPLS_LABEL_INVALID;
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "%U/%d", unformat_ip4_address,
6245                     &v4_address, &address_length))
6246         {
6247           is_ip4 = 1;
6248           address_set = 1;
6249         }
6250       else if (unformat (i, "%U/%d", unformat_ip6_address,
6251                          &v6_address, &address_length))
6252         {
6253           is_ip4 = 0;
6254           address_set = 1;
6255         }
6256       else if (unformat (i, "%d", &local_label))
6257         ;
6258       else if (unformat (i, "create-table"))
6259         create_table_if_needed = 1;
6260       else if (unformat (i, "table-id %d", &ip_table_id))
6261         ;
6262       else if (unformat (i, "unbind"))
6263         is_bind = 0;
6264       else if (unformat (i, "bind"))
6265         is_bind = 1;
6266       else
6267         {
6268           clib_warning ("parse error '%U'", format_unformat_error, i);
6269           return -99;
6270         }
6271     }
6272
6273   if (!address_set)
6274     {
6275       errmsg ("IP addres not set\n");
6276       return -99;
6277     }
6278
6279   if (MPLS_LABEL_INVALID == local_label)
6280     {
6281       errmsg ("missing label\n");
6282       return -99;
6283     }
6284
6285   /* Construct the API message */
6286   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6287
6288   mp->mb_create_table_if_needed = create_table_if_needed;
6289   mp->mb_is_bind = is_bind;
6290   mp->mb_is_ip4 = is_ip4;
6291   mp->mb_ip_table_id = ntohl (ip_table_id);
6292   mp->mb_mpls_table_id = 0;
6293   mp->mb_label = ntohl (local_label);
6294   mp->mb_address_length = address_length;
6295
6296   if (is_ip4)
6297     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6298   else
6299     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6300
6301   /* send it... */
6302   S;
6303
6304   /* Wait for a reply... */
6305   W;
6306 }
6307
6308 static int
6309 api_proxy_arp_add_del (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_proxy_arp_add_del_t *mp;
6313   f64 timeout;
6314   u32 vrf_id = 0;
6315   u8 is_add = 1;
6316   ip4_address_t lo, hi;
6317   u8 range_set = 0;
6318
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "vrf %d", &vrf_id))
6322         ;
6323       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6324                          unformat_ip4_address, &hi))
6325         range_set = 1;
6326       else if (unformat (i, "del"))
6327         is_add = 0;
6328       else
6329         {
6330           clib_warning ("parse error '%U'", format_unformat_error, i);
6331           return -99;
6332         }
6333     }
6334
6335   if (range_set == 0)
6336     {
6337       errmsg ("address range not set\n");
6338       return -99;
6339     }
6340
6341   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6342
6343   mp->vrf_id = ntohl (vrf_id);
6344   mp->is_add = is_add;
6345   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6346   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6347
6348   S;
6349   W;
6350   /* NOTREACHED */
6351   return 0;
6352 }
6353
6354 static int
6355 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6359   f64 timeout;
6360   u32 sw_if_index;
6361   u8 enable = 1;
6362   u8 sw_if_index_set = 0;
6363
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else if (unformat (i, "enable"))
6371         enable = 1;
6372       else if (unformat (i, "disable"))
6373         enable = 0;
6374       else
6375         {
6376           clib_warning ("parse error '%U'", format_unformat_error, i);
6377           return -99;
6378         }
6379     }
6380
6381   if (sw_if_index_set == 0)
6382     {
6383       errmsg ("missing interface name or sw_if_index\n");
6384       return -99;
6385     }
6386
6387   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6388
6389   mp->sw_if_index = ntohl (sw_if_index);
6390   mp->enable_disable = enable;
6391
6392   S;
6393   W;
6394   /* NOTREACHED */
6395   return 0;
6396 }
6397
6398 static int
6399 api_mpls_add_del_encap (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_mpls_add_del_encap_t *mp;
6403   f64 timeout;
6404   u32 vrf_id = 0;
6405   u32 *labels = 0;
6406   u32 label;
6407   ip4_address_t dst_address;
6408   u8 is_add = 1;
6409
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "vrf %d", &vrf_id))
6413         ;
6414       else if (unformat (i, "label %d", &label))
6415         vec_add1 (labels, ntohl (label));
6416       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6417         ;
6418       else if (unformat (i, "del"))
6419         is_add = 0;
6420       else
6421         {
6422           clib_warning ("parse error '%U'", format_unformat_error, i);
6423           return -99;
6424         }
6425     }
6426
6427   if (vec_len (labels) == 0)
6428     {
6429       errmsg ("missing encap label stack\n");
6430       return -99;
6431     }
6432
6433   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6434       sizeof (u32) * vec_len (labels));
6435
6436   mp->vrf_id = ntohl (vrf_id);
6437   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6438   mp->is_add = is_add;
6439   mp->nlabels = vec_len (labels);
6440   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6441
6442   vec_free (labels);
6443
6444   S;
6445   W;
6446   /* NOTREACHED */
6447   return 0;
6448 }
6449
6450 static int
6451 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6455   f64 timeout;
6456   u32 inner_vrf_id = 0;
6457   ip4_address_t intfc_address;
6458   u8 dst_mac_address[6];
6459   int dst_set = 1;
6460   u32 tmp;
6461   u8 intfc_address_length = 0;
6462   u8 is_add = 1;
6463   u8 l2_only = 0;
6464   u32 tx_sw_if_index;
6465   int tx_sw_if_index_set = 0;
6466
6467   /* Shut up coverity */
6468   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6469
6470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6471     {
6472       if (unformat (i, "vrf %d", &inner_vrf_id))
6473         ;
6474       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6475                          &intfc_address, &tmp))
6476         intfc_address_length = tmp;
6477       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6478         tx_sw_if_index_set = 1;
6479       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6480         tx_sw_if_index_set = 1;
6481       else if (unformat (i, "dst %U", unformat_ethernet_address,
6482                          dst_mac_address))
6483         dst_set = 1;
6484       else if (unformat (i, "l2-only"))
6485         l2_only = 1;
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else
6489         {
6490           clib_warning ("parse error '%U'", format_unformat_error, i);
6491           return -99;
6492         }
6493     }
6494
6495   if (!dst_set)
6496     {
6497       errmsg ("dst (mac address) not set\n");
6498       return -99;
6499     }
6500   if (!tx_sw_if_index_set)
6501     {
6502       errmsg ("tx-intfc not set\n");
6503       return -99;
6504     }
6505
6506   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6507
6508   mp->vrf_id = ntohl (inner_vrf_id);
6509   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6510   mp->adj_address_length = intfc_address_length;
6511   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6512                sizeof (dst_mac_address));
6513   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6514   mp->l2_only = l2_only;
6515   mp->is_add = is_add;
6516
6517   S;
6518   W;
6519   /* NOTREACHED */
6520   return 0;
6521 }
6522
6523 static int
6524 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6525 {
6526   unformat_input_t *i = vam->input;
6527   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6528   f64 timeout;
6529   u32 inner_vrf_id = 0;
6530   u32 outer_vrf_id = 0;
6531   ip4_address_t adj_address;
6532   int adj_address_set = 0;
6533   ip4_address_t next_hop_address;
6534   int next_hop_address_set = 0;
6535   u32 tmp;
6536   u8 adj_address_length = 0;
6537   u8 l2_only = 0;
6538   u8 is_add = 1;
6539   u32 resolve_attempts = 5;
6540   u8 resolve_if_needed = 1;
6541
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6545         ;
6546       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6547         ;
6548       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6549                          &adj_address, &tmp))
6550         {
6551           adj_address_length = tmp;
6552           adj_address_set = 1;
6553         }
6554       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6555                          &next_hop_address))
6556         next_hop_address_set = 1;
6557       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6558         ;
6559       else if (unformat (i, "resolve-if-needed %d", &tmp))
6560         resolve_if_needed = tmp;
6561       else if (unformat (i, "l2-only"))
6562         l2_only = 1;
6563       else if (unformat (i, "del"))
6564         is_add = 0;
6565       else
6566         {
6567           clib_warning ("parse error '%U'", format_unformat_error, i);
6568           return -99;
6569         }
6570     }
6571
6572   if (!adj_address_set)
6573     {
6574       errmsg ("adjacency address/mask not set\n");
6575       return -99;
6576     }
6577   if (!next_hop_address_set)
6578     {
6579       errmsg ("ip4 next hop address (in outer fib) not set\n");
6580       return -99;
6581     }
6582
6583   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6584
6585   mp->inner_vrf_id = ntohl (inner_vrf_id);
6586   mp->outer_vrf_id = ntohl (outer_vrf_id);
6587   mp->resolve_attempts = ntohl (resolve_attempts);
6588   mp->resolve_if_needed = resolve_if_needed;
6589   mp->is_add = is_add;
6590   mp->l2_only = l2_only;
6591   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6592   mp->adj_address_length = adj_address_length;
6593   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6594                sizeof (next_hop_address));
6595
6596   S;
6597   W;
6598   /* NOTREACHED */
6599   return 0;
6600 }
6601
6602 static int
6603 api_sw_interface_set_unnumbered (vat_main_t * vam)
6604 {
6605   unformat_input_t *i = vam->input;
6606   vl_api_sw_interface_set_unnumbered_t *mp;
6607   f64 timeout;
6608   u32 sw_if_index;
6609   u32 unnum_sw_index = ~0;
6610   u8 is_add = 1;
6611   u8 sw_if_index_set = 0;
6612
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6620         ;
6621       else if (unformat (i, "del"))
6622         is_add = 0;
6623       else
6624         {
6625           clib_warning ("parse error '%U'", format_unformat_error, i);
6626           return -99;
6627         }
6628     }
6629
6630   if (sw_if_index_set == 0)
6631     {
6632       errmsg ("missing interface name or sw_if_index\n");
6633       return -99;
6634     }
6635
6636   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6637
6638   mp->sw_if_index = ntohl (sw_if_index);
6639   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6640   mp->is_add = is_add;
6641
6642   S;
6643   W;
6644   /* NOTREACHED */
6645   return 0;
6646 }
6647
6648 static int
6649 api_ip_neighbor_add_del (vat_main_t * vam)
6650 {
6651   unformat_input_t *i = vam->input;
6652   vl_api_ip_neighbor_add_del_t *mp;
6653   f64 timeout;
6654   u32 sw_if_index;
6655   u8 sw_if_index_set = 0;
6656   u32 vrf_id = 0;
6657   u8 is_add = 1;
6658   u8 is_static = 0;
6659   u8 mac_address[6];
6660   u8 mac_set = 0;
6661   u8 v4_address_set = 0;
6662   u8 v6_address_set = 0;
6663   ip4_address_t v4address;
6664   ip6_address_t v6address;
6665
6666   memset (mac_address, 0, sizeof (mac_address));
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6672         {
6673           mac_set = 1;
6674         }
6675       else if (unformat (i, "del"))
6676         is_add = 0;
6677       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6680         sw_if_index_set = 1;
6681       else if (unformat (i, "is_static"))
6682         is_static = 1;
6683       else if (unformat (i, "vrf %d", &vrf_id))
6684         ;
6685       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6686         v4_address_set = 1;
6687       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6688         v6_address_set = 1;
6689       else
6690         {
6691           clib_warning ("parse error '%U'", format_unformat_error, i);
6692           return -99;
6693         }
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index\n");
6699       return -99;
6700     }
6701   if (v4_address_set && v6_address_set)
6702     {
6703       errmsg ("both v4 and v6 addresses set\n");
6704       return -99;
6705     }
6706   if (!v4_address_set && !v6_address_set)
6707     {
6708       errmsg ("no address set\n");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->is_add = is_add;
6717   mp->vrf_id = ntohl (vrf_id);
6718   mp->is_static = is_static;
6719   if (mac_set)
6720     clib_memcpy (mp->mac_address, mac_address, 6);
6721   if (v6_address_set)
6722     {
6723       mp->is_ipv6 = 1;
6724       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6725     }
6726   else
6727     {
6728       /* mp->is_ipv6 = 0; via memset in M macro above */
6729       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6730     }
6731
6732   /* send it... */
6733   S;
6734
6735   /* Wait for a reply, return good/bad news  */
6736   W;
6737
6738   /* NOTREACHED */
6739   return 0;
6740 }
6741
6742 static int
6743 api_reset_vrf (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_reset_vrf_t *mp;
6747   f64 timeout;
6748   u32 vrf_id = 0;
6749   u8 is_ipv6 = 0;
6750   u8 vrf_id_set = 0;
6751
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "vrf %d", &vrf_id))
6755         vrf_id_set = 1;
6756       else if (unformat (i, "ipv6"))
6757         is_ipv6 = 1;
6758       else
6759         {
6760           clib_warning ("parse error '%U'", format_unformat_error, i);
6761           return -99;
6762         }
6763     }
6764
6765   if (vrf_id_set == 0)
6766     {
6767       errmsg ("missing vrf id\n");
6768       return -99;
6769     }
6770
6771   M (RESET_VRF, reset_vrf);
6772
6773   mp->vrf_id = ntohl (vrf_id);
6774   mp->is_ipv6 = is_ipv6;
6775
6776   S;
6777   W;
6778   /* NOTREACHED */
6779   return 0;
6780 }
6781
6782 static int
6783 api_create_vlan_subif (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_create_vlan_subif_t *mp;
6787   f64 timeout;
6788   u32 sw_if_index;
6789   u8 sw_if_index_set = 0;
6790   u32 vlan_id;
6791   u8 vlan_id_set = 0;
6792
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "sw_if_index %d", &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "vlan %d", &vlan_id))
6800         vlan_id_set = 1;
6801       else
6802         {
6803           clib_warning ("parse error '%U'", format_unformat_error, i);
6804           return -99;
6805         }
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index\n");
6811       return -99;
6812     }
6813
6814   if (vlan_id_set == 0)
6815     {
6816       errmsg ("missing vlan_id\n");
6817       return -99;
6818     }
6819   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6820
6821   mp->sw_if_index = ntohl (sw_if_index);
6822   mp->vlan_id = ntohl (vlan_id);
6823
6824   S;
6825   W;
6826   /* NOTREACHED */
6827   return 0;
6828 }
6829
6830 #define foreach_create_subif_bit                \
6831 _(no_tags)                                      \
6832 _(one_tag)                                      \
6833 _(two_tags)                                     \
6834 _(dot1ad)                                       \
6835 _(exact_match)                                  \
6836 _(default_sub)                                  \
6837 _(outer_vlan_id_any)                            \
6838 _(inner_vlan_id_any)
6839
6840 static int
6841 api_create_subif (vat_main_t * vam)
6842 {
6843   unformat_input_t *i = vam->input;
6844   vl_api_create_subif_t *mp;
6845   f64 timeout;
6846   u32 sw_if_index;
6847   u8 sw_if_index_set = 0;
6848   u32 sub_id;
6849   u8 sub_id_set = 0;
6850   u32 no_tags = 0;
6851   u32 one_tag = 0;
6852   u32 two_tags = 0;
6853   u32 dot1ad = 0;
6854   u32 exact_match = 0;
6855   u32 default_sub = 0;
6856   u32 outer_vlan_id_any = 0;
6857   u32 inner_vlan_id_any = 0;
6858   u32 tmp;
6859   u16 outer_vlan_id = 0;
6860   u16 inner_vlan_id = 0;
6861
6862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6863     {
6864       if (unformat (i, "sw_if_index %d", &sw_if_index))
6865         sw_if_index_set = 1;
6866       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6867         sw_if_index_set = 1;
6868       else if (unformat (i, "sub_id %d", &sub_id))
6869         sub_id_set = 1;
6870       else if (unformat (i, "outer_vlan_id %d", &tmp))
6871         outer_vlan_id = tmp;
6872       else if (unformat (i, "inner_vlan_id %d", &tmp))
6873         inner_vlan_id = tmp;
6874
6875 #define _(a) else if (unformat (i, #a)) a = 1 ;
6876       foreach_create_subif_bit
6877 #undef _
6878         else
6879         {
6880           clib_warning ("parse error '%U'", format_unformat_error, i);
6881           return -99;
6882         }
6883     }
6884
6885   if (sw_if_index_set == 0)
6886     {
6887       errmsg ("missing interface name or sw_if_index\n");
6888       return -99;
6889     }
6890
6891   if (sub_id_set == 0)
6892     {
6893       errmsg ("missing sub_id\n");
6894       return -99;
6895     }
6896   M (CREATE_SUBIF, create_subif);
6897
6898   mp->sw_if_index = ntohl (sw_if_index);
6899   mp->sub_id = ntohl (sub_id);
6900
6901 #define _(a) mp->a = a;
6902   foreach_create_subif_bit;
6903 #undef _
6904
6905   mp->outer_vlan_id = ntohs (outer_vlan_id);
6906   mp->inner_vlan_id = ntohs (inner_vlan_id);
6907
6908   S;
6909   W;
6910   /* NOTREACHED */
6911   return 0;
6912 }
6913
6914 static int
6915 api_oam_add_del (vat_main_t * vam)
6916 {
6917   unformat_input_t *i = vam->input;
6918   vl_api_oam_add_del_t *mp;
6919   f64 timeout;
6920   u32 vrf_id = 0;
6921   u8 is_add = 1;
6922   ip4_address_t src, dst;
6923   u8 src_set = 0;
6924   u8 dst_set = 0;
6925
6926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6927     {
6928       if (unformat (i, "vrf %d", &vrf_id))
6929         ;
6930       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6931         src_set = 1;
6932       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6933         dst_set = 1;
6934       else if (unformat (i, "del"))
6935         is_add = 0;
6936       else
6937         {
6938           clib_warning ("parse error '%U'", format_unformat_error, i);
6939           return -99;
6940         }
6941     }
6942
6943   if (src_set == 0)
6944     {
6945       errmsg ("missing src addr\n");
6946       return -99;
6947     }
6948
6949   if (dst_set == 0)
6950     {
6951       errmsg ("missing dst addr\n");
6952       return -99;
6953     }
6954
6955   M (OAM_ADD_DEL, oam_add_del);
6956
6957   mp->vrf_id = ntohl (vrf_id);
6958   mp->is_add = is_add;
6959   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6960   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6961
6962   S;
6963   W;
6964   /* NOTREACHED */
6965   return 0;
6966 }
6967
6968 static int
6969 api_reset_fib (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_reset_fib_t *mp;
6973   f64 timeout;
6974   u32 vrf_id = 0;
6975   u8 is_ipv6 = 0;
6976   u8 vrf_id_set = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "vrf %d", &vrf_id))
6981         vrf_id_set = 1;
6982       else if (unformat (i, "ipv6"))
6983         is_ipv6 = 1;
6984       else
6985         {
6986           clib_warning ("parse error '%U'", format_unformat_error, i);
6987           return -99;
6988         }
6989     }
6990
6991   if (vrf_id_set == 0)
6992     {
6993       errmsg ("missing vrf id\n");
6994       return -99;
6995     }
6996
6997   M (RESET_FIB, reset_fib);
6998
6999   mp->vrf_id = ntohl (vrf_id);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S;
7003   W;
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_dhcp_proxy_config (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_dhcp_proxy_config_t *mp;
7013   f64 timeout;
7014   u32 vrf_id = 0;
7015   u8 is_add = 1;
7016   u8 insert_cid = 1;
7017   u8 v4_address_set = 0;
7018   u8 v6_address_set = 0;
7019   ip4_address_t v4address;
7020   ip6_address_t v6address;
7021   u8 v4_src_address_set = 0;
7022   u8 v6_src_address_set = 0;
7023   ip4_address_t v4srcaddress;
7024   ip6_address_t v6srcaddress;
7025
7026   /* Parse args required to build the message */
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "del"))
7030         is_add = 0;
7031       else if (unformat (i, "vrf %d", &vrf_id))
7032         ;
7033       else if (unformat (i, "insert-cid %d", &insert_cid))
7034         ;
7035       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7036         v4_address_set = 1;
7037       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7038         v6_address_set = 1;
7039       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7040         v4_src_address_set = 1;
7041       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7042         v6_src_address_set = 1;
7043       else
7044         break;
7045     }
7046
7047   if (v4_address_set && v6_address_set)
7048     {
7049       errmsg ("both v4 and v6 server addresses set\n");
7050       return -99;
7051     }
7052   if (!v4_address_set && !v6_address_set)
7053     {
7054       errmsg ("no server addresses set\n");
7055       return -99;
7056     }
7057
7058   if (v4_src_address_set && v6_src_address_set)
7059     {
7060       errmsg ("both v4 and v6  src addresses set\n");
7061       return -99;
7062     }
7063   if (!v4_src_address_set && !v6_src_address_set)
7064     {
7065       errmsg ("no src addresses set\n");
7066       return -99;
7067     }
7068
7069   if (!(v4_src_address_set && v4_address_set) &&
7070       !(v6_src_address_set && v6_address_set))
7071     {
7072       errmsg ("no matching server and src addresses set\n");
7073       return -99;
7074     }
7075
7076   /* Construct the API message */
7077   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7078
7079   mp->insert_circuit_id = insert_cid;
7080   mp->is_add = is_add;
7081   mp->vrf_id = ntohl (vrf_id);
7082   if (v6_address_set)
7083     {
7084       mp->is_ipv6 = 1;
7085       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7086       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7087     }
7088   else
7089     {
7090       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7091       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7092     }
7093
7094   /* send it... */
7095   S;
7096
7097   /* Wait for a reply, return good/bad news  */
7098   W;
7099   /* NOTREACHED */
7100   return 0;
7101 }
7102
7103 static int
7104 api_dhcp_proxy_config_2 (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_dhcp_proxy_config_2_t *mp;
7108   f64 timeout;
7109   u32 rx_vrf_id = 0;
7110   u32 server_vrf_id = 0;
7111   u8 is_add = 1;
7112   u8 insert_cid = 1;
7113   u8 v4_address_set = 0;
7114   u8 v6_address_set = 0;
7115   ip4_address_t v4address;
7116   ip6_address_t v6address;
7117   u8 v4_src_address_set = 0;
7118   u8 v6_src_address_set = 0;
7119   ip4_address_t v4srcaddress;
7120   ip6_address_t v6srcaddress;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "del"))
7126         is_add = 0;
7127       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7128         ;
7129       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7130         ;
7131       else if (unformat (i, "insert-cid %d", &insert_cid))
7132         ;
7133       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7134         v4_address_set = 1;
7135       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7136         v6_address_set = 1;
7137       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7138         v4_src_address_set = 1;
7139       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7140         v6_src_address_set = 1;
7141       else
7142         break;
7143     }
7144
7145   if (v4_address_set && v6_address_set)
7146     {
7147       errmsg ("both v4 and v6 server addresses set\n");
7148       return -99;
7149     }
7150   if (!v4_address_set && !v6_address_set)
7151     {
7152       errmsg ("no server addresses set\n");
7153       return -99;
7154     }
7155
7156   if (v4_src_address_set && v6_src_address_set)
7157     {
7158       errmsg ("both v4 and v6  src addresses set\n");
7159       return -99;
7160     }
7161   if (!v4_src_address_set && !v6_src_address_set)
7162     {
7163       errmsg ("no src addresses set\n");
7164       return -99;
7165     }
7166
7167   if (!(v4_src_address_set && v4_address_set) &&
7168       !(v6_src_address_set && v6_address_set))
7169     {
7170       errmsg ("no matching server and src addresses set\n");
7171       return -99;
7172     }
7173
7174   /* Construct the API message */
7175   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7176
7177   mp->insert_circuit_id = insert_cid;
7178   mp->is_add = is_add;
7179   mp->rx_vrf_id = ntohl (rx_vrf_id);
7180   mp->server_vrf_id = ntohl (server_vrf_id);
7181   if (v6_address_set)
7182     {
7183       mp->is_ipv6 = 1;
7184       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7185       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7186     }
7187   else
7188     {
7189       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7190       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7191     }
7192
7193   /* send it... */
7194   S;
7195
7196   /* Wait for a reply, return good/bad news  */
7197   W;
7198   /* NOTREACHED */
7199   return 0;
7200 }
7201
7202 static int
7203 api_dhcp_proxy_set_vss (vat_main_t * vam)
7204 {
7205   unformat_input_t *i = vam->input;
7206   vl_api_dhcp_proxy_set_vss_t *mp;
7207   f64 timeout;
7208   u8 is_ipv6 = 0;
7209   u8 is_add = 1;
7210   u32 tbl_id;
7211   u8 tbl_id_set = 0;
7212   u32 oui;
7213   u8 oui_set = 0;
7214   u32 fib_id;
7215   u8 fib_id_set = 0;
7216
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "tbl_id %d", &tbl_id))
7220         tbl_id_set = 1;
7221       if (unformat (i, "fib_id %d", &fib_id))
7222         fib_id_set = 1;
7223       if (unformat (i, "oui %d", &oui))
7224         oui_set = 1;
7225       else if (unformat (i, "ipv6"))
7226         is_ipv6 = 1;
7227       else if (unformat (i, "del"))
7228         is_add = 0;
7229       else
7230         {
7231           clib_warning ("parse error '%U'", format_unformat_error, i);
7232           return -99;
7233         }
7234     }
7235
7236   if (tbl_id_set == 0)
7237     {
7238       errmsg ("missing tbl id\n");
7239       return -99;
7240     }
7241
7242   if (fib_id_set == 0)
7243     {
7244       errmsg ("missing fib id\n");
7245       return -99;
7246     }
7247   if (oui_set == 0)
7248     {
7249       errmsg ("missing oui\n");
7250       return -99;
7251     }
7252
7253   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7254   mp->tbl_id = ntohl (tbl_id);
7255   mp->fib_id = ntohl (fib_id);
7256   mp->oui = ntohl (oui);
7257   mp->is_ipv6 = is_ipv6;
7258   mp->is_add = is_add;
7259
7260   S;
7261   W;
7262   /* NOTREACHED */
7263   return 0;
7264 }
7265
7266 static int
7267 api_dhcp_client_config (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_dhcp_client_config_t *mp;
7271   f64 timeout;
7272   u32 sw_if_index;
7273   u8 sw_if_index_set = 0;
7274   u8 is_add = 1;
7275   u8 *hostname = 0;
7276   u8 disable_event = 0;
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7286         sw_if_index_set = 1;
7287       else if (unformat (i, "hostname %s", &hostname))
7288         ;
7289       else if (unformat (i, "disable_event"))
7290         disable_event = 1;
7291       else
7292         break;
7293     }
7294
7295   if (sw_if_index_set == 0)
7296     {
7297       errmsg ("missing interface name or sw_if_index\n");
7298       return -99;
7299     }
7300
7301   if (vec_len (hostname) > 63)
7302     {
7303       errmsg ("hostname too long\n");
7304     }
7305   vec_add1 (hostname, 0);
7306
7307   /* Construct the API message */
7308   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7309
7310   mp->sw_if_index = ntohl (sw_if_index);
7311   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7312   vec_free (hostname);
7313   mp->is_add = is_add;
7314   mp->want_dhcp_event = disable_event ? 0 : 1;
7315   mp->pid = getpid ();
7316
7317   /* send it... */
7318   S;
7319
7320   /* Wait for a reply, return good/bad news  */
7321   W;
7322   /* NOTREACHED */
7323   return 0;
7324 }
7325
7326 static int
7327 api_set_ip_flow_hash (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_set_ip_flow_hash_t *mp;
7331   f64 timeout;
7332   u32 vrf_id = 0;
7333   u8 is_ipv6 = 0;
7334   u8 vrf_id_set = 0;
7335   u8 src = 0;
7336   u8 dst = 0;
7337   u8 sport = 0;
7338   u8 dport = 0;
7339   u8 proto = 0;
7340   u8 reverse = 0;
7341
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "vrf %d", &vrf_id))
7345         vrf_id_set = 1;
7346       else if (unformat (i, "ipv6"))
7347         is_ipv6 = 1;
7348       else if (unformat (i, "src"))
7349         src = 1;
7350       else if (unformat (i, "dst"))
7351         dst = 1;
7352       else if (unformat (i, "sport"))
7353         sport = 1;
7354       else if (unformat (i, "dport"))
7355         dport = 1;
7356       else if (unformat (i, "proto"))
7357         proto = 1;
7358       else if (unformat (i, "reverse"))
7359         reverse = 1;
7360
7361       else
7362         {
7363           clib_warning ("parse error '%U'", format_unformat_error, i);
7364           return -99;
7365         }
7366     }
7367
7368   if (vrf_id_set == 0)
7369     {
7370       errmsg ("missing vrf id\n");
7371       return -99;
7372     }
7373
7374   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7375   mp->src = src;
7376   mp->dst = dst;
7377   mp->sport = sport;
7378   mp->dport = dport;
7379   mp->proto = proto;
7380   mp->reverse = reverse;
7381   mp->vrf_id = ntohl (vrf_id);
7382   mp->is_ipv6 = is_ipv6;
7383
7384   S;
7385   W;
7386   /* NOTREACHED */
7387   return 0;
7388 }
7389
7390 static int
7391 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_sw_interface_ip6_enable_disable_t *mp;
7395   f64 timeout;
7396   u32 sw_if_index;
7397   u8 sw_if_index_set = 0;
7398   u8 enable = 0;
7399
7400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7401     {
7402       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7403         sw_if_index_set = 1;
7404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7405         sw_if_index_set = 1;
7406       else if (unformat (i, "enable"))
7407         enable = 1;
7408       else if (unformat (i, "disable"))
7409         enable = 0;
7410       else
7411         {
7412           clib_warning ("parse error '%U'", format_unformat_error, i);
7413           return -99;
7414         }
7415     }
7416
7417   if (sw_if_index_set == 0)
7418     {
7419       errmsg ("missing interface name or sw_if_index\n");
7420       return -99;
7421     }
7422
7423   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7424
7425   mp->sw_if_index = ntohl (sw_if_index);
7426   mp->enable = enable;
7427
7428   S;
7429   W;
7430   /* NOTREACHED */
7431   return 0;
7432 }
7433
7434 static int
7435 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7439   f64 timeout;
7440   u32 sw_if_index;
7441   u8 sw_if_index_set = 0;
7442   u32 address_length = 0;
7443   u8 v6_address_set = 0;
7444   ip6_address_t v6address;
7445
7446   /* Parse args required to build the message */
7447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7448     {
7449       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7450         sw_if_index_set = 1;
7451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7452         sw_if_index_set = 1;
7453       else if (unformat (i, "%U/%d",
7454                          unformat_ip6_address, &v6address, &address_length))
7455         v6_address_set = 1;
7456       else
7457         break;
7458     }
7459
7460   if (sw_if_index_set == 0)
7461     {
7462       errmsg ("missing interface name or sw_if_index\n");
7463       return -99;
7464     }
7465   if (!v6_address_set)
7466     {
7467       errmsg ("no address set\n");
7468       return -99;
7469     }
7470
7471   /* Construct the API message */
7472   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7473      sw_interface_ip6_set_link_local_address);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7477   mp->address_length = address_length;
7478
7479   /* send it... */
7480   S;
7481
7482   /* Wait for a reply, return good/bad news  */
7483   W;
7484
7485   /* NOTREACHED */
7486   return 0;
7487 }
7488
7489
7490 static int
7491 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7495   f64 timeout;
7496   u32 sw_if_index;
7497   u8 sw_if_index_set = 0;
7498   u32 address_length = 0;
7499   u8 v6_address_set = 0;
7500   ip6_address_t v6address;
7501   u8 use_default = 0;
7502   u8 no_advertise = 0;
7503   u8 off_link = 0;
7504   u8 no_autoconfig = 0;
7505   u8 no_onlink = 0;
7506   u8 is_no = 0;
7507   u32 val_lifetime = 0;
7508   u32 pref_lifetime = 0;
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7514         sw_if_index_set = 1;
7515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "%U/%d",
7518                          unformat_ip6_address, &v6address, &address_length))
7519         v6_address_set = 1;
7520       else if (unformat (i, "val_life %d", &val_lifetime))
7521         ;
7522       else if (unformat (i, "pref_life %d", &pref_lifetime))
7523         ;
7524       else if (unformat (i, "def"))
7525         use_default = 1;
7526       else if (unformat (i, "noadv"))
7527         no_advertise = 1;
7528       else if (unformat (i, "offl"))
7529         off_link = 1;
7530       else if (unformat (i, "noauto"))
7531         no_autoconfig = 1;
7532       else if (unformat (i, "nolink"))
7533         no_onlink = 1;
7534       else if (unformat (i, "isno"))
7535         is_no = 1;
7536       else
7537         {
7538           clib_warning ("parse error '%U'", format_unformat_error, i);
7539           return -99;
7540         }
7541     }
7542
7543   if (sw_if_index_set == 0)
7544     {
7545       errmsg ("missing interface name or sw_if_index\n");
7546       return -99;
7547     }
7548   if (!v6_address_set)
7549     {
7550       errmsg ("no address set\n");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7556
7557   mp->sw_if_index = ntohl (sw_if_index);
7558   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7559   mp->address_length = address_length;
7560   mp->use_default = use_default;
7561   mp->no_advertise = no_advertise;
7562   mp->off_link = off_link;
7563   mp->no_autoconfig = no_autoconfig;
7564   mp->no_onlink = no_onlink;
7565   mp->is_no = is_no;
7566   mp->val_lifetime = ntohl (val_lifetime);
7567   mp->pref_lifetime = ntohl (pref_lifetime);
7568
7569   /* send it... */
7570   S;
7571
7572   /* Wait for a reply, return good/bad news  */
7573   W;
7574
7575   /* NOTREACHED */
7576   return 0;
7577 }
7578
7579 static int
7580 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7581 {
7582   unformat_input_t *i = vam->input;
7583   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7584   f64 timeout;
7585   u32 sw_if_index;
7586   u8 sw_if_index_set = 0;
7587   u8 suppress = 0;
7588   u8 managed = 0;
7589   u8 other = 0;
7590   u8 ll_option = 0;
7591   u8 send_unicast = 0;
7592   u8 cease = 0;
7593   u8 is_no = 0;
7594   u8 default_router = 0;
7595   u32 max_interval = 0;
7596   u32 min_interval = 0;
7597   u32 lifetime = 0;
7598   u32 initial_count = 0;
7599   u32 initial_interval = 0;
7600
7601
7602   /* Parse args required to build the message */
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7606         sw_if_index_set = 1;
7607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7608         sw_if_index_set = 1;
7609       else if (unformat (i, "maxint %d", &max_interval))
7610         ;
7611       else if (unformat (i, "minint %d", &min_interval))
7612         ;
7613       else if (unformat (i, "life %d", &lifetime))
7614         ;
7615       else if (unformat (i, "count %d", &initial_count))
7616         ;
7617       else if (unformat (i, "interval %d", &initial_interval))
7618         ;
7619       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7620         suppress = 1;
7621       else if (unformat (i, "managed"))
7622         managed = 1;
7623       else if (unformat (i, "other"))
7624         other = 1;
7625       else if (unformat (i, "ll"))
7626         ll_option = 1;
7627       else if (unformat (i, "send"))
7628         send_unicast = 1;
7629       else if (unformat (i, "cease"))
7630         cease = 1;
7631       else if (unformat (i, "isno"))
7632         is_no = 1;
7633       else if (unformat (i, "def"))
7634         default_router = 1;
7635       else
7636         {
7637           clib_warning ("parse error '%U'", format_unformat_error, i);
7638           return -99;
7639         }
7640     }
7641
7642   if (sw_if_index_set == 0)
7643     {
7644       errmsg ("missing interface name or sw_if_index\n");
7645       return -99;
7646     }
7647
7648   /* Construct the API message */
7649   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7650
7651   mp->sw_if_index = ntohl (sw_if_index);
7652   mp->max_interval = ntohl (max_interval);
7653   mp->min_interval = ntohl (min_interval);
7654   mp->lifetime = ntohl (lifetime);
7655   mp->initial_count = ntohl (initial_count);
7656   mp->initial_interval = ntohl (initial_interval);
7657   mp->suppress = suppress;
7658   mp->managed = managed;
7659   mp->other = other;
7660   mp->ll_option = ll_option;
7661   mp->send_unicast = send_unicast;
7662   mp->cease = cease;
7663   mp->is_no = is_no;
7664   mp->default_router = default_router;
7665
7666   /* send it... */
7667   S;
7668
7669   /* Wait for a reply, return good/bad news  */
7670   W;
7671
7672   /* NOTREACHED */
7673   return 0;
7674 }
7675
7676 static int
7677 api_set_arp_neighbor_limit (vat_main_t * vam)
7678 {
7679   unformat_input_t *i = vam->input;
7680   vl_api_set_arp_neighbor_limit_t *mp;
7681   f64 timeout;
7682   u32 arp_nbr_limit;
7683   u8 limit_set = 0;
7684   u8 is_ipv6 = 0;
7685
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7689         limit_set = 1;
7690       else if (unformat (i, "ipv6"))
7691         is_ipv6 = 1;
7692       else
7693         {
7694           clib_warning ("parse error '%U'", format_unformat_error, i);
7695           return -99;
7696         }
7697     }
7698
7699   if (limit_set == 0)
7700     {
7701       errmsg ("missing limit value\n");
7702       return -99;
7703     }
7704
7705   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7706
7707   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7708   mp->is_ipv6 = is_ipv6;
7709
7710   S;
7711   W;
7712   /* NOTREACHED */
7713   return 0;
7714 }
7715
7716 static int
7717 api_l2_patch_add_del (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_l2_patch_add_del_t *mp;
7721   f64 timeout;
7722   u32 rx_sw_if_index;
7723   u8 rx_sw_if_index_set = 0;
7724   u32 tx_sw_if_index;
7725   u8 tx_sw_if_index_set = 0;
7726   u8 is_add = 1;
7727
7728   /* Parse args required to build the message */
7729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7730     {
7731       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7732         rx_sw_if_index_set = 1;
7733       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7734         tx_sw_if_index_set = 1;
7735       else if (unformat (i, "rx"))
7736         {
7737           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738             {
7739               if (unformat (i, "%U", unformat_sw_if_index, vam,
7740                             &rx_sw_if_index))
7741                 rx_sw_if_index_set = 1;
7742             }
7743           else
7744             break;
7745         }
7746       else if (unformat (i, "tx"))
7747         {
7748           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749             {
7750               if (unformat (i, "%U", unformat_sw_if_index, vam,
7751                             &tx_sw_if_index))
7752                 tx_sw_if_index_set = 1;
7753             }
7754           else
7755             break;
7756         }
7757       else if (unformat (i, "del"))
7758         is_add = 0;
7759       else
7760         break;
7761     }
7762
7763   if (rx_sw_if_index_set == 0)
7764     {
7765       errmsg ("missing rx interface name or rx_sw_if_index\n");
7766       return -99;
7767     }
7768
7769   if (tx_sw_if_index_set == 0)
7770     {
7771       errmsg ("missing tx interface name or tx_sw_if_index\n");
7772       return -99;
7773     }
7774
7775   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7776
7777   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7778   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7779   mp->is_add = is_add;
7780
7781   S;
7782   W;
7783   /* NOTREACHED */
7784   return 0;
7785 }
7786
7787 static int
7788 api_ioam_enable (vat_main_t * vam)
7789 {
7790   unformat_input_t *input = vam->input;
7791   vl_api_ioam_enable_t *mp;
7792   f64 timeout;
7793   u32 id = 0;
7794   int has_trace_option = 0;
7795   int has_pot_option = 0;
7796   int has_seqno_option = 0;
7797   int has_analyse_option = 0;
7798
7799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (input, "trace"))
7802         has_trace_option = 1;
7803       else if (unformat (input, "pot"))
7804         has_pot_option = 1;
7805       else if (unformat (input, "seqno"))
7806         has_seqno_option = 1;
7807       else if (unformat (input, "analyse"))
7808         has_analyse_option = 1;
7809       else
7810         break;
7811     }
7812   M (IOAM_ENABLE, ioam_enable);
7813   mp->id = htons (id);
7814   mp->seqno = has_seqno_option;
7815   mp->analyse = has_analyse_option;
7816   mp->pot_enable = has_pot_option;
7817   mp->trace_enable = has_trace_option;
7818
7819   S;
7820   W;
7821
7822   return (0);
7823
7824 }
7825
7826
7827 static int
7828 api_ioam_disable (vat_main_t * vam)
7829 {
7830   vl_api_ioam_disable_t *mp;
7831   f64 timeout;
7832
7833   M (IOAM_DISABLE, ioam_disable);
7834   S;
7835   W;
7836   return 0;
7837 }
7838
7839 static int
7840 api_sr_tunnel_add_del (vat_main_t * vam)
7841 {
7842   unformat_input_t *i = vam->input;
7843   vl_api_sr_tunnel_add_del_t *mp;
7844   f64 timeout;
7845   int is_del = 0;
7846   int pl_index;
7847   ip6_address_t src_address;
7848   int src_address_set = 0;
7849   ip6_address_t dst_address;
7850   u32 dst_mask_width;
7851   int dst_address_set = 0;
7852   u16 flags = 0;
7853   u32 rx_table_id = 0;
7854   u32 tx_table_id = 0;
7855   ip6_address_t *segments = 0;
7856   ip6_address_t *this_seg;
7857   ip6_address_t *tags = 0;
7858   ip6_address_t *this_tag;
7859   ip6_address_t next_address, tag;
7860   u8 *name = 0;
7861   u8 *policy_name = 0;
7862
7863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7864     {
7865       if (unformat (i, "del"))
7866         is_del = 1;
7867       else if (unformat (i, "name %s", &name))
7868         ;
7869       else if (unformat (i, "policy %s", &policy_name))
7870         ;
7871       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7872         ;
7873       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7874         ;
7875       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7876         src_address_set = 1;
7877       else if (unformat (i, "dst %U/%d",
7878                          unformat_ip6_address, &dst_address, &dst_mask_width))
7879         dst_address_set = 1;
7880       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7881         {
7882           vec_add2 (segments, this_seg, 1);
7883           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7884                        sizeof (*this_seg));
7885         }
7886       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7887         {
7888           vec_add2 (tags, this_tag, 1);
7889           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7890         }
7891       else if (unformat (i, "clean"))
7892         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7893       else if (unformat (i, "protected"))
7894         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7895       else if (unformat (i, "InPE %d", &pl_index))
7896         {
7897           if (pl_index <= 0 || pl_index > 4)
7898             {
7899             pl_index_range_error:
7900               errmsg ("pl index %d out of range\n", pl_index);
7901               return -99;
7902             }
7903           flags |=
7904             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7905         }
7906       else if (unformat (i, "EgPE %d", &pl_index))
7907         {
7908           if (pl_index <= 0 || pl_index > 4)
7909             goto pl_index_range_error;
7910           flags |=
7911             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7912         }
7913       else if (unformat (i, "OrgSrc %d", &pl_index))
7914         {
7915           if (pl_index <= 0 || pl_index > 4)
7916             goto pl_index_range_error;
7917           flags |=
7918             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7919         }
7920       else
7921         break;
7922     }
7923
7924   if (!src_address_set)
7925     {
7926       errmsg ("src address required\n");
7927       return -99;
7928     }
7929
7930   if (!dst_address_set)
7931     {
7932       errmsg ("dst address required\n");
7933       return -99;
7934     }
7935
7936   if (!segments)
7937     {
7938       errmsg ("at least one sr segment required\n");
7939       return -99;
7940     }
7941
7942   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7943       vec_len (segments) * sizeof (ip6_address_t)
7944       + vec_len (tags) * sizeof (ip6_address_t));
7945
7946   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7947   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7948   mp->dst_mask_width = dst_mask_width;
7949   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7950   mp->n_segments = vec_len (segments);
7951   mp->n_tags = vec_len (tags);
7952   mp->is_add = is_del == 0;
7953   clib_memcpy (mp->segs_and_tags, segments,
7954                vec_len (segments) * sizeof (ip6_address_t));
7955   clib_memcpy (mp->segs_and_tags +
7956                vec_len (segments) * sizeof (ip6_address_t), tags,
7957                vec_len (tags) * sizeof (ip6_address_t));
7958
7959   mp->outer_vrf_id = ntohl (rx_table_id);
7960   mp->inner_vrf_id = ntohl (tx_table_id);
7961   memcpy (mp->name, name, vec_len (name));
7962   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7963
7964   vec_free (segments);
7965   vec_free (tags);
7966
7967   S;
7968   W;
7969   /* NOTREACHED */
7970 }
7971
7972 static int
7973 api_sr_policy_add_del (vat_main_t * vam)
7974 {
7975   unformat_input_t *input = vam->input;
7976   vl_api_sr_policy_add_del_t *mp;
7977   f64 timeout;
7978   int is_del = 0;
7979   u8 *name = 0;
7980   u8 *tunnel_name = 0;
7981   u8 **tunnel_names = 0;
7982
7983   int name_set = 0;
7984   int tunnel_set = 0;
7985   int j = 0;
7986   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7987   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7988
7989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7990     {
7991       if (unformat (input, "del"))
7992         is_del = 1;
7993       else if (unformat (input, "name %s", &name))
7994         name_set = 1;
7995       else if (unformat (input, "tunnel %s", &tunnel_name))
7996         {
7997           if (tunnel_name)
7998             {
7999               vec_add1 (tunnel_names, tunnel_name);
8000               /* For serializer:
8001                  - length = #bytes to store in serial vector
8002                  - +1 = byte to store that length
8003                */
8004               tunnel_names_length += (vec_len (tunnel_name) + 1);
8005               tunnel_set = 1;
8006               tunnel_name = 0;
8007             }
8008         }
8009       else
8010         break;
8011     }
8012
8013   if (!name_set)
8014     {
8015       errmsg ("policy name required\n");
8016       return -99;
8017     }
8018
8019   if ((!tunnel_set) && (!is_del))
8020     {
8021       errmsg ("tunnel name required\n");
8022       return -99;
8023     }
8024
8025   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8026
8027
8028
8029   mp->is_add = !is_del;
8030
8031   memcpy (mp->name, name, vec_len (name));
8032   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8033   u8 *serial_orig = 0;
8034   vec_validate (serial_orig, tunnel_names_length);
8035   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8036   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8037
8038   for (j = 0; j < vec_len (tunnel_names); j++)
8039     {
8040       tun_name_len = vec_len (tunnel_names[j]);
8041       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8042       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8043       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8044       serial_orig += tun_name_len;      // Advance past the copy
8045     }
8046   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8047
8048   vec_free (tunnel_names);
8049   vec_free (tunnel_name);
8050
8051   S;
8052   W;
8053   /* NOTREACHED */
8054 }
8055
8056 static int
8057 api_sr_multicast_map_add_del (vat_main_t * vam)
8058 {
8059   unformat_input_t *input = vam->input;
8060   vl_api_sr_multicast_map_add_del_t *mp;
8061   f64 timeout;
8062   int is_del = 0;
8063   ip6_address_t multicast_address;
8064   u8 *policy_name = 0;
8065   int multicast_address_set = 0;
8066
8067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (input, "del"))
8070         is_del = 1;
8071       else
8072         if (unformat
8073             (input, "address %U", unformat_ip6_address, &multicast_address))
8074         multicast_address_set = 1;
8075       else if (unformat (input, "sr-policy %s", &policy_name))
8076         ;
8077       else
8078         break;
8079     }
8080
8081   if (!is_del && !policy_name)
8082     {
8083       errmsg ("sr-policy name required\n");
8084       return -99;
8085     }
8086
8087
8088   if (!multicast_address_set)
8089     {
8090       errmsg ("address required\n");
8091       return -99;
8092     }
8093
8094   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8095
8096   mp->is_add = !is_del;
8097   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8098   clib_memcpy (mp->multicast_address, &multicast_address,
8099                sizeof (mp->multicast_address));
8100
8101
8102   vec_free (policy_name);
8103
8104   S;
8105   W;
8106   /* NOTREACHED */
8107 }
8108
8109
8110 #define foreach_tcp_proto_field                 \
8111 _(src_port)                                     \
8112 _(dst_port)
8113
8114 #define foreach_udp_proto_field                 \
8115 _(src_port)                                     \
8116 _(dst_port)
8117
8118 #define foreach_ip4_proto_field                 \
8119 _(src_address)                                  \
8120 _(dst_address)                                  \
8121 _(tos)                                          \
8122 _(length)                                       \
8123 _(fragment_id)                                  \
8124 _(ttl)                                          \
8125 _(protocol)                                     \
8126 _(checksum)
8127
8128 uword
8129 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8130 {
8131   u8 **maskp = va_arg (*args, u8 **);
8132   u8 *mask = 0;
8133   u8 found_something = 0;
8134   tcp_header_t *tcp;
8135
8136 #define _(a) u8 a=0;
8137   foreach_tcp_proto_field;
8138 #undef _
8139
8140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (0);
8143 #define _(a) else if (unformat (input, #a)) a=1;
8144       foreach_tcp_proto_field
8145 #undef _
8146         else
8147         break;
8148     }
8149
8150 #define _(a) found_something += a;
8151   foreach_tcp_proto_field;
8152 #undef _
8153
8154   if (found_something == 0)
8155     return 0;
8156
8157   vec_validate (mask, sizeof (*tcp) - 1);
8158
8159   tcp = (tcp_header_t *) mask;
8160
8161 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8162   foreach_tcp_proto_field;
8163 #undef _
8164
8165   *maskp = mask;
8166   return 1;
8167 }
8168
8169 uword
8170 unformat_udp_mask (unformat_input_t * input, va_list * args)
8171 {
8172   u8 **maskp = va_arg (*args, u8 **);
8173   u8 *mask = 0;
8174   u8 found_something = 0;
8175   udp_header_t *udp;
8176
8177 #define _(a) u8 a=0;
8178   foreach_udp_proto_field;
8179 #undef _
8180
8181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (0);
8184 #define _(a) else if (unformat (input, #a)) a=1;
8185       foreach_udp_proto_field
8186 #undef _
8187         else
8188         break;
8189     }
8190
8191 #define _(a) found_something += a;
8192   foreach_udp_proto_field;
8193 #undef _
8194
8195   if (found_something == 0)
8196     return 0;
8197
8198   vec_validate (mask, sizeof (*udp) - 1);
8199
8200   udp = (udp_header_t *) mask;
8201
8202 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8203   foreach_udp_proto_field;
8204 #undef _
8205
8206   *maskp = mask;
8207   return 1;
8208 }
8209
8210 typedef struct
8211 {
8212   u16 src_port, dst_port;
8213 } tcpudp_header_t;
8214
8215 uword
8216 unformat_l4_mask (unformat_input_t * input, va_list * args)
8217 {
8218   u8 **maskp = va_arg (*args, u8 **);
8219   u16 src_port = 0, dst_port = 0;
8220   tcpudp_header_t *tcpudp;
8221
8222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8225         return 1;
8226       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8227         return 1;
8228       else if (unformat (input, "src_port"))
8229         src_port = 0xFFFF;
8230       else if (unformat (input, "dst_port"))
8231         dst_port = 0xFFFF;
8232       else
8233         return 0;
8234     }
8235
8236   if (!src_port && !dst_port)
8237     return 0;
8238
8239   u8 *mask = 0;
8240   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8241
8242   tcpudp = (tcpudp_header_t *) mask;
8243   tcpudp->src_port = src_port;
8244   tcpudp->dst_port = dst_port;
8245
8246   *maskp = mask;
8247
8248   return 1;
8249 }
8250
8251 uword
8252 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8253 {
8254   u8 **maskp = va_arg (*args, u8 **);
8255   u8 *mask = 0;
8256   u8 found_something = 0;
8257   ip4_header_t *ip;
8258
8259 #define _(a) u8 a=0;
8260   foreach_ip4_proto_field;
8261 #undef _
8262   u8 version = 0;
8263   u8 hdr_length = 0;
8264
8265
8266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8267     {
8268       if (unformat (input, "version"))
8269         version = 1;
8270       else if (unformat (input, "hdr_length"))
8271         hdr_length = 1;
8272       else if (unformat (input, "src"))
8273         src_address = 1;
8274       else if (unformat (input, "dst"))
8275         dst_address = 1;
8276       else if (unformat (input, "proto"))
8277         protocol = 1;
8278
8279 #define _(a) else if (unformat (input, #a)) a=1;
8280       foreach_ip4_proto_field
8281 #undef _
8282         else
8283         break;
8284     }
8285
8286 #define _(a) found_something += a;
8287   foreach_ip4_proto_field;
8288 #undef _
8289
8290   if (found_something == 0)
8291     return 0;
8292
8293   vec_validate (mask, sizeof (*ip) - 1);
8294
8295   ip = (ip4_header_t *) mask;
8296
8297 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8298   foreach_ip4_proto_field;
8299 #undef _
8300
8301   ip->ip_version_and_header_length = 0;
8302
8303   if (version)
8304     ip->ip_version_and_header_length |= 0xF0;
8305
8306   if (hdr_length)
8307     ip->ip_version_and_header_length |= 0x0F;
8308
8309   *maskp = mask;
8310   return 1;
8311 }
8312
8313 #define foreach_ip6_proto_field                 \
8314 _(src_address)                                  \
8315 _(dst_address)                                  \
8316 _(payload_length)                               \
8317 _(hop_limit)                                    \
8318 _(protocol)
8319
8320 uword
8321 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8322 {
8323   u8 **maskp = va_arg (*args, u8 **);
8324   u8 *mask = 0;
8325   u8 found_something = 0;
8326   ip6_header_t *ip;
8327   u32 ip_version_traffic_class_and_flow_label;
8328
8329 #define _(a) u8 a=0;
8330   foreach_ip6_proto_field;
8331 #undef _
8332   u8 version = 0;
8333   u8 traffic_class = 0;
8334   u8 flow_label = 0;
8335
8336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (input, "version"))
8339         version = 1;
8340       else if (unformat (input, "traffic-class"))
8341         traffic_class = 1;
8342       else if (unformat (input, "flow-label"))
8343         flow_label = 1;
8344       else if (unformat (input, "src"))
8345         src_address = 1;
8346       else if (unformat (input, "dst"))
8347         dst_address = 1;
8348       else if (unformat (input, "proto"))
8349         protocol = 1;
8350
8351 #define _(a) else if (unformat (input, #a)) a=1;
8352       foreach_ip6_proto_field
8353 #undef _
8354         else
8355         break;
8356     }
8357
8358 #define _(a) found_something += a;
8359   foreach_ip6_proto_field;
8360 #undef _
8361
8362   if (found_something == 0)
8363     return 0;
8364
8365   vec_validate (mask, sizeof (*ip) - 1);
8366
8367   ip = (ip6_header_t *) mask;
8368
8369 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8370   foreach_ip6_proto_field;
8371 #undef _
8372
8373   ip_version_traffic_class_and_flow_label = 0;
8374
8375   if (version)
8376     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8377
8378   if (traffic_class)
8379     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8380
8381   if (flow_label)
8382     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8383
8384   ip->ip_version_traffic_class_and_flow_label =
8385     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8386
8387   *maskp = mask;
8388   return 1;
8389 }
8390
8391 uword
8392 unformat_l3_mask (unformat_input_t * input, va_list * args)
8393 {
8394   u8 **maskp = va_arg (*args, u8 **);
8395
8396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8399         return 1;
8400       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8401         return 1;
8402       else
8403         break;
8404     }
8405   return 0;
8406 }
8407
8408 uword
8409 unformat_l2_mask (unformat_input_t * input, va_list * args)
8410 {
8411   u8 **maskp = va_arg (*args, u8 **);
8412   u8 *mask = 0;
8413   u8 src = 0;
8414   u8 dst = 0;
8415   u8 proto = 0;
8416   u8 tag1 = 0;
8417   u8 tag2 = 0;
8418   u8 ignore_tag1 = 0;
8419   u8 ignore_tag2 = 0;
8420   u8 cos1 = 0;
8421   u8 cos2 = 0;
8422   u8 dot1q = 0;
8423   u8 dot1ad = 0;
8424   int len = 14;
8425
8426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (input, "src"))
8429         src = 1;
8430       else if (unformat (input, "dst"))
8431         dst = 1;
8432       else if (unformat (input, "proto"))
8433         proto = 1;
8434       else if (unformat (input, "tag1"))
8435         tag1 = 1;
8436       else if (unformat (input, "tag2"))
8437         tag2 = 1;
8438       else if (unformat (input, "ignore-tag1"))
8439         ignore_tag1 = 1;
8440       else if (unformat (input, "ignore-tag2"))
8441         ignore_tag2 = 1;
8442       else if (unformat (input, "cos1"))
8443         cos1 = 1;
8444       else if (unformat (input, "cos2"))
8445         cos2 = 1;
8446       else if (unformat (input, "dot1q"))
8447         dot1q = 1;
8448       else if (unformat (input, "dot1ad"))
8449         dot1ad = 1;
8450       else
8451         break;
8452     }
8453   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8454        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8455     return 0;
8456
8457   if (tag1 || ignore_tag1 || cos1 || dot1q)
8458     len = 18;
8459   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8460     len = 22;
8461
8462   vec_validate (mask, len - 1);
8463
8464   if (dst)
8465     memset (mask, 0xff, 6);
8466
8467   if (src)
8468     memset (mask + 6, 0xff, 6);
8469
8470   if (tag2 || dot1ad)
8471     {
8472       /* inner vlan tag */
8473       if (tag2)
8474         {
8475           mask[19] = 0xff;
8476           mask[18] = 0x0f;
8477         }
8478       if (cos2)
8479         mask[18] |= 0xe0;
8480       if (proto)
8481         mask[21] = mask[20] = 0xff;
8482       if (tag1)
8483         {
8484           mask[15] = 0xff;
8485           mask[14] = 0x0f;
8486         }
8487       if (cos1)
8488         mask[14] |= 0xe0;
8489       *maskp = mask;
8490       return 1;
8491     }
8492   if (tag1 | dot1q)
8493     {
8494       if (tag1)
8495         {
8496           mask[15] = 0xff;
8497           mask[14] = 0x0f;
8498         }
8499       if (cos1)
8500         mask[14] |= 0xe0;
8501       if (proto)
8502         mask[16] = mask[17] = 0xff;
8503
8504       *maskp = mask;
8505       return 1;
8506     }
8507   if (cos2)
8508     mask[18] |= 0xe0;
8509   if (cos1)
8510     mask[14] |= 0xe0;
8511   if (proto)
8512     mask[12] = mask[13] = 0xff;
8513
8514   *maskp = mask;
8515   return 1;
8516 }
8517
8518 uword
8519 unformat_classify_mask (unformat_input_t * input, va_list * args)
8520 {
8521   u8 **maskp = va_arg (*args, u8 **);
8522   u32 *skipp = va_arg (*args, u32 *);
8523   u32 *matchp = va_arg (*args, u32 *);
8524   u32 match;
8525   u8 *mask = 0;
8526   u8 *l2 = 0;
8527   u8 *l3 = 0;
8528   u8 *l4 = 0;
8529   int i;
8530
8531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8534         ;
8535       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8536         ;
8537       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8538         ;
8539       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8540         ;
8541       else
8542         break;
8543     }
8544
8545   if (l4 && !l3)
8546     {
8547       vec_free (mask);
8548       vec_free (l2);
8549       vec_free (l4);
8550       return 0;
8551     }
8552
8553   if (mask || l2 || l3 || l4)
8554     {
8555       if (l2 || l3 || l4)
8556         {
8557           /* "With a free Ethernet header in every package" */
8558           if (l2 == 0)
8559             vec_validate (l2, 13);
8560           mask = l2;
8561           if (vec_len (l3))
8562             {
8563               vec_append (mask, l3);
8564               vec_free (l3);
8565             }
8566           if (vec_len (l4))
8567             {
8568               vec_append (mask, l4);
8569               vec_free (l4);
8570             }
8571         }
8572
8573       /* Scan forward looking for the first significant mask octet */
8574       for (i = 0; i < vec_len (mask); i++)
8575         if (mask[i])
8576           break;
8577
8578       /* compute (skip, match) params */
8579       *skipp = i / sizeof (u32x4);
8580       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8581
8582       /* Pad mask to an even multiple of the vector size */
8583       while (vec_len (mask) % sizeof (u32x4))
8584         vec_add1 (mask, 0);
8585
8586       match = vec_len (mask) / sizeof (u32x4);
8587
8588       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8589         {
8590           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8591           if (*tmp || *(tmp + 1))
8592             break;
8593           match--;
8594         }
8595       if (match == 0)
8596         clib_warning ("BUG: match 0");
8597
8598       _vec_len (mask) = match * sizeof (u32x4);
8599
8600       *matchp = match;
8601       *maskp = mask;
8602
8603       return 1;
8604     }
8605
8606   return 0;
8607 }
8608
8609 #define foreach_l2_next                         \
8610 _(drop, DROP)                                   \
8611 _(ethernet, ETHERNET_INPUT)                     \
8612 _(ip4, IP4_INPUT)                               \
8613 _(ip6, IP6_INPUT)
8614
8615 uword
8616 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8617 {
8618   u32 *miss_next_indexp = va_arg (*args, u32 *);
8619   u32 next_index = 0;
8620   u32 tmp;
8621
8622 #define _(n,N) \
8623   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8624   foreach_l2_next;
8625 #undef _
8626
8627   if (unformat (input, "%d", &tmp))
8628     {
8629       next_index = tmp;
8630       goto out;
8631     }
8632
8633   return 0;
8634
8635 out:
8636   *miss_next_indexp = next_index;
8637   return 1;
8638 }
8639
8640 #define foreach_ip_next                         \
8641 _(drop, DROP)                                   \
8642 _(local, LOCAL)                                 \
8643 _(rewrite, REWRITE)
8644
8645 uword
8646 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8647 {
8648   u32 *miss_next_indexp = va_arg (*args, u32 *);
8649   u32 next_index = 0;
8650   u32 tmp;
8651
8652 #define _(n,N) \
8653   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8654   foreach_ip_next;
8655 #undef _
8656
8657   if (unformat (input, "%d", &tmp))
8658     {
8659       next_index = tmp;
8660       goto out;
8661     }
8662
8663   return 0;
8664
8665 out:
8666   *miss_next_indexp = next_index;
8667   return 1;
8668 }
8669
8670 #define foreach_acl_next                        \
8671 _(deny, DENY)
8672
8673 uword
8674 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8675 {
8676   u32 *miss_next_indexp = va_arg (*args, u32 *);
8677   u32 next_index = 0;
8678   u32 tmp;
8679
8680 #define _(n,N) \
8681   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8682   foreach_acl_next;
8683 #undef _
8684
8685   if (unformat (input, "permit"))
8686     {
8687       next_index = ~0;
8688       goto out;
8689     }
8690   else if (unformat (input, "%d", &tmp))
8691     {
8692       next_index = tmp;
8693       goto out;
8694     }
8695
8696   return 0;
8697
8698 out:
8699   *miss_next_indexp = next_index;
8700   return 1;
8701 }
8702
8703 uword
8704 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8705 {
8706   u32 *r = va_arg (*args, u32 *);
8707
8708   if (unformat (input, "conform-color"))
8709     *r = POLICE_CONFORM;
8710   else if (unformat (input, "exceed-color"))
8711     *r = POLICE_EXCEED;
8712   else
8713     return 0;
8714
8715   return 1;
8716 }
8717
8718 static int
8719 api_classify_add_del_table (vat_main_t * vam)
8720 {
8721   unformat_input_t *i = vam->input;
8722   vl_api_classify_add_del_table_t *mp;
8723
8724   u32 nbuckets = 2;
8725   u32 skip = ~0;
8726   u32 match = ~0;
8727   int is_add = 1;
8728   u32 table_index = ~0;
8729   u32 next_table_index = ~0;
8730   u32 miss_next_index = ~0;
8731   u32 memory_size = 32 << 20;
8732   u8 *mask = 0;
8733   f64 timeout;
8734   u32 current_data_flag = 0;
8735   int current_data_offset = 0;
8736
8737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8738     {
8739       if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "buckets %d", &nbuckets))
8742         ;
8743       else if (unformat (i, "memory_size %d", &memory_size))
8744         ;
8745       else if (unformat (i, "skip %d", &skip))
8746         ;
8747       else if (unformat (i, "match %d", &match))
8748         ;
8749       else if (unformat (i, "table %d", &table_index))
8750         ;
8751       else if (unformat (i, "mask %U", unformat_classify_mask,
8752                          &mask, &skip, &match))
8753         ;
8754       else if (unformat (i, "next-table %d", &next_table_index))
8755         ;
8756       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8757                          &miss_next_index))
8758         ;
8759       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8760                          &miss_next_index))
8761         ;
8762       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8763                          &miss_next_index))
8764         ;
8765       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8766         ;
8767       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8768         ;
8769       else
8770         break;
8771     }
8772
8773   if (is_add && mask == 0)
8774     {
8775       errmsg ("Mask required\n");
8776       return -99;
8777     }
8778
8779   if (is_add && skip == ~0)
8780     {
8781       errmsg ("skip count required\n");
8782       return -99;
8783     }
8784
8785   if (is_add && match == ~0)
8786     {
8787       errmsg ("match count required\n");
8788       return -99;
8789     }
8790
8791   if (!is_add && table_index == ~0)
8792     {
8793       errmsg ("table index required for delete\n");
8794       return -99;
8795     }
8796
8797   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8798
8799   mp->is_add = is_add;
8800   mp->table_index = ntohl (table_index);
8801   mp->nbuckets = ntohl (nbuckets);
8802   mp->memory_size = ntohl (memory_size);
8803   mp->skip_n_vectors = ntohl (skip);
8804   mp->match_n_vectors = ntohl (match);
8805   mp->next_table_index = ntohl (next_table_index);
8806   mp->miss_next_index = ntohl (miss_next_index);
8807   mp->current_data_flag = ntohl (current_data_flag);
8808   mp->current_data_offset = ntohl (current_data_offset);
8809   clib_memcpy (mp->mask, mask, vec_len (mask));
8810
8811   vec_free (mask);
8812
8813   S;
8814   W;
8815   /* NOTREACHED */
8816 }
8817
8818 uword
8819 unformat_l4_match (unformat_input_t * input, va_list * args)
8820 {
8821   u8 **matchp = va_arg (*args, u8 **);
8822
8823   u8 *proto_header = 0;
8824   int src_port = 0;
8825   int dst_port = 0;
8826
8827   tcpudp_header_t h;
8828
8829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8830     {
8831       if (unformat (input, "src_port %d", &src_port))
8832         ;
8833       else if (unformat (input, "dst_port %d", &dst_port))
8834         ;
8835       else
8836         return 0;
8837     }
8838
8839   h.src_port = clib_host_to_net_u16 (src_port);
8840   h.dst_port = clib_host_to_net_u16 (dst_port);
8841   vec_validate (proto_header, sizeof (h) - 1);
8842   memcpy (proto_header, &h, sizeof (h));
8843
8844   *matchp = proto_header;
8845
8846   return 1;
8847 }
8848
8849 uword
8850 unformat_ip4_match (unformat_input_t * input, va_list * args)
8851 {
8852   u8 **matchp = va_arg (*args, u8 **);
8853   u8 *match = 0;
8854   ip4_header_t *ip;
8855   int version = 0;
8856   u32 version_val;
8857   int hdr_length = 0;
8858   u32 hdr_length_val;
8859   int src = 0, dst = 0;
8860   ip4_address_t src_val, dst_val;
8861   int proto = 0;
8862   u32 proto_val;
8863   int tos = 0;
8864   u32 tos_val;
8865   int length = 0;
8866   u32 length_val;
8867   int fragment_id = 0;
8868   u32 fragment_id_val;
8869   int ttl = 0;
8870   int ttl_val;
8871   int checksum = 0;
8872   u32 checksum_val;
8873
8874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (input, "version %d", &version_val))
8877         version = 1;
8878       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8879         hdr_length = 1;
8880       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8881         src = 1;
8882       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8883         dst = 1;
8884       else if (unformat (input, "proto %d", &proto_val))
8885         proto = 1;
8886       else if (unformat (input, "tos %d", &tos_val))
8887         tos = 1;
8888       else if (unformat (input, "length %d", &length_val))
8889         length = 1;
8890       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8891         fragment_id = 1;
8892       else if (unformat (input, "ttl %d", &ttl_val))
8893         ttl = 1;
8894       else if (unformat (input, "checksum %d", &checksum_val))
8895         checksum = 1;
8896       else
8897         break;
8898     }
8899
8900   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8901       + ttl + checksum == 0)
8902     return 0;
8903
8904   /*
8905    * Aligned because we use the real comparison functions
8906    */
8907   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8908
8909   ip = (ip4_header_t *) match;
8910
8911   /* These are realistically matched in practice */
8912   if (src)
8913     ip->src_address.as_u32 = src_val.as_u32;
8914
8915   if (dst)
8916     ip->dst_address.as_u32 = dst_val.as_u32;
8917
8918   if (proto)
8919     ip->protocol = proto_val;
8920
8921
8922   /* These are not, but they're included for completeness */
8923   if (version)
8924     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8925
8926   if (hdr_length)
8927     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8928
8929   if (tos)
8930     ip->tos = tos_val;
8931
8932   if (length)
8933     ip->length = clib_host_to_net_u16 (length_val);
8934
8935   if (ttl)
8936     ip->ttl = ttl_val;
8937
8938   if (checksum)
8939     ip->checksum = clib_host_to_net_u16 (checksum_val);
8940
8941   *matchp = match;
8942   return 1;
8943 }
8944
8945 uword
8946 unformat_ip6_match (unformat_input_t * input, va_list * args)
8947 {
8948   u8 **matchp = va_arg (*args, u8 **);
8949   u8 *match = 0;
8950   ip6_header_t *ip;
8951   int version = 0;
8952   u32 version_val;
8953   u8 traffic_class = 0;
8954   u32 traffic_class_val = 0;
8955   u8 flow_label = 0;
8956   u8 flow_label_val;
8957   int src = 0, dst = 0;
8958   ip6_address_t src_val, dst_val;
8959   int proto = 0;
8960   u32 proto_val;
8961   int payload_length = 0;
8962   u32 payload_length_val;
8963   int hop_limit = 0;
8964   int hop_limit_val;
8965   u32 ip_version_traffic_class_and_flow_label;
8966
8967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (input, "version %d", &version_val))
8970         version = 1;
8971       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8972         traffic_class = 1;
8973       else if (unformat (input, "flow_label %d", &flow_label_val))
8974         flow_label = 1;
8975       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8976         src = 1;
8977       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8978         dst = 1;
8979       else if (unformat (input, "proto %d", &proto_val))
8980         proto = 1;
8981       else if (unformat (input, "payload_length %d", &payload_length_val))
8982         payload_length = 1;
8983       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8984         hop_limit = 1;
8985       else
8986         break;
8987     }
8988
8989   if (version + traffic_class + flow_label + src + dst + proto +
8990       payload_length + hop_limit == 0)
8991     return 0;
8992
8993   /*
8994    * Aligned because we use the real comparison functions
8995    */
8996   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8997
8998   ip = (ip6_header_t *) match;
8999
9000   if (src)
9001     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9002
9003   if (dst)
9004     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9005
9006   if (proto)
9007     ip->protocol = proto_val;
9008
9009   ip_version_traffic_class_and_flow_label = 0;
9010
9011   if (version)
9012     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9013
9014   if (traffic_class)
9015     ip_version_traffic_class_and_flow_label |=
9016       (traffic_class_val & 0xFF) << 20;
9017
9018   if (flow_label)
9019     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9020
9021   ip->ip_version_traffic_class_and_flow_label =
9022     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9023
9024   if (payload_length)
9025     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9026
9027   if (hop_limit)
9028     ip->hop_limit = hop_limit_val;
9029
9030   *matchp = match;
9031   return 1;
9032 }
9033
9034 uword
9035 unformat_l3_match (unformat_input_t * input, va_list * args)
9036 {
9037   u8 **matchp = va_arg (*args, u8 **);
9038
9039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9042         return 1;
9043       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9044         return 1;
9045       else
9046         break;
9047     }
9048   return 0;
9049 }
9050
9051 uword
9052 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9053 {
9054   u8 *tagp = va_arg (*args, u8 *);
9055   u32 tag;
9056
9057   if (unformat (input, "%d", &tag))
9058     {
9059       tagp[0] = (tag >> 8) & 0x0F;
9060       tagp[1] = tag & 0xFF;
9061       return 1;
9062     }
9063
9064   return 0;
9065 }
9066
9067 uword
9068 unformat_l2_match (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **matchp = va_arg (*args, u8 **);
9071   u8 *match = 0;
9072   u8 src = 0;
9073   u8 src_val[6];
9074   u8 dst = 0;
9075   u8 dst_val[6];
9076   u8 proto = 0;
9077   u16 proto_val;
9078   u8 tag1 = 0;
9079   u8 tag1_val[2];
9080   u8 tag2 = 0;
9081   u8 tag2_val[2];
9082   int len = 14;
9083   u8 ignore_tag1 = 0;
9084   u8 ignore_tag2 = 0;
9085   u8 cos1 = 0;
9086   u8 cos2 = 0;
9087   u32 cos1_val = 0;
9088   u32 cos2_val = 0;
9089
9090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9093         src = 1;
9094       else
9095         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9096         dst = 1;
9097       else if (unformat (input, "proto %U",
9098                          unformat_ethernet_type_host_byte_order, &proto_val))
9099         proto = 1;
9100       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9101         tag1 = 1;
9102       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9103         tag2 = 1;
9104       else if (unformat (input, "ignore-tag1"))
9105         ignore_tag1 = 1;
9106       else if (unformat (input, "ignore-tag2"))
9107         ignore_tag2 = 1;
9108       else if (unformat (input, "cos1 %d", &cos1_val))
9109         cos1 = 1;
9110       else if (unformat (input, "cos2 %d", &cos2_val))
9111         cos2 = 1;
9112       else
9113         break;
9114     }
9115   if ((src + dst + proto + tag1 + tag2 +
9116        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9117     return 0;
9118
9119   if (tag1 || ignore_tag1 || cos1)
9120     len = 18;
9121   if (tag2 || ignore_tag2 || cos2)
9122     len = 22;
9123
9124   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9125
9126   if (dst)
9127     clib_memcpy (match, dst_val, 6);
9128
9129   if (src)
9130     clib_memcpy (match + 6, src_val, 6);
9131
9132   if (tag2)
9133     {
9134       /* inner vlan tag */
9135       match[19] = tag2_val[1];
9136       match[18] = tag2_val[0];
9137       if (cos2)
9138         match[18] |= (cos2_val & 0x7) << 5;
9139       if (proto)
9140         {
9141           match[21] = proto_val & 0xff;
9142           match[20] = proto_val >> 8;
9143         }
9144       if (tag1)
9145         {
9146           match[15] = tag1_val[1];
9147           match[14] = tag1_val[0];
9148         }
9149       if (cos1)
9150         match[14] |= (cos1_val & 0x7) << 5;
9151       *matchp = match;
9152       return 1;
9153     }
9154   if (tag1)
9155     {
9156       match[15] = tag1_val[1];
9157       match[14] = tag1_val[0];
9158       if (proto)
9159         {
9160           match[17] = proto_val & 0xff;
9161           match[16] = proto_val >> 8;
9162         }
9163       if (cos1)
9164         match[14] |= (cos1_val & 0x7) << 5;
9165
9166       *matchp = match;
9167       return 1;
9168     }
9169   if (cos2)
9170     match[18] |= (cos2_val & 0x7) << 5;
9171   if (cos1)
9172     match[14] |= (cos1_val & 0x7) << 5;
9173   if (proto)
9174     {
9175       match[13] = proto_val & 0xff;
9176       match[12] = proto_val >> 8;
9177     }
9178
9179   *matchp = match;
9180   return 1;
9181 }
9182
9183
9184 uword
9185 unformat_classify_match (unformat_input_t * input, va_list * args)
9186 {
9187   u8 **matchp = va_arg (*args, u8 **);
9188   u32 skip_n_vectors = va_arg (*args, u32);
9189   u32 match_n_vectors = va_arg (*args, u32);
9190
9191   u8 *match = 0;
9192   u8 *l2 = 0;
9193   u8 *l3 = 0;
9194   u8 *l4 = 0;
9195
9196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (input, "hex %U", unformat_hex_string, &match))
9199         ;
9200       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9201         ;
9202       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9203         ;
9204       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9205         ;
9206       else
9207         break;
9208     }
9209
9210   if (l4 && !l3)
9211     {
9212       vec_free (match);
9213       vec_free (l2);
9214       vec_free (l4);
9215       return 0;
9216     }
9217
9218   if (match || l2 || l3 || l4)
9219     {
9220       if (l2 || l3 || l4)
9221         {
9222           /* "Win a free Ethernet header in every packet" */
9223           if (l2 == 0)
9224             vec_validate_aligned (l2, 13, sizeof (u32x4));
9225           match = l2;
9226           if (vec_len (l3))
9227             {
9228               vec_append_aligned (match, l3, sizeof (u32x4));
9229               vec_free (l3);
9230             }
9231           if (vec_len (l4))
9232             {
9233               vec_append_aligned (match, l4, sizeof (u32x4));
9234               vec_free (l4);
9235             }
9236         }
9237
9238       /* Make sure the vector is big enough even if key is all 0's */
9239       vec_validate_aligned
9240         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9241          sizeof (u32x4));
9242
9243       /* Set size, include skipped vectors */
9244       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9245
9246       *matchp = match;
9247
9248       return 1;
9249     }
9250
9251   return 0;
9252 }
9253
9254 static int
9255 api_classify_add_del_session (vat_main_t * vam)
9256 {
9257   unformat_input_t *i = vam->input;
9258   vl_api_classify_add_del_session_t *mp;
9259   int is_add = 1;
9260   u32 table_index = ~0;
9261   u32 hit_next_index = ~0;
9262   u32 opaque_index = ~0;
9263   u8 *match = 0;
9264   i32 advance = 0;
9265   f64 timeout;
9266   u32 skip_n_vectors = 0;
9267   u32 match_n_vectors = 0;
9268   u32 action = 0;
9269   u32 metadata = 0;
9270
9271   /*
9272    * Warning: you have to supply skip_n and match_n
9273    * because the API client cant simply look at the classify
9274    * table object.
9275    */
9276
9277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (i, "del"))
9280         is_add = 0;
9281       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9282                          &hit_next_index))
9283         ;
9284       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9285                          &hit_next_index))
9286         ;
9287       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9288                          &hit_next_index))
9289         ;
9290       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9291         ;
9292       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9293         ;
9294       else if (unformat (i, "opaque-index %d", &opaque_index))
9295         ;
9296       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9297         ;
9298       else if (unformat (i, "match_n %d", &match_n_vectors))
9299         ;
9300       else if (unformat (i, "match %U", unformat_classify_match,
9301                          &match, skip_n_vectors, match_n_vectors))
9302         ;
9303       else if (unformat (i, "advance %d", &advance))
9304         ;
9305       else if (unformat (i, "table-index %d", &table_index))
9306         ;
9307       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9308         action = 1;
9309       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9310         action = 2;
9311       else if (unformat (i, "action %d", &action))
9312         ;
9313       else if (unformat (i, "metadata %d", &metadata))
9314         ;
9315       else
9316         break;
9317     }
9318
9319   if (table_index == ~0)
9320     {
9321       errmsg ("Table index required\n");
9322       return -99;
9323     }
9324
9325   if (is_add && match == 0)
9326     {
9327       errmsg ("Match value required\n");
9328       return -99;
9329     }
9330
9331   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9332
9333   mp->is_add = is_add;
9334   mp->table_index = ntohl (table_index);
9335   mp->hit_next_index = ntohl (hit_next_index);
9336   mp->opaque_index = ntohl (opaque_index);
9337   mp->advance = ntohl (advance);
9338   mp->action = action;
9339   mp->metadata = ntohl (metadata);
9340   clib_memcpy (mp->match, match, vec_len (match));
9341   vec_free (match);
9342
9343   S;
9344   W;
9345   /* NOTREACHED */
9346 }
9347
9348 static int
9349 api_classify_set_interface_ip_table (vat_main_t * vam)
9350 {
9351   unformat_input_t *i = vam->input;
9352   vl_api_classify_set_interface_ip_table_t *mp;
9353   f64 timeout;
9354   u32 sw_if_index;
9355   int sw_if_index_set;
9356   u32 table_index = ~0;
9357   u8 is_ipv6 = 0;
9358
9359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "table %d", &table_index))
9366         ;
9367       else
9368         {
9369           clib_warning ("parse error '%U'", format_unformat_error, i);
9370           return -99;
9371         }
9372     }
9373
9374   if (sw_if_index_set == 0)
9375     {
9376       errmsg ("missing interface name or sw_if_index\n");
9377       return -99;
9378     }
9379
9380
9381   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9382
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   mp->table_index = ntohl (table_index);
9385   mp->is_ipv6 = is_ipv6;
9386
9387   S;
9388   W;
9389   /* NOTREACHED */
9390   return 0;
9391 }
9392
9393 static int
9394 api_classify_set_interface_l2_tables (vat_main_t * vam)
9395 {
9396   unformat_input_t *i = vam->input;
9397   vl_api_classify_set_interface_l2_tables_t *mp;
9398   f64 timeout;
9399   u32 sw_if_index;
9400   int sw_if_index_set;
9401   u32 ip4_table_index = ~0;
9402   u32 ip6_table_index = ~0;
9403   u32 other_table_index = ~0;
9404   u32 is_input = 1;
9405
9406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9407     {
9408       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9409         sw_if_index_set = 1;
9410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9411         sw_if_index_set = 1;
9412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9413         ;
9414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9415         ;
9416       else if (unformat (i, "other-table %d", &other_table_index))
9417         ;
9418       else if (unformat (i, "is-input %d", &is_input))
9419         ;
9420       else
9421         {
9422           clib_warning ("parse error '%U'", format_unformat_error, i);
9423           return -99;
9424         }
9425     }
9426
9427   if (sw_if_index_set == 0)
9428     {
9429       errmsg ("missing interface name or sw_if_index\n");
9430       return -99;
9431     }
9432
9433
9434   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9435
9436   mp->sw_if_index = ntohl (sw_if_index);
9437   mp->ip4_table_index = ntohl (ip4_table_index);
9438   mp->ip6_table_index = ntohl (ip6_table_index);
9439   mp->other_table_index = ntohl (other_table_index);
9440   mp->is_input = (u8) is_input;
9441
9442   S;
9443   W;
9444   /* NOTREACHED */
9445   return 0;
9446 }
9447
9448 static int
9449 api_set_ipfix_exporter (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_set_ipfix_exporter_t *mp;
9453   ip4_address_t collector_address;
9454   u8 collector_address_set = 0;
9455   u32 collector_port = ~0;
9456   ip4_address_t src_address;
9457   u8 src_address_set = 0;
9458   u32 vrf_id = ~0;
9459   u32 path_mtu = ~0;
9460   u32 template_interval = ~0;
9461   u8 udp_checksum = 0;
9462   f64 timeout;
9463
9464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (i, "collector_address %U", unformat_ip4_address,
9467                     &collector_address))
9468         collector_address_set = 1;
9469       else if (unformat (i, "collector_port %d", &collector_port))
9470         ;
9471       else if (unformat (i, "src_address %U", unformat_ip4_address,
9472                          &src_address))
9473         src_address_set = 1;
9474       else if (unformat (i, "vrf_id %d", &vrf_id))
9475         ;
9476       else if (unformat (i, "path_mtu %d", &path_mtu))
9477         ;
9478       else if (unformat (i, "template_interval %d", &template_interval))
9479         ;
9480       else if (unformat (i, "udp_checksum"))
9481         udp_checksum = 1;
9482       else
9483         break;
9484     }
9485
9486   if (collector_address_set == 0)
9487     {
9488       errmsg ("collector_address required\n");
9489       return -99;
9490     }
9491
9492   if (src_address_set == 0)
9493     {
9494       errmsg ("src_address required\n");
9495       return -99;
9496     }
9497
9498   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9499
9500   memcpy (mp->collector_address, collector_address.data,
9501           sizeof (collector_address.data));
9502   mp->collector_port = htons ((u16) collector_port);
9503   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9504   mp->vrf_id = htonl (vrf_id);
9505   mp->path_mtu = htonl (path_mtu);
9506   mp->template_interval = htonl (template_interval);
9507   mp->udp_checksum = udp_checksum;
9508
9509   S;
9510   W;
9511   /* NOTREACHED */
9512 }
9513
9514 static int
9515 api_set_ipfix_classify_stream (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_set_ipfix_classify_stream_t *mp;
9519   u32 domain_id = 0;
9520   u32 src_port = UDP_DST_PORT_ipfix;
9521   f64 timeout;
9522
9523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9524     {
9525       if (unformat (i, "domain %d", &domain_id))
9526         ;
9527       else if (unformat (i, "src_port %d", &src_port))
9528         ;
9529       else
9530         {
9531           errmsg ("unknown input `%U'", format_unformat_error, i);
9532           return -99;
9533         }
9534     }
9535
9536   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9537
9538   mp->domain_id = htonl (domain_id);
9539   mp->src_port = htons ((u16) src_port);
9540
9541   S;
9542   W;
9543   /* NOTREACHED */
9544 }
9545
9546 static int
9547 api_ipfix_classify_table_add_del (vat_main_t * vam)
9548 {
9549   unformat_input_t *i = vam->input;
9550   vl_api_ipfix_classify_table_add_del_t *mp;
9551   int is_add = -1;
9552   u32 classify_table_index = ~0;
9553   u8 ip_version = 0;
9554   u8 transport_protocol = 255;
9555   f64 timeout;
9556
9557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9558     {
9559       if (unformat (i, "add"))
9560         is_add = 1;
9561       else if (unformat (i, "del"))
9562         is_add = 0;
9563       else if (unformat (i, "table %d", &classify_table_index))
9564         ;
9565       else if (unformat (i, "ip4"))
9566         ip_version = 4;
9567       else if (unformat (i, "ip6"))
9568         ip_version = 6;
9569       else if (unformat (i, "tcp"))
9570         transport_protocol = 6;
9571       else if (unformat (i, "udp"))
9572         transport_protocol = 17;
9573       else
9574         {
9575           errmsg ("unknown input `%U'", format_unformat_error, i);
9576           return -99;
9577         }
9578     }
9579
9580   if (is_add == -1)
9581     {
9582       errmsg ("expecting: add|del");
9583       return -99;
9584     }
9585   if (classify_table_index == ~0)
9586     {
9587       errmsg ("classifier table not specified");
9588       return -99;
9589     }
9590   if (ip_version == 0)
9591     {
9592       errmsg ("IP version not specified");
9593       return -99;
9594     }
9595
9596   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9597
9598   mp->is_add = is_add;
9599   mp->table_id = htonl (classify_table_index);
9600   mp->ip_version = ip_version;
9601   mp->transport_protocol = transport_protocol;
9602
9603   S;
9604   W;
9605   /* NOTREACHED */
9606 }
9607
9608 static int
9609 api_get_node_index (vat_main_t * vam)
9610 {
9611   unformat_input_t *i = vam->input;
9612   vl_api_get_node_index_t *mp;
9613   f64 timeout;
9614   u8 *name = 0;
9615
9616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9617     {
9618       if (unformat (i, "node %s", &name))
9619         ;
9620       else
9621         break;
9622     }
9623   if (name == 0)
9624     {
9625       errmsg ("node name required\n");
9626       return -99;
9627     }
9628   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9629     {
9630       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9631       return -99;
9632     }
9633
9634   M (GET_NODE_INDEX, get_node_index);
9635   clib_memcpy (mp->node_name, name, vec_len (name));
9636   vec_free (name);
9637
9638   S;
9639   W;
9640   /* NOTREACHED */
9641   return 0;
9642 }
9643
9644 static int
9645 api_get_next_index (vat_main_t * vam)
9646 {
9647   unformat_input_t *i = vam->input;
9648   vl_api_get_next_index_t *mp;
9649   f64 timeout;
9650   u8 *node_name = 0, *next_node_name = 0;
9651
9652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9653     {
9654       if (unformat (i, "node-name %s", &node_name))
9655         ;
9656       else if (unformat (i, "next-node-name %s", &next_node_name))
9657         break;
9658     }
9659
9660   if (node_name == 0)
9661     {
9662       errmsg ("node name required\n");
9663       return -99;
9664     }
9665   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9666     {
9667       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9668       return -99;
9669     }
9670
9671   if (next_node_name == 0)
9672     {
9673       errmsg ("next node name required\n");
9674       return -99;
9675     }
9676   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9677     {
9678       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9679       return -99;
9680     }
9681
9682   M (GET_NEXT_INDEX, get_next_index);
9683   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9684   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9685   vec_free (node_name);
9686   vec_free (next_node_name);
9687
9688   S;
9689   W;
9690   /* NOTREACHED */
9691   return 0;
9692 }
9693
9694 static int
9695 api_add_node_next (vat_main_t * vam)
9696 {
9697   unformat_input_t *i = vam->input;
9698   vl_api_add_node_next_t *mp;
9699   f64 timeout;
9700   u8 *name = 0;
9701   u8 *next = 0;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "node %s", &name))
9706         ;
9707       else if (unformat (i, "next %s", &next))
9708         ;
9709       else
9710         break;
9711     }
9712   if (name == 0)
9713     {
9714       errmsg ("node name required\n");
9715       return -99;
9716     }
9717   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9718     {
9719       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9720       return -99;
9721     }
9722   if (next == 0)
9723     {
9724       errmsg ("next node required\n");
9725       return -99;
9726     }
9727   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9728     {
9729       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9730       return -99;
9731     }
9732
9733   M (ADD_NODE_NEXT, add_node_next);
9734   clib_memcpy (mp->node_name, name, vec_len (name));
9735   clib_memcpy (mp->next_name, next, vec_len (next));
9736   vec_free (name);
9737   vec_free (next);
9738
9739   S;
9740   W;
9741   /* NOTREACHED */
9742   return 0;
9743 }
9744
9745 static int
9746 api_l2tpv3_create_tunnel (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   ip6_address_t client_address, our_address;
9750   int client_address_set = 0;
9751   int our_address_set = 0;
9752   u32 local_session_id = 0;
9753   u32 remote_session_id = 0;
9754   u64 local_cookie = 0;
9755   u64 remote_cookie = 0;
9756   u8 l2_sublayer_present = 0;
9757   vl_api_l2tpv3_create_tunnel_t *mp;
9758   f64 timeout;
9759
9760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9761     {
9762       if (unformat (i, "client_address %U", unformat_ip6_address,
9763                     &client_address))
9764         client_address_set = 1;
9765       else if (unformat (i, "our_address %U", unformat_ip6_address,
9766                          &our_address))
9767         our_address_set = 1;
9768       else if (unformat (i, "local_session_id %d", &local_session_id))
9769         ;
9770       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9771         ;
9772       else if (unformat (i, "local_cookie %lld", &local_cookie))
9773         ;
9774       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9775         ;
9776       else if (unformat (i, "l2-sublayer-present"))
9777         l2_sublayer_present = 1;
9778       else
9779         break;
9780     }
9781
9782   if (client_address_set == 0)
9783     {
9784       errmsg ("client_address required\n");
9785       return -99;
9786     }
9787
9788   if (our_address_set == 0)
9789     {
9790       errmsg ("our_address required\n");
9791       return -99;
9792     }
9793
9794   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9795
9796   clib_memcpy (mp->client_address, client_address.as_u8,
9797                sizeof (mp->client_address));
9798
9799   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9800
9801   mp->local_session_id = ntohl (local_session_id);
9802   mp->remote_session_id = ntohl (remote_session_id);
9803   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9804   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9805   mp->l2_sublayer_present = l2_sublayer_present;
9806   mp->is_ipv6 = 1;
9807
9808   S;
9809   W;
9810   /* NOTREACHED */
9811   return 0;
9812 }
9813
9814 static int
9815 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9816 {
9817   unformat_input_t *i = vam->input;
9818   u32 sw_if_index;
9819   u8 sw_if_index_set = 0;
9820   u64 new_local_cookie = 0;
9821   u64 new_remote_cookie = 0;
9822   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9823   f64 timeout;
9824
9825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9828         sw_if_index_set = 1;
9829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9830         sw_if_index_set = 1;
9831       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9832         ;
9833       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9834         ;
9835       else
9836         break;
9837     }
9838
9839   if (sw_if_index_set == 0)
9840     {
9841       errmsg ("missing interface name or sw_if_index\n");
9842       return -99;
9843     }
9844
9845   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9846
9847   mp->sw_if_index = ntohl (sw_if_index);
9848   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9849   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9850
9851   S;
9852   W;
9853   /* NOTREACHED */
9854   return 0;
9855 }
9856
9857 static int
9858 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_l2tpv3_interface_enable_disable_t *mp;
9862   f64 timeout;
9863   u32 sw_if_index;
9864   u8 sw_if_index_set = 0;
9865   u8 enable_disable = 1;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable_disable = 1;
9875       else if (unformat (i, "disable"))
9876         enable_disable = 0;
9877       else
9878         break;
9879     }
9880
9881   if (sw_if_index_set == 0)
9882     {
9883       errmsg ("missing interface name or sw_if_index\n");
9884       return -99;
9885     }
9886
9887   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9888
9889   mp->sw_if_index = ntohl (sw_if_index);
9890   mp->enable_disable = enable_disable;
9891
9892   S;
9893   W;
9894   /* NOTREACHED */
9895   return 0;
9896 }
9897
9898 static int
9899 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_l2tpv3_set_lookup_key_t *mp;
9903   f64 timeout;
9904   u8 key = ~0;
9905
9906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9907     {
9908       if (unformat (i, "lookup_v6_src"))
9909         key = L2T_LOOKUP_SRC_ADDRESS;
9910       else if (unformat (i, "lookup_v6_dst"))
9911         key = L2T_LOOKUP_DST_ADDRESS;
9912       else if (unformat (i, "lookup_session_id"))
9913         key = L2T_LOOKUP_SESSION_ID;
9914       else
9915         break;
9916     }
9917
9918   if (key == (u8) ~ 0)
9919     {
9920       errmsg ("l2tp session lookup key unset\n");
9921       return -99;
9922     }
9923
9924   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9925
9926   mp->key = key;
9927
9928   S;
9929   W;
9930   /* NOTREACHED */
9931   return 0;
9932 }
9933
9934 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9935   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9936 {
9937   vat_main_t *vam = &vat_main;
9938
9939   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9940            format_ip6_address, mp->our_address,
9941            format_ip6_address, mp->client_address,
9942            clib_net_to_host_u32 (mp->sw_if_index));
9943
9944   fformat (vam->ofp,
9945            "   local cookies %016llx %016llx remote cookie %016llx\n",
9946            clib_net_to_host_u64 (mp->local_cookie[0]),
9947            clib_net_to_host_u64 (mp->local_cookie[1]),
9948            clib_net_to_host_u64 (mp->remote_cookie));
9949
9950   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9951            clib_net_to_host_u32 (mp->local_session_id),
9952            clib_net_to_host_u32 (mp->remote_session_id));
9953
9954   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9955            mp->l2_sublayer_present ? "preset" : "absent");
9956
9957 }
9958
9959 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9960   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9961 {
9962   vat_main_t *vam = &vat_main;
9963   vat_json_node_t *node = NULL;
9964   struct in6_addr addr;
9965
9966   if (VAT_JSON_ARRAY != vam->json_tree.type)
9967     {
9968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9969       vat_json_init_array (&vam->json_tree);
9970     }
9971   node = vat_json_array_add (&vam->json_tree);
9972
9973   vat_json_init_object (node);
9974
9975   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9976   vat_json_object_add_ip6 (node, "our_address", addr);
9977   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9978   vat_json_object_add_ip6 (node, "client_address", addr);
9979
9980   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9981   vat_json_init_array (lc);
9982   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9983   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9984   vat_json_object_add_uint (node, "remote_cookie",
9985                             clib_net_to_host_u64 (mp->remote_cookie));
9986
9987   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9988   vat_json_object_add_uint (node, "local_session_id",
9989                             clib_net_to_host_u32 (mp->local_session_id));
9990   vat_json_object_add_uint (node, "remote_session_id",
9991                             clib_net_to_host_u32 (mp->remote_session_id));
9992   vat_json_object_add_string_copy (node, "l2_sublayer",
9993                                    mp->l2_sublayer_present ? (u8 *) "present"
9994                                    : (u8 *) "absent");
9995 }
9996
9997 static int
9998 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9999 {
10000   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10001   f64 timeout;
10002
10003   /* Get list of l2tpv3-tunnel interfaces */
10004   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10005   S;
10006
10007   /* Use a control ping for synchronization */
10008   {
10009     vl_api_control_ping_t *mp;
10010     M (CONTROL_PING, control_ping);
10011     S;
10012   }
10013   W;
10014 }
10015
10016
10017 static void vl_api_sw_interface_tap_details_t_handler
10018   (vl_api_sw_interface_tap_details_t * mp)
10019 {
10020   vat_main_t *vam = &vat_main;
10021
10022   fformat (vam->ofp, "%-16s %d\n",
10023            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10024 }
10025
10026 static void vl_api_sw_interface_tap_details_t_handler_json
10027   (vl_api_sw_interface_tap_details_t * mp)
10028 {
10029   vat_main_t *vam = &vat_main;
10030   vat_json_node_t *node = NULL;
10031
10032   if (VAT_JSON_ARRAY != vam->json_tree.type)
10033     {
10034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10035       vat_json_init_array (&vam->json_tree);
10036     }
10037   node = vat_json_array_add (&vam->json_tree);
10038
10039   vat_json_init_object (node);
10040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10041   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10042 }
10043
10044 static int
10045 api_sw_interface_tap_dump (vat_main_t * vam)
10046 {
10047   vl_api_sw_interface_tap_dump_t *mp;
10048   f64 timeout;
10049
10050   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10051   /* Get list of tap interfaces */
10052   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10053   S;
10054
10055   /* Use a control ping for synchronization */
10056   {
10057     vl_api_control_ping_t *mp;
10058     M (CONTROL_PING, control_ping);
10059     S;
10060   }
10061   W;
10062 }
10063
10064 static uword unformat_vxlan_decap_next
10065   (unformat_input_t * input, va_list * args)
10066 {
10067   u32 *result = va_arg (*args, u32 *);
10068   u32 tmp;
10069
10070   if (unformat (input, "l2"))
10071     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10072   else if (unformat (input, "%d", &tmp))
10073     *result = tmp;
10074   else
10075     return 0;
10076   return 1;
10077 }
10078
10079 static int
10080 api_vxlan_add_del_tunnel (vat_main_t * vam)
10081 {
10082   unformat_input_t *line_input = vam->input;
10083   vl_api_vxlan_add_del_tunnel_t *mp;
10084   f64 timeout;
10085   ip46_address_t src, dst;
10086   u8 is_add = 1;
10087   u8 ipv4_set = 0, ipv6_set = 0;
10088   u8 src_set = 0;
10089   u8 dst_set = 0;
10090   u8 grp_set = 0;
10091   u32 mcast_sw_if_index = ~0;
10092   u32 encap_vrf_id = 0;
10093   u32 decap_next_index = ~0;
10094   u32 vni = 0;
10095
10096   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10097   memset (&src, 0, sizeof src);
10098   memset (&dst, 0, sizeof dst);
10099
10100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (line_input, "del"))
10103         is_add = 0;
10104       else
10105         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10106         {
10107           ipv4_set = 1;
10108           src_set = 1;
10109         }
10110       else
10111         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10112         {
10113           ipv4_set = 1;
10114           dst_set = 1;
10115         }
10116       else
10117         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10118         {
10119           ipv6_set = 1;
10120           src_set = 1;
10121         }
10122       else
10123         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10124         {
10125           ipv6_set = 1;
10126           dst_set = 1;
10127         }
10128       else if (unformat (line_input, "group %U %U",
10129                          unformat_ip4_address, &dst.ip4,
10130                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10131         {
10132           grp_set = dst_set = 1;
10133           ipv4_set = 1;
10134         }
10135       else if (unformat (line_input, "group %U",
10136                          unformat_ip4_address, &dst.ip4))
10137         {
10138           grp_set = dst_set = 1;
10139           ipv4_set = 1;
10140         }
10141       else if (unformat (line_input, "group %U %U",
10142                          unformat_ip6_address, &dst.ip6,
10143                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10144         {
10145           grp_set = dst_set = 1;
10146           ipv6_set = 1;
10147         }
10148       else if (unformat (line_input, "group %U",
10149                          unformat_ip6_address, &dst.ip6))
10150         {
10151           grp_set = dst_set = 1;
10152           ipv6_set = 1;
10153         }
10154       else
10155         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10156         ;
10157       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10158         ;
10159       else if (unformat (line_input, "decap-next %U",
10160                          unformat_vxlan_decap_next, &decap_next_index))
10161         ;
10162       else if (unformat (line_input, "vni %d", &vni))
10163         ;
10164       else
10165         {
10166           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10167           return -99;
10168         }
10169     }
10170
10171   if (src_set == 0)
10172     {
10173       errmsg ("tunnel src address not specified\n");
10174       return -99;
10175     }
10176   if (dst_set == 0)
10177     {
10178       errmsg ("tunnel dst address not specified\n");
10179       return -99;
10180     }
10181
10182   if (grp_set && !ip46_address_is_multicast (&dst))
10183     {
10184       errmsg ("tunnel group address not multicast\n");
10185       return -99;
10186     }
10187   if (grp_set && mcast_sw_if_index == ~0)
10188     {
10189       errmsg ("tunnel nonexistent multicast device\n");
10190       return -99;
10191     }
10192
10193
10194   if (ipv4_set && ipv6_set)
10195     {
10196       errmsg ("both IPv4 and IPv6 addresses specified");
10197       return -99;
10198     }
10199
10200   if ((vni == 0) || (vni >> 24))
10201     {
10202       errmsg ("vni not specified or out of range\n");
10203       return -99;
10204     }
10205
10206   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10207
10208   if (ipv6_set)
10209     {
10210       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10211       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10212     }
10213   else
10214     {
10215       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10216       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10217     }
10218   mp->encap_vrf_id = ntohl (encap_vrf_id);
10219   mp->decap_next_index = ntohl (decap_next_index);
10220   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10221   mp->vni = ntohl (vni);
10222   mp->is_add = is_add;
10223   mp->is_ipv6 = ipv6_set;
10224
10225   S;
10226   W;
10227   /* NOTREACHED */
10228   return 0;
10229 }
10230
10231 static void vl_api_vxlan_tunnel_details_t_handler
10232   (vl_api_vxlan_tunnel_details_t * mp)
10233 {
10234   vat_main_t *vam = &vat_main;
10235   ip46_address_t src, dst;
10236
10237   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10238   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10239
10240   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10241            ntohl (mp->sw_if_index),
10242            format_ip46_address, &src, IP46_TYPE_ANY,
10243            format_ip46_address, &dst, IP46_TYPE_ANY,
10244            ntohl (mp->encap_vrf_id),
10245            ntohl (mp->decap_next_index), ntohl (mp->vni),
10246            ntohl (mp->mcast_sw_if_index));
10247 }
10248
10249 static void vl_api_vxlan_tunnel_details_t_handler_json
10250   (vl_api_vxlan_tunnel_details_t * mp)
10251 {
10252   vat_main_t *vam = &vat_main;
10253   vat_json_node_t *node = NULL;
10254
10255   if (VAT_JSON_ARRAY != vam->json_tree.type)
10256     {
10257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10258       vat_json_init_array (&vam->json_tree);
10259     }
10260   node = vat_json_array_add (&vam->json_tree);
10261
10262   vat_json_init_object (node);
10263   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10264   if (mp->is_ipv6)
10265     {
10266       struct in6_addr ip6;
10267
10268       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10269       vat_json_object_add_ip6 (node, "src_address", ip6);
10270       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10271       vat_json_object_add_ip6 (node, "dst_address", ip6);
10272     }
10273   else
10274     {
10275       struct in_addr ip4;
10276
10277       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10278       vat_json_object_add_ip4 (node, "src_address", ip4);
10279       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10280       vat_json_object_add_ip4 (node, "dst_address", ip4);
10281     }
10282   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10283   vat_json_object_add_uint (node, "decap_next_index",
10284                             ntohl (mp->decap_next_index));
10285   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10286   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10287   vat_json_object_add_uint (node, "mcast_sw_if_index",
10288                             ntohl (mp->mcast_sw_if_index));
10289 }
10290
10291 static int
10292 api_vxlan_tunnel_dump (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_vxlan_tunnel_dump_t *mp;
10296   f64 timeout;
10297   u32 sw_if_index;
10298   u8 sw_if_index_set = 0;
10299
10300   /* Parse args required to build the message */
10301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10302     {
10303       if (unformat (i, "sw_if_index %d", &sw_if_index))
10304         sw_if_index_set = 1;
10305       else
10306         break;
10307     }
10308
10309   if (sw_if_index_set == 0)
10310     {
10311       sw_if_index = ~0;
10312     }
10313
10314   if (!vam->json_output)
10315     {
10316       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10317                "sw_if_index", "src_address", "dst_address",
10318                "encap_vrf_id", "decap_next_index", "vni",
10319                "mcast_sw_if_index");
10320     }
10321
10322   /* Get list of vxlan-tunnel interfaces */
10323   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10324
10325   mp->sw_if_index = htonl (sw_if_index);
10326
10327   S;
10328
10329   /* Use a control ping for synchronization */
10330   {
10331     vl_api_control_ping_t *mp;
10332     M (CONTROL_PING, control_ping);
10333     S;
10334   }
10335   W;
10336 }
10337
10338 static int
10339 api_gre_add_del_tunnel (vat_main_t * vam)
10340 {
10341   unformat_input_t *line_input = vam->input;
10342   vl_api_gre_add_del_tunnel_t *mp;
10343   f64 timeout;
10344   ip4_address_t src4, dst4;
10345   u8 is_add = 1;
10346   u8 teb = 0;
10347   u8 src_set = 0;
10348   u8 dst_set = 0;
10349   u32 outer_fib_id = 0;
10350
10351   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10352     {
10353       if (unformat (line_input, "del"))
10354         is_add = 0;
10355       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10356         src_set = 1;
10357       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10358         dst_set = 1;
10359       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10360         ;
10361       else if (unformat (line_input, "teb"))
10362         teb = 1;
10363       else
10364         {
10365           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10366           return -99;
10367         }
10368     }
10369
10370   if (src_set == 0)
10371     {
10372       errmsg ("tunnel src address not specified\n");
10373       return -99;
10374     }
10375   if (dst_set == 0)
10376     {
10377       errmsg ("tunnel dst address not specified\n");
10378       return -99;
10379     }
10380
10381
10382   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10383
10384   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10385   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10386   mp->outer_fib_id = ntohl (outer_fib_id);
10387   mp->is_add = is_add;
10388   mp->teb = teb;
10389
10390   S;
10391   W;
10392   /* NOTREACHED */
10393   return 0;
10394 }
10395
10396 static void vl_api_gre_tunnel_details_t_handler
10397   (vl_api_gre_tunnel_details_t * mp)
10398 {
10399   vat_main_t *vam = &vat_main;
10400
10401   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10402            ntohl (mp->sw_if_index),
10403            format_ip4_address, &mp->src_address,
10404            format_ip4_address, &mp->dst_address,
10405            mp->teb, ntohl (mp->outer_fib_id));
10406 }
10407
10408 static void vl_api_gre_tunnel_details_t_handler_json
10409   (vl_api_gre_tunnel_details_t * mp)
10410 {
10411   vat_main_t *vam = &vat_main;
10412   vat_json_node_t *node = NULL;
10413   struct in_addr ip4;
10414
10415   if (VAT_JSON_ARRAY != vam->json_tree.type)
10416     {
10417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10418       vat_json_init_array (&vam->json_tree);
10419     }
10420   node = vat_json_array_add (&vam->json_tree);
10421
10422   vat_json_init_object (node);
10423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10424   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10425   vat_json_object_add_ip4 (node, "src_address", ip4);
10426   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10427   vat_json_object_add_ip4 (node, "dst_address", ip4);
10428   vat_json_object_add_uint (node, "teb", mp->teb);
10429   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10430 }
10431
10432 static int
10433 api_gre_tunnel_dump (vat_main_t * vam)
10434 {
10435   unformat_input_t *i = vam->input;
10436   vl_api_gre_tunnel_dump_t *mp;
10437   f64 timeout;
10438   u32 sw_if_index;
10439   u8 sw_if_index_set = 0;
10440
10441   /* Parse args required to build the message */
10442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10443     {
10444       if (unformat (i, "sw_if_index %d", &sw_if_index))
10445         sw_if_index_set = 1;
10446       else
10447         break;
10448     }
10449
10450   if (sw_if_index_set == 0)
10451     {
10452       sw_if_index = ~0;
10453     }
10454
10455   if (!vam->json_output)
10456     {
10457       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10458                "sw_if_index", "src_address", "dst_address", "teb",
10459                "outer_fib_id");
10460     }
10461
10462   /* Get list of gre-tunnel interfaces */
10463   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10464
10465   mp->sw_if_index = htonl (sw_if_index);
10466
10467   S;
10468
10469   /* Use a control ping for synchronization */
10470   {
10471     vl_api_control_ping_t *mp;
10472     M (CONTROL_PING, control_ping);
10473     S;
10474   }
10475   W;
10476 }
10477
10478 static int
10479 api_l2_fib_clear_table (vat_main_t * vam)
10480 {
10481 //  unformat_input_t * i = vam->input;
10482   vl_api_l2_fib_clear_table_t *mp;
10483   f64 timeout;
10484
10485   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10486
10487   S;
10488   W;
10489   /* NOTREACHED */
10490   return 0;
10491 }
10492
10493 static int
10494 api_l2_interface_efp_filter (vat_main_t * vam)
10495 {
10496   unformat_input_t *i = vam->input;
10497   vl_api_l2_interface_efp_filter_t *mp;
10498   f64 timeout;
10499   u32 sw_if_index;
10500   u8 enable = 1;
10501   u8 sw_if_index_set = 0;
10502
10503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10508         sw_if_index_set = 1;
10509       else if (unformat (i, "enable"))
10510         enable = 1;
10511       else if (unformat (i, "disable"))
10512         enable = 0;
10513       else
10514         {
10515           clib_warning ("parse error '%U'", format_unformat_error, i);
10516           return -99;
10517         }
10518     }
10519
10520   if (sw_if_index_set == 0)
10521     {
10522       errmsg ("missing sw_if_index\n");
10523       return -99;
10524     }
10525
10526   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10527
10528   mp->sw_if_index = ntohl (sw_if_index);
10529   mp->enable_disable = enable;
10530
10531   S;
10532   W;
10533   /* NOTREACHED */
10534   return 0;
10535 }
10536
10537 #define foreach_vtr_op                          \
10538 _("disable",  L2_VTR_DISABLED)                  \
10539 _("push-1",  L2_VTR_PUSH_1)                     \
10540 _("push-2",  L2_VTR_PUSH_2)                     \
10541 _("pop-1",  L2_VTR_POP_1)                       \
10542 _("pop-2",  L2_VTR_POP_2)                       \
10543 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10544 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10545 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10546 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10547
10548 static int
10549 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10550 {
10551   unformat_input_t *i = vam->input;
10552   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10553   f64 timeout;
10554   u32 sw_if_index;
10555   u8 sw_if_index_set = 0;
10556   u8 vtr_op_set = 0;
10557   u32 vtr_op = 0;
10558   u32 push_dot1q = 1;
10559   u32 tag1 = ~0;
10560   u32 tag2 = ~0;
10561
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10565         sw_if_index_set = 1;
10566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10567         sw_if_index_set = 1;
10568       else if (unformat (i, "vtr_op %d", &vtr_op))
10569         vtr_op_set = 1;
10570 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10571       foreach_vtr_op
10572 #undef _
10573         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10574         ;
10575       else if (unformat (i, "tag1 %d", &tag1))
10576         ;
10577       else if (unformat (i, "tag2 %d", &tag2))
10578         ;
10579       else
10580         {
10581           clib_warning ("parse error '%U'", format_unformat_error, i);
10582           return -99;
10583         }
10584     }
10585
10586   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10587     {
10588       errmsg ("missing vtr operation or sw_if_index\n");
10589       return -99;
10590     }
10591
10592   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10593     mp->sw_if_index = ntohl (sw_if_index);
10594   mp->vtr_op = ntohl (vtr_op);
10595   mp->push_dot1q = ntohl (push_dot1q);
10596   mp->tag1 = ntohl (tag1);
10597   mp->tag2 = ntohl (tag2);
10598
10599   S;
10600   W;
10601   /* NOTREACHED */
10602   return 0;
10603 }
10604
10605 static int
10606 api_create_vhost_user_if (vat_main_t * vam)
10607 {
10608   unformat_input_t *i = vam->input;
10609   vl_api_create_vhost_user_if_t *mp;
10610   f64 timeout;
10611   u8 *file_name;
10612   u8 is_server = 0;
10613   u8 file_name_set = 0;
10614   u32 custom_dev_instance = ~0;
10615   u8 hwaddr[6];
10616   u8 use_custom_mac = 0;
10617
10618   /* Shut up coverity */
10619   memset (hwaddr, 0, sizeof (hwaddr));
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "socket %s", &file_name))
10624         {
10625           file_name_set = 1;
10626         }
10627       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10628         ;
10629       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10630         use_custom_mac = 1;
10631       else if (unformat (i, "server"))
10632         is_server = 1;
10633       else
10634         break;
10635     }
10636
10637   if (file_name_set == 0)
10638     {
10639       errmsg ("missing socket file name\n");
10640       return -99;
10641     }
10642
10643   if (vec_len (file_name) > 255)
10644     {
10645       errmsg ("socket file name too long\n");
10646       return -99;
10647     }
10648   vec_add1 (file_name, 0);
10649
10650   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10651
10652   mp->is_server = is_server;
10653   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10654   vec_free (file_name);
10655   if (custom_dev_instance != ~0)
10656     {
10657       mp->renumber = 1;
10658       mp->custom_dev_instance = ntohl (custom_dev_instance);
10659     }
10660   mp->use_custom_mac = use_custom_mac;
10661   clib_memcpy (mp->mac_address, hwaddr, 6);
10662
10663   S;
10664   W;
10665   /* NOTREACHED */
10666   return 0;
10667 }
10668
10669 static int
10670 api_modify_vhost_user_if (vat_main_t * vam)
10671 {
10672   unformat_input_t *i = vam->input;
10673   vl_api_modify_vhost_user_if_t *mp;
10674   f64 timeout;
10675   u8 *file_name;
10676   u8 is_server = 0;
10677   u8 file_name_set = 0;
10678   u32 custom_dev_instance = ~0;
10679   u8 sw_if_index_set = 0;
10680   u32 sw_if_index = (u32) ~ 0;
10681
10682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683     {
10684       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10685         sw_if_index_set = 1;
10686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10687         sw_if_index_set = 1;
10688       else if (unformat (i, "socket %s", &file_name))
10689         {
10690           file_name_set = 1;
10691         }
10692       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10693         ;
10694       else if (unformat (i, "server"))
10695         is_server = 1;
10696       else
10697         break;
10698     }
10699
10700   if (sw_if_index_set == 0)
10701     {
10702       errmsg ("missing sw_if_index or interface name\n");
10703       return -99;
10704     }
10705
10706   if (file_name_set == 0)
10707     {
10708       errmsg ("missing socket file name\n");
10709       return -99;
10710     }
10711
10712   if (vec_len (file_name) > 255)
10713     {
10714       errmsg ("socket file name too long\n");
10715       return -99;
10716     }
10717   vec_add1 (file_name, 0);
10718
10719   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   mp->is_server = is_server;
10723   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10724   vec_free (file_name);
10725   if (custom_dev_instance != ~0)
10726     {
10727       mp->renumber = 1;
10728       mp->custom_dev_instance = ntohl (custom_dev_instance);
10729     }
10730
10731   S;
10732   W;
10733   /* NOTREACHED */
10734   return 0;
10735 }
10736
10737 static int
10738 api_delete_vhost_user_if (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_delete_vhost_user_if_t *mp;
10742   f64 timeout;
10743   u32 sw_if_index = ~0;
10744   u8 sw_if_index_set = 0;
10745
10746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10747     {
10748       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10749         sw_if_index_set = 1;
10750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10751         sw_if_index_set = 1;
10752       else
10753         break;
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       errmsg ("missing sw_if_index or interface name\n");
10759       return -99;
10760     }
10761
10762
10763   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10764
10765   mp->sw_if_index = ntohl (sw_if_index);
10766
10767   S;
10768   W;
10769   /* NOTREACHED */
10770   return 0;
10771 }
10772
10773 static void vl_api_sw_interface_vhost_user_details_t_handler
10774   (vl_api_sw_interface_vhost_user_details_t * mp)
10775 {
10776   vat_main_t *vam = &vat_main;
10777
10778   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10779            (char *) mp->interface_name,
10780            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10781            clib_net_to_host_u64 (mp->features), mp->is_server,
10782            ntohl (mp->num_regions), (char *) mp->sock_filename);
10783   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10784 }
10785
10786 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10787   (vl_api_sw_interface_vhost_user_details_t * mp)
10788 {
10789   vat_main_t *vam = &vat_main;
10790   vat_json_node_t *node = NULL;
10791
10792   if (VAT_JSON_ARRAY != vam->json_tree.type)
10793     {
10794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10795       vat_json_init_array (&vam->json_tree);
10796     }
10797   node = vat_json_array_add (&vam->json_tree);
10798
10799   vat_json_init_object (node);
10800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10801   vat_json_object_add_string_copy (node, "interface_name",
10802                                    mp->interface_name);
10803   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10804                             ntohl (mp->virtio_net_hdr_sz));
10805   vat_json_object_add_uint (node, "features",
10806                             clib_net_to_host_u64 (mp->features));
10807   vat_json_object_add_uint (node, "is_server", mp->is_server);
10808   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10809   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10810   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10811 }
10812
10813 static int
10814 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10815 {
10816   vl_api_sw_interface_vhost_user_dump_t *mp;
10817   f64 timeout;
10818   fformat (vam->ofp,
10819            "Interface name           idx hdr_sz features server regions filename\n");
10820
10821   /* Get list of vhost-user interfaces */
10822   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10823   S;
10824
10825   /* Use a control ping for synchronization */
10826   {
10827     vl_api_control_ping_t *mp;
10828     M (CONTROL_PING, control_ping);
10829     S;
10830   }
10831   W;
10832 }
10833
10834 static int
10835 api_show_version (vat_main_t * vam)
10836 {
10837   vl_api_show_version_t *mp;
10838   f64 timeout;
10839
10840   M (SHOW_VERSION, show_version);
10841
10842   S;
10843   W;
10844   /* NOTREACHED */
10845   return 0;
10846 }
10847
10848
10849 static int
10850 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10851 {
10852   unformat_input_t *line_input = vam->input;
10853   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10854   f64 timeout;
10855   ip4_address_t local4, remote4;
10856   ip6_address_t local6, remote6;
10857   u8 is_add = 1;
10858   u8 ipv4_set = 0, ipv6_set = 0;
10859   u8 local_set = 0;
10860   u8 remote_set = 0;
10861   u32 encap_vrf_id = 0;
10862   u32 decap_vrf_id = 0;
10863   u8 protocol = ~0;
10864   u32 vni;
10865   u8 vni_set = 0;
10866
10867   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (line_input, "del"))
10870         is_add = 0;
10871       else if (unformat (line_input, "local %U",
10872                          unformat_ip4_address, &local4))
10873         {
10874           local_set = 1;
10875           ipv4_set = 1;
10876         }
10877       else if (unformat (line_input, "remote %U",
10878                          unformat_ip4_address, &remote4))
10879         {
10880           remote_set = 1;
10881           ipv4_set = 1;
10882         }
10883       else if (unformat (line_input, "local %U",
10884                          unformat_ip6_address, &local6))
10885         {
10886           local_set = 1;
10887           ipv6_set = 1;
10888         }
10889       else if (unformat (line_input, "remote %U",
10890                          unformat_ip6_address, &remote6))
10891         {
10892           remote_set = 1;
10893           ipv6_set = 1;
10894         }
10895       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10896         ;
10897       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10898         ;
10899       else if (unformat (line_input, "vni %d", &vni))
10900         vni_set = 1;
10901       else if (unformat (line_input, "next-ip4"))
10902         protocol = 1;
10903       else if (unformat (line_input, "next-ip6"))
10904         protocol = 2;
10905       else if (unformat (line_input, "next-ethernet"))
10906         protocol = 3;
10907       else if (unformat (line_input, "next-nsh"))
10908         protocol = 4;
10909       else
10910         {
10911           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10912           return -99;
10913         }
10914     }
10915
10916   if (local_set == 0)
10917     {
10918       errmsg ("tunnel local address not specified\n");
10919       return -99;
10920     }
10921   if (remote_set == 0)
10922     {
10923       errmsg ("tunnel remote address not specified\n");
10924       return -99;
10925     }
10926   if (ipv4_set && ipv6_set)
10927     {
10928       errmsg ("both IPv4 and IPv6 addresses specified");
10929       return -99;
10930     }
10931
10932   if (vni_set == 0)
10933     {
10934       errmsg ("vni not specified\n");
10935       return -99;
10936     }
10937
10938   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10939
10940
10941   if (ipv6_set)
10942     {
10943       clib_memcpy (&mp->local, &local6, sizeof (local6));
10944       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10945     }
10946   else
10947     {
10948       clib_memcpy (&mp->local, &local4, sizeof (local4));
10949       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10950     }
10951
10952   mp->encap_vrf_id = ntohl (encap_vrf_id);
10953   mp->decap_vrf_id = ntohl (decap_vrf_id);
10954   mp->protocol = ntohl (protocol);
10955   mp->vni = ntohl (vni);
10956   mp->is_add = is_add;
10957   mp->is_ipv6 = ipv6_set;
10958
10959   S;
10960   W;
10961   /* NOTREACHED */
10962   return 0;
10963 }
10964
10965 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10966   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10967 {
10968   vat_main_t *vam = &vat_main;
10969
10970   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10971            ntohl (mp->sw_if_index),
10972            format_ip46_address, &(mp->local[0]),
10973            format_ip46_address, &(mp->remote[0]),
10974            ntohl (mp->vni),
10975            ntohl (mp->protocol),
10976            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10977 }
10978
10979 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10980   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10981 {
10982   vat_main_t *vam = &vat_main;
10983   vat_json_node_t *node = NULL;
10984   struct in_addr ip4;
10985   struct in6_addr ip6;
10986
10987   if (VAT_JSON_ARRAY != vam->json_tree.type)
10988     {
10989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10990       vat_json_init_array (&vam->json_tree);
10991     }
10992   node = vat_json_array_add (&vam->json_tree);
10993
10994   vat_json_init_object (node);
10995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10996   if (mp->is_ipv6)
10997     {
10998       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10999       vat_json_object_add_ip6 (node, "local", ip6);
11000       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11001       vat_json_object_add_ip6 (node, "remote", ip6);
11002     }
11003   else
11004     {
11005       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11006       vat_json_object_add_ip4 (node, "local", ip4);
11007       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11008       vat_json_object_add_ip4 (node, "remote", ip4);
11009     }
11010   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11011   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11012   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11013   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11014   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11015 }
11016
11017 static int
11018 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11019 {
11020   unformat_input_t *i = vam->input;
11021   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11022   f64 timeout;
11023   u32 sw_if_index;
11024   u8 sw_if_index_set = 0;
11025
11026   /* Parse args required to build the message */
11027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (i, "sw_if_index %d", &sw_if_index))
11030         sw_if_index_set = 1;
11031       else
11032         break;
11033     }
11034
11035   if (sw_if_index_set == 0)
11036     {
11037       sw_if_index = ~0;
11038     }
11039
11040   if (!vam->json_output)
11041     {
11042       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11043                "sw_if_index", "local", "remote", "vni",
11044                "protocol", "encap_vrf_id", "decap_vrf_id");
11045     }
11046
11047   /* Get list of vxlan-tunnel interfaces */
11048   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11049
11050   mp->sw_if_index = htonl (sw_if_index);
11051
11052   S;
11053
11054   /* Use a control ping for synchronization */
11055   {
11056     vl_api_control_ping_t *mp;
11057     M (CONTROL_PING, control_ping);
11058     S;
11059   }
11060   W;
11061 }
11062
11063 u8 *
11064 format_l2_fib_mac_address (u8 * s, va_list * args)
11065 {
11066   u8 *a = va_arg (*args, u8 *);
11067
11068   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11069                  a[2], a[3], a[4], a[5], a[6], a[7]);
11070 }
11071
11072 static void vl_api_l2_fib_table_entry_t_handler
11073   (vl_api_l2_fib_table_entry_t * mp)
11074 {
11075   vat_main_t *vam = &vat_main;
11076
11077   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11078            "       %d       %d     %d\n",
11079            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11080            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11081            mp->bvi_mac);
11082 }
11083
11084 static void vl_api_l2_fib_table_entry_t_handler_json
11085   (vl_api_l2_fib_table_entry_t * mp)
11086 {
11087   vat_main_t *vam = &vat_main;
11088   vat_json_node_t *node = NULL;
11089
11090   if (VAT_JSON_ARRAY != vam->json_tree.type)
11091     {
11092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11093       vat_json_init_array (&vam->json_tree);
11094     }
11095   node = vat_json_array_add (&vam->json_tree);
11096
11097   vat_json_init_object (node);
11098   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11099   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11100   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11101   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11102   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11103   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11104 }
11105
11106 static int
11107 api_l2_fib_table_dump (vat_main_t * vam)
11108 {
11109   unformat_input_t *i = vam->input;
11110   vl_api_l2_fib_table_dump_t *mp;
11111   f64 timeout;
11112   u32 bd_id;
11113   u8 bd_id_set = 0;
11114
11115   /* Parse args required to build the message */
11116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (i, "bd_id %d", &bd_id))
11119         bd_id_set = 1;
11120       else
11121         break;
11122     }
11123
11124   if (bd_id_set == 0)
11125     {
11126       errmsg ("missing bridge domain\n");
11127       return -99;
11128     }
11129
11130   fformat (vam->ofp,
11131            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11132
11133   /* Get list of l2 fib entries */
11134   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11135
11136   mp->bd_id = ntohl (bd_id);
11137   S;
11138
11139   /* Use a control ping for synchronization */
11140   {
11141     vl_api_control_ping_t *mp;
11142     M (CONTROL_PING, control_ping);
11143     S;
11144   }
11145   W;
11146 }
11147
11148
11149 static int
11150 api_interface_name_renumber (vat_main_t * vam)
11151 {
11152   unformat_input_t *line_input = vam->input;
11153   vl_api_interface_name_renumber_t *mp;
11154   u32 sw_if_index = ~0;
11155   f64 timeout;
11156   u32 new_show_dev_instance = ~0;
11157
11158   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11161                     &sw_if_index))
11162         ;
11163       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11164         ;
11165       else if (unformat (line_input, "new_show_dev_instance %d",
11166                          &new_show_dev_instance))
11167         ;
11168       else
11169         break;
11170     }
11171
11172   if (sw_if_index == ~0)
11173     {
11174       errmsg ("missing interface name or sw_if_index\n");
11175       return -99;
11176     }
11177
11178   if (new_show_dev_instance == ~0)
11179     {
11180       errmsg ("missing new_show_dev_instance\n");
11181       return -99;
11182     }
11183
11184   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11185
11186   mp->sw_if_index = ntohl (sw_if_index);
11187   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11188
11189   S;
11190   W;
11191 }
11192
11193 static int
11194 api_want_ip4_arp_events (vat_main_t * vam)
11195 {
11196   unformat_input_t *line_input = vam->input;
11197   vl_api_want_ip4_arp_events_t *mp;
11198   f64 timeout;
11199   ip4_address_t address;
11200   int address_set = 0;
11201   u32 enable_disable = 1;
11202
11203   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11204     {
11205       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11206         address_set = 1;
11207       else if (unformat (line_input, "del"))
11208         enable_disable = 0;
11209       else
11210         break;
11211     }
11212
11213   if (address_set == 0)
11214     {
11215       errmsg ("missing addresses\n");
11216       return -99;
11217     }
11218
11219   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11220   mp->enable_disable = enable_disable;
11221   mp->pid = getpid ();
11222   mp->address = address.as_u32;
11223
11224   S;
11225   W;
11226 }
11227
11228 static int
11229 api_want_ip6_nd_events (vat_main_t * vam)
11230 {
11231   unformat_input_t *line_input = vam->input;
11232   vl_api_want_ip6_nd_events_t *mp;
11233   f64 timeout;
11234   ip6_address_t address;
11235   int address_set = 0;
11236   u32 enable_disable = 1;
11237
11238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11239     {
11240       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11241         address_set = 1;
11242       else if (unformat (line_input, "del"))
11243         enable_disable = 0;
11244       else
11245         break;
11246     }
11247
11248   if (address_set == 0)
11249     {
11250       errmsg ("missing addresses\n");
11251       return -99;
11252     }
11253
11254   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11255   mp->enable_disable = enable_disable;
11256   mp->pid = getpid ();
11257   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11258
11259   S;
11260   W;
11261 }
11262
11263 static int
11264 api_input_acl_set_interface (vat_main_t * vam)
11265 {
11266   unformat_input_t *i = vam->input;
11267   vl_api_input_acl_set_interface_t *mp;
11268   f64 timeout;
11269   u32 sw_if_index;
11270   int sw_if_index_set;
11271   u32 ip4_table_index = ~0;
11272   u32 ip6_table_index = ~0;
11273   u32 l2_table_index = ~0;
11274   u8 is_add = 1;
11275
11276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11277     {
11278       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11279         sw_if_index_set = 1;
11280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11281         sw_if_index_set = 1;
11282       else if (unformat (i, "del"))
11283         is_add = 0;
11284       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11285         ;
11286       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11287         ;
11288       else if (unformat (i, "l2-table %d", &l2_table_index))
11289         ;
11290       else
11291         {
11292           clib_warning ("parse error '%U'", format_unformat_error, i);
11293           return -99;
11294         }
11295     }
11296
11297   if (sw_if_index_set == 0)
11298     {
11299       errmsg ("missing interface name or sw_if_index\n");
11300       return -99;
11301     }
11302
11303   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11304
11305   mp->sw_if_index = ntohl (sw_if_index);
11306   mp->ip4_table_index = ntohl (ip4_table_index);
11307   mp->ip6_table_index = ntohl (ip6_table_index);
11308   mp->l2_table_index = ntohl (l2_table_index);
11309   mp->is_add = is_add;
11310
11311   S;
11312   W;
11313   /* NOTREACHED */
11314   return 0;
11315 }
11316
11317 static int
11318 api_ip_address_dump (vat_main_t * vam)
11319 {
11320   unformat_input_t *i = vam->input;
11321   vl_api_ip_address_dump_t *mp;
11322   u32 sw_if_index = ~0;
11323   u8 sw_if_index_set = 0;
11324   u8 ipv4_set = 0;
11325   u8 ipv6_set = 0;
11326   f64 timeout;
11327
11328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11329     {
11330       if (unformat (i, "sw_if_index %d", &sw_if_index))
11331         sw_if_index_set = 1;
11332       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11333         sw_if_index_set = 1;
11334       else if (unformat (i, "ipv4"))
11335         ipv4_set = 1;
11336       else if (unformat (i, "ipv6"))
11337         ipv6_set = 1;
11338       else
11339         break;
11340     }
11341
11342   if (ipv4_set && ipv6_set)
11343     {
11344       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11345       return -99;
11346     }
11347
11348   if ((!ipv4_set) && (!ipv6_set))
11349     {
11350       errmsg ("no ipv4 nor ipv6 flag set\n");
11351       return -99;
11352     }
11353
11354   if (sw_if_index_set == 0)
11355     {
11356       errmsg ("missing interface name or sw_if_index\n");
11357       return -99;
11358     }
11359
11360   vam->current_sw_if_index = sw_if_index;
11361   vam->is_ipv6 = ipv6_set;
11362
11363   M (IP_ADDRESS_DUMP, ip_address_dump);
11364   mp->sw_if_index = ntohl (sw_if_index);
11365   mp->is_ipv6 = ipv6_set;
11366   S;
11367
11368   /* Use a control ping for synchronization */
11369   {
11370     vl_api_control_ping_t *mp;
11371     M (CONTROL_PING, control_ping);
11372     S;
11373   }
11374   W;
11375 }
11376
11377 static int
11378 api_ip_dump (vat_main_t * vam)
11379 {
11380   vl_api_ip_dump_t *mp;
11381   unformat_input_t *in = vam->input;
11382   int ipv4_set = 0;
11383   int ipv6_set = 0;
11384   int is_ipv6;
11385   f64 timeout;
11386   int i;
11387
11388   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11389     {
11390       if (unformat (in, "ipv4"))
11391         ipv4_set = 1;
11392       else if (unformat (in, "ipv6"))
11393         ipv6_set = 1;
11394       else
11395         break;
11396     }
11397
11398   if (ipv4_set && ipv6_set)
11399     {
11400       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11401       return -99;
11402     }
11403
11404   if ((!ipv4_set) && (!ipv6_set))
11405     {
11406       errmsg ("no ipv4 nor ipv6 flag set\n");
11407       return -99;
11408     }
11409
11410   is_ipv6 = ipv6_set;
11411   vam->is_ipv6 = is_ipv6;
11412
11413   /* free old data */
11414   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11415     {
11416       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11417     }
11418   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11419
11420   M (IP_DUMP, ip_dump);
11421   mp->is_ipv6 = ipv6_set;
11422   S;
11423
11424   /* Use a control ping for synchronization */
11425   {
11426     vl_api_control_ping_t *mp;
11427     M (CONTROL_PING, control_ping);
11428     S;
11429   }
11430   W;
11431 }
11432
11433 static int
11434 api_ipsec_spd_add_del (vat_main_t * vam)
11435 {
11436   unformat_input_t *i = vam->input;
11437   vl_api_ipsec_spd_add_del_t *mp;
11438   f64 timeout;
11439   u32 spd_id = ~0;
11440   u8 is_add = 1;
11441
11442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (i, "spd_id %d", &spd_id))
11445         ;
11446       else if (unformat (i, "del"))
11447         is_add = 0;
11448       else
11449         {
11450           clib_warning ("parse error '%U'", format_unformat_error, i);
11451           return -99;
11452         }
11453     }
11454   if (spd_id == ~0)
11455     {
11456       errmsg ("spd_id must be set\n");
11457       return -99;
11458     }
11459
11460   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11461
11462   mp->spd_id = ntohl (spd_id);
11463   mp->is_add = is_add;
11464
11465   S;
11466   W;
11467   /* NOTREACHED */
11468   return 0;
11469 }
11470
11471 static int
11472 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_ipsec_interface_add_del_spd_t *mp;
11476   f64 timeout;
11477   u32 sw_if_index;
11478   u8 sw_if_index_set = 0;
11479   u32 spd_id = (u32) ~ 0;
11480   u8 is_add = 1;
11481
11482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (i, "del"))
11485         is_add = 0;
11486       else if (unformat (i, "spd_id %d", &spd_id))
11487         ;
11488       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11489         sw_if_index_set = 1;
11490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11491         sw_if_index_set = 1;
11492       else
11493         {
11494           clib_warning ("parse error '%U'", format_unformat_error, i);
11495           return -99;
11496         }
11497
11498     }
11499
11500   if (spd_id == (u32) ~ 0)
11501     {
11502       errmsg ("spd_id must be set\n");
11503       return -99;
11504     }
11505
11506   if (sw_if_index_set == 0)
11507     {
11508       errmsg ("missing interface name or sw_if_index\n");
11509       return -99;
11510     }
11511
11512   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11513
11514   mp->spd_id = ntohl (spd_id);
11515   mp->sw_if_index = ntohl (sw_if_index);
11516   mp->is_add = is_add;
11517
11518   S;
11519   W;
11520   /* NOTREACHED */
11521   return 0;
11522 }
11523
11524 static int
11525 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11526 {
11527   unformat_input_t *i = vam->input;
11528   vl_api_ipsec_spd_add_del_entry_t *mp;
11529   f64 timeout;
11530   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11531   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11532   i32 priority = 0;
11533   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11534   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11535   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11536   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11537
11538   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11539   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11540   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11541   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11542   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11543   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11544
11545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11546     {
11547       if (unformat (i, "del"))
11548         is_add = 0;
11549       if (unformat (i, "outbound"))
11550         is_outbound = 1;
11551       if (unformat (i, "inbound"))
11552         is_outbound = 0;
11553       else if (unformat (i, "spd_id %d", &spd_id))
11554         ;
11555       else if (unformat (i, "sa_id %d", &sa_id))
11556         ;
11557       else if (unformat (i, "priority %d", &priority))
11558         ;
11559       else if (unformat (i, "protocol %d", &protocol))
11560         ;
11561       else if (unformat (i, "lport_start %d", &lport_start))
11562         ;
11563       else if (unformat (i, "lport_stop %d", &lport_stop))
11564         ;
11565       else if (unformat (i, "rport_start %d", &rport_start))
11566         ;
11567       else if (unformat (i, "rport_stop %d", &rport_stop))
11568         ;
11569       else
11570         if (unformat
11571             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11572         {
11573           is_ipv6 = 0;
11574           is_ip_any = 0;
11575         }
11576       else
11577         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11578         {
11579           is_ipv6 = 0;
11580           is_ip_any = 0;
11581         }
11582       else
11583         if (unformat
11584             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11585         {
11586           is_ipv6 = 0;
11587           is_ip_any = 0;
11588         }
11589       else
11590         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11591         {
11592           is_ipv6 = 0;
11593           is_ip_any = 0;
11594         }
11595       else
11596         if (unformat
11597             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11598         {
11599           is_ipv6 = 1;
11600           is_ip_any = 0;
11601         }
11602       else
11603         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11604         {
11605           is_ipv6 = 1;
11606           is_ip_any = 0;
11607         }
11608       else
11609         if (unformat
11610             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11611         {
11612           is_ipv6 = 1;
11613           is_ip_any = 0;
11614         }
11615       else
11616         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11617         {
11618           is_ipv6 = 1;
11619           is_ip_any = 0;
11620         }
11621       else
11622         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11623         {
11624           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11625             {
11626               clib_warning ("unsupported action: 'resolve'");
11627               return -99;
11628             }
11629         }
11630       else
11631         {
11632           clib_warning ("parse error '%U'", format_unformat_error, i);
11633           return -99;
11634         }
11635
11636     }
11637
11638   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11639
11640   mp->spd_id = ntohl (spd_id);
11641   mp->priority = ntohl (priority);
11642   mp->is_outbound = is_outbound;
11643
11644   mp->is_ipv6 = is_ipv6;
11645   if (is_ipv6 || is_ip_any)
11646     {
11647       clib_memcpy (mp->remote_address_start, &raddr6_start,
11648                    sizeof (ip6_address_t));
11649       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11650                    sizeof (ip6_address_t));
11651       clib_memcpy (mp->local_address_start, &laddr6_start,
11652                    sizeof (ip6_address_t));
11653       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11654                    sizeof (ip6_address_t));
11655     }
11656   else
11657     {
11658       clib_memcpy (mp->remote_address_start, &raddr4_start,
11659                    sizeof (ip4_address_t));
11660       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11661                    sizeof (ip4_address_t));
11662       clib_memcpy (mp->local_address_start, &laddr4_start,
11663                    sizeof (ip4_address_t));
11664       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11665                    sizeof (ip4_address_t));
11666     }
11667   mp->protocol = (u8) protocol;
11668   mp->local_port_start = ntohs ((u16) lport_start);
11669   mp->local_port_stop = ntohs ((u16) lport_stop);
11670   mp->remote_port_start = ntohs ((u16) rport_start);
11671   mp->remote_port_stop = ntohs ((u16) rport_stop);
11672   mp->policy = (u8) policy;
11673   mp->sa_id = ntohl (sa_id);
11674   mp->is_add = is_add;
11675   mp->is_ip_any = is_ip_any;
11676   S;
11677   W;
11678   /* NOTREACHED */
11679   return 0;
11680 }
11681
11682 static int
11683 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11684 {
11685   unformat_input_t *i = vam->input;
11686   vl_api_ipsec_sad_add_del_entry_t *mp;
11687   f64 timeout;
11688   u32 sad_id = 0, spi = 0;
11689   u8 *ck = 0, *ik = 0;
11690   u8 is_add = 1;
11691
11692   u8 protocol = IPSEC_PROTOCOL_AH;
11693   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11694   u32 crypto_alg = 0, integ_alg = 0;
11695   ip4_address_t tun_src4;
11696   ip4_address_t tun_dst4;
11697   ip6_address_t tun_src6;
11698   ip6_address_t tun_dst6;
11699
11700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11701     {
11702       if (unformat (i, "del"))
11703         is_add = 0;
11704       else if (unformat (i, "sad_id %d", &sad_id))
11705         ;
11706       else if (unformat (i, "spi %d", &spi))
11707         ;
11708       else if (unformat (i, "esp"))
11709         protocol = IPSEC_PROTOCOL_ESP;
11710       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11711         {
11712           is_tunnel = 1;
11713           is_tunnel_ipv6 = 0;
11714         }
11715       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11716         {
11717           is_tunnel = 1;
11718           is_tunnel_ipv6 = 0;
11719         }
11720       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11721         {
11722           is_tunnel = 1;
11723           is_tunnel_ipv6 = 1;
11724         }
11725       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11726         {
11727           is_tunnel = 1;
11728           is_tunnel_ipv6 = 1;
11729         }
11730       else
11731         if (unformat
11732             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11733         {
11734           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11735               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11736             {
11737               clib_warning ("unsupported crypto-alg: '%U'",
11738                             format_ipsec_crypto_alg, crypto_alg);
11739               return -99;
11740             }
11741         }
11742       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11743         ;
11744       else
11745         if (unformat
11746             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11747         {
11748           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11749               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11750             {
11751               clib_warning ("unsupported integ-alg: '%U'",
11752                             format_ipsec_integ_alg, integ_alg);
11753               return -99;
11754             }
11755         }
11756       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11757         ;
11758       else
11759         {
11760           clib_warning ("parse error '%U'", format_unformat_error, i);
11761           return -99;
11762         }
11763
11764     }
11765
11766   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11767
11768   mp->sad_id = ntohl (sad_id);
11769   mp->is_add = is_add;
11770   mp->protocol = protocol;
11771   mp->spi = ntohl (spi);
11772   mp->is_tunnel = is_tunnel;
11773   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11774   mp->crypto_algorithm = crypto_alg;
11775   mp->integrity_algorithm = integ_alg;
11776   mp->crypto_key_length = vec_len (ck);
11777   mp->integrity_key_length = vec_len (ik);
11778
11779   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11780     mp->crypto_key_length = sizeof (mp->crypto_key);
11781
11782   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11783     mp->integrity_key_length = sizeof (mp->integrity_key);
11784
11785   if (ck)
11786     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11787   if (ik)
11788     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11789
11790   if (is_tunnel)
11791     {
11792       if (is_tunnel_ipv6)
11793         {
11794           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11795                        sizeof (ip6_address_t));
11796           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11797                        sizeof (ip6_address_t));
11798         }
11799       else
11800         {
11801           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11802                        sizeof (ip4_address_t));
11803           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11804                        sizeof (ip4_address_t));
11805         }
11806     }
11807
11808   S;
11809   W;
11810   /* NOTREACHED */
11811   return 0;
11812 }
11813
11814 static int
11815 api_ipsec_sa_set_key (vat_main_t * vam)
11816 {
11817   unformat_input_t *i = vam->input;
11818   vl_api_ipsec_sa_set_key_t *mp;
11819   f64 timeout;
11820   u32 sa_id;
11821   u8 *ck = 0, *ik = 0;
11822
11823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11824     {
11825       if (unformat (i, "sa_id %d", &sa_id))
11826         ;
11827       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11828         ;
11829       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11830         ;
11831       else
11832         {
11833           clib_warning ("parse error '%U'", format_unformat_error, i);
11834           return -99;
11835         }
11836     }
11837
11838   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11839
11840   mp->sa_id = ntohl (sa_id);
11841   mp->crypto_key_length = vec_len (ck);
11842   mp->integrity_key_length = vec_len (ik);
11843
11844   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11845     mp->crypto_key_length = sizeof (mp->crypto_key);
11846
11847   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11848     mp->integrity_key_length = sizeof (mp->integrity_key);
11849
11850   if (ck)
11851     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11852   if (ik)
11853     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11854
11855   S;
11856   W;
11857   /* NOTREACHED */
11858   return 0;
11859 }
11860
11861 static int
11862 api_ikev2_profile_add_del (vat_main_t * vam)
11863 {
11864   unformat_input_t *i = vam->input;
11865   vl_api_ikev2_profile_add_del_t *mp;
11866   f64 timeout;
11867   u8 is_add = 1;
11868   u8 *name = 0;
11869
11870   const char *valid_chars = "a-zA-Z0-9_";
11871
11872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11873     {
11874       if (unformat (i, "del"))
11875         is_add = 0;
11876       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11877         vec_add1 (name, 0);
11878       else
11879         {
11880           errmsg ("parse error '%U'", format_unformat_error, i);
11881           return -99;
11882         }
11883     }
11884
11885   if (!vec_len (name))
11886     {
11887       errmsg ("profile name must be specified");
11888       return -99;
11889     }
11890
11891   if (vec_len (name) > 64)
11892     {
11893       errmsg ("profile name too long");
11894       return -99;
11895     }
11896
11897   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11898
11899   clib_memcpy (mp->name, name, vec_len (name));
11900   mp->is_add = is_add;
11901   vec_free (name);
11902
11903   S;
11904   W;
11905   /* NOTREACHED */
11906   return 0;
11907 }
11908
11909 static int
11910 api_ikev2_profile_set_auth (vat_main_t * vam)
11911 {
11912   unformat_input_t *i = vam->input;
11913   vl_api_ikev2_profile_set_auth_t *mp;
11914   f64 timeout;
11915   u8 *name = 0;
11916   u8 *data = 0;
11917   u32 auth_method = 0;
11918   u8 is_hex = 0;
11919
11920   const char *valid_chars = "a-zA-Z0-9_";
11921
11922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11923     {
11924       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11925         vec_add1 (name, 0);
11926       else if (unformat (i, "auth_method %U",
11927                          unformat_ikev2_auth_method, &auth_method))
11928         ;
11929       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11930         is_hex = 1;
11931       else if (unformat (i, "auth_data %v", &data))
11932         ;
11933       else
11934         {
11935           errmsg ("parse error '%U'", format_unformat_error, i);
11936           return -99;
11937         }
11938     }
11939
11940   if (!vec_len (name))
11941     {
11942       errmsg ("profile name must be specified");
11943       return -99;
11944     }
11945
11946   if (vec_len (name) > 64)
11947     {
11948       errmsg ("profile name too long");
11949       return -99;
11950     }
11951
11952   if (!vec_len (data))
11953     {
11954       errmsg ("auth_data must be specified");
11955       return -99;
11956     }
11957
11958   if (!auth_method)
11959     {
11960       errmsg ("auth_method must be specified");
11961       return -99;
11962     }
11963
11964   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11965
11966   mp->is_hex = is_hex;
11967   mp->auth_method = (u8) auth_method;
11968   mp->data_len = vec_len (data);
11969   clib_memcpy (mp->name, name, vec_len (name));
11970   clib_memcpy (mp->data, data, vec_len (data));
11971   vec_free (name);
11972   vec_free (data);
11973
11974   S;
11975   W;
11976   /* NOTREACHED */
11977   return 0;
11978 }
11979
11980 static int
11981 api_ikev2_profile_set_id (vat_main_t * vam)
11982 {
11983   unformat_input_t *i = vam->input;
11984   vl_api_ikev2_profile_set_id_t *mp;
11985   f64 timeout;
11986   u8 *name = 0;
11987   u8 *data = 0;
11988   u8 is_local = 0;
11989   u32 id_type = 0;
11990   ip4_address_t ip4;
11991
11992   const char *valid_chars = "a-zA-Z0-9_";
11993
11994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11995     {
11996       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11997         vec_add1 (name, 0);
11998       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11999         ;
12000       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12001         {
12002           data = vec_new (u8, 4);
12003           clib_memcpy (data, ip4.as_u8, 4);
12004         }
12005       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12006         ;
12007       else if (unformat (i, "id_data %v", &data))
12008         ;
12009       else if (unformat (i, "local"))
12010         is_local = 1;
12011       else if (unformat (i, "remote"))
12012         is_local = 0;
12013       else
12014         {
12015           errmsg ("parse error '%U'", format_unformat_error, i);
12016           return -99;
12017         }
12018     }
12019
12020   if (!vec_len (name))
12021     {
12022       errmsg ("profile name must be specified");
12023       return -99;
12024     }
12025
12026   if (vec_len (name) > 64)
12027     {
12028       errmsg ("profile name too long");
12029       return -99;
12030     }
12031
12032   if (!vec_len (data))
12033     {
12034       errmsg ("id_data must be specified");
12035       return -99;
12036     }
12037
12038   if (!id_type)
12039     {
12040       errmsg ("id_type must be specified");
12041       return -99;
12042     }
12043
12044   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12045
12046   mp->is_local = is_local;
12047   mp->id_type = (u8) id_type;
12048   mp->data_len = vec_len (data);
12049   clib_memcpy (mp->name, name, vec_len (name));
12050   clib_memcpy (mp->data, data, vec_len (data));
12051   vec_free (name);
12052   vec_free (data);
12053
12054   S;
12055   W;
12056   /* NOTREACHED */
12057   return 0;
12058 }
12059
12060 static int
12061 api_ikev2_profile_set_ts (vat_main_t * vam)
12062 {
12063   unformat_input_t *i = vam->input;
12064   vl_api_ikev2_profile_set_ts_t *mp;
12065   f64 timeout;
12066   u8 *name = 0;
12067   u8 is_local = 0;
12068   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12069   ip4_address_t start_addr, end_addr;
12070
12071   const char *valid_chars = "a-zA-Z0-9_";
12072
12073   start_addr.as_u32 = 0;
12074   end_addr.as_u32 = (u32) ~ 0;
12075
12076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12077     {
12078       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12079         vec_add1 (name, 0);
12080       else if (unformat (i, "protocol %d", &proto))
12081         ;
12082       else if (unformat (i, "start_port %d", &start_port))
12083         ;
12084       else if (unformat (i, "end_port %d", &end_port))
12085         ;
12086       else
12087         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12088         ;
12089       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12090         ;
12091       else if (unformat (i, "local"))
12092         is_local = 1;
12093       else if (unformat (i, "remote"))
12094         is_local = 0;
12095       else
12096         {
12097           errmsg ("parse error '%U'", format_unformat_error, i);
12098           return -99;
12099         }
12100     }
12101
12102   if (!vec_len (name))
12103     {
12104       errmsg ("profile name must be specified");
12105       return -99;
12106     }
12107
12108   if (vec_len (name) > 64)
12109     {
12110       errmsg ("profile name too long");
12111       return -99;
12112     }
12113
12114   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12115
12116   mp->is_local = is_local;
12117   mp->proto = (u8) proto;
12118   mp->start_port = (u16) start_port;
12119   mp->end_port = (u16) end_port;
12120   mp->start_addr = start_addr.as_u32;
12121   mp->end_addr = end_addr.as_u32;
12122   clib_memcpy (mp->name, name, vec_len (name));
12123   vec_free (name);
12124
12125   S;
12126   W;
12127   /* NOTREACHED */
12128   return 0;
12129 }
12130
12131 static int
12132 api_ikev2_set_local_key (vat_main_t * vam)
12133 {
12134   unformat_input_t *i = vam->input;
12135   vl_api_ikev2_set_local_key_t *mp;
12136   f64 timeout;
12137   u8 *file = 0;
12138
12139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12140     {
12141       if (unformat (i, "file %v", &file))
12142         vec_add1 (file, 0);
12143       else
12144         {
12145           errmsg ("parse error '%U'", format_unformat_error, i);
12146           return -99;
12147         }
12148     }
12149
12150   if (!vec_len (file))
12151     {
12152       errmsg ("RSA key file must be specified");
12153       return -99;
12154     }
12155
12156   if (vec_len (file) > 256)
12157     {
12158       errmsg ("file name too long");
12159       return -99;
12160     }
12161
12162   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12163
12164   clib_memcpy (mp->key_file, file, vec_len (file));
12165   vec_free (file);
12166
12167   S;
12168   W;
12169   /* NOTREACHED */
12170   return 0;
12171 }
12172
12173 /*
12174  * MAP
12175  */
12176 static int
12177 api_map_add_domain (vat_main_t * vam)
12178 {
12179   unformat_input_t *i = vam->input;
12180   vl_api_map_add_domain_t *mp;
12181   f64 timeout;
12182
12183   ip4_address_t ip4_prefix;
12184   ip6_address_t ip6_prefix;
12185   ip6_address_t ip6_src;
12186   u32 num_m_args = 0;
12187   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12188     0, psid_length = 0;
12189   u8 is_translation = 0;
12190   u32 mtu = 0;
12191   u32 ip6_src_len = 128;
12192
12193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12194     {
12195       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12196                     &ip4_prefix, &ip4_prefix_len))
12197         num_m_args++;
12198       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12199                          &ip6_prefix, &ip6_prefix_len))
12200         num_m_args++;
12201       else
12202         if (unformat
12203             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12204              &ip6_src_len))
12205         num_m_args++;
12206       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12207         num_m_args++;
12208       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12209         num_m_args++;
12210       else if (unformat (i, "psid-offset %d", &psid_offset))
12211         num_m_args++;
12212       else if (unformat (i, "psid-len %d", &psid_length))
12213         num_m_args++;
12214       else if (unformat (i, "mtu %d", &mtu))
12215         num_m_args++;
12216       else if (unformat (i, "map-t"))
12217         is_translation = 1;
12218       else
12219         {
12220           clib_warning ("parse error '%U'", format_unformat_error, i);
12221           return -99;
12222         }
12223     }
12224
12225   if (num_m_args < 3)
12226     {
12227       errmsg ("mandatory argument(s) missing\n");
12228       return -99;
12229     }
12230
12231   /* Construct the API message */
12232   M (MAP_ADD_DOMAIN, map_add_domain);
12233
12234   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12235   mp->ip4_prefix_len = ip4_prefix_len;
12236
12237   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12238   mp->ip6_prefix_len = ip6_prefix_len;
12239
12240   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12241   mp->ip6_src_prefix_len = ip6_src_len;
12242
12243   mp->ea_bits_len = ea_bits_len;
12244   mp->psid_offset = psid_offset;
12245   mp->psid_length = psid_length;
12246   mp->is_translation = is_translation;
12247   mp->mtu = htons (mtu);
12248
12249   /* send it... */
12250   S;
12251
12252   /* Wait for a reply, return good/bad news  */
12253   W;
12254 }
12255
12256 static int
12257 api_map_del_domain (vat_main_t * vam)
12258 {
12259   unformat_input_t *i = vam->input;
12260   vl_api_map_del_domain_t *mp;
12261   f64 timeout;
12262
12263   u32 num_m_args = 0;
12264   u32 index;
12265
12266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12267     {
12268       if (unformat (i, "index %d", &index))
12269         num_m_args++;
12270       else
12271         {
12272           clib_warning ("parse error '%U'", format_unformat_error, i);
12273           return -99;
12274         }
12275     }
12276
12277   if (num_m_args != 1)
12278     {
12279       errmsg ("mandatory argument(s) missing\n");
12280       return -99;
12281     }
12282
12283   /* Construct the API message */
12284   M (MAP_DEL_DOMAIN, map_del_domain);
12285
12286   mp->index = ntohl (index);
12287
12288   /* send it... */
12289   S;
12290
12291   /* Wait for a reply, return good/bad news  */
12292   W;
12293 }
12294
12295 static int
12296 api_map_add_del_rule (vat_main_t * vam)
12297 {
12298   unformat_input_t *i = vam->input;
12299   vl_api_map_add_del_rule_t *mp;
12300   f64 timeout;
12301   u8 is_add = 1;
12302   ip6_address_t ip6_dst;
12303   u32 num_m_args = 0, index, psid = 0;
12304
12305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12306     {
12307       if (unformat (i, "index %d", &index))
12308         num_m_args++;
12309       else if (unformat (i, "psid %d", &psid))
12310         num_m_args++;
12311       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12312         num_m_args++;
12313       else if (unformat (i, "del"))
12314         {
12315           is_add = 0;
12316         }
12317       else
12318         {
12319           clib_warning ("parse error '%U'", format_unformat_error, i);
12320           return -99;
12321         }
12322     }
12323
12324   /* Construct the API message */
12325   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12326
12327   mp->index = ntohl (index);
12328   mp->is_add = is_add;
12329   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12330   mp->psid = ntohs (psid);
12331
12332   /* send it... */
12333   S;
12334
12335   /* Wait for a reply, return good/bad news  */
12336   W;
12337 }
12338
12339 static int
12340 api_map_domain_dump (vat_main_t * vam)
12341 {
12342   vl_api_map_domain_dump_t *mp;
12343   f64 timeout;
12344
12345   /* Construct the API message */
12346   M (MAP_DOMAIN_DUMP, map_domain_dump);
12347
12348   /* send it... */
12349   S;
12350
12351   /* Use a control ping for synchronization */
12352   {
12353     vl_api_control_ping_t *mp;
12354     M (CONTROL_PING, control_ping);
12355     S;
12356   }
12357   W;
12358 }
12359
12360 static int
12361 api_map_rule_dump (vat_main_t * vam)
12362 {
12363   unformat_input_t *i = vam->input;
12364   vl_api_map_rule_dump_t *mp;
12365   f64 timeout;
12366   u32 domain_index = ~0;
12367
12368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12369     {
12370       if (unformat (i, "index %u", &domain_index))
12371         ;
12372       else
12373         break;
12374     }
12375
12376   if (domain_index == ~0)
12377     {
12378       clib_warning ("parse error: domain index expected");
12379       return -99;
12380     }
12381
12382   /* Construct the API message */
12383   M (MAP_RULE_DUMP, map_rule_dump);
12384
12385   mp->domain_index = htonl (domain_index);
12386
12387   /* send it... */
12388   S;
12389
12390   /* Use a control ping for synchronization */
12391   {
12392     vl_api_control_ping_t *mp;
12393     M (CONTROL_PING, control_ping);
12394     S;
12395   }
12396   W;
12397 }
12398
12399 static void vl_api_map_add_domain_reply_t_handler
12400   (vl_api_map_add_domain_reply_t * mp)
12401 {
12402   vat_main_t *vam = &vat_main;
12403   i32 retval = ntohl (mp->retval);
12404
12405   if (vam->async_mode)
12406     {
12407       vam->async_errors += (retval < 0);
12408     }
12409   else
12410     {
12411       vam->retval = retval;
12412       vam->result_ready = 1;
12413     }
12414 }
12415
12416 static void vl_api_map_add_domain_reply_t_handler_json
12417   (vl_api_map_add_domain_reply_t * mp)
12418 {
12419   vat_main_t *vam = &vat_main;
12420   vat_json_node_t node;
12421
12422   vat_json_init_object (&node);
12423   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12424   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12425
12426   vat_json_print (vam->ofp, &node);
12427   vat_json_free (&node);
12428
12429   vam->retval = ntohl (mp->retval);
12430   vam->result_ready = 1;
12431 }
12432
12433 static int
12434 api_get_first_msg_id (vat_main_t * vam)
12435 {
12436   vl_api_get_first_msg_id_t *mp;
12437   f64 timeout;
12438   unformat_input_t *i = vam->input;
12439   u8 *name;
12440   u8 name_set = 0;
12441
12442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12443     {
12444       if (unformat (i, "client %s", &name))
12445         name_set = 1;
12446       else
12447         break;
12448     }
12449
12450   if (name_set == 0)
12451     {
12452       errmsg ("missing client name\n");
12453       return -99;
12454     }
12455   vec_add1 (name, 0);
12456
12457   if (vec_len (name) > 63)
12458     {
12459       errmsg ("client name too long\n");
12460       return -99;
12461     }
12462
12463   M (GET_FIRST_MSG_ID, get_first_msg_id);
12464   clib_memcpy (mp->name, name, vec_len (name));
12465   S;
12466   W;
12467   /* NOTREACHED */
12468   return 0;
12469 }
12470
12471 static int
12472 api_cop_interface_enable_disable (vat_main_t * vam)
12473 {
12474   unformat_input_t *line_input = vam->input;
12475   vl_api_cop_interface_enable_disable_t *mp;
12476   f64 timeout;
12477   u32 sw_if_index = ~0;
12478   u8 enable_disable = 1;
12479
12480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12481     {
12482       if (unformat (line_input, "disable"))
12483         enable_disable = 0;
12484       if (unformat (line_input, "enable"))
12485         enable_disable = 1;
12486       else if (unformat (line_input, "%U", unformat_sw_if_index,
12487                          vam, &sw_if_index))
12488         ;
12489       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12490         ;
12491       else
12492         break;
12493     }
12494
12495   if (sw_if_index == ~0)
12496     {
12497       errmsg ("missing interface name or sw_if_index\n");
12498       return -99;
12499     }
12500
12501   /* Construct the API message */
12502   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12503   mp->sw_if_index = ntohl (sw_if_index);
12504   mp->enable_disable = enable_disable;
12505
12506   /* send it... */
12507   S;
12508   /* Wait for the reply */
12509   W;
12510 }
12511
12512 static int
12513 api_cop_whitelist_enable_disable (vat_main_t * vam)
12514 {
12515   unformat_input_t *line_input = vam->input;
12516   vl_api_cop_whitelist_enable_disable_t *mp;
12517   f64 timeout;
12518   u32 sw_if_index = ~0;
12519   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12520   u32 fib_id = 0;
12521
12522   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12523     {
12524       if (unformat (line_input, "ip4"))
12525         ip4 = 1;
12526       else if (unformat (line_input, "ip6"))
12527         ip6 = 1;
12528       else if (unformat (line_input, "default"))
12529         default_cop = 1;
12530       else if (unformat (line_input, "%U", unformat_sw_if_index,
12531                          vam, &sw_if_index))
12532         ;
12533       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12534         ;
12535       else if (unformat (line_input, "fib-id %d", &fib_id))
12536         ;
12537       else
12538         break;
12539     }
12540
12541   if (sw_if_index == ~0)
12542     {
12543       errmsg ("missing interface name or sw_if_index\n");
12544       return -99;
12545     }
12546
12547   /* Construct the API message */
12548   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12549   mp->sw_if_index = ntohl (sw_if_index);
12550   mp->fib_id = ntohl (fib_id);
12551   mp->ip4 = ip4;
12552   mp->ip6 = ip6;
12553   mp->default_cop = default_cop;
12554
12555   /* send it... */
12556   S;
12557   /* Wait for the reply */
12558   W;
12559 }
12560
12561 static int
12562 api_get_node_graph (vat_main_t * vam)
12563 {
12564   vl_api_get_node_graph_t *mp;
12565   f64 timeout;
12566
12567   M (GET_NODE_GRAPH, get_node_graph);
12568
12569   /* send it... */
12570   S;
12571   /* Wait for the reply */
12572   W;
12573 }
12574
12575 /* *INDENT-OFF* */
12576 /** Used for parsing LISP eids */
12577 typedef CLIB_PACKED(struct{
12578   u8 addr[16];   /**< eid address */
12579   u32 len;       /**< prefix length if IP */
12580   u8 type;      /**< type of eid */
12581 }) lisp_eid_vat_t;
12582 /* *INDENT-ON* */
12583
12584 static uword
12585 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12586 {
12587   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12588
12589   memset (a, 0, sizeof (a[0]));
12590
12591   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12592     {
12593       a->type = 0;              /* ipv4 type */
12594     }
12595   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12596     {
12597       a->type = 1;              /* ipv6 type */
12598     }
12599   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12600     {
12601       a->type = 2;              /* mac type */
12602     }
12603   else
12604     {
12605       return 0;
12606     }
12607
12608   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12609     {
12610       return 0;
12611     }
12612
12613   return 1;
12614 }
12615
12616 static int
12617 lisp_eid_size_vat (u8 type)
12618 {
12619   switch (type)
12620     {
12621     case 0:
12622       return 4;
12623     case 1:
12624       return 16;
12625     case 2:
12626       return 6;
12627     }
12628   return 0;
12629 }
12630
12631 static void
12632 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12633 {
12634   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12635 }
12636
12637 /* *INDENT-OFF* */
12638 /** Used for transferring locators via VPP API */
12639 typedef CLIB_PACKED(struct
12640 {
12641   u32 sw_if_index; /**< locator sw_if_index */
12642   u8 priority; /**< locator priority */
12643   u8 weight;   /**< locator weight */
12644 }) ls_locator_t;
12645 /* *INDENT-ON* */
12646
12647 static int
12648 api_lisp_add_del_locator_set (vat_main_t * vam)
12649 {
12650   unformat_input_t *input = vam->input;
12651   vl_api_lisp_add_del_locator_set_t *mp;
12652   f64 timeout = ~0;
12653   u8 is_add = 1;
12654   u8 *locator_set_name = NULL;
12655   u8 locator_set_name_set = 0;
12656   ls_locator_t locator, *locators = 0;
12657   u32 sw_if_index, priority, weight;
12658   u32 data_len = 0;
12659
12660   /* Parse args required to build the message */
12661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12662     {
12663       if (unformat (input, "del"))
12664         {
12665           is_add = 0;
12666         }
12667       else if (unformat (input, "locator-set %s", &locator_set_name))
12668         {
12669           locator_set_name_set = 1;
12670         }
12671       else if (unformat (input, "sw_if_index %u p %u w %u",
12672                          &sw_if_index, &priority, &weight))
12673         {
12674           locator.sw_if_index = htonl (sw_if_index);
12675           locator.priority = priority;
12676           locator.weight = weight;
12677           vec_add1 (locators, locator);
12678         }
12679       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12680                          vam, &sw_if_index, &priority, &weight))
12681         {
12682           locator.sw_if_index = htonl (sw_if_index);
12683           locator.priority = priority;
12684           locator.weight = weight;
12685           vec_add1 (locators, locator);
12686         }
12687       else
12688         break;
12689     }
12690
12691   if (locator_set_name_set == 0)
12692     {
12693       errmsg ("missing locator-set name");
12694       vec_free (locators);
12695       return -99;
12696     }
12697
12698   if (vec_len (locator_set_name) > 64)
12699     {
12700       errmsg ("locator-set name too long\n");
12701       vec_free (locator_set_name);
12702       vec_free (locators);
12703       return -99;
12704     }
12705   vec_add1 (locator_set_name, 0);
12706
12707   data_len = sizeof (ls_locator_t) * vec_len (locators);
12708
12709   /* Construct the API message */
12710   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12711
12712   mp->is_add = is_add;
12713   clib_memcpy (mp->locator_set_name, locator_set_name,
12714                vec_len (locator_set_name));
12715   vec_free (locator_set_name);
12716
12717   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12718   if (locators)
12719     clib_memcpy (mp->locators, locators, data_len);
12720   vec_free (locators);
12721
12722   /* send it... */
12723   S;
12724
12725   /* Wait for a reply... */
12726   W;
12727
12728   /* NOTREACHED */
12729   return 0;
12730 }
12731
12732 static int
12733 api_lisp_add_del_locator (vat_main_t * vam)
12734 {
12735   unformat_input_t *input = vam->input;
12736   vl_api_lisp_add_del_locator_t *mp;
12737   f64 timeout = ~0;
12738   u32 tmp_if_index = ~0;
12739   u32 sw_if_index = ~0;
12740   u8 sw_if_index_set = 0;
12741   u8 sw_if_index_if_name_set = 0;
12742   u32 priority = ~0;
12743   u8 priority_set = 0;
12744   u32 weight = ~0;
12745   u8 weight_set = 0;
12746   u8 is_add = 1;
12747   u8 *locator_set_name = NULL;
12748   u8 locator_set_name_set = 0;
12749
12750   /* Parse args required to build the message */
12751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12752     {
12753       if (unformat (input, "del"))
12754         {
12755           is_add = 0;
12756         }
12757       else if (unformat (input, "locator-set %s", &locator_set_name))
12758         {
12759           locator_set_name_set = 1;
12760         }
12761       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12762                          &tmp_if_index))
12763         {
12764           sw_if_index_if_name_set = 1;
12765           sw_if_index = tmp_if_index;
12766         }
12767       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12768         {
12769           sw_if_index_set = 1;
12770           sw_if_index = tmp_if_index;
12771         }
12772       else if (unformat (input, "p %d", &priority))
12773         {
12774           priority_set = 1;
12775         }
12776       else if (unformat (input, "w %d", &weight))
12777         {
12778           weight_set = 1;
12779         }
12780       else
12781         break;
12782     }
12783
12784   if (locator_set_name_set == 0)
12785     {
12786       errmsg ("missing locator-set name");
12787       return -99;
12788     }
12789
12790   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12791     {
12792       errmsg ("missing sw_if_index");
12793       vec_free (locator_set_name);
12794       return -99;
12795     }
12796
12797   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12798     {
12799       errmsg ("cannot use both params interface name and sw_if_index");
12800       vec_free (locator_set_name);
12801       return -99;
12802     }
12803
12804   if (priority_set == 0)
12805     {
12806       errmsg ("missing locator-set priority\n");
12807       vec_free (locator_set_name);
12808       return -99;
12809     }
12810
12811   if (weight_set == 0)
12812     {
12813       errmsg ("missing locator-set weight\n");
12814       vec_free (locator_set_name);
12815       return -99;
12816     }
12817
12818   if (vec_len (locator_set_name) > 64)
12819     {
12820       errmsg ("locator-set name too long\n");
12821       vec_free (locator_set_name);
12822       return -99;
12823     }
12824   vec_add1 (locator_set_name, 0);
12825
12826   /* Construct the API message */
12827   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12828
12829   mp->is_add = is_add;
12830   mp->sw_if_index = ntohl (sw_if_index);
12831   mp->priority = priority;
12832   mp->weight = weight;
12833   clib_memcpy (mp->locator_set_name, locator_set_name,
12834                vec_len (locator_set_name));
12835   vec_free (locator_set_name);
12836
12837   /* send it... */
12838   S;
12839
12840   /* Wait for a reply... */
12841   W;
12842
12843   /* NOTREACHED */
12844   return 0;
12845 }
12846
12847 static int
12848 api_lisp_add_del_local_eid (vat_main_t * vam)
12849 {
12850   unformat_input_t *input = vam->input;
12851   vl_api_lisp_add_del_local_eid_t *mp;
12852   f64 timeout = ~0;
12853   u8 is_add = 1;
12854   u8 eid_set = 0;
12855   lisp_eid_vat_t _eid, *eid = &_eid;
12856   u8 *locator_set_name = 0;
12857   u8 locator_set_name_set = 0;
12858   u32 vni = 0;
12859
12860   /* Parse args required to build the message */
12861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12862     {
12863       if (unformat (input, "del"))
12864         {
12865           is_add = 0;
12866         }
12867       else if (unformat (input, "vni %d", &vni))
12868         {
12869           ;
12870         }
12871       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12872         {
12873           eid_set = 1;
12874         }
12875       else if (unformat (input, "locator-set %s", &locator_set_name))
12876         {
12877           locator_set_name_set = 1;
12878         }
12879       else
12880         break;
12881     }
12882
12883   if (locator_set_name_set == 0)
12884     {
12885       errmsg ("missing locator-set name\n");
12886       return -99;
12887     }
12888
12889   if (0 == eid_set)
12890     {
12891       errmsg ("EID address not set!");
12892       vec_free (locator_set_name);
12893       return -99;
12894     }
12895
12896   if (vec_len (locator_set_name) > 64)
12897     {
12898       errmsg ("locator-set name too long\n");
12899       vec_free (locator_set_name);
12900       return -99;
12901     }
12902   vec_add1 (locator_set_name, 0);
12903
12904   /* Construct the API message */
12905   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12906
12907   mp->is_add = is_add;
12908   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12909   mp->eid_type = eid->type;
12910   mp->prefix_len = eid->len;
12911   mp->vni = clib_host_to_net_u32 (vni);
12912   clib_memcpy (mp->locator_set_name, locator_set_name,
12913                vec_len (locator_set_name));
12914
12915   vec_free (locator_set_name);
12916
12917   /* send it... */
12918   S;
12919
12920   /* Wait for a reply... */
12921   W;
12922
12923   /* NOTREACHED */
12924   return 0;
12925 }
12926
12927 /* *INDENT-OFF* */
12928 /** Used for transferring locators via VPP API */
12929 typedef CLIB_PACKED(struct
12930 {
12931   u8 is_ip4; /**< is locator an IPv4 address? */
12932   u8 priority; /**< locator priority */
12933   u8 weight;   /**< locator weight */
12934   u8 addr[16]; /**< IPv4/IPv6 address */
12935 }) rloc_t;
12936 /* *INDENT-ON* */
12937
12938 static int
12939 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12940 {
12941   unformat_input_t *input = vam->input;
12942   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12943   f64 timeout = ~0;
12944   u8 is_add = 1;
12945   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12946   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12947   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12948   u32 action = ~0, p, w;
12949   ip4_address_t rmt_rloc4, lcl_rloc4;
12950   ip6_address_t rmt_rloc6, lcl_rloc6;
12951   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12952
12953   memset (&rloc, 0, sizeof (rloc));
12954
12955   /* Parse args required to build the message */
12956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12957     {
12958       if (unformat (input, "del"))
12959         {
12960           is_add = 0;
12961         }
12962       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12963         {
12964           rmt_eid_set = 1;
12965         }
12966       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12967         {
12968           lcl_eid_set = 1;
12969         }
12970       else if (unformat (input, "p %d w %d", &p, &w))
12971         {
12972           if (!curr_rloc)
12973             {
12974               errmsg ("No RLOC configured for setting priority/weight!");
12975               return -99;
12976             }
12977           curr_rloc->priority = p;
12978           curr_rloc->weight = w;
12979         }
12980       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12981                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12982         {
12983           rloc.is_ip4 = 1;
12984
12985           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12986           rloc.priority = rloc.weight = 0;
12987           vec_add1 (lcl_locs, rloc);
12988
12989           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12990           vec_add1 (rmt_locs, rloc);
12991           /* priority and weight saved in rmt loc */
12992           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12993         }
12994       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12995                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12996         {
12997           rloc.is_ip4 = 0;
12998           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12999           rloc.priority = rloc.weight = 0;
13000           vec_add1 (lcl_locs, rloc);
13001
13002           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13003           vec_add1 (rmt_locs, rloc);
13004           /* priority and weight saved in rmt loc */
13005           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13006         }
13007       else if (unformat (input, "action %d", &action))
13008         {
13009           ;
13010         }
13011       else
13012         {
13013           clib_warning ("parse error '%U'", format_unformat_error, input);
13014           return -99;
13015         }
13016     }
13017
13018   if (!rmt_eid_set)
13019     {
13020       errmsg ("remote eid addresses not set\n");
13021       return -99;
13022     }
13023
13024   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13025     {
13026       errmsg ("eid types don't match\n");
13027       return -99;
13028     }
13029
13030   if (0 == rmt_locs && (u32) ~ 0 == action)
13031     {
13032       errmsg ("action not set for negative mapping\n");
13033       return -99;
13034     }
13035
13036   /* Construct the API message */
13037   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13038
13039   mp->is_add = is_add;
13040   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13041   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13042   mp->eid_type = rmt_eid->type;
13043   mp->rmt_len = rmt_eid->len;
13044   mp->lcl_len = lcl_eid->len;
13045   mp->action = action;
13046
13047   if (0 != rmt_locs && 0 != lcl_locs)
13048     {
13049       mp->loc_num = vec_len (rmt_locs);
13050       clib_memcpy (mp->lcl_locs, lcl_locs,
13051                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13052       clib_memcpy (mp->rmt_locs, rmt_locs,
13053                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13054     }
13055   vec_free (lcl_locs);
13056   vec_free (rmt_locs);
13057
13058   /* send it... */
13059   S;
13060
13061   /* Wait for a reply... */
13062   W;
13063
13064   /* NOTREACHED */
13065   return 0;
13066 }
13067
13068 static int
13069 api_lisp_add_del_map_resolver (vat_main_t * vam)
13070 {
13071   unformat_input_t *input = vam->input;
13072   vl_api_lisp_add_del_map_resolver_t *mp;
13073   f64 timeout = ~0;
13074   u8 is_add = 1;
13075   u8 ipv4_set = 0;
13076   u8 ipv6_set = 0;
13077   ip4_address_t ipv4;
13078   ip6_address_t ipv6;
13079
13080   /* Parse args required to build the message */
13081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13082     {
13083       if (unformat (input, "del"))
13084         {
13085           is_add = 0;
13086         }
13087       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13088         {
13089           ipv4_set = 1;
13090         }
13091       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13092         {
13093           ipv6_set = 1;
13094         }
13095       else
13096         break;
13097     }
13098
13099   if (ipv4_set && ipv6_set)
13100     {
13101       errmsg ("both eid v4 and v6 addresses set\n");
13102       return -99;
13103     }
13104
13105   if (!ipv4_set && !ipv6_set)
13106     {
13107       errmsg ("eid addresses not set\n");
13108       return -99;
13109     }
13110
13111   /* Construct the API message */
13112   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13113
13114   mp->is_add = is_add;
13115   if (ipv6_set)
13116     {
13117       mp->is_ipv6 = 1;
13118       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13119     }
13120   else
13121     {
13122       mp->is_ipv6 = 0;
13123       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13124     }
13125
13126   /* send it... */
13127   S;
13128
13129   /* Wait for a reply... */
13130   W;
13131
13132   /* NOTREACHED */
13133   return 0;
13134 }
13135
13136 static int
13137 api_lisp_gpe_enable_disable (vat_main_t * vam)
13138 {
13139   unformat_input_t *input = vam->input;
13140   vl_api_lisp_gpe_enable_disable_t *mp;
13141   f64 timeout = ~0;
13142   u8 is_set = 0;
13143   u8 is_en = 1;
13144
13145   /* Parse args required to build the message */
13146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13147     {
13148       if (unformat (input, "enable"))
13149         {
13150           is_set = 1;
13151           is_en = 1;
13152         }
13153       else if (unformat (input, "disable"))
13154         {
13155           is_set = 1;
13156           is_en = 0;
13157         }
13158       else
13159         break;
13160     }
13161
13162   if (is_set == 0)
13163     {
13164       errmsg ("Value not set\n");
13165       return -99;
13166     }
13167
13168   /* Construct the API message */
13169   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13170
13171   mp->is_en = is_en;
13172
13173   /* send it... */
13174   S;
13175
13176   /* Wait for a reply... */
13177   W;
13178
13179   /* NOTREACHED */
13180   return 0;
13181 }
13182
13183 static int
13184 api_lisp_enable_disable (vat_main_t * vam)
13185 {
13186   unformat_input_t *input = vam->input;
13187   vl_api_lisp_enable_disable_t *mp;
13188   f64 timeout = ~0;
13189   u8 is_set = 0;
13190   u8 is_en = 0;
13191
13192   /* Parse args required to build the message */
13193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13194     {
13195       if (unformat (input, "enable"))
13196         {
13197           is_set = 1;
13198           is_en = 1;
13199         }
13200       else if (unformat (input, "disable"))
13201         {
13202           is_set = 1;
13203         }
13204       else
13205         break;
13206     }
13207
13208   if (!is_set)
13209     {
13210       errmsg ("Value not set\n");
13211       return -99;
13212     }
13213
13214   /* Construct the API message */
13215   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13216
13217   mp->is_en = is_en;
13218
13219   /* send it... */
13220   S;
13221
13222   /* Wait for a reply... */
13223   W;
13224
13225   /* NOTREACHED */
13226   return 0;
13227 }
13228
13229 static int
13230 api_show_lisp_map_request_mode (vat_main_t * vam)
13231 {
13232   f64 timeout = ~0;
13233   vl_api_show_lisp_map_request_mode_t *mp;
13234
13235   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13236
13237   /* send */
13238   S;
13239
13240   /* wait for reply */
13241   W;
13242
13243   return 0;
13244 }
13245
13246 static int
13247 api_lisp_map_request_mode (vat_main_t * vam)
13248 {
13249   f64 timeout = ~0;
13250   unformat_input_t *input = vam->input;
13251   vl_api_lisp_map_request_mode_t *mp;
13252   u8 mode = 0;
13253
13254   /* Parse args required to build the message */
13255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13256     {
13257       if (unformat (input, "dst-only"))
13258         mode = 0;
13259       else if (unformat (input, "src-dst"))
13260         mode = 1;
13261       else
13262         {
13263           errmsg ("parse error '%U'", format_unformat_error, input);
13264           return -99;
13265         }
13266     }
13267
13268   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13269
13270   mp->mode = mode;
13271
13272   /* send */
13273   S;
13274
13275   /* wait for reply */
13276   W;
13277
13278   /* notreached */
13279   return 0;
13280 }
13281
13282 /**
13283  * Enable/disable LISP proxy ITR.
13284  *
13285  * @param vam vpp API test context
13286  * @return return code
13287  */
13288 static int
13289 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13290 {
13291   f64 timeout = ~0;
13292   u8 ls_name_set = 0;
13293   unformat_input_t *input = vam->input;
13294   vl_api_lisp_pitr_set_locator_set_t *mp;
13295   u8 is_add = 1;
13296   u8 *ls_name = 0;
13297
13298   /* Parse args required to build the message */
13299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13300     {
13301       if (unformat (input, "del"))
13302         is_add = 0;
13303       else if (unformat (input, "locator-set %s", &ls_name))
13304         ls_name_set = 1;
13305       else
13306         {
13307           errmsg ("parse error '%U'", format_unformat_error, input);
13308           return -99;
13309         }
13310     }
13311
13312   if (!ls_name_set)
13313     {
13314       errmsg ("locator-set name not set!");
13315       return -99;
13316     }
13317
13318   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13319
13320   mp->is_add = is_add;
13321   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13322   vec_free (ls_name);
13323
13324   /* send */
13325   S;
13326
13327   /* wait for reply */
13328   W;
13329
13330   /* notreached */
13331   return 0;
13332 }
13333
13334 static int
13335 api_show_lisp_pitr (vat_main_t * vam)
13336 {
13337   vl_api_show_lisp_pitr_t *mp;
13338   f64 timeout = ~0;
13339
13340   if (!vam->json_output)
13341     {
13342       fformat (vam->ofp, "%=20s\n", "lisp status:");
13343     }
13344
13345   M (SHOW_LISP_PITR, show_lisp_pitr);
13346   /* send it... */
13347   S;
13348
13349   /* Wait for a reply... */
13350   W;
13351
13352   /* NOTREACHED */
13353   return 0;
13354 }
13355
13356 /**
13357  * Add/delete mapping between vni and vrf
13358  */
13359 static int
13360 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13361 {
13362   f64 timeout = ~0;
13363   unformat_input_t *input = vam->input;
13364   vl_api_lisp_eid_table_add_del_map_t *mp;
13365   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13366   u32 vni, vrf, bd_index;
13367
13368   /* Parse args required to build the message */
13369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (input, "del"))
13372         is_add = 0;
13373       else if (unformat (input, "vrf %d", &vrf))
13374         vrf_set = 1;
13375       else if (unformat (input, "bd_index %d", &bd_index))
13376         bd_index_set = 1;
13377       else if (unformat (input, "vni %d", &vni))
13378         vni_set = 1;
13379       else
13380         break;
13381     }
13382
13383   if (!vni_set || (!vrf_set && !bd_index_set))
13384     {
13385       errmsg ("missing arguments!");
13386       return -99;
13387     }
13388
13389   if (vrf_set && bd_index_set)
13390     {
13391       errmsg ("error: both vrf and bd entered!");
13392       return -99;
13393     }
13394
13395   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13396
13397   mp->is_add = is_add;
13398   mp->vni = htonl (vni);
13399   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13400   mp->is_l2 = bd_index_set;
13401
13402   /* send */
13403   S;
13404
13405   /* wait for reply */
13406   W;
13407
13408   /* notreached */
13409   return 0;
13410 }
13411
13412 uword
13413 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13414 {
13415   u32 *action = va_arg (*args, u32 *);
13416   u8 *s = 0;
13417
13418   if (unformat (input, "%s", &s))
13419     {
13420       if (!strcmp ((char *) s, "no-action"))
13421         action[0] = 0;
13422       else if (!strcmp ((char *) s, "natively-forward"))
13423         action[0] = 1;
13424       else if (!strcmp ((char *) s, "send-map-request"))
13425         action[0] = 2;
13426       else if (!strcmp ((char *) s, "drop"))
13427         action[0] = 3;
13428       else
13429         {
13430           clib_warning ("invalid action: '%s'", s);
13431           action[0] = 3;
13432         }
13433     }
13434   else
13435     return 0;
13436
13437   vec_free (s);
13438   return 1;
13439 }
13440
13441 /**
13442  * Add/del remote mapping to/from LISP control plane
13443  *
13444  * @param vam vpp API test context
13445  * @return return code
13446  */
13447 static int
13448 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13449 {
13450   unformat_input_t *input = vam->input;
13451   vl_api_lisp_add_del_remote_mapping_t *mp;
13452   f64 timeout = ~0;
13453   u32 vni = 0;
13454   lisp_eid_vat_t _eid, *eid = &_eid;
13455   lisp_eid_vat_t _seid, *seid = &_seid;
13456   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13457   u32 action = ~0, p, w, data_len;
13458   ip4_address_t rloc4;
13459   ip6_address_t rloc6;
13460   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13461
13462   memset (&rloc, 0, sizeof (rloc));
13463
13464   /* Parse args required to build the message */
13465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13466     {
13467       if (unformat (input, "del-all"))
13468         {
13469           del_all = 1;
13470         }
13471       else if (unformat (input, "del"))
13472         {
13473           is_add = 0;
13474         }
13475       else if (unformat (input, "add"))
13476         {
13477           is_add = 1;
13478         }
13479       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13480         {
13481           eid_set = 1;
13482         }
13483       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13484         {
13485           seid_set = 1;
13486         }
13487       else if (unformat (input, "vni %d", &vni))
13488         {
13489           ;
13490         }
13491       else if (unformat (input, "p %d w %d", &p, &w))
13492         {
13493           if (!curr_rloc)
13494             {
13495               errmsg ("No RLOC configured for setting priority/weight!");
13496               return -99;
13497             }
13498           curr_rloc->priority = p;
13499           curr_rloc->weight = w;
13500         }
13501       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13502         {
13503           rloc.is_ip4 = 1;
13504           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13505           vec_add1 (rlocs, rloc);
13506           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13507         }
13508       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13509         {
13510           rloc.is_ip4 = 0;
13511           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13512           vec_add1 (rlocs, rloc);
13513           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13514         }
13515       else if (unformat (input, "action %U",
13516                          unformat_negative_mapping_action, &action))
13517         {
13518           ;
13519         }
13520       else
13521         {
13522           clib_warning ("parse error '%U'", format_unformat_error, input);
13523           return -99;
13524         }
13525     }
13526
13527   if (0 == eid_set)
13528     {
13529       errmsg ("missing params!");
13530       return -99;
13531     }
13532
13533   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13534     {
13535       errmsg ("no action set for negative map-reply!");
13536       return -99;
13537     }
13538
13539   data_len = vec_len (rlocs) * sizeof (rloc_t);
13540
13541   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13542   mp->is_add = is_add;
13543   mp->vni = htonl (vni);
13544   mp->action = (u8) action;
13545   mp->is_src_dst = seid_set;
13546   mp->eid_len = eid->len;
13547   mp->seid_len = seid->len;
13548   mp->del_all = del_all;
13549   mp->eid_type = eid->type;
13550   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13551   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13552
13553   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13554   clib_memcpy (mp->rlocs, rlocs, data_len);
13555   vec_free (rlocs);
13556
13557   /* send it... */
13558   S;
13559
13560   /* Wait for a reply... */
13561   W;
13562
13563   /* NOTREACHED */
13564   return 0;
13565 }
13566
13567 /**
13568  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13569  * forwarding entries in data-plane accordingly.
13570  *
13571  * @param vam vpp API test context
13572  * @return return code
13573  */
13574 static int
13575 api_lisp_add_del_adjacency (vat_main_t * vam)
13576 {
13577   unformat_input_t *input = vam->input;
13578   vl_api_lisp_add_del_adjacency_t *mp;
13579   f64 timeout = ~0;
13580   u32 vni = 0;
13581   ip4_address_t leid4, reid4;
13582   ip6_address_t leid6, reid6;
13583   u8 reid_mac[6] = { 0 };
13584   u8 leid_mac[6] = { 0 };
13585   u8 reid_type, leid_type;
13586   u32 leid_len = 0, reid_len = 0, len;
13587   u8 is_add = 1;
13588
13589   leid_type = reid_type = (u8) ~ 0;
13590
13591   /* Parse args required to build the message */
13592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13593     {
13594       if (unformat (input, "del"))
13595         {
13596           is_add = 0;
13597         }
13598       else if (unformat (input, "add"))
13599         {
13600           is_add = 1;
13601         }
13602       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13603                          &reid4, &len))
13604         {
13605           reid_type = 0;        /* ipv4 */
13606           reid_len = len;
13607         }
13608       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13609                          &reid6, &len))
13610         {
13611           reid_type = 1;        /* ipv6 */
13612           reid_len = len;
13613         }
13614       else if (unformat (input, "reid %U", unformat_ethernet_address,
13615                          reid_mac))
13616         {
13617           reid_type = 2;        /* mac */
13618         }
13619       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13620                          &leid4, &len))
13621         {
13622           leid_type = 0;        /* ipv4 */
13623           leid_len = len;
13624         }
13625       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13626                          &leid6, &len))
13627         {
13628           leid_type = 1;        /* ipv6 */
13629           leid_len = len;
13630         }
13631       else if (unformat (input, "leid %U", unformat_ethernet_address,
13632                          leid_mac))
13633         {
13634           leid_type = 2;        /* mac */
13635         }
13636       else if (unformat (input, "vni %d", &vni))
13637         {
13638           ;
13639         }
13640       else
13641         {
13642           errmsg ("parse error '%U'", format_unformat_error, input);
13643           return -99;
13644         }
13645     }
13646
13647   if ((u8) ~ 0 == reid_type)
13648     {
13649       errmsg ("missing params!");
13650       return -99;
13651     }
13652
13653   if (leid_type != reid_type)
13654     {
13655       errmsg ("remote and local EIDs are of different types!");
13656       return -99;
13657     }
13658
13659   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13660   mp->is_add = is_add;
13661   mp->vni = htonl (vni);
13662   mp->leid_len = leid_len;
13663   mp->reid_len = reid_len;
13664   mp->eid_type = reid_type;
13665
13666   switch (mp->eid_type)
13667     {
13668     case 0:
13669       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13670       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13671       break;
13672     case 1:
13673       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13674       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13675       break;
13676     case 2:
13677       clib_memcpy (mp->leid, leid_mac, 6);
13678       clib_memcpy (mp->reid, reid_mac, 6);
13679       break;
13680     default:
13681       errmsg ("unknown EID type %d!", mp->eid_type);
13682       return 0;
13683     }
13684
13685   /* send it... */
13686   S;
13687
13688   /* Wait for a reply... */
13689   W;
13690
13691   /* NOTREACHED */
13692   return 0;
13693 }
13694
13695 static int
13696 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13697 {
13698   unformat_input_t *input = vam->input;
13699   vl_api_lisp_gpe_add_del_iface_t *mp;
13700   f64 timeout = ~0;
13701   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13702   u32 dp_table = 0, vni = 0;
13703
13704   /* Parse args required to build the message */
13705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13706     {
13707       if (unformat (input, "up"))
13708         {
13709           action_set = 1;
13710           is_add = 1;
13711         }
13712       else if (unformat (input, "down"))
13713         {
13714           action_set = 1;
13715           is_add = 0;
13716         }
13717       else if (unformat (input, "table_id %d", &dp_table))
13718         {
13719           dp_table_set = 1;
13720         }
13721       else if (unformat (input, "bd_id %d", &dp_table))
13722         {
13723           dp_table_set = 1;
13724           is_l2 = 1;
13725         }
13726       else if (unformat (input, "vni %d", &vni))
13727         {
13728           vni_set = 1;
13729         }
13730       else
13731         break;
13732     }
13733
13734   if (action_set == 0)
13735     {
13736       errmsg ("Action not set\n");
13737       return -99;
13738     }
13739   if (dp_table_set == 0 || vni_set == 0)
13740     {
13741       errmsg ("vni and dp_table must be set\n");
13742       return -99;
13743     }
13744
13745   /* Construct the API message */
13746   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13747
13748   mp->is_add = is_add;
13749   mp->dp_table = dp_table;
13750   mp->is_l2 = is_l2;
13751   mp->vni = vni;
13752
13753   /* send it... */
13754   S;
13755
13756   /* Wait for a reply... */
13757   W;
13758
13759   /* NOTREACHED */
13760   return 0;
13761 }
13762
13763 /**
13764  * Add/del map request itr rlocs from LISP control plane and updates
13765  *
13766  * @param vam vpp API test context
13767  * @return return code
13768  */
13769 static int
13770 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13771 {
13772   unformat_input_t *input = vam->input;
13773   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13774   f64 timeout = ~0;
13775   u8 *locator_set_name = 0;
13776   u8 locator_set_name_set = 0;
13777   u8 is_add = 1;
13778
13779   /* Parse args required to build the message */
13780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13781     {
13782       if (unformat (input, "del"))
13783         {
13784           is_add = 0;
13785         }
13786       else if (unformat (input, "%_%v%_", &locator_set_name))
13787         {
13788           locator_set_name_set = 1;
13789         }
13790       else
13791         {
13792           clib_warning ("parse error '%U'", format_unformat_error, input);
13793           return -99;
13794         }
13795     }
13796
13797   if (is_add && !locator_set_name_set)
13798     {
13799       errmsg ("itr-rloc is not set!");
13800       return -99;
13801     }
13802
13803   if (is_add && vec_len (locator_set_name) > 64)
13804     {
13805       errmsg ("itr-rloc locator-set name too long\n");
13806       vec_free (locator_set_name);
13807       return -99;
13808     }
13809
13810   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13811   mp->is_add = is_add;
13812   if (is_add)
13813     {
13814       clib_memcpy (mp->locator_set_name, locator_set_name,
13815                    vec_len (locator_set_name));
13816     }
13817   else
13818     {
13819       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13820     }
13821   vec_free (locator_set_name);
13822
13823   /* send it... */
13824   S;
13825
13826   /* Wait for a reply... */
13827   W;
13828
13829   /* NOTREACHED */
13830   return 0;
13831 }
13832
13833 static int
13834 api_lisp_locator_dump (vat_main_t * vam)
13835 {
13836   unformat_input_t *input = vam->input;
13837   vl_api_lisp_locator_dump_t *mp;
13838   f64 timeout = ~0;
13839   u8 is_index_set = 0, is_name_set = 0;
13840   u8 *ls_name = 0;
13841   u32 ls_index = ~0;
13842
13843   /* Parse args required to build the message */
13844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (input, "ls_name %_%v%_", &ls_name))
13847         {
13848           is_name_set = 1;
13849         }
13850       else if (unformat (input, "ls_index %d", &ls_index))
13851         {
13852           is_index_set = 1;
13853         }
13854       else
13855         {
13856           errmsg ("parse error '%U'", format_unformat_error, input);
13857           return -99;
13858         }
13859     }
13860
13861   if (!is_index_set && !is_name_set)
13862     {
13863       errmsg ("error: expected one of index or name!\n");
13864       return -99;
13865     }
13866
13867   if (is_index_set && is_name_set)
13868     {
13869       errmsg ("error: only one param expected!\n");
13870       return -99;
13871     }
13872
13873   if (vec_len (ls_name) > 62)
13874     {
13875       errmsg ("error: locator set name too long!");
13876       return -99;
13877     }
13878
13879   if (!vam->json_output)
13880     {
13881       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13882                "weight");
13883     }
13884
13885   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13886   mp->is_index_set = is_index_set;
13887
13888   if (is_index_set)
13889     mp->ls_index = clib_host_to_net_u32 (ls_index);
13890   else
13891     {
13892       vec_add1 (ls_name, 0);
13893       strncpy ((char *) mp->ls_name, (char *) ls_name,
13894                sizeof (mp->ls_name) - 1);
13895     }
13896
13897   /* send it... */
13898   S;
13899
13900   /* Use a control ping for synchronization */
13901   {
13902     vl_api_control_ping_t *mp;
13903     M (CONTROL_PING, control_ping);
13904     S;
13905   }
13906   /* Wait for a reply... */
13907   W;
13908
13909   /* NOTREACHED */
13910   return 0;
13911 }
13912
13913 static int
13914 api_lisp_locator_set_dump (vat_main_t * vam)
13915 {
13916   vl_api_lisp_locator_set_dump_t *mp;
13917   unformat_input_t *input = vam->input;
13918   f64 timeout = ~0;
13919   u8 filter = 0;
13920
13921   /* Parse args required to build the message */
13922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13923     {
13924       if (unformat (input, "local"))
13925         {
13926           filter = 1;
13927         }
13928       else if (unformat (input, "remote"))
13929         {
13930           filter = 2;
13931         }
13932       else
13933         {
13934           errmsg ("parse error '%U'", format_unformat_error, input);
13935           return -99;
13936         }
13937     }
13938
13939   if (!vam->json_output)
13940     {
13941       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13942     }
13943
13944   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13945
13946   mp->filter = filter;
13947
13948   /* send it... */
13949   S;
13950
13951   /* Use a control ping for synchronization */
13952   {
13953     vl_api_control_ping_t *mp;
13954     M (CONTROL_PING, control_ping);
13955     S;
13956   }
13957   /* Wait for a reply... */
13958   W;
13959
13960   /* NOTREACHED */
13961   return 0;
13962 }
13963
13964 static int
13965 api_lisp_eid_table_map_dump (vat_main_t * vam)
13966 {
13967   u8 is_l2 = 0;
13968   u8 mode_set = 0;
13969   unformat_input_t *input = vam->input;
13970   vl_api_lisp_eid_table_map_dump_t *mp;
13971   f64 timeout = ~0;
13972
13973   /* Parse args required to build the message */
13974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13975     {
13976       if (unformat (input, "l2"))
13977         {
13978           is_l2 = 1;
13979           mode_set = 1;
13980         }
13981       else if (unformat (input, "l3"))
13982         {
13983           is_l2 = 0;
13984           mode_set = 1;
13985         }
13986       else
13987         {
13988           errmsg ("parse error '%U'", format_unformat_error, input);
13989           return -99;
13990         }
13991     }
13992
13993   if (!mode_set)
13994     {
13995       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13996       return -99;
13997     }
13998
13999   if (!vam->json_output)
14000     {
14001       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14002     }
14003
14004   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14005   mp->is_l2 = is_l2;
14006
14007   /* send it... */
14008   S;
14009
14010   /* Use a control ping for synchronization */
14011   {
14012     vl_api_control_ping_t *mp;
14013     M (CONTROL_PING, control_ping);
14014     S;
14015   }
14016   /* Wait for a reply... */
14017   W;
14018
14019   /* NOTREACHED */
14020   return 0;
14021 }
14022
14023 static int
14024 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14025 {
14026   vl_api_lisp_eid_table_vni_dump_t *mp;
14027   f64 timeout = ~0;
14028
14029   if (!vam->json_output)
14030     {
14031       fformat (vam->ofp, "VNI\n");
14032     }
14033
14034   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14035
14036   /* send it... */
14037   S;
14038
14039   /* Use a control ping for synchronization */
14040   {
14041     vl_api_control_ping_t *mp;
14042     M (CONTROL_PING, control_ping);
14043     S;
14044   }
14045   /* Wait for a reply... */
14046   W;
14047
14048   /* NOTREACHED */
14049   return 0;
14050 }
14051
14052 static int
14053 api_lisp_eid_table_dump (vat_main_t * vam)
14054 {
14055   unformat_input_t *i = vam->input;
14056   vl_api_lisp_eid_table_dump_t *mp;
14057   f64 timeout = ~0;
14058   struct in_addr ip4;
14059   struct in6_addr ip6;
14060   u8 mac[6];
14061   u8 eid_type = ~0, eid_set = 0;
14062   u32 prefix_length = ~0, t, vni = 0;
14063   u8 filter = 0;
14064
14065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14066     {
14067       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14068         {
14069           eid_set = 1;
14070           eid_type = 0;
14071           prefix_length = t;
14072         }
14073       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14074         {
14075           eid_set = 1;
14076           eid_type = 1;
14077           prefix_length = t;
14078         }
14079       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14080         {
14081           eid_set = 1;
14082           eid_type = 2;
14083         }
14084       else if (unformat (i, "vni %d", &t))
14085         {
14086           vni = t;
14087         }
14088       else if (unformat (i, "local"))
14089         {
14090           filter = 1;
14091         }
14092       else if (unformat (i, "remote"))
14093         {
14094           filter = 2;
14095         }
14096       else
14097         {
14098           errmsg ("parse error '%U'", format_unformat_error, i);
14099           return -99;
14100         }
14101     }
14102
14103   if (!vam->json_output)
14104     {
14105       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14106                "ls_index", "ttl", "authoritative");
14107     }
14108
14109   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14110
14111   mp->filter = filter;
14112   if (eid_set)
14113     {
14114       mp->eid_set = 1;
14115       mp->vni = htonl (vni);
14116       mp->eid_type = eid_type;
14117       switch (eid_type)
14118         {
14119         case 0:
14120           mp->prefix_length = prefix_length;
14121           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14122           break;
14123         case 1:
14124           mp->prefix_length = prefix_length;
14125           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14126           break;
14127         case 2:
14128           clib_memcpy (mp->eid, mac, sizeof (mac));
14129           break;
14130         default:
14131           errmsg ("unknown EID type %d!", eid_type);
14132           return -99;
14133         }
14134     }
14135
14136   /* send it... */
14137   S;
14138
14139   /* Use a control ping for synchronization */
14140   {
14141     vl_api_control_ping_t *mp;
14142     M (CONTROL_PING, control_ping);
14143     S;
14144   }
14145
14146   /* Wait for a reply... */
14147   W;
14148
14149   /* NOTREACHED */
14150   return 0;
14151 }
14152
14153 static int
14154 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14155 {
14156   vl_api_lisp_gpe_tunnel_dump_t *mp;
14157   f64 timeout = ~0;
14158
14159   if (!vam->json_output)
14160     {
14161       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14162                "%=16s%=16s%=16s%=16s%=16s\n",
14163                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14164                "Decap next", "Lisp version", "Flags", "Next protocol",
14165                "ver_res", "res", "iid");
14166     }
14167
14168   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14169   /* send it... */
14170   S;
14171
14172   /* Use a control ping for synchronization */
14173   {
14174     vl_api_control_ping_t *mp;
14175     M (CONTROL_PING, control_ping);
14176     S;
14177   }
14178   /* Wait for a reply... */
14179   W;
14180
14181   /* NOTREACHED */
14182   return 0;
14183 }
14184
14185 static int
14186 api_lisp_adjacencies_get (vat_main_t * vam)
14187 {
14188   unformat_input_t *i = vam->input;
14189   vl_api_lisp_adjacencies_get_t *mp;
14190   f64 timeout = ~0;
14191   u8 vni_set = 0;
14192   u32 vni = ~0;
14193
14194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14195     {
14196       if (unformat (i, "vni %d", &vni))
14197         {
14198           vni_set = 1;
14199         }
14200       else
14201         {
14202           errmsg ("parse error '%U'\n", format_unformat_error, i);
14203           return -99;
14204         }
14205     }
14206
14207   if (!vni_set)
14208     {
14209       errmsg ("vni not set!\n");
14210       return -99;
14211     }
14212
14213   if (!vam->json_output)
14214     {
14215       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14216     }
14217
14218   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14219   mp->vni = clib_host_to_net_u32 (vni);
14220
14221   /* send it... */
14222   S;
14223
14224   /* Wait for a reply... */
14225   W;
14226
14227   /* NOTREACHED */
14228   return 0;
14229 }
14230
14231 static int
14232 api_lisp_map_resolver_dump (vat_main_t * vam)
14233 {
14234   vl_api_lisp_map_resolver_dump_t *mp;
14235   f64 timeout = ~0;
14236
14237   if (!vam->json_output)
14238     {
14239       fformat (vam->ofp, "%=20s\n", "Map resolver");
14240     }
14241
14242   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14243   /* send it... */
14244   S;
14245
14246   /* Use a control ping for synchronization */
14247   {
14248     vl_api_control_ping_t *mp;
14249     M (CONTROL_PING, control_ping);
14250     S;
14251   }
14252   /* Wait for a reply... */
14253   W;
14254
14255   /* NOTREACHED */
14256   return 0;
14257 }
14258
14259 static int
14260 api_show_lisp_status (vat_main_t * vam)
14261 {
14262   vl_api_show_lisp_status_t *mp;
14263   f64 timeout = ~0;
14264
14265   if (!vam->json_output)
14266     {
14267       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14268     }
14269
14270   M (SHOW_LISP_STATUS, show_lisp_status);
14271   /* send it... */
14272   S;
14273   /* Wait for a reply... */
14274   W;
14275
14276   /* NOTREACHED */
14277   return 0;
14278 }
14279
14280 static int
14281 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14282 {
14283   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14284   f64 timeout = ~0;
14285
14286   if (!vam->json_output)
14287     {
14288       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14289     }
14290
14291   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14292   /* send it... */
14293   S;
14294   /* Wait for a reply... */
14295   W;
14296
14297   /* NOTREACHED */
14298   return 0;
14299 }
14300
14301 static int
14302 api_af_packet_create (vat_main_t * vam)
14303 {
14304   unformat_input_t *i = vam->input;
14305   vl_api_af_packet_create_t *mp;
14306   f64 timeout;
14307   u8 *host_if_name = 0;
14308   u8 hw_addr[6];
14309   u8 random_hw_addr = 1;
14310
14311   memset (hw_addr, 0, sizeof (hw_addr));
14312
14313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14314     {
14315       if (unformat (i, "name %s", &host_if_name))
14316         vec_add1 (host_if_name, 0);
14317       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14318         random_hw_addr = 0;
14319       else
14320         break;
14321     }
14322
14323   if (!vec_len (host_if_name))
14324     {
14325       errmsg ("host-interface name must be specified");
14326       return -99;
14327     }
14328
14329   if (vec_len (host_if_name) > 64)
14330     {
14331       errmsg ("host-interface name too long");
14332       return -99;
14333     }
14334
14335   M (AF_PACKET_CREATE, af_packet_create);
14336
14337   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14338   clib_memcpy (mp->hw_addr, hw_addr, 6);
14339   mp->use_random_hw_addr = random_hw_addr;
14340   vec_free (host_if_name);
14341
14342   S;
14343   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14344   /* NOTREACHED */
14345   return 0;
14346 }
14347
14348 static int
14349 api_af_packet_delete (vat_main_t * vam)
14350 {
14351   unformat_input_t *i = vam->input;
14352   vl_api_af_packet_delete_t *mp;
14353   f64 timeout;
14354   u8 *host_if_name = 0;
14355
14356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14357     {
14358       if (unformat (i, "name %s", &host_if_name))
14359         vec_add1 (host_if_name, 0);
14360       else
14361         break;
14362     }
14363
14364   if (!vec_len (host_if_name))
14365     {
14366       errmsg ("host-interface name must be specified");
14367       return -99;
14368     }
14369
14370   if (vec_len (host_if_name) > 64)
14371     {
14372       errmsg ("host-interface name too long");
14373       return -99;
14374     }
14375
14376   M (AF_PACKET_DELETE, af_packet_delete);
14377
14378   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14379   vec_free (host_if_name);
14380
14381   S;
14382   W;
14383   /* NOTREACHED */
14384   return 0;
14385 }
14386
14387 static int
14388 api_policer_add_del (vat_main_t * vam)
14389 {
14390   unformat_input_t *i = vam->input;
14391   vl_api_policer_add_del_t *mp;
14392   f64 timeout;
14393   u8 is_add = 1;
14394   u8 *name = 0;
14395   u32 cir = 0;
14396   u32 eir = 0;
14397   u64 cb = 0;
14398   u64 eb = 0;
14399   u8 rate_type = 0;
14400   u8 round_type = 0;
14401   u8 type = 0;
14402   u8 color_aware = 0;
14403   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14404
14405   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14406   conform_action.dscp = 0;
14407   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14408   exceed_action.dscp = 0;
14409   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14410   violate_action.dscp = 0;
14411
14412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (unformat (i, "del"))
14415         is_add = 0;
14416       else if (unformat (i, "name %s", &name))
14417         vec_add1 (name, 0);
14418       else if (unformat (i, "cir %u", &cir))
14419         ;
14420       else if (unformat (i, "eir %u", &eir))
14421         ;
14422       else if (unformat (i, "cb %u", &cb))
14423         ;
14424       else if (unformat (i, "eb %u", &eb))
14425         ;
14426       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14427                          &rate_type))
14428         ;
14429       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14430                          &round_type))
14431         ;
14432       else if (unformat (i, "type %U", unformat_policer_type, &type))
14433         ;
14434       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14435                          &conform_action))
14436         ;
14437       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14438                          &exceed_action))
14439         ;
14440       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14441                          &violate_action))
14442         ;
14443       else if (unformat (i, "color-aware"))
14444         color_aware = 1;
14445       else
14446         break;
14447     }
14448
14449   if (!vec_len (name))
14450     {
14451       errmsg ("policer name must be specified");
14452       return -99;
14453     }
14454
14455   if (vec_len (name) > 64)
14456     {
14457       errmsg ("policer name too long");
14458       return -99;
14459     }
14460
14461   M (POLICER_ADD_DEL, policer_add_del);
14462
14463   clib_memcpy (mp->name, name, vec_len (name));
14464   vec_free (name);
14465   mp->is_add = is_add;
14466   mp->cir = cir;
14467   mp->eir = eir;
14468   mp->cb = cb;
14469   mp->eb = eb;
14470   mp->rate_type = rate_type;
14471   mp->round_type = round_type;
14472   mp->type = type;
14473   mp->conform_action_type = conform_action.action_type;
14474   mp->conform_dscp = conform_action.dscp;
14475   mp->exceed_action_type = exceed_action.action_type;
14476   mp->exceed_dscp = exceed_action.dscp;
14477   mp->violate_action_type = violate_action.action_type;
14478   mp->violate_dscp = violate_action.dscp;
14479   mp->color_aware = color_aware;
14480
14481   S;
14482   W;
14483   /* NOTREACHED */
14484   return 0;
14485 }
14486
14487 static int
14488 api_policer_dump (vat_main_t * vam)
14489 {
14490   unformat_input_t *i = vam->input;
14491   vl_api_policer_dump_t *mp;
14492   f64 timeout = ~0;
14493   u8 *match_name = 0;
14494   u8 match_name_valid = 0;
14495
14496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14497     {
14498       if (unformat (i, "name %s", &match_name))
14499         {
14500           vec_add1 (match_name, 0);
14501           match_name_valid = 1;
14502         }
14503       else
14504         break;
14505     }
14506
14507   M (POLICER_DUMP, policer_dump);
14508   mp->match_name_valid = match_name_valid;
14509   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14510   vec_free (match_name);
14511   /* send it... */
14512   S;
14513
14514   /* Use a control ping for synchronization */
14515   {
14516     vl_api_control_ping_t *mp;
14517     M (CONTROL_PING, control_ping);
14518     S;
14519   }
14520   /* Wait for a reply... */
14521   W;
14522
14523   /* NOTREACHED */
14524   return 0;
14525 }
14526
14527 static int
14528 api_policer_classify_set_interface (vat_main_t * vam)
14529 {
14530   unformat_input_t *i = vam->input;
14531   vl_api_policer_classify_set_interface_t *mp;
14532   f64 timeout;
14533   u32 sw_if_index;
14534   int sw_if_index_set;
14535   u32 ip4_table_index = ~0;
14536   u32 ip6_table_index = ~0;
14537   u32 l2_table_index = ~0;
14538   u8 is_add = 1;
14539
14540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14541     {
14542       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14543         sw_if_index_set = 1;
14544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14545         sw_if_index_set = 1;
14546       else if (unformat (i, "del"))
14547         is_add = 0;
14548       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14549         ;
14550       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14551         ;
14552       else if (unformat (i, "l2-table %d", &l2_table_index))
14553         ;
14554       else
14555         {
14556           clib_warning ("parse error '%U'", format_unformat_error, i);
14557           return -99;
14558         }
14559     }
14560
14561   if (sw_if_index_set == 0)
14562     {
14563       errmsg ("missing interface name or sw_if_index\n");
14564       return -99;
14565     }
14566
14567   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14568
14569   mp->sw_if_index = ntohl (sw_if_index);
14570   mp->ip4_table_index = ntohl (ip4_table_index);
14571   mp->ip6_table_index = ntohl (ip6_table_index);
14572   mp->l2_table_index = ntohl (l2_table_index);
14573   mp->is_add = is_add;
14574
14575   S;
14576   W;
14577   /* NOTREACHED */
14578   return 0;
14579 }
14580
14581 static int
14582 api_policer_classify_dump (vat_main_t * vam)
14583 {
14584   unformat_input_t *i = vam->input;
14585   vl_api_policer_classify_dump_t *mp;
14586   f64 timeout = ~0;
14587   u8 type = POLICER_CLASSIFY_N_TABLES;
14588
14589   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14590     ;
14591   else
14592     {
14593       errmsg ("classify table type must be specified\n");
14594       return -99;
14595     }
14596
14597   if (!vam->json_output)
14598     {
14599       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14600     }
14601
14602   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14603   mp->type = type;
14604   /* send it... */
14605   S;
14606
14607   /* Use a control ping for synchronization */
14608   {
14609     vl_api_control_ping_t *mp;
14610     M (CONTROL_PING, control_ping);
14611     S;
14612   }
14613   /* Wait for a reply... */
14614   W;
14615
14616   /* NOTREACHED */
14617   return 0;
14618 }
14619
14620 static int
14621 api_netmap_create (vat_main_t * vam)
14622 {
14623   unformat_input_t *i = vam->input;
14624   vl_api_netmap_create_t *mp;
14625   f64 timeout;
14626   u8 *if_name = 0;
14627   u8 hw_addr[6];
14628   u8 random_hw_addr = 1;
14629   u8 is_pipe = 0;
14630   u8 is_master = 0;
14631
14632   memset (hw_addr, 0, sizeof (hw_addr));
14633
14634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14635     {
14636       if (unformat (i, "name %s", &if_name))
14637         vec_add1 (if_name, 0);
14638       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14639         random_hw_addr = 0;
14640       else if (unformat (i, "pipe"))
14641         is_pipe = 1;
14642       else if (unformat (i, "master"))
14643         is_master = 1;
14644       else if (unformat (i, "slave"))
14645         is_master = 0;
14646       else
14647         break;
14648     }
14649
14650   if (!vec_len (if_name))
14651     {
14652       errmsg ("interface name must be specified");
14653       return -99;
14654     }
14655
14656   if (vec_len (if_name) > 64)
14657     {
14658       errmsg ("interface name too long");
14659       return -99;
14660     }
14661
14662   M (NETMAP_CREATE, netmap_create);
14663
14664   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14665   clib_memcpy (mp->hw_addr, hw_addr, 6);
14666   mp->use_random_hw_addr = random_hw_addr;
14667   mp->is_pipe = is_pipe;
14668   mp->is_master = is_master;
14669   vec_free (if_name);
14670
14671   S;
14672   W;
14673   /* NOTREACHED */
14674   return 0;
14675 }
14676
14677 static int
14678 api_netmap_delete (vat_main_t * vam)
14679 {
14680   unformat_input_t *i = vam->input;
14681   vl_api_netmap_delete_t *mp;
14682   f64 timeout;
14683   u8 *if_name = 0;
14684
14685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14686     {
14687       if (unformat (i, "name %s", &if_name))
14688         vec_add1 (if_name, 0);
14689       else
14690         break;
14691     }
14692
14693   if (!vec_len (if_name))
14694     {
14695       errmsg ("interface name must be specified");
14696       return -99;
14697     }
14698
14699   if (vec_len (if_name) > 64)
14700     {
14701       errmsg ("interface name too long");
14702       return -99;
14703     }
14704
14705   M (NETMAP_DELETE, netmap_delete);
14706
14707   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14708   vec_free (if_name);
14709
14710   S;
14711   W;
14712   /* NOTREACHED */
14713   return 0;
14714 }
14715
14716 static void vl_api_mpls_eth_tunnel_details_t_handler
14717   (vl_api_mpls_eth_tunnel_details_t * mp)
14718 {
14719   vat_main_t *vam = &vat_main;
14720   i32 i;
14721   i32 len = ntohl (mp->nlabels);
14722
14723   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14724            ntohl (mp->tunnel_index),
14725            format_ethernet_address, &mp->tunnel_dst_mac,
14726            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14727   for (i = 0; i < len; i++)
14728     {
14729       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14730     }
14731   fformat (vam->ofp, "\n");
14732   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14733            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14734 }
14735
14736 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14737   (vl_api_mpls_eth_tunnel_details_t * mp)
14738 {
14739   vat_main_t *vam = &vat_main;
14740   vat_json_node_t *node = NULL;
14741   struct in_addr ip4;
14742   i32 i;
14743   i32 len = ntohl (mp->nlabels);
14744
14745   if (VAT_JSON_ARRAY != vam->json_tree.type)
14746     {
14747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14748       vat_json_init_array (&vam->json_tree);
14749     }
14750   node = vat_json_array_add (&vam->json_tree);
14751
14752   vat_json_init_object (node);
14753   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14754   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14755   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14756   vat_json_object_add_uint (node, "inner_fib_index",
14757                             ntohl (mp->inner_fib_index));
14758   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14759   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14760   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14761   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14762   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14763                                    format (0, "%U", format_ethernet_address,
14764                                            &mp->tunnel_dst_mac));
14765   vat_json_object_add_uint (node, "tx_sw_if_index",
14766                             ntohl (mp->tx_sw_if_index));
14767   vat_json_object_add_uint (node, "label_count", len);
14768   for (i = 0; i < len; i++)
14769     {
14770       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14771     }
14772 }
14773
14774 static int
14775 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14776 {
14777   vl_api_mpls_eth_tunnel_dump_t *mp;
14778   f64 timeout;
14779   i32 index = -1;
14780
14781   /* Parse args required to build the message */
14782   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (!unformat (vam->input, "tunnel_index %d", &index))
14785         {
14786           index = -1;
14787           break;
14788         }
14789     }
14790
14791   fformat (vam->ofp, "  tunnel_index %d\n", index);
14792
14793   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14794   mp->tunnel_index = htonl (index);
14795   S;
14796
14797   /* Use a control ping for synchronization */
14798   {
14799     vl_api_control_ping_t *mp;
14800     M (CONTROL_PING, control_ping);
14801     S;
14802   }
14803   W;
14804 }
14805
14806 static void vl_api_mpls_fib_encap_details_t_handler
14807   (vl_api_mpls_fib_encap_details_t * mp)
14808 {
14809   vat_main_t *vam = &vat_main;
14810   i32 i;
14811   i32 len = ntohl (mp->nlabels);
14812
14813   fformat (vam->ofp, "table %d, dest %U, label ",
14814            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14815   for (i = 0; i < len; i++)
14816     {
14817       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14818     }
14819   fformat (vam->ofp, "\n");
14820 }
14821
14822 static void vl_api_mpls_fib_encap_details_t_handler_json
14823   (vl_api_mpls_fib_encap_details_t * mp)
14824 {
14825   vat_main_t *vam = &vat_main;
14826   vat_json_node_t *node = NULL;
14827   i32 i;
14828   i32 len = ntohl (mp->nlabels);
14829   struct in_addr ip4;
14830
14831   if (VAT_JSON_ARRAY != vam->json_tree.type)
14832     {
14833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14834       vat_json_init_array (&vam->json_tree);
14835     }
14836   node = vat_json_array_add (&vam->json_tree);
14837
14838   vat_json_init_object (node);
14839   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14840   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14841   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14842   vat_json_object_add_ip4 (node, "dest", ip4);
14843   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14844   vat_json_object_add_uint (node, "label_count", len);
14845   for (i = 0; i < len; i++)
14846     {
14847       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14848     }
14849 }
14850
14851 static int
14852 api_mpls_fib_encap_dump (vat_main_t * vam)
14853 {
14854   vl_api_mpls_fib_encap_dump_t *mp;
14855   f64 timeout;
14856
14857   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14858   S;
14859
14860   /* Use a control ping for synchronization */
14861   {
14862     vl_api_control_ping_t *mp;
14863     M (CONTROL_PING, control_ping);
14864     S;
14865   }
14866   W;
14867 }
14868
14869 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14870 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14871
14872 static void
14873 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14874 {
14875   vat_main_t *vam = &vat_main;
14876   int count = ntohl (mp->count);
14877   vl_api_fib_path_t *fp;
14878   int i;
14879
14880   fformat (vam->ofp,
14881            "table-id %d, label %u, ess_bit %u\n",
14882            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14883   fp = mp->path;
14884   for (i = 0; i < count; i++)
14885     {
14886       if (fp->afi == IP46_TYPE_IP6)
14887         fformat (vam->ofp,
14888                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14889                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14890                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14891                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14892                  format_ip6_address, fp->next_hop);
14893       else if (fp->afi == IP46_TYPE_IP4)
14894         fformat (vam->ofp,
14895                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14896                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14897                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14898                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14899                  format_ip4_address, fp->next_hop);
14900       fp++;
14901     }
14902 }
14903
14904 static void vl_api_mpls_fib_details_t_handler_json
14905   (vl_api_mpls_fib_details_t * mp)
14906 {
14907   vat_main_t *vam = &vat_main;
14908   int count = ntohl (mp->count);
14909   vat_json_node_t *node = NULL;
14910   struct in_addr ip4;
14911   struct in6_addr ip6;
14912   vl_api_fib_path_t *fp;
14913   int i;
14914
14915   if (VAT_JSON_ARRAY != vam->json_tree.type)
14916     {
14917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14918       vat_json_init_array (&vam->json_tree);
14919     }
14920   node = vat_json_array_add (&vam->json_tree);
14921
14922   vat_json_init_object (node);
14923   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14924   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14925   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14926   vat_json_object_add_uint (node, "path_count", count);
14927   fp = mp->path;
14928   for (i = 0; i < count; i++)
14929     {
14930       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14931       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14932       vat_json_object_add_uint (node, "is_local", fp->is_local);
14933       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14934       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14935       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14936       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14937       if (fp->afi == IP46_TYPE_IP4)
14938         {
14939           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14940           vat_json_object_add_ip4 (node, "next_hop", ip4);
14941         }
14942       else if (fp->afi == IP46_TYPE_IP6)
14943         {
14944           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14945           vat_json_object_add_ip6 (node, "next_hop", ip6);
14946         }
14947     }
14948 }
14949
14950 static int
14951 api_mpls_fib_dump (vat_main_t * vam)
14952 {
14953   vl_api_mpls_fib_dump_t *mp;
14954   f64 timeout;
14955
14956   M (MPLS_FIB_DUMP, mpls_fib_dump);
14957   S;
14958
14959   /* Use a control ping for synchronization */
14960   {
14961     vl_api_control_ping_t *mp;
14962     M (CONTROL_PING, control_ping);
14963     S;
14964   }
14965   W;
14966 }
14967
14968 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14969 #define vl_api_ip_fib_details_t_print vl_noop_handler
14970
14971 static void
14972 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14973 {
14974   vat_main_t *vam = &vat_main;
14975   int count = ntohl (mp->count);
14976   vl_api_fib_path_t *fp;
14977   int i;
14978
14979   fformat (vam->ofp,
14980            "table-id %d, prefix %U/%d\n",
14981            ntohl (mp->table_id), format_ip4_address, mp->address,
14982            mp->address_length);
14983   fp = mp->path;
14984   for (i = 0; i < count; i++)
14985     {
14986       if (fp->afi == IP46_TYPE_IP6)
14987         fformat (vam->ofp,
14988                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14989                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14990                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14991                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14992                  format_ip6_address, fp->next_hop);
14993       else if (fp->afi == IP46_TYPE_IP4)
14994         fformat (vam->ofp,
14995                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14996                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14997                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14998                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14999                  format_ip4_address, fp->next_hop);
15000       fp++;
15001     }
15002 }
15003
15004 static void vl_api_ip_fib_details_t_handler_json
15005   (vl_api_ip_fib_details_t * mp)
15006 {
15007   vat_main_t *vam = &vat_main;
15008   int count = ntohl (mp->count);
15009   vat_json_node_t *node = NULL;
15010   struct in_addr ip4;
15011   struct in6_addr ip6;
15012   vl_api_fib_path_t *fp;
15013   int i;
15014
15015   if (VAT_JSON_ARRAY != vam->json_tree.type)
15016     {
15017       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15018       vat_json_init_array (&vam->json_tree);
15019     }
15020   node = vat_json_array_add (&vam->json_tree);
15021
15022   vat_json_init_object (node);
15023   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15024   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15025   vat_json_object_add_ip4 (node, "prefix", ip4);
15026   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15027   vat_json_object_add_uint (node, "path_count", count);
15028   fp = mp->path;
15029   for (i = 0; i < count; i++)
15030     {
15031       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15032       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15033       vat_json_object_add_uint (node, "is_local", fp->is_local);
15034       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15035       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15036       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15037       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15038       if (fp->afi == IP46_TYPE_IP4)
15039         {
15040           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15041           vat_json_object_add_ip4 (node, "next_hop", ip4);
15042         }
15043       else if (fp->afi == IP46_TYPE_IP6)
15044         {
15045           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15046           vat_json_object_add_ip6 (node, "next_hop", ip6);
15047         }
15048     }
15049 }
15050
15051 static int
15052 api_ip_fib_dump (vat_main_t * vam)
15053 {
15054   vl_api_ip_fib_dump_t *mp;
15055   f64 timeout;
15056
15057   M (IP_FIB_DUMP, ip_fib_dump);
15058   S;
15059
15060   /* Use a control ping for synchronization */
15061   {
15062     vl_api_control_ping_t *mp;
15063     M (CONTROL_PING, control_ping);
15064     S;
15065   }
15066   W;
15067 }
15068
15069 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15070 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15071
15072 static void
15073 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15074 {
15075   vat_main_t *vam = &vat_main;
15076   int count = ntohl (mp->count);
15077   vl_api_fib_path_t *fp;
15078   int i;
15079
15080   fformat (vam->ofp,
15081            "table-id %d, prefix %U/%d\n",
15082            ntohl (mp->table_id), format_ip6_address, mp->address,
15083            mp->address_length);
15084   fp = mp->path;
15085   for (i = 0; i < count; i++)
15086     {
15087       if (fp->afi == IP46_TYPE_IP6)
15088         fformat (vam->ofp,
15089                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15090                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15091                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15092                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15093                  format_ip6_address, fp->next_hop);
15094       else if (fp->afi == IP46_TYPE_IP4)
15095         fformat (vam->ofp,
15096                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15097                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15098                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15099                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15100                  format_ip4_address, fp->next_hop);
15101       fp++;
15102     }
15103 }
15104
15105 static void vl_api_ip6_fib_details_t_handler_json
15106   (vl_api_ip6_fib_details_t * mp)
15107 {
15108   vat_main_t *vam = &vat_main;
15109   int count = ntohl (mp->count);
15110   vat_json_node_t *node = NULL;
15111   struct in_addr ip4;
15112   struct in6_addr ip6;
15113   vl_api_fib_path_t *fp;
15114   int i;
15115
15116   if (VAT_JSON_ARRAY != vam->json_tree.type)
15117     {
15118       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15119       vat_json_init_array (&vam->json_tree);
15120     }
15121   node = vat_json_array_add (&vam->json_tree);
15122
15123   vat_json_init_object (node);
15124   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15125   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15126   vat_json_object_add_ip6 (node, "prefix", ip6);
15127   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15128   vat_json_object_add_uint (node, "path_count", count);
15129   fp = mp->path;
15130   for (i = 0; i < count; i++)
15131     {
15132       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15133       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15134       vat_json_object_add_uint (node, "is_local", fp->is_local);
15135       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15136       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15137       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15138       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15139       if (fp->afi == IP46_TYPE_IP4)
15140         {
15141           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15142           vat_json_object_add_ip4 (node, "next_hop", ip4);
15143         }
15144       else if (fp->afi == IP46_TYPE_IP6)
15145         {
15146           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15147           vat_json_object_add_ip6 (node, "next_hop", ip6);
15148         }
15149     }
15150 }
15151
15152 static int
15153 api_ip6_fib_dump (vat_main_t * vam)
15154 {
15155   vl_api_ip6_fib_dump_t *mp;
15156   f64 timeout;
15157
15158   M (IP6_FIB_DUMP, ip6_fib_dump);
15159   S;
15160
15161   /* Use a control ping for synchronization */
15162   {
15163     vl_api_control_ping_t *mp;
15164     M (CONTROL_PING, control_ping);
15165     S;
15166   }
15167   W;
15168 }
15169
15170 int
15171 api_classify_table_ids (vat_main_t * vam)
15172 {
15173   vl_api_classify_table_ids_t *mp;
15174   f64 timeout;
15175
15176   /* Construct the API message */
15177   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15178   mp->context = 0;
15179
15180   S;
15181   W;
15182   /* NOTREACHED */
15183   return 0;
15184 }
15185
15186 int
15187 api_classify_table_by_interface (vat_main_t * vam)
15188 {
15189   unformat_input_t *input = vam->input;
15190   vl_api_classify_table_by_interface_t *mp;
15191   f64 timeout;
15192
15193   u32 sw_if_index = ~0;
15194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15195     {
15196       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15197         ;
15198       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15199         ;
15200       else
15201         break;
15202     }
15203   if (sw_if_index == ~0)
15204     {
15205       errmsg ("missing interface name or sw_if_index\n");
15206       return -99;
15207     }
15208
15209   /* Construct the API message */
15210   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15211   mp->context = 0;
15212   mp->sw_if_index = ntohl (sw_if_index);
15213
15214   S;
15215   W;
15216   /* NOTREACHED */
15217   return 0;
15218 }
15219
15220 int
15221 api_classify_table_info (vat_main_t * vam)
15222 {
15223   unformat_input_t *input = vam->input;
15224   vl_api_classify_table_info_t *mp;
15225   f64 timeout;
15226
15227   u32 table_id = ~0;
15228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (input, "table_id %d", &table_id))
15231         ;
15232       else
15233         break;
15234     }
15235   if (table_id == ~0)
15236     {
15237       errmsg ("missing table id\n");
15238       return -99;
15239     }
15240
15241   /* Construct the API message */
15242   M (CLASSIFY_TABLE_INFO, classify_table_info);
15243   mp->context = 0;
15244   mp->table_id = ntohl (table_id);
15245
15246   S;
15247   W;
15248   /* NOTREACHED */
15249   return 0;
15250 }
15251
15252 int
15253 api_classify_session_dump (vat_main_t * vam)
15254 {
15255   unformat_input_t *input = vam->input;
15256   vl_api_classify_session_dump_t *mp;
15257   f64 timeout;
15258
15259   u32 table_id = ~0;
15260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15261     {
15262       if (unformat (input, "table_id %d", &table_id))
15263         ;
15264       else
15265         break;
15266     }
15267   if (table_id == ~0)
15268     {
15269       errmsg ("missing table id\n");
15270       return -99;
15271     }
15272
15273   /* Construct the API message */
15274   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15275   mp->context = 0;
15276   mp->table_id = ntohl (table_id);
15277   S;
15278
15279   /* Use a control ping for synchronization */
15280   {
15281     vl_api_control_ping_t *mp;
15282     M (CONTROL_PING, control_ping);
15283     S;
15284   }
15285   W;
15286   /* NOTREACHED */
15287   return 0;
15288 }
15289
15290 static void
15291 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15292 {
15293   vat_main_t *vam = &vat_main;
15294
15295   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15296            "src_address %U, vrf_id %d, path_mtu %u, "
15297            "template_interval %u, udp_checksum %d\n",
15298            format_ip4_address, mp->collector_address,
15299            ntohs (mp->collector_port),
15300            format_ip4_address, mp->src_address,
15301            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15302            ntohl (mp->template_interval), mp->udp_checksum);
15303
15304   vam->retval = 0;
15305   vam->result_ready = 1;
15306 }
15307
15308 static void
15309   vl_api_ipfix_exporter_details_t_handler_json
15310   (vl_api_ipfix_exporter_details_t * mp)
15311 {
15312   vat_main_t *vam = &vat_main;
15313   vat_json_node_t node;
15314   struct in_addr collector_address;
15315   struct in_addr src_address;
15316
15317   vat_json_init_object (&node);
15318   clib_memcpy (&collector_address, &mp->collector_address,
15319                sizeof (collector_address));
15320   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15321   vat_json_object_add_uint (&node, "collector_port",
15322                             ntohs (mp->collector_port));
15323   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15324   vat_json_object_add_ip4 (&node, "src_address", src_address);
15325   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15326   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15327   vat_json_object_add_uint (&node, "template_interval",
15328                             ntohl (mp->template_interval));
15329   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15330
15331   vat_json_print (vam->ofp, &node);
15332   vat_json_free (&node);
15333   vam->retval = 0;
15334   vam->result_ready = 1;
15335 }
15336
15337 int
15338 api_ipfix_exporter_dump (vat_main_t * vam)
15339 {
15340   vl_api_ipfix_exporter_dump_t *mp;
15341   f64 timeout;
15342
15343   /* Construct the API message */
15344   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15345   mp->context = 0;
15346
15347   S;
15348   W;
15349   /* NOTREACHED */
15350   return 0;
15351 }
15352
15353 static int
15354 api_ipfix_classify_stream_dump (vat_main_t * vam)
15355 {
15356   vl_api_ipfix_classify_stream_dump_t *mp;
15357   f64 timeout;
15358
15359   /* Construct the API message */
15360   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15361   mp->context = 0;
15362
15363   S;
15364   W;
15365   /* NOTREACHED */
15366   return 0;
15367 }
15368
15369 static void
15370   vl_api_ipfix_classify_stream_details_t_handler
15371   (vl_api_ipfix_classify_stream_details_t * mp)
15372 {
15373   vat_main_t *vam = &vat_main;
15374   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15375            ntohl (mp->domain_id), ntohs (mp->src_port));
15376   vam->retval = 0;
15377   vam->result_ready = 1;
15378 }
15379
15380 static void
15381   vl_api_ipfix_classify_stream_details_t_handler_json
15382   (vl_api_ipfix_classify_stream_details_t * mp)
15383 {
15384   vat_main_t *vam = &vat_main;
15385   vat_json_node_t node;
15386
15387   vat_json_init_object (&node);
15388   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15389   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15390
15391   vat_json_print (vam->ofp, &node);
15392   vat_json_free (&node);
15393   vam->retval = 0;
15394   vam->result_ready = 1;
15395 }
15396
15397 static int
15398 api_ipfix_classify_table_dump (vat_main_t * vam)
15399 {
15400   vl_api_ipfix_classify_table_dump_t *mp;
15401   f64 timeout;
15402
15403   if (!vam->json_output)
15404     {
15405       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15406                "transport_protocol");
15407     }
15408
15409   /* Construct the API message */
15410   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15411
15412   /* send it... */
15413   S;
15414
15415   /* Use a control ping for synchronization */
15416   {
15417     vl_api_control_ping_t *mp;
15418     M (CONTROL_PING, control_ping);
15419     S;
15420   }
15421   W;
15422 }
15423
15424 static void
15425   vl_api_ipfix_classify_table_details_t_handler
15426   (vl_api_ipfix_classify_table_details_t * mp)
15427 {
15428   vat_main_t *vam = &vat_main;
15429   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15430            mp->transport_protocol);
15431 }
15432
15433 static void
15434   vl_api_ipfix_classify_table_details_t_handler_json
15435   (vl_api_ipfix_classify_table_details_t * mp)
15436 {
15437   vat_json_node_t *node = NULL;
15438   vat_main_t *vam = &vat_main;
15439
15440   if (VAT_JSON_ARRAY != vam->json_tree.type)
15441     {
15442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15443       vat_json_init_array (&vam->json_tree);
15444     }
15445
15446   node = vat_json_array_add (&vam->json_tree);
15447   vat_json_init_object (node);
15448
15449   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15450   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15451   vat_json_object_add_uint (node, "transport_protocol",
15452                             mp->transport_protocol);
15453 }
15454
15455 static int
15456 api_sw_interface_span_enable_disable (vat_main_t * vam)
15457 {
15458   unformat_input_t *i = vam->input;
15459   vl_api_sw_interface_span_enable_disable_t *mp;
15460   f64 timeout;
15461   u32 src_sw_if_index = ~0;
15462   u32 dst_sw_if_index = ~0;
15463   u8 enable = 1;
15464
15465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15468         ;
15469       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15470         ;
15471       else
15472         if (unformat
15473             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15474         ;
15475       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15476         ;
15477       else if (unformat (i, "disable"))
15478         enable = 0;
15479       else
15480         break;
15481     }
15482
15483   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15484
15485   mp->sw_if_index_from = htonl (src_sw_if_index);
15486   mp->sw_if_index_to = htonl (dst_sw_if_index);
15487   mp->enable = enable;
15488
15489   S;
15490   W;
15491   /* NOTREACHED */
15492   return 0;
15493 }
15494
15495 static void
15496 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15497                                             * mp)
15498 {
15499   vat_main_t *vam = &vat_main;
15500
15501   fformat (vam->ofp, "%u => %u\n",
15502            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15503 }
15504
15505 static void
15506   vl_api_sw_interface_span_details_t_handler_json
15507   (vl_api_sw_interface_span_details_t * mp)
15508 {
15509   vat_main_t *vam = &vat_main;
15510   vat_json_node_t *node = NULL;
15511
15512   if (VAT_JSON_ARRAY != vam->json_tree.type)
15513     {
15514       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15515       vat_json_init_array (&vam->json_tree);
15516     }
15517   node = vat_json_array_add (&vam->json_tree);
15518
15519   vat_json_init_object (node);
15520   vat_json_object_add_uint (node, "src-if-index",
15521                             ntohl (mp->sw_if_index_from));
15522   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15523 }
15524
15525 static int
15526 api_sw_interface_span_dump (vat_main_t * vam)
15527 {
15528   vl_api_sw_interface_span_dump_t *mp;
15529   f64 timeout;
15530
15531   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15532   S;
15533
15534   /* Use a control ping for synchronization */
15535   {
15536     vl_api_control_ping_t *mp;
15537     M (CONTROL_PING, control_ping);
15538     S;
15539   }
15540   W;
15541 }
15542
15543 int
15544 api_pg_create_interface (vat_main_t * vam)
15545 {
15546   unformat_input_t *input = vam->input;
15547   vl_api_pg_create_interface_t *mp;
15548   f64 timeout;
15549
15550   u32 if_id = ~0;
15551   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15552     {
15553       if (unformat (input, "if_id %d", &if_id))
15554         ;
15555       else
15556         break;
15557     }
15558   if (if_id == ~0)
15559     {
15560       errmsg ("missing pg interface index\n");
15561       return -99;
15562     }
15563
15564   /* Construct the API message */
15565   M (PG_CREATE_INTERFACE, pg_create_interface);
15566   mp->context = 0;
15567   mp->interface_id = ntohl (if_id);
15568
15569   S;
15570   W;
15571   /* NOTREACHED */
15572   return 0;
15573 }
15574
15575 int
15576 api_pg_capture (vat_main_t * vam)
15577 {
15578   unformat_input_t *input = vam->input;
15579   vl_api_pg_capture_t *mp;
15580   f64 timeout;
15581
15582   u32 if_id = ~0;
15583   u8 enable = 1;
15584   u32 count = 1;
15585   u8 pcap_file_set = 0;
15586   u8 *pcap_file = 0;
15587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (input, "if_id %d", &if_id))
15590         ;
15591       else if (unformat (input, "pcap %s", &pcap_file))
15592         pcap_file_set = 1;
15593       else if (unformat (input, "count %d", &count))
15594         ;
15595       else if (unformat (input, "disable"))
15596         enable = 0;
15597       else
15598         break;
15599     }
15600   if (if_id == ~0)
15601     {
15602       errmsg ("missing pg interface index\n");
15603       return -99;
15604     }
15605   if (pcap_file_set > 0)
15606     {
15607       if (vec_len (pcap_file) > 255)
15608         {
15609           errmsg ("pcap file name is too long\n");
15610           return -99;
15611         }
15612     }
15613
15614   u32 name_len = vec_len (pcap_file);
15615   /* Construct the API message */
15616   M (PG_CAPTURE, pg_capture);
15617   mp->context = 0;
15618   mp->interface_id = ntohl (if_id);
15619   mp->is_enabled = enable;
15620   mp->count = ntohl (count);
15621   mp->pcap_name_length = ntohl (name_len);
15622   if (pcap_file_set != 0)
15623     {
15624       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15625     }
15626   vec_free (pcap_file);
15627
15628   S;
15629   W;
15630   /* NOTREACHED */
15631   return 0;
15632 }
15633
15634 int
15635 api_pg_enable_disable (vat_main_t * vam)
15636 {
15637   unformat_input_t *input = vam->input;
15638   vl_api_pg_enable_disable_t *mp;
15639   f64 timeout;
15640
15641   u8 enable = 1;
15642   u8 stream_name_set = 0;
15643   u8 *stream_name = 0;
15644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (input, "stream %s", &stream_name))
15647         stream_name_set = 1;
15648       else if (unformat (input, "disable"))
15649         enable = 0;
15650       else
15651         break;
15652     }
15653
15654   if (stream_name_set > 0)
15655     {
15656       if (vec_len (stream_name) > 255)
15657         {
15658           errmsg ("stream name too long\n");
15659           return -99;
15660         }
15661     }
15662
15663   u32 name_len = vec_len (stream_name);
15664   /* Construct the API message */
15665   M (PG_ENABLE_DISABLE, pg_enable_disable);
15666   mp->context = 0;
15667   mp->is_enabled = enable;
15668   if (stream_name_set != 0)
15669     {
15670       mp->stream_name_length = ntohl (name_len);
15671       clib_memcpy (mp->stream_name, stream_name, name_len);
15672     }
15673   vec_free (stream_name);
15674
15675   S;
15676   W;
15677   /* NOTREACHED */
15678   return 0;
15679 }
15680
15681 int
15682 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15683 {
15684   unformat_input_t *input = vam->input;
15685   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15686   f64 timeout;
15687
15688   u16 *low_ports = 0;
15689   u16 *high_ports = 0;
15690   u16 this_low;
15691   u16 this_hi;
15692   ip4_address_t ip4_addr;
15693   ip6_address_t ip6_addr;
15694   u32 length;
15695   u32 tmp, tmp2;
15696   u8 prefix_set = 0;
15697   u32 vrf_id = ~0;
15698   u8 is_add = 1;
15699   u8 is_ipv6 = 0;
15700
15701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15702     {
15703       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15704         {
15705           prefix_set = 1;
15706         }
15707       else
15708         if (unformat
15709             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15710         {
15711           prefix_set = 1;
15712           is_ipv6 = 1;
15713         }
15714       else if (unformat (input, "vrf %d", &vrf_id))
15715         ;
15716       else if (unformat (input, "del"))
15717         is_add = 0;
15718       else if (unformat (input, "port %d", &tmp))
15719         {
15720           if (tmp == 0 || tmp > 65535)
15721             {
15722               errmsg ("port %d out of range", tmp);
15723               return -99;
15724             }
15725           this_low = tmp;
15726           this_hi = this_low + 1;
15727           vec_add1 (low_ports, this_low);
15728           vec_add1 (high_ports, this_hi);
15729         }
15730       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15731         {
15732           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15733             {
15734               errmsg ("incorrect range parameters\n");
15735               return -99;
15736             }
15737           this_low = tmp;
15738           /* Note: in debug CLI +1 is added to high before
15739              passing to real fn that does "the work"
15740              (ip_source_and_port_range_check_add_del).
15741              This fn is a wrapper around the binary API fn a
15742              control plane will call, which expects this increment
15743              to have occurred. Hence letting the binary API control
15744              plane fn do the increment for consistency between VAT
15745              and other control planes.
15746            */
15747           this_hi = tmp2;
15748           vec_add1 (low_ports, this_low);
15749           vec_add1 (high_ports, this_hi);
15750         }
15751       else
15752         break;
15753     }
15754
15755   if (prefix_set == 0)
15756     {
15757       errmsg ("<address>/<mask> not specified\n");
15758       return -99;
15759     }
15760
15761   if (vrf_id == ~0)
15762     {
15763       errmsg ("VRF ID required, not specified\n");
15764       return -99;
15765     }
15766
15767   if (vrf_id == 0)
15768     {
15769       errmsg
15770         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15771       return -99;
15772     }
15773
15774   if (vec_len (low_ports) == 0)
15775     {
15776       errmsg ("At least one port or port range required\n");
15777       return -99;
15778     }
15779
15780   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15781      ip_source_and_port_range_check_add_del);
15782
15783   mp->is_add = is_add;
15784
15785   if (is_ipv6)
15786     {
15787       mp->is_ipv6 = 1;
15788       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15789     }
15790   else
15791     {
15792       mp->is_ipv6 = 0;
15793       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15794     }
15795
15796   mp->mask_length = length;
15797   mp->number_of_ranges = vec_len (low_ports);
15798
15799   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15800   vec_free (low_ports);
15801
15802   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15803   vec_free (high_ports);
15804
15805   mp->vrf_id = ntohl (vrf_id);
15806
15807   S;
15808   W;
15809   /* NOTREACHED */
15810   return 0;
15811 }
15812
15813 int
15814 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15815 {
15816   unformat_input_t *input = vam->input;
15817   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15818   f64 timeout;
15819   u32 sw_if_index = ~0;
15820   int vrf_set = 0;
15821   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15822   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15823   u8 is_add = 1;
15824
15825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15828         ;
15829       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15830         ;
15831       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15832         vrf_set = 1;
15833       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15834         vrf_set = 1;
15835       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15836         vrf_set = 1;
15837       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15838         vrf_set = 1;
15839       else if (unformat (input, "del"))
15840         is_add = 0;
15841       else
15842         break;
15843     }
15844
15845   if (sw_if_index == ~0)
15846     {
15847       errmsg ("Interface required but not specified\n");
15848       return -99;
15849     }
15850
15851   if (vrf_set == 0)
15852     {
15853       errmsg ("VRF ID required but not specified\n");
15854       return -99;
15855     }
15856
15857   if (tcp_out_vrf_id == 0
15858       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15859     {
15860       errmsg
15861         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15862       return -99;
15863     }
15864
15865   /* Construct the API message */
15866   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15867      ip_source_and_port_range_check_interface_add_del);
15868
15869   mp->sw_if_index = ntohl (sw_if_index);
15870   mp->is_add = is_add;
15871   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15872   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15873   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15874   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15875
15876   /* send it... */
15877   S;
15878
15879   /* Wait for a reply... */
15880   W;
15881 }
15882
15883 static int
15884 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15885 {
15886   unformat_input_t *i = vam->input;
15887   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15888   f64 timeout;
15889   u32 local_sa_id = 0;
15890   u32 remote_sa_id = 0;
15891   ip4_address_t src_address;
15892   ip4_address_t dst_address;
15893   u8 is_add = 1;
15894
15895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15896     {
15897       if (unformat (i, "local_sa %d", &local_sa_id))
15898         ;
15899       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15900         ;
15901       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15902         ;
15903       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15904         ;
15905       else if (unformat (i, "del"))
15906         is_add = 0;
15907       else
15908         {
15909           clib_warning ("parse error '%U'", format_unformat_error, i);
15910           return -99;
15911         }
15912     }
15913
15914   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15915
15916   mp->local_sa_id = ntohl (local_sa_id);
15917   mp->remote_sa_id = ntohl (remote_sa_id);
15918   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15919   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15920   mp->is_add = is_add;
15921
15922   S;
15923   W;
15924   /* NOTREACHED */
15925   return 0;
15926 }
15927
15928 static int
15929 api_punt (vat_main_t * vam)
15930 {
15931   unformat_input_t *i = vam->input;
15932   vl_api_punt_t *mp;
15933   f64 timeout;
15934   u32 ipv = ~0;
15935   u32 protocol = ~0;
15936   u32 port = ~0;
15937   int is_add = 1;
15938
15939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15940     {
15941       if (unformat (i, "ip %d", &ipv))
15942         ;
15943       else if (unformat (i, "protocol %d", &protocol))
15944         ;
15945       else if (unformat (i, "port %d", &port))
15946         ;
15947       else if (unformat (i, "del"))
15948         is_add = 0;
15949       else
15950         {
15951           clib_warning ("parse error '%U'", format_unformat_error, i);
15952           return -99;
15953         }
15954     }
15955
15956   M (PUNT, punt);
15957
15958   mp->is_add = (u8) is_add;
15959   mp->ipv = (u8) ipv;
15960   mp->l4_protocol = (u8) protocol;
15961   mp->l4_port = htons ((u16) port);
15962
15963   S;
15964   W;
15965   /* NOTREACHED */
15966   return 0;
15967 }
15968
15969 static void vl_api_ipsec_gre_tunnel_details_t_handler
15970   (vl_api_ipsec_gre_tunnel_details_t * mp)
15971 {
15972   vat_main_t *vam = &vat_main;
15973
15974   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15975            ntohl (mp->sw_if_index),
15976            format_ip4_address, &mp->src_address,
15977            format_ip4_address, &mp->dst_address,
15978            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15979 }
15980
15981 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15982   (vl_api_ipsec_gre_tunnel_details_t * mp)
15983 {
15984   vat_main_t *vam = &vat_main;
15985   vat_json_node_t *node = NULL;
15986   struct in_addr ip4;
15987
15988   if (VAT_JSON_ARRAY != vam->json_tree.type)
15989     {
15990       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15991       vat_json_init_array (&vam->json_tree);
15992     }
15993   node = vat_json_array_add (&vam->json_tree);
15994
15995   vat_json_init_object (node);
15996   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15997   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15998   vat_json_object_add_ip4 (node, "src_address", ip4);
15999   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16000   vat_json_object_add_ip4 (node, "dst_address", ip4);
16001   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16002   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16003 }
16004
16005 static int
16006 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16007 {
16008   unformat_input_t *i = vam->input;
16009   vl_api_ipsec_gre_tunnel_dump_t *mp;
16010   f64 timeout;
16011   u32 sw_if_index;
16012   u8 sw_if_index_set = 0;
16013
16014   /* Parse args required to build the message */
16015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16016     {
16017       if (unformat (i, "sw_if_index %d", &sw_if_index))
16018         sw_if_index_set = 1;
16019       else
16020         break;
16021     }
16022
16023   if (sw_if_index_set == 0)
16024     {
16025       sw_if_index = ~0;
16026     }
16027
16028   if (!vam->json_output)
16029     {
16030       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16031                "sw_if_index", "src_address", "dst_address",
16032                "local_sa_id", "remote_sa_id");
16033     }
16034
16035   /* Get list of gre-tunnel interfaces */
16036   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16037
16038   mp->sw_if_index = htonl (sw_if_index);
16039
16040   S;
16041
16042   /* Use a control ping for synchronization */
16043   {
16044     vl_api_control_ping_t *mp;
16045     M (CONTROL_PING, control_ping);
16046     S;
16047   }
16048   W;
16049 }
16050
16051 static int
16052 api_delete_subif (vat_main_t * vam)
16053 {
16054   unformat_input_t *i = vam->input;
16055   vl_api_delete_subif_t *mp;
16056   f64 timeout;
16057   u32 sw_if_index = ~0;
16058
16059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16060     {
16061       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16062         ;
16063       if (unformat (i, "sw_if_index %d", &sw_if_index))
16064         ;
16065       else
16066         break;
16067     }
16068
16069   if (sw_if_index == ~0)
16070     {
16071       errmsg ("missing sw_if_index\n");
16072       return -99;
16073     }
16074
16075   /* Construct the API message */
16076   M (DELETE_SUBIF, delete_subif);
16077   mp->sw_if_index = ntohl (sw_if_index);
16078
16079   S;
16080   W;
16081 }
16082
16083 #define foreach_pbb_vtr_op      \
16084 _("disable",  L2_VTR_DISABLED)  \
16085 _("pop",  L2_VTR_POP_2)         \
16086 _("push",  L2_VTR_PUSH_2)
16087
16088 static int
16089 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16090 {
16091   unformat_input_t *i = vam->input;
16092   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16093   f64 timeout;
16094   u32 sw_if_index = ~0, vtr_op = ~0;
16095   u16 outer_tag = ~0;
16096   u8 dmac[6], smac[6];
16097   u8 dmac_set = 0, smac_set = 0;
16098   u16 vlanid = 0;
16099   u32 sid = ~0;
16100   u32 tmp;
16101
16102   /* Shut up coverity */
16103   memset (dmac, 0, sizeof (dmac));
16104   memset (smac, 0, sizeof (smac));
16105
16106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16107     {
16108       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16109         ;
16110       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16111         ;
16112       else if (unformat (i, "vtr_op %d", &vtr_op))
16113         ;
16114 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16115       foreach_pbb_vtr_op
16116 #undef _
16117         else if (unformat (i, "translate_pbb_stag"))
16118         {
16119           if (unformat (i, "%d", &tmp))
16120             {
16121               vtr_op = L2_VTR_TRANSLATE_2_1;
16122               outer_tag = tmp;
16123             }
16124           else
16125             {
16126               errmsg
16127                 ("translate_pbb_stag operation requires outer tag definition\n");
16128               return -99;
16129             }
16130         }
16131       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16132         dmac_set++;
16133       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16134         smac_set++;
16135       else if (unformat (i, "sid %d", &sid))
16136         ;
16137       else if (unformat (i, "vlanid %d", &tmp))
16138         vlanid = tmp;
16139       else
16140         {
16141           clib_warning ("parse error '%U'", format_unformat_error, i);
16142           return -99;
16143         }
16144     }
16145
16146   if ((sw_if_index == ~0) || (vtr_op == ~0))
16147     {
16148       errmsg ("missing sw_if_index or vtr operation\n");
16149       return -99;
16150     }
16151   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16152       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16153     {
16154       errmsg
16155         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16156       return -99;
16157     }
16158
16159   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16160   mp->sw_if_index = ntohl (sw_if_index);
16161   mp->vtr_op = ntohl (vtr_op);
16162   mp->outer_tag = ntohs (outer_tag);
16163   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16164   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16165   mp->b_vlanid = ntohs (vlanid);
16166   mp->i_sid = ntohl (sid);
16167
16168   S;
16169   W;
16170   /* NOTREACHED */
16171   return 0;
16172 }
16173
16174 static int
16175 api_flow_classify_set_interface (vat_main_t * vam)
16176 {
16177   unformat_input_t *i = vam->input;
16178   vl_api_flow_classify_set_interface_t *mp;
16179   f64 timeout;
16180   u32 sw_if_index;
16181   int sw_if_index_set;
16182   u32 ip4_table_index = ~0;
16183   u32 ip6_table_index = ~0;
16184   u8 is_add = 1;
16185
16186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16187     {
16188       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16189         sw_if_index_set = 1;
16190       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16191         sw_if_index_set = 1;
16192       else if (unformat (i, "del"))
16193         is_add = 0;
16194       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16195         ;
16196       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16197         ;
16198       else
16199         {
16200           clib_warning ("parse error '%U'", format_unformat_error, i);
16201           return -99;
16202         }
16203     }
16204
16205   if (sw_if_index_set == 0)
16206     {
16207       errmsg ("missing interface name or sw_if_index\n");
16208       return -99;
16209     }
16210
16211   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16212
16213   mp->sw_if_index = ntohl (sw_if_index);
16214   mp->ip4_table_index = ntohl (ip4_table_index);
16215   mp->ip6_table_index = ntohl (ip6_table_index);
16216   mp->is_add = is_add;
16217
16218   S;
16219   W;
16220   /* NOTREACHED */
16221   return 0;
16222 }
16223
16224 static int
16225 api_flow_classify_dump (vat_main_t * vam)
16226 {
16227   unformat_input_t *i = vam->input;
16228   vl_api_flow_classify_dump_t *mp;
16229   f64 timeout = ~0;
16230   u8 type = FLOW_CLASSIFY_N_TABLES;
16231
16232   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16233     ;
16234   else
16235     {
16236       errmsg ("classify table type must be specified\n");
16237       return -99;
16238     }
16239
16240   if (!vam->json_output)
16241     {
16242       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16243     }
16244
16245   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16246   mp->type = type;
16247   /* send it... */
16248   S;
16249
16250   /* Use a control ping for synchronization */
16251   {
16252     vl_api_control_ping_t *mp;
16253     M (CONTROL_PING, control_ping);
16254     S;
16255   }
16256   /* Wait for a reply... */
16257   W;
16258
16259   /* NOTREACHED */
16260   return 0;
16261 }
16262
16263 static int
16264 api_feature_enable_disable (vat_main_t * vam)
16265 {
16266   unformat_input_t *i = vam->input;
16267   vl_api_feature_enable_disable_t *mp;
16268   f64 timeout;
16269   u8 *arc_name = 0;
16270   u8 *feature_name = 0;
16271   u32 sw_if_index = ~0;
16272   u8 enable = 1;
16273
16274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16275     {
16276       if (unformat (i, "arc_name %s", &arc_name))
16277         ;
16278       else if (unformat (i, "feature_name %s", &feature_name))
16279         ;
16280       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16281         ;
16282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16283         ;
16284       else if (unformat (i, "disable"))
16285         enable = 0;
16286       else
16287         break;
16288     }
16289
16290   if (arc_name == 0)
16291     {
16292       errmsg ("missing arc name\n");
16293       return -99;
16294     }
16295   if (vec_len (arc_name) > 63)
16296     {
16297       errmsg ("arc name too long\n");
16298     }
16299
16300   if (feature_name == 0)
16301     {
16302       errmsg ("missing feature name\n");
16303       return -99;
16304     }
16305   if (vec_len (feature_name) > 63)
16306     {
16307       errmsg ("feature name too long\n");
16308     }
16309
16310   if (sw_if_index == ~0)
16311     {
16312       errmsg ("missing interface name or sw_if_index\n");
16313       return -99;
16314     }
16315
16316   /* Construct the API message */
16317   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16318   mp->sw_if_index = ntohl (sw_if_index);
16319   mp->enable = enable;
16320   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16321   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16322   vec_free (arc_name);
16323   vec_free (feature_name);
16324
16325   S;
16326   W;
16327 }
16328
16329 static int
16330 q_or_quit (vat_main_t * vam)
16331 {
16332   longjmp (vam->jump_buf, 1);
16333   return 0;                     /* not so much */
16334 }
16335
16336 static int
16337 q (vat_main_t * vam)
16338 {
16339   return q_or_quit (vam);
16340 }
16341
16342 static int
16343 quit (vat_main_t * vam)
16344 {
16345   return q_or_quit (vam);
16346 }
16347
16348 static int
16349 comment (vat_main_t * vam)
16350 {
16351   return 0;
16352 }
16353
16354 static int
16355 cmd_cmp (void *a1, void *a2)
16356 {
16357   u8 **c1 = a1;
16358   u8 **c2 = a2;
16359
16360   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16361 }
16362
16363 static int
16364 help (vat_main_t * vam)
16365 {
16366   u8 **cmds = 0;
16367   u8 *name = 0;
16368   hash_pair_t *p;
16369   unformat_input_t *i = vam->input;
16370   int j;
16371
16372   if (unformat (i, "%s", &name))
16373     {
16374       uword *hs;
16375
16376       vec_add1 (name, 0);
16377
16378       hs = hash_get_mem (vam->help_by_name, name);
16379       if (hs)
16380         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16381       else
16382         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16383       vec_free (name);
16384       return 0;
16385     }
16386
16387   fformat (vam->ofp, "Help is available for the following:\n");
16388
16389     /* *INDENT-OFF* */
16390     hash_foreach_pair (p, vam->function_by_name,
16391     ({
16392       vec_add1 (cmds, (u8 *)(p->key));
16393     }));
16394     /* *INDENT-ON* */
16395
16396   vec_sort_with_function (cmds, cmd_cmp);
16397
16398   for (j = 0; j < vec_len (cmds); j++)
16399     fformat (vam->ofp, "%s\n", cmds[j]);
16400
16401   vec_free (cmds);
16402   return 0;
16403 }
16404
16405 static int
16406 set (vat_main_t * vam)
16407 {
16408   u8 *name = 0, *value = 0;
16409   unformat_input_t *i = vam->input;
16410
16411   if (unformat (i, "%s", &name))
16412     {
16413       /* The input buffer is a vector, not a string. */
16414       value = vec_dup (i->buffer);
16415       vec_delete (value, i->index, 0);
16416       /* Almost certainly has a trailing newline */
16417       if (value[vec_len (value) - 1] == '\n')
16418         value[vec_len (value) - 1] = 0;
16419       /* Make sure it's a proper string, one way or the other */
16420       vec_add1 (value, 0);
16421       (void) clib_macro_set_value (&vam->macro_main,
16422                                    (char *) name, (char *) value);
16423     }
16424   else
16425     errmsg ("usage: set <name> <value>\n");
16426
16427   vec_free (name);
16428   vec_free (value);
16429   return 0;
16430 }
16431
16432 static int
16433 unset (vat_main_t * vam)
16434 {
16435   u8 *name = 0;
16436
16437   if (unformat (vam->input, "%s", &name))
16438     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16439       errmsg ("unset: %s wasn't set\n", name);
16440   vec_free (name);
16441   return 0;
16442 }
16443
16444 typedef struct
16445 {
16446   u8 *name;
16447   u8 *value;
16448 } macro_sort_t;
16449
16450
16451 static int
16452 macro_sort_cmp (void *a1, void *a2)
16453 {
16454   macro_sort_t *s1 = a1;
16455   macro_sort_t *s2 = a2;
16456
16457   return strcmp ((char *) (s1->name), (char *) (s2->name));
16458 }
16459
16460 static int
16461 dump_macro_table (vat_main_t * vam)
16462 {
16463   macro_sort_t *sort_me = 0, *sm;
16464   int i;
16465   hash_pair_t *p;
16466
16467     /* *INDENT-OFF* */
16468     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16469     ({
16470       vec_add2 (sort_me, sm, 1);
16471       sm->name = (u8 *)(p->key);
16472       sm->value = (u8 *) (p->value[0]);
16473     }));
16474     /* *INDENT-ON* */
16475
16476   vec_sort_with_function (sort_me, macro_sort_cmp);
16477
16478   if (vec_len (sort_me))
16479     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16480   else
16481     fformat (vam->ofp, "The macro table is empty...\n");
16482
16483   for (i = 0; i < vec_len (sort_me); i++)
16484     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16485   return 0;
16486 }
16487
16488 static int
16489 dump_node_table (vat_main_t * vam)
16490 {
16491   int i, j;
16492   vlib_node_t *node, *next_node;
16493
16494   if (vec_len (vam->graph_nodes) == 0)
16495     {
16496       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16497       return 0;
16498     }
16499
16500   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16501     {
16502       node = vam->graph_nodes[i];
16503       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16504       for (j = 0; j < vec_len (node->next_nodes); j++)
16505         {
16506           if (node->next_nodes[j] != ~0)
16507             {
16508               next_node = vam->graph_nodes[node->next_nodes[j]];
16509               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16510             }
16511         }
16512     }
16513   return 0;
16514 }
16515
16516 static int
16517 value_sort_cmp (void *a1, void *a2)
16518 {
16519   name_sort_t *n1 = a1;
16520   name_sort_t *n2 = a2;
16521
16522   if (n1->value < n2->value)
16523     return -1;
16524   if (n1->value > n2->value)
16525     return 1;
16526   return 0;
16527 }
16528
16529
16530 static int
16531 dump_msg_api_table (vat_main_t * vam)
16532 {
16533   api_main_t *am = &api_main;
16534   name_sort_t *nses = 0, *ns;
16535   hash_pair_t *hp;
16536   int i;
16537
16538   /* *INDENT-OFF* */
16539   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16540   ({
16541     vec_add2 (nses, ns, 1);
16542     ns->name = (u8 *)(hp->key);
16543     ns->value = (u32) hp->value[0];
16544   }));
16545   /* *INDENT-ON* */
16546
16547   vec_sort_with_function (nses, value_sort_cmp);
16548
16549   for (i = 0; i < vec_len (nses); i++)
16550     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16551   vec_free (nses);
16552   return 0;
16553 }
16554
16555 static int
16556 get_msg_id (vat_main_t * vam)
16557 {
16558   u8 *name_and_crc;
16559   u32 message_index;
16560
16561   if (unformat (vam->input, "%s", &name_and_crc))
16562     {
16563       message_index = vl_api_get_msg_index (name_and_crc);
16564       if (message_index == ~0)
16565         {
16566           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16567           return 0;
16568         }
16569       fformat (vam->ofp, " '%s' has message index %d\n",
16570                name_and_crc, message_index);
16571       return 0;
16572     }
16573   errmsg ("name_and_crc required...\n");
16574   return 0;
16575 }
16576
16577 static int
16578 search_node_table (vat_main_t * vam)
16579 {
16580   unformat_input_t *line_input = vam->input;
16581   u8 *node_to_find;
16582   int j;
16583   vlib_node_t *node, *next_node;
16584   uword *p;
16585
16586   if (vam->graph_node_index_by_name == 0)
16587     {
16588       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16589       return 0;
16590     }
16591
16592   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16593     {
16594       if (unformat (line_input, "%s", &node_to_find))
16595         {
16596           vec_add1 (node_to_find, 0);
16597           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16598           if (p == 0)
16599             {
16600               fformat (vam->ofp, "%s not found...\n", node_to_find);
16601               goto out;
16602             }
16603           node = vam->graph_nodes[p[0]];
16604           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16605           for (j = 0; j < vec_len (node->next_nodes); j++)
16606             {
16607               if (node->next_nodes[j] != ~0)
16608                 {
16609                   next_node = vam->graph_nodes[node->next_nodes[j]];
16610                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16611                 }
16612             }
16613         }
16614
16615       else
16616         {
16617           clib_warning ("parse error '%U'", format_unformat_error,
16618                         line_input);
16619           return -99;
16620         }
16621
16622     out:
16623       vec_free (node_to_find);
16624
16625     }
16626
16627   return 0;
16628 }
16629
16630
16631 static int
16632 script (vat_main_t * vam)
16633 {
16634   u8 *s = 0;
16635   char *save_current_file;
16636   unformat_input_t save_input;
16637   jmp_buf save_jump_buf;
16638   u32 save_line_number;
16639
16640   FILE *new_fp, *save_ifp;
16641
16642   if (unformat (vam->input, "%s", &s))
16643     {
16644       new_fp = fopen ((char *) s, "r");
16645       if (new_fp == 0)
16646         {
16647           errmsg ("Couldn't open script file %s\n", s);
16648           vec_free (s);
16649           return -99;
16650         }
16651     }
16652   else
16653     {
16654       errmsg ("Missing script name\n");
16655       return -99;
16656     }
16657
16658   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16659   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16660   save_ifp = vam->ifp;
16661   save_line_number = vam->input_line_number;
16662   save_current_file = (char *) vam->current_file;
16663
16664   vam->input_line_number = 0;
16665   vam->ifp = new_fp;
16666   vam->current_file = s;
16667   do_one_file (vam);
16668
16669   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16670   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16671   vam->ifp = save_ifp;
16672   vam->input_line_number = save_line_number;
16673   vam->current_file = (u8 *) save_current_file;
16674   vec_free (s);
16675
16676   return 0;
16677 }
16678
16679 static int
16680 echo (vat_main_t * vam)
16681 {
16682   fformat (vam->ofp, "%v", vam->input->buffer);
16683   return 0;
16684 }
16685
16686 /* List of API message constructors, CLI names map to api_xxx */
16687 #define foreach_vpe_api_msg                                             \
16688 _(create_loopback,"[mac <mac-addr>]")                                   \
16689 _(sw_interface_dump,"")                                                 \
16690 _(sw_interface_set_flags,                                               \
16691   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16692 _(sw_interface_add_del_address,                                         \
16693   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16694 _(sw_interface_set_table,                                               \
16695   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16696 _(sw_interface_set_mpls_enable,                                                \
16697   "<intfc> | sw_if_index [disable | dis]")                                \
16698 _(sw_interface_set_vpath,                                               \
16699   "<intfc> | sw_if_index <id> enable | disable")                        \
16700 _(sw_interface_set_l2_xconnect,                                         \
16701   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16702   "enable | disable")                                                   \
16703 _(sw_interface_set_l2_bridge,                                           \
16704   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16705   "[shg <split-horizon-group>] [bvi]\n"                                 \
16706   "enable | disable")                                                   \
16707 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16708   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16709   "profile <profile-id>\n")                                             \
16710 _(sw_interface_set_dpdk_hqos_subport,                                   \
16711   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16712   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16713 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16714   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16715 _(bridge_domain_add_del,                                                \
16716   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16717 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16718 _(l2fib_add_del,                                                        \
16719   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16720 _(l2_flags,                                                             \
16721   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16722 _(bridge_flags,                                                         \
16723   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16724 _(tap_connect,                                                          \
16725   "tapname <name> mac <mac-addr> | random-mac")                         \
16726 _(tap_modify,                                                           \
16727   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16728 _(tap_delete,                                                           \
16729   "<vpp-if-name> | sw_if_index <id>")                                   \
16730 _(sw_interface_tap_dump, "")                                            \
16731 _(ip_add_del_route,                                                     \
16732   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16733   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16734   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16735   "[multipath] [count <n>]")                                            \
16736 _(mpls_route_add_del,                                                   \
16737   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16738   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16739   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16740   "[multipath] [count <n>]")                                            \
16741 _(mpls_ip_bind_unbind,                                                  \
16742   "<label> <addr/len>")                                                 \
16743 _(proxy_arp_add_del,                                                    \
16744   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16745 _(proxy_arp_intfc_enable_disable,                                       \
16746   "<intfc> | sw_if_index <id> enable | disable")                        \
16747 _(mpls_add_del_encap,                                                   \
16748   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16749 _(sw_interface_set_unnumbered,                                          \
16750   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16751 _(ip_neighbor_add_del,                                                  \
16752   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16753   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16754 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16755 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16756 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16757   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16758   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16759   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16760 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16761 _(reset_fib, "vrf <n> [ipv6]")                                          \
16762 _(dhcp_proxy_config,                                                    \
16763   "svr <v46-address> src <v46-address>\n"                               \
16764    "insert-cid <n> [del]")                                              \
16765 _(dhcp_proxy_config_2,                                                  \
16766   "svr <v46-address> src <v46-address>\n"                               \
16767    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16768 _(dhcp_proxy_set_vss,                                                   \
16769   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16770 _(dhcp_client_config,                                                   \
16771   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16772 _(set_ip_flow_hash,                                                     \
16773   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16774 _(sw_interface_ip6_enable_disable,                                      \
16775   "<intfc> | sw_if_index <id> enable | disable")                        \
16776 _(sw_interface_ip6_set_link_local_address,                              \
16777   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16778 _(sw_interface_ip6nd_ra_prefix,                                         \
16779   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16780   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16781   "[nolink] [isno]")                                                    \
16782 _(sw_interface_ip6nd_ra_config,                                         \
16783   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16784   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16785   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16786 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16787 _(l2_patch_add_del,                                                     \
16788   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16789   "enable | disable")                                                   \
16790 _(mpls_ethernet_add_del_tunnel,                                         \
16791   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16792   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16793 _(mpls_ethernet_add_del_tunnel_2,                                       \
16794   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16795   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16796 _(sr_tunnel_add_del,                                                    \
16797   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16798   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16799   "[policy <policy_name>]")                                             \
16800 _(sr_policy_add_del,                                                    \
16801   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16802 _(sr_multicast_map_add_del,                                             \
16803   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16804 _(classify_add_del_table,                                               \
16805   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16806   " [del] mask <mask-value>\n"                                          \
16807   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16808   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16809 _(classify_add_del_session,                                             \
16810   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16811   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16812   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16813   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16814 _(classify_set_interface_ip_table,                                      \
16815   "<intfc> | sw_if_index <nn> table <nn>")                              \
16816 _(classify_set_interface_l2_tables,                                     \
16817   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16818   "  [other-table <nn>]")                                               \
16819 _(get_node_index, "node <node-name")                                    \
16820 _(add_node_next, "node <node-name> next <next-node-name>")              \
16821 _(l2tpv3_create_tunnel,                                                 \
16822   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16823   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16824   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16825 _(l2tpv3_set_tunnel_cookies,                                            \
16826   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16827   "[new_remote_cookie <nn>]\n")                                         \
16828 _(l2tpv3_interface_enable_disable,                                      \
16829   "<intfc> | sw_if_index <nn> enable | disable")                        \
16830 _(l2tpv3_set_lookup_key,                                                \
16831   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16832 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16833 _(vxlan_add_del_tunnel,                                                 \
16834   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16835   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16836   "vni <vni> [encap-vrf-id <nn>] [decap-next l2|ip4|ip6] [del]")        \
16837 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16838 _(gre_add_del_tunnel,                                                   \
16839   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16840 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16841 _(l2_fib_clear_table, "")                                               \
16842 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16843 _(l2_interface_vlan_tag_rewrite,                                        \
16844   "<intfc> | sw_if_index <nn> \n"                                       \
16845   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16846   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16847 _(create_vhost_user_if,                                                 \
16848         "socket <filename> [server] [renumber <dev_instance>] "         \
16849         "[mac <mac_address>]")                                          \
16850 _(modify_vhost_user_if,                                                 \
16851         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16852         "[server] [renumber <dev_instance>]")                           \
16853 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16854 _(sw_interface_vhost_user_dump, "")                                     \
16855 _(show_version, "")                                                     \
16856 _(vxlan_gpe_add_del_tunnel,                                             \
16857   "local <addr> remote <addr> vni <nn>\n"                               \
16858     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16859   "[next-ethernet] [next-nsh]\n")                                       \
16860 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16861 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16862 _(interface_name_renumber,                                              \
16863   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16864 _(input_acl_set_interface,                                              \
16865   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16866   "  [l2-table <nn>] [del]")                                            \
16867 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16868 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16869 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16870 _(ip_dump, "ipv4 | ipv6")                                               \
16871 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16872 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16873   "  spid_id <n> ")                                                     \
16874 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16875   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16876   "  integ_alg <alg> integ_key <hex>")                                  \
16877 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16878   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16879   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16880   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16881 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16882 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16883 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16884   "(auth_data 0x<data> | auth_data <data>)")                            \
16885 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16886   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16887 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16888   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16889   "(local|remote)")                                                     \
16890 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16891 _(delete_loopback,"sw_if_index <nn>")                                   \
16892 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16893 _(map_add_domain,                                                       \
16894   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16895   "ip6-src <ip6addr> "                                                  \
16896   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16897 _(map_del_domain, "index <n>")                                          \
16898 _(map_add_del_rule,                                                     \
16899   "index <n> psid <n> dst <ip6addr> [del]")                             \
16900 _(map_domain_dump, "")                                                  \
16901 _(map_rule_dump, "index <map-domain>")                                  \
16902 _(want_interface_events,  "enable|disable")                             \
16903 _(want_stats,"enable|disable")                                          \
16904 _(get_first_msg_id, "client <name>")                                    \
16905 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16906 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16907   "fib-id <nn> [ip4][ip6][default]")                                    \
16908 _(get_node_graph, " ")                                                  \
16909 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16910 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16911 _(ioam_disable, "")                                                \
16912 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16913                             " sw_if_index <sw_if_index> p <priority> "  \
16914                             "w <weight>] [del]")                        \
16915 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16916                         "iface <intf> | sw_if_index <sw_if_index> "     \
16917                         "p <priority> w <weight> [del]")                \
16918 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16919                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16920                           "locator-set <locator_name> [del]")           \
16921 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16922   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16923 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16924 _(lisp_gpe_enable_disable, "enable|disable")                            \
16925 _(lisp_enable_disable, "enable|disable")                                \
16926 _(lisp_gpe_add_del_iface, "up|down")                                    \
16927 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16928                                "[seid <seid>] "                         \
16929                                "rloc <locator> p <prio> "               \
16930                                "w <weight> [rloc <loc> ... ] "          \
16931                                "action <action> [del-all]")             \
16932 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16933                           "<local-eid>")                                \
16934 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16935 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16936 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16937 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16938 _(lisp_locator_set_dump, "[local | remote]")                            \
16939 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16940 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16941                        "[local] | [remote]")                            \
16942 _(lisp_eid_table_vni_dump, "")                                          \
16943 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16944 _(lisp_gpe_tunnel_dump, "")                                             \
16945 _(lisp_map_resolver_dump, "")                                           \
16946 _(lisp_adjacencies_get, "vni <vni>")                                    \
16947 _(show_lisp_status, "")                                                 \
16948 _(lisp_get_map_request_itr_rlocs, "")                                   \
16949 _(show_lisp_pitr, "")                                                   \
16950 _(show_lisp_map_request_mode, "")                                       \
16951 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16952 _(af_packet_delete, "name <host interface name>")                       \
16953 _(policer_add_del, "name <policer name> <params> [del]")                \
16954 _(policer_dump, "[name <policer name>]")                                \
16955 _(policer_classify_set_interface,                                       \
16956   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16957   "  [l2-table <nn>] [del]")                                            \
16958 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16959 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16960     "[master|slave]")                                                   \
16961 _(netmap_delete, "name <interface name>")                               \
16962 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16963 _(mpls_fib_encap_dump, "")                                              \
16964 _(mpls_fib_dump, "")                                                    \
16965 _(classify_table_ids, "")                                               \
16966 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16967 _(classify_table_info, "table_id <nn>")                                 \
16968 _(classify_session_dump, "table_id <nn>")                               \
16969 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16970     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16971     "[template_interval <nn>] [udp_checksum]")                          \
16972 _(ipfix_exporter_dump, "")                                              \
16973 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16974 _(ipfix_classify_stream_dump, "")                                       \
16975 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16976 _(ipfix_classify_table_dump, "")                                        \
16977 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16978 _(sw_interface_span_dump, "")                                           \
16979 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16980 _(pg_create_interface, "if_id <nn>")                                    \
16981 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16982 _(pg_enable_disable, "[stream <id>] disable")                           \
16983 _(ip_source_and_port_range_check_add_del,                               \
16984   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16985 _(ip_source_and_port_range_check_interface_add_del,                     \
16986   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16987   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16988 _(ipsec_gre_add_del_tunnel,                                             \
16989   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16990 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16991 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16992 _(l2_interface_pbb_tag_rewrite,                                         \
16993   "<intfc> | sw_if_index <nn> \n"                                       \
16994   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16995   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16996 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16997 _(flow_classify_set_interface,                                          \
16998   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16999 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17000 _(ip_fib_dump, "")                                                      \
17001 _(ip6_fib_dump, "")                                                     \
17002 _(feature_enable_disable, "arc_name <arc_name> "                        \
17003   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
17004
17005 /* List of command functions, CLI names map directly to functions */
17006 #define foreach_cli_function                                    \
17007 _(comment, "usage: comment <ignore-rest-of-line>")              \
17008 _(dump_interface_table, "usage: dump_interface_table")          \
17009 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17010 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17011 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17012 _(dump_stats_table, "usage: dump_stats_table")                  \
17013 _(dump_macro_table, "usage: dump_macro_table ")                 \
17014 _(dump_node_table, "usage: dump_node_table")                    \
17015 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17016 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17017 _(echo, "usage: echo <message>")                                \
17018 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17019 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17020 _(help, "usage: help")                                          \
17021 _(q, "usage: quit")                                             \
17022 _(quit, "usage: quit")                                          \
17023 _(search_node_table, "usage: search_node_table <name>...")      \
17024 _(set, "usage: set <variable-name> <value>")                    \
17025 _(script, "usage: script <file-name>")                          \
17026 _(unset, "usage: unset <variable-name>")
17027
17028 #define _(N,n)                                  \
17029     static void vl_api_##n##_t_handler_uni      \
17030     (vl_api_##n##_t * mp)                       \
17031     {                                           \
17032         vat_main_t * vam = &vat_main;           \
17033         if (vam->json_output) {                 \
17034             vl_api_##n##_t_handler_json(mp);    \
17035         } else {                                \
17036             vl_api_##n##_t_handler(mp);         \
17037         }                                       \
17038     }
17039 foreach_vpe_api_reply_msg;
17040 #undef _
17041
17042 void
17043 vat_api_hookup (vat_main_t * vam)
17044 {
17045 #define _(N,n)                                                  \
17046     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17047                            vl_api_##n##_t_handler_uni,          \
17048                            vl_noop_handler,                     \
17049                            vl_api_##n##_t_endian,               \
17050                            vl_api_##n##_t_print,                \
17051                            sizeof(vl_api_##n##_t), 1);
17052   foreach_vpe_api_reply_msg;
17053 #undef _
17054
17055   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17056
17057   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17058
17059   vam->function_by_name = hash_create_string (0, sizeof (uword));
17060
17061   vam->help_by_name = hash_create_string (0, sizeof (uword));
17062
17063   /* API messages we can send */
17064 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17065   foreach_vpe_api_msg;
17066 #undef _
17067
17068   /* Help strings */
17069 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17070   foreach_vpe_api_msg;
17071 #undef _
17072
17073   /* CLI functions */
17074 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17075   foreach_cli_function;
17076 #undef _
17077
17078   /* Help strings */
17079 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17080   foreach_cli_function;
17081 #undef _
17082 }
17083
17084 #undef vl_api_version
17085 #define vl_api_version(n,v) static u32 memory_api_version = v;
17086 #include <vlibmemory/vl_memory_api_h.h>
17087 #undef vl_api_version
17088
17089 #undef vl_api_version
17090 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17091 #include <vnet/interface.api.h>
17092 #undef vl_api_version
17093
17094 #undef vl_api_version
17095 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17096 #include <vpp-api/vpe.api.h>
17097 #undef vl_api_version
17098
17099 static u32 *api_versions[] = {
17100   &memory_api_version,
17101   &vnet_interface_api_version,
17102   &vpp_api_version,
17103 };
17104
17105 void
17106 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17107 {
17108   int i;
17109
17110   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17111
17112   /*
17113    * Send the API signatures. This bit of code must
17114    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17115    */
17116
17117   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17118     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17119 }
17120
17121 /*
17122  * fd.io coding-style-patch-verification: ON
17123  *
17124  * Local Variables:
17125  * eval: (c-set-style "gnu")
17126  * End:
17127  */