dpdk: Add support for Mellanox ConnectX-4 devices
[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.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 <inttypes.h>
53 #include <sys/stat.h>
54
55 #define vl_typedefs             /* define message structures */
56 #include <vpp-api/vpe_all_api_h.h>
57 #undef vl_typedefs
58
59 /* declare message handlers for each api */
60
61 #define vl_endianfun            /* define message structures */
62 #include <vpp-api/vpe_all_api_h.h>
63 #undef vl_endianfun
64
65 /* instantiate all the print functions we know about */
66 #define vl_print(handle, ...)
67 #define vl_printfun
68 #include <vpp-api/vpe_all_api_h.h>
69 #undef vl_printfun
70
71 static uword
72 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
73 {
74   vat_main_t *vam = va_arg (*args, vat_main_t *);
75   u32 *result = va_arg (*args, u32 *);
76   u8 *if_name;
77   uword *p;
78
79   if (!unformat (input, "%s", &if_name))
80     return 0;
81
82   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
83   if (p == 0)
84     return 0;
85   *result = p[0];
86   return 1;
87 }
88
89 void vat_suspend (vlib_main_t * vm, f64 interval);
90
91 #if VPP_API_TEST_BUILTIN == 0
92 /* Parse an IP4 address %d.%d.%d.%d. */
93 uword
94 unformat_ip4_address (unformat_input_t * input, va_list * args)
95 {
96   u8 *result = va_arg (*args, u8 *);
97   unsigned a[4];
98
99   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
100     return 0;
101
102   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
103     return 0;
104
105   result[0] = a[0];
106   result[1] = a[1];
107   result[2] = a[2];
108   result[3] = a[3];
109
110   return 1;
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 #endif /* VPP_API_TEST_BUILTIN */
349
350 static uword
351 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
352 {
353   u8 *r = va_arg (*args, u8 *);
354
355   if (unformat (input, "kbps"))
356     *r = SSE2_QOS_RATE_KBPS;
357   else if (unformat (input, "pps"))
358     *r = SSE2_QOS_RATE_PPS;
359   else
360     return 0;
361   return 1;
362 }
363
364 static uword
365 unformat_policer_round_type (unformat_input_t * input, va_list * args)
366 {
367   u8 *r = va_arg (*args, u8 *);
368
369   if (unformat (input, "closest"))
370     *r = SSE2_QOS_ROUND_TO_CLOSEST;
371   else if (unformat (input, "up"))
372     *r = SSE2_QOS_ROUND_TO_UP;
373   else if (unformat (input, "down"))
374     *r = SSE2_QOS_ROUND_TO_DOWN;
375   else
376     return 0;
377   return 1;
378 }
379
380 static uword
381 unformat_policer_type (unformat_input_t * input, va_list * args)
382 {
383   u8 *r = va_arg (*args, u8 *);
384
385   if (unformat (input, "1r2c"))
386     *r = SSE2_QOS_POLICER_TYPE_1R2C;
387   else if (unformat (input, "1r3c"))
388     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
389   else if (unformat (input, "2r3c-2698"))
390     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
391   else if (unformat (input, "2r3c-4115"))
392     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
393   else if (unformat (input, "2r3c-mef5cf1"))
394     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
395   else
396     return 0;
397   return 1;
398 }
399
400 static uword
401 unformat_dscp (unformat_input_t * input, va_list * va)
402 {
403   u8 *r = va_arg (*va, u8 *);
404
405   if (0);
406 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
407   foreach_vnet_dscp
408 #undef _
409     else
410     return 0;
411   return 1;
412 }
413
414 static uword
415 unformat_policer_action_type (unformat_input_t * input, va_list * va)
416 {
417   sse2_qos_pol_action_params_st *a
418     = va_arg (*va, sse2_qos_pol_action_params_st *);
419
420   if (unformat (input, "drop"))
421     a->action_type = SSE2_QOS_ACTION_DROP;
422   else if (unformat (input, "transmit"))
423     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
424   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
425     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
426   else
427     return 0;
428   return 1;
429 }
430
431 static uword
432 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
433 {
434   u32 *r = va_arg (*va, u32 *);
435   u32 tid;
436
437   if (unformat (input, "ip4"))
438     tid = POLICER_CLASSIFY_TABLE_IP4;
439   else if (unformat (input, "ip6"))
440     tid = POLICER_CLASSIFY_TABLE_IP6;
441   else if (unformat (input, "l2"))
442     tid = POLICER_CLASSIFY_TABLE_L2;
443   else
444     return 0;
445
446   *r = tid;
447   return 1;
448 }
449
450 static uword
451 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
452 {
453   u32 *r = va_arg (*va, u32 *);
454   u32 tid;
455
456   if (unformat (input, "ip4"))
457     tid = FLOW_CLASSIFY_TABLE_IP4;
458   else if (unformat (input, "ip6"))
459     tid = FLOW_CLASSIFY_TABLE_IP6;
460   else
461     return 0;
462
463   *r = tid;
464   return 1;
465 }
466
467 #if (VPP_API_TEST_BUILTIN==0)
468 u8 *
469 format_ip4_address (u8 * s, va_list * args)
470 {
471   u8 *a = va_arg (*args, u8 *);
472   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
473 }
474
475 u8 *
476 format_ip6_address (u8 * s, va_list * args)
477 {
478   ip6_address_t *a = va_arg (*args, ip6_address_t *);
479   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
480
481   i_max_n_zero = ARRAY_LEN (a->as_u16);
482   max_n_zeros = 0;
483   i_first_zero = i_max_n_zero;
484   n_zeros = 0;
485   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
486     {
487       u32 is_zero = a->as_u16[i] == 0;
488       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
489         {
490           i_first_zero = i;
491           n_zeros = 0;
492         }
493       n_zeros += is_zero;
494       if ((!is_zero && n_zeros > max_n_zeros)
495           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
496         {
497           i_max_n_zero = i_first_zero;
498           max_n_zeros = n_zeros;
499           i_first_zero = ARRAY_LEN (a->as_u16);
500           n_zeros = 0;
501         }
502     }
503
504   last_double_colon = 0;
505   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
506     {
507       if (i == i_max_n_zero && max_n_zeros > 1)
508         {
509           s = format (s, "::");
510           i += max_n_zeros - 1;
511           last_double_colon = 1;
512         }
513       else
514         {
515           s = format (s, "%s%x",
516                       (last_double_colon || i == 0) ? "" : ":",
517                       clib_net_to_host_u16 (a->as_u16[i]));
518           last_double_colon = 0;
519         }
520     }
521
522   return s;
523 }
524
525 /* Format an IP46 address. */
526 u8 *
527 format_ip46_address (u8 * s, va_list * args)
528 {
529   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
530   ip46_type_t type = va_arg (*args, ip46_type_t);
531   int is_ip4 = 1;
532
533   switch (type)
534     {
535     case IP46_TYPE_ANY:
536       is_ip4 = ip46_address_is_ip4 (ip46);
537       break;
538     case IP46_TYPE_IP4:
539       is_ip4 = 1;
540       break;
541     case IP46_TYPE_IP6:
542       is_ip4 = 0;
543       break;
544     }
545
546   return is_ip4 ?
547     format (s, "%U", format_ip4_address, &ip46->ip4) :
548     format (s, "%U", format_ip6_address, &ip46->ip6);
549 }
550
551 u8 *
552 format_ethernet_address (u8 * s, va_list * args)
553 {
554   u8 *a = va_arg (*args, u8 *);
555
556   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
557                  a[0], a[1], a[2], a[3], a[4], a[5]);
558 }
559 #endif
560
561 static void
562 increment_v4_address (ip4_address_t * a)
563 {
564   u32 v;
565
566   v = ntohl (a->as_u32) + 1;
567   a->as_u32 = ntohl (v);
568 }
569
570 static void
571 increment_v6_address (ip6_address_t * a)
572 {
573   u64 v0, v1;
574
575   v0 = clib_net_to_host_u64 (a->as_u64[0]);
576   v1 = clib_net_to_host_u64 (a->as_u64[1]);
577
578   v1 += 1;
579   if (v1 == 0)
580     v0 += 1;
581   a->as_u64[0] = clib_net_to_host_u64 (v0);
582   a->as_u64[1] = clib_net_to_host_u64 (v1);
583 }
584
585 static void
586 increment_mac_address (u64 * mac)
587 {
588   u64 tmp = *mac;
589
590   tmp = clib_net_to_host_u64 (tmp);
591   tmp += 1 << 16;               /* skip unused (least significant) octets */
592   tmp = clib_host_to_net_u64 (tmp);
593   *mac = tmp;
594 }
595
596 static void vl_api_create_loopback_reply_t_handler
597   (vl_api_create_loopback_reply_t * mp)
598 {
599   vat_main_t *vam = &vat_main;
600   i32 retval = ntohl (mp->retval);
601
602   vam->retval = retval;
603   vam->regenerate_interface_table = 1;
604   vam->sw_if_index = ntohl (mp->sw_if_index);
605   vam->result_ready = 1;
606 }
607
608 static void vl_api_create_loopback_reply_t_handler_json
609   (vl_api_create_loopback_reply_t * mp)
610 {
611   vat_main_t *vam = &vat_main;
612   vat_json_node_t node;
613
614   vat_json_init_object (&node);
615   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
616   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
617
618   vat_json_print (vam->ofp, &node);
619   vat_json_free (&node);
620   vam->retval = ntohl (mp->retval);
621   vam->result_ready = 1;
622 }
623
624 static void vl_api_af_packet_create_reply_t_handler
625   (vl_api_af_packet_create_reply_t * mp)
626 {
627   vat_main_t *vam = &vat_main;
628   i32 retval = ntohl (mp->retval);
629
630   vam->retval = retval;
631   vam->regenerate_interface_table = 1;
632   vam->sw_if_index = ntohl (mp->sw_if_index);
633   vam->result_ready = 1;
634 }
635
636 static void vl_api_af_packet_create_reply_t_handler_json
637   (vl_api_af_packet_create_reply_t * mp)
638 {
639   vat_main_t *vam = &vat_main;
640   vat_json_node_t node;
641
642   vat_json_init_object (&node);
643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
644   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
645
646   vat_json_print (vam->ofp, &node);
647   vat_json_free (&node);
648
649   vam->retval = ntohl (mp->retval);
650   vam->result_ready = 1;
651 }
652
653 static void vl_api_create_vlan_subif_reply_t_handler
654   (vl_api_create_vlan_subif_reply_t * mp)
655 {
656   vat_main_t *vam = &vat_main;
657   i32 retval = ntohl (mp->retval);
658
659   vam->retval = retval;
660   vam->regenerate_interface_table = 1;
661   vam->sw_if_index = ntohl (mp->sw_if_index);
662   vam->result_ready = 1;
663 }
664
665 static void vl_api_create_vlan_subif_reply_t_handler_json
666   (vl_api_create_vlan_subif_reply_t * mp)
667 {
668   vat_main_t *vam = &vat_main;
669   vat_json_node_t node;
670
671   vat_json_init_object (&node);
672   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
673   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
674
675   vat_json_print (vam->ofp, &node);
676   vat_json_free (&node);
677
678   vam->retval = ntohl (mp->retval);
679   vam->result_ready = 1;
680 }
681
682 static void vl_api_create_subif_reply_t_handler
683   (vl_api_create_subif_reply_t * mp)
684 {
685   vat_main_t *vam = &vat_main;
686   i32 retval = ntohl (mp->retval);
687
688   vam->retval = retval;
689   vam->regenerate_interface_table = 1;
690   vam->sw_if_index = ntohl (mp->sw_if_index);
691   vam->result_ready = 1;
692 }
693
694 static void vl_api_create_subif_reply_t_handler_json
695   (vl_api_create_subif_reply_t * mp)
696 {
697   vat_main_t *vam = &vat_main;
698   vat_json_node_t node;
699
700   vat_json_init_object (&node);
701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
702   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
703
704   vat_json_print (vam->ofp, &node);
705   vat_json_free (&node);
706
707   vam->retval = ntohl (mp->retval);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_interface_name_renumber_reply_t_handler
712   (vl_api_interface_name_renumber_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   i32 retval = ntohl (mp->retval);
716
717   vam->retval = retval;
718   vam->regenerate_interface_table = 1;
719   vam->result_ready = 1;
720 }
721
722 static void vl_api_interface_name_renumber_reply_t_handler_json
723   (vl_api_interface_name_renumber_reply_t * mp)
724 {
725   vat_main_t *vam = &vat_main;
726   vat_json_node_t node;
727
728   vat_json_init_object (&node);
729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
730
731   vat_json_print (vam->ofp, &node);
732   vat_json_free (&node);
733
734   vam->retval = ntohl (mp->retval);
735   vam->result_ready = 1;
736 }
737
738 /*
739  * Special-case: build the interface table, maintain
740  * the next loopback sw_if_index vbl.
741  */
742 static void vl_api_sw_interface_details_t_handler
743   (vl_api_sw_interface_details_t * mp)
744 {
745   vat_main_t *vam = &vat_main;
746   u8 *s = format (0, "%s%c", mp->interface_name, 0);
747
748   hash_set_mem (vam->sw_if_index_by_interface_name, s,
749                 ntohl (mp->sw_if_index));
750
751   /* In sub interface case, fill the sub interface table entry */
752   if (mp->sw_if_index != mp->sup_sw_if_index)
753     {
754       sw_interface_subif_t *sub = NULL;
755
756       vec_add2 (vam->sw_if_subif_table, sub, 1);
757
758       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
759       strncpy ((char *) sub->interface_name, (char *) s,
760                vec_len (sub->interface_name));
761       sub->sw_if_index = ntohl (mp->sw_if_index);
762       sub->sub_id = ntohl (mp->sub_id);
763
764       sub->sub_dot1ad = mp->sub_dot1ad;
765       sub->sub_number_of_tags = mp->sub_number_of_tags;
766       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
767       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
768       sub->sub_exact_match = mp->sub_exact_match;
769       sub->sub_default = mp->sub_default;
770       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
771       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
772
773       /* vlan tag rewrite */
774       sub->vtr_op = ntohl (mp->vtr_op);
775       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
776       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
777       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
778     }
779 }
780
781 static void vl_api_sw_interface_details_t_handler_json
782   (vl_api_sw_interface_details_t * mp)
783 {
784   vat_main_t *vam = &vat_main;
785   vat_json_node_t *node = NULL;
786
787   if (VAT_JSON_ARRAY != vam->json_tree.type)
788     {
789       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
790       vat_json_init_array (&vam->json_tree);
791     }
792   node = vat_json_array_add (&vam->json_tree);
793
794   vat_json_init_object (node);
795   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
796   vat_json_object_add_uint (node, "sup_sw_if_index",
797                             ntohl (mp->sup_sw_if_index));
798   vat_json_object_add_uint (node, "l2_address_length",
799                             ntohl (mp->l2_address_length));
800   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
801                              sizeof (mp->l2_address));
802   vat_json_object_add_string_copy (node, "interface_name",
803                                    mp->interface_name);
804   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
805   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
806   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
807   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
808   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
809   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
810   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
811   vat_json_object_add_uint (node, "sub_number_of_tags",
812                             mp->sub_number_of_tags);
813   vat_json_object_add_uint (node, "sub_outer_vlan_id",
814                             ntohs (mp->sub_outer_vlan_id));
815   vat_json_object_add_uint (node, "sub_inner_vlan_id",
816                             ntohs (mp->sub_inner_vlan_id));
817   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
818   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
819   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
820                             mp->sub_outer_vlan_id_any);
821   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
822                             mp->sub_inner_vlan_id_any);
823   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
824   vat_json_object_add_uint (node, "vtr_push_dot1q",
825                             ntohl (mp->vtr_push_dot1q));
826   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
827   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
828 }
829
830 static void vl_api_sw_interface_set_flags_t_handler
831   (vl_api_sw_interface_set_flags_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   if (vam->interface_event_display)
835     errmsg ("interface flags: sw_if_index %d %s %s",
836             ntohl (mp->sw_if_index),
837             mp->admin_up_down ? "admin-up" : "admin-down",
838             mp->link_up_down ? "link-up" : "link-down");
839 }
840
841 static void vl_api_sw_interface_set_flags_t_handler_json
842   (vl_api_sw_interface_set_flags_t * mp)
843 {
844   /* JSON output not supported */
845 }
846
847 static void
848 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
849 {
850   vat_main_t *vam = &vat_main;
851   i32 retval = ntohl (mp->retval);
852
853   vam->retval = retval;
854   vam->shmem_result = (u8 *) mp->reply_in_shmem;
855   vam->result_ready = 1;
856 }
857
858 static void
859 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   vat_json_node_t node;
863   api_main_t *am = &api_main;
864   void *oldheap;
865   u8 *reply;
866
867   vat_json_init_object (&node);
868   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
869   vat_json_object_add_uint (&node, "reply_in_shmem",
870                             ntohl (mp->reply_in_shmem));
871   /* Toss the shared-memory original... */
872   pthread_mutex_lock (&am->vlib_rp->mutex);
873   oldheap = svm_push_data_heap (am->vlib_rp);
874
875   reply = (u8 *) (mp->reply_in_shmem);
876   vec_free (reply);
877
878   svm_pop_heap (oldheap);
879   pthread_mutex_unlock (&am->vlib_rp->mutex);
880
881   vat_json_print (vam->ofp, &node);
882   vat_json_free (&node);
883
884   vam->retval = ntohl (mp->retval);
885   vam->result_ready = 1;
886 }
887
888 static void
889 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
890 {
891   vat_main_t *vam = &vat_main;
892   i32 retval = ntohl (mp->retval);
893
894   vam->retval = retval;
895   vam->cmd_reply = mp->reply;
896   vam->result_ready = 1;
897 }
898
899 static void
900 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
901 {
902   vat_main_t *vam = &vat_main;
903   vat_json_node_t node;
904
905   vat_json_init_object (&node);
906   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
907   vat_json_object_add_string_copy (&node, "reply", mp->reply);
908
909   vat_json_print (vam->ofp, &node);
910   vat_json_free (&node);
911
912   vam->retval = ntohl (mp->retval);
913   vam->result_ready = 1;
914 }
915
916 static void vl_api_classify_add_del_table_reply_t_handler
917   (vl_api_classify_add_del_table_reply_t * mp)
918 {
919   vat_main_t *vam = &vat_main;
920   i32 retval = ntohl (mp->retval);
921   if (vam->async_mode)
922     {
923       vam->async_errors += (retval < 0);
924     }
925   else
926     {
927       vam->retval = retval;
928       if (retval == 0 &&
929           ((mp->new_table_index != 0xFFFFFFFF) ||
930            (mp->skip_n_vectors != 0xFFFFFFFF) ||
931            (mp->match_n_vectors != 0xFFFFFFFF)))
932         /*
933          * Note: this is just barely thread-safe, depends on
934          * the main thread spinning waiting for an answer...
935          */
936         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
937                 ntohl (mp->new_table_index),
938                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
939       vam->result_ready = 1;
940     }
941 }
942
943 static void vl_api_classify_add_del_table_reply_t_handler_json
944   (vl_api_classify_add_del_table_reply_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   vat_json_node_t node;
948
949   vat_json_init_object (&node);
950   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
951   vat_json_object_add_uint (&node, "new_table_index",
952                             ntohl (mp->new_table_index));
953   vat_json_object_add_uint (&node, "skip_n_vectors",
954                             ntohl (mp->skip_n_vectors));
955   vat_json_object_add_uint (&node, "match_n_vectors",
956                             ntohl (mp->match_n_vectors));
957
958   vat_json_print (vam->ofp, &node);
959   vat_json_free (&node);
960
961   vam->retval = ntohl (mp->retval);
962   vam->result_ready = 1;
963 }
964
965 static void vl_api_get_node_index_reply_t_handler
966   (vl_api_get_node_index_reply_t * mp)
967 {
968   vat_main_t *vam = &vat_main;
969   i32 retval = ntohl (mp->retval);
970   if (vam->async_mode)
971     {
972       vam->async_errors += (retval < 0);
973     }
974   else
975     {
976       vam->retval = retval;
977       if (retval == 0)
978         errmsg ("node index %d", ntohl (mp->node_index));
979       vam->result_ready = 1;
980     }
981 }
982
983 static void vl_api_get_node_index_reply_t_handler_json
984   (vl_api_get_node_index_reply_t * mp)
985 {
986   vat_main_t *vam = &vat_main;
987   vat_json_node_t node;
988
989   vat_json_init_object (&node);
990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
991   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
992
993   vat_json_print (vam->ofp, &node);
994   vat_json_free (&node);
995
996   vam->retval = ntohl (mp->retval);
997   vam->result_ready = 1;
998 }
999
1000 static void vl_api_get_next_index_reply_t_handler
1001   (vl_api_get_next_index_reply_t * mp)
1002 {
1003   vat_main_t *vam = &vat_main;
1004   i32 retval = ntohl (mp->retval);
1005   if (vam->async_mode)
1006     {
1007       vam->async_errors += (retval < 0);
1008     }
1009   else
1010     {
1011       vam->retval = retval;
1012       if (retval == 0)
1013         errmsg ("next node index %d", ntohl (mp->next_index));
1014       vam->result_ready = 1;
1015     }
1016 }
1017
1018 static void vl_api_get_next_index_reply_t_handler_json
1019   (vl_api_get_next_index_reply_t * mp)
1020 {
1021   vat_main_t *vam = &vat_main;
1022   vat_json_node_t node;
1023
1024   vat_json_init_object (&node);
1025   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1026   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1027
1028   vat_json_print (vam->ofp, &node);
1029   vat_json_free (&node);
1030
1031   vam->retval = ntohl (mp->retval);
1032   vam->result_ready = 1;
1033 }
1034
1035 static void vl_api_add_node_next_reply_t_handler
1036   (vl_api_add_node_next_reply_t * mp)
1037 {
1038   vat_main_t *vam = &vat_main;
1039   i32 retval = ntohl (mp->retval);
1040   if (vam->async_mode)
1041     {
1042       vam->async_errors += (retval < 0);
1043     }
1044   else
1045     {
1046       vam->retval = retval;
1047       if (retval == 0)
1048         errmsg ("next index %d", ntohl (mp->next_index));
1049       vam->result_ready = 1;
1050     }
1051 }
1052
1053 static void vl_api_add_node_next_reply_t_handler_json
1054   (vl_api_add_node_next_reply_t * mp)
1055 {
1056   vat_main_t *vam = &vat_main;
1057   vat_json_node_t node;
1058
1059   vat_json_init_object (&node);
1060   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1061   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1062
1063   vat_json_print (vam->ofp, &node);
1064   vat_json_free (&node);
1065
1066   vam->retval = ntohl (mp->retval);
1067   vam->result_ready = 1;
1068 }
1069
1070 static void vl_api_show_version_reply_t_handler
1071   (vl_api_show_version_reply_t * mp)
1072 {
1073   vat_main_t *vam = &vat_main;
1074   i32 retval = ntohl (mp->retval);
1075
1076   if (retval >= 0)
1077     {
1078       errmsg ("        program: %s", mp->program);
1079       errmsg ("        version: %s", mp->version);
1080       errmsg ("     build date: %s", mp->build_date);
1081       errmsg ("build directory: %s", mp->build_directory);
1082     }
1083   vam->retval = retval;
1084   vam->result_ready = 1;
1085 }
1086
1087 static void vl_api_show_version_reply_t_handler_json
1088   (vl_api_show_version_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   vat_json_node_t node;
1092
1093   vat_json_init_object (&node);
1094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1095   vat_json_object_add_string_copy (&node, "program", mp->program);
1096   vat_json_object_add_string_copy (&node, "version", mp->version);
1097   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1098   vat_json_object_add_string_copy (&node, "build_directory",
1099                                    mp->build_directory);
1100
1101   vat_json_print (vam->ofp, &node);
1102   vat_json_free (&node);
1103
1104   vam->retval = ntohl (mp->retval);
1105   vam->result_ready = 1;
1106 }
1107
1108 static void
1109 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1110 {
1111   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1112           mp->mac_ip ? "mac/ip binding" : "address resolution",
1113           format_ip4_address, &mp->address,
1114           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1115 }
1116
1117 static void
1118 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1119 {
1120   /* JSON output not supported */
1121 }
1122
1123 static void
1124 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1125 {
1126   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1127           mp->mac_ip ? "mac/ip binding" : "address resolution",
1128           format_ip6_address, mp->address,
1129           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1130 }
1131
1132 static void
1133 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1134 {
1135   /* JSON output not supported */
1136 }
1137
1138 /*
1139  * Special-case: build the bridge domain table, maintain
1140  * the next bd id vbl.
1141  */
1142 static void vl_api_bridge_domain_details_t_handler
1143   (vl_api_bridge_domain_details_t * mp)
1144 {
1145   vat_main_t *vam = &vat_main;
1146   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1147
1148   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1149          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1150
1151   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1152          ntohl (mp->bd_id), mp->learn, mp->forward,
1153          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1154
1155   if (n_sw_ifs)
1156     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "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   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208          mp->shg, sw_if_name ? (char *) sw_if_name :
1209          "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored");
1662       errmsg ("ip_dump should be called first");
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       print (vam->ofp,
1786              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
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       print (vam->ofp,
1795              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
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   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
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   print (vam->ofp, " %d (psid) %U (ip6-dst)",
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   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1839           "router_addr %U host_mac %U",
1840           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1841           format_ip4_address, &mp->host_address,
1842           format_ip4_address, &mp->router_address,
1843           format_ethernet_address, mp->host_mac);
1844 }
1845
1846 static void vl_api_dhcp_compl_event_t_handler_json
1847   (vl_api_dhcp_compl_event_t * mp)
1848 {
1849   /* JSON output not supported */
1850 }
1851
1852 static void
1853 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1854                               u32 counter)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   static u64 default_counter = 0;
1858
1859   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1860                            NULL);
1861   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1862                            sw_if_index, default_counter);
1863   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1864 }
1865
1866 static void
1867 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1868                                 interface_counter_t counter)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   static interface_counter_t default_counter = { 0, };
1872
1873   vec_validate_init_empty (vam->combined_interface_counters,
1874                            vnet_counter_type, NULL);
1875   vec_validate_init_empty (vam->combined_interface_counters
1876                            [vnet_counter_type], sw_if_index, default_counter);
1877   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1878 }
1879
1880 static void vl_api_vnet_interface_counters_t_handler
1881   (vl_api_vnet_interface_counters_t * mp)
1882 {
1883   /* not supported */
1884 }
1885
1886 static void vl_api_vnet_interface_counters_t_handler_json
1887   (vl_api_vnet_interface_counters_t * mp)
1888 {
1889   interface_counter_t counter;
1890   vlib_counter_t *v;
1891   u64 *v_packets;
1892   u64 packets;
1893   u32 count;
1894   u32 first_sw_if_index;
1895   int i;
1896
1897   count = ntohl (mp->count);
1898   first_sw_if_index = ntohl (mp->first_sw_if_index);
1899
1900   if (!mp->is_combined)
1901     {
1902       v_packets = (u64 *) & mp->data;
1903       for (i = 0; i < count; i++)
1904         {
1905           packets =
1906             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1907           set_simple_interface_counter (mp->vnet_counter_type,
1908                                         first_sw_if_index + i, packets);
1909           v_packets++;
1910         }
1911     }
1912   else
1913     {
1914       v = (vlib_counter_t *) & mp->data;
1915       for (i = 0; i < count; i++)
1916         {
1917           counter.packets =
1918             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1919           counter.bytes =
1920             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1921           set_combined_interface_counter (mp->vnet_counter_type,
1922                                           first_sw_if_index + i, counter);
1923           v++;
1924         }
1925     }
1926 }
1927
1928 static u32
1929 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   u32 i;
1933
1934   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1935     {
1936       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1937         {
1938           return i;
1939         }
1940     }
1941   return ~0;
1942 }
1943
1944 static u32
1945 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   u32 i;
1949
1950   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1951     {
1952       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1953         {
1954           return i;
1955         }
1956     }
1957   return ~0;
1958 }
1959
1960 static void vl_api_vnet_ip4_fib_counters_t_handler
1961   (vl_api_vnet_ip4_fib_counters_t * mp)
1962 {
1963   /* not supported */
1964 }
1965
1966 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1967   (vl_api_vnet_ip4_fib_counters_t * mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   vl_api_ip4_fib_counter_t *v;
1971   ip4_fib_counter_t *counter;
1972   struct in_addr ip4;
1973   u32 vrf_id;
1974   u32 vrf_index;
1975   u32 count;
1976   int i;
1977
1978   vrf_id = ntohl (mp->vrf_id);
1979   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1980   if (~0 == vrf_index)
1981     {
1982       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1983       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1984       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1985       vec_validate (vam->ip4_fib_counters, vrf_index);
1986       vam->ip4_fib_counters[vrf_index] = NULL;
1987     }
1988
1989   vec_free (vam->ip4_fib_counters[vrf_index]);
1990   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1991   count = ntohl (mp->count);
1992   for (i = 0; i < count; i++)
1993     {
1994       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1995       counter = &vam->ip4_fib_counters[vrf_index][i];
1996       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1997       counter->address = ip4;
1998       counter->address_length = v->address_length;
1999       counter->packets = clib_net_to_host_u64 (v->packets);
2000       counter->bytes = clib_net_to_host_u64 (v->bytes);
2001       v++;
2002     }
2003 }
2004
2005 static void vl_api_vnet_ip6_fib_counters_t_handler
2006   (vl_api_vnet_ip6_fib_counters_t * mp)
2007 {
2008   /* not supported */
2009 }
2010
2011 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2012   (vl_api_vnet_ip6_fib_counters_t * mp)
2013 {
2014   vat_main_t *vam = &vat_main;
2015   vl_api_ip6_fib_counter_t *v;
2016   ip6_fib_counter_t *counter;
2017   struct in6_addr ip6;
2018   u32 vrf_id;
2019   u32 vrf_index;
2020   u32 count;
2021   int i;
2022
2023   vrf_id = ntohl (mp->vrf_id);
2024   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2025   if (~0 == vrf_index)
2026     {
2027       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2028       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2029       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2030       vec_validate (vam->ip6_fib_counters, vrf_index);
2031       vam->ip6_fib_counters[vrf_index] = NULL;
2032     }
2033
2034   vec_free (vam->ip6_fib_counters[vrf_index]);
2035   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2036   count = ntohl (mp->count);
2037   for (i = 0; i < count; i++)
2038     {
2039       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2040       counter = &vam->ip6_fib_counters[vrf_index][i];
2041       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2042       counter->address = ip6;
2043       counter->address_length = v->address_length;
2044       counter->packets = clib_net_to_host_u64 (v->packets);
2045       counter->bytes = clib_net_to_host_u64 (v->bytes);
2046       v++;
2047     }
2048 }
2049
2050 static void vl_api_get_first_msg_id_reply_t_handler
2051   (vl_api_get_first_msg_id_reply_t * mp)
2052 {
2053   vat_main_t *vam = &vat_main;
2054   i32 retval = ntohl (mp->retval);
2055
2056   if (vam->async_mode)
2057     {
2058       vam->async_errors += (retval < 0);
2059     }
2060   else
2061     {
2062       vam->retval = retval;
2063       vam->result_ready = 1;
2064     }
2065   if (retval >= 0)
2066     {
2067       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2068     }
2069 }
2070
2071 static void vl_api_get_first_msg_id_reply_t_handler_json
2072   (vl_api_get_first_msg_id_reply_t * mp)
2073 {
2074   vat_main_t *vam = &vat_main;
2075   vat_json_node_t node;
2076
2077   vat_json_init_object (&node);
2078   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2079   vat_json_object_add_uint (&node, "first_msg_id",
2080                             (uint) ntohs (mp->first_msg_id));
2081
2082   vat_json_print (vam->ofp, &node);
2083   vat_json_free (&node);
2084
2085   vam->retval = ntohl (mp->retval);
2086   vam->result_ready = 1;
2087 }
2088
2089 static void vl_api_get_node_graph_reply_t_handler
2090   (vl_api_get_node_graph_reply_t * mp)
2091 {
2092   vat_main_t *vam = &vat_main;
2093   api_main_t *am = &api_main;
2094   i32 retval = ntohl (mp->retval);
2095   u8 *pvt_copy, *reply;
2096   void *oldheap;
2097   vlib_node_t *node;
2098   int i;
2099
2100   if (vam->async_mode)
2101     {
2102       vam->async_errors += (retval < 0);
2103     }
2104   else
2105     {
2106       vam->retval = retval;
2107       vam->result_ready = 1;
2108     }
2109
2110   /* "Should never happen..." */
2111   if (retval != 0)
2112     return;
2113
2114   reply = (u8 *) (mp->reply_in_shmem);
2115   pvt_copy = vec_dup (reply);
2116
2117   /* Toss the shared-memory original... */
2118   pthread_mutex_lock (&am->vlib_rp->mutex);
2119   oldheap = svm_push_data_heap (am->vlib_rp);
2120
2121   vec_free (reply);
2122
2123   svm_pop_heap (oldheap);
2124   pthread_mutex_unlock (&am->vlib_rp->mutex);
2125
2126   if (vam->graph_nodes)
2127     {
2128       hash_free (vam->graph_node_index_by_name);
2129
2130       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2131         {
2132           node = vam->graph_nodes[i];
2133           vec_free (node->name);
2134           vec_free (node->next_nodes);
2135           vec_free (node);
2136         }
2137       vec_free (vam->graph_nodes);
2138     }
2139
2140   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2141   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2142   vec_free (pvt_copy);
2143
2144   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2145     {
2146       node = vam->graph_nodes[i];
2147       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2148     }
2149 }
2150
2151 static void vl_api_get_node_graph_reply_t_handler_json
2152   (vl_api_get_node_graph_reply_t * mp)
2153 {
2154   vat_main_t *vam = &vat_main;
2155   api_main_t *am = &api_main;
2156   void *oldheap;
2157   vat_json_node_t node;
2158   u8 *reply;
2159
2160   /* $$$$ make this real? */
2161   vat_json_init_object (&node);
2162   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2163   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2164
2165   reply = (u8 *) (mp->reply_in_shmem);
2166
2167   /* Toss the shared-memory original... */
2168   pthread_mutex_lock (&am->vlib_rp->mutex);
2169   oldheap = svm_push_data_heap (am->vlib_rp);
2170
2171   vec_free (reply);
2172
2173   svm_pop_heap (oldheap);
2174   pthread_mutex_unlock (&am->vlib_rp->mutex);
2175
2176   vat_json_print (vam->ofp, &node);
2177   vat_json_free (&node);
2178
2179   vam->retval = ntohl (mp->retval);
2180   vam->result_ready = 1;
2181 }
2182
2183 static void
2184 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   u8 *s = 0;
2188
2189   if (mp->local)
2190     {
2191       s = format (s, "%=16d%=16d%=16d",
2192                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2193     }
2194   else
2195     {
2196       s = format (s, "%=16U%=16d%=16d",
2197                   mp->is_ipv6 ? format_ip6_address :
2198                   format_ip4_address,
2199                   mp->ip_address, mp->priority, mp->weight);
2200     }
2201
2202   print (vam->ofp, "%v", s);
2203   vec_free (s);
2204 }
2205
2206 static void
2207 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2208                                             mp)
2209 {
2210   vat_main_t *vam = &vat_main;
2211   vat_json_node_t *node = NULL;
2212   struct in6_addr ip6;
2213   struct in_addr ip4;
2214
2215   if (VAT_JSON_ARRAY != vam->json_tree.type)
2216     {
2217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2218       vat_json_init_array (&vam->json_tree);
2219     }
2220   node = vat_json_array_add (&vam->json_tree);
2221   vat_json_init_object (node);
2222
2223   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2224   vat_json_object_add_uint (node, "priority", mp->priority);
2225   vat_json_object_add_uint (node, "weight", mp->weight);
2226
2227   if (mp->local)
2228     vat_json_object_add_uint (node, "sw_if_index",
2229                               clib_net_to_host_u32 (mp->sw_if_index));
2230   else
2231     {
2232       if (mp->is_ipv6)
2233         {
2234           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2235           vat_json_object_add_ip6 (node, "address", ip6);
2236         }
2237       else
2238         {
2239           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2240           vat_json_object_add_ip4 (node, "address", ip4);
2241         }
2242     }
2243 }
2244
2245 static void
2246 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2247                                            mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   u8 *ls_name = 0;
2251
2252   ls_name = format (0, "%s", mp->ls_name);
2253
2254   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2255          ls_name);
2256   vec_free (ls_name);
2257 }
2258
2259 static void
2260   vl_api_lisp_locator_set_details_t_handler_json
2261   (vl_api_lisp_locator_set_details_t * mp)
2262 {
2263   vat_main_t *vam = &vat_main;
2264   vat_json_node_t *node = 0;
2265   u8 *ls_name = 0;
2266
2267   ls_name = format (0, "%s", mp->ls_name);
2268   vec_add1 (ls_name, 0);
2269
2270   if (VAT_JSON_ARRAY != vam->json_tree.type)
2271     {
2272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2273       vat_json_init_array (&vam->json_tree);
2274     }
2275   node = vat_json_array_add (&vam->json_tree);
2276
2277   vat_json_init_object (node);
2278   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2279   vat_json_object_add_uint (node, "ls_index",
2280                             clib_net_to_host_u32 (mp->ls_index));
2281   vec_free (ls_name);
2282 }
2283
2284 static u8 *
2285 format_lisp_flat_eid (u8 * s, va_list * args)
2286 {
2287   u32 type = va_arg (*args, u32);
2288   u8 *eid = va_arg (*args, u8 *);
2289   u32 eid_len = va_arg (*args, u32);
2290
2291   switch (type)
2292     {
2293     case 0:
2294       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2295     case 1:
2296       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2297     case 2:
2298       return format (s, "%U", format_ethernet_address, eid);
2299     }
2300   return 0;
2301 }
2302
2303 static u8 *
2304 format_lisp_eid_vat (u8 * s, va_list * args)
2305 {
2306   u32 type = va_arg (*args, u32);
2307   u8 *eid = va_arg (*args, u8 *);
2308   u32 eid_len = va_arg (*args, u32);
2309   u8 *seid = va_arg (*args, u8 *);
2310   u32 seid_len = va_arg (*args, u32);
2311   u32 is_src_dst = va_arg (*args, u32);
2312
2313   if (is_src_dst)
2314     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2315
2316   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2317
2318   return s;
2319 }
2320
2321 static void
2322 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2323 {
2324   vat_main_t *vam = &vat_main;
2325   u8 *s = 0, *eid = 0;
2326
2327   if (~0 == mp->locator_set_index)
2328     s = format (0, "action: %d", mp->action);
2329   else
2330     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2331
2332   eid = format (0, "%U", format_lisp_eid_vat,
2333                 mp->eid_type,
2334                 mp->eid,
2335                 mp->eid_prefix_len,
2336                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2337   vec_add1 (eid, 0);
2338
2339   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2340          clib_net_to_host_u32 (mp->vni),
2341          eid,
2342          mp->is_local ? "local" : "remote",
2343          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2344          clib_net_to_host_u16 (mp->key_id), mp->key);
2345
2346   vec_free (s);
2347   vec_free (eid);
2348 }
2349
2350 static void
2351 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2352                                               * mp)
2353 {
2354   vat_main_t *vam = &vat_main;
2355   vat_json_node_t *node = 0;
2356   u8 *eid = 0;
2357
2358   if (VAT_JSON_ARRAY != vam->json_tree.type)
2359     {
2360       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2361       vat_json_init_array (&vam->json_tree);
2362     }
2363   node = vat_json_array_add (&vam->json_tree);
2364
2365   vat_json_init_object (node);
2366   if (~0 == mp->locator_set_index)
2367     vat_json_object_add_uint (node, "action", mp->action);
2368   else
2369     vat_json_object_add_uint (node, "locator_set_index",
2370                               clib_net_to_host_u32 (mp->locator_set_index));
2371
2372   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2373   eid = format (0, "%U", format_lisp_eid_vat,
2374                 mp->eid_type,
2375                 mp->eid,
2376                 mp->eid_prefix_len,
2377                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2378   vec_add1 (eid, 0);
2379   vat_json_object_add_string_copy (node, "eid", eid);
2380   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2381   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2382   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2383
2384   if (mp->key_id)
2385     {
2386       vat_json_object_add_uint (node, "key_id",
2387                                 clib_net_to_host_u16 (mp->key_id));
2388       vat_json_object_add_string_copy (node, "key", mp->key);
2389     }
2390   vec_free (eid);
2391 }
2392
2393 static void
2394   vl_api_lisp_eid_table_map_details_t_handler
2395   (vl_api_lisp_eid_table_map_details_t * mp)
2396 {
2397   vat_main_t *vam = &vat_main;
2398
2399   u8 *line = format (0, "%=10d%=10d",
2400                      clib_net_to_host_u32 (mp->vni),
2401                      clib_net_to_host_u32 (mp->dp_table));
2402   print (vam->ofp, "%v", line);
2403   vec_free (line);
2404 }
2405
2406 static void
2407   vl_api_lisp_eid_table_map_details_t_handler_json
2408   (vl_api_lisp_eid_table_map_details_t * mp)
2409 {
2410   vat_main_t *vam = &vat_main;
2411   vat_json_node_t *node = NULL;
2412
2413   if (VAT_JSON_ARRAY != vam->json_tree.type)
2414     {
2415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2416       vat_json_init_array (&vam->json_tree);
2417     }
2418   node = vat_json_array_add (&vam->json_tree);
2419   vat_json_init_object (node);
2420   vat_json_object_add_uint (node, "dp_table",
2421                             clib_net_to_host_u32 (mp->dp_table));
2422   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2423 }
2424
2425 static void
2426   vl_api_lisp_eid_table_vni_details_t_handler
2427   (vl_api_lisp_eid_table_vni_details_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430
2431   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2432   print (vam->ofp, "%v", line);
2433   vec_free (line);
2434 }
2435
2436 static void
2437   vl_api_lisp_eid_table_vni_details_t_handler_json
2438   (vl_api_lisp_eid_table_vni_details_t * mp)
2439 {
2440   vat_main_t *vam = &vat_main;
2441   vat_json_node_t *node = NULL;
2442
2443   if (VAT_JSON_ARRAY != vam->json_tree.type)
2444     {
2445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2446       vat_json_init_array (&vam->json_tree);
2447     }
2448   node = vat_json_array_add (&vam->json_tree);
2449   vat_json_init_object (node);
2450   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2451 }
2452
2453 static u8 *
2454 format_decap_next (u8 * s, va_list * args)
2455 {
2456   u32 next_index = va_arg (*args, u32);
2457
2458   switch (next_index)
2459     {
2460     case LISP_GPE_INPUT_NEXT_DROP:
2461       return format (s, "drop");
2462     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2463       return format (s, "ip4");
2464     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2465       return format (s, "ip6");
2466     default:
2467       return format (s, "unknown %d", next_index);
2468     }
2469   return s;
2470 }
2471
2472 static void
2473 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2474                                           mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477   u8 *iid_str;
2478   u8 *flag_str = NULL;
2479
2480   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2481
2482 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2483   foreach_lisp_gpe_flag_bit;
2484 #undef _
2485
2486   print (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2487          "%=16d%=16d%=16sd=16d%=16s%=16s",
2488          mp->tunnels,
2489          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2490          mp->source_ip,
2491          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2492          mp->destination_ip,
2493          ntohl (mp->encap_fib_id),
2494          ntohl (mp->decap_fib_id),
2495          format_decap_next, ntohl (mp->dcap_next),
2496          mp->ver_res >> 6,
2497          flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2498
2499   vec_free (iid_str);
2500 }
2501
2502 static void
2503   vl_api_lisp_gpe_tunnel_details_t_handler_json
2504   (vl_api_lisp_gpe_tunnel_details_t * mp)
2505 {
2506   vat_main_t *vam = &vat_main;
2507   vat_json_node_t *node = NULL;
2508   struct in6_addr ip6;
2509   struct in_addr ip4;
2510   u8 *next_decap_str;
2511
2512   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2513
2514   if (VAT_JSON_ARRAY != vam->json_tree.type)
2515     {
2516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2517       vat_json_init_array (&vam->json_tree);
2518     }
2519   node = vat_json_array_add (&vam->json_tree);
2520
2521   vat_json_init_object (node);
2522   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2523   if (mp->is_ipv6)
2524     {
2525       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2526       vat_json_object_add_ip6 (node, "source address", ip6);
2527       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2528       vat_json_object_add_ip6 (node, "destination address", ip6);
2529     }
2530   else
2531     {
2532       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2533       vat_json_object_add_ip4 (node, "source address", ip4);
2534       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2535       vat_json_object_add_ip4 (node, "destination address", ip4);
2536     }
2537   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2538   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2539   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2540   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2541   vat_json_object_add_uint (node, "flags", mp->flags);
2542   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2543   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2544   vat_json_object_add_uint (node, "res", mp->res);
2545   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2546
2547   vec_free (next_decap_str);
2548 }
2549
2550 static void
2551   vl_api_show_lisp_map_register_state_reply_t_handler
2552   (vl_api_show_lisp_map_register_state_reply_t * mp)
2553 {
2554   vat_main_t *vam = &vat_main;
2555   int retval = clib_net_to_host_u32 (mp->retval);
2556
2557   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2558
2559   vam->retval = retval;
2560   vam->result_ready = 1;
2561 }
2562
2563 static void
2564   vl_api_show_lisp_map_register_state_reply_t_handler_json
2565   (vl_api_show_lisp_map_register_state_reply_t * mp)
2566 {
2567   vat_main_t *vam = &vat_main;
2568   vat_json_node_t _node, *node = &_node;
2569   int retval = clib_net_to_host_u32 (mp->retval);
2570
2571   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2572
2573   vat_json_init_object (node);
2574   vat_json_object_add_string_copy (node, "state", s);
2575
2576   vat_json_print (vam->ofp, node);
2577   vat_json_free (node);
2578
2579   vam->retval = retval;
2580   vam->result_ready = 1;
2581   vec_free (s);
2582 }
2583
2584 static void
2585   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2586   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   int retval = clib_net_to_host_u32 (mp->retval);
2590
2591   if (retval)
2592     goto end;
2593
2594   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2595 end:
2596   vam->retval = retval;
2597   vam->result_ready = 1;
2598 }
2599
2600 static void
2601   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2602   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2603 {
2604   vat_main_t *vam = &vat_main;
2605   vat_json_node_t _node, *node = &_node;
2606   int retval = clib_net_to_host_u32 (mp->retval);
2607
2608   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2609   vat_json_init_object (node);
2610   vat_json_object_add_string_copy (node, "state", s);
2611
2612   vat_json_print (vam->ofp, node);
2613   vat_json_free (node);
2614
2615   vam->retval = retval;
2616   vam->result_ready = 1;
2617   vec_free (s);
2618 }
2619
2620 static void
2621   vl_api_lisp_adjacencies_get_reply_t_handler
2622   (vl_api_lisp_adjacencies_get_reply_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
2625   u32 i, n;
2626   int retval = clib_net_to_host_u32 (mp->retval);
2627   vl_api_lisp_adjacency_t *a;
2628
2629   if (retval)
2630     goto end;
2631
2632   n = clib_net_to_host_u32 (mp->count);
2633
2634   for (i = 0; i < n; i++)
2635     {
2636       a = &mp->adjacencies[i];
2637       print (vam->ofp, "%U %40U",
2638              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2639              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2640     }
2641
2642 end:
2643   vam->retval = retval;
2644   vam->result_ready = 1;
2645 }
2646
2647 static void
2648   vl_api_lisp_adjacencies_get_reply_t_handler_json
2649   (vl_api_lisp_adjacencies_get_reply_t * mp)
2650 {
2651   u8 *s = 0;
2652   vat_main_t *vam = &vat_main;
2653   vat_json_node_t *e = 0, root;
2654   u32 i, n;
2655   int retval = clib_net_to_host_u32 (mp->retval);
2656   vl_api_lisp_adjacency_t *a;
2657
2658   if (retval)
2659     goto end;
2660
2661   n = clib_net_to_host_u32 (mp->count);
2662   vat_json_init_array (&root);
2663
2664   for (i = 0; i < n; i++)
2665     {
2666       e = vat_json_array_add (&root);
2667       a = &mp->adjacencies[i];
2668
2669       vat_json_init_object (e);
2670       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2671                   a->leid_prefix_len);
2672       vec_add1 (s, 0);
2673       vat_json_object_add_string_copy (e, "leid", s);
2674       vec_free (s);
2675
2676       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2677                   a->reid_prefix_len);
2678       vec_add1 (s, 0);
2679       vat_json_object_add_string_copy (e, "reid", s);
2680       vec_free (s);
2681     }
2682
2683   vat_json_print (vam->ofp, &root);
2684   vat_json_free (&root);
2685
2686 end:
2687   vam->retval = retval;
2688   vam->result_ready = 1;
2689 }
2690
2691 static void
2692 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2693                                           * mp)
2694 {
2695   vat_main_t *vam = &vat_main;
2696
2697   print (vam->ofp, "%=20U",
2698          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2699          mp->ip_address);
2700 }
2701
2702 static void
2703   vl_api_lisp_map_server_details_t_handler_json
2704   (vl_api_lisp_map_server_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t *node = NULL;
2708   struct in6_addr ip6;
2709   struct in_addr ip4;
2710
2711   if (VAT_JSON_ARRAY != vam->json_tree.type)
2712     {
2713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2714       vat_json_init_array (&vam->json_tree);
2715     }
2716   node = vat_json_array_add (&vam->json_tree);
2717
2718   vat_json_init_object (node);
2719   if (mp->is_ipv6)
2720     {
2721       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2722       vat_json_object_add_ip6 (node, "map-server", ip6);
2723     }
2724   else
2725     {
2726       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2727       vat_json_object_add_ip4 (node, "map-server", ip4);
2728     }
2729 }
2730
2731 static void
2732 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2733                                             * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736
2737   print (vam->ofp, "%=20U",
2738          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2739          mp->ip_address);
2740 }
2741
2742 static void
2743   vl_api_lisp_map_resolver_details_t_handler_json
2744   (vl_api_lisp_map_resolver_details_t * mp)
2745 {
2746   vat_main_t *vam = &vat_main;
2747   vat_json_node_t *node = NULL;
2748   struct in6_addr ip6;
2749   struct in_addr ip4;
2750
2751   if (VAT_JSON_ARRAY != vam->json_tree.type)
2752     {
2753       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2754       vat_json_init_array (&vam->json_tree);
2755     }
2756   node = vat_json_array_add (&vam->json_tree);
2757
2758   vat_json_init_object (node);
2759   if (mp->is_ipv6)
2760     {
2761       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2762       vat_json_object_add_ip6 (node, "map resolver", ip6);
2763     }
2764   else
2765     {
2766       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2767       vat_json_object_add_ip4 (node, "map resolver", ip4);
2768     }
2769 }
2770
2771 static void
2772   vl_api_show_lisp_status_reply_t_handler
2773   (vl_api_show_lisp_status_reply_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   i32 retval = ntohl (mp->retval);
2777
2778   if (0 <= retval)
2779     {
2780       print (vam->ofp, "feature: %s\ngpe: %s",
2781              mp->feature_status ? "enabled" : "disabled",
2782              mp->gpe_status ? "enabled" : "disabled");
2783     }
2784
2785   vam->retval = retval;
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790   vl_api_show_lisp_status_reply_t_handler_json
2791   (vl_api_show_lisp_status_reply_t * mp)
2792 {
2793   vat_main_t *vam = &vat_main;
2794   vat_json_node_t node;
2795   u8 *gpe_status = NULL;
2796   u8 *feature_status = NULL;
2797
2798   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2799   feature_status = format (0, "%s",
2800                            mp->feature_status ? "enabled" : "disabled");
2801   vec_add1 (gpe_status, 0);
2802   vec_add1 (feature_status, 0);
2803
2804   vat_json_init_object (&node);
2805   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2806   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2807
2808   vec_free (gpe_status);
2809   vec_free (feature_status);
2810
2811   vat_json_print (vam->ofp, &node);
2812   vat_json_free (&node);
2813
2814   vam->retval = ntohl (mp->retval);
2815   vam->result_ready = 1;
2816 }
2817
2818 static void
2819   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2820   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2821 {
2822   vat_main_t *vam = &vat_main;
2823   i32 retval = ntohl (mp->retval);
2824
2825   if (retval >= 0)
2826     {
2827       print (vam->ofp, "%=20s", mp->locator_set_name);
2828     }
2829
2830   vam->retval = retval;
2831   vam->result_ready = 1;
2832 }
2833
2834 static void
2835   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2836   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   vat_json_node_t *node = NULL;
2840
2841   if (VAT_JSON_ARRAY != vam->json_tree.type)
2842     {
2843       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2844       vat_json_init_array (&vam->json_tree);
2845     }
2846   node = vat_json_array_add (&vam->json_tree);
2847
2848   vat_json_init_object (node);
2849   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2850
2851   vat_json_print (vam->ofp, node);
2852   vat_json_free (node);
2853
2854   vam->retval = ntohl (mp->retval);
2855   vam->result_ready = 1;
2856 }
2857
2858 static u8 *
2859 format_lisp_map_request_mode (u8 * s, va_list * args)
2860 {
2861   u32 mode = va_arg (*args, u32);
2862
2863   switch (mode)
2864     {
2865     case 0:
2866       return format (0, "dst-only");
2867     case 1:
2868       return format (0, "src-dst");
2869     }
2870   return 0;
2871 }
2872
2873 static void
2874   vl_api_show_lisp_map_request_mode_reply_t_handler
2875   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878   i32 retval = ntohl (mp->retval);
2879
2880   if (0 <= retval)
2881     {
2882       u32 mode = mp->mode;
2883       print (vam->ofp, "map_request_mode: %U",
2884              format_lisp_map_request_mode, mode);
2885     }
2886
2887   vam->retval = retval;
2888   vam->result_ready = 1;
2889 }
2890
2891 static void
2892   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2893   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   vat_json_node_t node;
2897   u8 *s = 0;
2898   u32 mode;
2899
2900   mode = mp->mode;
2901   s = format (0, "%U", format_lisp_map_request_mode, mode);
2902   vec_add1 (s, 0);
2903
2904   vat_json_init_object (&node);
2905   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2906   vat_json_print (vam->ofp, &node);
2907   vat_json_free (&node);
2908
2909   vec_free (s);
2910   vam->retval = ntohl (mp->retval);
2911   vam->result_ready = 1;
2912 }
2913
2914 static void
2915 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2916 {
2917   vat_main_t *vam = &vat_main;
2918   i32 retval = ntohl (mp->retval);
2919
2920   if (0 <= retval)
2921     {
2922       print (vam->ofp, "%-20s%-16s",
2923              mp->status ? "enabled" : "disabled",
2924              mp->status ? (char *) mp->locator_set_name : "");
2925     }
2926
2927   vam->retval = retval;
2928   vam->result_ready = 1;
2929 }
2930
2931 static void
2932 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2933                                             mp)
2934 {
2935   vat_main_t *vam = &vat_main;
2936   vat_json_node_t node;
2937   u8 *status = 0;
2938
2939   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2940   vec_add1 (status, 0);
2941
2942   vat_json_init_object (&node);
2943   vat_json_object_add_string_copy (&node, "status", status);
2944   if (mp->status)
2945     {
2946       vat_json_object_add_string_copy (&node, "locator_set",
2947                                        mp->locator_set_name);
2948     }
2949
2950   vec_free (status);
2951
2952   vat_json_print (vam->ofp, &node);
2953   vat_json_free (&node);
2954
2955   vam->retval = ntohl (mp->retval);
2956   vam->result_ready = 1;
2957 }
2958
2959 static u8 *
2960 format_policer_type (u8 * s, va_list * va)
2961 {
2962   u32 i = va_arg (*va, u32);
2963
2964   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2965     s = format (s, "1r2c");
2966   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2967     s = format (s, "1r3c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2969     s = format (s, "2r3c-2698");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2971     s = format (s, "2r3c-4115");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2973     s = format (s, "2r3c-mef5cf1");
2974   else
2975     s = format (s, "ILLEGAL");
2976   return s;
2977 }
2978
2979 static u8 *
2980 format_policer_rate_type (u8 * s, va_list * va)
2981 {
2982   u32 i = va_arg (*va, u32);
2983
2984   if (i == SSE2_QOS_RATE_KBPS)
2985     s = format (s, "kbps");
2986   else if (i == SSE2_QOS_RATE_PPS)
2987     s = format (s, "pps");
2988   else
2989     s = format (s, "ILLEGAL");
2990   return s;
2991 }
2992
2993 static u8 *
2994 format_policer_round_type (u8 * s, va_list * va)
2995 {
2996   u32 i = va_arg (*va, u32);
2997
2998   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2999     s = format (s, "closest");
3000   else if (i == SSE2_QOS_ROUND_TO_UP)
3001     s = format (s, "up");
3002   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3003     s = format (s, "down");
3004   else
3005     s = format (s, "ILLEGAL");
3006   return s;
3007 }
3008
3009 static u8 *
3010 format_policer_action_type (u8 * s, va_list * va)
3011 {
3012   u32 i = va_arg (*va, u32);
3013
3014   if (i == SSE2_QOS_ACTION_DROP)
3015     s = format (s, "drop");
3016   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3017     s = format (s, "transmit");
3018   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3019     s = format (s, "mark-and-transmit");
3020   else
3021     s = format (s, "ILLEGAL");
3022   return s;
3023 }
3024
3025 static u8 *
3026 format_dscp (u8 * s, va_list * va)
3027 {
3028   u32 i = va_arg (*va, u32);
3029   char *t = 0;
3030
3031   switch (i)
3032     {
3033 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3034       foreach_vnet_dscp
3035 #undef _
3036     default:
3037       return format (s, "ILLEGAL");
3038     }
3039   s = format (s, "%s", t);
3040   return s;
3041 }
3042
3043 static void
3044 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3045 {
3046   vat_main_t *vam = &vat_main;
3047   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3048
3049   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3050     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3051   else
3052     conform_dscp_str = format (0, "");
3053
3054   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3055     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3056   else
3057     exceed_dscp_str = format (0, "");
3058
3059   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3060     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3061   else
3062     violate_dscp_str = format (0, "");
3063
3064   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3065          "rate type %U, round type %U, %s rate, %s color-aware, "
3066          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3067          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3068          "conform action %U%s, exceed action %U%s, violate action %U%s",
3069          mp->name,
3070          format_policer_type, mp->type,
3071          ntohl (mp->cir),
3072          ntohl (mp->eir),
3073          clib_net_to_host_u64 (mp->cb),
3074          clib_net_to_host_u64 (mp->eb),
3075          format_policer_rate_type, mp->rate_type,
3076          format_policer_round_type, mp->round_type,
3077          mp->single_rate ? "single" : "dual",
3078          mp->color_aware ? "is" : "not",
3079          ntohl (mp->cir_tokens_per_period),
3080          ntohl (mp->pir_tokens_per_period),
3081          ntohl (mp->scale),
3082          ntohl (mp->current_limit),
3083          ntohl (mp->current_bucket),
3084          ntohl (mp->extended_limit),
3085          ntohl (mp->extended_bucket),
3086          clib_net_to_host_u64 (mp->last_update_time),
3087          format_policer_action_type, mp->conform_action_type,
3088          conform_dscp_str,
3089          format_policer_action_type, mp->exceed_action_type,
3090          exceed_dscp_str,
3091          format_policer_action_type, mp->violate_action_type,
3092          violate_dscp_str);
3093
3094   vec_free (conform_dscp_str);
3095   vec_free (exceed_dscp_str);
3096   vec_free (violate_dscp_str);
3097 }
3098
3099 static void vl_api_policer_details_t_handler_json
3100   (vl_api_policer_details_t * mp)
3101 {
3102   vat_main_t *vam = &vat_main;
3103   vat_json_node_t *node;
3104   u8 *rate_type_str, *round_type_str, *type_str;
3105   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3106
3107   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3108   round_type_str =
3109     format (0, "%U", format_policer_round_type, mp->round_type);
3110   type_str = format (0, "%U", format_policer_type, mp->type);
3111   conform_action_str = format (0, "%U", format_policer_action_type,
3112                                mp->conform_action_type);
3113   exceed_action_str = format (0, "%U", format_policer_action_type,
3114                               mp->exceed_action_type);
3115   violate_action_str = format (0, "%U", format_policer_action_type,
3116                                mp->violate_action_type);
3117
3118   if (VAT_JSON_ARRAY != vam->json_tree.type)
3119     {
3120       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3121       vat_json_init_array (&vam->json_tree);
3122     }
3123   node = vat_json_array_add (&vam->json_tree);
3124
3125   vat_json_init_object (node);
3126   vat_json_object_add_string_copy (node, "name", mp->name);
3127   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3128   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3129   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3130   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3131   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3132   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3133   vat_json_object_add_string_copy (node, "type", type_str);
3134   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3135   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3136   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3137   vat_json_object_add_uint (node, "cir_tokens_per_period",
3138                             ntohl (mp->cir_tokens_per_period));
3139   vat_json_object_add_uint (node, "eir_tokens_per_period",
3140                             ntohl (mp->pir_tokens_per_period));
3141   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3142   vat_json_object_add_uint (node, "current_bucket",
3143                             ntohl (mp->current_bucket));
3144   vat_json_object_add_uint (node, "extended_limit",
3145                             ntohl (mp->extended_limit));
3146   vat_json_object_add_uint (node, "extended_bucket",
3147                             ntohl (mp->extended_bucket));
3148   vat_json_object_add_uint (node, "last_update_time",
3149                             ntohl (mp->last_update_time));
3150   vat_json_object_add_string_copy (node, "conform_action",
3151                                    conform_action_str);
3152   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3153     {
3154       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3155       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3156       vec_free (dscp_str);
3157     }
3158   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3159   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3160     {
3161       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3162       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3163       vec_free (dscp_str);
3164     }
3165   vat_json_object_add_string_copy (node, "violate_action",
3166                                    violate_action_str);
3167   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3168     {
3169       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3170       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3171       vec_free (dscp_str);
3172     }
3173
3174   vec_free (rate_type_str);
3175   vec_free (round_type_str);
3176   vec_free (type_str);
3177   vec_free (conform_action_str);
3178   vec_free (exceed_action_str);
3179   vec_free (violate_action_str);
3180 }
3181
3182 static void
3183 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3184                                            mp)
3185 {
3186   vat_main_t *vam = &vat_main;
3187   int i, count = ntohl (mp->count);
3188
3189   if (count > 0)
3190     print (vam->ofp, "classify table ids (%d) : ", count);
3191   for (i = 0; i < count; i++)
3192     {
3193       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3194       print (vam->ofp, (i < count - 1) ? "," : "");
3195     }
3196   vam->retval = ntohl (mp->retval);
3197   vam->result_ready = 1;
3198 }
3199
3200 static void
3201   vl_api_classify_table_ids_reply_t_handler_json
3202   (vl_api_classify_table_ids_reply_t * mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205   int i, count = ntohl (mp->count);
3206
3207   if (count > 0)
3208     {
3209       vat_json_node_t node;
3210
3211       vat_json_init_object (&node);
3212       for (i = 0; i < count; i++)
3213         {
3214           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3215         }
3216       vat_json_print (vam->ofp, &node);
3217       vat_json_free (&node);
3218     }
3219   vam->retval = ntohl (mp->retval);
3220   vam->result_ready = 1;
3221 }
3222
3223 static void
3224   vl_api_classify_table_by_interface_reply_t_handler
3225   (vl_api_classify_table_by_interface_reply_t * mp)
3226 {
3227   vat_main_t *vam = &vat_main;
3228   u32 table_id;
3229
3230   table_id = ntohl (mp->l2_table_id);
3231   if (table_id != ~0)
3232     print (vam->ofp, "l2 table id : %d", table_id);
3233   else
3234     print (vam->ofp, "l2 table id : No input ACL tables configured");
3235   table_id = ntohl (mp->ip4_table_id);
3236   if (table_id != ~0)
3237     print (vam->ofp, "ip4 table id : %d", table_id);
3238   else
3239     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3240   table_id = ntohl (mp->ip6_table_id);
3241   if (table_id != ~0)
3242     print (vam->ofp, "ip6 table id : %d", table_id);
3243   else
3244     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3245   vam->retval = ntohl (mp->retval);
3246   vam->result_ready = 1;
3247 }
3248
3249 static void
3250   vl_api_classify_table_by_interface_reply_t_handler_json
3251   (vl_api_classify_table_by_interface_reply_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   vat_json_node_t node;
3255
3256   vat_json_init_object (&node);
3257
3258   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3259   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3260   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3261
3262   vat_json_print (vam->ofp, &node);
3263   vat_json_free (&node);
3264
3265   vam->retval = ntohl (mp->retval);
3266   vam->result_ready = 1;
3267 }
3268
3269 static void vl_api_policer_add_del_reply_t_handler
3270   (vl_api_policer_add_del_reply_t * mp)
3271 {
3272   vat_main_t *vam = &vat_main;
3273   i32 retval = ntohl (mp->retval);
3274   if (vam->async_mode)
3275     {
3276       vam->async_errors += (retval < 0);
3277     }
3278   else
3279     {
3280       vam->retval = retval;
3281       vam->result_ready = 1;
3282       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3283         /*
3284          * Note: this is just barely thread-safe, depends on
3285          * the main thread spinning waiting for an answer...
3286          */
3287         errmsg ("policer index %d", ntohl (mp->policer_index));
3288     }
3289 }
3290
3291 static void vl_api_policer_add_del_reply_t_handler_json
3292   (vl_api_policer_add_del_reply_t * mp)
3293 {
3294   vat_main_t *vam = &vat_main;
3295   vat_json_node_t node;
3296
3297   vat_json_init_object (&node);
3298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3299   vat_json_object_add_uint (&node, "policer_index",
3300                             ntohl (mp->policer_index));
3301
3302   vat_json_print (vam->ofp, &node);
3303   vat_json_free (&node);
3304
3305   vam->retval = ntohl (mp->retval);
3306   vam->result_ready = 1;
3307 }
3308
3309 /* Format hex dump. */
3310 u8 *
3311 format_hex_bytes (u8 * s, va_list * va)
3312 {
3313   u8 *bytes = va_arg (*va, u8 *);
3314   int n_bytes = va_arg (*va, int);
3315   uword i;
3316
3317   /* Print short or long form depending on byte count. */
3318   uword short_form = n_bytes <= 32;
3319   uword indent = format_get_indent (s);
3320
3321   if (n_bytes == 0)
3322     return s;
3323
3324   for (i = 0; i < n_bytes; i++)
3325     {
3326       if (!short_form && (i % 32) == 0)
3327         s = format (s, "%08x: ", i);
3328       s = format (s, "%02x", bytes[i]);
3329       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3330         s = format (s, "\n%U", format_white_space, indent);
3331     }
3332
3333   return s;
3334 }
3335
3336 static void
3337 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3338                                             * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   i32 retval = ntohl (mp->retval);
3342   if (retval == 0)
3343     {
3344       print (vam->ofp, "classify table info :");
3345       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3346              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3347              ntohl (mp->miss_next_index));
3348       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3349              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3350              ntohl (mp->match_n_vectors));
3351       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3352              ntohl (mp->mask_length));
3353     }
3354   vam->retval = retval;
3355   vam->result_ready = 1;
3356 }
3357
3358 static void
3359   vl_api_classify_table_info_reply_t_handler_json
3360   (vl_api_classify_table_info_reply_t * mp)
3361 {
3362   vat_main_t *vam = &vat_main;
3363   vat_json_node_t node;
3364
3365   i32 retval = ntohl (mp->retval);
3366   if (retval == 0)
3367     {
3368       vat_json_init_object (&node);
3369
3370       vat_json_object_add_int (&node, "sessions",
3371                                ntohl (mp->active_sessions));
3372       vat_json_object_add_int (&node, "nexttbl",
3373                                ntohl (mp->next_table_index));
3374       vat_json_object_add_int (&node, "nextnode",
3375                                ntohl (mp->miss_next_index));
3376       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3377       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3378       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3379       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3380                       ntohl (mp->mask_length), 0);
3381       vat_json_object_add_string_copy (&node, "mask", s);
3382
3383       vat_json_print (vam->ofp, &node);
3384       vat_json_free (&node);
3385     }
3386   vam->retval = ntohl (mp->retval);
3387   vam->result_ready = 1;
3388 }
3389
3390 static void
3391 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3392                                            mp)
3393 {
3394   vat_main_t *vam = &vat_main;
3395
3396   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3397          ntohl (mp->hit_next_index), ntohl (mp->advance),
3398          ntohl (mp->opaque_index));
3399   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3400          ntohl (mp->match_length));
3401 }
3402
3403 static void
3404   vl_api_classify_session_details_t_handler_json
3405   (vl_api_classify_session_details_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   vat_json_node_t *node = NULL;
3409
3410   if (VAT_JSON_ARRAY != vam->json_tree.type)
3411     {
3412       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3413       vat_json_init_array (&vam->json_tree);
3414     }
3415   node = vat_json_array_add (&vam->json_tree);
3416
3417   vat_json_init_object (node);
3418   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3419   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3420   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3421   u8 *s =
3422     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3423             0);
3424   vat_json_object_add_string_copy (node, "match", s);
3425 }
3426
3427 static void vl_api_pg_create_interface_reply_t_handler
3428   (vl_api_pg_create_interface_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431
3432   vam->retval = ntohl (mp->retval);
3433   vam->result_ready = 1;
3434 }
3435
3436 static void vl_api_pg_create_interface_reply_t_handler_json
3437   (vl_api_pg_create_interface_reply_t * mp)
3438 {
3439   vat_main_t *vam = &vat_main;
3440   vat_json_node_t node;
3441
3442   i32 retval = ntohl (mp->retval);
3443   if (retval == 0)
3444     {
3445       vat_json_init_object (&node);
3446
3447       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3448
3449       vat_json_print (vam->ofp, &node);
3450       vat_json_free (&node);
3451     }
3452   vam->retval = ntohl (mp->retval);
3453   vam->result_ready = 1;
3454 }
3455
3456 static void vl_api_policer_classify_details_t_handler
3457   (vl_api_policer_classify_details_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460
3461   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3462          ntohl (mp->table_index));
3463 }
3464
3465 static void vl_api_policer_classify_details_t_handler_json
3466   (vl_api_policer_classify_details_t * mp)
3467 {
3468   vat_main_t *vam = &vat_main;
3469   vat_json_node_t *node;
3470
3471   if (VAT_JSON_ARRAY != vam->json_tree.type)
3472     {
3473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3474       vat_json_init_array (&vam->json_tree);
3475     }
3476   node = vat_json_array_add (&vam->json_tree);
3477
3478   vat_json_init_object (node);
3479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3480   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3481 }
3482
3483 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3484   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3485 {
3486   vat_main_t *vam = &vat_main;
3487   i32 retval = ntohl (mp->retval);
3488   if (vam->async_mode)
3489     {
3490       vam->async_errors += (retval < 0);
3491     }
3492   else
3493     {
3494       vam->retval = retval;
3495       vam->sw_if_index = ntohl (mp->sw_if_index);
3496       vam->result_ready = 1;
3497     }
3498 }
3499
3500 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3501   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3502 {
3503   vat_main_t *vam = &vat_main;
3504   vat_json_node_t node;
3505
3506   vat_json_init_object (&node);
3507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3509
3510   vat_json_print (vam->ofp, &node);
3511   vat_json_free (&node);
3512
3513   vam->retval = ntohl (mp->retval);
3514   vam->result_ready = 1;
3515 }
3516
3517 static void vl_api_flow_classify_details_t_handler
3518   (vl_api_flow_classify_details_t * mp)
3519 {
3520   vat_main_t *vam = &vat_main;
3521
3522   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3523          ntohl (mp->table_index));
3524 }
3525
3526 static void vl_api_flow_classify_details_t_handler_json
3527   (vl_api_flow_classify_details_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530   vat_json_node_t *node;
3531
3532   if (VAT_JSON_ARRAY != vam->json_tree.type)
3533     {
3534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3535       vat_json_init_array (&vam->json_tree);
3536     }
3537   node = vat_json_array_add (&vam->json_tree);
3538
3539   vat_json_init_object (node);
3540   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3541   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3542 }
3543
3544
3545
3546 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3547 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3548 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3550 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3551 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3552
3553 /*
3554  * Generate boilerplate reply handlers, which
3555  * dig the return value out of the xxx_reply_t API message,
3556  * stick it into vam->retval, and set vam->result_ready
3557  *
3558  * Could also do this by pointing N message decode slots at
3559  * a single function, but that could break in subtle ways.
3560  */
3561
3562 #define foreach_standard_reply_retval_handler           \
3563 _(sw_interface_set_flags_reply)                         \
3564 _(sw_interface_add_del_address_reply)                   \
3565 _(sw_interface_set_table_reply)                         \
3566 _(sw_interface_set_mpls_enable_reply)                   \
3567 _(sw_interface_set_vpath_reply)                         \
3568 _(sw_interface_set_vxlan_bypass_reply)                  \
3569 _(sw_interface_set_l2_bridge_reply)                     \
3570 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3571 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3572 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3573 _(bridge_domain_add_del_reply)                          \
3574 _(sw_interface_set_l2_xconnect_reply)                   \
3575 _(l2fib_add_del_reply)                                  \
3576 _(ip_add_del_route_reply)                               \
3577 _(mpls_route_add_del_reply)                             \
3578 _(mpls_ip_bind_unbind_reply)                            \
3579 _(proxy_arp_add_del_reply)                              \
3580 _(proxy_arp_intfc_enable_disable_reply)                 \
3581 _(sw_interface_set_unnumbered_reply)                    \
3582 _(ip_neighbor_add_del_reply)                            \
3583 _(reset_vrf_reply)                                      \
3584 _(oam_add_del_reply)                                    \
3585 _(reset_fib_reply)                                      \
3586 _(dhcp_proxy_config_reply)                              \
3587 _(dhcp_proxy_config_2_reply)                            \
3588 _(dhcp_proxy_set_vss_reply)                             \
3589 _(dhcp_client_config_reply)                             \
3590 _(set_ip_flow_hash_reply)                               \
3591 _(sw_interface_ip6_enable_disable_reply)                \
3592 _(sw_interface_ip6_set_link_local_address_reply)        \
3593 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3594 _(sw_interface_ip6nd_ra_config_reply)                   \
3595 _(set_arp_neighbor_limit_reply)                         \
3596 _(l2_patch_add_del_reply)                               \
3597 _(sr_tunnel_add_del_reply)                              \
3598 _(sr_policy_add_del_reply)                              \
3599 _(sr_multicast_map_add_del_reply)                       \
3600 _(classify_add_del_session_reply)                       \
3601 _(classify_set_interface_ip_table_reply)                \
3602 _(classify_set_interface_l2_tables_reply)               \
3603 _(l2tpv3_set_tunnel_cookies_reply)                      \
3604 _(l2tpv3_interface_enable_disable_reply)                \
3605 _(l2tpv3_set_lookup_key_reply)                          \
3606 _(l2_fib_clear_table_reply)                             \
3607 _(l2_interface_efp_filter_reply)                        \
3608 _(l2_interface_vlan_tag_rewrite_reply)                  \
3609 _(modify_vhost_user_if_reply)                           \
3610 _(delete_vhost_user_if_reply)                           \
3611 _(want_ip4_arp_events_reply)                            \
3612 _(want_ip6_nd_events_reply)                             \
3613 _(input_acl_set_interface_reply)                        \
3614 _(ipsec_spd_add_del_reply)                              \
3615 _(ipsec_interface_add_del_spd_reply)                    \
3616 _(ipsec_spd_add_del_entry_reply)                        \
3617 _(ipsec_sad_add_del_entry_reply)                        \
3618 _(ipsec_sa_set_key_reply)                               \
3619 _(ikev2_profile_add_del_reply)                          \
3620 _(ikev2_profile_set_auth_reply)                         \
3621 _(ikev2_profile_set_id_reply)                           \
3622 _(ikev2_profile_set_ts_reply)                           \
3623 _(ikev2_set_local_key_reply)                            \
3624 _(delete_loopback_reply)                                \
3625 _(bd_ip_mac_add_del_reply)                              \
3626 _(map_del_domain_reply)                                 \
3627 _(map_add_del_rule_reply)                               \
3628 _(want_interface_events_reply)                          \
3629 _(want_stats_reply)                                     \
3630 _(cop_interface_enable_disable_reply)                   \
3631 _(cop_whitelist_enable_disable_reply)                   \
3632 _(sw_interface_clear_stats_reply)                       \
3633 _(ioam_enable_reply)                              \
3634 _(ioam_disable_reply)                              \
3635 _(lisp_add_del_locator_reply)                           \
3636 _(lisp_add_del_local_eid_reply)                         \
3637 _(lisp_add_del_remote_mapping_reply)                    \
3638 _(lisp_add_del_adjacency_reply)                         \
3639 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3640 _(lisp_add_del_map_resolver_reply)                      \
3641 _(lisp_add_del_map_server_reply)                        \
3642 _(lisp_gpe_enable_disable_reply)                        \
3643 _(lisp_gpe_add_del_iface_reply)                         \
3644 _(lisp_enable_disable_reply)                            \
3645 _(lisp_rloc_probe_enable_disable_reply)                 \
3646 _(lisp_map_register_enable_disable_reply)               \
3647 _(lisp_pitr_set_locator_set_reply)                      \
3648 _(lisp_map_request_mode_reply)                          \
3649 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3650 _(lisp_eid_table_add_del_map_reply)                     \
3651 _(vxlan_gpe_add_del_tunnel_reply)                       \
3652 _(af_packet_delete_reply)                               \
3653 _(policer_classify_set_interface_reply)                 \
3654 _(netmap_create_reply)                                  \
3655 _(netmap_delete_reply)                                  \
3656 _(set_ipfix_exporter_reply)                             \
3657 _(set_ipfix_classify_stream_reply)                      \
3658 _(ipfix_classify_table_add_del_reply)                   \
3659 _(flow_classify_set_interface_reply)                    \
3660 _(sw_interface_span_enable_disable_reply)               \
3661 _(pg_capture_reply)                                     \
3662 _(pg_enable_disable_reply)                              \
3663 _(ip_source_and_port_range_check_add_del_reply)         \
3664 _(ip_source_and_port_range_check_interface_add_del_reply)\
3665 _(delete_subif_reply)                                   \
3666 _(l2_interface_pbb_tag_rewrite_reply)                   \
3667 _(punt_reply)                                           \
3668 _(feature_enable_disable_reply)                         \
3669 _(sw_interface_tag_add_del_reply)                       \
3670 _(sw_interface_set_mtu_reply)
3671
3672 #define _(n)                                    \
3673     static void vl_api_##n##_t_handler          \
3674     (vl_api_##n##_t * mp)                       \
3675     {                                           \
3676         vat_main_t * vam = &vat_main;           \
3677         i32 retval = ntohl(mp->retval);         \
3678         if (vam->async_mode) {                  \
3679             vam->async_errors += (retval < 0);  \
3680         } else {                                \
3681             vam->retval = retval;               \
3682             vam->result_ready = 1;              \
3683         }                                       \
3684     }
3685 foreach_standard_reply_retval_handler;
3686 #undef _
3687
3688 #define _(n)                                    \
3689     static void vl_api_##n##_t_handler_json     \
3690     (vl_api_##n##_t * mp)                       \
3691     {                                           \
3692         vat_main_t * vam = &vat_main;           \
3693         vat_json_node_t node;                   \
3694         vat_json_init_object(&node);            \
3695         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3696         vat_json_print(vam->ofp, &node);        \
3697         vam->retval = ntohl(mp->retval);        \
3698         vam->result_ready = 1;                  \
3699     }
3700 foreach_standard_reply_retval_handler;
3701 #undef _
3702
3703 /*
3704  * Table of message reply handlers, must include boilerplate handlers
3705  * we just generated
3706  */
3707
3708 #define foreach_vpe_api_reply_msg                                       \
3709 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3710 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3711 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3712 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3713 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3714 _(CLI_REPLY, cli_reply)                                                 \
3715 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3716 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3717   sw_interface_add_del_address_reply)                                   \
3718 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3719 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3720 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3721 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3722 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3723   sw_interface_set_l2_xconnect_reply)                                   \
3724 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3725   sw_interface_set_l2_bridge_reply)                                     \
3726 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3727   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3728 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3729   sw_interface_set_dpdk_hqos_subport_reply)                             \
3730 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3731   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3732 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3733 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3734 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3735 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3736 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3737 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3738 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3739 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3740 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3741 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3742 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3743 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3744 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3745 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3746 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3747   proxy_arp_intfc_enable_disable_reply)                                 \
3748 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3749 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3750   sw_interface_set_unnumbered_reply)                                    \
3751 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3752 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3753 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3754 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3755 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3756 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3757 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3758 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3759 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3760 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3761 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3762 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3763   sw_interface_ip6_enable_disable_reply)                                \
3764 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3765   sw_interface_ip6_set_link_local_address_reply)                        \
3766 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3767   sw_interface_ip6nd_ra_prefix_reply)                                   \
3768 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3769   sw_interface_ip6nd_ra_config_reply)                                   \
3770 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3771 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3772 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3773 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3774 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3775 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3776 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3777 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3778 classify_set_interface_ip_table_reply)                                  \
3779 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3780   classify_set_interface_l2_tables_reply)                               \
3781 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3782 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3783 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3784 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3785 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3786   l2tpv3_interface_enable_disable_reply)                                \
3787 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3788 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3789 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3790 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3791 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3792 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3793 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3794 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3795 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3796 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3797 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3798 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3799 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3800 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3801 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3802 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3803 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3804 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3805 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3806 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3807 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3808 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3809 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3810 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3811 _(IP_DETAILS, ip_details)                                               \
3812 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3813 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3814 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3815 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3816 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3817 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3818 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3819 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3820 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3821 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3822 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3823 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3824 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3825 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3826 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3827 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3828 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3829 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3830 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3831 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3832 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3833 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3834 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3835 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3836 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3837 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3838 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3839 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3840 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3841 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3842 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3843 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3844 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3845 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3846 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3847 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3848 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3849 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3850 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3851 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3852 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3853   lisp_map_register_enable_disable_reply)                               \
3854 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3855   lisp_rloc_probe_enable_disable_reply)                                 \
3856 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3857 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3858 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3859 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3860 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3861 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3862 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3863 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3864 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3865 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3866 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3867 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3868 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3869 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3870 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3871   lisp_add_del_map_request_itr_rlocs_reply)                             \
3872 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3873   lisp_get_map_request_itr_rlocs_reply)                                 \
3874 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3875 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3876 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3877 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3878   show_lisp_map_register_state_reply)                                   \
3879 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3880 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3881 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3882 _(POLICER_DETAILS, policer_details)                                     \
3883 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3884 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3885 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3886 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3887 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3888 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3889 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3890 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3891 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3892 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3893 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3894 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3895 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3896 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3897 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3898 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3899 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3900 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3901 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3902 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3903 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3904 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3905 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3906 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3907 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3908  ip_source_and_port_range_check_add_del_reply)                          \
3909 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3910  ip_source_and_port_range_check_interface_add_del_reply)                \
3911 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3912 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3913 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3914 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3915 _(PUNT_REPLY, punt_reply)                                               \
3916 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3917 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3918 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3919 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3920 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3921 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3922 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3923 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3924
3925 /* M: construct, but don't yet send a message */
3926
3927 #define M(T,t)                                          \
3928 do {                                                    \
3929     vam->result_ready = 0;                              \
3930     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp));    \
3931     memset (mp, 0, sizeof (*mp));                       \
3932     mp->_vl_msg_id = ntohs (VL_API_##T);                \
3933     mp->client_index = vam->my_client_index;            \
3934 } while(0);
3935
3936 #define M2(T,t,n)                                               \
3937 do {                                                            \
3938     vam->result_ready = 0;                                      \
3939     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n));        \
3940     memset (mp, 0, sizeof (*mp));                               \
3941     mp->_vl_msg_id = ntohs (VL_API_##T);                        \
3942     mp->client_index = vam->my_client_index;                    \
3943 } while(0);
3944
3945
3946 /* S: send a message */
3947 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3948
3949 /* W: wait for results, with timeout */
3950 #define W                                       \
3951 do {                                            \
3952     timeout = vat_time_now (vam) + 1.0;         \
3953                                                 \
3954     while (vat_time_now (vam) < timeout) {      \
3955         if (vam->result_ready == 1) {           \
3956             return (vam->retval);               \
3957         }                                       \
3958         vat_suspend (vam->vlib_main, 1e-3);     \
3959     }                                           \
3960     return -99;                                 \
3961 } while(0);
3962
3963 /* W2: wait for results, with timeout */
3964 #define W2(body)                                \
3965 do {                                            \
3966     timeout = vat_time_now (vam) + 1.0;         \
3967                                                 \
3968     while (vat_time_now (vam) < timeout) {      \
3969         if (vam->result_ready == 1) {           \
3970           (body);                               \
3971           return (vam->retval);                 \
3972         }                                       \
3973         vat_suspend (vam->vlib_main, 1e-3);     \
3974     }                                           \
3975     return -99;                                 \
3976 } while(0);
3977
3978 typedef struct
3979 {
3980   u8 *name;
3981   u32 value;
3982 } name_sort_t;
3983
3984
3985 #define STR_VTR_OP_CASE(op)     \
3986     case L2_VTR_ ## op:         \
3987         return "" # op;
3988
3989 static const char *
3990 str_vtr_op (u32 vtr_op)
3991 {
3992   switch (vtr_op)
3993     {
3994       STR_VTR_OP_CASE (DISABLED);
3995       STR_VTR_OP_CASE (PUSH_1);
3996       STR_VTR_OP_CASE (PUSH_2);
3997       STR_VTR_OP_CASE (POP_1);
3998       STR_VTR_OP_CASE (POP_2);
3999       STR_VTR_OP_CASE (TRANSLATE_1_1);
4000       STR_VTR_OP_CASE (TRANSLATE_1_2);
4001       STR_VTR_OP_CASE (TRANSLATE_2_1);
4002       STR_VTR_OP_CASE (TRANSLATE_2_2);
4003     }
4004
4005   return "UNKNOWN";
4006 }
4007
4008 static int
4009 dump_sub_interface_table (vat_main_t * vam)
4010 {
4011   const sw_interface_subif_t *sub = NULL;
4012
4013   if (vam->json_output)
4014     {
4015       clib_warning
4016         ("JSON output supported only for VPE API calls and dump_stats_table");
4017       return -99;
4018     }
4019
4020   print (vam->ofp,
4021          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4022          "Interface", "sw_if_index",
4023          "sub id", "dot1ad", "tags", "outer id",
4024          "inner id", "exact", "default", "outer any", "inner any");
4025
4026   vec_foreach (sub, vam->sw_if_subif_table)
4027   {
4028     print (vam->ofp,
4029            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4030            sub->interface_name,
4031            sub->sw_if_index,
4032            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4033            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4034            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4035            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4036     if (sub->vtr_op != L2_VTR_DISABLED)
4037       {
4038         print (vam->ofp,
4039                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4040                "tag1: %d tag2: %d ]",
4041                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4042                sub->vtr_tag1, sub->vtr_tag2);
4043       }
4044   }
4045
4046   return 0;
4047 }
4048
4049 static int
4050 name_sort_cmp (void *a1, void *a2)
4051 {
4052   name_sort_t *n1 = a1;
4053   name_sort_t *n2 = a2;
4054
4055   return strcmp ((char *) n1->name, (char *) n2->name);
4056 }
4057
4058 static int
4059 dump_interface_table (vat_main_t * vam)
4060 {
4061   hash_pair_t *p;
4062   name_sort_t *nses = 0, *ns;
4063
4064   if (vam->json_output)
4065     {
4066       clib_warning
4067         ("JSON output supported only for VPE API calls and dump_stats_table");
4068       return -99;
4069     }
4070
4071   /* *INDENT-OFF* */
4072   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4073   ({
4074     vec_add2 (nses, ns, 1);
4075     ns->name = (u8 *)(p->key);
4076     ns->value = (u32) p->value[0];
4077   }));
4078   /* *INDENT-ON* */
4079
4080   vec_sort_with_function (nses, name_sort_cmp);
4081
4082   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4083   vec_foreach (ns, nses)
4084   {
4085     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4086   }
4087   vec_free (nses);
4088   return 0;
4089 }
4090
4091 static int
4092 dump_ip_table (vat_main_t * vam, int is_ipv6)
4093 {
4094   const ip_details_t *det = NULL;
4095   const ip_address_details_t *address = NULL;
4096   u32 i = ~0;
4097
4098   print (vam->ofp, "%-12s", "sw_if_index");
4099
4100   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4101   {
4102     i++;
4103     if (!det->present)
4104       {
4105         continue;
4106       }
4107     print (vam->ofp, "%-12d", i);
4108     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4109     if (!det->addr)
4110       {
4111         continue;
4112       }
4113     vec_foreach (address, det->addr)
4114     {
4115       print (vam->ofp,
4116              "            %-30U%-13d",
4117              is_ipv6 ? format_ip6_address : format_ip4_address,
4118              address->ip, address->prefix_length);
4119     }
4120   }
4121
4122   return 0;
4123 }
4124
4125 static int
4126 dump_ipv4_table (vat_main_t * vam)
4127 {
4128   if (vam->json_output)
4129     {
4130       clib_warning
4131         ("JSON output supported only for VPE API calls and dump_stats_table");
4132       return -99;
4133     }
4134
4135   return dump_ip_table (vam, 0);
4136 }
4137
4138 static int
4139 dump_ipv6_table (vat_main_t * vam)
4140 {
4141   if (vam->json_output)
4142     {
4143       clib_warning
4144         ("JSON output supported only for VPE API calls and dump_stats_table");
4145       return -99;
4146     }
4147
4148   return dump_ip_table (vam, 1);
4149 }
4150
4151 static char *
4152 counter_type_to_str (u8 counter_type, u8 is_combined)
4153 {
4154   if (!is_combined)
4155     {
4156       switch (counter_type)
4157         {
4158         case VNET_INTERFACE_COUNTER_DROP:
4159           return "drop";
4160         case VNET_INTERFACE_COUNTER_PUNT:
4161           return "punt";
4162         case VNET_INTERFACE_COUNTER_IP4:
4163           return "ip4";
4164         case VNET_INTERFACE_COUNTER_IP6:
4165           return "ip6";
4166         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4167           return "rx-no-buf";
4168         case VNET_INTERFACE_COUNTER_RX_MISS:
4169           return "rx-miss";
4170         case VNET_INTERFACE_COUNTER_RX_ERROR:
4171           return "rx-error";
4172         case VNET_INTERFACE_COUNTER_TX_ERROR:
4173           return "tx-error";
4174         default:
4175           return "INVALID-COUNTER-TYPE";
4176         }
4177     }
4178   else
4179     {
4180       switch (counter_type)
4181         {
4182         case VNET_INTERFACE_COUNTER_RX:
4183           return "rx";
4184         case VNET_INTERFACE_COUNTER_TX:
4185           return "tx";
4186         default:
4187           return "INVALID-COUNTER-TYPE";
4188         }
4189     }
4190 }
4191
4192 static int
4193 dump_stats_table (vat_main_t * vam)
4194 {
4195   vat_json_node_t node;
4196   vat_json_node_t *msg_array;
4197   vat_json_node_t *msg;
4198   vat_json_node_t *counter_array;
4199   vat_json_node_t *counter;
4200   interface_counter_t c;
4201   u64 packets;
4202   ip4_fib_counter_t *c4;
4203   ip6_fib_counter_t *c6;
4204   int i, j;
4205
4206   if (!vam->json_output)
4207     {
4208       clib_warning ("dump_stats_table supported only in JSON format");
4209       return -99;
4210     }
4211
4212   vat_json_init_object (&node);
4213
4214   /* interface counters */
4215   msg_array = vat_json_object_add (&node, "interface_counters");
4216   vat_json_init_array (msg_array);
4217   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4218     {
4219       msg = vat_json_array_add (msg_array);
4220       vat_json_init_object (msg);
4221       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4222                                        (u8 *) counter_type_to_str (i, 0));
4223       vat_json_object_add_int (msg, "is_combined", 0);
4224       counter_array = vat_json_object_add (msg, "data");
4225       vat_json_init_array (counter_array);
4226       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4227         {
4228           packets = vam->simple_interface_counters[i][j];
4229           vat_json_array_add_uint (counter_array, packets);
4230         }
4231     }
4232   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4233     {
4234       msg = vat_json_array_add (msg_array);
4235       vat_json_init_object (msg);
4236       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4237                                        (u8 *) counter_type_to_str (i, 1));
4238       vat_json_object_add_int (msg, "is_combined", 1);
4239       counter_array = vat_json_object_add (msg, "data");
4240       vat_json_init_array (counter_array);
4241       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4242         {
4243           c = vam->combined_interface_counters[i][j];
4244           counter = vat_json_array_add (counter_array);
4245           vat_json_init_object (counter);
4246           vat_json_object_add_uint (counter, "packets", c.packets);
4247           vat_json_object_add_uint (counter, "bytes", c.bytes);
4248         }
4249     }
4250
4251   /* ip4 fib counters */
4252   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4253   vat_json_init_array (msg_array);
4254   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4255     {
4256       msg = vat_json_array_add (msg_array);
4257       vat_json_init_object (msg);
4258       vat_json_object_add_uint (msg, "vrf_id",
4259                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4260       counter_array = vat_json_object_add (msg, "c");
4261       vat_json_init_array (counter_array);
4262       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4263         {
4264           counter = vat_json_array_add (counter_array);
4265           vat_json_init_object (counter);
4266           c4 = &vam->ip4_fib_counters[i][j];
4267           vat_json_object_add_ip4 (counter, "address", c4->address);
4268           vat_json_object_add_uint (counter, "address_length",
4269                                     c4->address_length);
4270           vat_json_object_add_uint (counter, "packets", c4->packets);
4271           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4272         }
4273     }
4274
4275   /* ip6 fib counters */
4276   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4277   vat_json_init_array (msg_array);
4278   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4279     {
4280       msg = vat_json_array_add (msg_array);
4281       vat_json_init_object (msg);
4282       vat_json_object_add_uint (msg, "vrf_id",
4283                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4284       counter_array = vat_json_object_add (msg, "c");
4285       vat_json_init_array (counter_array);
4286       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4287         {
4288           counter = vat_json_array_add (counter_array);
4289           vat_json_init_object (counter);
4290           c6 = &vam->ip6_fib_counters[i][j];
4291           vat_json_object_add_ip6 (counter, "address", c6->address);
4292           vat_json_object_add_uint (counter, "address_length",
4293                                     c6->address_length);
4294           vat_json_object_add_uint (counter, "packets", c6->packets);
4295           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4296         }
4297     }
4298
4299   vat_json_print (vam->ofp, &node);
4300   vat_json_free (&node);
4301
4302   return 0;
4303 }
4304
4305 int
4306 exec (vat_main_t * vam)
4307 {
4308   api_main_t *am = &api_main;
4309   vl_api_cli_request_t *mp;
4310   f64 timeout;
4311   void *oldheap;
4312   u8 *cmd = 0;
4313   unformat_input_t *i = vam->input;
4314
4315   if (vec_len (i->buffer) == 0)
4316     return -1;
4317
4318   if (vam->exec_mode == 0 && unformat (i, "mode"))
4319     {
4320       vam->exec_mode = 1;
4321       return 0;
4322     }
4323   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4324     {
4325       vam->exec_mode = 0;
4326       return 0;
4327     }
4328
4329
4330   M (CLI_REQUEST, cli_request);
4331
4332   /*
4333    * Copy cmd into shared memory.
4334    * In order for the CLI command to work, it
4335    * must be a vector ending in \n, not a C-string ending
4336    * in \n\0.
4337    */
4338   pthread_mutex_lock (&am->vlib_rp->mutex);
4339   oldheap = svm_push_data_heap (am->vlib_rp);
4340
4341   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4342   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4343
4344   svm_pop_heap (oldheap);
4345   pthread_mutex_unlock (&am->vlib_rp->mutex);
4346
4347   mp->cmd_in_shmem = (u64) cmd;
4348   S;
4349   timeout = vat_time_now (vam) + 10.0;
4350
4351   while (vat_time_now (vam) < timeout)
4352     {
4353       if (vam->result_ready == 1)
4354         {
4355           u8 *free_me;
4356           if (vam->shmem_result != NULL)
4357             print (vam->ofp, "%s", vam->shmem_result);
4358           pthread_mutex_lock (&am->vlib_rp->mutex);
4359           oldheap = svm_push_data_heap (am->vlib_rp);
4360
4361           free_me = (u8 *) vam->shmem_result;
4362           vec_free (free_me);
4363
4364           svm_pop_heap (oldheap);
4365           pthread_mutex_unlock (&am->vlib_rp->mutex);
4366           return 0;
4367         }
4368     }
4369   return -99;
4370 }
4371
4372 /*
4373  * Future replacement of exec() that passes CLI buffers directly in
4374  * the API messages instead of an additional shared memory area.
4375  */
4376 static int
4377 exec_inband (vat_main_t * vam)
4378 {
4379   vl_api_cli_inband_t *mp;
4380   f64 timeout;
4381   unformat_input_t *i = vam->input;
4382
4383   if (vec_len (i->buffer) == 0)
4384     return -1;
4385
4386   if (vam->exec_mode == 0 && unformat (i, "mode"))
4387     {
4388       vam->exec_mode = 1;
4389       return 0;
4390     }
4391   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4392     {
4393       vam->exec_mode = 0;
4394       return 0;
4395     }
4396
4397   /*
4398    * In order for the CLI command to work, it
4399    * must be a vector ending in \n, not a C-string ending
4400    * in \n\0.
4401    */
4402   u32 len = vec_len (vam->input->buffer);
4403   M2 (CLI_INBAND, cli_inband, len);
4404   clib_memcpy (mp->cmd, vam->input->buffer, len);
4405   mp->length = htonl (len);
4406
4407   S;
4408   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4409 }
4410
4411 static int
4412 api_create_loopback (vat_main_t * vam)
4413 {
4414   unformat_input_t *i = vam->input;
4415   vl_api_create_loopback_t *mp;
4416   f64 timeout;
4417   u8 mac_address[6];
4418   u8 mac_set = 0;
4419
4420   memset (mac_address, 0, sizeof (mac_address));
4421
4422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4423     {
4424       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4425         mac_set = 1;
4426       else
4427         break;
4428     }
4429
4430   /* Construct the API message */
4431   M (CREATE_LOOPBACK, create_loopback);
4432   if (mac_set)
4433     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4434
4435   S;
4436   W;
4437 }
4438
4439 static int
4440 api_delete_loopback (vat_main_t * vam)
4441 {
4442   unformat_input_t *i = vam->input;
4443   vl_api_delete_loopback_t *mp;
4444   f64 timeout;
4445   u32 sw_if_index = ~0;
4446
4447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4448     {
4449       if (unformat (i, "sw_if_index %d", &sw_if_index))
4450         ;
4451       else
4452         break;
4453     }
4454
4455   if (sw_if_index == ~0)
4456     {
4457       errmsg ("missing sw_if_index");
4458       return -99;
4459     }
4460
4461   /* Construct the API message */
4462   M (DELETE_LOOPBACK, delete_loopback);
4463   mp->sw_if_index = ntohl (sw_if_index);
4464
4465   S;
4466   W;
4467 }
4468
4469 static int
4470 api_want_stats (vat_main_t * vam)
4471 {
4472   unformat_input_t *i = vam->input;
4473   vl_api_want_stats_t *mp;
4474   f64 timeout;
4475   int enable = -1;
4476
4477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4478     {
4479       if (unformat (i, "enable"))
4480         enable = 1;
4481       else if (unformat (i, "disable"))
4482         enable = 0;
4483       else
4484         break;
4485     }
4486
4487   if (enable == -1)
4488     {
4489       errmsg ("missing enable|disable");
4490       return -99;
4491     }
4492
4493   M (WANT_STATS, want_stats);
4494   mp->enable_disable = enable;
4495
4496   S;
4497   W;
4498 }
4499
4500 static int
4501 api_want_interface_events (vat_main_t * vam)
4502 {
4503   unformat_input_t *i = vam->input;
4504   vl_api_want_interface_events_t *mp;
4505   f64 timeout;
4506   int enable = -1;
4507
4508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4509     {
4510       if (unformat (i, "enable"))
4511         enable = 1;
4512       else if (unformat (i, "disable"))
4513         enable = 0;
4514       else
4515         break;
4516     }
4517
4518   if (enable == -1)
4519     {
4520       errmsg ("missing enable|disable");
4521       return -99;
4522     }
4523
4524   M (WANT_INTERFACE_EVENTS, want_interface_events);
4525   mp->enable_disable = enable;
4526
4527   vam->interface_event_display = enable;
4528
4529   S;
4530   W;
4531 }
4532
4533
4534 /* Note: non-static, called once to set up the initial intfc table */
4535 int
4536 api_sw_interface_dump (vat_main_t * vam)
4537 {
4538   vl_api_sw_interface_dump_t *mp;
4539   f64 timeout;
4540   hash_pair_t *p;
4541   name_sort_t *nses = 0, *ns;
4542   sw_interface_subif_t *sub = NULL;
4543
4544   /* Toss the old name table */
4545   /* *INDENT-OFF* */
4546   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4547   ({
4548     vec_add2 (nses, ns, 1);
4549     ns->name = (u8 *)(p->key);
4550     ns->value = (u32) p->value[0];
4551   }));
4552   /* *INDENT-ON* */
4553
4554   hash_free (vam->sw_if_index_by_interface_name);
4555
4556   vec_foreach (ns, nses) vec_free (ns->name);
4557
4558   vec_free (nses);
4559
4560   vec_foreach (sub, vam->sw_if_subif_table)
4561   {
4562     vec_free (sub->interface_name);
4563   }
4564   vec_free (vam->sw_if_subif_table);
4565
4566   /* recreate the interface name hash table */
4567   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4568
4569   /* Get list of ethernets */
4570   M (SW_INTERFACE_DUMP, sw_interface_dump);
4571   mp->name_filter_valid = 1;
4572   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4573   S;
4574
4575   /* and local / loopback interfaces */
4576   M (SW_INTERFACE_DUMP, sw_interface_dump);
4577   mp->name_filter_valid = 1;
4578   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4579   S;
4580
4581   /* and packet-generator interfaces */
4582   M (SW_INTERFACE_DUMP, sw_interface_dump);
4583   mp->name_filter_valid = 1;
4584   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4585   S;
4586
4587   /* and vxlan-gpe tunnel interfaces */
4588   M (SW_INTERFACE_DUMP, sw_interface_dump);
4589   mp->name_filter_valid = 1;
4590   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4591            sizeof (mp->name_filter) - 1);
4592   S;
4593
4594   /* and vxlan tunnel interfaces */
4595   M (SW_INTERFACE_DUMP, sw_interface_dump);
4596   mp->name_filter_valid = 1;
4597   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4598   S;
4599
4600   /* and host (af_packet) interfaces */
4601   M (SW_INTERFACE_DUMP, sw_interface_dump);
4602   mp->name_filter_valid = 1;
4603   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4604   S;
4605
4606   /* and l2tpv3 tunnel interfaces */
4607   M (SW_INTERFACE_DUMP, sw_interface_dump);
4608   mp->name_filter_valid = 1;
4609   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4610            sizeof (mp->name_filter) - 1);
4611   S;
4612
4613   /* and GRE tunnel interfaces */
4614   M (SW_INTERFACE_DUMP, sw_interface_dump);
4615   mp->name_filter_valid = 1;
4616   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4617   S;
4618
4619   /* and LISP-GPE interfaces */
4620   M (SW_INTERFACE_DUMP, sw_interface_dump);
4621   mp->name_filter_valid = 1;
4622   strncpy ((char *) mp->name_filter, "lisp_gpe",
4623            sizeof (mp->name_filter) - 1);
4624   S;
4625
4626   /* and IPSEC tunnel interfaces */
4627   M (SW_INTERFACE_DUMP, sw_interface_dump);
4628   mp->name_filter_valid = 1;
4629   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4630   S;
4631
4632   /* Use a control ping for synchronization */
4633   {
4634     vl_api_control_ping_t *mp;
4635     M (CONTROL_PING, control_ping);
4636     S;
4637   }
4638   W;
4639 }
4640
4641 static int
4642 api_sw_interface_set_flags (vat_main_t * vam)
4643 {
4644   unformat_input_t *i = vam->input;
4645   vl_api_sw_interface_set_flags_t *mp;
4646   f64 timeout;
4647   u32 sw_if_index;
4648   u8 sw_if_index_set = 0;
4649   u8 admin_up = 0, link_up = 0;
4650
4651   /* Parse args required to build the message */
4652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4653     {
4654       if (unformat (i, "admin-up"))
4655         admin_up = 1;
4656       else if (unformat (i, "admin-down"))
4657         admin_up = 0;
4658       else if (unformat (i, "link-up"))
4659         link_up = 1;
4660       else if (unformat (i, "link-down"))
4661         link_up = 0;
4662       else
4663         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4664         sw_if_index_set = 1;
4665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4666         sw_if_index_set = 1;
4667       else
4668         break;
4669     }
4670
4671   if (sw_if_index_set == 0)
4672     {
4673       errmsg ("missing interface name or sw_if_index");
4674       return -99;
4675     }
4676
4677   /* Construct the API message */
4678   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4679   mp->sw_if_index = ntohl (sw_if_index);
4680   mp->admin_up_down = admin_up;
4681   mp->link_up_down = link_up;
4682
4683   /* send it... */
4684   S;
4685
4686   /* Wait for a reply, return the good/bad news... */
4687   W;
4688 }
4689
4690 static int
4691 api_sw_interface_clear_stats (vat_main_t * vam)
4692 {
4693   unformat_input_t *i = vam->input;
4694   vl_api_sw_interface_clear_stats_t *mp;
4695   f64 timeout;
4696   u32 sw_if_index;
4697   u8 sw_if_index_set = 0;
4698
4699   /* Parse args required to build the message */
4700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701     {
4702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4703         sw_if_index_set = 1;
4704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4705         sw_if_index_set = 1;
4706       else
4707         break;
4708     }
4709
4710   /* Construct the API message */
4711   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4712
4713   if (sw_if_index_set == 1)
4714     mp->sw_if_index = ntohl (sw_if_index);
4715   else
4716     mp->sw_if_index = ~0;
4717
4718   /* send it... */
4719   S;
4720
4721   /* Wait for a reply, return the good/bad news... */
4722   W;
4723 }
4724
4725 static int
4726 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4727 {
4728   unformat_input_t *i = vam->input;
4729   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4730   f64 timeout;
4731   u32 sw_if_index;
4732   u8 sw_if_index_set = 0;
4733   u32 subport;
4734   u8 subport_set = 0;
4735   u32 pipe;
4736   u8 pipe_set = 0;
4737   u32 profile;
4738   u8 profile_set = 0;
4739
4740   /* Parse args required to build the message */
4741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4742     {
4743       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4744         sw_if_index_set = 1;
4745       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4746         sw_if_index_set = 1;
4747       else if (unformat (i, "subport %u", &subport))
4748         subport_set = 1;
4749       else
4750         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4751         sw_if_index_set = 1;
4752       else if (unformat (i, "pipe %u", &pipe))
4753         pipe_set = 1;
4754       else if (unformat (i, "profile %u", &profile))
4755         profile_set = 1;
4756       else
4757         break;
4758     }
4759
4760   if (sw_if_index_set == 0)
4761     {
4762       errmsg ("missing interface name or sw_if_index");
4763       return -99;
4764     }
4765
4766   if (subport_set == 0)
4767     {
4768       errmsg ("missing subport ");
4769       return -99;
4770     }
4771
4772   if (pipe_set == 0)
4773     {
4774       errmsg ("missing pipe");
4775       return -99;
4776     }
4777
4778   if (profile_set == 0)
4779     {
4780       errmsg ("missing profile");
4781       return -99;
4782     }
4783
4784   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4785
4786   mp->sw_if_index = ntohl (sw_if_index);
4787   mp->subport = ntohl (subport);
4788   mp->pipe = ntohl (pipe);
4789   mp->profile = ntohl (profile);
4790
4791
4792   S;
4793   W;
4794   /* NOTREACHED */
4795   return 0;
4796 }
4797
4798 static int
4799 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4800 {
4801   unformat_input_t *i = vam->input;
4802   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4803   f64 timeout;
4804   u32 sw_if_index;
4805   u8 sw_if_index_set = 0;
4806   u32 subport;
4807   u8 subport_set = 0;
4808   u32 tb_rate = 1250000000;     /* 10GbE */
4809   u32 tb_size = 1000000;
4810   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4811   u32 tc_period = 10;
4812
4813   /* Parse args required to build the message */
4814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4815     {
4816       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4817         sw_if_index_set = 1;
4818       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4819         sw_if_index_set = 1;
4820       else if (unformat (i, "subport %u", &subport))
4821         subport_set = 1;
4822       else
4823         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4824         sw_if_index_set = 1;
4825       else if (unformat (i, "rate %u", &tb_rate))
4826         {
4827           u32 tc_id;
4828
4829           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4830                tc_id++)
4831             tc_rate[tc_id] = tb_rate;
4832         }
4833       else if (unformat (i, "bktsize %u", &tb_size))
4834         ;
4835       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4836         ;
4837       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4838         ;
4839       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4840         ;
4841       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4842         ;
4843       else if (unformat (i, "period %u", &tc_period))
4844         ;
4845       else
4846         break;
4847     }
4848
4849   if (sw_if_index_set == 0)
4850     {
4851       errmsg ("missing interface name or sw_if_index");
4852       return -99;
4853     }
4854
4855   if (subport_set == 0)
4856     {
4857       errmsg ("missing subport ");
4858       return -99;
4859     }
4860
4861   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4862
4863   mp->sw_if_index = ntohl (sw_if_index);
4864   mp->subport = ntohl (subport);
4865   mp->tb_rate = ntohl (tb_rate);
4866   mp->tb_size = ntohl (tb_size);
4867   mp->tc_rate[0] = ntohl (tc_rate[0]);
4868   mp->tc_rate[1] = ntohl (tc_rate[1]);
4869   mp->tc_rate[2] = ntohl (tc_rate[2]);
4870   mp->tc_rate[3] = ntohl (tc_rate[3]);
4871   mp->tc_period = ntohl (tc_period);
4872
4873   S;
4874   W;
4875   /* NOTREACHED */
4876   return 0;
4877 }
4878
4879 static int
4880 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4881 {
4882   unformat_input_t *i = vam->input;
4883   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4884   f64 timeout;
4885   u32 sw_if_index;
4886   u8 sw_if_index_set = 0;
4887   u8 entry_set = 0;
4888   u8 tc_set = 0;
4889   u8 queue_set = 0;
4890   u32 entry, tc, queue;
4891
4892   /* Parse args required to build the message */
4893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4894     {
4895       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4896         sw_if_index_set = 1;
4897       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4898         sw_if_index_set = 1;
4899       else if (unformat (i, "entry %d", &entry))
4900         entry_set = 1;
4901       else if (unformat (i, "tc %d", &tc))
4902         tc_set = 1;
4903       else if (unformat (i, "queue %d", &queue))
4904         queue_set = 1;
4905       else
4906         break;
4907     }
4908
4909   if (sw_if_index_set == 0)
4910     {
4911       errmsg ("missing interface name or sw_if_index");
4912       return -99;
4913     }
4914
4915   if (entry_set == 0)
4916     {
4917       errmsg ("missing entry ");
4918       return -99;
4919     }
4920
4921   if (tc_set == 0)
4922     {
4923       errmsg ("missing traffic class ");
4924       return -99;
4925     }
4926
4927   if (queue_set == 0)
4928     {
4929       errmsg ("missing queue ");
4930       return -99;
4931     }
4932
4933   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4934
4935   mp->sw_if_index = ntohl (sw_if_index);
4936   mp->entry = ntohl (entry);
4937   mp->tc = ntohl (tc);
4938   mp->queue = ntohl (queue);
4939
4940   S;
4941   W;
4942   /* NOTREACHED */
4943   return 0;
4944 }
4945
4946 static int
4947 api_sw_interface_add_del_address (vat_main_t * vam)
4948 {
4949   unformat_input_t *i = vam->input;
4950   vl_api_sw_interface_add_del_address_t *mp;
4951   f64 timeout;
4952   u32 sw_if_index;
4953   u8 sw_if_index_set = 0;
4954   u8 is_add = 1, del_all = 0;
4955   u32 address_length = 0;
4956   u8 v4_address_set = 0;
4957   u8 v6_address_set = 0;
4958   ip4_address_t v4address;
4959   ip6_address_t v6address;
4960
4961   /* Parse args required to build the message */
4962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4963     {
4964       if (unformat (i, "del-all"))
4965         del_all = 1;
4966       else if (unformat (i, "del"))
4967         is_add = 0;
4968       else
4969         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4970         sw_if_index_set = 1;
4971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4972         sw_if_index_set = 1;
4973       else if (unformat (i, "%U/%d",
4974                          unformat_ip4_address, &v4address, &address_length))
4975         v4_address_set = 1;
4976       else if (unformat (i, "%U/%d",
4977                          unformat_ip6_address, &v6address, &address_length))
4978         v6_address_set = 1;
4979       else
4980         break;
4981     }
4982
4983   if (sw_if_index_set == 0)
4984     {
4985       errmsg ("missing interface name or sw_if_index");
4986       return -99;
4987     }
4988   if (v4_address_set && v6_address_set)
4989     {
4990       errmsg ("both v4 and v6 addresses set");
4991       return -99;
4992     }
4993   if (!v4_address_set && !v6_address_set && !del_all)
4994     {
4995       errmsg ("no addresses set");
4996       return -99;
4997     }
4998
4999   /* Construct the API message */
5000   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5001
5002   mp->sw_if_index = ntohl (sw_if_index);
5003   mp->is_add = is_add;
5004   mp->del_all = del_all;
5005   if (v6_address_set)
5006     {
5007       mp->is_ipv6 = 1;
5008       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5009     }
5010   else
5011     {
5012       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5013     }
5014   mp->address_length = address_length;
5015
5016   /* send it... */
5017   S;
5018
5019   /* Wait for a reply, return good/bad news  */
5020   W;
5021 }
5022
5023 static int
5024 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5025 {
5026   unformat_input_t *i = vam->input;
5027   vl_api_sw_interface_set_mpls_enable_t *mp;
5028   f64 timeout;
5029   u32 sw_if_index;
5030   u8 sw_if_index_set = 0;
5031   u8 enable = 1;
5032
5033   /* Parse args required to build the message */
5034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5035     {
5036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5037         sw_if_index_set = 1;
5038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5039         sw_if_index_set = 1;
5040       else if (unformat (i, "disable"))
5041         enable = 0;
5042       else if (unformat (i, "dis"))
5043         enable = 0;
5044       else
5045         break;
5046     }
5047
5048   if (sw_if_index_set == 0)
5049     {
5050       errmsg ("missing interface name or sw_if_index");
5051       return -99;
5052     }
5053
5054   /* Construct the API message */
5055   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5056
5057   mp->sw_if_index = ntohl (sw_if_index);
5058   mp->enable = enable;
5059
5060   /* send it... */
5061   S;
5062
5063   /* Wait for a reply... */
5064   W;
5065 }
5066
5067 static int
5068 api_sw_interface_set_table (vat_main_t * vam)
5069 {
5070   unformat_input_t *i = vam->input;
5071   vl_api_sw_interface_set_table_t *mp;
5072   f64 timeout;
5073   u32 sw_if_index, vrf_id = 0;
5074   u8 sw_if_index_set = 0;
5075   u8 is_ipv6 = 0;
5076
5077   /* Parse args required to build the message */
5078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5079     {
5080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5081         sw_if_index_set = 1;
5082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5083         sw_if_index_set = 1;
5084       else if (unformat (i, "vrf %d", &vrf_id))
5085         ;
5086       else if (unformat (i, "ipv6"))
5087         is_ipv6 = 1;
5088       else
5089         break;
5090     }
5091
5092   if (sw_if_index_set == 0)
5093     {
5094       errmsg ("missing interface name or sw_if_index");
5095       return -99;
5096     }
5097
5098   /* Construct the API message */
5099   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5100
5101   mp->sw_if_index = ntohl (sw_if_index);
5102   mp->is_ipv6 = is_ipv6;
5103   mp->vrf_id = ntohl (vrf_id);
5104
5105   /* send it... */
5106   S;
5107
5108   /* Wait for a reply... */
5109   W;
5110 }
5111
5112 static void vl_api_sw_interface_get_table_reply_t_handler
5113   (vl_api_sw_interface_get_table_reply_t * mp)
5114 {
5115   vat_main_t *vam = &vat_main;
5116
5117   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5118
5119   vam->retval = ntohl (mp->retval);
5120   vam->result_ready = 1;
5121
5122 }
5123
5124 static void vl_api_sw_interface_get_table_reply_t_handler_json
5125   (vl_api_sw_interface_get_table_reply_t * mp)
5126 {
5127   vat_main_t *vam = &vat_main;
5128   vat_json_node_t node;
5129
5130   vat_json_init_object (&node);
5131   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5132   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5133
5134   vat_json_print (vam->ofp, &node);
5135   vat_json_free (&node);
5136
5137   vam->retval = ntohl (mp->retval);
5138   vam->result_ready = 1;
5139 }
5140
5141 static int
5142 api_sw_interface_get_table (vat_main_t * vam)
5143 {
5144   unformat_input_t *i = vam->input;
5145   vl_api_sw_interface_get_table_t *mp;
5146   u32 sw_if_index;
5147   u8 sw_if_index_set = 0;
5148   u8 is_ipv6 = 0;
5149   f64 timeout;
5150
5151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5152     {
5153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5154         sw_if_index_set = 1;
5155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5156         sw_if_index_set = 1;
5157       else if (unformat (i, "ipv6"))
5158         is_ipv6 = 1;
5159       else
5160         break;
5161     }
5162
5163   if (sw_if_index_set == 0)
5164     {
5165       errmsg ("missing interface name or sw_if_index");
5166       return -99;
5167     }
5168
5169   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5170   mp->sw_if_index = htonl (sw_if_index);
5171   mp->is_ipv6 = is_ipv6;
5172
5173   S;
5174   W;
5175 }
5176
5177 static int
5178 api_sw_interface_set_vpath (vat_main_t * vam)
5179 {
5180   unformat_input_t *i = vam->input;
5181   vl_api_sw_interface_set_vpath_t *mp;
5182   f64 timeout;
5183   u32 sw_if_index = 0;
5184   u8 sw_if_index_set = 0;
5185   u8 is_enable = 0;
5186
5187   /* Parse args required to build the message */
5188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5189     {
5190       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5191         sw_if_index_set = 1;
5192       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5193         sw_if_index_set = 1;
5194       else if (unformat (i, "enable"))
5195         is_enable = 1;
5196       else if (unformat (i, "disable"))
5197         is_enable = 0;
5198       else
5199         break;
5200     }
5201
5202   if (sw_if_index_set == 0)
5203     {
5204       errmsg ("missing interface name or sw_if_index");
5205       return -99;
5206     }
5207
5208   /* Construct the API message */
5209   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5210
5211   mp->sw_if_index = ntohl (sw_if_index);
5212   mp->enable = is_enable;
5213
5214   /* send it... */
5215   S;
5216
5217   /* Wait for a reply... */
5218   W;
5219 }
5220
5221 static int
5222 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5223 {
5224   unformat_input_t *i = vam->input;
5225   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5226   f64 timeout;
5227   u32 sw_if_index = 0;
5228   u8 sw_if_index_set = 0;
5229   u8 is_enable = 0;
5230   u8 is_ipv6 = 0;
5231
5232   /* Parse args required to build the message */
5233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5234     {
5235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5236         sw_if_index_set = 1;
5237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5238         sw_if_index_set = 1;
5239       else if (unformat (i, "enable"))
5240         is_enable = 1;
5241       else if (unformat (i, "disable"))
5242         is_enable = 0;
5243       else if (unformat (i, "ip4"))
5244         is_ipv6 = 0;
5245       else if (unformat (i, "ip6"))
5246         is_ipv6 = 1;
5247       else
5248         break;
5249     }
5250
5251   if (sw_if_index_set == 0)
5252     {
5253       errmsg ("missing interface name or sw_if_index");
5254       return -99;
5255     }
5256
5257   /* Construct the API message */
5258   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5259
5260   mp->sw_if_index = ntohl (sw_if_index);
5261   mp->enable = is_enable;
5262   mp->is_ipv6 = is_ipv6;
5263
5264   /* send it... */
5265   S;
5266
5267   /* Wait for a reply... */
5268   W;
5269 }
5270
5271 static int
5272 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5273 {
5274   unformat_input_t *i = vam->input;
5275   vl_api_sw_interface_set_l2_xconnect_t *mp;
5276   f64 timeout;
5277   u32 rx_sw_if_index;
5278   u8 rx_sw_if_index_set = 0;
5279   u32 tx_sw_if_index;
5280   u8 tx_sw_if_index_set = 0;
5281   u8 enable = 1;
5282
5283   /* Parse args required to build the message */
5284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5285     {
5286       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5287         rx_sw_if_index_set = 1;
5288       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5289         tx_sw_if_index_set = 1;
5290       else if (unformat (i, "rx"))
5291         {
5292           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5293             {
5294               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5295                             &rx_sw_if_index))
5296                 rx_sw_if_index_set = 1;
5297             }
5298           else
5299             break;
5300         }
5301       else if (unformat (i, "tx"))
5302         {
5303           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5304             {
5305               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5306                             &tx_sw_if_index))
5307                 tx_sw_if_index_set = 1;
5308             }
5309           else
5310             break;
5311         }
5312       else if (unformat (i, "enable"))
5313         enable = 1;
5314       else if (unformat (i, "disable"))
5315         enable = 0;
5316       else
5317         break;
5318     }
5319
5320   if (rx_sw_if_index_set == 0)
5321     {
5322       errmsg ("missing rx interface name or rx_sw_if_index");
5323       return -99;
5324     }
5325
5326   if (enable && (tx_sw_if_index_set == 0))
5327     {
5328       errmsg ("missing tx interface name or tx_sw_if_index");
5329       return -99;
5330     }
5331
5332   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5333
5334   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5335   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5336   mp->enable = enable;
5337
5338   S;
5339   W;
5340   /* NOTREACHED */
5341   return 0;
5342 }
5343
5344 static int
5345 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5346 {
5347   unformat_input_t *i = vam->input;
5348   vl_api_sw_interface_set_l2_bridge_t *mp;
5349   f64 timeout;
5350   u32 rx_sw_if_index;
5351   u8 rx_sw_if_index_set = 0;
5352   u32 bd_id;
5353   u8 bd_id_set = 0;
5354   u8 bvi = 0;
5355   u32 shg = 0;
5356   u8 enable = 1;
5357
5358   /* Parse args required to build the message */
5359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5360     {
5361       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5362         rx_sw_if_index_set = 1;
5363       else if (unformat (i, "bd_id %d", &bd_id))
5364         bd_id_set = 1;
5365       else
5366         if (unformat
5367             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5368         rx_sw_if_index_set = 1;
5369       else if (unformat (i, "shg %d", &shg))
5370         ;
5371       else if (unformat (i, "bvi"))
5372         bvi = 1;
5373       else if (unformat (i, "enable"))
5374         enable = 1;
5375       else if (unformat (i, "disable"))
5376         enable = 0;
5377       else
5378         break;
5379     }
5380
5381   if (rx_sw_if_index_set == 0)
5382     {
5383       errmsg ("missing rx interface name or sw_if_index");
5384       return -99;
5385     }
5386
5387   if (enable && (bd_id_set == 0))
5388     {
5389       errmsg ("missing bridge domain");
5390       return -99;
5391     }
5392
5393   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5394
5395   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5396   mp->bd_id = ntohl (bd_id);
5397   mp->shg = (u8) shg;
5398   mp->bvi = bvi;
5399   mp->enable = enable;
5400
5401   S;
5402   W;
5403   /* NOTREACHED */
5404   return 0;
5405 }
5406
5407 static int
5408 api_bridge_domain_dump (vat_main_t * vam)
5409 {
5410   unformat_input_t *i = vam->input;
5411   vl_api_bridge_domain_dump_t *mp;
5412   f64 timeout;
5413   u32 bd_id = ~0;
5414
5415   /* Parse args required to build the message */
5416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5417     {
5418       if (unformat (i, "bd_id %d", &bd_id))
5419         ;
5420       else
5421         break;
5422     }
5423
5424   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5425   mp->bd_id = ntohl (bd_id);
5426   S;
5427
5428   /* Use a control ping for synchronization */
5429   {
5430     vl_api_control_ping_t *mp;
5431     M (CONTROL_PING, control_ping);
5432     S;
5433   }
5434
5435   W;
5436   /* NOTREACHED */
5437   return 0;
5438 }
5439
5440 static int
5441 api_bridge_domain_add_del (vat_main_t * vam)
5442 {
5443   unformat_input_t *i = vam->input;
5444   vl_api_bridge_domain_add_del_t *mp;
5445   f64 timeout;
5446   u32 bd_id = ~0;
5447   u8 is_add = 1;
5448   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5449   u32 mac_age = 0;
5450
5451   /* Parse args required to build the message */
5452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5453     {
5454       if (unformat (i, "bd_id %d", &bd_id))
5455         ;
5456       else if (unformat (i, "flood %d", &flood))
5457         ;
5458       else if (unformat (i, "uu-flood %d", &uu_flood))
5459         ;
5460       else if (unformat (i, "forward %d", &forward))
5461         ;
5462       else if (unformat (i, "learn %d", &learn))
5463         ;
5464       else if (unformat (i, "arp-term %d", &arp_term))
5465         ;
5466       else if (unformat (i, "mac-age %d", &mac_age))
5467         ;
5468       else if (unformat (i, "del"))
5469         {
5470           is_add = 0;
5471           flood = uu_flood = forward = learn = 0;
5472         }
5473       else
5474         break;
5475     }
5476
5477   if (bd_id == ~0)
5478     {
5479       errmsg ("missing bridge domain");
5480       return -99;
5481     }
5482
5483   if (mac_age > 255)
5484     {
5485       errmsg ("mac age must be less than 256 ");
5486       return -99;
5487     }
5488
5489   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5490
5491   mp->bd_id = ntohl (bd_id);
5492   mp->flood = flood;
5493   mp->uu_flood = uu_flood;
5494   mp->forward = forward;
5495   mp->learn = learn;
5496   mp->arp_term = arp_term;
5497   mp->is_add = is_add;
5498   mp->mac_age = (u8) mac_age;
5499
5500   S;
5501   W;
5502   /* NOTREACHED */
5503   return 0;
5504 }
5505
5506 static int
5507 api_l2fib_add_del (vat_main_t * vam)
5508 {
5509   unformat_input_t *i = vam->input;
5510   vl_api_l2fib_add_del_t *mp;
5511   f64 timeout;
5512   u64 mac = 0;
5513   u8 mac_set = 0;
5514   u32 bd_id;
5515   u8 bd_id_set = 0;
5516   u32 sw_if_index = ~0;
5517   u8 sw_if_index_set = 0;
5518   u8 is_add = 1;
5519   u8 static_mac = 0;
5520   u8 filter_mac = 0;
5521   u8 bvi_mac = 0;
5522   int count = 1;
5523   f64 before = 0;
5524   int j;
5525
5526   /* Parse args required to build the message */
5527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5528     {
5529       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5530         mac_set = 1;
5531       else if (unformat (i, "bd_id %d", &bd_id))
5532         bd_id_set = 1;
5533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5534         sw_if_index_set = 1;
5535       else if (unformat (i, "sw_if"))
5536         {
5537           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5538             {
5539               if (unformat
5540                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5541                 sw_if_index_set = 1;
5542             }
5543           else
5544             break;
5545         }
5546       else if (unformat (i, "static"))
5547         static_mac = 1;
5548       else if (unformat (i, "filter"))
5549         {
5550           filter_mac = 1;
5551           static_mac = 1;
5552         }
5553       else if (unformat (i, "bvi"))
5554         {
5555           bvi_mac = 1;
5556           static_mac = 1;
5557         }
5558       else if (unformat (i, "del"))
5559         is_add = 0;
5560       else if (unformat (i, "count %d", &count))
5561         ;
5562       else
5563         break;
5564     }
5565
5566   if (mac_set == 0)
5567     {
5568       errmsg ("missing mac address");
5569       return -99;
5570     }
5571
5572   if (bd_id_set == 0)
5573     {
5574       errmsg ("missing bridge domain");
5575       return -99;
5576     }
5577
5578   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5579     {
5580       errmsg ("missing interface name or sw_if_index");
5581       return -99;
5582     }
5583
5584   if (count > 1)
5585     {
5586       /* Turn on async mode */
5587       vam->async_mode = 1;
5588       vam->async_errors = 0;
5589       before = vat_time_now (vam);
5590     }
5591
5592   for (j = 0; j < count; j++)
5593     {
5594       M (L2FIB_ADD_DEL, l2fib_add_del);
5595
5596       mp->mac = mac;
5597       mp->bd_id = ntohl (bd_id);
5598       mp->is_add = is_add;
5599
5600       if (is_add)
5601         {
5602           mp->sw_if_index = ntohl (sw_if_index);
5603           mp->static_mac = static_mac;
5604           mp->filter_mac = filter_mac;
5605           mp->bvi_mac = bvi_mac;
5606         }
5607       increment_mac_address (&mac);
5608       /* send it... */
5609       S;
5610     }
5611
5612   if (count > 1)
5613     {
5614       vl_api_control_ping_t *mp;
5615       f64 after;
5616
5617       /* Shut off async mode */
5618       vam->async_mode = 0;
5619
5620       M (CONTROL_PING, control_ping);
5621       S;
5622
5623       timeout = vat_time_now (vam) + 1.0;
5624       while (vat_time_now (vam) < timeout)
5625         if (vam->result_ready == 1)
5626           goto out;
5627       vam->retval = -99;
5628
5629     out:
5630       if (vam->retval == -99)
5631         errmsg ("timeout");
5632
5633       if (vam->async_errors > 0)
5634         {
5635           errmsg ("%d asynchronous errors", vam->async_errors);
5636           vam->retval = -98;
5637         }
5638       vam->async_errors = 0;
5639       after = vat_time_now (vam);
5640
5641       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5642              count, after - before, count / (after - before));
5643     }
5644   else
5645     {
5646       /* Wait for a reply... */
5647       W;
5648     }
5649   /* Return the good/bad news */
5650   return (vam->retval);
5651 }
5652
5653 static int
5654 api_l2_flags (vat_main_t * vam)
5655 {
5656   unformat_input_t *i = vam->input;
5657   vl_api_l2_flags_t *mp;
5658   f64 timeout;
5659   u32 sw_if_index;
5660   u32 feature_bitmap = 0;
5661   u8 sw_if_index_set = 0;
5662
5663   /* Parse args required to build the message */
5664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5665     {
5666       if (unformat (i, "sw_if_index %d", &sw_if_index))
5667         sw_if_index_set = 1;
5668       else if (unformat (i, "sw_if"))
5669         {
5670           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5671             {
5672               if (unformat
5673                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5674                 sw_if_index_set = 1;
5675             }
5676           else
5677             break;
5678         }
5679       else if (unformat (i, "learn"))
5680         feature_bitmap |= L2INPUT_FEAT_LEARN;
5681       else if (unformat (i, "forward"))
5682         feature_bitmap |= L2INPUT_FEAT_FWD;
5683       else if (unformat (i, "flood"))
5684         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5685       else if (unformat (i, "uu-flood"))
5686         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5687       else
5688         break;
5689     }
5690
5691   if (sw_if_index_set == 0)
5692     {
5693       errmsg ("missing interface name or sw_if_index");
5694       return -99;
5695     }
5696
5697   M (L2_FLAGS, l2_flags);
5698
5699   mp->sw_if_index = ntohl (sw_if_index);
5700   mp->feature_bitmap = ntohl (feature_bitmap);
5701
5702   S;
5703   W;
5704   /* NOTREACHED */
5705   return 0;
5706 }
5707
5708 static int
5709 api_bridge_flags (vat_main_t * vam)
5710 {
5711   unformat_input_t *i = vam->input;
5712   vl_api_bridge_flags_t *mp;
5713   f64 timeout;
5714   u32 bd_id;
5715   u8 bd_id_set = 0;
5716   u8 is_set = 1;
5717   u32 flags = 0;
5718
5719   /* Parse args required to build the message */
5720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5721     {
5722       if (unformat (i, "bd_id %d", &bd_id))
5723         bd_id_set = 1;
5724       else if (unformat (i, "learn"))
5725         flags |= L2_LEARN;
5726       else if (unformat (i, "forward"))
5727         flags |= L2_FWD;
5728       else if (unformat (i, "flood"))
5729         flags |= L2_FLOOD;
5730       else if (unformat (i, "uu-flood"))
5731         flags |= L2_UU_FLOOD;
5732       else if (unformat (i, "arp-term"))
5733         flags |= L2_ARP_TERM;
5734       else if (unformat (i, "off"))
5735         is_set = 0;
5736       else if (unformat (i, "disable"))
5737         is_set = 0;
5738       else
5739         break;
5740     }
5741
5742   if (bd_id_set == 0)
5743     {
5744       errmsg ("missing bridge domain");
5745       return -99;
5746     }
5747
5748   M (BRIDGE_FLAGS, bridge_flags);
5749
5750   mp->bd_id = ntohl (bd_id);
5751   mp->feature_bitmap = ntohl (flags);
5752   mp->is_set = is_set;
5753
5754   S;
5755   W;
5756   /* NOTREACHED */
5757   return 0;
5758 }
5759
5760 static int
5761 api_bd_ip_mac_add_del (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_bd_ip_mac_add_del_t *mp;
5765   f64 timeout;
5766   u32 bd_id;
5767   u8 is_ipv6 = 0;
5768   u8 is_add = 1;
5769   u8 bd_id_set = 0;
5770   u8 ip_set = 0;
5771   u8 mac_set = 0;
5772   ip4_address_t v4addr;
5773   ip6_address_t v6addr;
5774   u8 macaddr[6];
5775
5776
5777   /* Parse args required to build the message */
5778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5779     {
5780       if (unformat (i, "bd_id %d", &bd_id))
5781         {
5782           bd_id_set++;
5783         }
5784       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5785         {
5786           ip_set++;
5787         }
5788       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5789         {
5790           ip_set++;
5791           is_ipv6++;
5792         }
5793       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5794         {
5795           mac_set++;
5796         }
5797       else if (unformat (i, "del"))
5798         is_add = 0;
5799       else
5800         break;
5801     }
5802
5803   if (bd_id_set == 0)
5804     {
5805       errmsg ("missing bridge domain");
5806       return -99;
5807     }
5808   else if (ip_set == 0)
5809     {
5810       errmsg ("missing IP address");
5811       return -99;
5812     }
5813   else if (mac_set == 0)
5814     {
5815       errmsg ("missing MAC address");
5816       return -99;
5817     }
5818
5819   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5820
5821   mp->bd_id = ntohl (bd_id);
5822   mp->is_ipv6 = is_ipv6;
5823   mp->is_add = is_add;
5824   if (is_ipv6)
5825     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5826   else
5827     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5828   clib_memcpy (mp->mac_address, macaddr, 6);
5829   S;
5830   W;
5831   /* NOTREACHED */
5832   return 0;
5833 }
5834
5835 static int
5836 api_tap_connect (vat_main_t * vam)
5837 {
5838   unformat_input_t *i = vam->input;
5839   vl_api_tap_connect_t *mp;
5840   f64 timeout;
5841   u8 mac_address[6];
5842   u8 random_mac = 1;
5843   u8 name_set = 0;
5844   u8 *tap_name;
5845   u8 *tag = 0;
5846
5847   memset (mac_address, 0, sizeof (mac_address));
5848
5849   /* Parse args required to build the message */
5850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5851     {
5852       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5853         {
5854           random_mac = 0;
5855         }
5856       else if (unformat (i, "random-mac"))
5857         random_mac = 1;
5858       else if (unformat (i, "tapname %s", &tap_name))
5859         name_set = 1;
5860       else if (unformat (i, "tag %s", &tag))
5861         ;
5862       else
5863         break;
5864     }
5865
5866   if (name_set == 0)
5867     {
5868       errmsg ("missing tap name");
5869       return -99;
5870     }
5871   if (vec_len (tap_name) > 63)
5872     {
5873       errmsg ("tap name too long");
5874       return -99;
5875     }
5876   vec_add1 (tap_name, 0);
5877
5878   if (vec_len (tag) > 63)
5879     {
5880       errmsg ("tag too long");
5881       return -99;
5882     }
5883
5884   /* Construct the API message */
5885   M (TAP_CONNECT, tap_connect);
5886
5887   mp->use_random_mac = random_mac;
5888   clib_memcpy (mp->mac_address, mac_address, 6);
5889   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5890   if (tag)
5891     clib_memcpy (mp->tag, tag, vec_len (tag));
5892
5893   vec_free (tap_name);
5894   vec_free (tag);
5895
5896   /* send it... */
5897   S;
5898
5899   /* Wait for a reply... */
5900   W;
5901 }
5902
5903 static int
5904 api_tap_modify (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_tap_modify_t *mp;
5908   f64 timeout;
5909   u8 mac_address[6];
5910   u8 random_mac = 1;
5911   u8 name_set = 0;
5912   u8 *tap_name;
5913   u32 sw_if_index = ~0;
5914   u8 sw_if_index_set = 0;
5915
5916   memset (mac_address, 0, sizeof (mac_address));
5917
5918   /* Parse args required to build the message */
5919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5920     {
5921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5922         sw_if_index_set = 1;
5923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5924         sw_if_index_set = 1;
5925       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5926         {
5927           random_mac = 0;
5928         }
5929       else if (unformat (i, "random-mac"))
5930         random_mac = 1;
5931       else if (unformat (i, "tapname %s", &tap_name))
5932         name_set = 1;
5933       else
5934         break;
5935     }
5936
5937   if (sw_if_index_set == 0)
5938     {
5939       errmsg ("missing vpp interface name");
5940       return -99;
5941     }
5942   if (name_set == 0)
5943     {
5944       errmsg ("missing tap name");
5945       return -99;
5946     }
5947   if (vec_len (tap_name) > 63)
5948     {
5949       errmsg ("tap name too long");
5950     }
5951   vec_add1 (tap_name, 0);
5952
5953   /* Construct the API message */
5954   M (TAP_MODIFY, tap_modify);
5955
5956   mp->use_random_mac = random_mac;
5957   mp->sw_if_index = ntohl (sw_if_index);
5958   clib_memcpy (mp->mac_address, mac_address, 6);
5959   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5960   vec_free (tap_name);
5961
5962   /* send it... */
5963   S;
5964
5965   /* Wait for a reply... */
5966   W;
5967 }
5968
5969 static int
5970 api_tap_delete (vat_main_t * vam)
5971 {
5972   unformat_input_t *i = vam->input;
5973   vl_api_tap_delete_t *mp;
5974   f64 timeout;
5975   u32 sw_if_index = ~0;
5976   u8 sw_if_index_set = 0;
5977
5978   /* Parse args required to build the message */
5979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5980     {
5981       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5982         sw_if_index_set = 1;
5983       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5984         sw_if_index_set = 1;
5985       else
5986         break;
5987     }
5988
5989   if (sw_if_index_set == 0)
5990     {
5991       errmsg ("missing vpp interface name");
5992       return -99;
5993     }
5994
5995   /* Construct the API message */
5996   M (TAP_DELETE, tap_delete);
5997
5998   mp->sw_if_index = ntohl (sw_if_index);
5999
6000   /* send it... */
6001   S;
6002
6003   /* Wait for a reply... */
6004   W;
6005 }
6006
6007 static int
6008 api_ip_add_del_route (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_ip_add_del_route_t *mp;
6012   f64 timeout;
6013   u32 sw_if_index = ~0, vrf_id = 0;
6014   u8 is_ipv6 = 0;
6015   u8 is_local = 0, is_drop = 0;
6016   u8 is_unreach = 0, is_prohibit = 0;
6017   u8 create_vrf_if_needed = 0;
6018   u8 is_add = 1;
6019   u32 next_hop_weight = 1;
6020   u8 not_last = 0;
6021   u8 is_multipath = 0;
6022   u8 address_set = 0;
6023   u8 address_length_set = 0;
6024   u32 next_hop_table_id = 0;
6025   u32 resolve_attempts = 0;
6026   u32 dst_address_length = 0;
6027   u8 next_hop_set = 0;
6028   ip4_address_t v4_dst_address, v4_next_hop_address;
6029   ip6_address_t v6_dst_address, v6_next_hop_address;
6030   int count = 1;
6031   int j;
6032   f64 before = 0;
6033   u32 random_add_del = 0;
6034   u32 *random_vector = 0;
6035   uword *random_hash;
6036   u32 random_seed = 0xdeaddabe;
6037   u32 classify_table_index = ~0;
6038   u8 is_classify = 0;
6039   u8 resolve_host = 0, resolve_attached = 0;
6040   mpls_label_t *next_hop_out_label_stack = NULL;
6041   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6042   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6043
6044   /* Parse args required to build the message */
6045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6046     {
6047       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6048         ;
6049       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6050         ;
6051       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6052         {
6053           address_set = 1;
6054           is_ipv6 = 0;
6055         }
6056       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6057         {
6058           address_set = 1;
6059           is_ipv6 = 1;
6060         }
6061       else if (unformat (i, "/%d", &dst_address_length))
6062         {
6063           address_length_set = 1;
6064         }
6065
6066       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6067                                          &v4_next_hop_address))
6068         {
6069           next_hop_set = 1;
6070         }
6071       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6072                                          &v6_next_hop_address))
6073         {
6074           next_hop_set = 1;
6075         }
6076       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6077         ;
6078       else if (unformat (i, "weight %d", &next_hop_weight))
6079         ;
6080       else if (unformat (i, "drop"))
6081         {
6082           is_drop = 1;
6083         }
6084       else if (unformat (i, "null-send-unreach"))
6085         {
6086           is_unreach = 1;
6087         }
6088       else if (unformat (i, "null-send-prohibit"))
6089         {
6090           is_prohibit = 1;
6091         }
6092       else if (unformat (i, "local"))
6093         {
6094           is_local = 1;
6095         }
6096       else if (unformat (i, "classify %d", &classify_table_index))
6097         {
6098           is_classify = 1;
6099         }
6100       else if (unformat (i, "del"))
6101         is_add = 0;
6102       else if (unformat (i, "add"))
6103         is_add = 1;
6104       else if (unformat (i, "not-last"))
6105         not_last = 1;
6106       else if (unformat (i, "resolve-via-host"))
6107         resolve_host = 1;
6108       else if (unformat (i, "resolve-via-attached"))
6109         resolve_attached = 1;
6110       else if (unformat (i, "multipath"))
6111         is_multipath = 1;
6112       else if (unformat (i, "vrf %d", &vrf_id))
6113         ;
6114       else if (unformat (i, "create-vrf"))
6115         create_vrf_if_needed = 1;
6116       else if (unformat (i, "count %d", &count))
6117         ;
6118       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6119         ;
6120       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6121         ;
6122       else if (unformat (i, "out-label %d", &next_hop_out_label))
6123         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6124       else if (unformat (i, "via-label %d", &next_hop_via_label))
6125         ;
6126       else if (unformat (i, "random"))
6127         random_add_del = 1;
6128       else if (unformat (i, "seed %d", &random_seed))
6129         ;
6130       else
6131         {
6132           clib_warning ("parse error '%U'", format_unformat_error, i);
6133           return -99;
6134         }
6135     }
6136
6137   if (!next_hop_set && !is_drop && !is_local &&
6138       !is_classify && !is_unreach && !is_prohibit &&
6139       MPLS_LABEL_INVALID == next_hop_via_label)
6140     {
6141       errmsg
6142         ("next hop / local / drop / unreach / prohibit / classify not set");
6143       return -99;
6144     }
6145
6146   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6147     {
6148       errmsg ("next hop and next-hop via label set");
6149       return -99;
6150     }
6151   if (address_set == 0)
6152     {
6153       errmsg ("missing addresses");
6154       return -99;
6155     }
6156
6157   if (address_length_set == 0)
6158     {
6159       errmsg ("missing address length");
6160       return -99;
6161     }
6162
6163   /* Generate a pile of unique, random routes */
6164   if (random_add_del)
6165     {
6166       u32 this_random_address;
6167       random_hash = hash_create (count, sizeof (uword));
6168
6169       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6170       for (j = 0; j <= count; j++)
6171         {
6172           do
6173             {
6174               this_random_address = random_u32 (&random_seed);
6175               this_random_address =
6176                 clib_host_to_net_u32 (this_random_address);
6177             }
6178           while (hash_get (random_hash, this_random_address));
6179           vec_add1 (random_vector, this_random_address);
6180           hash_set (random_hash, this_random_address, 1);
6181         }
6182       hash_free (random_hash);
6183       v4_dst_address.as_u32 = random_vector[0];
6184     }
6185
6186   if (count > 1)
6187     {
6188       /* Turn on async mode */
6189       vam->async_mode = 1;
6190       vam->async_errors = 0;
6191       before = vat_time_now (vam);
6192     }
6193
6194   for (j = 0; j < count; j++)
6195     {
6196       /* Construct the API message */
6197       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6198           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6199
6200       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6201       mp->table_id = ntohl (vrf_id);
6202       mp->create_vrf_if_needed = create_vrf_if_needed;
6203
6204       mp->is_add = is_add;
6205       mp->is_drop = is_drop;
6206       mp->is_unreach = is_unreach;
6207       mp->is_prohibit = is_prohibit;
6208       mp->is_ipv6 = is_ipv6;
6209       mp->is_local = is_local;
6210       mp->is_classify = is_classify;
6211       mp->is_multipath = is_multipath;
6212       mp->is_resolve_host = resolve_host;
6213       mp->is_resolve_attached = resolve_attached;
6214       mp->not_last = not_last;
6215       mp->next_hop_weight = next_hop_weight;
6216       mp->dst_address_length = dst_address_length;
6217       mp->next_hop_table_id = ntohl (next_hop_table_id);
6218       mp->classify_table_index = ntohl (classify_table_index);
6219       mp->next_hop_via_label = ntohl (next_hop_via_label);
6220       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6221       if (0 != mp->next_hop_n_out_labels)
6222         {
6223           memcpy (mp->next_hop_out_label_stack,
6224                   next_hop_out_label_stack,
6225                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6226           vec_free (next_hop_out_label_stack);
6227         }
6228
6229       if (is_ipv6)
6230         {
6231           clib_memcpy (mp->dst_address, &v6_dst_address,
6232                        sizeof (v6_dst_address));
6233           if (next_hop_set)
6234             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6235                          sizeof (v6_next_hop_address));
6236           increment_v6_address (&v6_dst_address);
6237         }
6238       else
6239         {
6240           clib_memcpy (mp->dst_address, &v4_dst_address,
6241                        sizeof (v4_dst_address));
6242           if (next_hop_set)
6243             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6244                          sizeof (v4_next_hop_address));
6245           if (random_add_del)
6246             v4_dst_address.as_u32 = random_vector[j + 1];
6247           else
6248             increment_v4_address (&v4_dst_address);
6249         }
6250       /* send it... */
6251       S;
6252       /* If we receive SIGTERM, stop now... */
6253       if (vam->do_exit)
6254         break;
6255     }
6256
6257   /* When testing multiple add/del ops, use a control-ping to sync */
6258   if (count > 1)
6259     {
6260       vl_api_control_ping_t *mp;
6261       f64 after;
6262
6263       /* Shut off async mode */
6264       vam->async_mode = 0;
6265
6266       M (CONTROL_PING, control_ping);
6267       S;
6268
6269       timeout = vat_time_now (vam) + 1.0;
6270       while (vat_time_now (vam) < timeout)
6271         if (vam->result_ready == 1)
6272           goto out;
6273       vam->retval = -99;
6274
6275     out:
6276       if (vam->retval == -99)
6277         errmsg ("timeout");
6278
6279       if (vam->async_errors > 0)
6280         {
6281           errmsg ("%d asynchronous errors", vam->async_errors);
6282           vam->retval = -98;
6283         }
6284       vam->async_errors = 0;
6285       after = vat_time_now (vam);
6286
6287       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6288       if (j > 0)
6289         count = j;
6290
6291       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6292              count, after - before, count / (after - before));
6293     }
6294   else
6295     {
6296       /* Wait for a reply... */
6297       W;
6298     }
6299
6300   /* Return the good/bad news */
6301   return (vam->retval);
6302 }
6303
6304 static int
6305 api_mpls_route_add_del (vat_main_t * vam)
6306 {
6307   unformat_input_t *i = vam->input;
6308   vl_api_mpls_route_add_del_t *mp;
6309   f64 timeout;
6310   u32 sw_if_index = ~0, table_id = 0;
6311   u8 create_table_if_needed = 0;
6312   u8 is_add = 1;
6313   u32 next_hop_weight = 1;
6314   u8 is_multipath = 0;
6315   u32 next_hop_table_id = 0;
6316   u8 next_hop_set = 0;
6317   ip4_address_t v4_next_hop_address = {
6318     .as_u32 = 0,
6319   };
6320   ip6_address_t v6_next_hop_address = { {0} };
6321   int count = 1;
6322   int j;
6323   f64 before = 0;
6324   u32 classify_table_index = ~0;
6325   u8 is_classify = 0;
6326   u8 resolve_host = 0, resolve_attached = 0;
6327   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6328   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6329   mpls_label_t *next_hop_out_label_stack = NULL;
6330   mpls_label_t local_label = MPLS_LABEL_INVALID;
6331   u8 is_eos = 0;
6332   u8 next_hop_proto_is_ip4 = 1;
6333
6334   /* Parse args required to build the message */
6335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6336     {
6337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6338         ;
6339       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6340         ;
6341       else if (unformat (i, "%d", &local_label))
6342         ;
6343       else if (unformat (i, "eos"))
6344         is_eos = 1;
6345       else if (unformat (i, "non-eos"))
6346         is_eos = 0;
6347       else if (unformat (i, "via %U", unformat_ip4_address,
6348                          &v4_next_hop_address))
6349         {
6350           next_hop_set = 1;
6351           next_hop_proto_is_ip4 = 1;
6352         }
6353       else if (unformat (i, "via %U", unformat_ip6_address,
6354                          &v6_next_hop_address))
6355         {
6356           next_hop_set = 1;
6357           next_hop_proto_is_ip4 = 0;
6358         }
6359       else if (unformat (i, "weight %d", &next_hop_weight))
6360         ;
6361       else if (unformat (i, "create-table"))
6362         create_table_if_needed = 1;
6363       else if (unformat (i, "classify %d", &classify_table_index))
6364         {
6365           is_classify = 1;
6366         }
6367       else if (unformat (i, "del"))
6368         is_add = 0;
6369       else if (unformat (i, "add"))
6370         is_add = 1;
6371       else if (unformat (i, "resolve-via-host"))
6372         resolve_host = 1;
6373       else if (unformat (i, "resolve-via-attached"))
6374         resolve_attached = 1;
6375       else if (unformat (i, "multipath"))
6376         is_multipath = 1;
6377       else if (unformat (i, "count %d", &count))
6378         ;
6379       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6380         {
6381           next_hop_set = 1;
6382           next_hop_proto_is_ip4 = 1;
6383         }
6384       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6385         {
6386           next_hop_set = 1;
6387           next_hop_proto_is_ip4 = 0;
6388         }
6389       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6390         ;
6391       else if (unformat (i, "via-label %d", &next_hop_via_label))
6392         ;
6393       else if (unformat (i, "out-label %d", &next_hop_out_label))
6394         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6395       else
6396         {
6397           clib_warning ("parse error '%U'", format_unformat_error, i);
6398           return -99;
6399         }
6400     }
6401
6402   if (!next_hop_set && !is_classify)
6403     {
6404       errmsg ("next hop / classify not set");
6405       return -99;
6406     }
6407
6408   if (MPLS_LABEL_INVALID == local_label)
6409     {
6410       errmsg ("missing label");
6411       return -99;
6412     }
6413
6414   if (count > 1)
6415     {
6416       /* Turn on async mode */
6417       vam->async_mode = 1;
6418       vam->async_errors = 0;
6419       before = vat_time_now (vam);
6420     }
6421
6422   for (j = 0; j < count; j++)
6423     {
6424       /* Construct the API message */
6425       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6426           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6427
6428       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6429       mp->mr_table_id = ntohl (table_id);
6430       mp->mr_create_table_if_needed = create_table_if_needed;
6431
6432       mp->mr_is_add = is_add;
6433       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6434       mp->mr_is_classify = is_classify;
6435       mp->mr_is_multipath = is_multipath;
6436       mp->mr_is_resolve_host = resolve_host;
6437       mp->mr_is_resolve_attached = resolve_attached;
6438       mp->mr_next_hop_weight = next_hop_weight;
6439       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6440       mp->mr_classify_table_index = ntohl (classify_table_index);
6441       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6442       mp->mr_label = ntohl (local_label);
6443       mp->mr_eos = is_eos;
6444
6445       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6446       if (0 != mp->mr_next_hop_n_out_labels)
6447         {
6448           memcpy (mp->mr_next_hop_out_label_stack,
6449                   next_hop_out_label_stack,
6450                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6451           vec_free (next_hop_out_label_stack);
6452         }
6453
6454       if (next_hop_set)
6455         {
6456           if (next_hop_proto_is_ip4)
6457             {
6458               clib_memcpy (mp->mr_next_hop,
6459                            &v4_next_hop_address,
6460                            sizeof (v4_next_hop_address));
6461             }
6462           else
6463             {
6464               clib_memcpy (mp->mr_next_hop,
6465                            &v6_next_hop_address,
6466                            sizeof (v6_next_hop_address));
6467             }
6468         }
6469       local_label++;
6470
6471       /* send it... */
6472       S;
6473       /* If we receive SIGTERM, stop now... */
6474       if (vam->do_exit)
6475         break;
6476     }
6477
6478   /* When testing multiple add/del ops, use a control-ping to sync */
6479   if (count > 1)
6480     {
6481       vl_api_control_ping_t *mp;
6482       f64 after;
6483
6484       /* Shut off async mode */
6485       vam->async_mode = 0;
6486
6487       M (CONTROL_PING, control_ping);
6488       S;
6489
6490       timeout = vat_time_now (vam) + 1.0;
6491       while (vat_time_now (vam) < timeout)
6492         if (vam->result_ready == 1)
6493           goto out;
6494       vam->retval = -99;
6495
6496     out:
6497       if (vam->retval == -99)
6498         errmsg ("timeout");
6499
6500       if (vam->async_errors > 0)
6501         {
6502           errmsg ("%d asynchronous errors", vam->async_errors);
6503           vam->retval = -98;
6504         }
6505       vam->async_errors = 0;
6506       after = vat_time_now (vam);
6507
6508       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6509       if (j > 0)
6510         count = j;
6511
6512       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6513              count, after - before, count / (after - before));
6514     }
6515   else
6516     {
6517       /* Wait for a reply... */
6518       W;
6519     }
6520
6521   /* Return the good/bad news */
6522   return (vam->retval);
6523 }
6524
6525 static int
6526 api_mpls_ip_bind_unbind (vat_main_t * vam)
6527 {
6528   unformat_input_t *i = vam->input;
6529   vl_api_mpls_ip_bind_unbind_t *mp;
6530   f64 timeout;
6531   u32 ip_table_id = 0;
6532   u8 create_table_if_needed = 0;
6533   u8 is_bind = 1;
6534   u8 is_ip4 = 1;
6535   ip4_address_t v4_address;
6536   ip6_address_t v6_address;
6537   u32 address_length;
6538   u8 address_set = 0;
6539   mpls_label_t local_label = MPLS_LABEL_INVALID;
6540
6541   /* Parse args required to build the message */
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "%U/%d", unformat_ip4_address,
6545                     &v4_address, &address_length))
6546         {
6547           is_ip4 = 1;
6548           address_set = 1;
6549         }
6550       else if (unformat (i, "%U/%d", unformat_ip6_address,
6551                          &v6_address, &address_length))
6552         {
6553           is_ip4 = 0;
6554           address_set = 1;
6555         }
6556       else if (unformat (i, "%d", &local_label))
6557         ;
6558       else if (unformat (i, "create-table"))
6559         create_table_if_needed = 1;
6560       else if (unformat (i, "table-id %d", &ip_table_id))
6561         ;
6562       else if (unformat (i, "unbind"))
6563         is_bind = 0;
6564       else if (unformat (i, "bind"))
6565         is_bind = 1;
6566       else
6567         {
6568           clib_warning ("parse error '%U'", format_unformat_error, i);
6569           return -99;
6570         }
6571     }
6572
6573   if (!address_set)
6574     {
6575       errmsg ("IP addres not set");
6576       return -99;
6577     }
6578
6579   if (MPLS_LABEL_INVALID == local_label)
6580     {
6581       errmsg ("missing label");
6582       return -99;
6583     }
6584
6585   /* Construct the API message */
6586   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6587
6588   mp->mb_create_table_if_needed = create_table_if_needed;
6589   mp->mb_is_bind = is_bind;
6590   mp->mb_is_ip4 = is_ip4;
6591   mp->mb_ip_table_id = ntohl (ip_table_id);
6592   mp->mb_mpls_table_id = 0;
6593   mp->mb_label = ntohl (local_label);
6594   mp->mb_address_length = address_length;
6595
6596   if (is_ip4)
6597     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6598   else
6599     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6600
6601   /* send it... */
6602   S;
6603
6604   /* Wait for a reply... */
6605   W;
6606 }
6607
6608 static int
6609 api_proxy_arp_add_del (vat_main_t * vam)
6610 {
6611   unformat_input_t *i = vam->input;
6612   vl_api_proxy_arp_add_del_t *mp;
6613   f64 timeout;
6614   u32 vrf_id = 0;
6615   u8 is_add = 1;
6616   ip4_address_t lo, hi;
6617   u8 range_set = 0;
6618
6619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6620     {
6621       if (unformat (i, "vrf %d", &vrf_id))
6622         ;
6623       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6624                          unformat_ip4_address, &hi))
6625         range_set = 1;
6626       else if (unformat (i, "del"))
6627         is_add = 0;
6628       else
6629         {
6630           clib_warning ("parse error '%U'", format_unformat_error, i);
6631           return -99;
6632         }
6633     }
6634
6635   if (range_set == 0)
6636     {
6637       errmsg ("address range not set");
6638       return -99;
6639     }
6640
6641   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6642
6643   mp->vrf_id = ntohl (vrf_id);
6644   mp->is_add = is_add;
6645   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6646   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6647
6648   S;
6649   W;
6650   /* NOTREACHED */
6651   return 0;
6652 }
6653
6654 static int
6655 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6656 {
6657   unformat_input_t *i = vam->input;
6658   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6659   f64 timeout;
6660   u32 sw_if_index;
6661   u8 enable = 1;
6662   u8 sw_if_index_set = 0;
6663
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6667         sw_if_index_set = 1;
6668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6669         sw_if_index_set = 1;
6670       else if (unformat (i, "enable"))
6671         enable = 1;
6672       else if (unformat (i, "disable"))
6673         enable = 0;
6674       else
6675         {
6676           clib_warning ("parse error '%U'", format_unformat_error, i);
6677           return -99;
6678         }
6679     }
6680
6681   if (sw_if_index_set == 0)
6682     {
6683       errmsg ("missing interface name or sw_if_index");
6684       return -99;
6685     }
6686
6687   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6688
6689   mp->sw_if_index = ntohl (sw_if_index);
6690   mp->enable_disable = enable;
6691
6692   S;
6693   W;
6694   /* NOTREACHED */
6695   return 0;
6696 }
6697
6698 static int
6699 api_mpls_tunnel_add_del (vat_main_t * vam)
6700 {
6701   unformat_input_t *i = vam->input;
6702   vl_api_mpls_tunnel_add_del_t *mp;
6703   f64 timeout;
6704
6705   u8 is_add = 1;
6706   u8 l2_only = 0;
6707   u32 sw_if_index = ~0;
6708   u32 next_hop_sw_if_index = ~0;
6709   u32 next_hop_proto_is_ip4 = 1;
6710
6711   u32 next_hop_table_id = 0;
6712   ip4_address_t v4_next_hop_address = {
6713     .as_u32 = 0,
6714   };
6715   ip6_address_t v6_next_hop_address = { {0} };
6716   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6717
6718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6719     {
6720       if (unformat (i, "add"))
6721         is_add = 1;
6722       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6723         is_add = 0;
6724       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6725         ;
6726       else if (unformat (i, "via %U",
6727                          unformat_ip4_address, &v4_next_hop_address))
6728         {
6729           next_hop_proto_is_ip4 = 1;
6730         }
6731       else if (unformat (i, "via %U",
6732                          unformat_ip6_address, &v6_next_hop_address))
6733         {
6734           next_hop_proto_is_ip4 = 0;
6735         }
6736       else if (unformat (i, "l2-only"))
6737         l2_only = 1;
6738       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6739         ;
6740       else if (unformat (i, "out-label %d", &next_hop_out_label))
6741         vec_add1 (labels, ntohl (next_hop_out_label));
6742       else
6743         {
6744           clib_warning ("parse error '%U'", format_unformat_error, i);
6745           return -99;
6746         }
6747     }
6748
6749   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6750       sizeof (mpls_label_t) * vec_len (labels));
6751
6752   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6753   mp->mt_sw_if_index = ntohl (sw_if_index);
6754   mp->mt_is_add = is_add;
6755   mp->mt_l2_only = l2_only;
6756   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6757   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6758
6759   mp->mt_next_hop_n_out_labels = vec_len (labels);
6760
6761   if (0 != mp->mt_next_hop_n_out_labels)
6762     {
6763       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6764                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6765       vec_free (labels);
6766     }
6767
6768   if (next_hop_proto_is_ip4)
6769     {
6770       clib_memcpy (mp->mt_next_hop,
6771                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6772     }
6773   else
6774     {
6775       clib_memcpy (mp->mt_next_hop,
6776                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6777     }
6778
6779   S;
6780   W;
6781   /* NOTREACHED */
6782   return 0;
6783 }
6784
6785 static int
6786 api_sw_interface_set_unnumbered (vat_main_t * vam)
6787 {
6788   unformat_input_t *i = vam->input;
6789   vl_api_sw_interface_set_unnumbered_t *mp;
6790   f64 timeout;
6791   u32 sw_if_index;
6792   u32 unnum_sw_index = ~0;
6793   u8 is_add = 1;
6794   u8 sw_if_index_set = 0;
6795
6796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6797     {
6798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6799         sw_if_index_set = 1;
6800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6801         sw_if_index_set = 1;
6802       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6803         ;
6804       else if (unformat (i, "del"))
6805         is_add = 0;
6806       else
6807         {
6808           clib_warning ("parse error '%U'", format_unformat_error, i);
6809           return -99;
6810         }
6811     }
6812
6813   if (sw_if_index_set == 0)
6814     {
6815       errmsg ("missing interface name or sw_if_index");
6816       return -99;
6817     }
6818
6819   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6820
6821   mp->sw_if_index = ntohl (sw_if_index);
6822   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6823   mp->is_add = is_add;
6824
6825   S;
6826   W;
6827   /* NOTREACHED */
6828   return 0;
6829 }
6830
6831 static int
6832 api_ip_neighbor_add_del (vat_main_t * vam)
6833 {
6834   unformat_input_t *i = vam->input;
6835   vl_api_ip_neighbor_add_del_t *mp;
6836   f64 timeout;
6837   u32 sw_if_index;
6838   u8 sw_if_index_set = 0;
6839   u32 vrf_id = 0;
6840   u8 is_add = 1;
6841   u8 is_static = 0;
6842   u8 mac_address[6];
6843   u8 mac_set = 0;
6844   u8 v4_address_set = 0;
6845   u8 v6_address_set = 0;
6846   ip4_address_t v4address;
6847   ip6_address_t v6address;
6848
6849   memset (mac_address, 0, sizeof (mac_address));
6850
6851   /* Parse args required to build the message */
6852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6853     {
6854       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6855         {
6856           mac_set = 1;
6857         }
6858       else if (unformat (i, "del"))
6859         is_add = 0;
6860       else
6861         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6862         sw_if_index_set = 1;
6863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6864         sw_if_index_set = 1;
6865       else if (unformat (i, "is_static"))
6866         is_static = 1;
6867       else if (unformat (i, "vrf %d", &vrf_id))
6868         ;
6869       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6870         v4_address_set = 1;
6871       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6872         v6_address_set = 1;
6873       else
6874         {
6875           clib_warning ("parse error '%U'", format_unformat_error, i);
6876           return -99;
6877         }
6878     }
6879
6880   if (sw_if_index_set == 0)
6881     {
6882       errmsg ("missing interface name or sw_if_index");
6883       return -99;
6884     }
6885   if (v4_address_set && v6_address_set)
6886     {
6887       errmsg ("both v4 and v6 addresses set");
6888       return -99;
6889     }
6890   if (!v4_address_set && !v6_address_set)
6891     {
6892       errmsg ("no address set");
6893       return -99;
6894     }
6895
6896   /* Construct the API message */
6897   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6898
6899   mp->sw_if_index = ntohl (sw_if_index);
6900   mp->is_add = is_add;
6901   mp->vrf_id = ntohl (vrf_id);
6902   mp->is_static = is_static;
6903   if (mac_set)
6904     clib_memcpy (mp->mac_address, mac_address, 6);
6905   if (v6_address_set)
6906     {
6907       mp->is_ipv6 = 1;
6908       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6909     }
6910   else
6911     {
6912       /* mp->is_ipv6 = 0; via memset in M macro above */
6913       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6914     }
6915
6916   /* send it... */
6917   S;
6918
6919   /* Wait for a reply, return good/bad news  */
6920   W;
6921
6922   /* NOTREACHED */
6923   return 0;
6924 }
6925
6926 static int
6927 api_reset_vrf (vat_main_t * vam)
6928 {
6929   unformat_input_t *i = vam->input;
6930   vl_api_reset_vrf_t *mp;
6931   f64 timeout;
6932   u32 vrf_id = 0;
6933   u8 is_ipv6 = 0;
6934   u8 vrf_id_set = 0;
6935
6936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6937     {
6938       if (unformat (i, "vrf %d", &vrf_id))
6939         vrf_id_set = 1;
6940       else if (unformat (i, "ipv6"))
6941         is_ipv6 = 1;
6942       else
6943         {
6944           clib_warning ("parse error '%U'", format_unformat_error, i);
6945           return -99;
6946         }
6947     }
6948
6949   if (vrf_id_set == 0)
6950     {
6951       errmsg ("missing vrf id");
6952       return -99;
6953     }
6954
6955   M (RESET_VRF, reset_vrf);
6956
6957   mp->vrf_id = ntohl (vrf_id);
6958   mp->is_ipv6 = is_ipv6;
6959
6960   S;
6961   W;
6962   /* NOTREACHED */
6963   return 0;
6964 }
6965
6966 static int
6967 api_create_vlan_subif (vat_main_t * vam)
6968 {
6969   unformat_input_t *i = vam->input;
6970   vl_api_create_vlan_subif_t *mp;
6971   f64 timeout;
6972   u32 sw_if_index;
6973   u8 sw_if_index_set = 0;
6974   u32 vlan_id;
6975   u8 vlan_id_set = 0;
6976
6977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978     {
6979       if (unformat (i, "sw_if_index %d", &sw_if_index))
6980         sw_if_index_set = 1;
6981       else
6982         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6983         sw_if_index_set = 1;
6984       else if (unformat (i, "vlan %d", &vlan_id))
6985         vlan_id_set = 1;
6986       else
6987         {
6988           clib_warning ("parse error '%U'", format_unformat_error, i);
6989           return -99;
6990         }
6991     }
6992
6993   if (sw_if_index_set == 0)
6994     {
6995       errmsg ("missing interface name or sw_if_index");
6996       return -99;
6997     }
6998
6999   if (vlan_id_set == 0)
7000     {
7001       errmsg ("missing vlan_id");
7002       return -99;
7003     }
7004   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7005
7006   mp->sw_if_index = ntohl (sw_if_index);
7007   mp->vlan_id = ntohl (vlan_id);
7008
7009   S;
7010   W;
7011   /* NOTREACHED */
7012   return 0;
7013 }
7014
7015 #define foreach_create_subif_bit                \
7016 _(no_tags)                                      \
7017 _(one_tag)                                      \
7018 _(two_tags)                                     \
7019 _(dot1ad)                                       \
7020 _(exact_match)                                  \
7021 _(default_sub)                                  \
7022 _(outer_vlan_id_any)                            \
7023 _(inner_vlan_id_any)
7024
7025 static int
7026 api_create_subif (vat_main_t * vam)
7027 {
7028   unformat_input_t *i = vam->input;
7029   vl_api_create_subif_t *mp;
7030   f64 timeout;
7031   u32 sw_if_index;
7032   u8 sw_if_index_set = 0;
7033   u32 sub_id;
7034   u8 sub_id_set = 0;
7035   u32 no_tags = 0;
7036   u32 one_tag = 0;
7037   u32 two_tags = 0;
7038   u32 dot1ad = 0;
7039   u32 exact_match = 0;
7040   u32 default_sub = 0;
7041   u32 outer_vlan_id_any = 0;
7042   u32 inner_vlan_id_any = 0;
7043   u32 tmp;
7044   u16 outer_vlan_id = 0;
7045   u16 inner_vlan_id = 0;
7046
7047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048     {
7049       if (unformat (i, "sw_if_index %d", &sw_if_index))
7050         sw_if_index_set = 1;
7051       else
7052         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7053         sw_if_index_set = 1;
7054       else if (unformat (i, "sub_id %d", &sub_id))
7055         sub_id_set = 1;
7056       else if (unformat (i, "outer_vlan_id %d", &tmp))
7057         outer_vlan_id = tmp;
7058       else if (unformat (i, "inner_vlan_id %d", &tmp))
7059         inner_vlan_id = tmp;
7060
7061 #define _(a) else if (unformat (i, #a)) a = 1 ;
7062       foreach_create_subif_bit
7063 #undef _
7064         else
7065         {
7066           clib_warning ("parse error '%U'", format_unformat_error, i);
7067           return -99;
7068         }
7069     }
7070
7071   if (sw_if_index_set == 0)
7072     {
7073       errmsg ("missing interface name or sw_if_index");
7074       return -99;
7075     }
7076
7077   if (sub_id_set == 0)
7078     {
7079       errmsg ("missing sub_id");
7080       return -99;
7081     }
7082   M (CREATE_SUBIF, create_subif);
7083
7084   mp->sw_if_index = ntohl (sw_if_index);
7085   mp->sub_id = ntohl (sub_id);
7086
7087 #define _(a) mp->a = a;
7088   foreach_create_subif_bit;
7089 #undef _
7090
7091   mp->outer_vlan_id = ntohs (outer_vlan_id);
7092   mp->inner_vlan_id = ntohs (inner_vlan_id);
7093
7094   S;
7095   W;
7096   /* NOTREACHED */
7097   return 0;
7098 }
7099
7100 static int
7101 api_oam_add_del (vat_main_t * vam)
7102 {
7103   unformat_input_t *i = vam->input;
7104   vl_api_oam_add_del_t *mp;
7105   f64 timeout;
7106   u32 vrf_id = 0;
7107   u8 is_add = 1;
7108   ip4_address_t src, dst;
7109   u8 src_set = 0;
7110   u8 dst_set = 0;
7111
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "vrf %d", &vrf_id))
7115         ;
7116       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7117         src_set = 1;
7118       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7119         dst_set = 1;
7120       else if (unformat (i, "del"))
7121         is_add = 0;
7122       else
7123         {
7124           clib_warning ("parse error '%U'", format_unformat_error, i);
7125           return -99;
7126         }
7127     }
7128
7129   if (src_set == 0)
7130     {
7131       errmsg ("missing src addr");
7132       return -99;
7133     }
7134
7135   if (dst_set == 0)
7136     {
7137       errmsg ("missing dst addr");
7138       return -99;
7139     }
7140
7141   M (OAM_ADD_DEL, oam_add_del);
7142
7143   mp->vrf_id = ntohl (vrf_id);
7144   mp->is_add = is_add;
7145   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7146   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7147
7148   S;
7149   W;
7150   /* NOTREACHED */
7151   return 0;
7152 }
7153
7154 static int
7155 api_reset_fib (vat_main_t * vam)
7156 {
7157   unformat_input_t *i = vam->input;
7158   vl_api_reset_fib_t *mp;
7159   f64 timeout;
7160   u32 vrf_id = 0;
7161   u8 is_ipv6 = 0;
7162   u8 vrf_id_set = 0;
7163
7164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7165     {
7166       if (unformat (i, "vrf %d", &vrf_id))
7167         vrf_id_set = 1;
7168       else if (unformat (i, "ipv6"))
7169         is_ipv6 = 1;
7170       else
7171         {
7172           clib_warning ("parse error '%U'", format_unformat_error, i);
7173           return -99;
7174         }
7175     }
7176
7177   if (vrf_id_set == 0)
7178     {
7179       errmsg ("missing vrf id");
7180       return -99;
7181     }
7182
7183   M (RESET_FIB, reset_fib);
7184
7185   mp->vrf_id = ntohl (vrf_id);
7186   mp->is_ipv6 = is_ipv6;
7187
7188   S;
7189   W;
7190   /* NOTREACHED */
7191   return 0;
7192 }
7193
7194 static int
7195 api_dhcp_proxy_config (vat_main_t * vam)
7196 {
7197   unformat_input_t *i = vam->input;
7198   vl_api_dhcp_proxy_config_t *mp;
7199   f64 timeout;
7200   u32 vrf_id = 0;
7201   u8 is_add = 1;
7202   u8 insert_cid = 1;
7203   u8 v4_address_set = 0;
7204   u8 v6_address_set = 0;
7205   ip4_address_t v4address;
7206   ip6_address_t v6address;
7207   u8 v4_src_address_set = 0;
7208   u8 v6_src_address_set = 0;
7209   ip4_address_t v4srcaddress;
7210   ip6_address_t v6srcaddress;
7211
7212   /* Parse args required to build the message */
7213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7214     {
7215       if (unformat (i, "del"))
7216         is_add = 0;
7217       else if (unformat (i, "vrf %d", &vrf_id))
7218         ;
7219       else if (unformat (i, "insert-cid %d", &insert_cid))
7220         ;
7221       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7222         v4_address_set = 1;
7223       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7224         v6_address_set = 1;
7225       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7226         v4_src_address_set = 1;
7227       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7228         v6_src_address_set = 1;
7229       else
7230         break;
7231     }
7232
7233   if (v4_address_set && v6_address_set)
7234     {
7235       errmsg ("both v4 and v6 server addresses set");
7236       return -99;
7237     }
7238   if (!v4_address_set && !v6_address_set)
7239     {
7240       errmsg ("no server addresses set");
7241       return -99;
7242     }
7243
7244   if (v4_src_address_set && v6_src_address_set)
7245     {
7246       errmsg ("both v4 and v6  src addresses set");
7247       return -99;
7248     }
7249   if (!v4_src_address_set && !v6_src_address_set)
7250     {
7251       errmsg ("no src addresses set");
7252       return -99;
7253     }
7254
7255   if (!(v4_src_address_set && v4_address_set) &&
7256       !(v6_src_address_set && v6_address_set))
7257     {
7258       errmsg ("no matching server and src addresses set");
7259       return -99;
7260     }
7261
7262   /* Construct the API message */
7263   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7264
7265   mp->insert_circuit_id = insert_cid;
7266   mp->is_add = is_add;
7267   mp->vrf_id = ntohl (vrf_id);
7268   if (v6_address_set)
7269     {
7270       mp->is_ipv6 = 1;
7271       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7272       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7273     }
7274   else
7275     {
7276       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7277       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7278     }
7279
7280   /* send it... */
7281   S;
7282
7283   /* Wait for a reply, return good/bad news  */
7284   W;
7285   /* NOTREACHED */
7286   return 0;
7287 }
7288
7289 static int
7290 api_dhcp_proxy_config_2 (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_dhcp_proxy_config_2_t *mp;
7294   f64 timeout;
7295   u32 rx_vrf_id = 0;
7296   u32 server_vrf_id = 0;
7297   u8 is_add = 1;
7298   u8 insert_cid = 1;
7299   u8 v4_address_set = 0;
7300   u8 v6_address_set = 0;
7301   ip4_address_t v4address;
7302   ip6_address_t v6address;
7303   u8 v4_src_address_set = 0;
7304   u8 v6_src_address_set = 0;
7305   ip4_address_t v4srcaddress;
7306   ip6_address_t v6srcaddress;
7307
7308   /* Parse args required to build the message */
7309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7310     {
7311       if (unformat (i, "del"))
7312         is_add = 0;
7313       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7314         ;
7315       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7316         ;
7317       else if (unformat (i, "insert-cid %d", &insert_cid))
7318         ;
7319       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7320         v4_address_set = 1;
7321       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7322         v6_address_set = 1;
7323       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7324         v4_src_address_set = 1;
7325       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7326         v6_src_address_set = 1;
7327       else
7328         break;
7329     }
7330
7331   if (v4_address_set && v6_address_set)
7332     {
7333       errmsg ("both v4 and v6 server addresses set");
7334       return -99;
7335     }
7336   if (!v4_address_set && !v6_address_set)
7337     {
7338       errmsg ("no server addresses set");
7339       return -99;
7340     }
7341
7342   if (v4_src_address_set && v6_src_address_set)
7343     {
7344       errmsg ("both v4 and v6  src addresses set");
7345       return -99;
7346     }
7347   if (!v4_src_address_set && !v6_src_address_set)
7348     {
7349       errmsg ("no src addresses set");
7350       return -99;
7351     }
7352
7353   if (!(v4_src_address_set && v4_address_set) &&
7354       !(v6_src_address_set && v6_address_set))
7355     {
7356       errmsg ("no matching server and src addresses set");
7357       return -99;
7358     }
7359
7360   /* Construct the API message */
7361   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7362
7363   mp->insert_circuit_id = insert_cid;
7364   mp->is_add = is_add;
7365   mp->rx_vrf_id = ntohl (rx_vrf_id);
7366   mp->server_vrf_id = ntohl (server_vrf_id);
7367   if (v6_address_set)
7368     {
7369       mp->is_ipv6 = 1;
7370       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7371       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7372     }
7373   else
7374     {
7375       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7376       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7377     }
7378
7379   /* send it... */
7380   S;
7381
7382   /* Wait for a reply, return good/bad news  */
7383   W;
7384   /* NOTREACHED */
7385   return 0;
7386 }
7387
7388 static int
7389 api_dhcp_proxy_set_vss (vat_main_t * vam)
7390 {
7391   unformat_input_t *i = vam->input;
7392   vl_api_dhcp_proxy_set_vss_t *mp;
7393   f64 timeout;
7394   u8 is_ipv6 = 0;
7395   u8 is_add = 1;
7396   u32 tbl_id;
7397   u8 tbl_id_set = 0;
7398   u32 oui;
7399   u8 oui_set = 0;
7400   u32 fib_id;
7401   u8 fib_id_set = 0;
7402
7403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7404     {
7405       if (unformat (i, "tbl_id %d", &tbl_id))
7406         tbl_id_set = 1;
7407       if (unformat (i, "fib_id %d", &fib_id))
7408         fib_id_set = 1;
7409       if (unformat (i, "oui %d", &oui))
7410         oui_set = 1;
7411       else if (unformat (i, "ipv6"))
7412         is_ipv6 = 1;
7413       else if (unformat (i, "del"))
7414         is_add = 0;
7415       else
7416         {
7417           clib_warning ("parse error '%U'", format_unformat_error, i);
7418           return -99;
7419         }
7420     }
7421
7422   if (tbl_id_set == 0)
7423     {
7424       errmsg ("missing tbl id");
7425       return -99;
7426     }
7427
7428   if (fib_id_set == 0)
7429     {
7430       errmsg ("missing fib id");
7431       return -99;
7432     }
7433   if (oui_set == 0)
7434     {
7435       errmsg ("missing oui");
7436       return -99;
7437     }
7438
7439   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7440   mp->tbl_id = ntohl (tbl_id);
7441   mp->fib_id = ntohl (fib_id);
7442   mp->oui = ntohl (oui);
7443   mp->is_ipv6 = is_ipv6;
7444   mp->is_add = is_add;
7445
7446   S;
7447   W;
7448   /* NOTREACHED */
7449   return 0;
7450 }
7451
7452 static int
7453 api_dhcp_client_config (vat_main_t * vam)
7454 {
7455   unformat_input_t *i = vam->input;
7456   vl_api_dhcp_client_config_t *mp;
7457   f64 timeout;
7458   u32 sw_if_index;
7459   u8 sw_if_index_set = 0;
7460   u8 is_add = 1;
7461   u8 *hostname = 0;
7462   u8 disable_event = 0;
7463
7464   /* Parse args required to build the message */
7465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466     {
7467       if (unformat (i, "del"))
7468         is_add = 0;
7469       else
7470         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7473         sw_if_index_set = 1;
7474       else if (unformat (i, "hostname %s", &hostname))
7475         ;
7476       else if (unformat (i, "disable_event"))
7477         disable_event = 1;
7478       else
7479         break;
7480     }
7481
7482   if (sw_if_index_set == 0)
7483     {
7484       errmsg ("missing interface name or sw_if_index");
7485       return -99;
7486     }
7487
7488   if (vec_len (hostname) > 63)
7489     {
7490       errmsg ("hostname too long");
7491     }
7492   vec_add1 (hostname, 0);
7493
7494   /* Construct the API message */
7495   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7496
7497   mp->sw_if_index = ntohl (sw_if_index);
7498   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7499   vec_free (hostname);
7500   mp->is_add = is_add;
7501   mp->want_dhcp_event = disable_event ? 0 : 1;
7502   mp->pid = getpid ();
7503
7504   /* send it... */
7505   S;
7506
7507   /* Wait for a reply, return good/bad news  */
7508   W;
7509   /* NOTREACHED */
7510   return 0;
7511 }
7512
7513 static int
7514 api_set_ip_flow_hash (vat_main_t * vam)
7515 {
7516   unformat_input_t *i = vam->input;
7517   vl_api_set_ip_flow_hash_t *mp;
7518   f64 timeout;
7519   u32 vrf_id = 0;
7520   u8 is_ipv6 = 0;
7521   u8 vrf_id_set = 0;
7522   u8 src = 0;
7523   u8 dst = 0;
7524   u8 sport = 0;
7525   u8 dport = 0;
7526   u8 proto = 0;
7527   u8 reverse = 0;
7528
7529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7530     {
7531       if (unformat (i, "vrf %d", &vrf_id))
7532         vrf_id_set = 1;
7533       else if (unformat (i, "ipv6"))
7534         is_ipv6 = 1;
7535       else if (unformat (i, "src"))
7536         src = 1;
7537       else if (unformat (i, "dst"))
7538         dst = 1;
7539       else if (unformat (i, "sport"))
7540         sport = 1;
7541       else if (unformat (i, "dport"))
7542         dport = 1;
7543       else if (unformat (i, "proto"))
7544         proto = 1;
7545       else if (unformat (i, "reverse"))
7546         reverse = 1;
7547
7548       else
7549         {
7550           clib_warning ("parse error '%U'", format_unformat_error, i);
7551           return -99;
7552         }
7553     }
7554
7555   if (vrf_id_set == 0)
7556     {
7557       errmsg ("missing vrf id");
7558       return -99;
7559     }
7560
7561   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7562   mp->src = src;
7563   mp->dst = dst;
7564   mp->sport = sport;
7565   mp->dport = dport;
7566   mp->proto = proto;
7567   mp->reverse = reverse;
7568   mp->vrf_id = ntohl (vrf_id);
7569   mp->is_ipv6 = is_ipv6;
7570
7571   S;
7572   W;
7573   /* NOTREACHED */
7574   return 0;
7575 }
7576
7577 static int
7578 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7579 {
7580   unformat_input_t *i = vam->input;
7581   vl_api_sw_interface_ip6_enable_disable_t *mp;
7582   f64 timeout;
7583   u32 sw_if_index;
7584   u8 sw_if_index_set = 0;
7585   u8 enable = 0;
7586
7587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7590         sw_if_index_set = 1;
7591       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7592         sw_if_index_set = 1;
7593       else if (unformat (i, "enable"))
7594         enable = 1;
7595       else if (unformat (i, "disable"))
7596         enable = 0;
7597       else
7598         {
7599           clib_warning ("parse error '%U'", format_unformat_error, i);
7600           return -99;
7601         }
7602     }
7603
7604   if (sw_if_index_set == 0)
7605     {
7606       errmsg ("missing interface name or sw_if_index");
7607       return -99;
7608     }
7609
7610   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7611
7612   mp->sw_if_index = ntohl (sw_if_index);
7613   mp->enable = enable;
7614
7615   S;
7616   W;
7617   /* NOTREACHED */
7618   return 0;
7619 }
7620
7621 static int
7622 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7623 {
7624   unformat_input_t *i = vam->input;
7625   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7626   f64 timeout;
7627   u32 sw_if_index;
7628   u8 sw_if_index_set = 0;
7629   u32 address_length = 0;
7630   u8 v6_address_set = 0;
7631   ip6_address_t v6address;
7632
7633   /* Parse args required to build the message */
7634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7635     {
7636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7637         sw_if_index_set = 1;
7638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7639         sw_if_index_set = 1;
7640       else if (unformat (i, "%U/%d",
7641                          unformat_ip6_address, &v6address, &address_length))
7642         v6_address_set = 1;
7643       else
7644         break;
7645     }
7646
7647   if (sw_if_index_set == 0)
7648     {
7649       errmsg ("missing interface name or sw_if_index");
7650       return -99;
7651     }
7652   if (!v6_address_set)
7653     {
7654       errmsg ("no address set");
7655       return -99;
7656     }
7657
7658   /* Construct the API message */
7659   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7660      sw_interface_ip6_set_link_local_address);
7661
7662   mp->sw_if_index = ntohl (sw_if_index);
7663   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7664   mp->address_length = address_length;
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
7677 static int
7678 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7679 {
7680   unformat_input_t *i = vam->input;
7681   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7682   f64 timeout;
7683   u32 sw_if_index;
7684   u8 sw_if_index_set = 0;
7685   u32 address_length = 0;
7686   u8 v6_address_set = 0;
7687   ip6_address_t v6address;
7688   u8 use_default = 0;
7689   u8 no_advertise = 0;
7690   u8 off_link = 0;
7691   u8 no_autoconfig = 0;
7692   u8 no_onlink = 0;
7693   u8 is_no = 0;
7694   u32 val_lifetime = 0;
7695   u32 pref_lifetime = 0;
7696
7697   /* Parse args required to build the message */
7698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7699     {
7700       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7701         sw_if_index_set = 1;
7702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7703         sw_if_index_set = 1;
7704       else if (unformat (i, "%U/%d",
7705                          unformat_ip6_address, &v6address, &address_length))
7706         v6_address_set = 1;
7707       else if (unformat (i, "val_life %d", &val_lifetime))
7708         ;
7709       else if (unformat (i, "pref_life %d", &pref_lifetime))
7710         ;
7711       else if (unformat (i, "def"))
7712         use_default = 1;
7713       else if (unformat (i, "noadv"))
7714         no_advertise = 1;
7715       else if (unformat (i, "offl"))
7716         off_link = 1;
7717       else if (unformat (i, "noauto"))
7718         no_autoconfig = 1;
7719       else if (unformat (i, "nolink"))
7720         no_onlink = 1;
7721       else if (unformat (i, "isno"))
7722         is_no = 1;
7723       else
7724         {
7725           clib_warning ("parse error '%U'", format_unformat_error, i);
7726           return -99;
7727         }
7728     }
7729
7730   if (sw_if_index_set == 0)
7731     {
7732       errmsg ("missing interface name or sw_if_index");
7733       return -99;
7734     }
7735   if (!v6_address_set)
7736     {
7737       errmsg ("no address set");
7738       return -99;
7739     }
7740
7741   /* Construct the API message */
7742   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7743
7744   mp->sw_if_index = ntohl (sw_if_index);
7745   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7746   mp->address_length = address_length;
7747   mp->use_default = use_default;
7748   mp->no_advertise = no_advertise;
7749   mp->off_link = off_link;
7750   mp->no_autoconfig = no_autoconfig;
7751   mp->no_onlink = no_onlink;
7752   mp->is_no = is_no;
7753   mp->val_lifetime = ntohl (val_lifetime);
7754   mp->pref_lifetime = ntohl (pref_lifetime);
7755
7756   /* send it... */
7757   S;
7758
7759   /* Wait for a reply, return good/bad news  */
7760   W;
7761
7762   /* NOTREACHED */
7763   return 0;
7764 }
7765
7766 static int
7767 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7768 {
7769   unformat_input_t *i = vam->input;
7770   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7771   f64 timeout;
7772   u32 sw_if_index;
7773   u8 sw_if_index_set = 0;
7774   u8 suppress = 0;
7775   u8 managed = 0;
7776   u8 other = 0;
7777   u8 ll_option = 0;
7778   u8 send_unicast = 0;
7779   u8 cease = 0;
7780   u8 is_no = 0;
7781   u8 default_router = 0;
7782   u32 max_interval = 0;
7783   u32 min_interval = 0;
7784   u32 lifetime = 0;
7785   u32 initial_count = 0;
7786   u32 initial_interval = 0;
7787
7788
7789   /* Parse args required to build the message */
7790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7791     {
7792       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7793         sw_if_index_set = 1;
7794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7795         sw_if_index_set = 1;
7796       else if (unformat (i, "maxint %d", &max_interval))
7797         ;
7798       else if (unformat (i, "minint %d", &min_interval))
7799         ;
7800       else if (unformat (i, "life %d", &lifetime))
7801         ;
7802       else if (unformat (i, "count %d", &initial_count))
7803         ;
7804       else if (unformat (i, "interval %d", &initial_interval))
7805         ;
7806       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7807         suppress = 1;
7808       else if (unformat (i, "managed"))
7809         managed = 1;
7810       else if (unformat (i, "other"))
7811         other = 1;
7812       else if (unformat (i, "ll"))
7813         ll_option = 1;
7814       else if (unformat (i, "send"))
7815         send_unicast = 1;
7816       else if (unformat (i, "cease"))
7817         cease = 1;
7818       else if (unformat (i, "isno"))
7819         is_no = 1;
7820       else if (unformat (i, "def"))
7821         default_router = 1;
7822       else
7823         {
7824           clib_warning ("parse error '%U'", format_unformat_error, i);
7825           return -99;
7826         }
7827     }
7828
7829   if (sw_if_index_set == 0)
7830     {
7831       errmsg ("missing interface name or sw_if_index");
7832       return -99;
7833     }
7834
7835   /* Construct the API message */
7836   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7837
7838   mp->sw_if_index = ntohl (sw_if_index);
7839   mp->max_interval = ntohl (max_interval);
7840   mp->min_interval = ntohl (min_interval);
7841   mp->lifetime = ntohl (lifetime);
7842   mp->initial_count = ntohl (initial_count);
7843   mp->initial_interval = ntohl (initial_interval);
7844   mp->suppress = suppress;
7845   mp->managed = managed;
7846   mp->other = other;
7847   mp->ll_option = ll_option;
7848   mp->send_unicast = send_unicast;
7849   mp->cease = cease;
7850   mp->is_no = is_no;
7851   mp->default_router = default_router;
7852
7853   /* send it... */
7854   S;
7855
7856   /* Wait for a reply, return good/bad news  */
7857   W;
7858
7859   /* NOTREACHED */
7860   return 0;
7861 }
7862
7863 static int
7864 api_set_arp_neighbor_limit (vat_main_t * vam)
7865 {
7866   unformat_input_t *i = vam->input;
7867   vl_api_set_arp_neighbor_limit_t *mp;
7868   f64 timeout;
7869   u32 arp_nbr_limit;
7870   u8 limit_set = 0;
7871   u8 is_ipv6 = 0;
7872
7873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7874     {
7875       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7876         limit_set = 1;
7877       else if (unformat (i, "ipv6"))
7878         is_ipv6 = 1;
7879       else
7880         {
7881           clib_warning ("parse error '%U'", format_unformat_error, i);
7882           return -99;
7883         }
7884     }
7885
7886   if (limit_set == 0)
7887     {
7888       errmsg ("missing limit value");
7889       return -99;
7890     }
7891
7892   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7893
7894   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7895   mp->is_ipv6 = is_ipv6;
7896
7897   S;
7898   W;
7899   /* NOTREACHED */
7900   return 0;
7901 }
7902
7903 static int
7904 api_l2_patch_add_del (vat_main_t * vam)
7905 {
7906   unformat_input_t *i = vam->input;
7907   vl_api_l2_patch_add_del_t *mp;
7908   f64 timeout;
7909   u32 rx_sw_if_index;
7910   u8 rx_sw_if_index_set = 0;
7911   u32 tx_sw_if_index;
7912   u8 tx_sw_if_index_set = 0;
7913   u8 is_add = 1;
7914
7915   /* Parse args required to build the message */
7916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7917     {
7918       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7919         rx_sw_if_index_set = 1;
7920       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7921         tx_sw_if_index_set = 1;
7922       else if (unformat (i, "rx"))
7923         {
7924           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7925             {
7926               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7927                             &rx_sw_if_index))
7928                 rx_sw_if_index_set = 1;
7929             }
7930           else
7931             break;
7932         }
7933       else if (unformat (i, "tx"))
7934         {
7935           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7936             {
7937               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7938                             &tx_sw_if_index))
7939                 tx_sw_if_index_set = 1;
7940             }
7941           else
7942             break;
7943         }
7944       else if (unformat (i, "del"))
7945         is_add = 0;
7946       else
7947         break;
7948     }
7949
7950   if (rx_sw_if_index_set == 0)
7951     {
7952       errmsg ("missing rx interface name or rx_sw_if_index");
7953       return -99;
7954     }
7955
7956   if (tx_sw_if_index_set == 0)
7957     {
7958       errmsg ("missing tx interface name or tx_sw_if_index");
7959       return -99;
7960     }
7961
7962   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7963
7964   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7965   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7966   mp->is_add = is_add;
7967
7968   S;
7969   W;
7970   /* NOTREACHED */
7971   return 0;
7972 }
7973
7974 static int
7975 api_ioam_enable (vat_main_t * vam)
7976 {
7977   unformat_input_t *input = vam->input;
7978   vl_api_ioam_enable_t *mp;
7979   f64 timeout;
7980   u32 id = 0;
7981   int has_trace_option = 0;
7982   int has_pot_option = 0;
7983   int has_seqno_option = 0;
7984   int has_analyse_option = 0;
7985
7986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7987     {
7988       if (unformat (input, "trace"))
7989         has_trace_option = 1;
7990       else if (unformat (input, "pot"))
7991         has_pot_option = 1;
7992       else if (unformat (input, "seqno"))
7993         has_seqno_option = 1;
7994       else if (unformat (input, "analyse"))
7995         has_analyse_option = 1;
7996       else
7997         break;
7998     }
7999   M (IOAM_ENABLE, ioam_enable);
8000   mp->id = htons (id);
8001   mp->seqno = has_seqno_option;
8002   mp->analyse = has_analyse_option;
8003   mp->pot_enable = has_pot_option;
8004   mp->trace_enable = has_trace_option;
8005
8006   S;
8007   W;
8008
8009   return (0);
8010
8011 }
8012
8013
8014 static int
8015 api_ioam_disable (vat_main_t * vam)
8016 {
8017   vl_api_ioam_disable_t *mp;
8018   f64 timeout;
8019
8020   M (IOAM_DISABLE, ioam_disable);
8021   S;
8022   W;
8023   return 0;
8024 }
8025
8026 static int
8027 api_sr_tunnel_add_del (vat_main_t * vam)
8028 {
8029   unformat_input_t *i = vam->input;
8030   vl_api_sr_tunnel_add_del_t *mp;
8031   f64 timeout;
8032   int is_del = 0;
8033   int pl_index;
8034   ip6_address_t src_address;
8035   int src_address_set = 0;
8036   ip6_address_t dst_address;
8037   u32 dst_mask_width;
8038   int dst_address_set = 0;
8039   u16 flags = 0;
8040   u32 rx_table_id = 0;
8041   u32 tx_table_id = 0;
8042   ip6_address_t *segments = 0;
8043   ip6_address_t *this_seg;
8044   ip6_address_t *tags = 0;
8045   ip6_address_t *this_tag;
8046   ip6_address_t next_address, tag;
8047   u8 *name = 0;
8048   u8 *policy_name = 0;
8049
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "del"))
8053         is_del = 1;
8054       else if (unformat (i, "name %s", &name))
8055         ;
8056       else if (unformat (i, "policy %s", &policy_name))
8057         ;
8058       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8059         ;
8060       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8061         ;
8062       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8063         src_address_set = 1;
8064       else if (unformat (i, "dst %U/%d",
8065                          unformat_ip6_address, &dst_address, &dst_mask_width))
8066         dst_address_set = 1;
8067       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8068         {
8069           vec_add2 (segments, this_seg, 1);
8070           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8071                        sizeof (*this_seg));
8072         }
8073       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8074         {
8075           vec_add2 (tags, this_tag, 1);
8076           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8077         }
8078       else if (unformat (i, "clean"))
8079         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8080       else if (unformat (i, "protected"))
8081         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8082       else if (unformat (i, "InPE %d", &pl_index))
8083         {
8084           if (pl_index <= 0 || pl_index > 4)
8085             {
8086             pl_index_range_error:
8087               errmsg ("pl index %d out of range", pl_index);
8088               return -99;
8089             }
8090           flags |=
8091             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8092         }
8093       else if (unformat (i, "EgPE %d", &pl_index))
8094         {
8095           if (pl_index <= 0 || pl_index > 4)
8096             goto pl_index_range_error;
8097           flags |=
8098             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8099         }
8100       else if (unformat (i, "OrgSrc %d", &pl_index))
8101         {
8102           if (pl_index <= 0 || pl_index > 4)
8103             goto pl_index_range_error;
8104           flags |=
8105             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8106         }
8107       else
8108         break;
8109     }
8110
8111   if (!src_address_set)
8112     {
8113       errmsg ("src address required");
8114       return -99;
8115     }
8116
8117   if (!dst_address_set)
8118     {
8119       errmsg ("dst address required");
8120       return -99;
8121     }
8122
8123   if (!segments)
8124     {
8125       errmsg ("at least one sr segment required");
8126       return -99;
8127     }
8128
8129   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8130       vec_len (segments) * sizeof (ip6_address_t)
8131       + vec_len (tags) * sizeof (ip6_address_t));
8132
8133   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8134   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8135   mp->dst_mask_width = dst_mask_width;
8136   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8137   mp->n_segments = vec_len (segments);
8138   mp->n_tags = vec_len (tags);
8139   mp->is_add = is_del == 0;
8140   clib_memcpy (mp->segs_and_tags, segments,
8141                vec_len (segments) * sizeof (ip6_address_t));
8142   clib_memcpy (mp->segs_and_tags +
8143                vec_len (segments) * sizeof (ip6_address_t), tags,
8144                vec_len (tags) * sizeof (ip6_address_t));
8145
8146   mp->outer_vrf_id = ntohl (rx_table_id);
8147   mp->inner_vrf_id = ntohl (tx_table_id);
8148   memcpy (mp->name, name, vec_len (name));
8149   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8150
8151   vec_free (segments);
8152   vec_free (tags);
8153
8154   S;
8155   W;
8156   /* NOTREACHED */
8157 }
8158
8159 static int
8160 api_sr_policy_add_del (vat_main_t * vam)
8161 {
8162   unformat_input_t *input = vam->input;
8163   vl_api_sr_policy_add_del_t *mp;
8164   f64 timeout;
8165   int is_del = 0;
8166   u8 *name = 0;
8167   u8 *tunnel_name = 0;
8168   u8 **tunnel_names = 0;
8169
8170   int name_set = 0;
8171   int tunnel_set = 0;
8172   int j = 0;
8173   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8174   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8175
8176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8177     {
8178       if (unformat (input, "del"))
8179         is_del = 1;
8180       else if (unformat (input, "name %s", &name))
8181         name_set = 1;
8182       else if (unformat (input, "tunnel %s", &tunnel_name))
8183         {
8184           if (tunnel_name)
8185             {
8186               vec_add1 (tunnel_names, tunnel_name);
8187               /* For serializer:
8188                  - length = #bytes to store in serial vector
8189                  - +1 = byte to store that length
8190                */
8191               tunnel_names_length += (vec_len (tunnel_name) + 1);
8192               tunnel_set = 1;
8193               tunnel_name = 0;
8194             }
8195         }
8196       else
8197         break;
8198     }
8199
8200   if (!name_set)
8201     {
8202       errmsg ("policy name required");
8203       return -99;
8204     }
8205
8206   if ((!tunnel_set) && (!is_del))
8207     {
8208       errmsg ("tunnel name required");
8209       return -99;
8210     }
8211
8212   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8213
8214
8215
8216   mp->is_add = !is_del;
8217
8218   memcpy (mp->name, name, vec_len (name));
8219   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8220   u8 *serial_orig = 0;
8221   vec_validate (serial_orig, tunnel_names_length);
8222   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8223   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8224
8225   for (j = 0; j < vec_len (tunnel_names); j++)
8226     {
8227       tun_name_len = vec_len (tunnel_names[j]);
8228       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8229       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8230       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8231       serial_orig += tun_name_len;      // Advance past the copy
8232     }
8233   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8234
8235   vec_free (tunnel_names);
8236   vec_free (tunnel_name);
8237
8238   S;
8239   W;
8240   /* NOTREACHED */
8241 }
8242
8243 static int
8244 api_sr_multicast_map_add_del (vat_main_t * vam)
8245 {
8246   unformat_input_t *input = vam->input;
8247   vl_api_sr_multicast_map_add_del_t *mp;
8248   f64 timeout;
8249   int is_del = 0;
8250   ip6_address_t multicast_address;
8251   u8 *policy_name = 0;
8252   int multicast_address_set = 0;
8253
8254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8255     {
8256       if (unformat (input, "del"))
8257         is_del = 1;
8258       else
8259         if (unformat
8260             (input, "address %U", unformat_ip6_address, &multicast_address))
8261         multicast_address_set = 1;
8262       else if (unformat (input, "sr-policy %s", &policy_name))
8263         ;
8264       else
8265         break;
8266     }
8267
8268   if (!is_del && !policy_name)
8269     {
8270       errmsg ("sr-policy name required");
8271       return -99;
8272     }
8273
8274
8275   if (!multicast_address_set)
8276     {
8277       errmsg ("address required");
8278       return -99;
8279     }
8280
8281   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8282
8283   mp->is_add = !is_del;
8284   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8285   clib_memcpy (mp->multicast_address, &multicast_address,
8286                sizeof (mp->multicast_address));
8287
8288
8289   vec_free (policy_name);
8290
8291   S;
8292   W;
8293   /* NOTREACHED */
8294 }
8295
8296
8297 #define foreach_tcp_proto_field                 \
8298 _(src_port)                                     \
8299 _(dst_port)
8300
8301 #define foreach_udp_proto_field                 \
8302 _(src_port)                                     \
8303 _(dst_port)
8304
8305 #define foreach_ip4_proto_field                 \
8306 _(src_address)                                  \
8307 _(dst_address)                                  \
8308 _(tos)                                          \
8309 _(length)                                       \
8310 _(fragment_id)                                  \
8311 _(ttl)                                          \
8312 _(protocol)                                     \
8313 _(checksum)
8314
8315 uword
8316 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8317 {
8318   u8 **maskp = va_arg (*args, u8 **);
8319   u8 *mask = 0;
8320   u8 found_something = 0;
8321   tcp_header_t *tcp;
8322
8323 #define _(a) u8 a=0;
8324   foreach_tcp_proto_field;
8325 #undef _
8326
8327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8328     {
8329       if (0);
8330 #define _(a) else if (unformat (input, #a)) a=1;
8331       foreach_tcp_proto_field
8332 #undef _
8333         else
8334         break;
8335     }
8336
8337 #define _(a) found_something += a;
8338   foreach_tcp_proto_field;
8339 #undef _
8340
8341   if (found_something == 0)
8342     return 0;
8343
8344   vec_validate (mask, sizeof (*tcp) - 1);
8345
8346   tcp = (tcp_header_t *) mask;
8347
8348 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8349   foreach_tcp_proto_field;
8350 #undef _
8351
8352   *maskp = mask;
8353   return 1;
8354 }
8355
8356 uword
8357 unformat_udp_mask (unformat_input_t * input, va_list * args)
8358 {
8359   u8 **maskp = va_arg (*args, u8 **);
8360   u8 *mask = 0;
8361   u8 found_something = 0;
8362   udp_header_t *udp;
8363
8364 #define _(a) u8 a=0;
8365   foreach_udp_proto_field;
8366 #undef _
8367
8368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8369     {
8370       if (0);
8371 #define _(a) else if (unformat (input, #a)) a=1;
8372       foreach_udp_proto_field
8373 #undef _
8374         else
8375         break;
8376     }
8377
8378 #define _(a) found_something += a;
8379   foreach_udp_proto_field;
8380 #undef _
8381
8382   if (found_something == 0)
8383     return 0;
8384
8385   vec_validate (mask, sizeof (*udp) - 1);
8386
8387   udp = (udp_header_t *) mask;
8388
8389 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8390   foreach_udp_proto_field;
8391 #undef _
8392
8393   *maskp = mask;
8394   return 1;
8395 }
8396
8397 typedef struct
8398 {
8399   u16 src_port, dst_port;
8400 } tcpudp_header_t;
8401
8402 uword
8403 unformat_l4_mask (unformat_input_t * input, va_list * args)
8404 {
8405   u8 **maskp = va_arg (*args, u8 **);
8406   u16 src_port = 0, dst_port = 0;
8407   tcpudp_header_t *tcpudp;
8408
8409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8410     {
8411       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8412         return 1;
8413       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8414         return 1;
8415       else if (unformat (input, "src_port"))
8416         src_port = 0xFFFF;
8417       else if (unformat (input, "dst_port"))
8418         dst_port = 0xFFFF;
8419       else
8420         return 0;
8421     }
8422
8423   if (!src_port && !dst_port)
8424     return 0;
8425
8426   u8 *mask = 0;
8427   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8428
8429   tcpudp = (tcpudp_header_t *) mask;
8430   tcpudp->src_port = src_port;
8431   tcpudp->dst_port = dst_port;
8432
8433   *maskp = mask;
8434
8435   return 1;
8436 }
8437
8438 uword
8439 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8440 {
8441   u8 **maskp = va_arg (*args, u8 **);
8442   u8 *mask = 0;
8443   u8 found_something = 0;
8444   ip4_header_t *ip;
8445
8446 #define _(a) u8 a=0;
8447   foreach_ip4_proto_field;
8448 #undef _
8449   u8 version = 0;
8450   u8 hdr_length = 0;
8451
8452
8453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8454     {
8455       if (unformat (input, "version"))
8456         version = 1;
8457       else if (unformat (input, "hdr_length"))
8458         hdr_length = 1;
8459       else if (unformat (input, "src"))
8460         src_address = 1;
8461       else if (unformat (input, "dst"))
8462         dst_address = 1;
8463       else if (unformat (input, "proto"))
8464         protocol = 1;
8465
8466 #define _(a) else if (unformat (input, #a)) a=1;
8467       foreach_ip4_proto_field
8468 #undef _
8469         else
8470         break;
8471     }
8472
8473 #define _(a) found_something += a;
8474   foreach_ip4_proto_field;
8475 #undef _
8476
8477   if (found_something == 0)
8478     return 0;
8479
8480   vec_validate (mask, sizeof (*ip) - 1);
8481
8482   ip = (ip4_header_t *) mask;
8483
8484 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8485   foreach_ip4_proto_field;
8486 #undef _
8487
8488   ip->ip_version_and_header_length = 0;
8489
8490   if (version)
8491     ip->ip_version_and_header_length |= 0xF0;
8492
8493   if (hdr_length)
8494     ip->ip_version_and_header_length |= 0x0F;
8495
8496   *maskp = mask;
8497   return 1;
8498 }
8499
8500 #define foreach_ip6_proto_field                 \
8501 _(src_address)                                  \
8502 _(dst_address)                                  \
8503 _(payload_length)                               \
8504 _(hop_limit)                                    \
8505 _(protocol)
8506
8507 uword
8508 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8509 {
8510   u8 **maskp = va_arg (*args, u8 **);
8511   u8 *mask = 0;
8512   u8 found_something = 0;
8513   ip6_header_t *ip;
8514   u32 ip_version_traffic_class_and_flow_label;
8515
8516 #define _(a) u8 a=0;
8517   foreach_ip6_proto_field;
8518 #undef _
8519   u8 version = 0;
8520   u8 traffic_class = 0;
8521   u8 flow_label = 0;
8522
8523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8524     {
8525       if (unformat (input, "version"))
8526         version = 1;
8527       else if (unformat (input, "traffic-class"))
8528         traffic_class = 1;
8529       else if (unformat (input, "flow-label"))
8530         flow_label = 1;
8531       else if (unformat (input, "src"))
8532         src_address = 1;
8533       else if (unformat (input, "dst"))
8534         dst_address = 1;
8535       else if (unformat (input, "proto"))
8536         protocol = 1;
8537
8538 #define _(a) else if (unformat (input, #a)) a=1;
8539       foreach_ip6_proto_field
8540 #undef _
8541         else
8542         break;
8543     }
8544
8545 #define _(a) found_something += a;
8546   foreach_ip6_proto_field;
8547 #undef _
8548
8549   if (found_something == 0)
8550     return 0;
8551
8552   vec_validate (mask, sizeof (*ip) - 1);
8553
8554   ip = (ip6_header_t *) mask;
8555
8556 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8557   foreach_ip6_proto_field;
8558 #undef _
8559
8560   ip_version_traffic_class_and_flow_label = 0;
8561
8562   if (version)
8563     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8564
8565   if (traffic_class)
8566     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8567
8568   if (flow_label)
8569     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8570
8571   ip->ip_version_traffic_class_and_flow_label =
8572     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8573
8574   *maskp = mask;
8575   return 1;
8576 }
8577
8578 uword
8579 unformat_l3_mask (unformat_input_t * input, va_list * args)
8580 {
8581   u8 **maskp = va_arg (*args, u8 **);
8582
8583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8584     {
8585       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8586         return 1;
8587       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8588         return 1;
8589       else
8590         break;
8591     }
8592   return 0;
8593 }
8594
8595 uword
8596 unformat_l2_mask (unformat_input_t * input, va_list * args)
8597 {
8598   u8 **maskp = va_arg (*args, u8 **);
8599   u8 *mask = 0;
8600   u8 src = 0;
8601   u8 dst = 0;
8602   u8 proto = 0;
8603   u8 tag1 = 0;
8604   u8 tag2 = 0;
8605   u8 ignore_tag1 = 0;
8606   u8 ignore_tag2 = 0;
8607   u8 cos1 = 0;
8608   u8 cos2 = 0;
8609   u8 dot1q = 0;
8610   u8 dot1ad = 0;
8611   int len = 14;
8612
8613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8614     {
8615       if (unformat (input, "src"))
8616         src = 1;
8617       else if (unformat (input, "dst"))
8618         dst = 1;
8619       else if (unformat (input, "proto"))
8620         proto = 1;
8621       else if (unformat (input, "tag1"))
8622         tag1 = 1;
8623       else if (unformat (input, "tag2"))
8624         tag2 = 1;
8625       else if (unformat (input, "ignore-tag1"))
8626         ignore_tag1 = 1;
8627       else if (unformat (input, "ignore-tag2"))
8628         ignore_tag2 = 1;
8629       else if (unformat (input, "cos1"))
8630         cos1 = 1;
8631       else if (unformat (input, "cos2"))
8632         cos2 = 1;
8633       else if (unformat (input, "dot1q"))
8634         dot1q = 1;
8635       else if (unformat (input, "dot1ad"))
8636         dot1ad = 1;
8637       else
8638         break;
8639     }
8640   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8641        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8642     return 0;
8643
8644   if (tag1 || ignore_tag1 || cos1 || dot1q)
8645     len = 18;
8646   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8647     len = 22;
8648
8649   vec_validate (mask, len - 1);
8650
8651   if (dst)
8652     memset (mask, 0xff, 6);
8653
8654   if (src)
8655     memset (mask + 6, 0xff, 6);
8656
8657   if (tag2 || dot1ad)
8658     {
8659       /* inner vlan tag */
8660       if (tag2)
8661         {
8662           mask[19] = 0xff;
8663           mask[18] = 0x0f;
8664         }
8665       if (cos2)
8666         mask[18] |= 0xe0;
8667       if (proto)
8668         mask[21] = mask[20] = 0xff;
8669       if (tag1)
8670         {
8671           mask[15] = 0xff;
8672           mask[14] = 0x0f;
8673         }
8674       if (cos1)
8675         mask[14] |= 0xe0;
8676       *maskp = mask;
8677       return 1;
8678     }
8679   if (tag1 | dot1q)
8680     {
8681       if (tag1)
8682         {
8683           mask[15] = 0xff;
8684           mask[14] = 0x0f;
8685         }
8686       if (cos1)
8687         mask[14] |= 0xe0;
8688       if (proto)
8689         mask[16] = mask[17] = 0xff;
8690
8691       *maskp = mask;
8692       return 1;
8693     }
8694   if (cos2)
8695     mask[18] |= 0xe0;
8696   if (cos1)
8697     mask[14] |= 0xe0;
8698   if (proto)
8699     mask[12] = mask[13] = 0xff;
8700
8701   *maskp = mask;
8702   return 1;
8703 }
8704
8705 uword
8706 unformat_classify_mask (unformat_input_t * input, va_list * args)
8707 {
8708   u8 **maskp = va_arg (*args, u8 **);
8709   u32 *skipp = va_arg (*args, u32 *);
8710   u32 *matchp = va_arg (*args, u32 *);
8711   u32 match;
8712   u8 *mask = 0;
8713   u8 *l2 = 0;
8714   u8 *l3 = 0;
8715   u8 *l4 = 0;
8716   int i;
8717
8718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8719     {
8720       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8721         ;
8722       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8723         ;
8724       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8725         ;
8726       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8727         ;
8728       else
8729         break;
8730     }
8731
8732   if (l4 && !l3)
8733     {
8734       vec_free (mask);
8735       vec_free (l2);
8736       vec_free (l4);
8737       return 0;
8738     }
8739
8740   if (mask || l2 || l3 || l4)
8741     {
8742       if (l2 || l3 || l4)
8743         {
8744           /* "With a free Ethernet header in every package" */
8745           if (l2 == 0)
8746             vec_validate (l2, 13);
8747           mask = l2;
8748           if (vec_len (l3))
8749             {
8750               vec_append (mask, l3);
8751               vec_free (l3);
8752             }
8753           if (vec_len (l4))
8754             {
8755               vec_append (mask, l4);
8756               vec_free (l4);
8757             }
8758         }
8759
8760       /* Scan forward looking for the first significant mask octet */
8761       for (i = 0; i < vec_len (mask); i++)
8762         if (mask[i])
8763           break;
8764
8765       /* compute (skip, match) params */
8766       *skipp = i / sizeof (u32x4);
8767       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8768
8769       /* Pad mask to an even multiple of the vector size */
8770       while (vec_len (mask) % sizeof (u32x4))
8771         vec_add1 (mask, 0);
8772
8773       match = vec_len (mask) / sizeof (u32x4);
8774
8775       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8776         {
8777           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8778           if (*tmp || *(tmp + 1))
8779             break;
8780           match--;
8781         }
8782       if (match == 0)
8783         clib_warning ("BUG: match 0");
8784
8785       _vec_len (mask) = match * sizeof (u32x4);
8786
8787       *matchp = match;
8788       *maskp = mask;
8789
8790       return 1;
8791     }
8792
8793   return 0;
8794 }
8795
8796 #define foreach_l2_next                         \
8797 _(drop, DROP)                                   \
8798 _(ethernet, ETHERNET_INPUT)                     \
8799 _(ip4, IP4_INPUT)                               \
8800 _(ip6, IP6_INPUT)
8801
8802 uword
8803 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8804 {
8805   u32 *miss_next_indexp = va_arg (*args, u32 *);
8806   u32 next_index = 0;
8807   u32 tmp;
8808
8809 #define _(n,N) \
8810   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8811   foreach_l2_next;
8812 #undef _
8813
8814   if (unformat (input, "%d", &tmp))
8815     {
8816       next_index = tmp;
8817       goto out;
8818     }
8819
8820   return 0;
8821
8822 out:
8823   *miss_next_indexp = next_index;
8824   return 1;
8825 }
8826
8827 #define foreach_ip_next                         \
8828 _(drop, DROP)                                   \
8829 _(local, LOCAL)                                 \
8830 _(rewrite, REWRITE)
8831
8832 uword
8833 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8834 {
8835   u32 *miss_next_indexp = va_arg (*args, u32 *);
8836   u32 next_index = 0;
8837   u32 tmp;
8838
8839 #define _(n,N) \
8840   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8841   foreach_ip_next;
8842 #undef _
8843
8844   if (unformat (input, "%d", &tmp))
8845     {
8846       next_index = tmp;
8847       goto out;
8848     }
8849
8850   return 0;
8851
8852 out:
8853   *miss_next_indexp = next_index;
8854   return 1;
8855 }
8856
8857 #define foreach_acl_next                        \
8858 _(deny, DENY)
8859
8860 uword
8861 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8862 {
8863   u32 *miss_next_indexp = va_arg (*args, u32 *);
8864   u32 next_index = 0;
8865   u32 tmp;
8866
8867 #define _(n,N) \
8868   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8869   foreach_acl_next;
8870 #undef _
8871
8872   if (unformat (input, "permit"))
8873     {
8874       next_index = ~0;
8875       goto out;
8876     }
8877   else if (unformat (input, "%d", &tmp))
8878     {
8879       next_index = tmp;
8880       goto out;
8881     }
8882
8883   return 0;
8884
8885 out:
8886   *miss_next_indexp = next_index;
8887   return 1;
8888 }
8889
8890 uword
8891 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8892 {
8893   u32 *r = va_arg (*args, u32 *);
8894
8895   if (unformat (input, "conform-color"))
8896     *r = POLICE_CONFORM;
8897   else if (unformat (input, "exceed-color"))
8898     *r = POLICE_EXCEED;
8899   else
8900     return 0;
8901
8902   return 1;
8903 }
8904
8905 static int
8906 api_classify_add_del_table (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_classify_add_del_table_t *mp;
8910
8911   u32 nbuckets = 2;
8912   u32 skip = ~0;
8913   u32 match = ~0;
8914   int is_add = 1;
8915   int del_chain = 0;
8916   u32 table_index = ~0;
8917   u32 next_table_index = ~0;
8918   u32 miss_next_index = ~0;
8919   u32 memory_size = 32 << 20;
8920   u8 *mask = 0;
8921   f64 timeout;
8922   u32 current_data_flag = 0;
8923   int current_data_offset = 0;
8924
8925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8926     {
8927       if (unformat (i, "del"))
8928         is_add = 0;
8929       else if (unformat (i, "del-chain"))
8930         {
8931           is_add = 0;
8932           del_chain = 1;
8933         }
8934       else if (unformat (i, "buckets %d", &nbuckets))
8935         ;
8936       else if (unformat (i, "memory_size %d", &memory_size))
8937         ;
8938       else if (unformat (i, "skip %d", &skip))
8939         ;
8940       else if (unformat (i, "match %d", &match))
8941         ;
8942       else if (unformat (i, "table %d", &table_index))
8943         ;
8944       else if (unformat (i, "mask %U", unformat_classify_mask,
8945                          &mask, &skip, &match))
8946         ;
8947       else if (unformat (i, "next-table %d", &next_table_index))
8948         ;
8949       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8950                          &miss_next_index))
8951         ;
8952       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8953                          &miss_next_index))
8954         ;
8955       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8956                          &miss_next_index))
8957         ;
8958       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8959         ;
8960       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8961         ;
8962       else
8963         break;
8964     }
8965
8966   if (is_add && mask == 0)
8967     {
8968       errmsg ("Mask required");
8969       return -99;
8970     }
8971
8972   if (is_add && skip == ~0)
8973     {
8974       errmsg ("skip count required");
8975       return -99;
8976     }
8977
8978   if (is_add && match == ~0)
8979     {
8980       errmsg ("match count required");
8981       return -99;
8982     }
8983
8984   if (!is_add && table_index == ~0)
8985     {
8986       errmsg ("table index required for delete");
8987       return -99;
8988     }
8989
8990   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8991
8992   mp->is_add = is_add;
8993   mp->del_chain = del_chain;
8994   mp->table_index = ntohl (table_index);
8995   mp->nbuckets = ntohl (nbuckets);
8996   mp->memory_size = ntohl (memory_size);
8997   mp->skip_n_vectors = ntohl (skip);
8998   mp->match_n_vectors = ntohl (match);
8999   mp->next_table_index = ntohl (next_table_index);
9000   mp->miss_next_index = ntohl (miss_next_index);
9001   mp->current_data_flag = ntohl (current_data_flag);
9002   mp->current_data_offset = ntohl (current_data_offset);
9003   clib_memcpy (mp->mask, mask, vec_len (mask));
9004
9005   vec_free (mask);
9006
9007   S;
9008   W;
9009   /* NOTREACHED */
9010 }
9011
9012 uword
9013 unformat_l4_match (unformat_input_t * input, va_list * args)
9014 {
9015   u8 **matchp = va_arg (*args, u8 **);
9016
9017   u8 *proto_header = 0;
9018   int src_port = 0;
9019   int dst_port = 0;
9020
9021   tcpudp_header_t h;
9022
9023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9024     {
9025       if (unformat (input, "src_port %d", &src_port))
9026         ;
9027       else if (unformat (input, "dst_port %d", &dst_port))
9028         ;
9029       else
9030         return 0;
9031     }
9032
9033   h.src_port = clib_host_to_net_u16 (src_port);
9034   h.dst_port = clib_host_to_net_u16 (dst_port);
9035   vec_validate (proto_header, sizeof (h) - 1);
9036   memcpy (proto_header, &h, sizeof (h));
9037
9038   *matchp = proto_header;
9039
9040   return 1;
9041 }
9042
9043 uword
9044 unformat_ip4_match (unformat_input_t * input, va_list * args)
9045 {
9046   u8 **matchp = va_arg (*args, u8 **);
9047   u8 *match = 0;
9048   ip4_header_t *ip;
9049   int version = 0;
9050   u32 version_val;
9051   int hdr_length = 0;
9052   u32 hdr_length_val;
9053   int src = 0, dst = 0;
9054   ip4_address_t src_val, dst_val;
9055   int proto = 0;
9056   u32 proto_val;
9057   int tos = 0;
9058   u32 tos_val;
9059   int length = 0;
9060   u32 length_val;
9061   int fragment_id = 0;
9062   u32 fragment_id_val;
9063   int ttl = 0;
9064   int ttl_val;
9065   int checksum = 0;
9066   u32 checksum_val;
9067
9068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9069     {
9070       if (unformat (input, "version %d", &version_val))
9071         version = 1;
9072       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9073         hdr_length = 1;
9074       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9075         src = 1;
9076       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9077         dst = 1;
9078       else if (unformat (input, "proto %d", &proto_val))
9079         proto = 1;
9080       else if (unformat (input, "tos %d", &tos_val))
9081         tos = 1;
9082       else if (unformat (input, "length %d", &length_val))
9083         length = 1;
9084       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9085         fragment_id = 1;
9086       else if (unformat (input, "ttl %d", &ttl_val))
9087         ttl = 1;
9088       else if (unformat (input, "checksum %d", &checksum_val))
9089         checksum = 1;
9090       else
9091         break;
9092     }
9093
9094   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9095       + ttl + checksum == 0)
9096     return 0;
9097
9098   /*
9099    * Aligned because we use the real comparison functions
9100    */
9101   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9102
9103   ip = (ip4_header_t *) match;
9104
9105   /* These are realistically matched in practice */
9106   if (src)
9107     ip->src_address.as_u32 = src_val.as_u32;
9108
9109   if (dst)
9110     ip->dst_address.as_u32 = dst_val.as_u32;
9111
9112   if (proto)
9113     ip->protocol = proto_val;
9114
9115
9116   /* These are not, but they're included for completeness */
9117   if (version)
9118     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9119
9120   if (hdr_length)
9121     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9122
9123   if (tos)
9124     ip->tos = tos_val;
9125
9126   if (length)
9127     ip->length = clib_host_to_net_u16 (length_val);
9128
9129   if (ttl)
9130     ip->ttl = ttl_val;
9131
9132   if (checksum)
9133     ip->checksum = clib_host_to_net_u16 (checksum_val);
9134
9135   *matchp = match;
9136   return 1;
9137 }
9138
9139 uword
9140 unformat_ip6_match (unformat_input_t * input, va_list * args)
9141 {
9142   u8 **matchp = va_arg (*args, u8 **);
9143   u8 *match = 0;
9144   ip6_header_t *ip;
9145   int version = 0;
9146   u32 version_val;
9147   u8 traffic_class = 0;
9148   u32 traffic_class_val = 0;
9149   u8 flow_label = 0;
9150   u8 flow_label_val;
9151   int src = 0, dst = 0;
9152   ip6_address_t src_val, dst_val;
9153   int proto = 0;
9154   u32 proto_val;
9155   int payload_length = 0;
9156   u32 payload_length_val;
9157   int hop_limit = 0;
9158   int hop_limit_val;
9159   u32 ip_version_traffic_class_and_flow_label;
9160
9161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (input, "version %d", &version_val))
9164         version = 1;
9165       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9166         traffic_class = 1;
9167       else if (unformat (input, "flow_label %d", &flow_label_val))
9168         flow_label = 1;
9169       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9170         src = 1;
9171       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9172         dst = 1;
9173       else if (unformat (input, "proto %d", &proto_val))
9174         proto = 1;
9175       else if (unformat (input, "payload_length %d", &payload_length_val))
9176         payload_length = 1;
9177       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9178         hop_limit = 1;
9179       else
9180         break;
9181     }
9182
9183   if (version + traffic_class + flow_label + src + dst + proto +
9184       payload_length + hop_limit == 0)
9185     return 0;
9186
9187   /*
9188    * Aligned because we use the real comparison functions
9189    */
9190   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9191
9192   ip = (ip6_header_t *) match;
9193
9194   if (src)
9195     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9196
9197   if (dst)
9198     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9199
9200   if (proto)
9201     ip->protocol = proto_val;
9202
9203   ip_version_traffic_class_and_flow_label = 0;
9204
9205   if (version)
9206     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9207
9208   if (traffic_class)
9209     ip_version_traffic_class_and_flow_label |=
9210       (traffic_class_val & 0xFF) << 20;
9211
9212   if (flow_label)
9213     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9214
9215   ip->ip_version_traffic_class_and_flow_label =
9216     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9217
9218   if (payload_length)
9219     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9220
9221   if (hop_limit)
9222     ip->hop_limit = hop_limit_val;
9223
9224   *matchp = match;
9225   return 1;
9226 }
9227
9228 uword
9229 unformat_l3_match (unformat_input_t * input, va_list * args)
9230 {
9231   u8 **matchp = va_arg (*args, u8 **);
9232
9233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9234     {
9235       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9236         return 1;
9237       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9238         return 1;
9239       else
9240         break;
9241     }
9242   return 0;
9243 }
9244
9245 uword
9246 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9247 {
9248   u8 *tagp = va_arg (*args, u8 *);
9249   u32 tag;
9250
9251   if (unformat (input, "%d", &tag))
9252     {
9253       tagp[0] = (tag >> 8) & 0x0F;
9254       tagp[1] = tag & 0xFF;
9255       return 1;
9256     }
9257
9258   return 0;
9259 }
9260
9261 uword
9262 unformat_l2_match (unformat_input_t * input, va_list * args)
9263 {
9264   u8 **matchp = va_arg (*args, u8 **);
9265   u8 *match = 0;
9266   u8 src = 0;
9267   u8 src_val[6];
9268   u8 dst = 0;
9269   u8 dst_val[6];
9270   u8 proto = 0;
9271   u16 proto_val;
9272   u8 tag1 = 0;
9273   u8 tag1_val[2];
9274   u8 tag2 = 0;
9275   u8 tag2_val[2];
9276   int len = 14;
9277   u8 ignore_tag1 = 0;
9278   u8 ignore_tag2 = 0;
9279   u8 cos1 = 0;
9280   u8 cos2 = 0;
9281   u32 cos1_val = 0;
9282   u32 cos2_val = 0;
9283
9284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9285     {
9286       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9287         src = 1;
9288       else
9289         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9290         dst = 1;
9291       else if (unformat (input, "proto %U",
9292                          unformat_ethernet_type_host_byte_order, &proto_val))
9293         proto = 1;
9294       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9295         tag1 = 1;
9296       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9297         tag2 = 1;
9298       else if (unformat (input, "ignore-tag1"))
9299         ignore_tag1 = 1;
9300       else if (unformat (input, "ignore-tag2"))
9301         ignore_tag2 = 1;
9302       else if (unformat (input, "cos1 %d", &cos1_val))
9303         cos1 = 1;
9304       else if (unformat (input, "cos2 %d", &cos2_val))
9305         cos2 = 1;
9306       else
9307         break;
9308     }
9309   if ((src + dst + proto + tag1 + tag2 +
9310        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9311     return 0;
9312
9313   if (tag1 || ignore_tag1 || cos1)
9314     len = 18;
9315   if (tag2 || ignore_tag2 || cos2)
9316     len = 22;
9317
9318   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9319
9320   if (dst)
9321     clib_memcpy (match, dst_val, 6);
9322
9323   if (src)
9324     clib_memcpy (match + 6, src_val, 6);
9325
9326   if (tag2)
9327     {
9328       /* inner vlan tag */
9329       match[19] = tag2_val[1];
9330       match[18] = tag2_val[0];
9331       if (cos2)
9332         match[18] |= (cos2_val & 0x7) << 5;
9333       if (proto)
9334         {
9335           match[21] = proto_val & 0xff;
9336           match[20] = proto_val >> 8;
9337         }
9338       if (tag1)
9339         {
9340           match[15] = tag1_val[1];
9341           match[14] = tag1_val[0];
9342         }
9343       if (cos1)
9344         match[14] |= (cos1_val & 0x7) << 5;
9345       *matchp = match;
9346       return 1;
9347     }
9348   if (tag1)
9349     {
9350       match[15] = tag1_val[1];
9351       match[14] = tag1_val[0];
9352       if (proto)
9353         {
9354           match[17] = proto_val & 0xff;
9355           match[16] = proto_val >> 8;
9356         }
9357       if (cos1)
9358         match[14] |= (cos1_val & 0x7) << 5;
9359
9360       *matchp = match;
9361       return 1;
9362     }
9363   if (cos2)
9364     match[18] |= (cos2_val & 0x7) << 5;
9365   if (cos1)
9366     match[14] |= (cos1_val & 0x7) << 5;
9367   if (proto)
9368     {
9369       match[13] = proto_val & 0xff;
9370       match[12] = proto_val >> 8;
9371     }
9372
9373   *matchp = match;
9374   return 1;
9375 }
9376
9377
9378 uword
9379 unformat_classify_match (unformat_input_t * input, va_list * args)
9380 {
9381   u8 **matchp = va_arg (*args, u8 **);
9382   u32 skip_n_vectors = va_arg (*args, u32);
9383   u32 match_n_vectors = va_arg (*args, u32);
9384
9385   u8 *match = 0;
9386   u8 *l2 = 0;
9387   u8 *l3 = 0;
9388   u8 *l4 = 0;
9389
9390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9391     {
9392       if (unformat (input, "hex %U", unformat_hex_string, &match))
9393         ;
9394       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9395         ;
9396       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9397         ;
9398       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9399         ;
9400       else
9401         break;
9402     }
9403
9404   if (l4 && !l3)
9405     {
9406       vec_free (match);
9407       vec_free (l2);
9408       vec_free (l4);
9409       return 0;
9410     }
9411
9412   if (match || l2 || l3 || l4)
9413     {
9414       if (l2 || l3 || l4)
9415         {
9416           /* "Win a free Ethernet header in every packet" */
9417           if (l2 == 0)
9418             vec_validate_aligned (l2, 13, sizeof (u32x4));
9419           match = l2;
9420           if (vec_len (l3))
9421             {
9422               vec_append_aligned (match, l3, sizeof (u32x4));
9423               vec_free (l3);
9424             }
9425           if (vec_len (l4))
9426             {
9427               vec_append_aligned (match, l4, sizeof (u32x4));
9428               vec_free (l4);
9429             }
9430         }
9431
9432       /* Make sure the vector is big enough even if key is all 0's */
9433       vec_validate_aligned
9434         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9435          sizeof (u32x4));
9436
9437       /* Set size, include skipped vectors */
9438       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9439
9440       *matchp = match;
9441
9442       return 1;
9443     }
9444
9445   return 0;
9446 }
9447
9448 static int
9449 api_classify_add_del_session (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_classify_add_del_session_t *mp;
9453   int is_add = 1;
9454   u32 table_index = ~0;
9455   u32 hit_next_index = ~0;
9456   u32 opaque_index = ~0;
9457   u8 *match = 0;
9458   i32 advance = 0;
9459   f64 timeout;
9460   u32 skip_n_vectors = 0;
9461   u32 match_n_vectors = 0;
9462   u32 action = 0;
9463   u32 metadata = 0;
9464
9465   /*
9466    * Warning: you have to supply skip_n and match_n
9467    * because the API client cant simply look at the classify
9468    * table object.
9469    */
9470
9471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9472     {
9473       if (unformat (i, "del"))
9474         is_add = 0;
9475       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9476                          &hit_next_index))
9477         ;
9478       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9479                          &hit_next_index))
9480         ;
9481       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9482                          &hit_next_index))
9483         ;
9484       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9485         ;
9486       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9487         ;
9488       else if (unformat (i, "opaque-index %d", &opaque_index))
9489         ;
9490       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9491         ;
9492       else if (unformat (i, "match_n %d", &match_n_vectors))
9493         ;
9494       else if (unformat (i, "match %U", unformat_classify_match,
9495                          &match, skip_n_vectors, match_n_vectors))
9496         ;
9497       else if (unformat (i, "advance %d", &advance))
9498         ;
9499       else if (unformat (i, "table-index %d", &table_index))
9500         ;
9501       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9502         action = 1;
9503       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9504         action = 2;
9505       else if (unformat (i, "action %d", &action))
9506         ;
9507       else if (unformat (i, "metadata %d", &metadata))
9508         ;
9509       else
9510         break;
9511     }
9512
9513   if (table_index == ~0)
9514     {
9515       errmsg ("Table index required");
9516       return -99;
9517     }
9518
9519   if (is_add && match == 0)
9520     {
9521       errmsg ("Match value required");
9522       return -99;
9523     }
9524
9525   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9526
9527   mp->is_add = is_add;
9528   mp->table_index = ntohl (table_index);
9529   mp->hit_next_index = ntohl (hit_next_index);
9530   mp->opaque_index = ntohl (opaque_index);
9531   mp->advance = ntohl (advance);
9532   mp->action = action;
9533   mp->metadata = ntohl (metadata);
9534   clib_memcpy (mp->match, match, vec_len (match));
9535   vec_free (match);
9536
9537   S;
9538   W;
9539   /* NOTREACHED */
9540 }
9541
9542 static int
9543 api_classify_set_interface_ip_table (vat_main_t * vam)
9544 {
9545   unformat_input_t *i = vam->input;
9546   vl_api_classify_set_interface_ip_table_t *mp;
9547   f64 timeout;
9548   u32 sw_if_index;
9549   int sw_if_index_set;
9550   u32 table_index = ~0;
9551   u8 is_ipv6 = 0;
9552
9553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9554     {
9555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9556         sw_if_index_set = 1;
9557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9558         sw_if_index_set = 1;
9559       else if (unformat (i, "table %d", &table_index))
9560         ;
9561       else
9562         {
9563           clib_warning ("parse error '%U'", format_unformat_error, i);
9564           return -99;
9565         }
9566     }
9567
9568   if (sw_if_index_set == 0)
9569     {
9570       errmsg ("missing interface name or sw_if_index");
9571       return -99;
9572     }
9573
9574
9575   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9576
9577   mp->sw_if_index = ntohl (sw_if_index);
9578   mp->table_index = ntohl (table_index);
9579   mp->is_ipv6 = is_ipv6;
9580
9581   S;
9582   W;
9583   /* NOTREACHED */
9584   return 0;
9585 }
9586
9587 static int
9588 api_classify_set_interface_l2_tables (vat_main_t * vam)
9589 {
9590   unformat_input_t *i = vam->input;
9591   vl_api_classify_set_interface_l2_tables_t *mp;
9592   f64 timeout;
9593   u32 sw_if_index;
9594   int sw_if_index_set;
9595   u32 ip4_table_index = ~0;
9596   u32 ip6_table_index = ~0;
9597   u32 other_table_index = ~0;
9598   u32 is_input = 1;
9599
9600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9601     {
9602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9603         sw_if_index_set = 1;
9604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9605         sw_if_index_set = 1;
9606       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9607         ;
9608       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9609         ;
9610       else if (unformat (i, "other-table %d", &other_table_index))
9611         ;
9612       else if (unformat (i, "is-input %d", &is_input))
9613         ;
9614       else
9615         {
9616           clib_warning ("parse error '%U'", format_unformat_error, i);
9617           return -99;
9618         }
9619     }
9620
9621   if (sw_if_index_set == 0)
9622     {
9623       errmsg ("missing interface name or sw_if_index");
9624       return -99;
9625     }
9626
9627
9628   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9629
9630   mp->sw_if_index = ntohl (sw_if_index);
9631   mp->ip4_table_index = ntohl (ip4_table_index);
9632   mp->ip6_table_index = ntohl (ip6_table_index);
9633   mp->other_table_index = ntohl (other_table_index);
9634   mp->is_input = (u8) is_input;
9635
9636   S;
9637   W;
9638   /* NOTREACHED */
9639   return 0;
9640 }
9641
9642 static int
9643 api_set_ipfix_exporter (vat_main_t * vam)
9644 {
9645   unformat_input_t *i = vam->input;
9646   vl_api_set_ipfix_exporter_t *mp;
9647   ip4_address_t collector_address;
9648   u8 collector_address_set = 0;
9649   u32 collector_port = ~0;
9650   ip4_address_t src_address;
9651   u8 src_address_set = 0;
9652   u32 vrf_id = ~0;
9653   u32 path_mtu = ~0;
9654   u32 template_interval = ~0;
9655   u8 udp_checksum = 0;
9656   f64 timeout;
9657
9658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9659     {
9660       if (unformat (i, "collector_address %U", unformat_ip4_address,
9661                     &collector_address))
9662         collector_address_set = 1;
9663       else if (unformat (i, "collector_port %d", &collector_port))
9664         ;
9665       else if (unformat (i, "src_address %U", unformat_ip4_address,
9666                          &src_address))
9667         src_address_set = 1;
9668       else if (unformat (i, "vrf_id %d", &vrf_id))
9669         ;
9670       else if (unformat (i, "path_mtu %d", &path_mtu))
9671         ;
9672       else if (unformat (i, "template_interval %d", &template_interval))
9673         ;
9674       else if (unformat (i, "udp_checksum"))
9675         udp_checksum = 1;
9676       else
9677         break;
9678     }
9679
9680   if (collector_address_set == 0)
9681     {
9682       errmsg ("collector_address required");
9683       return -99;
9684     }
9685
9686   if (src_address_set == 0)
9687     {
9688       errmsg ("src_address required");
9689       return -99;
9690     }
9691
9692   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9693
9694   memcpy (mp->collector_address, collector_address.data,
9695           sizeof (collector_address.data));
9696   mp->collector_port = htons ((u16) collector_port);
9697   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9698   mp->vrf_id = htonl (vrf_id);
9699   mp->path_mtu = htonl (path_mtu);
9700   mp->template_interval = htonl (template_interval);
9701   mp->udp_checksum = udp_checksum;
9702
9703   S;
9704   W;
9705   /* NOTREACHED */
9706 }
9707
9708 static int
9709 api_set_ipfix_classify_stream (vat_main_t * vam)
9710 {
9711   unformat_input_t *i = vam->input;
9712   vl_api_set_ipfix_classify_stream_t *mp;
9713   u32 domain_id = 0;
9714   u32 src_port = UDP_DST_PORT_ipfix;
9715   f64 timeout;
9716
9717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9718     {
9719       if (unformat (i, "domain %d", &domain_id))
9720         ;
9721       else if (unformat (i, "src_port %d", &src_port))
9722         ;
9723       else
9724         {
9725           errmsg ("unknown input `%U'", format_unformat_error, i);
9726           return -99;
9727         }
9728     }
9729
9730   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9731
9732   mp->domain_id = htonl (domain_id);
9733   mp->src_port = htons ((u16) src_port);
9734
9735   S;
9736   W;
9737   /* NOTREACHED */
9738 }
9739
9740 static int
9741 api_ipfix_classify_table_add_del (vat_main_t * vam)
9742 {
9743   unformat_input_t *i = vam->input;
9744   vl_api_ipfix_classify_table_add_del_t *mp;
9745   int is_add = -1;
9746   u32 classify_table_index = ~0;
9747   u8 ip_version = 0;
9748   u8 transport_protocol = 255;
9749   f64 timeout;
9750
9751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (i, "add"))
9754         is_add = 1;
9755       else if (unformat (i, "del"))
9756         is_add = 0;
9757       else if (unformat (i, "table %d", &classify_table_index))
9758         ;
9759       else if (unformat (i, "ip4"))
9760         ip_version = 4;
9761       else if (unformat (i, "ip6"))
9762         ip_version = 6;
9763       else if (unformat (i, "tcp"))
9764         transport_protocol = 6;
9765       else if (unformat (i, "udp"))
9766         transport_protocol = 17;
9767       else
9768         {
9769           errmsg ("unknown input `%U'", format_unformat_error, i);
9770           return -99;
9771         }
9772     }
9773
9774   if (is_add == -1)
9775     {
9776       errmsg ("expecting: add|del");
9777       return -99;
9778     }
9779   if (classify_table_index == ~0)
9780     {
9781       errmsg ("classifier table not specified");
9782       return -99;
9783     }
9784   if (ip_version == 0)
9785     {
9786       errmsg ("IP version not specified");
9787       return -99;
9788     }
9789
9790   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9791
9792   mp->is_add = is_add;
9793   mp->table_id = htonl (classify_table_index);
9794   mp->ip_version = ip_version;
9795   mp->transport_protocol = transport_protocol;
9796
9797   S;
9798   W;
9799   /* NOTREACHED */
9800 }
9801
9802 static int
9803 api_get_node_index (vat_main_t * vam)
9804 {
9805   unformat_input_t *i = vam->input;
9806   vl_api_get_node_index_t *mp;
9807   f64 timeout;
9808   u8 *name = 0;
9809
9810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9811     {
9812       if (unformat (i, "node %s", &name))
9813         ;
9814       else
9815         break;
9816     }
9817   if (name == 0)
9818     {
9819       errmsg ("node name required");
9820       return -99;
9821     }
9822   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9823     {
9824       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9825       return -99;
9826     }
9827
9828   M (GET_NODE_INDEX, get_node_index);
9829   clib_memcpy (mp->node_name, name, vec_len (name));
9830   vec_free (name);
9831
9832   S;
9833   W;
9834   /* NOTREACHED */
9835   return 0;
9836 }
9837
9838 static int
9839 api_get_next_index (vat_main_t * vam)
9840 {
9841   unformat_input_t *i = vam->input;
9842   vl_api_get_next_index_t *mp;
9843   f64 timeout;
9844   u8 *node_name = 0, *next_node_name = 0;
9845
9846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9847     {
9848       if (unformat (i, "node-name %s", &node_name))
9849         ;
9850       else if (unformat (i, "next-node-name %s", &next_node_name))
9851         break;
9852     }
9853
9854   if (node_name == 0)
9855     {
9856       errmsg ("node name required");
9857       return -99;
9858     }
9859   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9860     {
9861       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9862       return -99;
9863     }
9864
9865   if (next_node_name == 0)
9866     {
9867       errmsg ("next node name required");
9868       return -99;
9869     }
9870   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9871     {
9872       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9873       return -99;
9874     }
9875
9876   M (GET_NEXT_INDEX, get_next_index);
9877   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9878   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9879   vec_free (node_name);
9880   vec_free (next_node_name);
9881
9882   S;
9883   W;
9884   /* NOTREACHED */
9885   return 0;
9886 }
9887
9888 static int
9889 api_add_node_next (vat_main_t * vam)
9890 {
9891   unformat_input_t *i = vam->input;
9892   vl_api_add_node_next_t *mp;
9893   f64 timeout;
9894   u8 *name = 0;
9895   u8 *next = 0;
9896
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "node %s", &name))
9900         ;
9901       else if (unformat (i, "next %s", &next))
9902         ;
9903       else
9904         break;
9905     }
9906   if (name == 0)
9907     {
9908       errmsg ("node name required");
9909       return -99;
9910     }
9911   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9912     {
9913       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9914       return -99;
9915     }
9916   if (next == 0)
9917     {
9918       errmsg ("next node required");
9919       return -99;
9920     }
9921   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9922     {
9923       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9924       return -99;
9925     }
9926
9927   M (ADD_NODE_NEXT, add_node_next);
9928   clib_memcpy (mp->node_name, name, vec_len (name));
9929   clib_memcpy (mp->next_name, next, vec_len (next));
9930   vec_free (name);
9931   vec_free (next);
9932
9933   S;
9934   W;
9935   /* NOTREACHED */
9936   return 0;
9937 }
9938
9939 static int
9940 api_l2tpv3_create_tunnel (vat_main_t * vam)
9941 {
9942   unformat_input_t *i = vam->input;
9943   ip6_address_t client_address, our_address;
9944   int client_address_set = 0;
9945   int our_address_set = 0;
9946   u32 local_session_id = 0;
9947   u32 remote_session_id = 0;
9948   u64 local_cookie = 0;
9949   u64 remote_cookie = 0;
9950   u8 l2_sublayer_present = 0;
9951   vl_api_l2tpv3_create_tunnel_t *mp;
9952   f64 timeout;
9953
9954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (unformat (i, "client_address %U", unformat_ip6_address,
9957                     &client_address))
9958         client_address_set = 1;
9959       else if (unformat (i, "our_address %U", unformat_ip6_address,
9960                          &our_address))
9961         our_address_set = 1;
9962       else if (unformat (i, "local_session_id %d", &local_session_id))
9963         ;
9964       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9965         ;
9966       else if (unformat (i, "local_cookie %lld", &local_cookie))
9967         ;
9968       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9969         ;
9970       else if (unformat (i, "l2-sublayer-present"))
9971         l2_sublayer_present = 1;
9972       else
9973         break;
9974     }
9975
9976   if (client_address_set == 0)
9977     {
9978       errmsg ("client_address required");
9979       return -99;
9980     }
9981
9982   if (our_address_set == 0)
9983     {
9984       errmsg ("our_address required");
9985       return -99;
9986     }
9987
9988   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9989
9990   clib_memcpy (mp->client_address, client_address.as_u8,
9991                sizeof (mp->client_address));
9992
9993   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9994
9995   mp->local_session_id = ntohl (local_session_id);
9996   mp->remote_session_id = ntohl (remote_session_id);
9997   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9998   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9999   mp->l2_sublayer_present = l2_sublayer_present;
10000   mp->is_ipv6 = 1;
10001
10002   S;
10003   W;
10004   /* NOTREACHED */
10005   return 0;
10006 }
10007
10008 static int
10009 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10010 {
10011   unformat_input_t *i = vam->input;
10012   u32 sw_if_index;
10013   u8 sw_if_index_set = 0;
10014   u64 new_local_cookie = 0;
10015   u64 new_remote_cookie = 0;
10016   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10017   f64 timeout;
10018
10019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10020     {
10021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10022         sw_if_index_set = 1;
10023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10024         sw_if_index_set = 1;
10025       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10026         ;
10027       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10028         ;
10029       else
10030         break;
10031     }
10032
10033   if (sw_if_index_set == 0)
10034     {
10035       errmsg ("missing interface name or sw_if_index");
10036       return -99;
10037     }
10038
10039   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10040
10041   mp->sw_if_index = ntohl (sw_if_index);
10042   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10043   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10044
10045   S;
10046   W;
10047   /* NOTREACHED */
10048   return 0;
10049 }
10050
10051 static int
10052 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10053 {
10054   unformat_input_t *i = vam->input;
10055   vl_api_l2tpv3_interface_enable_disable_t *mp;
10056   f64 timeout;
10057   u32 sw_if_index;
10058   u8 sw_if_index_set = 0;
10059   u8 enable_disable = 1;
10060
10061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10062     {
10063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10064         sw_if_index_set = 1;
10065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10066         sw_if_index_set = 1;
10067       else if (unformat (i, "enable"))
10068         enable_disable = 1;
10069       else if (unformat (i, "disable"))
10070         enable_disable = 0;
10071       else
10072         break;
10073     }
10074
10075   if (sw_if_index_set == 0)
10076     {
10077       errmsg ("missing interface name or sw_if_index");
10078       return -99;
10079     }
10080
10081   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10082
10083   mp->sw_if_index = ntohl (sw_if_index);
10084   mp->enable_disable = enable_disable;
10085
10086   S;
10087   W;
10088   /* NOTREACHED */
10089   return 0;
10090 }
10091
10092 static int
10093 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10094 {
10095   unformat_input_t *i = vam->input;
10096   vl_api_l2tpv3_set_lookup_key_t *mp;
10097   f64 timeout;
10098   u8 key = ~0;
10099
10100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (i, "lookup_v6_src"))
10103         key = L2T_LOOKUP_SRC_ADDRESS;
10104       else if (unformat (i, "lookup_v6_dst"))
10105         key = L2T_LOOKUP_DST_ADDRESS;
10106       else if (unformat (i, "lookup_session_id"))
10107         key = L2T_LOOKUP_SESSION_ID;
10108       else
10109         break;
10110     }
10111
10112   if (key == (u8) ~ 0)
10113     {
10114       errmsg ("l2tp session lookup key unset");
10115       return -99;
10116     }
10117
10118   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10119
10120   mp->key = key;
10121
10122   S;
10123   W;
10124   /* NOTREACHED */
10125   return 0;
10126 }
10127
10128 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10129   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10130 {
10131   vat_main_t *vam = &vat_main;
10132
10133   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10134          format_ip6_address, mp->our_address,
10135          format_ip6_address, mp->client_address,
10136          clib_net_to_host_u32 (mp->sw_if_index));
10137
10138   print (vam->ofp,
10139          "   local cookies %016llx %016llx remote cookie %016llx",
10140          clib_net_to_host_u64 (mp->local_cookie[0]),
10141          clib_net_to_host_u64 (mp->local_cookie[1]),
10142          clib_net_to_host_u64 (mp->remote_cookie));
10143
10144   print (vam->ofp, "   local session-id %d remote session-id %d",
10145          clib_net_to_host_u32 (mp->local_session_id),
10146          clib_net_to_host_u32 (mp->remote_session_id));
10147
10148   print (vam->ofp, "   l2 specific sublayer %s\n",
10149          mp->l2_sublayer_present ? "preset" : "absent");
10150
10151 }
10152
10153 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10154   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10155 {
10156   vat_main_t *vam = &vat_main;
10157   vat_json_node_t *node = NULL;
10158   struct in6_addr addr;
10159
10160   if (VAT_JSON_ARRAY != vam->json_tree.type)
10161     {
10162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10163       vat_json_init_array (&vam->json_tree);
10164     }
10165   node = vat_json_array_add (&vam->json_tree);
10166
10167   vat_json_init_object (node);
10168
10169   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10170   vat_json_object_add_ip6 (node, "our_address", addr);
10171   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10172   vat_json_object_add_ip6 (node, "client_address", addr);
10173
10174   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10175   vat_json_init_array (lc);
10176   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10177   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10178   vat_json_object_add_uint (node, "remote_cookie",
10179                             clib_net_to_host_u64 (mp->remote_cookie));
10180
10181   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10182   vat_json_object_add_uint (node, "local_session_id",
10183                             clib_net_to_host_u32 (mp->local_session_id));
10184   vat_json_object_add_uint (node, "remote_session_id",
10185                             clib_net_to_host_u32 (mp->remote_session_id));
10186   vat_json_object_add_string_copy (node, "l2_sublayer",
10187                                    mp->l2_sublayer_present ? (u8 *) "present"
10188                                    : (u8 *) "absent");
10189 }
10190
10191 static int
10192 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10193 {
10194   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10195   f64 timeout;
10196
10197   /* Get list of l2tpv3-tunnel interfaces */
10198   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10199   S;
10200
10201   /* Use a control ping for synchronization */
10202   {
10203     vl_api_control_ping_t *mp;
10204     M (CONTROL_PING, control_ping);
10205     S;
10206   }
10207   W;
10208 }
10209
10210
10211 static void vl_api_sw_interface_tap_details_t_handler
10212   (vl_api_sw_interface_tap_details_t * mp)
10213 {
10214   vat_main_t *vam = &vat_main;
10215
10216   print (vam->ofp, "%-16s %d",
10217          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10218 }
10219
10220 static void vl_api_sw_interface_tap_details_t_handler_json
10221   (vl_api_sw_interface_tap_details_t * mp)
10222 {
10223   vat_main_t *vam = &vat_main;
10224   vat_json_node_t *node = NULL;
10225
10226   if (VAT_JSON_ARRAY != vam->json_tree.type)
10227     {
10228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10229       vat_json_init_array (&vam->json_tree);
10230     }
10231   node = vat_json_array_add (&vam->json_tree);
10232
10233   vat_json_init_object (node);
10234   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10235   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10236 }
10237
10238 static int
10239 api_sw_interface_tap_dump (vat_main_t * vam)
10240 {
10241   vl_api_sw_interface_tap_dump_t *mp;
10242   f64 timeout;
10243
10244   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10245   /* Get list of tap interfaces */
10246   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10247   S;
10248
10249   /* Use a control ping for synchronization */
10250   {
10251     vl_api_control_ping_t *mp;
10252     M (CONTROL_PING, control_ping);
10253     S;
10254   }
10255   W;
10256 }
10257
10258 static uword unformat_vxlan_decap_next
10259   (unformat_input_t * input, va_list * args)
10260 {
10261   u32 *result = va_arg (*args, u32 *);
10262   u32 tmp;
10263
10264   if (unformat (input, "l2"))
10265     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10266   else if (unformat (input, "%d", &tmp))
10267     *result = tmp;
10268   else
10269     return 0;
10270   return 1;
10271 }
10272
10273 static int
10274 api_vxlan_add_del_tunnel (vat_main_t * vam)
10275 {
10276   unformat_input_t *line_input = vam->input;
10277   vl_api_vxlan_add_del_tunnel_t *mp;
10278   f64 timeout;
10279   ip46_address_t src, dst;
10280   u8 is_add = 1;
10281   u8 ipv4_set = 0, ipv6_set = 0;
10282   u8 src_set = 0;
10283   u8 dst_set = 0;
10284   u8 grp_set = 0;
10285   u32 mcast_sw_if_index = ~0;
10286   u32 encap_vrf_id = 0;
10287   u32 decap_next_index = ~0;
10288   u32 vni = 0;
10289
10290   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10291   memset (&src, 0, sizeof src);
10292   memset (&dst, 0, sizeof dst);
10293
10294   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10295     {
10296       if (unformat (line_input, "del"))
10297         is_add = 0;
10298       else
10299         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10300         {
10301           ipv4_set = 1;
10302           src_set = 1;
10303         }
10304       else
10305         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10306         {
10307           ipv4_set = 1;
10308           dst_set = 1;
10309         }
10310       else
10311         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10312         {
10313           ipv6_set = 1;
10314           src_set = 1;
10315         }
10316       else
10317         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10318         {
10319           ipv6_set = 1;
10320           dst_set = 1;
10321         }
10322       else if (unformat (line_input, "group %U %U",
10323                          unformat_ip4_address, &dst.ip4,
10324                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10325         {
10326           grp_set = dst_set = 1;
10327           ipv4_set = 1;
10328         }
10329       else if (unformat (line_input, "group %U",
10330                          unformat_ip4_address, &dst.ip4))
10331         {
10332           grp_set = dst_set = 1;
10333           ipv4_set = 1;
10334         }
10335       else if (unformat (line_input, "group %U %U",
10336                          unformat_ip6_address, &dst.ip6,
10337                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10338         {
10339           grp_set = dst_set = 1;
10340           ipv6_set = 1;
10341         }
10342       else if (unformat (line_input, "group %U",
10343                          unformat_ip6_address, &dst.ip6))
10344         {
10345           grp_set = dst_set = 1;
10346           ipv6_set = 1;
10347         }
10348       else
10349         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10350         ;
10351       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10352         ;
10353       else if (unformat (line_input, "decap-next %U",
10354                          unformat_vxlan_decap_next, &decap_next_index))
10355         ;
10356       else if (unformat (line_input, "vni %d", &vni))
10357         ;
10358       else
10359         {
10360           errmsg ("parse error '%U'", format_unformat_error, line_input);
10361           return -99;
10362         }
10363     }
10364
10365   if (src_set == 0)
10366     {
10367       errmsg ("tunnel src address not specified");
10368       return -99;
10369     }
10370   if (dst_set == 0)
10371     {
10372       errmsg ("tunnel dst address not specified");
10373       return -99;
10374     }
10375
10376   if (grp_set && !ip46_address_is_multicast (&dst))
10377     {
10378       errmsg ("tunnel group address not multicast");
10379       return -99;
10380     }
10381   if (grp_set && mcast_sw_if_index == ~0)
10382     {
10383       errmsg ("tunnel nonexistent multicast device");
10384       return -99;
10385     }
10386   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10387     {
10388       errmsg ("tunnel dst address must be unicast");
10389       return -99;
10390     }
10391
10392
10393   if (ipv4_set && ipv6_set)
10394     {
10395       errmsg ("both IPv4 and IPv6 addresses specified");
10396       return -99;
10397     }
10398
10399   if ((vni == 0) || (vni >> 24))
10400     {
10401       errmsg ("vni not specified or out of range");
10402       return -99;
10403     }
10404
10405   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10406
10407   if (ipv6_set)
10408     {
10409       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10410       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10411     }
10412   else
10413     {
10414       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10415       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10416     }
10417   mp->encap_vrf_id = ntohl (encap_vrf_id);
10418   mp->decap_next_index = ntohl (decap_next_index);
10419   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10420   mp->vni = ntohl (vni);
10421   mp->is_add = is_add;
10422   mp->is_ipv6 = ipv6_set;
10423
10424   S;
10425   W;
10426   /* NOTREACHED */
10427   return 0;
10428 }
10429
10430 static void vl_api_vxlan_tunnel_details_t_handler
10431   (vl_api_vxlan_tunnel_details_t * mp)
10432 {
10433   vat_main_t *vam = &vat_main;
10434   ip46_address_t src, dst;
10435
10436   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10437   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10438
10439   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10440          ntohl (mp->sw_if_index),
10441          format_ip46_address, &src, IP46_TYPE_ANY,
10442          format_ip46_address, &dst, IP46_TYPE_ANY,
10443          ntohl (mp->encap_vrf_id),
10444          ntohl (mp->decap_next_index), ntohl (mp->vni),
10445          ntohl (mp->mcast_sw_if_index));
10446 }
10447
10448 static void vl_api_vxlan_tunnel_details_t_handler_json
10449   (vl_api_vxlan_tunnel_details_t * mp)
10450 {
10451   vat_main_t *vam = &vat_main;
10452   vat_json_node_t *node = NULL;
10453
10454   if (VAT_JSON_ARRAY != vam->json_tree.type)
10455     {
10456       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10457       vat_json_init_array (&vam->json_tree);
10458     }
10459   node = vat_json_array_add (&vam->json_tree);
10460
10461   vat_json_init_object (node);
10462   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10463   if (mp->is_ipv6)
10464     {
10465       struct in6_addr ip6;
10466
10467       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10468       vat_json_object_add_ip6 (node, "src_address", ip6);
10469       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10470       vat_json_object_add_ip6 (node, "dst_address", ip6);
10471     }
10472   else
10473     {
10474       struct in_addr ip4;
10475
10476       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10477       vat_json_object_add_ip4 (node, "src_address", ip4);
10478       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10479       vat_json_object_add_ip4 (node, "dst_address", ip4);
10480     }
10481   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10482   vat_json_object_add_uint (node, "decap_next_index",
10483                             ntohl (mp->decap_next_index));
10484   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10485   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10486   vat_json_object_add_uint (node, "mcast_sw_if_index",
10487                             ntohl (mp->mcast_sw_if_index));
10488 }
10489
10490 static int
10491 api_vxlan_tunnel_dump (vat_main_t * vam)
10492 {
10493   unformat_input_t *i = vam->input;
10494   vl_api_vxlan_tunnel_dump_t *mp;
10495   f64 timeout;
10496   u32 sw_if_index;
10497   u8 sw_if_index_set = 0;
10498
10499   /* Parse args required to build the message */
10500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10501     {
10502       if (unformat (i, "sw_if_index %d", &sw_if_index))
10503         sw_if_index_set = 1;
10504       else
10505         break;
10506     }
10507
10508   if (sw_if_index_set == 0)
10509     {
10510       sw_if_index = ~0;
10511     }
10512
10513   if (!vam->json_output)
10514     {
10515       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10516              "sw_if_index", "src_address", "dst_address",
10517              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10518     }
10519
10520   /* Get list of vxlan-tunnel interfaces */
10521   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10522
10523   mp->sw_if_index = htonl (sw_if_index);
10524
10525   S;
10526
10527   /* Use a control ping for synchronization */
10528   {
10529     vl_api_control_ping_t *mp;
10530     M (CONTROL_PING, control_ping);
10531     S;
10532   }
10533   W;
10534 }
10535
10536 static int
10537 api_gre_add_del_tunnel (vat_main_t * vam)
10538 {
10539   unformat_input_t *line_input = vam->input;
10540   vl_api_gre_add_del_tunnel_t *mp;
10541   f64 timeout;
10542   ip4_address_t src4, dst4;
10543   u8 is_add = 1;
10544   u8 teb = 0;
10545   u8 src_set = 0;
10546   u8 dst_set = 0;
10547   u32 outer_fib_id = 0;
10548
10549   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10550     {
10551       if (unformat (line_input, "del"))
10552         is_add = 0;
10553       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10554         src_set = 1;
10555       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10556         dst_set = 1;
10557       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10558         ;
10559       else if (unformat (line_input, "teb"))
10560         teb = 1;
10561       else
10562         {
10563           errmsg ("parse error '%U'", format_unformat_error, line_input);
10564           return -99;
10565         }
10566     }
10567
10568   if (src_set == 0)
10569     {
10570       errmsg ("tunnel src address not specified");
10571       return -99;
10572     }
10573   if (dst_set == 0)
10574     {
10575       errmsg ("tunnel dst address not specified");
10576       return -99;
10577     }
10578
10579
10580   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10581
10582   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10583   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10584   mp->outer_fib_id = ntohl (outer_fib_id);
10585   mp->is_add = is_add;
10586   mp->teb = teb;
10587
10588   S;
10589   W;
10590   /* NOTREACHED */
10591   return 0;
10592 }
10593
10594 static void vl_api_gre_tunnel_details_t_handler
10595   (vl_api_gre_tunnel_details_t * mp)
10596 {
10597   vat_main_t *vam = &vat_main;
10598
10599   print (vam->ofp, "%11d%15U%15U%6d%14d",
10600          ntohl (mp->sw_if_index),
10601          format_ip4_address, &mp->src_address,
10602          format_ip4_address, &mp->dst_address,
10603          mp->teb, ntohl (mp->outer_fib_id));
10604 }
10605
10606 static void vl_api_gre_tunnel_details_t_handler_json
10607   (vl_api_gre_tunnel_details_t * mp)
10608 {
10609   vat_main_t *vam = &vat_main;
10610   vat_json_node_t *node = NULL;
10611   struct in_addr ip4;
10612
10613   if (VAT_JSON_ARRAY != vam->json_tree.type)
10614     {
10615       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10616       vat_json_init_array (&vam->json_tree);
10617     }
10618   node = vat_json_array_add (&vam->json_tree);
10619
10620   vat_json_init_object (node);
10621   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10622   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10623   vat_json_object_add_ip4 (node, "src_address", ip4);
10624   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10625   vat_json_object_add_ip4 (node, "dst_address", ip4);
10626   vat_json_object_add_uint (node, "teb", mp->teb);
10627   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10628 }
10629
10630 static int
10631 api_gre_tunnel_dump (vat_main_t * vam)
10632 {
10633   unformat_input_t *i = vam->input;
10634   vl_api_gre_tunnel_dump_t *mp;
10635   f64 timeout;
10636   u32 sw_if_index;
10637   u8 sw_if_index_set = 0;
10638
10639   /* Parse args required to build the message */
10640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10641     {
10642       if (unformat (i, "sw_if_index %d", &sw_if_index))
10643         sw_if_index_set = 1;
10644       else
10645         break;
10646     }
10647
10648   if (sw_if_index_set == 0)
10649     {
10650       sw_if_index = ~0;
10651     }
10652
10653   if (!vam->json_output)
10654     {
10655       print (vam->ofp, "%11s%15s%15s%6s%14s",
10656              "sw_if_index", "src_address", "dst_address", "teb",
10657              "outer_fib_id");
10658     }
10659
10660   /* Get list of gre-tunnel interfaces */
10661   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10662
10663   mp->sw_if_index = htonl (sw_if_index);
10664
10665   S;
10666
10667   /* Use a control ping for synchronization */
10668   {
10669     vl_api_control_ping_t *mp;
10670     M (CONTROL_PING, control_ping);
10671     S;
10672   }
10673   W;
10674 }
10675
10676 static int
10677 api_l2_fib_clear_table (vat_main_t * vam)
10678 {
10679 //  unformat_input_t * i = vam->input;
10680   vl_api_l2_fib_clear_table_t *mp;
10681   f64 timeout;
10682
10683   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10684
10685   S;
10686   W;
10687   /* NOTREACHED */
10688   return 0;
10689 }
10690
10691 static int
10692 api_l2_interface_efp_filter (vat_main_t * vam)
10693 {
10694   unformat_input_t *i = vam->input;
10695   vl_api_l2_interface_efp_filter_t *mp;
10696   f64 timeout;
10697   u32 sw_if_index;
10698   u8 enable = 1;
10699   u8 sw_if_index_set = 0;
10700
10701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10704         sw_if_index_set = 1;
10705       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10706         sw_if_index_set = 1;
10707       else if (unformat (i, "enable"))
10708         enable = 1;
10709       else if (unformat (i, "disable"))
10710         enable = 0;
10711       else
10712         {
10713           clib_warning ("parse error '%U'", format_unformat_error, i);
10714           return -99;
10715         }
10716     }
10717
10718   if (sw_if_index_set == 0)
10719     {
10720       errmsg ("missing sw_if_index");
10721       return -99;
10722     }
10723
10724   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10725
10726   mp->sw_if_index = ntohl (sw_if_index);
10727   mp->enable_disable = enable;
10728
10729   S;
10730   W;
10731   /* NOTREACHED */
10732   return 0;
10733 }
10734
10735 #define foreach_vtr_op                          \
10736 _("disable",  L2_VTR_DISABLED)                  \
10737 _("push-1",  L2_VTR_PUSH_1)                     \
10738 _("push-2",  L2_VTR_PUSH_2)                     \
10739 _("pop-1",  L2_VTR_POP_1)                       \
10740 _("pop-2",  L2_VTR_POP_2)                       \
10741 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10742 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10743 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10744 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10745
10746 static int
10747 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10748 {
10749   unformat_input_t *i = vam->input;
10750   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10751   f64 timeout;
10752   u32 sw_if_index;
10753   u8 sw_if_index_set = 0;
10754   u8 vtr_op_set = 0;
10755   u32 vtr_op = 0;
10756   u32 push_dot1q = 1;
10757   u32 tag1 = ~0;
10758   u32 tag2 = ~0;
10759
10760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10761     {
10762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10763         sw_if_index_set = 1;
10764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10765         sw_if_index_set = 1;
10766       else if (unformat (i, "vtr_op %d", &vtr_op))
10767         vtr_op_set = 1;
10768 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10769       foreach_vtr_op
10770 #undef _
10771         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10772         ;
10773       else if (unformat (i, "tag1 %d", &tag1))
10774         ;
10775       else if (unformat (i, "tag2 %d", &tag2))
10776         ;
10777       else
10778         {
10779           clib_warning ("parse error '%U'", format_unformat_error, i);
10780           return -99;
10781         }
10782     }
10783
10784   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10785     {
10786       errmsg ("missing vtr operation or sw_if_index");
10787       return -99;
10788     }
10789
10790   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10791     mp->sw_if_index = ntohl (sw_if_index);
10792   mp->vtr_op = ntohl (vtr_op);
10793   mp->push_dot1q = ntohl (push_dot1q);
10794   mp->tag1 = ntohl (tag1);
10795   mp->tag2 = ntohl (tag2);
10796
10797   S;
10798   W;
10799   /* NOTREACHED */
10800   return 0;
10801 }
10802
10803 static int
10804 api_create_vhost_user_if (vat_main_t * vam)
10805 {
10806   unformat_input_t *i = vam->input;
10807   vl_api_create_vhost_user_if_t *mp;
10808   f64 timeout;
10809   u8 *file_name;
10810   u8 is_server = 0;
10811   u8 file_name_set = 0;
10812   u32 custom_dev_instance = ~0;
10813   u8 hwaddr[6];
10814   u8 use_custom_mac = 0;
10815   u8 *tag = 0;
10816
10817   /* Shut up coverity */
10818   memset (hwaddr, 0, sizeof (hwaddr));
10819
10820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10821     {
10822       if (unformat (i, "socket %s", &file_name))
10823         {
10824           file_name_set = 1;
10825         }
10826       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10827         ;
10828       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10829         use_custom_mac = 1;
10830       else if (unformat (i, "server"))
10831         is_server = 1;
10832       else if (unformat (i, "tag %s", &tag))
10833         ;
10834       else
10835         break;
10836     }
10837
10838   if (file_name_set == 0)
10839     {
10840       errmsg ("missing socket file name");
10841       return -99;
10842     }
10843
10844   if (vec_len (file_name) > 255)
10845     {
10846       errmsg ("socket file name too long");
10847       return -99;
10848     }
10849   vec_add1 (file_name, 0);
10850
10851   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10852
10853   mp->is_server = is_server;
10854   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10855   vec_free (file_name);
10856   if (custom_dev_instance != ~0)
10857     {
10858       mp->renumber = 1;
10859       mp->custom_dev_instance = ntohl (custom_dev_instance);
10860     }
10861   mp->use_custom_mac = use_custom_mac;
10862   clib_memcpy (mp->mac_address, hwaddr, 6);
10863   if (tag)
10864     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10865   vec_free (tag);
10866
10867   S;
10868   W;
10869   /* NOTREACHED */
10870   return 0;
10871 }
10872
10873 static int
10874 api_modify_vhost_user_if (vat_main_t * vam)
10875 {
10876   unformat_input_t *i = vam->input;
10877   vl_api_modify_vhost_user_if_t *mp;
10878   f64 timeout;
10879   u8 *file_name;
10880   u8 is_server = 0;
10881   u8 file_name_set = 0;
10882   u32 custom_dev_instance = ~0;
10883   u8 sw_if_index_set = 0;
10884   u32 sw_if_index = (u32) ~ 0;
10885
10886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10889         sw_if_index_set = 1;
10890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10891         sw_if_index_set = 1;
10892       else if (unformat (i, "socket %s", &file_name))
10893         {
10894           file_name_set = 1;
10895         }
10896       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10897         ;
10898       else if (unformat (i, "server"))
10899         is_server = 1;
10900       else
10901         break;
10902     }
10903
10904   if (sw_if_index_set == 0)
10905     {
10906       errmsg ("missing sw_if_index or interface name");
10907       return -99;
10908     }
10909
10910   if (file_name_set == 0)
10911     {
10912       errmsg ("missing socket file name");
10913       return -99;
10914     }
10915
10916   if (vec_len (file_name) > 255)
10917     {
10918       errmsg ("socket file name too long");
10919       return -99;
10920     }
10921   vec_add1 (file_name, 0);
10922
10923   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10924
10925   mp->sw_if_index = ntohl (sw_if_index);
10926   mp->is_server = is_server;
10927   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10928   vec_free (file_name);
10929   if (custom_dev_instance != ~0)
10930     {
10931       mp->renumber = 1;
10932       mp->custom_dev_instance = ntohl (custom_dev_instance);
10933     }
10934
10935   S;
10936   W;
10937   /* NOTREACHED */
10938   return 0;
10939 }
10940
10941 static int
10942 api_delete_vhost_user_if (vat_main_t * vam)
10943 {
10944   unformat_input_t *i = vam->input;
10945   vl_api_delete_vhost_user_if_t *mp;
10946   f64 timeout;
10947   u32 sw_if_index = ~0;
10948   u8 sw_if_index_set = 0;
10949
10950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10951     {
10952       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10953         sw_if_index_set = 1;
10954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10955         sw_if_index_set = 1;
10956       else
10957         break;
10958     }
10959
10960   if (sw_if_index_set == 0)
10961     {
10962       errmsg ("missing sw_if_index or interface name");
10963       return -99;
10964     }
10965
10966
10967   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10968
10969   mp->sw_if_index = ntohl (sw_if_index);
10970
10971   S;
10972   W;
10973   /* NOTREACHED */
10974   return 0;
10975 }
10976
10977 static void vl_api_sw_interface_vhost_user_details_t_handler
10978   (vl_api_sw_interface_vhost_user_details_t * mp)
10979 {
10980   vat_main_t *vam = &vat_main;
10981
10982   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10983          (char *) mp->interface_name,
10984          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10985          clib_net_to_host_u64 (mp->features), mp->is_server,
10986          ntohl (mp->num_regions), (char *) mp->sock_filename);
10987   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10988 }
10989
10990 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10991   (vl_api_sw_interface_vhost_user_details_t * mp)
10992 {
10993   vat_main_t *vam = &vat_main;
10994   vat_json_node_t *node = NULL;
10995
10996   if (VAT_JSON_ARRAY != vam->json_tree.type)
10997     {
10998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10999       vat_json_init_array (&vam->json_tree);
11000     }
11001   node = vat_json_array_add (&vam->json_tree);
11002
11003   vat_json_init_object (node);
11004   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11005   vat_json_object_add_string_copy (node, "interface_name",
11006                                    mp->interface_name);
11007   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11008                             ntohl (mp->virtio_net_hdr_sz));
11009   vat_json_object_add_uint (node, "features",
11010                             clib_net_to_host_u64 (mp->features));
11011   vat_json_object_add_uint (node, "is_server", mp->is_server);
11012   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11013   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11014   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11015 }
11016
11017 static int
11018 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11019 {
11020   vl_api_sw_interface_vhost_user_dump_t *mp;
11021   f64 timeout;
11022   print (vam->ofp,
11023          "Interface name           idx hdr_sz features server regions filename");
11024
11025   /* Get list of vhost-user interfaces */
11026   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11027   S;
11028
11029   /* Use a control ping for synchronization */
11030   {
11031     vl_api_control_ping_t *mp;
11032     M (CONTROL_PING, control_ping);
11033     S;
11034   }
11035   W;
11036 }
11037
11038 static int
11039 api_show_version (vat_main_t * vam)
11040 {
11041   vl_api_show_version_t *mp;
11042   f64 timeout;
11043
11044   M (SHOW_VERSION, show_version);
11045
11046   S;
11047   W;
11048   /* NOTREACHED */
11049   return 0;
11050 }
11051
11052
11053 static int
11054 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11055 {
11056   unformat_input_t *line_input = vam->input;
11057   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11058   f64 timeout;
11059   ip4_address_t local4, remote4;
11060   ip6_address_t local6, remote6;
11061   u8 is_add = 1;
11062   u8 ipv4_set = 0, ipv6_set = 0;
11063   u8 local_set = 0;
11064   u8 remote_set = 0;
11065   u32 encap_vrf_id = 0;
11066   u32 decap_vrf_id = 0;
11067   u8 protocol = ~0;
11068   u32 vni;
11069   u8 vni_set = 0;
11070
11071   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11072     {
11073       if (unformat (line_input, "del"))
11074         is_add = 0;
11075       else if (unformat (line_input, "local %U",
11076                          unformat_ip4_address, &local4))
11077         {
11078           local_set = 1;
11079           ipv4_set = 1;
11080         }
11081       else if (unformat (line_input, "remote %U",
11082                          unformat_ip4_address, &remote4))
11083         {
11084           remote_set = 1;
11085           ipv4_set = 1;
11086         }
11087       else if (unformat (line_input, "local %U",
11088                          unformat_ip6_address, &local6))
11089         {
11090           local_set = 1;
11091           ipv6_set = 1;
11092         }
11093       else if (unformat (line_input, "remote %U",
11094                          unformat_ip6_address, &remote6))
11095         {
11096           remote_set = 1;
11097           ipv6_set = 1;
11098         }
11099       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11100         ;
11101       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11102         ;
11103       else if (unformat (line_input, "vni %d", &vni))
11104         vni_set = 1;
11105       else if (unformat (line_input, "next-ip4"))
11106         protocol = 1;
11107       else if (unformat (line_input, "next-ip6"))
11108         protocol = 2;
11109       else if (unformat (line_input, "next-ethernet"))
11110         protocol = 3;
11111       else if (unformat (line_input, "next-nsh"))
11112         protocol = 4;
11113       else
11114         {
11115           errmsg ("parse error '%U'", format_unformat_error, line_input);
11116           return -99;
11117         }
11118     }
11119
11120   if (local_set == 0)
11121     {
11122       errmsg ("tunnel local address not specified");
11123       return -99;
11124     }
11125   if (remote_set == 0)
11126     {
11127       errmsg ("tunnel remote address not specified");
11128       return -99;
11129     }
11130   if (ipv4_set && ipv6_set)
11131     {
11132       errmsg ("both IPv4 and IPv6 addresses specified");
11133       return -99;
11134     }
11135
11136   if (vni_set == 0)
11137     {
11138       errmsg ("vni not specified");
11139       return -99;
11140     }
11141
11142   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11143
11144
11145   if (ipv6_set)
11146     {
11147       clib_memcpy (&mp->local, &local6, sizeof (local6));
11148       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11149     }
11150   else
11151     {
11152       clib_memcpy (&mp->local, &local4, sizeof (local4));
11153       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11154     }
11155
11156   mp->encap_vrf_id = ntohl (encap_vrf_id);
11157   mp->decap_vrf_id = ntohl (decap_vrf_id);
11158   mp->protocol = protocol;
11159   mp->vni = ntohl (vni);
11160   mp->is_add = is_add;
11161   mp->is_ipv6 = ipv6_set;
11162
11163   S;
11164   W;
11165   /* NOTREACHED */
11166   return 0;
11167 }
11168
11169 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11170   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11171 {
11172   vat_main_t *vam = &vat_main;
11173
11174   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11175          ntohl (mp->sw_if_index),
11176          format_ip46_address, &(mp->local[0]),
11177          format_ip46_address, &(mp->remote[0]),
11178          ntohl (mp->vni),
11179          ntohl (mp->protocol),
11180          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11181 }
11182
11183 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11184   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11185 {
11186   vat_main_t *vam = &vat_main;
11187   vat_json_node_t *node = NULL;
11188   struct in_addr ip4;
11189   struct in6_addr ip6;
11190
11191   if (VAT_JSON_ARRAY != vam->json_tree.type)
11192     {
11193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11194       vat_json_init_array (&vam->json_tree);
11195     }
11196   node = vat_json_array_add (&vam->json_tree);
11197
11198   vat_json_init_object (node);
11199   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11200   if (mp->is_ipv6)
11201     {
11202       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11203       vat_json_object_add_ip6 (node, "local", ip6);
11204       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11205       vat_json_object_add_ip6 (node, "remote", ip6);
11206     }
11207   else
11208     {
11209       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11210       vat_json_object_add_ip4 (node, "local", ip4);
11211       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11212       vat_json_object_add_ip4 (node, "remote", ip4);
11213     }
11214   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11215   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11216   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11217   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11218   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11219 }
11220
11221 static int
11222 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11223 {
11224   unformat_input_t *i = vam->input;
11225   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11226   f64 timeout;
11227   u32 sw_if_index;
11228   u8 sw_if_index_set = 0;
11229
11230   /* Parse args required to build the message */
11231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11232     {
11233       if (unformat (i, "sw_if_index %d", &sw_if_index))
11234         sw_if_index_set = 1;
11235       else
11236         break;
11237     }
11238
11239   if (sw_if_index_set == 0)
11240     {
11241       sw_if_index = ~0;
11242     }
11243
11244   if (!vam->json_output)
11245     {
11246       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11247              "sw_if_index", "local", "remote", "vni",
11248              "protocol", "encap_vrf_id", "decap_vrf_id");
11249     }
11250
11251   /* Get list of vxlan-tunnel interfaces */
11252   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11253
11254   mp->sw_if_index = htonl (sw_if_index);
11255
11256   S;
11257
11258   /* Use a control ping for synchronization */
11259   {
11260     vl_api_control_ping_t *mp;
11261     M (CONTROL_PING, control_ping);
11262     S;
11263   }
11264   W;
11265 }
11266
11267 u8 *
11268 format_l2_fib_mac_address (u8 * s, va_list * args)
11269 {
11270   u8 *a = va_arg (*args, u8 *);
11271
11272   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11273                  a[2], a[3], a[4], a[5], a[6], a[7]);
11274 }
11275
11276 static void vl_api_l2_fib_table_entry_t_handler
11277   (vl_api_l2_fib_table_entry_t * mp)
11278 {
11279   vat_main_t *vam = &vat_main;
11280
11281   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11282          "       %d       %d     %d",
11283          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11284          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11285          mp->bvi_mac);
11286 }
11287
11288 static void vl_api_l2_fib_table_entry_t_handler_json
11289   (vl_api_l2_fib_table_entry_t * mp)
11290 {
11291   vat_main_t *vam = &vat_main;
11292   vat_json_node_t *node = NULL;
11293
11294   if (VAT_JSON_ARRAY != vam->json_tree.type)
11295     {
11296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11297       vat_json_init_array (&vam->json_tree);
11298     }
11299   node = vat_json_array_add (&vam->json_tree);
11300
11301   vat_json_init_object (node);
11302   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11303   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11304   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11305   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11306   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11307   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11308 }
11309
11310 static int
11311 api_l2_fib_table_dump (vat_main_t * vam)
11312 {
11313   unformat_input_t *i = vam->input;
11314   vl_api_l2_fib_table_dump_t *mp;
11315   f64 timeout;
11316   u32 bd_id;
11317   u8 bd_id_set = 0;
11318
11319   /* Parse args required to build the message */
11320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11321     {
11322       if (unformat (i, "bd_id %d", &bd_id))
11323         bd_id_set = 1;
11324       else
11325         break;
11326     }
11327
11328   if (bd_id_set == 0)
11329     {
11330       errmsg ("missing bridge domain");
11331       return -99;
11332     }
11333
11334   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11335
11336   /* Get list of l2 fib entries */
11337   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11338
11339   mp->bd_id = ntohl (bd_id);
11340   S;
11341
11342   /* Use a control ping for synchronization */
11343   {
11344     vl_api_control_ping_t *mp;
11345     M (CONTROL_PING, control_ping);
11346     S;
11347   }
11348   W;
11349 }
11350
11351
11352 static int
11353 api_interface_name_renumber (vat_main_t * vam)
11354 {
11355   unformat_input_t *line_input = vam->input;
11356   vl_api_interface_name_renumber_t *mp;
11357   u32 sw_if_index = ~0;
11358   f64 timeout;
11359   u32 new_show_dev_instance = ~0;
11360
11361   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11362     {
11363       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11364                     &sw_if_index))
11365         ;
11366       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11367         ;
11368       else if (unformat (line_input, "new_show_dev_instance %d",
11369                          &new_show_dev_instance))
11370         ;
11371       else
11372         break;
11373     }
11374
11375   if (sw_if_index == ~0)
11376     {
11377       errmsg ("missing interface name or sw_if_index");
11378       return -99;
11379     }
11380
11381   if (new_show_dev_instance == ~0)
11382     {
11383       errmsg ("missing new_show_dev_instance");
11384       return -99;
11385     }
11386
11387   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11388
11389   mp->sw_if_index = ntohl (sw_if_index);
11390   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11391
11392   S;
11393   W;
11394 }
11395
11396 static int
11397 api_want_ip4_arp_events (vat_main_t * vam)
11398 {
11399   unformat_input_t *line_input = vam->input;
11400   vl_api_want_ip4_arp_events_t *mp;
11401   f64 timeout;
11402   ip4_address_t address;
11403   int address_set = 0;
11404   u32 enable_disable = 1;
11405
11406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11407     {
11408       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11409         address_set = 1;
11410       else if (unformat (line_input, "del"))
11411         enable_disable = 0;
11412       else
11413         break;
11414     }
11415
11416   if (address_set == 0)
11417     {
11418       errmsg ("missing addresses");
11419       return -99;
11420     }
11421
11422   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11423   mp->enable_disable = enable_disable;
11424   mp->pid = getpid ();
11425   mp->address = address.as_u32;
11426
11427   S;
11428   W;
11429 }
11430
11431 static int
11432 api_want_ip6_nd_events (vat_main_t * vam)
11433 {
11434   unformat_input_t *line_input = vam->input;
11435   vl_api_want_ip6_nd_events_t *mp;
11436   f64 timeout;
11437   ip6_address_t address;
11438   int address_set = 0;
11439   u32 enable_disable = 1;
11440
11441   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11442     {
11443       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11444         address_set = 1;
11445       else if (unformat (line_input, "del"))
11446         enable_disable = 0;
11447       else
11448         break;
11449     }
11450
11451   if (address_set == 0)
11452     {
11453       errmsg ("missing addresses");
11454       return -99;
11455     }
11456
11457   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11458   mp->enable_disable = enable_disable;
11459   mp->pid = getpid ();
11460   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11461
11462   S;
11463   W;
11464 }
11465
11466 static int
11467 api_input_acl_set_interface (vat_main_t * vam)
11468 {
11469   unformat_input_t *i = vam->input;
11470   vl_api_input_acl_set_interface_t *mp;
11471   f64 timeout;
11472   u32 sw_if_index;
11473   int sw_if_index_set;
11474   u32 ip4_table_index = ~0;
11475   u32 ip6_table_index = ~0;
11476   u32 l2_table_index = ~0;
11477   u8 is_add = 1;
11478
11479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11480     {
11481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11482         sw_if_index_set = 1;
11483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11484         sw_if_index_set = 1;
11485       else if (unformat (i, "del"))
11486         is_add = 0;
11487       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11488         ;
11489       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11490         ;
11491       else if (unformat (i, "l2-table %d", &l2_table_index))
11492         ;
11493       else
11494         {
11495           clib_warning ("parse error '%U'", format_unformat_error, i);
11496           return -99;
11497         }
11498     }
11499
11500   if (sw_if_index_set == 0)
11501     {
11502       errmsg ("missing interface name or sw_if_index");
11503       return -99;
11504     }
11505
11506   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11507
11508   mp->sw_if_index = ntohl (sw_if_index);
11509   mp->ip4_table_index = ntohl (ip4_table_index);
11510   mp->ip6_table_index = ntohl (ip6_table_index);
11511   mp->l2_table_index = ntohl (l2_table_index);
11512   mp->is_add = is_add;
11513
11514   S;
11515   W;
11516   /* NOTREACHED */
11517   return 0;
11518 }
11519
11520 static int
11521 api_ip_address_dump (vat_main_t * vam)
11522 {
11523   unformat_input_t *i = vam->input;
11524   vl_api_ip_address_dump_t *mp;
11525   u32 sw_if_index = ~0;
11526   u8 sw_if_index_set = 0;
11527   u8 ipv4_set = 0;
11528   u8 ipv6_set = 0;
11529   f64 timeout;
11530
11531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (i, "sw_if_index %d", &sw_if_index))
11534         sw_if_index_set = 1;
11535       else
11536         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11537         sw_if_index_set = 1;
11538       else if (unformat (i, "ipv4"))
11539         ipv4_set = 1;
11540       else if (unformat (i, "ipv6"))
11541         ipv6_set = 1;
11542       else
11543         break;
11544     }
11545
11546   if (ipv4_set && ipv6_set)
11547     {
11548       errmsg ("ipv4 and ipv6 flags cannot be both set");
11549       return -99;
11550     }
11551
11552   if ((!ipv4_set) && (!ipv6_set))
11553     {
11554       errmsg ("no ipv4 nor ipv6 flag set");
11555       return -99;
11556     }
11557
11558   if (sw_if_index_set == 0)
11559     {
11560       errmsg ("missing interface name or sw_if_index");
11561       return -99;
11562     }
11563
11564   vam->current_sw_if_index = sw_if_index;
11565   vam->is_ipv6 = ipv6_set;
11566
11567   M (IP_ADDRESS_DUMP, ip_address_dump);
11568   mp->sw_if_index = ntohl (sw_if_index);
11569   mp->is_ipv6 = ipv6_set;
11570   S;
11571
11572   /* Use a control ping for synchronization */
11573   {
11574     vl_api_control_ping_t *mp;
11575     M (CONTROL_PING, control_ping);
11576     S;
11577   }
11578   W;
11579 }
11580
11581 static int
11582 api_ip_dump (vat_main_t * vam)
11583 {
11584   vl_api_ip_dump_t *mp;
11585   unformat_input_t *in = vam->input;
11586   int ipv4_set = 0;
11587   int ipv6_set = 0;
11588   int is_ipv6;
11589   f64 timeout;
11590   int i;
11591
11592   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11593     {
11594       if (unformat (in, "ipv4"))
11595         ipv4_set = 1;
11596       else if (unformat (in, "ipv6"))
11597         ipv6_set = 1;
11598       else
11599         break;
11600     }
11601
11602   if (ipv4_set && ipv6_set)
11603     {
11604       errmsg ("ipv4 and ipv6 flags cannot be both set");
11605       return -99;
11606     }
11607
11608   if ((!ipv4_set) && (!ipv6_set))
11609     {
11610       errmsg ("no ipv4 nor ipv6 flag set");
11611       return -99;
11612     }
11613
11614   is_ipv6 = ipv6_set;
11615   vam->is_ipv6 = is_ipv6;
11616
11617   /* free old data */
11618   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11619     {
11620       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11621     }
11622   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11623
11624   M (IP_DUMP, ip_dump);
11625   mp->is_ipv6 = ipv6_set;
11626   S;
11627
11628   /* Use a control ping for synchronization */
11629   {
11630     vl_api_control_ping_t *mp;
11631     M (CONTROL_PING, control_ping);
11632     S;
11633   }
11634   W;
11635 }
11636
11637 static int
11638 api_ipsec_spd_add_del (vat_main_t * vam)
11639 {
11640   unformat_input_t *i = vam->input;
11641   vl_api_ipsec_spd_add_del_t *mp;
11642   f64 timeout;
11643   u32 spd_id = ~0;
11644   u8 is_add = 1;
11645
11646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (i, "spd_id %d", &spd_id))
11649         ;
11650       else if (unformat (i, "del"))
11651         is_add = 0;
11652       else
11653         {
11654           clib_warning ("parse error '%U'", format_unformat_error, i);
11655           return -99;
11656         }
11657     }
11658   if (spd_id == ~0)
11659     {
11660       errmsg ("spd_id must be set");
11661       return -99;
11662     }
11663
11664   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11665
11666   mp->spd_id = ntohl (spd_id);
11667   mp->is_add = is_add;
11668
11669   S;
11670   W;
11671   /* NOTREACHED */
11672   return 0;
11673 }
11674
11675 static int
11676 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11677 {
11678   unformat_input_t *i = vam->input;
11679   vl_api_ipsec_interface_add_del_spd_t *mp;
11680   f64 timeout;
11681   u32 sw_if_index;
11682   u8 sw_if_index_set = 0;
11683   u32 spd_id = (u32) ~ 0;
11684   u8 is_add = 1;
11685
11686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (i, "del"))
11689         is_add = 0;
11690       else if (unformat (i, "spd_id %d", &spd_id))
11691         ;
11692       else
11693         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11694         sw_if_index_set = 1;
11695       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11696         sw_if_index_set = 1;
11697       else
11698         {
11699           clib_warning ("parse error '%U'", format_unformat_error, i);
11700           return -99;
11701         }
11702
11703     }
11704
11705   if (spd_id == (u32) ~ 0)
11706     {
11707       errmsg ("spd_id must be set");
11708       return -99;
11709     }
11710
11711   if (sw_if_index_set == 0)
11712     {
11713       errmsg ("missing interface name or sw_if_index");
11714       return -99;
11715     }
11716
11717   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11718
11719   mp->spd_id = ntohl (spd_id);
11720   mp->sw_if_index = ntohl (sw_if_index);
11721   mp->is_add = is_add;
11722
11723   S;
11724   W;
11725   /* NOTREACHED */
11726   return 0;
11727 }
11728
11729 static int
11730 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11731 {
11732   unformat_input_t *i = vam->input;
11733   vl_api_ipsec_spd_add_del_entry_t *mp;
11734   f64 timeout;
11735   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11736   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11737   i32 priority = 0;
11738   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11739   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11740   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11741   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11742
11743   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11744   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11745   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11746   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11747   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11748   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11749
11750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11751     {
11752       if (unformat (i, "del"))
11753         is_add = 0;
11754       if (unformat (i, "outbound"))
11755         is_outbound = 1;
11756       if (unformat (i, "inbound"))
11757         is_outbound = 0;
11758       else if (unformat (i, "spd_id %d", &spd_id))
11759         ;
11760       else if (unformat (i, "sa_id %d", &sa_id))
11761         ;
11762       else if (unformat (i, "priority %d", &priority))
11763         ;
11764       else if (unformat (i, "protocol %d", &protocol))
11765         ;
11766       else if (unformat (i, "lport_start %d", &lport_start))
11767         ;
11768       else if (unformat (i, "lport_stop %d", &lport_stop))
11769         ;
11770       else if (unformat (i, "rport_start %d", &rport_start))
11771         ;
11772       else if (unformat (i, "rport_stop %d", &rport_stop))
11773         ;
11774       else
11775         if (unformat
11776             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11777         {
11778           is_ipv6 = 0;
11779           is_ip_any = 0;
11780         }
11781       else
11782         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11783         {
11784           is_ipv6 = 0;
11785           is_ip_any = 0;
11786         }
11787       else
11788         if (unformat
11789             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11790         {
11791           is_ipv6 = 0;
11792           is_ip_any = 0;
11793         }
11794       else
11795         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11796         {
11797           is_ipv6 = 0;
11798           is_ip_any = 0;
11799         }
11800       else
11801         if (unformat
11802             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11803         {
11804           is_ipv6 = 1;
11805           is_ip_any = 0;
11806         }
11807       else
11808         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11809         {
11810           is_ipv6 = 1;
11811           is_ip_any = 0;
11812         }
11813       else
11814         if (unformat
11815             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11816         {
11817           is_ipv6 = 1;
11818           is_ip_any = 0;
11819         }
11820       else
11821         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11822         {
11823           is_ipv6 = 1;
11824           is_ip_any = 0;
11825         }
11826       else
11827         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11828         {
11829           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11830             {
11831               clib_warning ("unsupported action: 'resolve'");
11832               return -99;
11833             }
11834         }
11835       else
11836         {
11837           clib_warning ("parse error '%U'", format_unformat_error, i);
11838           return -99;
11839         }
11840
11841     }
11842
11843   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11844
11845   mp->spd_id = ntohl (spd_id);
11846   mp->priority = ntohl (priority);
11847   mp->is_outbound = is_outbound;
11848
11849   mp->is_ipv6 = is_ipv6;
11850   if (is_ipv6 || is_ip_any)
11851     {
11852       clib_memcpy (mp->remote_address_start, &raddr6_start,
11853                    sizeof (ip6_address_t));
11854       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11855                    sizeof (ip6_address_t));
11856       clib_memcpy (mp->local_address_start, &laddr6_start,
11857                    sizeof (ip6_address_t));
11858       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11859                    sizeof (ip6_address_t));
11860     }
11861   else
11862     {
11863       clib_memcpy (mp->remote_address_start, &raddr4_start,
11864                    sizeof (ip4_address_t));
11865       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11866                    sizeof (ip4_address_t));
11867       clib_memcpy (mp->local_address_start, &laddr4_start,
11868                    sizeof (ip4_address_t));
11869       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11870                    sizeof (ip4_address_t));
11871     }
11872   mp->protocol = (u8) protocol;
11873   mp->local_port_start = ntohs ((u16) lport_start);
11874   mp->local_port_stop = ntohs ((u16) lport_stop);
11875   mp->remote_port_start = ntohs ((u16) rport_start);
11876   mp->remote_port_stop = ntohs ((u16) rport_stop);
11877   mp->policy = (u8) policy;
11878   mp->sa_id = ntohl (sa_id);
11879   mp->is_add = is_add;
11880   mp->is_ip_any = is_ip_any;
11881   S;
11882   W;
11883   /* NOTREACHED */
11884   return 0;
11885 }
11886
11887 static int
11888 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11889 {
11890   unformat_input_t *i = vam->input;
11891   vl_api_ipsec_sad_add_del_entry_t *mp;
11892   f64 timeout;
11893   u32 sad_id = 0, spi = 0;
11894   u8 *ck = 0, *ik = 0;
11895   u8 is_add = 1;
11896
11897   u8 protocol = IPSEC_PROTOCOL_AH;
11898   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11899   u32 crypto_alg = 0, integ_alg = 0;
11900   ip4_address_t tun_src4;
11901   ip4_address_t tun_dst4;
11902   ip6_address_t tun_src6;
11903   ip6_address_t tun_dst6;
11904
11905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11906     {
11907       if (unformat (i, "del"))
11908         is_add = 0;
11909       else if (unformat (i, "sad_id %d", &sad_id))
11910         ;
11911       else if (unformat (i, "spi %d", &spi))
11912         ;
11913       else if (unformat (i, "esp"))
11914         protocol = IPSEC_PROTOCOL_ESP;
11915       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11916         {
11917           is_tunnel = 1;
11918           is_tunnel_ipv6 = 0;
11919         }
11920       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11921         {
11922           is_tunnel = 1;
11923           is_tunnel_ipv6 = 0;
11924         }
11925       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11926         {
11927           is_tunnel = 1;
11928           is_tunnel_ipv6 = 1;
11929         }
11930       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11931         {
11932           is_tunnel = 1;
11933           is_tunnel_ipv6 = 1;
11934         }
11935       else
11936         if (unformat
11937             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11938         {
11939           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11940               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11941             {
11942               clib_warning ("unsupported crypto-alg: '%U'",
11943                             format_ipsec_crypto_alg, crypto_alg);
11944               return -99;
11945             }
11946         }
11947       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11948         ;
11949       else
11950         if (unformat
11951             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11952         {
11953 #if DPDK_CRYPTO==1
11954           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11955 #else
11956           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11957 #endif
11958               integ_alg >= IPSEC_INTEG_N_ALG)
11959             {
11960               clib_warning ("unsupported integ-alg: '%U'",
11961                             format_ipsec_integ_alg, integ_alg);
11962               return -99;
11963             }
11964         }
11965       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11966         ;
11967       else
11968         {
11969           clib_warning ("parse error '%U'", format_unformat_error, i);
11970           return -99;
11971         }
11972
11973     }
11974
11975 #if DPDK_CRYPTO==1
11976   /*Special cases, aes-gcm-128 encryption */
11977   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11978     {
11979       if (integ_alg != IPSEC_INTEG_ALG_NONE
11980           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11981         {
11982           clib_warning
11983             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11984           return -99;
11985         }
11986       else                      /*set integ-alg internally to aes-gcm-128 */
11987         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11988     }
11989   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11990     {
11991       clib_warning ("unsupported integ-alg: aes-gcm-128");
11992       return -99;
11993     }
11994   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11995     {
11996       clib_warning ("unsupported integ-alg: none");
11997       return -99;
11998     }
11999 #endif
12000
12001
12002   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12003
12004   mp->sad_id = ntohl (sad_id);
12005   mp->is_add = is_add;
12006   mp->protocol = protocol;
12007   mp->spi = ntohl (spi);
12008   mp->is_tunnel = is_tunnel;
12009   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12010   mp->crypto_algorithm = crypto_alg;
12011   mp->integrity_algorithm = integ_alg;
12012   mp->crypto_key_length = vec_len (ck);
12013   mp->integrity_key_length = vec_len (ik);
12014
12015   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12016     mp->crypto_key_length = sizeof (mp->crypto_key);
12017
12018   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12019     mp->integrity_key_length = sizeof (mp->integrity_key);
12020
12021   if (ck)
12022     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12023   if (ik)
12024     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12025
12026   if (is_tunnel)
12027     {
12028       if (is_tunnel_ipv6)
12029         {
12030           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12031                        sizeof (ip6_address_t));
12032           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12033                        sizeof (ip6_address_t));
12034         }
12035       else
12036         {
12037           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12038                        sizeof (ip4_address_t));
12039           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12040                        sizeof (ip4_address_t));
12041         }
12042     }
12043
12044   S;
12045   W;
12046   /* NOTREACHED */
12047   return 0;
12048 }
12049
12050 static int
12051 api_ipsec_sa_set_key (vat_main_t * vam)
12052 {
12053   unformat_input_t *i = vam->input;
12054   vl_api_ipsec_sa_set_key_t *mp;
12055   f64 timeout;
12056   u32 sa_id;
12057   u8 *ck = 0, *ik = 0;
12058
12059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12060     {
12061       if (unformat (i, "sa_id %d", &sa_id))
12062         ;
12063       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12064         ;
12065       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12066         ;
12067       else
12068         {
12069           clib_warning ("parse error '%U'", format_unformat_error, i);
12070           return -99;
12071         }
12072     }
12073
12074   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12075
12076   mp->sa_id = ntohl (sa_id);
12077   mp->crypto_key_length = vec_len (ck);
12078   mp->integrity_key_length = vec_len (ik);
12079
12080   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12081     mp->crypto_key_length = sizeof (mp->crypto_key);
12082
12083   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12084     mp->integrity_key_length = sizeof (mp->integrity_key);
12085
12086   if (ck)
12087     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12088   if (ik)
12089     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12090
12091   S;
12092   W;
12093   /* NOTREACHED */
12094   return 0;
12095 }
12096
12097 static int
12098 api_ikev2_profile_add_del (vat_main_t * vam)
12099 {
12100   unformat_input_t *i = vam->input;
12101   vl_api_ikev2_profile_add_del_t *mp;
12102   f64 timeout;
12103   u8 is_add = 1;
12104   u8 *name = 0;
12105
12106   const char *valid_chars = "a-zA-Z0-9_";
12107
12108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12109     {
12110       if (unformat (i, "del"))
12111         is_add = 0;
12112       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12113         vec_add1 (name, 0);
12114       else
12115         {
12116           errmsg ("parse error '%U'", format_unformat_error, i);
12117           return -99;
12118         }
12119     }
12120
12121   if (!vec_len (name))
12122     {
12123       errmsg ("profile name must be specified");
12124       return -99;
12125     }
12126
12127   if (vec_len (name) > 64)
12128     {
12129       errmsg ("profile name too long");
12130       return -99;
12131     }
12132
12133   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12134
12135   clib_memcpy (mp->name, name, vec_len (name));
12136   mp->is_add = is_add;
12137   vec_free (name);
12138
12139   S;
12140   W;
12141   /* NOTREACHED */
12142   return 0;
12143 }
12144
12145 static int
12146 api_ikev2_profile_set_auth (vat_main_t * vam)
12147 {
12148   unformat_input_t *i = vam->input;
12149   vl_api_ikev2_profile_set_auth_t *mp;
12150   f64 timeout;
12151   u8 *name = 0;
12152   u8 *data = 0;
12153   u32 auth_method = 0;
12154   u8 is_hex = 0;
12155
12156   const char *valid_chars = "a-zA-Z0-9_";
12157
12158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12159     {
12160       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12161         vec_add1 (name, 0);
12162       else if (unformat (i, "auth_method %U",
12163                          unformat_ikev2_auth_method, &auth_method))
12164         ;
12165       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12166         is_hex = 1;
12167       else if (unformat (i, "auth_data %v", &data))
12168         ;
12169       else
12170         {
12171           errmsg ("parse error '%U'", format_unformat_error, i);
12172           return -99;
12173         }
12174     }
12175
12176   if (!vec_len (name))
12177     {
12178       errmsg ("profile name must be specified");
12179       return -99;
12180     }
12181
12182   if (vec_len (name) > 64)
12183     {
12184       errmsg ("profile name too long");
12185       return -99;
12186     }
12187
12188   if (!vec_len (data))
12189     {
12190       errmsg ("auth_data must be specified");
12191       return -99;
12192     }
12193
12194   if (!auth_method)
12195     {
12196       errmsg ("auth_method must be specified");
12197       return -99;
12198     }
12199
12200   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12201
12202   mp->is_hex = is_hex;
12203   mp->auth_method = (u8) auth_method;
12204   mp->data_len = vec_len (data);
12205   clib_memcpy (mp->name, name, vec_len (name));
12206   clib_memcpy (mp->data, data, vec_len (data));
12207   vec_free (name);
12208   vec_free (data);
12209
12210   S;
12211   W;
12212   /* NOTREACHED */
12213   return 0;
12214 }
12215
12216 static int
12217 api_ikev2_profile_set_id (vat_main_t * vam)
12218 {
12219   unformat_input_t *i = vam->input;
12220   vl_api_ikev2_profile_set_id_t *mp;
12221   f64 timeout;
12222   u8 *name = 0;
12223   u8 *data = 0;
12224   u8 is_local = 0;
12225   u32 id_type = 0;
12226   ip4_address_t ip4;
12227
12228   const char *valid_chars = "a-zA-Z0-9_";
12229
12230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12233         vec_add1 (name, 0);
12234       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12235         ;
12236       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12237         {
12238           data = vec_new (u8, 4);
12239           clib_memcpy (data, ip4.as_u8, 4);
12240         }
12241       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12242         ;
12243       else if (unformat (i, "id_data %v", &data))
12244         ;
12245       else if (unformat (i, "local"))
12246         is_local = 1;
12247       else if (unformat (i, "remote"))
12248         is_local = 0;
12249       else
12250         {
12251           errmsg ("parse error '%U'", format_unformat_error, i);
12252           return -99;
12253         }
12254     }
12255
12256   if (!vec_len (name))
12257     {
12258       errmsg ("profile name must be specified");
12259       return -99;
12260     }
12261
12262   if (vec_len (name) > 64)
12263     {
12264       errmsg ("profile name too long");
12265       return -99;
12266     }
12267
12268   if (!vec_len (data))
12269     {
12270       errmsg ("id_data must be specified");
12271       return -99;
12272     }
12273
12274   if (!id_type)
12275     {
12276       errmsg ("id_type must be specified");
12277       return -99;
12278     }
12279
12280   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12281
12282   mp->is_local = is_local;
12283   mp->id_type = (u8) id_type;
12284   mp->data_len = vec_len (data);
12285   clib_memcpy (mp->name, name, vec_len (name));
12286   clib_memcpy (mp->data, data, vec_len (data));
12287   vec_free (name);
12288   vec_free (data);
12289
12290   S;
12291   W;
12292   /* NOTREACHED */
12293   return 0;
12294 }
12295
12296 static int
12297 api_ikev2_profile_set_ts (vat_main_t * vam)
12298 {
12299   unformat_input_t *i = vam->input;
12300   vl_api_ikev2_profile_set_ts_t *mp;
12301   f64 timeout;
12302   u8 *name = 0;
12303   u8 is_local = 0;
12304   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12305   ip4_address_t start_addr, end_addr;
12306
12307   const char *valid_chars = "a-zA-Z0-9_";
12308
12309   start_addr.as_u32 = 0;
12310   end_addr.as_u32 = (u32) ~ 0;
12311
12312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12313     {
12314       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12315         vec_add1 (name, 0);
12316       else if (unformat (i, "protocol %d", &proto))
12317         ;
12318       else if (unformat (i, "start_port %d", &start_port))
12319         ;
12320       else if (unformat (i, "end_port %d", &end_port))
12321         ;
12322       else
12323         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12324         ;
12325       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12326         ;
12327       else if (unformat (i, "local"))
12328         is_local = 1;
12329       else if (unformat (i, "remote"))
12330         is_local = 0;
12331       else
12332         {
12333           errmsg ("parse error '%U'", format_unformat_error, i);
12334           return -99;
12335         }
12336     }
12337
12338   if (!vec_len (name))
12339     {
12340       errmsg ("profile name must be specified");
12341       return -99;
12342     }
12343
12344   if (vec_len (name) > 64)
12345     {
12346       errmsg ("profile name too long");
12347       return -99;
12348     }
12349
12350   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12351
12352   mp->is_local = is_local;
12353   mp->proto = (u8) proto;
12354   mp->start_port = (u16) start_port;
12355   mp->end_port = (u16) end_port;
12356   mp->start_addr = start_addr.as_u32;
12357   mp->end_addr = end_addr.as_u32;
12358   clib_memcpy (mp->name, name, vec_len (name));
12359   vec_free (name);
12360
12361   S;
12362   W;
12363   /* NOTREACHED */
12364   return 0;
12365 }
12366
12367 static int
12368 api_ikev2_set_local_key (vat_main_t * vam)
12369 {
12370   unformat_input_t *i = vam->input;
12371   vl_api_ikev2_set_local_key_t *mp;
12372   f64 timeout;
12373   u8 *file = 0;
12374
12375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12376     {
12377       if (unformat (i, "file %v", &file))
12378         vec_add1 (file, 0);
12379       else
12380         {
12381           errmsg ("parse error '%U'", format_unformat_error, i);
12382           return -99;
12383         }
12384     }
12385
12386   if (!vec_len (file))
12387     {
12388       errmsg ("RSA key file must be specified");
12389       return -99;
12390     }
12391
12392   if (vec_len (file) > 256)
12393     {
12394       errmsg ("file name too long");
12395       return -99;
12396     }
12397
12398   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12399
12400   clib_memcpy (mp->key_file, file, vec_len (file));
12401   vec_free (file);
12402
12403   S;
12404   W;
12405   /* NOTREACHED */
12406   return 0;
12407 }
12408
12409 /*
12410  * MAP
12411  */
12412 static int
12413 api_map_add_domain (vat_main_t * vam)
12414 {
12415   unformat_input_t *i = vam->input;
12416   vl_api_map_add_domain_t *mp;
12417   f64 timeout;
12418
12419   ip4_address_t ip4_prefix;
12420   ip6_address_t ip6_prefix;
12421   ip6_address_t ip6_src;
12422   u32 num_m_args = 0;
12423   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12424     0, psid_length = 0;
12425   u8 is_translation = 0;
12426   u32 mtu = 0;
12427   u32 ip6_src_len = 128;
12428
12429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12432                     &ip4_prefix, &ip4_prefix_len))
12433         num_m_args++;
12434       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12435                          &ip6_prefix, &ip6_prefix_len))
12436         num_m_args++;
12437       else
12438         if (unformat
12439             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12440              &ip6_src_len))
12441         num_m_args++;
12442       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12443         num_m_args++;
12444       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12445         num_m_args++;
12446       else if (unformat (i, "psid-offset %d", &psid_offset))
12447         num_m_args++;
12448       else if (unformat (i, "psid-len %d", &psid_length))
12449         num_m_args++;
12450       else if (unformat (i, "mtu %d", &mtu))
12451         num_m_args++;
12452       else if (unformat (i, "map-t"))
12453         is_translation = 1;
12454       else
12455         {
12456           clib_warning ("parse error '%U'", format_unformat_error, i);
12457           return -99;
12458         }
12459     }
12460
12461   if (num_m_args < 3)
12462     {
12463       errmsg ("mandatory argument(s) missing");
12464       return -99;
12465     }
12466
12467   /* Construct the API message */
12468   M (MAP_ADD_DOMAIN, map_add_domain);
12469
12470   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12471   mp->ip4_prefix_len = ip4_prefix_len;
12472
12473   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12474   mp->ip6_prefix_len = ip6_prefix_len;
12475
12476   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12477   mp->ip6_src_prefix_len = ip6_src_len;
12478
12479   mp->ea_bits_len = ea_bits_len;
12480   mp->psid_offset = psid_offset;
12481   mp->psid_length = psid_length;
12482   mp->is_translation = is_translation;
12483   mp->mtu = htons (mtu);
12484
12485   /* send it... */
12486   S;
12487
12488   /* Wait for a reply, return good/bad news  */
12489   W;
12490 }
12491
12492 static int
12493 api_map_del_domain (vat_main_t * vam)
12494 {
12495   unformat_input_t *i = vam->input;
12496   vl_api_map_del_domain_t *mp;
12497   f64 timeout;
12498
12499   u32 num_m_args = 0;
12500   u32 index;
12501
12502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12503     {
12504       if (unformat (i, "index %d", &index))
12505         num_m_args++;
12506       else
12507         {
12508           clib_warning ("parse error '%U'", format_unformat_error, i);
12509           return -99;
12510         }
12511     }
12512
12513   if (num_m_args != 1)
12514     {
12515       errmsg ("mandatory argument(s) missing");
12516       return -99;
12517     }
12518
12519   /* Construct the API message */
12520   M (MAP_DEL_DOMAIN, map_del_domain);
12521
12522   mp->index = ntohl (index);
12523
12524   /* send it... */
12525   S;
12526
12527   /* Wait for a reply, return good/bad news  */
12528   W;
12529 }
12530
12531 static int
12532 api_map_add_del_rule (vat_main_t * vam)
12533 {
12534   unformat_input_t *i = vam->input;
12535   vl_api_map_add_del_rule_t *mp;
12536   f64 timeout;
12537   u8 is_add = 1;
12538   ip6_address_t ip6_dst;
12539   u32 num_m_args = 0, index, psid = 0;
12540
12541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12542     {
12543       if (unformat (i, "index %d", &index))
12544         num_m_args++;
12545       else if (unformat (i, "psid %d", &psid))
12546         num_m_args++;
12547       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12548         num_m_args++;
12549       else if (unformat (i, "del"))
12550         {
12551           is_add = 0;
12552         }
12553       else
12554         {
12555           clib_warning ("parse error '%U'", format_unformat_error, i);
12556           return -99;
12557         }
12558     }
12559
12560   /* Construct the API message */
12561   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12562
12563   mp->index = ntohl (index);
12564   mp->is_add = is_add;
12565   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12566   mp->psid = ntohs (psid);
12567
12568   /* send it... */
12569   S;
12570
12571   /* Wait for a reply, return good/bad news  */
12572   W;
12573 }
12574
12575 static int
12576 api_map_domain_dump (vat_main_t * vam)
12577 {
12578   vl_api_map_domain_dump_t *mp;
12579   f64 timeout;
12580
12581   /* Construct the API message */
12582   M (MAP_DOMAIN_DUMP, map_domain_dump);
12583
12584   /* send it... */
12585   S;
12586
12587   /* Use a control ping for synchronization */
12588   {
12589     vl_api_control_ping_t *mp;
12590     M (CONTROL_PING, control_ping);
12591     S;
12592   }
12593   W;
12594 }
12595
12596 static int
12597 api_map_rule_dump (vat_main_t * vam)
12598 {
12599   unformat_input_t *i = vam->input;
12600   vl_api_map_rule_dump_t *mp;
12601   f64 timeout;
12602   u32 domain_index = ~0;
12603
12604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12605     {
12606       if (unformat (i, "index %u", &domain_index))
12607         ;
12608       else
12609         break;
12610     }
12611
12612   if (domain_index == ~0)
12613     {
12614       clib_warning ("parse error: domain index expected");
12615       return -99;
12616     }
12617
12618   /* Construct the API message */
12619   M (MAP_RULE_DUMP, map_rule_dump);
12620
12621   mp->domain_index = htonl (domain_index);
12622
12623   /* send it... */
12624   S;
12625
12626   /* Use a control ping for synchronization */
12627   {
12628     vl_api_control_ping_t *mp;
12629     M (CONTROL_PING, control_ping);
12630     S;
12631   }
12632   W;
12633 }
12634
12635 static void vl_api_map_add_domain_reply_t_handler
12636   (vl_api_map_add_domain_reply_t * mp)
12637 {
12638   vat_main_t *vam = &vat_main;
12639   i32 retval = ntohl (mp->retval);
12640
12641   if (vam->async_mode)
12642     {
12643       vam->async_errors += (retval < 0);
12644     }
12645   else
12646     {
12647       vam->retval = retval;
12648       vam->result_ready = 1;
12649     }
12650 }
12651
12652 static void vl_api_map_add_domain_reply_t_handler_json
12653   (vl_api_map_add_domain_reply_t * mp)
12654 {
12655   vat_main_t *vam = &vat_main;
12656   vat_json_node_t node;
12657
12658   vat_json_init_object (&node);
12659   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12660   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12661
12662   vat_json_print (vam->ofp, &node);
12663   vat_json_free (&node);
12664
12665   vam->retval = ntohl (mp->retval);
12666   vam->result_ready = 1;
12667 }
12668
12669 static int
12670 api_get_first_msg_id (vat_main_t * vam)
12671 {
12672   vl_api_get_first_msg_id_t *mp;
12673   f64 timeout;
12674   unformat_input_t *i = vam->input;
12675   u8 *name;
12676   u8 name_set = 0;
12677
12678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12679     {
12680       if (unformat (i, "client %s", &name))
12681         name_set = 1;
12682       else
12683         break;
12684     }
12685
12686   if (name_set == 0)
12687     {
12688       errmsg ("missing client name");
12689       return -99;
12690     }
12691   vec_add1 (name, 0);
12692
12693   if (vec_len (name) > 63)
12694     {
12695       errmsg ("client name too long");
12696       return -99;
12697     }
12698
12699   M (GET_FIRST_MSG_ID, get_first_msg_id);
12700   clib_memcpy (mp->name, name, vec_len (name));
12701   S;
12702   W;
12703   /* NOTREACHED */
12704   return 0;
12705 }
12706
12707 static int
12708 api_cop_interface_enable_disable (vat_main_t * vam)
12709 {
12710   unformat_input_t *line_input = vam->input;
12711   vl_api_cop_interface_enable_disable_t *mp;
12712   f64 timeout;
12713   u32 sw_if_index = ~0;
12714   u8 enable_disable = 1;
12715
12716   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12717     {
12718       if (unformat (line_input, "disable"))
12719         enable_disable = 0;
12720       if (unformat (line_input, "enable"))
12721         enable_disable = 1;
12722       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12723                          vam, &sw_if_index))
12724         ;
12725       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12726         ;
12727       else
12728         break;
12729     }
12730
12731   if (sw_if_index == ~0)
12732     {
12733       errmsg ("missing interface name or sw_if_index");
12734       return -99;
12735     }
12736
12737   /* Construct the API message */
12738   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12739   mp->sw_if_index = ntohl (sw_if_index);
12740   mp->enable_disable = enable_disable;
12741
12742   /* send it... */
12743   S;
12744   /* Wait for the reply */
12745   W;
12746 }
12747
12748 static int
12749 api_cop_whitelist_enable_disable (vat_main_t * vam)
12750 {
12751   unformat_input_t *line_input = vam->input;
12752   vl_api_cop_whitelist_enable_disable_t *mp;
12753   f64 timeout;
12754   u32 sw_if_index = ~0;
12755   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12756   u32 fib_id = 0;
12757
12758   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12759     {
12760       if (unformat (line_input, "ip4"))
12761         ip4 = 1;
12762       else if (unformat (line_input, "ip6"))
12763         ip6 = 1;
12764       else if (unformat (line_input, "default"))
12765         default_cop = 1;
12766       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12767                          vam, &sw_if_index))
12768         ;
12769       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12770         ;
12771       else if (unformat (line_input, "fib-id %d", &fib_id))
12772         ;
12773       else
12774         break;
12775     }
12776
12777   if (sw_if_index == ~0)
12778     {
12779       errmsg ("missing interface name or sw_if_index");
12780       return -99;
12781     }
12782
12783   /* Construct the API message */
12784   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12785   mp->sw_if_index = ntohl (sw_if_index);
12786   mp->fib_id = ntohl (fib_id);
12787   mp->ip4 = ip4;
12788   mp->ip6 = ip6;
12789   mp->default_cop = default_cop;
12790
12791   /* send it... */
12792   S;
12793   /* Wait for the reply */
12794   W;
12795 }
12796
12797 static int
12798 api_get_node_graph (vat_main_t * vam)
12799 {
12800   vl_api_get_node_graph_t *mp;
12801   f64 timeout;
12802
12803   M (GET_NODE_GRAPH, get_node_graph);
12804
12805   /* send it... */
12806   S;
12807   /* Wait for the reply */
12808   W;
12809 }
12810
12811 /* *INDENT-OFF* */
12812 /** Used for parsing LISP eids */
12813 typedef CLIB_PACKED(struct{
12814   u8 addr[16];   /**< eid address */
12815   u32 len;       /**< prefix length if IP */
12816   u8 type;      /**< type of eid */
12817 }) lisp_eid_vat_t;
12818 /* *INDENT-ON* */
12819
12820 static uword
12821 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12822 {
12823   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12824
12825   memset (a, 0, sizeof (a[0]));
12826
12827   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12828     {
12829       a->type = 0;              /* ipv4 type */
12830     }
12831   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12832     {
12833       a->type = 1;              /* ipv6 type */
12834     }
12835   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12836     {
12837       a->type = 2;              /* mac type */
12838     }
12839   else
12840     {
12841       return 0;
12842     }
12843
12844   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12845     {
12846       return 0;
12847     }
12848
12849   return 1;
12850 }
12851
12852 static int
12853 lisp_eid_size_vat (u8 type)
12854 {
12855   switch (type)
12856     {
12857     case 0:
12858       return 4;
12859     case 1:
12860       return 16;
12861     case 2:
12862       return 6;
12863     }
12864   return 0;
12865 }
12866
12867 static void
12868 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12869 {
12870   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12871 }
12872
12873 /* *INDENT-OFF* */
12874 /** Used for transferring locators via VPP API */
12875 typedef CLIB_PACKED(struct
12876 {
12877   u32 sw_if_index; /**< locator sw_if_index */
12878   u8 priority; /**< locator priority */
12879   u8 weight;   /**< locator weight */
12880 }) ls_locator_t;
12881 /* *INDENT-ON* */
12882
12883 static int
12884 api_lisp_add_del_locator_set (vat_main_t * vam)
12885 {
12886   unformat_input_t *input = vam->input;
12887   vl_api_lisp_add_del_locator_set_t *mp;
12888   f64 timeout = ~0;
12889   u8 is_add = 1;
12890   u8 *locator_set_name = NULL;
12891   u8 locator_set_name_set = 0;
12892   ls_locator_t locator, *locators = 0;
12893   u32 sw_if_index, priority, weight;
12894   u32 data_len = 0;
12895
12896   /* Parse args required to build the message */
12897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12898     {
12899       if (unformat (input, "del"))
12900         {
12901           is_add = 0;
12902         }
12903       else if (unformat (input, "locator-set %s", &locator_set_name))
12904         {
12905           locator_set_name_set = 1;
12906         }
12907       else if (unformat (input, "sw_if_index %u p %u w %u",
12908                          &sw_if_index, &priority, &weight))
12909         {
12910           locator.sw_if_index = htonl (sw_if_index);
12911           locator.priority = priority;
12912           locator.weight = weight;
12913           vec_add1 (locators, locator);
12914         }
12915       else
12916         if (unformat
12917             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12918              &sw_if_index, &priority, &weight))
12919         {
12920           locator.sw_if_index = htonl (sw_if_index);
12921           locator.priority = priority;
12922           locator.weight = weight;
12923           vec_add1 (locators, locator);
12924         }
12925       else
12926         break;
12927     }
12928
12929   if (locator_set_name_set == 0)
12930     {
12931       errmsg ("missing locator-set name");
12932       vec_free (locators);
12933       return -99;
12934     }
12935
12936   if (vec_len (locator_set_name) > 64)
12937     {
12938       errmsg ("locator-set name too long");
12939       vec_free (locator_set_name);
12940       vec_free (locators);
12941       return -99;
12942     }
12943   vec_add1 (locator_set_name, 0);
12944
12945   data_len = sizeof (ls_locator_t) * vec_len (locators);
12946
12947   /* Construct the API message */
12948   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12949
12950   mp->is_add = is_add;
12951   clib_memcpy (mp->locator_set_name, locator_set_name,
12952                vec_len (locator_set_name));
12953   vec_free (locator_set_name);
12954
12955   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12956   if (locators)
12957     clib_memcpy (mp->locators, locators, data_len);
12958   vec_free (locators);
12959
12960   /* send it... */
12961   S;
12962
12963   /* Wait for a reply... */
12964   W;
12965
12966   /* NOTREACHED */
12967   return 0;
12968 }
12969
12970 static int
12971 api_lisp_add_del_locator (vat_main_t * vam)
12972 {
12973   unformat_input_t *input = vam->input;
12974   vl_api_lisp_add_del_locator_t *mp;
12975   f64 timeout = ~0;
12976   u32 tmp_if_index = ~0;
12977   u32 sw_if_index = ~0;
12978   u8 sw_if_index_set = 0;
12979   u8 sw_if_index_if_name_set = 0;
12980   u32 priority = ~0;
12981   u8 priority_set = 0;
12982   u32 weight = ~0;
12983   u8 weight_set = 0;
12984   u8 is_add = 1;
12985   u8 *locator_set_name = NULL;
12986   u8 locator_set_name_set = 0;
12987
12988   /* Parse args required to build the message */
12989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat (input, "del"))
12992         {
12993           is_add = 0;
12994         }
12995       else if (unformat (input, "locator-set %s", &locator_set_name))
12996         {
12997           locator_set_name_set = 1;
12998         }
12999       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13000                          &tmp_if_index))
13001         {
13002           sw_if_index_if_name_set = 1;
13003           sw_if_index = tmp_if_index;
13004         }
13005       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13006         {
13007           sw_if_index_set = 1;
13008           sw_if_index = tmp_if_index;
13009         }
13010       else if (unformat (input, "p %d", &priority))
13011         {
13012           priority_set = 1;
13013         }
13014       else if (unformat (input, "w %d", &weight))
13015         {
13016           weight_set = 1;
13017         }
13018       else
13019         break;
13020     }
13021
13022   if (locator_set_name_set == 0)
13023     {
13024       errmsg ("missing locator-set name");
13025       return -99;
13026     }
13027
13028   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13029     {
13030       errmsg ("missing sw_if_index");
13031       vec_free (locator_set_name);
13032       return -99;
13033     }
13034
13035   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13036     {
13037       errmsg ("cannot use both params interface name and sw_if_index");
13038       vec_free (locator_set_name);
13039       return -99;
13040     }
13041
13042   if (priority_set == 0)
13043     {
13044       errmsg ("missing locator-set priority");
13045       vec_free (locator_set_name);
13046       return -99;
13047     }
13048
13049   if (weight_set == 0)
13050     {
13051       errmsg ("missing locator-set weight");
13052       vec_free (locator_set_name);
13053       return -99;
13054     }
13055
13056   if (vec_len (locator_set_name) > 64)
13057     {
13058       errmsg ("locator-set name too long");
13059       vec_free (locator_set_name);
13060       return -99;
13061     }
13062   vec_add1 (locator_set_name, 0);
13063
13064   /* Construct the API message */
13065   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13066
13067   mp->is_add = is_add;
13068   mp->sw_if_index = ntohl (sw_if_index);
13069   mp->priority = priority;
13070   mp->weight = weight;
13071   clib_memcpy (mp->locator_set_name, locator_set_name,
13072                vec_len (locator_set_name));
13073   vec_free (locator_set_name);
13074
13075   /* send it... */
13076   S;
13077
13078   /* Wait for a reply... */
13079   W;
13080
13081   /* NOTREACHED */
13082   return 0;
13083 }
13084
13085 uword
13086 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13087 {
13088   u32 *key_id = va_arg (*args, u32 *);
13089   u8 *s = 0;
13090
13091   if (unformat (input, "%s", &s))
13092     {
13093       if (!strcmp ((char *) s, "sha1"))
13094         key_id[0] = HMAC_SHA_1_96;
13095       else if (!strcmp ((char *) s, "sha256"))
13096         key_id[0] = HMAC_SHA_256_128;
13097       else
13098         {
13099           clib_warning ("invalid key_id: '%s'", s);
13100           key_id[0] = HMAC_NO_KEY;
13101         }
13102     }
13103   else
13104     return 0;
13105
13106   vec_free (s);
13107   return 1;
13108 }
13109
13110 static int
13111 api_lisp_add_del_local_eid (vat_main_t * vam)
13112 {
13113   unformat_input_t *input = vam->input;
13114   vl_api_lisp_add_del_local_eid_t *mp;
13115   f64 timeout = ~0;
13116   u8 is_add = 1;
13117   u8 eid_set = 0;
13118   lisp_eid_vat_t _eid, *eid = &_eid;
13119   u8 *locator_set_name = 0;
13120   u8 locator_set_name_set = 0;
13121   u32 vni = 0;
13122   u16 key_id = 0;
13123   u8 *key = 0;
13124
13125   /* Parse args required to build the message */
13126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13127     {
13128       if (unformat (input, "del"))
13129         {
13130           is_add = 0;
13131         }
13132       else if (unformat (input, "vni %d", &vni))
13133         {
13134           ;
13135         }
13136       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13137         {
13138           eid_set = 1;
13139         }
13140       else if (unformat (input, "locator-set %s", &locator_set_name))
13141         {
13142           locator_set_name_set = 1;
13143         }
13144       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13145         ;
13146       else if (unformat (input, "secret-key %_%v%_", &key))
13147         ;
13148       else
13149         break;
13150     }
13151
13152   if (locator_set_name_set == 0)
13153     {
13154       errmsg ("missing locator-set name");
13155       return -99;
13156     }
13157
13158   if (0 == eid_set)
13159     {
13160       errmsg ("EID address not set!");
13161       vec_free (locator_set_name);
13162       return -99;
13163     }
13164
13165   if (key && (0 == key_id))
13166     {
13167       errmsg ("invalid key_id!");
13168       return -99;
13169     }
13170
13171   if (vec_len (key) > 64)
13172     {
13173       errmsg ("key too long");
13174       vec_free (key);
13175       return -99;
13176     }
13177
13178   if (vec_len (locator_set_name) > 64)
13179     {
13180       errmsg ("locator-set name too long");
13181       vec_free (locator_set_name);
13182       return -99;
13183     }
13184   vec_add1 (locator_set_name, 0);
13185
13186   /* Construct the API message */
13187   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13188
13189   mp->is_add = is_add;
13190   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13191   mp->eid_type = eid->type;
13192   mp->prefix_len = eid->len;
13193   mp->vni = clib_host_to_net_u32 (vni);
13194   mp->key_id = clib_host_to_net_u16 (key_id);
13195   clib_memcpy (mp->locator_set_name, locator_set_name,
13196                vec_len (locator_set_name));
13197   clib_memcpy (mp->key, key, vec_len (key));
13198
13199   vec_free (locator_set_name);
13200   vec_free (key);
13201
13202   /* send it... */
13203   S;
13204
13205   /* Wait for a reply... */
13206   W;
13207
13208   /* NOTREACHED */
13209   return 0;
13210 }
13211
13212 /* *INDENT-OFF* */
13213 /** Used for transferring locators via VPP API */
13214 typedef CLIB_PACKED(struct
13215 {
13216   u8 is_ip4; /**< is locator an IPv4 address? */
13217   u8 priority; /**< locator priority */
13218   u8 weight;   /**< locator weight */
13219   u8 addr[16]; /**< IPv4/IPv6 address */
13220 }) rloc_t;
13221 /* *INDENT-ON* */
13222
13223 static int
13224 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13225 {
13226   unformat_input_t *input = vam->input;
13227   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13228   f64 timeout = ~0;
13229   u8 is_add = 1;
13230   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13231   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13232   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13233   u32 action = ~0, p, w;
13234   ip4_address_t rmt_rloc4, lcl_rloc4;
13235   ip6_address_t rmt_rloc6, lcl_rloc6;
13236   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13237
13238   memset (&rloc, 0, sizeof (rloc));
13239
13240   /* Parse args required to build the message */
13241   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13242     {
13243       if (unformat (input, "del"))
13244         {
13245           is_add = 0;
13246         }
13247       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13248         {
13249           rmt_eid_set = 1;
13250         }
13251       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13252         {
13253           lcl_eid_set = 1;
13254         }
13255       else if (unformat (input, "p %d w %d", &p, &w))
13256         {
13257           if (!curr_rloc)
13258             {
13259               errmsg ("No RLOC configured for setting priority/weight!");
13260               return -99;
13261             }
13262           curr_rloc->priority = p;
13263           curr_rloc->weight = w;
13264         }
13265       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13266                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13267         {
13268           rloc.is_ip4 = 1;
13269
13270           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13271           rloc.priority = rloc.weight = 0;
13272           vec_add1 (lcl_locs, rloc);
13273
13274           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13275           vec_add1 (rmt_locs, rloc);
13276           /* priority and weight saved in rmt loc */
13277           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13278         }
13279       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13280                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13281         {
13282           rloc.is_ip4 = 0;
13283           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13284           rloc.priority = rloc.weight = 0;
13285           vec_add1 (lcl_locs, rloc);
13286
13287           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13288           vec_add1 (rmt_locs, rloc);
13289           /* priority and weight saved in rmt loc */
13290           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13291         }
13292       else if (unformat (input, "action %d", &action))
13293         {
13294           ;
13295         }
13296       else
13297         {
13298           clib_warning ("parse error '%U'", format_unformat_error, input);
13299           return -99;
13300         }
13301     }
13302
13303   if (!rmt_eid_set)
13304     {
13305       errmsg ("remote eid addresses not set");
13306       return -99;
13307     }
13308
13309   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13310     {
13311       errmsg ("eid types don't match");
13312       return -99;
13313     }
13314
13315   if (0 == rmt_locs && (u32) ~ 0 == action)
13316     {
13317       errmsg ("action not set for negative mapping");
13318       return -99;
13319     }
13320
13321   /* Construct the API message */
13322   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13323
13324   mp->is_add = is_add;
13325   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13326   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13327   mp->eid_type = rmt_eid->type;
13328   mp->rmt_len = rmt_eid->len;
13329   mp->lcl_len = lcl_eid->len;
13330   mp->action = action;
13331
13332   if (0 != rmt_locs && 0 != lcl_locs)
13333     {
13334       mp->loc_num = vec_len (rmt_locs);
13335       clib_memcpy (mp->lcl_locs, lcl_locs,
13336                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13337       clib_memcpy (mp->rmt_locs, rmt_locs,
13338                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13339     }
13340   vec_free (lcl_locs);
13341   vec_free (rmt_locs);
13342
13343   /* send it... */
13344   S;
13345
13346   /* Wait for a reply... */
13347   W;
13348
13349   /* NOTREACHED */
13350   return 0;
13351 }
13352
13353 static int
13354 api_lisp_add_del_map_server (vat_main_t * vam)
13355 {
13356   unformat_input_t *input = vam->input;
13357   vl_api_lisp_add_del_map_server_t *mp;
13358   f64 timeout = ~0;
13359   u8 is_add = 1;
13360   u8 ipv4_set = 0;
13361   u8 ipv6_set = 0;
13362   ip4_address_t ipv4;
13363   ip6_address_t ipv6;
13364
13365   /* Parse args required to build the message */
13366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13367     {
13368       if (unformat (input, "del"))
13369         {
13370           is_add = 0;
13371         }
13372       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13373         {
13374           ipv4_set = 1;
13375         }
13376       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13377         {
13378           ipv6_set = 1;
13379         }
13380       else
13381         break;
13382     }
13383
13384   if (ipv4_set && ipv6_set)
13385     {
13386       errmsg ("both eid v4 and v6 addresses set");
13387       return -99;
13388     }
13389
13390   if (!ipv4_set && !ipv6_set)
13391     {
13392       errmsg ("eid addresses not set");
13393       return -99;
13394     }
13395
13396   /* Construct the API message */
13397   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13398
13399   mp->is_add = is_add;
13400   if (ipv6_set)
13401     {
13402       mp->is_ipv6 = 1;
13403       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13404     }
13405   else
13406     {
13407       mp->is_ipv6 = 0;
13408       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13409     }
13410
13411   /* send it... */
13412   S;
13413
13414   /* Wait for a reply... */
13415   W;
13416
13417   /* NOTREACHED */
13418   return 0;
13419 }
13420
13421 static int
13422 api_lisp_add_del_map_resolver (vat_main_t * vam)
13423 {
13424   unformat_input_t *input = vam->input;
13425   vl_api_lisp_add_del_map_resolver_t *mp;
13426   f64 timeout = ~0;
13427   u8 is_add = 1;
13428   u8 ipv4_set = 0;
13429   u8 ipv6_set = 0;
13430   ip4_address_t ipv4;
13431   ip6_address_t ipv6;
13432
13433   /* Parse args required to build the message */
13434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13435     {
13436       if (unformat (input, "del"))
13437         {
13438           is_add = 0;
13439         }
13440       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13441         {
13442           ipv4_set = 1;
13443         }
13444       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13445         {
13446           ipv6_set = 1;
13447         }
13448       else
13449         break;
13450     }
13451
13452   if (ipv4_set && ipv6_set)
13453     {
13454       errmsg ("both eid v4 and v6 addresses set");
13455       return -99;
13456     }
13457
13458   if (!ipv4_set && !ipv6_set)
13459     {
13460       errmsg ("eid addresses not set");
13461       return -99;
13462     }
13463
13464   /* Construct the API message */
13465   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13466
13467   mp->is_add = is_add;
13468   if (ipv6_set)
13469     {
13470       mp->is_ipv6 = 1;
13471       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13472     }
13473   else
13474     {
13475       mp->is_ipv6 = 0;
13476       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13477     }
13478
13479   /* send it... */
13480   S;
13481
13482   /* Wait for a reply... */
13483   W;
13484
13485   /* NOTREACHED */
13486   return 0;
13487 }
13488
13489 static int
13490 api_lisp_gpe_enable_disable (vat_main_t * vam)
13491 {
13492   unformat_input_t *input = vam->input;
13493   vl_api_lisp_gpe_enable_disable_t *mp;
13494   f64 timeout = ~0;
13495   u8 is_set = 0;
13496   u8 is_en = 1;
13497
13498   /* Parse args required to build the message */
13499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13500     {
13501       if (unformat (input, "enable"))
13502         {
13503           is_set = 1;
13504           is_en = 1;
13505         }
13506       else if (unformat (input, "disable"))
13507         {
13508           is_set = 1;
13509           is_en = 0;
13510         }
13511       else
13512         break;
13513     }
13514
13515   if (is_set == 0)
13516     {
13517       errmsg ("Value not set");
13518       return -99;
13519     }
13520
13521   /* Construct the API message */
13522   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13523
13524   mp->is_en = is_en;
13525
13526   /* send it... */
13527   S;
13528
13529   /* Wait for a reply... */
13530   W;
13531
13532   /* NOTREACHED */
13533   return 0;
13534 }
13535
13536 static int
13537 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13538 {
13539   unformat_input_t *input = vam->input;
13540   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13541   f64 timeout = ~0;
13542   u8 is_set = 0;
13543   u8 is_en = 0;
13544
13545   /* Parse args required to build the message */
13546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13547     {
13548       if (unformat (input, "enable"))
13549         {
13550           is_set = 1;
13551           is_en = 1;
13552         }
13553       else if (unformat (input, "disable"))
13554         is_set = 1;
13555       else
13556         break;
13557     }
13558
13559   if (!is_set)
13560     {
13561       errmsg ("Value not set");
13562       return -99;
13563     }
13564
13565   /* Construct the API message */
13566   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13567
13568   mp->is_enabled = is_en;
13569
13570   /* send it... */
13571   S;
13572
13573   /* Wait for a reply... */
13574   W;
13575
13576   /* NOTREACHED */
13577   return 0;
13578 }
13579
13580 static int
13581 api_lisp_map_register_enable_disable (vat_main_t * vam)
13582 {
13583   unformat_input_t *input = vam->input;
13584   vl_api_lisp_map_register_enable_disable_t *mp;
13585   f64 timeout = ~0;
13586   u8 is_set = 0;
13587   u8 is_en = 0;
13588
13589   /* Parse args required to build the message */
13590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13591     {
13592       if (unformat (input, "enable"))
13593         {
13594           is_set = 1;
13595           is_en = 1;
13596         }
13597       else if (unformat (input, "disable"))
13598         is_set = 1;
13599       else
13600         break;
13601     }
13602
13603   if (!is_set)
13604     {
13605       errmsg ("Value not set");
13606       return -99;
13607     }
13608
13609   /* Construct the API message */
13610   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13611
13612   mp->is_enabled = is_en;
13613
13614   /* send it... */
13615   S;
13616
13617   /* Wait for a reply... */
13618   W;
13619
13620   /* NOTREACHED */
13621   return 0;
13622 }
13623
13624 static int
13625 api_lisp_enable_disable (vat_main_t * vam)
13626 {
13627   unformat_input_t *input = vam->input;
13628   vl_api_lisp_enable_disable_t *mp;
13629   f64 timeout = ~0;
13630   u8 is_set = 0;
13631   u8 is_en = 0;
13632
13633   /* Parse args required to build the message */
13634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13635     {
13636       if (unformat (input, "enable"))
13637         {
13638           is_set = 1;
13639           is_en = 1;
13640         }
13641       else if (unformat (input, "disable"))
13642         {
13643           is_set = 1;
13644         }
13645       else
13646         break;
13647     }
13648
13649   if (!is_set)
13650     {
13651       errmsg ("Value not set");
13652       return -99;
13653     }
13654
13655   /* Construct the API message */
13656   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13657
13658   mp->is_en = is_en;
13659
13660   /* send it... */
13661   S;
13662
13663   /* Wait for a reply... */
13664   W;
13665
13666   /* NOTREACHED */
13667   return 0;
13668 }
13669
13670 static int
13671 api_show_lisp_map_register_state (vat_main_t * vam)
13672 {
13673   f64 timeout = ~0;
13674   vl_api_show_lisp_map_register_state_t *mp;
13675
13676   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13677
13678   /* send */
13679   S;
13680
13681   /* wait for reply */
13682   W;
13683
13684   return 0;
13685 }
13686
13687 static int
13688 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13689 {
13690   f64 timeout = ~0;
13691   vl_api_show_lisp_rloc_probe_state_t *mp;
13692
13693   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13694
13695   /* send */
13696   S;
13697
13698   /* wait for reply */
13699   W;
13700
13701   return 0;
13702 }
13703
13704 static int
13705 api_show_lisp_map_request_mode (vat_main_t * vam)
13706 {
13707   f64 timeout = ~0;
13708   vl_api_show_lisp_map_request_mode_t *mp;
13709
13710   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13711
13712   /* send */
13713   S;
13714
13715   /* wait for reply */
13716   W;
13717
13718   return 0;
13719 }
13720
13721 static int
13722 api_lisp_map_request_mode (vat_main_t * vam)
13723 {
13724   f64 timeout = ~0;
13725   unformat_input_t *input = vam->input;
13726   vl_api_lisp_map_request_mode_t *mp;
13727   u8 mode = 0;
13728
13729   /* Parse args required to build the message */
13730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13731     {
13732       if (unformat (input, "dst-only"))
13733         mode = 0;
13734       else if (unformat (input, "src-dst"))
13735         mode = 1;
13736       else
13737         {
13738           errmsg ("parse error '%U'", format_unformat_error, input);
13739           return -99;
13740         }
13741     }
13742
13743   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13744
13745   mp->mode = mode;
13746
13747   /* send */
13748   S;
13749
13750   /* wait for reply */
13751   W;
13752
13753   /* notreached */
13754   return 0;
13755 }
13756
13757 /**
13758  * Enable/disable LISP proxy ITR.
13759  *
13760  * @param vam vpp API test context
13761  * @return return code
13762  */
13763 static int
13764 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13765 {
13766   f64 timeout = ~0;
13767   u8 ls_name_set = 0;
13768   unformat_input_t *input = vam->input;
13769   vl_api_lisp_pitr_set_locator_set_t *mp;
13770   u8 is_add = 1;
13771   u8 *ls_name = 0;
13772
13773   /* Parse args required to build the message */
13774   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13775     {
13776       if (unformat (input, "del"))
13777         is_add = 0;
13778       else if (unformat (input, "locator-set %s", &ls_name))
13779         ls_name_set = 1;
13780       else
13781         {
13782           errmsg ("parse error '%U'", format_unformat_error, input);
13783           return -99;
13784         }
13785     }
13786
13787   if (!ls_name_set)
13788     {
13789       errmsg ("locator-set name not set!");
13790       return -99;
13791     }
13792
13793   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13794
13795   mp->is_add = is_add;
13796   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13797   vec_free (ls_name);
13798
13799   /* send */
13800   S;
13801
13802   /* wait for reply */
13803   W;
13804
13805   /* notreached */
13806   return 0;
13807 }
13808
13809 static int
13810 api_show_lisp_pitr (vat_main_t * vam)
13811 {
13812   vl_api_show_lisp_pitr_t *mp;
13813   f64 timeout = ~0;
13814
13815   if (!vam->json_output)
13816     {
13817       print (vam->ofp, "%=20s", "lisp status:");
13818     }
13819
13820   M (SHOW_LISP_PITR, show_lisp_pitr);
13821   /* send it... */
13822   S;
13823
13824   /* Wait for a reply... */
13825   W;
13826
13827   /* NOTREACHED */
13828   return 0;
13829 }
13830
13831 /**
13832  * Add/delete mapping between vni and vrf
13833  */
13834 static int
13835 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13836 {
13837   f64 timeout = ~0;
13838   unformat_input_t *input = vam->input;
13839   vl_api_lisp_eid_table_add_del_map_t *mp;
13840   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13841   u32 vni, vrf, bd_index;
13842
13843   /* Parse args required to build the message */
13844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (input, "del"))
13847         is_add = 0;
13848       else if (unformat (input, "vrf %d", &vrf))
13849         vrf_set = 1;
13850       else if (unformat (input, "bd_index %d", &bd_index))
13851         bd_index_set = 1;
13852       else if (unformat (input, "vni %d", &vni))
13853         vni_set = 1;
13854       else
13855         break;
13856     }
13857
13858   if (!vni_set || (!vrf_set && !bd_index_set))
13859     {
13860       errmsg ("missing arguments!");
13861       return -99;
13862     }
13863
13864   if (vrf_set && bd_index_set)
13865     {
13866       errmsg ("error: both vrf and bd entered!");
13867       return -99;
13868     }
13869
13870   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13871
13872   mp->is_add = is_add;
13873   mp->vni = htonl (vni);
13874   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13875   mp->is_l2 = bd_index_set;
13876
13877   /* send */
13878   S;
13879
13880   /* wait for reply */
13881   W;
13882
13883   /* notreached */
13884   return 0;
13885 }
13886
13887 uword
13888 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13889 {
13890   u32 *action = va_arg (*args, u32 *);
13891   u8 *s = 0;
13892
13893   if (unformat (input, "%s", &s))
13894     {
13895       if (!strcmp ((char *) s, "no-action"))
13896         action[0] = 0;
13897       else if (!strcmp ((char *) s, "natively-forward"))
13898         action[0] = 1;
13899       else if (!strcmp ((char *) s, "send-map-request"))
13900         action[0] = 2;
13901       else if (!strcmp ((char *) s, "drop"))
13902         action[0] = 3;
13903       else
13904         {
13905           clib_warning ("invalid action: '%s'", s);
13906           action[0] = 3;
13907         }
13908     }
13909   else
13910     return 0;
13911
13912   vec_free (s);
13913   return 1;
13914 }
13915
13916 /**
13917  * Add/del remote mapping to/from LISP control plane
13918  *
13919  * @param vam vpp API test context
13920  * @return return code
13921  */
13922 static int
13923 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13924 {
13925   unformat_input_t *input = vam->input;
13926   vl_api_lisp_add_del_remote_mapping_t *mp;
13927   f64 timeout = ~0;
13928   u32 vni = 0;
13929   lisp_eid_vat_t _eid, *eid = &_eid;
13930   lisp_eid_vat_t _seid, *seid = &_seid;
13931   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13932   u32 action = ~0, p, w, data_len;
13933   ip4_address_t rloc4;
13934   ip6_address_t rloc6;
13935   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13936
13937   memset (&rloc, 0, sizeof (rloc));
13938
13939   /* Parse args required to build the message */
13940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13941     {
13942       if (unformat (input, "del-all"))
13943         {
13944           del_all = 1;
13945         }
13946       else if (unformat (input, "del"))
13947         {
13948           is_add = 0;
13949         }
13950       else if (unformat (input, "add"))
13951         {
13952           is_add = 1;
13953         }
13954       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13955         {
13956           eid_set = 1;
13957         }
13958       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13959         {
13960           seid_set = 1;
13961         }
13962       else if (unformat (input, "vni %d", &vni))
13963         {
13964           ;
13965         }
13966       else if (unformat (input, "p %d w %d", &p, &w))
13967         {
13968           if (!curr_rloc)
13969             {
13970               errmsg ("No RLOC configured for setting priority/weight!");
13971               return -99;
13972             }
13973           curr_rloc->priority = p;
13974           curr_rloc->weight = w;
13975         }
13976       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13977         {
13978           rloc.is_ip4 = 1;
13979           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13980           vec_add1 (rlocs, rloc);
13981           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13982         }
13983       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13984         {
13985           rloc.is_ip4 = 0;
13986           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13987           vec_add1 (rlocs, rloc);
13988           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13989         }
13990       else if (unformat (input, "action %U",
13991                          unformat_negative_mapping_action, &action))
13992         {
13993           ;
13994         }
13995       else
13996         {
13997           clib_warning ("parse error '%U'", format_unformat_error, input);
13998           return -99;
13999         }
14000     }
14001
14002   if (0 == eid_set)
14003     {
14004       errmsg ("missing params!");
14005       return -99;
14006     }
14007
14008   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14009     {
14010       errmsg ("no action set for negative map-reply!");
14011       return -99;
14012     }
14013
14014   data_len = vec_len (rlocs) * sizeof (rloc_t);
14015
14016   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14017   mp->is_add = is_add;
14018   mp->vni = htonl (vni);
14019   mp->action = (u8) action;
14020   mp->is_src_dst = seid_set;
14021   mp->eid_len = eid->len;
14022   mp->seid_len = seid->len;
14023   mp->del_all = del_all;
14024   mp->eid_type = eid->type;
14025   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14026   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14027
14028   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14029   clib_memcpy (mp->rlocs, rlocs, data_len);
14030   vec_free (rlocs);
14031
14032   /* send it... */
14033   S;
14034
14035   /* Wait for a reply... */
14036   W;
14037
14038   /* NOTREACHED */
14039   return 0;
14040 }
14041
14042 /**
14043  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14044  * forwarding entries in data-plane accordingly.
14045  *
14046  * @param vam vpp API test context
14047  * @return return code
14048  */
14049 static int
14050 api_lisp_add_del_adjacency (vat_main_t * vam)
14051 {
14052   unformat_input_t *input = vam->input;
14053   vl_api_lisp_add_del_adjacency_t *mp;
14054   f64 timeout = ~0;
14055   u32 vni = 0;
14056   ip4_address_t leid4, reid4;
14057   ip6_address_t leid6, reid6;
14058   u8 reid_mac[6] = { 0 };
14059   u8 leid_mac[6] = { 0 };
14060   u8 reid_type, leid_type;
14061   u32 leid_len = 0, reid_len = 0, len;
14062   u8 is_add = 1;
14063
14064   leid_type = reid_type = (u8) ~ 0;
14065
14066   /* Parse args required to build the message */
14067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (input, "del"))
14070         {
14071           is_add = 0;
14072         }
14073       else if (unformat (input, "add"))
14074         {
14075           is_add = 1;
14076         }
14077       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14078                          &reid4, &len))
14079         {
14080           reid_type = 0;        /* ipv4 */
14081           reid_len = len;
14082         }
14083       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14084                          &reid6, &len))
14085         {
14086           reid_type = 1;        /* ipv6 */
14087           reid_len = len;
14088         }
14089       else if (unformat (input, "reid %U", unformat_ethernet_address,
14090                          reid_mac))
14091         {
14092           reid_type = 2;        /* mac */
14093         }
14094       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14095                          &leid4, &len))
14096         {
14097           leid_type = 0;        /* ipv4 */
14098           leid_len = len;
14099         }
14100       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14101                          &leid6, &len))
14102         {
14103           leid_type = 1;        /* ipv6 */
14104           leid_len = len;
14105         }
14106       else if (unformat (input, "leid %U", unformat_ethernet_address,
14107                          leid_mac))
14108         {
14109           leid_type = 2;        /* mac */
14110         }
14111       else if (unformat (input, "vni %d", &vni))
14112         {
14113           ;
14114         }
14115       else
14116         {
14117           errmsg ("parse error '%U'", format_unformat_error, input);
14118           return -99;
14119         }
14120     }
14121
14122   if ((u8) ~ 0 == reid_type)
14123     {
14124       errmsg ("missing params!");
14125       return -99;
14126     }
14127
14128   if (leid_type != reid_type)
14129     {
14130       errmsg ("remote and local EIDs are of different types!");
14131       return -99;
14132     }
14133
14134   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14135   mp->is_add = is_add;
14136   mp->vni = htonl (vni);
14137   mp->leid_len = leid_len;
14138   mp->reid_len = reid_len;
14139   mp->eid_type = reid_type;
14140
14141   switch (mp->eid_type)
14142     {
14143     case 0:
14144       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14145       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14146       break;
14147     case 1:
14148       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14149       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14150       break;
14151     case 2:
14152       clib_memcpy (mp->leid, leid_mac, 6);
14153       clib_memcpy (mp->reid, reid_mac, 6);
14154       break;
14155     default:
14156       errmsg ("unknown EID type %d!", mp->eid_type);
14157       return 0;
14158     }
14159
14160   /* send it... */
14161   S;
14162
14163   /* Wait for a reply... */
14164   W;
14165
14166   /* NOTREACHED */
14167   return 0;
14168 }
14169
14170 static int
14171 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14172 {
14173   unformat_input_t *input = vam->input;
14174   vl_api_lisp_gpe_add_del_iface_t *mp;
14175   f64 timeout = ~0;
14176   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14177   u32 dp_table = 0, vni = 0;
14178
14179   /* Parse args required to build the message */
14180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14181     {
14182       if (unformat (input, "up"))
14183         {
14184           action_set = 1;
14185           is_add = 1;
14186         }
14187       else if (unformat (input, "down"))
14188         {
14189           action_set = 1;
14190           is_add = 0;
14191         }
14192       else if (unformat (input, "table_id %d", &dp_table))
14193         {
14194           dp_table_set = 1;
14195         }
14196       else if (unformat (input, "bd_id %d", &dp_table))
14197         {
14198           dp_table_set = 1;
14199           is_l2 = 1;
14200         }
14201       else if (unformat (input, "vni %d", &vni))
14202         {
14203           vni_set = 1;
14204         }
14205       else
14206         break;
14207     }
14208
14209   if (action_set == 0)
14210     {
14211       errmsg ("Action not set");
14212       return -99;
14213     }
14214   if (dp_table_set == 0 || vni_set == 0)
14215     {
14216       errmsg ("vni and dp_table must be set");
14217       return -99;
14218     }
14219
14220   /* Construct the API message */
14221   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14222
14223   mp->is_add = is_add;
14224   mp->dp_table = dp_table;
14225   mp->is_l2 = is_l2;
14226   mp->vni = vni;
14227
14228   /* send it... */
14229   S;
14230
14231   /* Wait for a reply... */
14232   W;
14233
14234   /* NOTREACHED */
14235   return 0;
14236 }
14237
14238 /**
14239  * Add/del map request itr rlocs from LISP control plane and updates
14240  *
14241  * @param vam vpp API test context
14242  * @return return code
14243  */
14244 static int
14245 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14246 {
14247   unformat_input_t *input = vam->input;
14248   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14249   f64 timeout = ~0;
14250   u8 *locator_set_name = 0;
14251   u8 locator_set_name_set = 0;
14252   u8 is_add = 1;
14253
14254   /* Parse args required to build the message */
14255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14256     {
14257       if (unformat (input, "del"))
14258         {
14259           is_add = 0;
14260         }
14261       else if (unformat (input, "%_%v%_", &locator_set_name))
14262         {
14263           locator_set_name_set = 1;
14264         }
14265       else
14266         {
14267           clib_warning ("parse error '%U'", format_unformat_error, input);
14268           return -99;
14269         }
14270     }
14271
14272   if (is_add && !locator_set_name_set)
14273     {
14274       errmsg ("itr-rloc is not set!");
14275       return -99;
14276     }
14277
14278   if (is_add && vec_len (locator_set_name) > 64)
14279     {
14280       errmsg ("itr-rloc locator-set name too long");
14281       vec_free (locator_set_name);
14282       return -99;
14283     }
14284
14285   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14286   mp->is_add = is_add;
14287   if (is_add)
14288     {
14289       clib_memcpy (mp->locator_set_name, locator_set_name,
14290                    vec_len (locator_set_name));
14291     }
14292   else
14293     {
14294       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14295     }
14296   vec_free (locator_set_name);
14297
14298   /* send it... */
14299   S;
14300
14301   /* Wait for a reply... */
14302   W;
14303
14304   /* NOTREACHED */
14305   return 0;
14306 }
14307
14308 static int
14309 api_lisp_locator_dump (vat_main_t * vam)
14310 {
14311   unformat_input_t *input = vam->input;
14312   vl_api_lisp_locator_dump_t *mp;
14313   f64 timeout = ~0;
14314   u8 is_index_set = 0, is_name_set = 0;
14315   u8 *ls_name = 0;
14316   u32 ls_index = ~0;
14317
14318   /* Parse args required to build the message */
14319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14320     {
14321       if (unformat (input, "ls_name %_%v%_", &ls_name))
14322         {
14323           is_name_set = 1;
14324         }
14325       else if (unformat (input, "ls_index %d", &ls_index))
14326         {
14327           is_index_set = 1;
14328         }
14329       else
14330         {
14331           errmsg ("parse error '%U'", format_unformat_error, input);
14332           return -99;
14333         }
14334     }
14335
14336   if (!is_index_set && !is_name_set)
14337     {
14338       errmsg ("error: expected one of index or name!");
14339       return -99;
14340     }
14341
14342   if (is_index_set && is_name_set)
14343     {
14344       errmsg ("error: only one param expected!");
14345       return -99;
14346     }
14347
14348   if (vec_len (ls_name) > 62)
14349     {
14350       errmsg ("error: locator set name too long!");
14351       return -99;
14352     }
14353
14354   if (!vam->json_output)
14355     {
14356       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14357     }
14358
14359   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14360   mp->is_index_set = is_index_set;
14361
14362   if (is_index_set)
14363     mp->ls_index = clib_host_to_net_u32 (ls_index);
14364   else
14365     {
14366       vec_add1 (ls_name, 0);
14367       strncpy ((char *) mp->ls_name, (char *) ls_name,
14368                sizeof (mp->ls_name) - 1);
14369     }
14370
14371   /* send it... */
14372   S;
14373
14374   /* Use a control ping for synchronization */
14375   {
14376     vl_api_control_ping_t *mp;
14377     M (CONTROL_PING, control_ping);
14378     S;
14379   }
14380   /* Wait for a reply... */
14381   W;
14382
14383   /* NOTREACHED */
14384   return 0;
14385 }
14386
14387 static int
14388 api_lisp_locator_set_dump (vat_main_t * vam)
14389 {
14390   vl_api_lisp_locator_set_dump_t *mp;
14391   unformat_input_t *input = vam->input;
14392   f64 timeout = ~0;
14393   u8 filter = 0;
14394
14395   /* Parse args required to build the message */
14396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14397     {
14398       if (unformat (input, "local"))
14399         {
14400           filter = 1;
14401         }
14402       else if (unformat (input, "remote"))
14403         {
14404           filter = 2;
14405         }
14406       else
14407         {
14408           errmsg ("parse error '%U'", format_unformat_error, input);
14409           return -99;
14410         }
14411     }
14412
14413   if (!vam->json_output)
14414     {
14415       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14416     }
14417
14418   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14419
14420   mp->filter = filter;
14421
14422   /* send it... */
14423   S;
14424
14425   /* Use a control ping for synchronization */
14426   {
14427     vl_api_control_ping_t *mp;
14428     M (CONTROL_PING, control_ping);
14429     S;
14430   }
14431   /* Wait for a reply... */
14432   W;
14433
14434   /* NOTREACHED */
14435   return 0;
14436 }
14437
14438 static int
14439 api_lisp_eid_table_map_dump (vat_main_t * vam)
14440 {
14441   u8 is_l2 = 0;
14442   u8 mode_set = 0;
14443   unformat_input_t *input = vam->input;
14444   vl_api_lisp_eid_table_map_dump_t *mp;
14445   f64 timeout = ~0;
14446
14447   /* Parse args required to build the message */
14448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14449     {
14450       if (unformat (input, "l2"))
14451         {
14452           is_l2 = 1;
14453           mode_set = 1;
14454         }
14455       else if (unformat (input, "l3"))
14456         {
14457           is_l2 = 0;
14458           mode_set = 1;
14459         }
14460       else
14461         {
14462           errmsg ("parse error '%U'", format_unformat_error, input);
14463           return -99;
14464         }
14465     }
14466
14467   if (!mode_set)
14468     {
14469       errmsg ("expected one of 'l2' or 'l3' parameter!");
14470       return -99;
14471     }
14472
14473   if (!vam->json_output)
14474     {
14475       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14476     }
14477
14478   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14479   mp->is_l2 = is_l2;
14480
14481   /* send it... */
14482   S;
14483
14484   /* Use a control ping for synchronization */
14485   {
14486     vl_api_control_ping_t *mp;
14487     M (CONTROL_PING, control_ping);
14488     S;
14489   }
14490   /* Wait for a reply... */
14491   W;
14492
14493   /* NOTREACHED */
14494   return 0;
14495 }
14496
14497 static int
14498 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14499 {
14500   vl_api_lisp_eid_table_vni_dump_t *mp;
14501   f64 timeout = ~0;
14502
14503   if (!vam->json_output)
14504     {
14505       print (vam->ofp, "VNI");
14506     }
14507
14508   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14509
14510   /* send it... */
14511   S;
14512
14513   /* Use a control ping for synchronization */
14514   {
14515     vl_api_control_ping_t *mp;
14516     M (CONTROL_PING, control_ping);
14517     S;
14518   }
14519   /* Wait for a reply... */
14520   W;
14521
14522   /* NOTREACHED */
14523   return 0;
14524 }
14525
14526 static int
14527 api_lisp_eid_table_dump (vat_main_t * vam)
14528 {
14529   unformat_input_t *i = vam->input;
14530   vl_api_lisp_eid_table_dump_t *mp;
14531   f64 timeout = ~0;
14532   struct in_addr ip4;
14533   struct in6_addr ip6;
14534   u8 mac[6];
14535   u8 eid_type = ~0, eid_set = 0;
14536   u32 prefix_length = ~0, t, vni = 0;
14537   u8 filter = 0;
14538
14539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14542         {
14543           eid_set = 1;
14544           eid_type = 0;
14545           prefix_length = t;
14546         }
14547       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14548         {
14549           eid_set = 1;
14550           eid_type = 1;
14551           prefix_length = t;
14552         }
14553       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14554         {
14555           eid_set = 1;
14556           eid_type = 2;
14557         }
14558       else if (unformat (i, "vni %d", &t))
14559         {
14560           vni = t;
14561         }
14562       else if (unformat (i, "local"))
14563         {
14564           filter = 1;
14565         }
14566       else if (unformat (i, "remote"))
14567         {
14568           filter = 2;
14569         }
14570       else
14571         {
14572           errmsg ("parse error '%U'", format_unformat_error, i);
14573           return -99;
14574         }
14575     }
14576
14577   if (!vam->json_output)
14578     {
14579       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14580              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14581     }
14582
14583   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14584
14585   mp->filter = filter;
14586   if (eid_set)
14587     {
14588       mp->eid_set = 1;
14589       mp->vni = htonl (vni);
14590       mp->eid_type = eid_type;
14591       switch (eid_type)
14592         {
14593         case 0:
14594           mp->prefix_length = prefix_length;
14595           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14596           break;
14597         case 1:
14598           mp->prefix_length = prefix_length;
14599           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14600           break;
14601         case 2:
14602           clib_memcpy (mp->eid, mac, sizeof (mac));
14603           break;
14604         default:
14605           errmsg ("unknown EID type %d!", eid_type);
14606           return -99;
14607         }
14608     }
14609
14610   /* send it... */
14611   S;
14612
14613   /* Use a control ping for synchronization */
14614   {
14615     vl_api_control_ping_t *mp;
14616     M (CONTROL_PING, control_ping);
14617     S;
14618   }
14619
14620   /* Wait for a reply... */
14621   W;
14622
14623   /* NOTREACHED */
14624   return 0;
14625 }
14626
14627 static int
14628 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14629 {
14630   vl_api_lisp_gpe_tunnel_dump_t *mp;
14631   f64 timeout = ~0;
14632
14633   if (!vam->json_output)
14634     {
14635       print (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14636              "%=16s%=16s%=16s%=16s%=16s",
14637              "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14638              "Decap next", "Lisp version", "Flags", "Next protocol",
14639              "ver_res", "res", "iid");
14640     }
14641
14642   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14643   /* send it... */
14644   S;
14645
14646   /* Use a control ping for synchronization */
14647   {
14648     vl_api_control_ping_t *mp;
14649     M (CONTROL_PING, control_ping);
14650     S;
14651   }
14652   /* Wait for a reply... */
14653   W;
14654
14655   /* NOTREACHED */
14656   return 0;
14657 }
14658
14659 static int
14660 api_lisp_adjacencies_get (vat_main_t * vam)
14661 {
14662   unformat_input_t *i = vam->input;
14663   vl_api_lisp_adjacencies_get_t *mp;
14664   f64 timeout = ~0;
14665   u8 vni_set = 0;
14666   u32 vni = ~0;
14667
14668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14669     {
14670       if (unformat (i, "vni %d", &vni))
14671         {
14672           vni_set = 1;
14673         }
14674       else
14675         {
14676           errmsg ("parse error '%U'", format_unformat_error, i);
14677           return -99;
14678         }
14679     }
14680
14681   if (!vni_set)
14682     {
14683       errmsg ("vni not set!");
14684       return -99;
14685     }
14686
14687   if (!vam->json_output)
14688     {
14689       print (vam->ofp, "%s %40s", "leid", "reid");
14690     }
14691
14692   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14693   mp->vni = clib_host_to_net_u32 (vni);
14694
14695   /* send it... */
14696   S;
14697
14698   /* Wait for a reply... */
14699   W;
14700
14701   /* NOTREACHED */
14702   return 0;
14703 }
14704
14705 static int
14706 api_lisp_map_server_dump (vat_main_t * vam)
14707 {
14708   vl_api_lisp_map_server_dump_t *mp;
14709   f64 timeout = ~0;
14710
14711   if (!vam->json_output)
14712     {
14713       print (vam->ofp, "%=20s", "Map server");
14714     }
14715
14716   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14717   /* send it... */
14718   S;
14719
14720   /* Use a control ping for synchronization */
14721   {
14722     vl_api_control_ping_t *mp;
14723     M (CONTROL_PING, control_ping);
14724     S;
14725   }
14726   /* Wait for a reply... */
14727   W;
14728
14729   /* NOTREACHED */
14730   return 0;
14731 }
14732
14733 static int
14734 api_lisp_map_resolver_dump (vat_main_t * vam)
14735 {
14736   vl_api_lisp_map_resolver_dump_t *mp;
14737   f64 timeout = ~0;
14738
14739   if (!vam->json_output)
14740     {
14741       print (vam->ofp, "%=20s", "Map resolver");
14742     }
14743
14744   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14745   /* send it... */
14746   S;
14747
14748   /* Use a control ping for synchronization */
14749   {
14750     vl_api_control_ping_t *mp;
14751     M (CONTROL_PING, control_ping);
14752     S;
14753   }
14754   /* Wait for a reply... */
14755   W;
14756
14757   /* NOTREACHED */
14758   return 0;
14759 }
14760
14761 static int
14762 api_show_lisp_status (vat_main_t * vam)
14763 {
14764   vl_api_show_lisp_status_t *mp;
14765   f64 timeout = ~0;
14766
14767   if (!vam->json_output)
14768     {
14769       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14770     }
14771
14772   M (SHOW_LISP_STATUS, show_lisp_status);
14773   /* send it... */
14774   S;
14775   /* Wait for a reply... */
14776   W;
14777
14778   /* NOTREACHED */
14779   return 0;
14780 }
14781
14782 static int
14783 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14784 {
14785   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14786   f64 timeout = ~0;
14787
14788   if (!vam->json_output)
14789     {
14790       print (vam->ofp, "%=20s", "itr-rlocs:");
14791     }
14792
14793   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14794   /* send it... */
14795   S;
14796   /* Wait for a reply... */
14797   W;
14798
14799   /* NOTREACHED */
14800   return 0;
14801 }
14802
14803 static int
14804 api_af_packet_create (vat_main_t * vam)
14805 {
14806   unformat_input_t *i = vam->input;
14807   vl_api_af_packet_create_t *mp;
14808   f64 timeout;
14809   u8 *host_if_name = 0;
14810   u8 hw_addr[6];
14811   u8 random_hw_addr = 1;
14812
14813   memset (hw_addr, 0, sizeof (hw_addr));
14814
14815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14816     {
14817       if (unformat (i, "name %s", &host_if_name))
14818         vec_add1 (host_if_name, 0);
14819       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14820         random_hw_addr = 0;
14821       else
14822         break;
14823     }
14824
14825   if (!vec_len (host_if_name))
14826     {
14827       errmsg ("host-interface name must be specified");
14828       return -99;
14829     }
14830
14831   if (vec_len (host_if_name) > 64)
14832     {
14833       errmsg ("host-interface name too long");
14834       return -99;
14835     }
14836
14837   M (AF_PACKET_CREATE, af_packet_create);
14838
14839   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14840   clib_memcpy (mp->hw_addr, hw_addr, 6);
14841   mp->use_random_hw_addr = random_hw_addr;
14842   vec_free (host_if_name);
14843
14844   S;
14845   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14846   /* NOTREACHED */
14847   return 0;
14848 }
14849
14850 static int
14851 api_af_packet_delete (vat_main_t * vam)
14852 {
14853   unformat_input_t *i = vam->input;
14854   vl_api_af_packet_delete_t *mp;
14855   f64 timeout;
14856   u8 *host_if_name = 0;
14857
14858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14859     {
14860       if (unformat (i, "name %s", &host_if_name))
14861         vec_add1 (host_if_name, 0);
14862       else
14863         break;
14864     }
14865
14866   if (!vec_len (host_if_name))
14867     {
14868       errmsg ("host-interface name must be specified");
14869       return -99;
14870     }
14871
14872   if (vec_len (host_if_name) > 64)
14873     {
14874       errmsg ("host-interface name too long");
14875       return -99;
14876     }
14877
14878   M (AF_PACKET_DELETE, af_packet_delete);
14879
14880   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14881   vec_free (host_if_name);
14882
14883   S;
14884   W;
14885   /* NOTREACHED */
14886   return 0;
14887 }
14888
14889 static int
14890 api_policer_add_del (vat_main_t * vam)
14891 {
14892   unformat_input_t *i = vam->input;
14893   vl_api_policer_add_del_t *mp;
14894   f64 timeout;
14895   u8 is_add = 1;
14896   u8 *name = 0;
14897   u32 cir = 0;
14898   u32 eir = 0;
14899   u64 cb = 0;
14900   u64 eb = 0;
14901   u8 rate_type = 0;
14902   u8 round_type = 0;
14903   u8 type = 0;
14904   u8 color_aware = 0;
14905   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14906
14907   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14908   conform_action.dscp = 0;
14909   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14910   exceed_action.dscp = 0;
14911   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14912   violate_action.dscp = 0;
14913
14914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (i, "del"))
14917         is_add = 0;
14918       else if (unformat (i, "name %s", &name))
14919         vec_add1 (name, 0);
14920       else if (unformat (i, "cir %u", &cir))
14921         ;
14922       else if (unformat (i, "eir %u", &eir))
14923         ;
14924       else if (unformat (i, "cb %u", &cb))
14925         ;
14926       else if (unformat (i, "eb %u", &eb))
14927         ;
14928       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14929                          &rate_type))
14930         ;
14931       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14932                          &round_type))
14933         ;
14934       else if (unformat (i, "type %U", unformat_policer_type, &type))
14935         ;
14936       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14937                          &conform_action))
14938         ;
14939       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14940                          &exceed_action))
14941         ;
14942       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14943                          &violate_action))
14944         ;
14945       else if (unformat (i, "color-aware"))
14946         color_aware = 1;
14947       else
14948         break;
14949     }
14950
14951   if (!vec_len (name))
14952     {
14953       errmsg ("policer name must be specified");
14954       return -99;
14955     }
14956
14957   if (vec_len (name) > 64)
14958     {
14959       errmsg ("policer name too long");
14960       return -99;
14961     }
14962
14963   M (POLICER_ADD_DEL, policer_add_del);
14964
14965   clib_memcpy (mp->name, name, vec_len (name));
14966   vec_free (name);
14967   mp->is_add = is_add;
14968   mp->cir = cir;
14969   mp->eir = eir;
14970   mp->cb = cb;
14971   mp->eb = eb;
14972   mp->rate_type = rate_type;
14973   mp->round_type = round_type;
14974   mp->type = type;
14975   mp->conform_action_type = conform_action.action_type;
14976   mp->conform_dscp = conform_action.dscp;
14977   mp->exceed_action_type = exceed_action.action_type;
14978   mp->exceed_dscp = exceed_action.dscp;
14979   mp->violate_action_type = violate_action.action_type;
14980   mp->violate_dscp = violate_action.dscp;
14981   mp->color_aware = color_aware;
14982
14983   S;
14984   W;
14985   /* NOTREACHED */
14986   return 0;
14987 }
14988
14989 static int
14990 api_policer_dump (vat_main_t * vam)
14991 {
14992   unformat_input_t *i = vam->input;
14993   vl_api_policer_dump_t *mp;
14994   f64 timeout = ~0;
14995   u8 *match_name = 0;
14996   u8 match_name_valid = 0;
14997
14998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14999     {
15000       if (unformat (i, "name %s", &match_name))
15001         {
15002           vec_add1 (match_name, 0);
15003           match_name_valid = 1;
15004         }
15005       else
15006         break;
15007     }
15008
15009   M (POLICER_DUMP, policer_dump);
15010   mp->match_name_valid = match_name_valid;
15011   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15012   vec_free (match_name);
15013   /* send it... */
15014   S;
15015
15016   /* Use a control ping for synchronization */
15017   {
15018     vl_api_control_ping_t *mp;
15019     M (CONTROL_PING, control_ping);
15020     S;
15021   }
15022   /* Wait for a reply... */
15023   W;
15024
15025   /* NOTREACHED */
15026   return 0;
15027 }
15028
15029 static int
15030 api_policer_classify_set_interface (vat_main_t * vam)
15031 {
15032   unformat_input_t *i = vam->input;
15033   vl_api_policer_classify_set_interface_t *mp;
15034   f64 timeout;
15035   u32 sw_if_index;
15036   int sw_if_index_set;
15037   u32 ip4_table_index = ~0;
15038   u32 ip6_table_index = ~0;
15039   u32 l2_table_index = ~0;
15040   u8 is_add = 1;
15041
15042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15043     {
15044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15045         sw_if_index_set = 1;
15046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15047         sw_if_index_set = 1;
15048       else if (unformat (i, "del"))
15049         is_add = 0;
15050       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15051         ;
15052       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15053         ;
15054       else if (unformat (i, "l2-table %d", &l2_table_index))
15055         ;
15056       else
15057         {
15058           clib_warning ("parse error '%U'", format_unformat_error, i);
15059           return -99;
15060         }
15061     }
15062
15063   if (sw_if_index_set == 0)
15064     {
15065       errmsg ("missing interface name or sw_if_index");
15066       return -99;
15067     }
15068
15069   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15070
15071   mp->sw_if_index = ntohl (sw_if_index);
15072   mp->ip4_table_index = ntohl (ip4_table_index);
15073   mp->ip6_table_index = ntohl (ip6_table_index);
15074   mp->l2_table_index = ntohl (l2_table_index);
15075   mp->is_add = is_add;
15076
15077   S;
15078   W;
15079   /* NOTREACHED */
15080   return 0;
15081 }
15082
15083 static int
15084 api_policer_classify_dump (vat_main_t * vam)
15085 {
15086   unformat_input_t *i = vam->input;
15087   vl_api_policer_classify_dump_t *mp;
15088   f64 timeout = ~0;
15089   u8 type = POLICER_CLASSIFY_N_TABLES;
15090
15091   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15092     ;
15093   else
15094     {
15095       errmsg ("classify table type must be specified");
15096       return -99;
15097     }
15098
15099   if (!vam->json_output)
15100     {
15101       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15102     }
15103
15104   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15105   mp->type = type;
15106   /* send it... */
15107   S;
15108
15109   /* Use a control ping for synchronization */
15110   {
15111     vl_api_control_ping_t *mp;
15112     M (CONTROL_PING, control_ping);
15113     S;
15114   }
15115   /* Wait for a reply... */
15116   W;
15117
15118   /* NOTREACHED */
15119   return 0;
15120 }
15121
15122 static int
15123 api_netmap_create (vat_main_t * vam)
15124 {
15125   unformat_input_t *i = vam->input;
15126   vl_api_netmap_create_t *mp;
15127   f64 timeout;
15128   u8 *if_name = 0;
15129   u8 hw_addr[6];
15130   u8 random_hw_addr = 1;
15131   u8 is_pipe = 0;
15132   u8 is_master = 0;
15133
15134   memset (hw_addr, 0, sizeof (hw_addr));
15135
15136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15137     {
15138       if (unformat (i, "name %s", &if_name))
15139         vec_add1 (if_name, 0);
15140       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15141         random_hw_addr = 0;
15142       else if (unformat (i, "pipe"))
15143         is_pipe = 1;
15144       else if (unformat (i, "master"))
15145         is_master = 1;
15146       else if (unformat (i, "slave"))
15147         is_master = 0;
15148       else
15149         break;
15150     }
15151
15152   if (!vec_len (if_name))
15153     {
15154       errmsg ("interface name must be specified");
15155       return -99;
15156     }
15157
15158   if (vec_len (if_name) > 64)
15159     {
15160       errmsg ("interface name too long");
15161       return -99;
15162     }
15163
15164   M (NETMAP_CREATE, netmap_create);
15165
15166   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15167   clib_memcpy (mp->hw_addr, hw_addr, 6);
15168   mp->use_random_hw_addr = random_hw_addr;
15169   mp->is_pipe = is_pipe;
15170   mp->is_master = is_master;
15171   vec_free (if_name);
15172
15173   S;
15174   W;
15175   /* NOTREACHED */
15176   return 0;
15177 }
15178
15179 static int
15180 api_netmap_delete (vat_main_t * vam)
15181 {
15182   unformat_input_t *i = vam->input;
15183   vl_api_netmap_delete_t *mp;
15184   f64 timeout;
15185   u8 *if_name = 0;
15186
15187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15188     {
15189       if (unformat (i, "name %s", &if_name))
15190         vec_add1 (if_name, 0);
15191       else
15192         break;
15193     }
15194
15195   if (!vec_len (if_name))
15196     {
15197       errmsg ("interface name must be specified");
15198       return -99;
15199     }
15200
15201   if (vec_len (if_name) > 64)
15202     {
15203       errmsg ("interface name too long");
15204       return -99;
15205     }
15206
15207   M (NETMAP_DELETE, netmap_delete);
15208
15209   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15210   vec_free (if_name);
15211
15212   S;
15213   W;
15214   /* NOTREACHED */
15215   return 0;
15216 }
15217
15218 static void vl_api_mpls_tunnel_details_t_handler
15219   (vl_api_mpls_tunnel_details_t * mp)
15220 {
15221   vat_main_t *vam = &vat_main;
15222   i32 len = mp->mt_next_hop_n_labels;
15223   i32 i;
15224
15225   print (vam->ofp, "[%d]: via %U %d labels ",
15226          mp->tunnel_index,
15227          format_ip4_address, mp->mt_next_hop,
15228          ntohl (mp->mt_next_hop_sw_if_index));
15229   for (i = 0; i < len; i++)
15230     {
15231       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15232     }
15233   print (vam->ofp, "");
15234 }
15235
15236 static void vl_api_mpls_tunnel_details_t_handler_json
15237   (vl_api_mpls_tunnel_details_t * mp)
15238 {
15239   vat_main_t *vam = &vat_main;
15240   vat_json_node_t *node = NULL;
15241   struct in_addr ip4;
15242   i32 i;
15243   i32 len = mp->mt_next_hop_n_labels;
15244
15245   if (VAT_JSON_ARRAY != vam->json_tree.type)
15246     {
15247       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15248       vat_json_init_array (&vam->json_tree);
15249     }
15250   node = vat_json_array_add (&vam->json_tree);
15251
15252   vat_json_init_object (node);
15253   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15254   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15255   vat_json_object_add_ip4 (node, "next_hop", ip4);
15256   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15257                             ntohl (mp->mt_next_hop_sw_if_index));
15258   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15259   vat_json_object_add_uint (node, "label_count", len);
15260   for (i = 0; i < len; i++)
15261     {
15262       vat_json_object_add_uint (node, "label",
15263                                 ntohl (mp->mt_next_hop_out_labels[i]));
15264     }
15265 }
15266
15267 static int
15268 api_mpls_tunnel_dump (vat_main_t * vam)
15269 {
15270   vl_api_mpls_tunnel_dump_t *mp;
15271   f64 timeout;
15272   i32 index = -1;
15273
15274   /* Parse args required to build the message */
15275   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15276     {
15277       if (!unformat (vam->input, "tunnel_index %d", &index))
15278         {
15279           index = -1;
15280           break;
15281         }
15282     }
15283
15284   print (vam->ofp, "  tunnel_index %d", index);
15285
15286   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15287   mp->tunnel_index = htonl (index);
15288   S;
15289
15290   /* Use a control ping for synchronization */
15291   {
15292     vl_api_control_ping_t *mp;
15293     M (CONTROL_PING, control_ping);
15294     S;
15295   }
15296   W;
15297 }
15298
15299 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15300 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15301
15302 static void
15303 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15304 {
15305   vat_main_t *vam = &vat_main;
15306   int count = ntohl (mp->count);
15307   vl_api_fib_path2_t *fp;
15308   int i;
15309
15310   print (vam->ofp,
15311          "table-id %d, label %u, ess_bit %u",
15312          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15313   fp = mp->path;
15314   for (i = 0; i < count; i++)
15315     {
15316       if (fp->afi == IP46_TYPE_IP6)
15317         print (vam->ofp,
15318                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15319                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15320                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15321                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15322                format_ip6_address, fp->next_hop);
15323       else if (fp->afi == IP46_TYPE_IP4)
15324         print (vam->ofp,
15325                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15326                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15327                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15328                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15329                format_ip4_address, fp->next_hop);
15330       fp++;
15331     }
15332 }
15333
15334 static void vl_api_mpls_fib_details_t_handler_json
15335   (vl_api_mpls_fib_details_t * mp)
15336 {
15337   vat_main_t *vam = &vat_main;
15338   int count = ntohl (mp->count);
15339   vat_json_node_t *node = NULL;
15340   struct in_addr ip4;
15341   struct in6_addr ip6;
15342   vl_api_fib_path2_t *fp;
15343   int i;
15344
15345   if (VAT_JSON_ARRAY != vam->json_tree.type)
15346     {
15347       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15348       vat_json_init_array (&vam->json_tree);
15349     }
15350   node = vat_json_array_add (&vam->json_tree);
15351
15352   vat_json_init_object (node);
15353   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15354   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15355   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15356   vat_json_object_add_uint (node, "path_count", count);
15357   fp = mp->path;
15358   for (i = 0; i < count; i++)
15359     {
15360       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15361       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15362       vat_json_object_add_uint (node, "is_local", fp->is_local);
15363       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15364       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15365       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15366       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15367       if (fp->afi == IP46_TYPE_IP4)
15368         {
15369           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15370           vat_json_object_add_ip4 (node, "next_hop", ip4);
15371         }
15372       else if (fp->afi == IP46_TYPE_IP6)
15373         {
15374           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15375           vat_json_object_add_ip6 (node, "next_hop", ip6);
15376         }
15377     }
15378 }
15379
15380 static int
15381 api_mpls_fib_dump (vat_main_t * vam)
15382 {
15383   vl_api_mpls_fib_dump_t *mp;
15384   f64 timeout;
15385
15386   M (MPLS_FIB_DUMP, mpls_fib_dump);
15387   S;
15388
15389   /* Use a control ping for synchronization */
15390   {
15391     vl_api_control_ping_t *mp;
15392     M (CONTROL_PING, control_ping);
15393     S;
15394   }
15395   W;
15396 }
15397
15398 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15399 #define vl_api_ip_fib_details_t_print vl_noop_handler
15400
15401 static void
15402 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15403 {
15404   vat_main_t *vam = &vat_main;
15405   int count = ntohl (mp->count);
15406   vl_api_fib_path_t *fp;
15407   int i;
15408
15409   print (vam->ofp,
15410          "table-id %d, prefix %U/%d",
15411          ntohl (mp->table_id), format_ip4_address, mp->address,
15412          mp->address_length);
15413   fp = mp->path;
15414   for (i = 0; i < count; i++)
15415     {
15416       if (fp->afi == IP46_TYPE_IP6)
15417         print (vam->ofp,
15418                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15419                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15420                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15421                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15422                format_ip6_address, fp->next_hop);
15423       else if (fp->afi == IP46_TYPE_IP4)
15424         print (vam->ofp,
15425                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15426                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15427                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15428                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15429                format_ip4_address, fp->next_hop);
15430       fp++;
15431     }
15432 }
15433
15434 static void vl_api_ip_fib_details_t_handler_json
15435   (vl_api_ip_fib_details_t * mp)
15436 {
15437   vat_main_t *vam = &vat_main;
15438   int count = ntohl (mp->count);
15439   vat_json_node_t *node = NULL;
15440   struct in_addr ip4;
15441   struct in6_addr ip6;
15442   vl_api_fib_path_t *fp;
15443   int i;
15444
15445   if (VAT_JSON_ARRAY != vam->json_tree.type)
15446     {
15447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15448       vat_json_init_array (&vam->json_tree);
15449     }
15450   node = vat_json_array_add (&vam->json_tree);
15451
15452   vat_json_init_object (node);
15453   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15454   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15455   vat_json_object_add_ip4 (node, "prefix", ip4);
15456   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15457   vat_json_object_add_uint (node, "path_count", count);
15458   fp = mp->path;
15459   for (i = 0; i < count; i++)
15460     {
15461       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15462       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15463       vat_json_object_add_uint (node, "is_local", fp->is_local);
15464       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15465       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15466       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15467       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15468       if (fp->afi == IP46_TYPE_IP4)
15469         {
15470           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15471           vat_json_object_add_ip4 (node, "next_hop", ip4);
15472         }
15473       else if (fp->afi == IP46_TYPE_IP6)
15474         {
15475           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15476           vat_json_object_add_ip6 (node, "next_hop", ip6);
15477         }
15478     }
15479 }
15480
15481 static int
15482 api_ip_fib_dump (vat_main_t * vam)
15483 {
15484   vl_api_ip_fib_dump_t *mp;
15485   f64 timeout;
15486
15487   M (IP_FIB_DUMP, ip_fib_dump);
15488   S;
15489
15490   /* Use a control ping for synchronization */
15491   {
15492     vl_api_control_ping_t *mp;
15493     M (CONTROL_PING, control_ping);
15494     S;
15495   }
15496   W;
15497 }
15498
15499 static void vl_api_ip_neighbor_details_t_handler
15500   (vl_api_ip_neighbor_details_t * mp)
15501 {
15502   vat_main_t *vam = &vat_main;
15503
15504   print (vam->ofp, "%c %U %U",
15505          (mp->is_static) ? 'S' : 'D',
15506          format_ethernet_address, &mp->mac_address,
15507          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15508          &mp->ip_address);
15509 }
15510
15511 static void vl_api_ip_neighbor_details_t_handler_json
15512   (vl_api_ip_neighbor_details_t * mp)
15513 {
15514
15515   vat_main_t *vam = &vat_main;
15516   vat_json_node_t *node;
15517   struct in_addr ip4;
15518   struct in6_addr ip6;
15519
15520   if (VAT_JSON_ARRAY != vam->json_tree.type)
15521     {
15522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15523       vat_json_init_array (&vam->json_tree);
15524     }
15525   node = vat_json_array_add (&vam->json_tree);
15526
15527   vat_json_init_object (node);
15528   vat_json_object_add_string_copy (node, "flag",
15529                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15530                                    "dynamic");
15531
15532   vat_json_object_add_string_copy (node, "link_layer",
15533                                    format (0, "%U", format_ethernet_address,
15534                                            &mp->mac_address));
15535
15536   if (mp->is_ipv6)
15537     {
15538       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15539       vat_json_object_add_ip6 (node, "ip_address", ip6);
15540     }
15541   else
15542     {
15543       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15544       vat_json_object_add_ip4 (node, "ip_address", ip4);
15545     }
15546 }
15547
15548 static int
15549 api_ip_neighbor_dump (vat_main_t * vam)
15550 {
15551   unformat_input_t *i = vam->input;
15552   vl_api_ip_neighbor_dump_t *mp;
15553   f64 timeout;
15554   u8 is_ipv6 = 0;
15555   u32 sw_if_index = ~0;
15556
15557   /* Parse args required to build the message */
15558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15559     {
15560       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15561         ;
15562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15563         ;
15564       else if (unformat (i, "ip6"))
15565         is_ipv6 = 1;
15566       else
15567         break;
15568     }
15569
15570   if (sw_if_index == ~0)
15571     {
15572       errmsg ("missing interface name or sw_if_index");
15573       return -99;
15574     }
15575
15576   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15577   mp->is_ipv6 = (u8) is_ipv6;
15578   mp->sw_if_index = ntohl (sw_if_index);
15579   S;
15580
15581   /* Use a control ping for synchronization */
15582   {
15583     vl_api_control_ping_t *mp;
15584     M (CONTROL_PING, control_ping);
15585     S;
15586   }
15587   W;
15588 }
15589
15590 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15591 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15592
15593 static void
15594 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15595 {
15596   vat_main_t *vam = &vat_main;
15597   int count = ntohl (mp->count);
15598   vl_api_fib_path_t *fp;
15599   int i;
15600
15601   print (vam->ofp,
15602          "table-id %d, prefix %U/%d",
15603          ntohl (mp->table_id), format_ip6_address, mp->address,
15604          mp->address_length);
15605   fp = mp->path;
15606   for (i = 0; i < count; i++)
15607     {
15608       if (fp->afi == IP46_TYPE_IP6)
15609         print (vam->ofp,
15610                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15611                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15612                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15613                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15614                format_ip6_address, fp->next_hop);
15615       else if (fp->afi == IP46_TYPE_IP4)
15616         print (vam->ofp,
15617                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15618                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15619                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15620                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15621                format_ip4_address, fp->next_hop);
15622       fp++;
15623     }
15624 }
15625
15626 static void vl_api_ip6_fib_details_t_handler_json
15627   (vl_api_ip6_fib_details_t * mp)
15628 {
15629   vat_main_t *vam = &vat_main;
15630   int count = ntohl (mp->count);
15631   vat_json_node_t *node = NULL;
15632   struct in_addr ip4;
15633   struct in6_addr ip6;
15634   vl_api_fib_path_t *fp;
15635   int i;
15636
15637   if (VAT_JSON_ARRAY != vam->json_tree.type)
15638     {
15639       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15640       vat_json_init_array (&vam->json_tree);
15641     }
15642   node = vat_json_array_add (&vam->json_tree);
15643
15644   vat_json_init_object (node);
15645   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15646   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15647   vat_json_object_add_ip6 (node, "prefix", ip6);
15648   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15649   vat_json_object_add_uint (node, "path_count", count);
15650   fp = mp->path;
15651   for (i = 0; i < count; i++)
15652     {
15653       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15654       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15655       vat_json_object_add_uint (node, "is_local", fp->is_local);
15656       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15657       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15658       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15659       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15660       if (fp->afi == IP46_TYPE_IP4)
15661         {
15662           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15663           vat_json_object_add_ip4 (node, "next_hop", ip4);
15664         }
15665       else if (fp->afi == IP46_TYPE_IP6)
15666         {
15667           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15668           vat_json_object_add_ip6 (node, "next_hop", ip6);
15669         }
15670     }
15671 }
15672
15673 static int
15674 api_ip6_fib_dump (vat_main_t * vam)
15675 {
15676   vl_api_ip6_fib_dump_t *mp;
15677   f64 timeout;
15678
15679   M (IP6_FIB_DUMP, ip6_fib_dump);
15680   S;
15681
15682   /* Use a control ping for synchronization */
15683   {
15684     vl_api_control_ping_t *mp;
15685     M (CONTROL_PING, control_ping);
15686     S;
15687   }
15688   W;
15689 }
15690
15691 int
15692 api_classify_table_ids (vat_main_t * vam)
15693 {
15694   vl_api_classify_table_ids_t *mp;
15695   f64 timeout;
15696
15697   /* Construct the API message */
15698   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15699   mp->context = 0;
15700
15701   S;
15702   W;
15703   /* NOTREACHED */
15704   return 0;
15705 }
15706
15707 int
15708 api_classify_table_by_interface (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_classify_table_by_interface_t *mp;
15712   f64 timeout;
15713
15714   u32 sw_if_index = ~0;
15715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15716     {
15717       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15718         ;
15719       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15720         ;
15721       else
15722         break;
15723     }
15724   if (sw_if_index == ~0)
15725     {
15726       errmsg ("missing interface name or sw_if_index");
15727       return -99;
15728     }
15729
15730   /* Construct the API message */
15731   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15732   mp->context = 0;
15733   mp->sw_if_index = ntohl (sw_if_index);
15734
15735   S;
15736   W;
15737   /* NOTREACHED */
15738   return 0;
15739 }
15740
15741 int
15742 api_classify_table_info (vat_main_t * vam)
15743 {
15744   unformat_input_t *input = vam->input;
15745   vl_api_classify_table_info_t *mp;
15746   f64 timeout;
15747
15748   u32 table_id = ~0;
15749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15750     {
15751       if (unformat (input, "table_id %d", &table_id))
15752         ;
15753       else
15754         break;
15755     }
15756   if (table_id == ~0)
15757     {
15758       errmsg ("missing table id");
15759       return -99;
15760     }
15761
15762   /* Construct the API message */
15763   M (CLASSIFY_TABLE_INFO, classify_table_info);
15764   mp->context = 0;
15765   mp->table_id = ntohl (table_id);
15766
15767   S;
15768   W;
15769   /* NOTREACHED */
15770   return 0;
15771 }
15772
15773 int
15774 api_classify_session_dump (vat_main_t * vam)
15775 {
15776   unformat_input_t *input = vam->input;
15777   vl_api_classify_session_dump_t *mp;
15778   f64 timeout;
15779
15780   u32 table_id = ~0;
15781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15782     {
15783       if (unformat (input, "table_id %d", &table_id))
15784         ;
15785       else
15786         break;
15787     }
15788   if (table_id == ~0)
15789     {
15790       errmsg ("missing table id");
15791       return -99;
15792     }
15793
15794   /* Construct the API message */
15795   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15796   mp->context = 0;
15797   mp->table_id = ntohl (table_id);
15798   S;
15799
15800   /* Use a control ping for synchronization */
15801   {
15802     vl_api_control_ping_t *mp;
15803     M (CONTROL_PING, control_ping);
15804     S;
15805   }
15806   W;
15807   /* NOTREACHED */
15808   return 0;
15809 }
15810
15811 static void
15812 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15813 {
15814   vat_main_t *vam = &vat_main;
15815
15816   print (vam->ofp, "collector_address %U, collector_port %d, "
15817          "src_address %U, vrf_id %d, path_mtu %u, "
15818          "template_interval %u, udp_checksum %d",
15819          format_ip4_address, mp->collector_address,
15820          ntohs (mp->collector_port),
15821          format_ip4_address, mp->src_address,
15822          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15823          ntohl (mp->template_interval), mp->udp_checksum);
15824
15825   vam->retval = 0;
15826   vam->result_ready = 1;
15827 }
15828
15829 static void
15830   vl_api_ipfix_exporter_details_t_handler_json
15831   (vl_api_ipfix_exporter_details_t * mp)
15832 {
15833   vat_main_t *vam = &vat_main;
15834   vat_json_node_t node;
15835   struct in_addr collector_address;
15836   struct in_addr src_address;
15837
15838   vat_json_init_object (&node);
15839   clib_memcpy (&collector_address, &mp->collector_address,
15840                sizeof (collector_address));
15841   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15842   vat_json_object_add_uint (&node, "collector_port",
15843                             ntohs (mp->collector_port));
15844   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15845   vat_json_object_add_ip4 (&node, "src_address", src_address);
15846   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15847   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15848   vat_json_object_add_uint (&node, "template_interval",
15849                             ntohl (mp->template_interval));
15850   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15851
15852   vat_json_print (vam->ofp, &node);
15853   vat_json_free (&node);
15854   vam->retval = 0;
15855   vam->result_ready = 1;
15856 }
15857
15858 int
15859 api_ipfix_exporter_dump (vat_main_t * vam)
15860 {
15861   vl_api_ipfix_exporter_dump_t *mp;
15862   f64 timeout;
15863
15864   /* Construct the API message */
15865   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15866   mp->context = 0;
15867
15868   S;
15869   W;
15870   /* NOTREACHED */
15871   return 0;
15872 }
15873
15874 static int
15875 api_ipfix_classify_stream_dump (vat_main_t * vam)
15876 {
15877   vl_api_ipfix_classify_stream_dump_t *mp;
15878   f64 timeout;
15879
15880   /* Construct the API message */
15881   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15882   mp->context = 0;
15883
15884   S;
15885   W;
15886   /* NOTREACHED */
15887   return 0;
15888 }
15889
15890 static void
15891   vl_api_ipfix_classify_stream_details_t_handler
15892   (vl_api_ipfix_classify_stream_details_t * mp)
15893 {
15894   vat_main_t *vam = &vat_main;
15895   print (vam->ofp, "domain_id %d, src_port %d",
15896          ntohl (mp->domain_id), ntohs (mp->src_port));
15897   vam->retval = 0;
15898   vam->result_ready = 1;
15899 }
15900
15901 static void
15902   vl_api_ipfix_classify_stream_details_t_handler_json
15903   (vl_api_ipfix_classify_stream_details_t * mp)
15904 {
15905   vat_main_t *vam = &vat_main;
15906   vat_json_node_t node;
15907
15908   vat_json_init_object (&node);
15909   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15910   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15911
15912   vat_json_print (vam->ofp, &node);
15913   vat_json_free (&node);
15914   vam->retval = 0;
15915   vam->result_ready = 1;
15916 }
15917
15918 static int
15919 api_ipfix_classify_table_dump (vat_main_t * vam)
15920 {
15921   vl_api_ipfix_classify_table_dump_t *mp;
15922   f64 timeout;
15923
15924   if (!vam->json_output)
15925     {
15926       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15927              "transport_protocol");
15928     }
15929
15930   /* Construct the API message */
15931   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15932
15933   /* send it... */
15934   S;
15935
15936   /* Use a control ping for synchronization */
15937   {
15938     vl_api_control_ping_t *mp;
15939     M (CONTROL_PING, control_ping);
15940     S;
15941   }
15942   W;
15943 }
15944
15945 static void
15946   vl_api_ipfix_classify_table_details_t_handler
15947   (vl_api_ipfix_classify_table_details_t * mp)
15948 {
15949   vat_main_t *vam = &vat_main;
15950   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15951          mp->transport_protocol);
15952 }
15953
15954 static void
15955   vl_api_ipfix_classify_table_details_t_handler_json
15956   (vl_api_ipfix_classify_table_details_t * mp)
15957 {
15958   vat_json_node_t *node = NULL;
15959   vat_main_t *vam = &vat_main;
15960
15961   if (VAT_JSON_ARRAY != vam->json_tree.type)
15962     {
15963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15964       vat_json_init_array (&vam->json_tree);
15965     }
15966
15967   node = vat_json_array_add (&vam->json_tree);
15968   vat_json_init_object (node);
15969
15970   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15971   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15972   vat_json_object_add_uint (node, "transport_protocol",
15973                             mp->transport_protocol);
15974 }
15975
15976 static int
15977 api_sw_interface_span_enable_disable (vat_main_t * vam)
15978 {
15979   unformat_input_t *i = vam->input;
15980   vl_api_sw_interface_span_enable_disable_t *mp;
15981   f64 timeout;
15982   u32 src_sw_if_index = ~0;
15983   u32 dst_sw_if_index = ~0;
15984   u8 state = 3;
15985
15986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15987     {
15988       if (unformat
15989           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
15990         ;
15991       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15992         ;
15993       else
15994         if (unformat
15995             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
15996         ;
15997       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15998         ;
15999       else if (unformat (i, "disable"))
16000         state = 0;
16001       else if (unformat (i, "rx"))
16002         state = 1;
16003       else if (unformat (i, "tx"))
16004         state = 2;
16005       else if (unformat (i, "both"))
16006         state = 3;
16007       else
16008         break;
16009     }
16010
16011   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16012
16013   mp->sw_if_index_from = htonl (src_sw_if_index);
16014   mp->sw_if_index_to = htonl (dst_sw_if_index);
16015   mp->state = state;
16016
16017   S;
16018   W;
16019   /* NOTREACHED */
16020   return 0;
16021 }
16022
16023 static void
16024 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16025                                             * mp)
16026 {
16027   vat_main_t *vam = &vat_main;
16028   u8 *sw_if_from_name = 0;
16029   u8 *sw_if_to_name = 0;
16030   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16031   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16032   char *states[] = { "none", "rx", "tx", "both" };
16033   hash_pair_t *p;
16034
16035   /* *INDENT-OFF* */
16036   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16037   ({
16038     if ((u32) p->value[0] == sw_if_index_from)
16039       {
16040         sw_if_from_name = (u8 *)(p->key);
16041         if (sw_if_to_name)
16042           break;
16043       }
16044     if ((u32) p->value[0] == sw_if_index_to)
16045       {
16046         sw_if_to_name = (u8 *)(p->key);
16047         if (sw_if_from_name)
16048           break;
16049       }
16050   }));
16051   /* *INDENT-ON* */
16052   print (vam->ofp, "%20s => %20s (%s)",
16053          sw_if_from_name, sw_if_to_name, states[mp->state]);
16054 }
16055
16056 static void
16057   vl_api_sw_interface_span_details_t_handler_json
16058   (vl_api_sw_interface_span_details_t * mp)
16059 {
16060   vat_main_t *vam = &vat_main;
16061   vat_json_node_t *node = NULL;
16062   u8 *sw_if_from_name = 0;
16063   u8 *sw_if_to_name = 0;
16064   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16065   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16066   hash_pair_t *p;
16067
16068   /* *INDENT-OFF* */
16069   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16070   ({
16071     if ((u32) p->value[0] == sw_if_index_from)
16072       {
16073         sw_if_from_name = (u8 *)(p->key);
16074         if (sw_if_to_name)
16075           break;
16076       }
16077     if ((u32) p->value[0] == sw_if_index_to)
16078       {
16079         sw_if_to_name = (u8 *)(p->key);
16080         if (sw_if_from_name)
16081           break;
16082       }
16083   }));
16084   /* *INDENT-ON* */
16085
16086   if (VAT_JSON_ARRAY != vam->json_tree.type)
16087     {
16088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16089       vat_json_init_array (&vam->json_tree);
16090     }
16091   node = vat_json_array_add (&vam->json_tree);
16092
16093   vat_json_init_object (node);
16094   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16095   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16096   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16097   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16098   vat_json_object_add_uint (node, "state", mp->state);
16099 }
16100
16101 static int
16102 api_sw_interface_span_dump (vat_main_t * vam)
16103 {
16104   vl_api_sw_interface_span_dump_t *mp;
16105   f64 timeout;
16106
16107   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16108   S;
16109
16110   /* Use a control ping for synchronization */
16111   {
16112     vl_api_control_ping_t *mp;
16113     M (CONTROL_PING, control_ping);
16114     S;
16115   }
16116   W;
16117 }
16118
16119 int
16120 api_pg_create_interface (vat_main_t * vam)
16121 {
16122   unformat_input_t *input = vam->input;
16123   vl_api_pg_create_interface_t *mp;
16124   f64 timeout;
16125
16126   u32 if_id = ~0;
16127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (input, "if_id %d", &if_id))
16130         ;
16131       else
16132         break;
16133     }
16134   if (if_id == ~0)
16135     {
16136       errmsg ("missing pg interface index");
16137       return -99;
16138     }
16139
16140   /* Construct the API message */
16141   M (PG_CREATE_INTERFACE, pg_create_interface);
16142   mp->context = 0;
16143   mp->interface_id = ntohl (if_id);
16144
16145   S;
16146   W;
16147   /* NOTREACHED */
16148   return 0;
16149 }
16150
16151 int
16152 api_pg_capture (vat_main_t * vam)
16153 {
16154   unformat_input_t *input = vam->input;
16155   vl_api_pg_capture_t *mp;
16156   f64 timeout;
16157
16158   u32 if_id = ~0;
16159   u8 enable = 1;
16160   u32 count = 1;
16161   u8 pcap_file_set = 0;
16162   u8 *pcap_file = 0;
16163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16164     {
16165       if (unformat (input, "if_id %d", &if_id))
16166         ;
16167       else if (unformat (input, "pcap %s", &pcap_file))
16168         pcap_file_set = 1;
16169       else if (unformat (input, "count %d", &count))
16170         ;
16171       else if (unformat (input, "disable"))
16172         enable = 0;
16173       else
16174         break;
16175     }
16176   if (if_id == ~0)
16177     {
16178       errmsg ("missing pg interface index");
16179       return -99;
16180     }
16181   if (pcap_file_set > 0)
16182     {
16183       if (vec_len (pcap_file) > 255)
16184         {
16185           errmsg ("pcap file name is too long");
16186           return -99;
16187         }
16188     }
16189
16190   u32 name_len = vec_len (pcap_file);
16191   /* Construct the API message */
16192   M (PG_CAPTURE, pg_capture);
16193   mp->context = 0;
16194   mp->interface_id = ntohl (if_id);
16195   mp->is_enabled = enable;
16196   mp->count = ntohl (count);
16197   mp->pcap_name_length = ntohl (name_len);
16198   if (pcap_file_set != 0)
16199     {
16200       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16201     }
16202   vec_free (pcap_file);
16203
16204   S;
16205   W;
16206   /* NOTREACHED */
16207   return 0;
16208 }
16209
16210 int
16211 api_pg_enable_disable (vat_main_t * vam)
16212 {
16213   unformat_input_t *input = vam->input;
16214   vl_api_pg_enable_disable_t *mp;
16215   f64 timeout;
16216
16217   u8 enable = 1;
16218   u8 stream_name_set = 0;
16219   u8 *stream_name = 0;
16220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16221     {
16222       if (unformat (input, "stream %s", &stream_name))
16223         stream_name_set = 1;
16224       else if (unformat (input, "disable"))
16225         enable = 0;
16226       else
16227         break;
16228     }
16229
16230   if (stream_name_set > 0)
16231     {
16232       if (vec_len (stream_name) > 255)
16233         {
16234           errmsg ("stream name too long");
16235           return -99;
16236         }
16237     }
16238
16239   u32 name_len = vec_len (stream_name);
16240   /* Construct the API message */
16241   M (PG_ENABLE_DISABLE, pg_enable_disable);
16242   mp->context = 0;
16243   mp->is_enabled = enable;
16244   if (stream_name_set != 0)
16245     {
16246       mp->stream_name_length = ntohl (name_len);
16247       clib_memcpy (mp->stream_name, stream_name, name_len);
16248     }
16249   vec_free (stream_name);
16250
16251   S;
16252   W;
16253   /* NOTREACHED */
16254   return 0;
16255 }
16256
16257 int
16258 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16259 {
16260   unformat_input_t *input = vam->input;
16261   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16262   f64 timeout;
16263
16264   u16 *low_ports = 0;
16265   u16 *high_ports = 0;
16266   u16 this_low;
16267   u16 this_hi;
16268   ip4_address_t ip4_addr;
16269   ip6_address_t ip6_addr;
16270   u32 length;
16271   u32 tmp, tmp2;
16272   u8 prefix_set = 0;
16273   u32 vrf_id = ~0;
16274   u8 is_add = 1;
16275   u8 is_ipv6 = 0;
16276
16277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16278     {
16279       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16280         {
16281           prefix_set = 1;
16282         }
16283       else
16284         if (unformat
16285             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16286         {
16287           prefix_set = 1;
16288           is_ipv6 = 1;
16289         }
16290       else if (unformat (input, "vrf %d", &vrf_id))
16291         ;
16292       else if (unformat (input, "del"))
16293         is_add = 0;
16294       else if (unformat (input, "port %d", &tmp))
16295         {
16296           if (tmp == 0 || tmp > 65535)
16297             {
16298               errmsg ("port %d out of range", tmp);
16299               return -99;
16300             }
16301           this_low = tmp;
16302           this_hi = this_low + 1;
16303           vec_add1 (low_ports, this_low);
16304           vec_add1 (high_ports, this_hi);
16305         }
16306       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16307         {
16308           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16309             {
16310               errmsg ("incorrect range parameters");
16311               return -99;
16312             }
16313           this_low = tmp;
16314           /* Note: in debug CLI +1 is added to high before
16315              passing to real fn that does "the work"
16316              (ip_source_and_port_range_check_add_del).
16317              This fn is a wrapper around the binary API fn a
16318              control plane will call, which expects this increment
16319              to have occurred. Hence letting the binary API control
16320              plane fn do the increment for consistency between VAT
16321              and other control planes.
16322            */
16323           this_hi = tmp2;
16324           vec_add1 (low_ports, this_low);
16325           vec_add1 (high_ports, this_hi);
16326         }
16327       else
16328         break;
16329     }
16330
16331   if (prefix_set == 0)
16332     {
16333       errmsg ("<address>/<mask> not specified");
16334       return -99;
16335     }
16336
16337   if (vrf_id == ~0)
16338     {
16339       errmsg ("VRF ID required, not specified");
16340       return -99;
16341     }
16342
16343   if (vrf_id == 0)
16344     {
16345       errmsg
16346         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16347       return -99;
16348     }
16349
16350   if (vec_len (low_ports) == 0)
16351     {
16352       errmsg ("At least one port or port range required");
16353       return -99;
16354     }
16355
16356   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16357      ip_source_and_port_range_check_add_del);
16358
16359   mp->is_add = is_add;
16360
16361   if (is_ipv6)
16362     {
16363       mp->is_ipv6 = 1;
16364       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16365     }
16366   else
16367     {
16368       mp->is_ipv6 = 0;
16369       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16370     }
16371
16372   mp->mask_length = length;
16373   mp->number_of_ranges = vec_len (low_ports);
16374
16375   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16376   vec_free (low_ports);
16377
16378   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16379   vec_free (high_ports);
16380
16381   mp->vrf_id = ntohl (vrf_id);
16382
16383   S;
16384   W;
16385   /* NOTREACHED */
16386   return 0;
16387 }
16388
16389 int
16390 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16391 {
16392   unformat_input_t *input = vam->input;
16393   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16394   f64 timeout;
16395   u32 sw_if_index = ~0;
16396   int vrf_set = 0;
16397   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16398   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16399   u8 is_add = 1;
16400
16401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16402     {
16403       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16404         ;
16405       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16406         ;
16407       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16408         vrf_set = 1;
16409       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16410         vrf_set = 1;
16411       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16412         vrf_set = 1;
16413       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16414         vrf_set = 1;
16415       else if (unformat (input, "del"))
16416         is_add = 0;
16417       else
16418         break;
16419     }
16420
16421   if (sw_if_index == ~0)
16422     {
16423       errmsg ("Interface required but not specified");
16424       return -99;
16425     }
16426
16427   if (vrf_set == 0)
16428     {
16429       errmsg ("VRF ID required but not specified");
16430       return -99;
16431     }
16432
16433   if (tcp_out_vrf_id == 0
16434       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16435     {
16436       errmsg
16437         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16438       return -99;
16439     }
16440
16441   /* Construct the API message */
16442   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16443      ip_source_and_port_range_check_interface_add_del);
16444
16445   mp->sw_if_index = ntohl (sw_if_index);
16446   mp->is_add = is_add;
16447   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16448   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16449   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16450   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16451
16452   /* send it... */
16453   S;
16454
16455   /* Wait for a reply... */
16456   W;
16457 }
16458
16459 static int
16460 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16461 {
16462   unformat_input_t *i = vam->input;
16463   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16464   f64 timeout;
16465   u32 local_sa_id = 0;
16466   u32 remote_sa_id = 0;
16467   ip4_address_t src_address;
16468   ip4_address_t dst_address;
16469   u8 is_add = 1;
16470
16471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16472     {
16473       if (unformat (i, "local_sa %d", &local_sa_id))
16474         ;
16475       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16476         ;
16477       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16478         ;
16479       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16480         ;
16481       else if (unformat (i, "del"))
16482         is_add = 0;
16483       else
16484         {
16485           clib_warning ("parse error '%U'", format_unformat_error, i);
16486           return -99;
16487         }
16488     }
16489
16490   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16491
16492   mp->local_sa_id = ntohl (local_sa_id);
16493   mp->remote_sa_id = ntohl (remote_sa_id);
16494   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16495   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16496   mp->is_add = is_add;
16497
16498   S;
16499   W;
16500   /* NOTREACHED */
16501   return 0;
16502 }
16503
16504 static int
16505 api_punt (vat_main_t * vam)
16506 {
16507   unformat_input_t *i = vam->input;
16508   vl_api_punt_t *mp;
16509   f64 timeout;
16510   u32 ipv = ~0;
16511   u32 protocol = ~0;
16512   u32 port = ~0;
16513   int is_add = 1;
16514
16515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (i, "ip %d", &ipv))
16518         ;
16519       else if (unformat (i, "protocol %d", &protocol))
16520         ;
16521       else if (unformat (i, "port %d", &port))
16522         ;
16523       else if (unformat (i, "del"))
16524         is_add = 0;
16525       else
16526         {
16527           clib_warning ("parse error '%U'", format_unformat_error, i);
16528           return -99;
16529         }
16530     }
16531
16532   M (PUNT, punt);
16533
16534   mp->is_add = (u8) is_add;
16535   mp->ipv = (u8) ipv;
16536   mp->l4_protocol = (u8) protocol;
16537   mp->l4_port = htons ((u16) port);
16538
16539   S;
16540   W;
16541   /* NOTREACHED */
16542   return 0;
16543 }
16544
16545 static void vl_api_ipsec_gre_tunnel_details_t_handler
16546   (vl_api_ipsec_gre_tunnel_details_t * mp)
16547 {
16548   vat_main_t *vam = &vat_main;
16549
16550   print (vam->ofp, "%11d%15U%15U%14d%14d",
16551          ntohl (mp->sw_if_index),
16552          format_ip4_address, &mp->src_address,
16553          format_ip4_address, &mp->dst_address,
16554          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16555 }
16556
16557 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16558   (vl_api_ipsec_gre_tunnel_details_t * mp)
16559 {
16560   vat_main_t *vam = &vat_main;
16561   vat_json_node_t *node = NULL;
16562   struct in_addr ip4;
16563
16564   if (VAT_JSON_ARRAY != vam->json_tree.type)
16565     {
16566       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16567       vat_json_init_array (&vam->json_tree);
16568     }
16569   node = vat_json_array_add (&vam->json_tree);
16570
16571   vat_json_init_object (node);
16572   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16573   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16574   vat_json_object_add_ip4 (node, "src_address", ip4);
16575   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16576   vat_json_object_add_ip4 (node, "dst_address", ip4);
16577   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16578   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16579 }
16580
16581 static int
16582 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16583 {
16584   unformat_input_t *i = vam->input;
16585   vl_api_ipsec_gre_tunnel_dump_t *mp;
16586   f64 timeout;
16587   u32 sw_if_index;
16588   u8 sw_if_index_set = 0;
16589
16590   /* Parse args required to build the message */
16591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16592     {
16593       if (unformat (i, "sw_if_index %d", &sw_if_index))
16594         sw_if_index_set = 1;
16595       else
16596         break;
16597     }
16598
16599   if (sw_if_index_set == 0)
16600     {
16601       sw_if_index = ~0;
16602     }
16603
16604   if (!vam->json_output)
16605     {
16606       print (vam->ofp, "%11s%15s%15s%14s%14s",
16607              "sw_if_index", "src_address", "dst_address",
16608              "local_sa_id", "remote_sa_id");
16609     }
16610
16611   /* Get list of gre-tunnel interfaces */
16612   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16613
16614   mp->sw_if_index = htonl (sw_if_index);
16615
16616   S;
16617
16618   /* Use a control ping for synchronization */
16619   {
16620     vl_api_control_ping_t *mp;
16621     M (CONTROL_PING, control_ping);
16622     S;
16623   }
16624   W;
16625 }
16626
16627 static int
16628 api_delete_subif (vat_main_t * vam)
16629 {
16630   unformat_input_t *i = vam->input;
16631   vl_api_delete_subif_t *mp;
16632   f64 timeout;
16633   u32 sw_if_index = ~0;
16634
16635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16636     {
16637       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16638         ;
16639       if (unformat (i, "sw_if_index %d", &sw_if_index))
16640         ;
16641       else
16642         break;
16643     }
16644
16645   if (sw_if_index == ~0)
16646     {
16647       errmsg ("missing sw_if_index");
16648       return -99;
16649     }
16650
16651   /* Construct the API message */
16652   M (DELETE_SUBIF, delete_subif);
16653   mp->sw_if_index = ntohl (sw_if_index);
16654
16655   S;
16656   W;
16657 }
16658
16659 #define foreach_pbb_vtr_op      \
16660 _("disable",  L2_VTR_DISABLED)  \
16661 _("pop",  L2_VTR_POP_2)         \
16662 _("push",  L2_VTR_PUSH_2)
16663
16664 static int
16665 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16666 {
16667   unformat_input_t *i = vam->input;
16668   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16669   f64 timeout;
16670   u32 sw_if_index = ~0, vtr_op = ~0;
16671   u16 outer_tag = ~0;
16672   u8 dmac[6], smac[6];
16673   u8 dmac_set = 0, smac_set = 0;
16674   u16 vlanid = 0;
16675   u32 sid = ~0;
16676   u32 tmp;
16677
16678   /* Shut up coverity */
16679   memset (dmac, 0, sizeof (dmac));
16680   memset (smac, 0, sizeof (smac));
16681
16682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16683     {
16684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16685         ;
16686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16687         ;
16688       else if (unformat (i, "vtr_op %d", &vtr_op))
16689         ;
16690 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16691       foreach_pbb_vtr_op
16692 #undef _
16693         else if (unformat (i, "translate_pbb_stag"))
16694         {
16695           if (unformat (i, "%d", &tmp))
16696             {
16697               vtr_op = L2_VTR_TRANSLATE_2_1;
16698               outer_tag = tmp;
16699             }
16700           else
16701             {
16702               errmsg
16703                 ("translate_pbb_stag operation requires outer tag definition");
16704               return -99;
16705             }
16706         }
16707       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16708         dmac_set++;
16709       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16710         smac_set++;
16711       else if (unformat (i, "sid %d", &sid))
16712         ;
16713       else if (unformat (i, "vlanid %d", &tmp))
16714         vlanid = tmp;
16715       else
16716         {
16717           clib_warning ("parse error '%U'", format_unformat_error, i);
16718           return -99;
16719         }
16720     }
16721
16722   if ((sw_if_index == ~0) || (vtr_op == ~0))
16723     {
16724       errmsg ("missing sw_if_index or vtr operation");
16725       return -99;
16726     }
16727   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16728       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16729     {
16730       errmsg
16731         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16732       return -99;
16733     }
16734
16735   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16736   mp->sw_if_index = ntohl (sw_if_index);
16737   mp->vtr_op = ntohl (vtr_op);
16738   mp->outer_tag = ntohs (outer_tag);
16739   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16740   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16741   mp->b_vlanid = ntohs (vlanid);
16742   mp->i_sid = ntohl (sid);
16743
16744   S;
16745   W;
16746   /* NOTREACHED */
16747   return 0;
16748 }
16749
16750 static int
16751 api_flow_classify_set_interface (vat_main_t * vam)
16752 {
16753   unformat_input_t *i = vam->input;
16754   vl_api_flow_classify_set_interface_t *mp;
16755   f64 timeout;
16756   u32 sw_if_index;
16757   int sw_if_index_set;
16758   u32 ip4_table_index = ~0;
16759   u32 ip6_table_index = ~0;
16760   u8 is_add = 1;
16761
16762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16763     {
16764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16765         sw_if_index_set = 1;
16766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16767         sw_if_index_set = 1;
16768       else if (unformat (i, "del"))
16769         is_add = 0;
16770       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16771         ;
16772       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16773         ;
16774       else
16775         {
16776           clib_warning ("parse error '%U'", format_unformat_error, i);
16777           return -99;
16778         }
16779     }
16780
16781   if (sw_if_index_set == 0)
16782     {
16783       errmsg ("missing interface name or sw_if_index");
16784       return -99;
16785     }
16786
16787   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16788
16789   mp->sw_if_index = ntohl (sw_if_index);
16790   mp->ip4_table_index = ntohl (ip4_table_index);
16791   mp->ip6_table_index = ntohl (ip6_table_index);
16792   mp->is_add = is_add;
16793
16794   S;
16795   W;
16796   /* NOTREACHED */
16797   return 0;
16798 }
16799
16800 static int
16801 api_flow_classify_dump (vat_main_t * vam)
16802 {
16803   unformat_input_t *i = vam->input;
16804   vl_api_flow_classify_dump_t *mp;
16805   f64 timeout = ~0;
16806   u8 type = FLOW_CLASSIFY_N_TABLES;
16807
16808   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16809     ;
16810   else
16811     {
16812       errmsg ("classify table type must be specified");
16813       return -99;
16814     }
16815
16816   if (!vam->json_output)
16817     {
16818       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16819     }
16820
16821   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16822   mp->type = type;
16823   /* send it... */
16824   S;
16825
16826   /* Use a control ping for synchronization */
16827   {
16828     vl_api_control_ping_t *mp;
16829     M (CONTROL_PING, control_ping);
16830     S;
16831   }
16832   /* Wait for a reply... */
16833   W;
16834
16835   /* NOTREACHED */
16836   return 0;
16837 }
16838
16839 static int
16840 api_feature_enable_disable (vat_main_t * vam)
16841 {
16842   unformat_input_t *i = vam->input;
16843   vl_api_feature_enable_disable_t *mp;
16844   f64 timeout;
16845   u8 *arc_name = 0;
16846   u8 *feature_name = 0;
16847   u32 sw_if_index = ~0;
16848   u8 enable = 1;
16849
16850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16851     {
16852       if (unformat (i, "arc_name %s", &arc_name))
16853         ;
16854       else if (unformat (i, "feature_name %s", &feature_name))
16855         ;
16856       else
16857         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16858         ;
16859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16860         ;
16861       else if (unformat (i, "disable"))
16862         enable = 0;
16863       else
16864         break;
16865     }
16866
16867   if (arc_name == 0)
16868     {
16869       errmsg ("missing arc name");
16870       return -99;
16871     }
16872   if (vec_len (arc_name) > 63)
16873     {
16874       errmsg ("arc name too long");
16875     }
16876
16877   if (feature_name == 0)
16878     {
16879       errmsg ("missing feature name");
16880       return -99;
16881     }
16882   if (vec_len (feature_name) > 63)
16883     {
16884       errmsg ("feature name too long");
16885     }
16886
16887   if (sw_if_index == ~0)
16888     {
16889       errmsg ("missing interface name or sw_if_index");
16890       return -99;
16891     }
16892
16893   /* Construct the API message */
16894   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16895   mp->sw_if_index = ntohl (sw_if_index);
16896   mp->enable = enable;
16897   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16898   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16899   vec_free (arc_name);
16900   vec_free (feature_name);
16901
16902   S;
16903   W;
16904 }
16905
16906 static int
16907 api_sw_interface_tag_add_del (vat_main_t * vam)
16908 {
16909   unformat_input_t *i = vam->input;
16910   vl_api_sw_interface_tag_add_del_t *mp;
16911   f64 timeout;
16912   u32 sw_if_index = ~0;
16913   u8 *tag = 0;
16914   u8 enable = 1;
16915
16916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16917     {
16918       if (unformat (i, "tag %s", &tag))
16919         ;
16920       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16921         ;
16922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16923         ;
16924       else if (unformat (i, "del"))
16925         enable = 0;
16926       else
16927         break;
16928     }
16929
16930   if (sw_if_index == ~0)
16931     {
16932       errmsg ("missing interface name or sw_if_index");
16933       return -99;
16934     }
16935
16936   if (enable && (tag == 0))
16937     {
16938       errmsg ("no tag specified");
16939       return -99;
16940     }
16941
16942   /* Construct the API message */
16943   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16944   mp->sw_if_index = ntohl (sw_if_index);
16945   mp->is_add = enable;
16946   if (enable)
16947     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16948   vec_free (tag);
16949
16950   S;
16951   W;
16952 }
16953
16954 static void vl_api_l2_xconnect_details_t_handler
16955   (vl_api_l2_xconnect_details_t * mp)
16956 {
16957   vat_main_t *vam = &vat_main;
16958
16959   print (vam->ofp, "%15d%15d",
16960          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16961 }
16962
16963 static void vl_api_l2_xconnect_details_t_handler_json
16964   (vl_api_l2_xconnect_details_t * mp)
16965 {
16966   vat_main_t *vam = &vat_main;
16967   vat_json_node_t *node = NULL;
16968
16969   if (VAT_JSON_ARRAY != vam->json_tree.type)
16970     {
16971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16972       vat_json_init_array (&vam->json_tree);
16973     }
16974   node = vat_json_array_add (&vam->json_tree);
16975
16976   vat_json_init_object (node);
16977   vat_json_object_add_uint (node, "rx_sw_if_index",
16978                             ntohl (mp->rx_sw_if_index));
16979   vat_json_object_add_uint (node, "tx_sw_if_index",
16980                             ntohl (mp->tx_sw_if_index));
16981 }
16982
16983 static int
16984 api_l2_xconnect_dump (vat_main_t * vam)
16985 {
16986   vl_api_l2_xconnect_dump_t *mp;
16987   f64 timeout;
16988
16989   if (!vam->json_output)
16990     {
16991       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
16992     }
16993
16994   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16995
16996   S;
16997
16998   /* Use a control ping for synchronization */
16999   {
17000     vl_api_control_ping_t *mp;
17001     M (CONTROL_PING, control_ping);
17002     S;
17003   }
17004   W;
17005 }
17006
17007 static int
17008 api_sw_interface_set_mtu (vat_main_t * vam)
17009 {
17010   unformat_input_t *i = vam->input;
17011   vl_api_sw_interface_set_mtu_t *mp;
17012   f64 timeout;
17013   u32 sw_if_index = ~0;
17014   u32 mtu = 0;
17015
17016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17017     {
17018       if (unformat (i, "mtu %d", &mtu))
17019         ;
17020       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17021         ;
17022       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17023         ;
17024       else
17025         break;
17026     }
17027
17028   if (sw_if_index == ~0)
17029     {
17030       errmsg ("missing interface name or sw_if_index");
17031       return -99;
17032     }
17033
17034   if (mtu == 0)
17035     {
17036       errmsg ("no mtu specified");
17037       return -99;
17038     }
17039
17040   /* Construct the API message */
17041   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17042   mp->sw_if_index = ntohl (sw_if_index);
17043   mp->mtu = ntohs ((u16) mtu);
17044
17045   S;
17046   W;
17047 }
17048
17049
17050 static int
17051 q_or_quit (vat_main_t * vam)
17052 {
17053   longjmp (vam->jump_buf, 1);
17054   return 0;                     /* not so much */
17055 }
17056
17057 static int
17058 q (vat_main_t * vam)
17059 {
17060   return q_or_quit (vam);
17061 }
17062
17063 static int
17064 quit (vat_main_t * vam)
17065 {
17066   return q_or_quit (vam);
17067 }
17068
17069 static int
17070 comment (vat_main_t * vam)
17071 {
17072   return 0;
17073 }
17074
17075 static int
17076 cmd_cmp (void *a1, void *a2)
17077 {
17078   u8 **c1 = a1;
17079   u8 **c2 = a2;
17080
17081   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17082 }
17083
17084 static int
17085 help (vat_main_t * vam)
17086 {
17087   u8 **cmds = 0;
17088   u8 *name = 0;
17089   hash_pair_t *p;
17090   unformat_input_t *i = vam->input;
17091   int j;
17092
17093   if (unformat (i, "%s", &name))
17094     {
17095       uword *hs;
17096
17097       vec_add1 (name, 0);
17098
17099       hs = hash_get_mem (vam->help_by_name, name);
17100       if (hs)
17101         print (vam->ofp, "usage: %s %s", name, hs[0]);
17102       else
17103         print (vam->ofp, "No such msg / command '%s'", name);
17104       vec_free (name);
17105       return 0;
17106     }
17107
17108   print (vam->ofp, "Help is available for the following:");
17109
17110     /* *INDENT-OFF* */
17111     hash_foreach_pair (p, vam->function_by_name,
17112     ({
17113       vec_add1 (cmds, (u8 *)(p->key));
17114     }));
17115     /* *INDENT-ON* */
17116
17117   vec_sort_with_function (cmds, cmd_cmp);
17118
17119   for (j = 0; j < vec_len (cmds); j++)
17120     print (vam->ofp, "%s", cmds[j]);
17121
17122   vec_free (cmds);
17123   return 0;
17124 }
17125
17126 static int
17127 set (vat_main_t * vam)
17128 {
17129   u8 *name = 0, *value = 0;
17130   unformat_input_t *i = vam->input;
17131
17132   if (unformat (i, "%s", &name))
17133     {
17134       /* The input buffer is a vector, not a string. */
17135       value = vec_dup (i->buffer);
17136       vec_delete (value, i->index, 0);
17137       /* Almost certainly has a trailing newline */
17138       if (value[vec_len (value) - 1] == '\n')
17139         value[vec_len (value) - 1] = 0;
17140       /* Make sure it's a proper string, one way or the other */
17141       vec_add1 (value, 0);
17142       (void) clib_macro_set_value (&vam->macro_main,
17143                                    (char *) name, (char *) value);
17144     }
17145   else
17146     errmsg ("usage: set <name> <value>");
17147
17148   vec_free (name);
17149   vec_free (value);
17150   return 0;
17151 }
17152
17153 static int
17154 unset (vat_main_t * vam)
17155 {
17156   u8 *name = 0;
17157
17158   if (unformat (vam->input, "%s", &name))
17159     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17160       errmsg ("unset: %s wasn't set", name);
17161   vec_free (name);
17162   return 0;
17163 }
17164
17165 typedef struct
17166 {
17167   u8 *name;
17168   u8 *value;
17169 } macro_sort_t;
17170
17171
17172 static int
17173 macro_sort_cmp (void *a1, void *a2)
17174 {
17175   macro_sort_t *s1 = a1;
17176   macro_sort_t *s2 = a2;
17177
17178   return strcmp ((char *) (s1->name), (char *) (s2->name));
17179 }
17180
17181 static int
17182 dump_macro_table (vat_main_t * vam)
17183 {
17184   macro_sort_t *sort_me = 0, *sm;
17185   int i;
17186   hash_pair_t *p;
17187
17188     /* *INDENT-OFF* */
17189     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17190     ({
17191       vec_add2 (sort_me, sm, 1);
17192       sm->name = (u8 *)(p->key);
17193       sm->value = (u8 *) (p->value[0]);
17194     }));
17195     /* *INDENT-ON* */
17196
17197   vec_sort_with_function (sort_me, macro_sort_cmp);
17198
17199   if (vec_len (sort_me))
17200     print (vam->ofp, "%-15s%s", "Name", "Value");
17201   else
17202     print (vam->ofp, "The macro table is empty...");
17203
17204   for (i = 0; i < vec_len (sort_me); i++)
17205     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17206   return 0;
17207 }
17208
17209 static int
17210 dump_node_table (vat_main_t * vam)
17211 {
17212   int i, j;
17213   vlib_node_t *node, *next_node;
17214
17215   if (vec_len (vam->graph_nodes) == 0)
17216     {
17217       print (vam->ofp, "Node table empty, issue get_node_graph...");
17218       return 0;
17219     }
17220
17221   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17222     {
17223       node = vam->graph_nodes[i];
17224       print (vam->ofp, "[%d] %s", i, node->name);
17225       for (j = 0; j < vec_len (node->next_nodes); j++)
17226         {
17227           if (node->next_nodes[j] != ~0)
17228             {
17229               next_node = vam->graph_nodes[node->next_nodes[j]];
17230               print (vam->ofp, "  [%d] %s", j, next_node->name);
17231             }
17232         }
17233     }
17234   return 0;
17235 }
17236
17237 static int
17238 value_sort_cmp (void *a1, void *a2)
17239 {
17240   name_sort_t *n1 = a1;
17241   name_sort_t *n2 = a2;
17242
17243   if (n1->value < n2->value)
17244     return -1;
17245   if (n1->value > n2->value)
17246     return 1;
17247   return 0;
17248 }
17249
17250
17251 static int
17252 dump_msg_api_table (vat_main_t * vam)
17253 {
17254   api_main_t *am = &api_main;
17255   name_sort_t *nses = 0, *ns;
17256   hash_pair_t *hp;
17257   int i;
17258
17259   /* *INDENT-OFF* */
17260   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17261   ({
17262     vec_add2 (nses, ns, 1);
17263     ns->name = (u8 *)(hp->key);
17264     ns->value = (u32) hp->value[0];
17265   }));
17266   /* *INDENT-ON* */
17267
17268   vec_sort_with_function (nses, value_sort_cmp);
17269
17270   for (i = 0; i < vec_len (nses); i++)
17271     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17272   vec_free (nses);
17273   return 0;
17274 }
17275
17276 static int
17277 get_msg_id (vat_main_t * vam)
17278 {
17279   u8 *name_and_crc;
17280   u32 message_index;
17281
17282   if (unformat (vam->input, "%s", &name_and_crc))
17283     {
17284       message_index = vl_api_get_msg_index (name_and_crc);
17285       if (message_index == ~0)
17286         {
17287           print (vam->ofp, " '%s' not found", name_and_crc);
17288           return 0;
17289         }
17290       print (vam->ofp, " '%s' has message index %d",
17291              name_and_crc, message_index);
17292       return 0;
17293     }
17294   errmsg ("name_and_crc required...");
17295   return 0;
17296 }
17297
17298 static int
17299 search_node_table (vat_main_t * vam)
17300 {
17301   unformat_input_t *line_input = vam->input;
17302   u8 *node_to_find;
17303   int j;
17304   vlib_node_t *node, *next_node;
17305   uword *p;
17306
17307   if (vam->graph_node_index_by_name == 0)
17308     {
17309       print (vam->ofp, "Node table empty, issue get_node_graph...");
17310       return 0;
17311     }
17312
17313   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17314     {
17315       if (unformat (line_input, "%s", &node_to_find))
17316         {
17317           vec_add1 (node_to_find, 0);
17318           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17319           if (p == 0)
17320             {
17321               print (vam->ofp, "%s not found...", node_to_find);
17322               goto out;
17323             }
17324           node = vam->graph_nodes[p[0]];
17325           print (vam->ofp, "[%d] %s", p[0], node->name);
17326           for (j = 0; j < vec_len (node->next_nodes); j++)
17327             {
17328               if (node->next_nodes[j] != ~0)
17329                 {
17330                   next_node = vam->graph_nodes[node->next_nodes[j]];
17331                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17332                 }
17333             }
17334         }
17335
17336       else
17337         {
17338           clib_warning ("parse error '%U'", format_unformat_error,
17339                         line_input);
17340           return -99;
17341         }
17342
17343     out:
17344       vec_free (node_to_find);
17345
17346     }
17347
17348   return 0;
17349 }
17350
17351
17352 static int
17353 script (vat_main_t * vam)
17354 {
17355 #if (VPP_API_TEST_BUILTIN==0)
17356   u8 *s = 0;
17357   char *save_current_file;
17358   unformat_input_t save_input;
17359   jmp_buf save_jump_buf;
17360   u32 save_line_number;
17361
17362   FILE *new_fp, *save_ifp;
17363
17364   if (unformat (vam->input, "%s", &s))
17365     {
17366       new_fp = fopen ((char *) s, "r");
17367       if (new_fp == 0)
17368         {
17369           errmsg ("Couldn't open script file %s", s);
17370           vec_free (s);
17371           return -99;
17372         }
17373     }
17374   else
17375     {
17376       errmsg ("Missing script name");
17377       return -99;
17378     }
17379
17380   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17381   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17382   save_ifp = vam->ifp;
17383   save_line_number = vam->input_line_number;
17384   save_current_file = (char *) vam->current_file;
17385
17386   vam->input_line_number = 0;
17387   vam->ifp = new_fp;
17388   vam->current_file = s;
17389   do_one_file (vam);
17390
17391   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17392   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17393   vam->ifp = save_ifp;
17394   vam->input_line_number = save_line_number;
17395   vam->current_file = (u8 *) save_current_file;
17396   vec_free (s);
17397
17398   return 0;
17399 #else
17400   clib_warning ("use the exec command...");
17401   return -99;
17402 #endif
17403 }
17404
17405 static int
17406 echo (vat_main_t * vam)
17407 {
17408   print (vam->ofp, "%v", vam->input->buffer);
17409   return 0;
17410 }
17411
17412 /* List of API message constructors, CLI names map to api_xxx */
17413 #define foreach_vpe_api_msg                                             \
17414 _(create_loopback,"[mac <mac-addr>]")                                   \
17415 _(sw_interface_dump,"")                                                 \
17416 _(sw_interface_set_flags,                                               \
17417   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17418 _(sw_interface_add_del_address,                                         \
17419   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17420 _(sw_interface_set_table,                                               \
17421   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17422 _(sw_interface_set_mpls_enable,                                         \
17423   "<intfc> | sw_if_index [disable | dis]")                              \
17424 _(sw_interface_set_vpath,                                               \
17425   "<intfc> | sw_if_index <id> enable | disable")                        \
17426 _(sw_interface_set_vxlan_bypass,                                        \
17427   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17428 _(sw_interface_set_l2_xconnect,                                         \
17429   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17430   "enable | disable")                                                   \
17431 _(sw_interface_set_l2_bridge,                                           \
17432   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17433   "[shg <split-horizon-group>] [bvi]\n"                                 \
17434   "enable | disable")                                                   \
17435 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17436   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17437   "profile <profile-id>\n")                                             \
17438 _(sw_interface_set_dpdk_hqos_subport,                                   \
17439   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17440   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17441 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17442   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17443 _(bridge_domain_add_del,                                                \
17444   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17445 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17446 _(l2fib_add_del,                                                        \
17447   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17448 _(l2_flags,                                                             \
17449   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17450 _(bridge_flags,                                                         \
17451   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17452 _(tap_connect,                                                          \
17453   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17454 _(tap_modify,                                                           \
17455   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17456 _(tap_delete,                                                           \
17457   "<vpp-if-name> | sw_if_index <id>")                                   \
17458 _(sw_interface_tap_dump, "")                                            \
17459 _(ip_add_del_route,                                                     \
17460   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17461   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17462   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17463   "[multipath] [count <n>]")                                            \
17464 _(mpls_route_add_del,                                                   \
17465   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17466   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17467   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17468   "[multipath] [count <n>]")                                            \
17469 _(mpls_ip_bind_unbind,                                                  \
17470   "<label> <addr/len>")                                                 \
17471 _(mpls_tunnel_add_del,                                                  \
17472   " via <addr> [table-id <n>]\n"                                        \
17473   "sw_if_index <id>] [l2]  [del]")                                      \
17474 _(proxy_arp_add_del,                                                    \
17475   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17476 _(proxy_arp_intfc_enable_disable,                                       \
17477   "<intfc> | sw_if_index <id> enable | disable")                        \
17478 _(sw_interface_set_unnumbered,                                          \
17479   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17480 _(ip_neighbor_add_del,                                                  \
17481   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17482   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17483 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17484 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17485 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17486   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17487   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17488   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17489 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17490 _(reset_fib, "vrf <n> [ipv6]")                                          \
17491 _(dhcp_proxy_config,                                                    \
17492   "svr <v46-address> src <v46-address>\n"                               \
17493    "insert-cid <n> [del]")                                              \
17494 _(dhcp_proxy_config_2,                                                  \
17495   "svr <v46-address> src <v46-address>\n"                               \
17496    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17497 _(dhcp_proxy_set_vss,                                                   \
17498   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17499 _(dhcp_client_config,                                                   \
17500   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17501 _(set_ip_flow_hash,                                                     \
17502   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17503 _(sw_interface_ip6_enable_disable,                                      \
17504   "<intfc> | sw_if_index <id> enable | disable")                        \
17505 _(sw_interface_ip6_set_link_local_address,                              \
17506   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17507 _(sw_interface_ip6nd_ra_prefix,                                         \
17508   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17509   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17510   "[nolink] [isno]")                                                    \
17511 _(sw_interface_ip6nd_ra_config,                                         \
17512   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17513   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17514   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17515 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17516 _(l2_patch_add_del,                                                     \
17517   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17518   "enable | disable")                                                   \
17519 _(sr_tunnel_add_del,                                                    \
17520   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17521   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17522   "[policy <policy_name>]")                                             \
17523 _(sr_policy_add_del,                                                    \
17524   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17525 _(sr_multicast_map_add_del,                                             \
17526   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17527 _(classify_add_del_table,                                               \
17528   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17529   " [del] [del-chain] mask <mask-value>\n"                              \
17530   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17531   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17532 _(classify_add_del_session,                                             \
17533   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17534   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17535   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17536   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17537 _(classify_set_interface_ip_table,                                      \
17538   "<intfc> | sw_if_index <nn> table <nn>")                              \
17539 _(classify_set_interface_l2_tables,                                     \
17540   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17541   "  [other-table <nn>]")                                               \
17542 _(get_node_index, "node <node-name")                                    \
17543 _(add_node_next, "node <node-name> next <next-node-name>")              \
17544 _(l2tpv3_create_tunnel,                                                 \
17545   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17546   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17547   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17548 _(l2tpv3_set_tunnel_cookies,                                            \
17549   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17550   "[new_remote_cookie <nn>]\n")                                         \
17551 _(l2tpv3_interface_enable_disable,                                      \
17552   "<intfc> | sw_if_index <nn> enable | disable")                        \
17553 _(l2tpv3_set_lookup_key,                                                \
17554   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17555 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17556 _(vxlan_add_del_tunnel,                                                 \
17557   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17558   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17559   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17560 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17561 _(gre_add_del_tunnel,                                                   \
17562   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17563 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17564 _(l2_fib_clear_table, "")                                               \
17565 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17566 _(l2_interface_vlan_tag_rewrite,                                        \
17567   "<intfc> | sw_if_index <nn> \n"                                       \
17568   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17569   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17570 _(create_vhost_user_if,                                                 \
17571         "socket <filename> [server] [renumber <dev_instance>] "         \
17572         "[mac <mac_address>]")                                          \
17573 _(modify_vhost_user_if,                                                 \
17574         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17575         "[server] [renumber <dev_instance>]")                           \
17576 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17577 _(sw_interface_vhost_user_dump, "")                                     \
17578 _(show_version, "")                                                     \
17579 _(vxlan_gpe_add_del_tunnel,                                             \
17580   "local <addr> remote <addr> vni <nn>\n"                               \
17581     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17582   "[next-ethernet] [next-nsh]\n")                                       \
17583 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17584 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17585 _(interface_name_renumber,                                              \
17586   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17587 _(input_acl_set_interface,                                              \
17588   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17589   "  [l2-table <nn>] [del]")                                            \
17590 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17591 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17592 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17593 _(ip_dump, "ipv4 | ipv6")                                               \
17594 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17595 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17596   "  spid_id <n> ")                                                     \
17597 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17598   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17599   "  integ_alg <alg> integ_key <hex>")                                  \
17600 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17601   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17602   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17603   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17604 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17605 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17606 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17607   "(auth_data 0x<data> | auth_data <data>)")                            \
17608 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17609   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17610 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17611   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17612   "(local|remote)")                                                     \
17613 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17614 _(delete_loopback,"sw_if_index <nn>")                                   \
17615 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17616 _(map_add_domain,                                                       \
17617   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17618   "ip6-src <ip6addr> "                                                  \
17619   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17620 _(map_del_domain, "index <n>")                                          \
17621 _(map_add_del_rule,                                                     \
17622   "index <n> psid <n> dst <ip6addr> [del]")                             \
17623 _(map_domain_dump, "")                                                  \
17624 _(map_rule_dump, "index <map-domain>")                                  \
17625 _(want_interface_events,  "enable|disable")                             \
17626 _(want_stats,"enable|disable")                                          \
17627 _(get_first_msg_id, "client <name>")                                    \
17628 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17629 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17630   "fib-id <nn> [ip4][ip6][default]")                                    \
17631 _(get_node_graph, " ")                                                  \
17632 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17633 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17634 _(ioam_disable, "")                                                     \
17635 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17636                             " sw_if_index <sw_if_index> p <priority> "  \
17637                             "w <weight>] [del]")                        \
17638 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17639                         "iface <intf> | sw_if_index <sw_if_index> "     \
17640                         "p <priority> w <weight> [del]")                \
17641 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17642                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17643                          "locator-set <locator_name> [del]"             \
17644                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17645 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17646   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17647 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17648 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17649 _(lisp_gpe_enable_disable, "enable|disable")                            \
17650 _(lisp_enable_disable, "enable|disable")                                \
17651 _(lisp_map_register_enable_disable, "enable|disable")                   \
17652 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17653 _(lisp_gpe_add_del_iface, "up|down")                                    \
17654 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17655                                "[seid <seid>] "                         \
17656                                "rloc <locator> p <prio> "               \
17657                                "w <weight> [rloc <loc> ... ] "          \
17658                                "action <action> [del-all]")             \
17659 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17660                           "<local-eid>")                                \
17661 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17662 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17663 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17664 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17665 _(lisp_locator_set_dump, "[local | remote]")                            \
17666 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17667 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17668                        "[local] | [remote]")                            \
17669 _(lisp_eid_table_vni_dump, "")                                          \
17670 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17671 _(lisp_gpe_tunnel_dump, "")                                             \
17672 _(lisp_map_resolver_dump, "")                                           \
17673 _(lisp_map_server_dump, "")                                             \
17674 _(lisp_adjacencies_get, "vni <vni>")                                    \
17675 _(show_lisp_rloc_probe_state, "")                                       \
17676 _(show_lisp_map_register_state, "")                                     \
17677 _(show_lisp_status, "")                                                 \
17678 _(lisp_get_map_request_itr_rlocs, "")                                   \
17679 _(show_lisp_pitr, "")                                                   \
17680 _(show_lisp_map_request_mode, "")                                       \
17681 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17682 _(af_packet_delete, "name <host interface name>")                       \
17683 _(policer_add_del, "name <policer name> <params> [del]")                \
17684 _(policer_dump, "[name <policer name>]")                                \
17685 _(policer_classify_set_interface,                                       \
17686   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17687   "  [l2-table <nn>] [del]")                                            \
17688 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17689 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17690     "[master|slave]")                                                   \
17691 _(netmap_delete, "name <interface name>")                               \
17692 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17693 _(mpls_fib_dump, "")                                                    \
17694 _(classify_table_ids, "")                                               \
17695 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17696 _(classify_table_info, "table_id <nn>")                                 \
17697 _(classify_session_dump, "table_id <nn>")                               \
17698 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17699     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17700     "[template_interval <nn>] [udp_checksum]")                          \
17701 _(ipfix_exporter_dump, "")                                              \
17702 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17703 _(ipfix_classify_stream_dump, "")                                       \
17704 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17705 _(ipfix_classify_table_dump, "")                                        \
17706 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17707 _(sw_interface_span_dump, "")                                           \
17708 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17709 _(pg_create_interface, "if_id <nn>")                                    \
17710 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17711 _(pg_enable_disable, "[stream <id>] disable")                           \
17712 _(ip_source_and_port_range_check_add_del,                               \
17713   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17714 _(ip_source_and_port_range_check_interface_add_del,                     \
17715   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17716   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17717 _(ipsec_gre_add_del_tunnel,                                             \
17718   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17719 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17720 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17721 _(l2_interface_pbb_tag_rewrite,                                         \
17722   "<intfc> | sw_if_index <nn> \n"                                       \
17723   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17724   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17725 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17726 _(flow_classify_set_interface,                                          \
17727   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17728 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17729 _(ip_fib_dump, "")                                                      \
17730 _(ip6_fib_dump, "")                                                     \
17731 _(feature_enable_disable, "arc_name <arc_name> "                        \
17732   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17733 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17734 "[disable]")                                                            \
17735 _(l2_xconnect_dump, "")                                                 \
17736 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17737 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17738 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17739
17740 /* List of command functions, CLI names map directly to functions */
17741 #define foreach_cli_function                                    \
17742 _(comment, "usage: comment <ignore-rest-of-line>")              \
17743 _(dump_interface_table, "usage: dump_interface_table")          \
17744 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17745 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17746 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17747 _(dump_stats_table, "usage: dump_stats_table")                  \
17748 _(dump_macro_table, "usage: dump_macro_table ")                 \
17749 _(dump_node_table, "usage: dump_node_table")                    \
17750 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17751 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17752 _(echo, "usage: echo <message>")                                \
17753 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17754 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17755 _(help, "usage: help")                                          \
17756 _(q, "usage: quit")                                             \
17757 _(quit, "usage: quit")                                          \
17758 _(search_node_table, "usage: search_node_table <name>...")      \
17759 _(set, "usage: set <variable-name> <value>")                    \
17760 _(script, "usage: script <file-name>")                          \
17761 _(unset, "usage: unset <variable-name>")
17762
17763 #define _(N,n)                                  \
17764     static void vl_api_##n##_t_handler_uni      \
17765     (vl_api_##n##_t * mp)                       \
17766     {                                           \
17767         vat_main_t * vam = &vat_main;           \
17768         if (vam->json_output) {                 \
17769             vl_api_##n##_t_handler_json(mp);    \
17770         } else {                                \
17771             vl_api_##n##_t_handler(mp);         \
17772         }                                       \
17773     }
17774 foreach_vpe_api_reply_msg;
17775 #undef _
17776
17777 void
17778 vat_api_hookup (vat_main_t * vam)
17779 {
17780 #define _(N,n)                                                  \
17781     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17782                            vl_api_##n##_t_handler_uni,          \
17783                            vl_noop_handler,                     \
17784                            vl_api_##n##_t_endian,               \
17785                            vl_api_##n##_t_print,                \
17786                            sizeof(vl_api_##n##_t), 1);
17787   foreach_vpe_api_reply_msg;
17788 #undef _
17789
17790 #if (VPP_API_TEST_BUILTIN==0)
17791   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17792 #endif
17793
17794   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17795
17796   vam->function_by_name = hash_create_string (0, sizeof (uword));
17797
17798   vam->help_by_name = hash_create_string (0, sizeof (uword));
17799
17800   /* API messages we can send */
17801 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17802   foreach_vpe_api_msg;
17803 #undef _
17804
17805   /* Help strings */
17806 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17807   foreach_vpe_api_msg;
17808 #undef _
17809
17810   /* CLI functions */
17811 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17812   foreach_cli_function;
17813 #undef _
17814
17815   /* Help strings */
17816 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17817   foreach_cli_function;
17818 #undef _
17819 }
17820
17821 /*
17822  * fd.io coding-style-patch-verification: ON
17823  *
17824  * Local Variables:
17825  * eval: (c-set-style "gnu")
17826  * End:
17827  */