Add signal handling
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void
1319 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_l2_flags_reply_t_handler_json
1335   (vl_api_l2_flags_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1343                             ntohl (mp->resulting_feature_bitmap));
1344
1345   vat_json_print (vam->ofp, &node);
1346   vat_json_free (&node);
1347
1348   vam->retval = ntohl (mp->retval);
1349   vam->result_ready = 1;
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_bridge_flags_reply_t_handler_json
1369   (vl_api_bridge_flags_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   vat_json_node_t node;
1373
1374   vat_json_init_object (&node);
1375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1376   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1377                             ntohl (mp->resulting_feature_bitmap));
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_tap_connect_reply_t_handler
1387   (vl_api_tap_connect_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->sw_if_index = ntohl (mp->sw_if_index);
1399       vam->result_ready = 1;
1400     }
1401
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler_json
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409
1410   vat_json_init_object (&node);
1411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = ntohl (mp->retval);
1418   vam->result_ready = 1;
1419
1420 }
1421
1422 static void
1423 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   i32 retval = ntohl (mp->retval);
1427   if (vam->async_mode)
1428     {
1429       vam->async_errors += (retval < 0);
1430     }
1431   else
1432     {
1433       vam->retval = retval;
1434       vam->sw_if_index = ntohl (mp->sw_if_index);
1435       vam->result_ready = 1;
1436     }
1437 }
1438
1439 static void vl_api_tap_modify_reply_t_handler_json
1440   (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   vat_json_node_t node;
1444
1445   vat_json_init_object (&node);
1446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1448
1449   vat_json_print (vam->ofp, &node);
1450   vat_json_free (&node);
1451
1452   vam->retval = ntohl (mp->retval);
1453   vam->result_ready = 1;
1454 }
1455
1456 static void
1457 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   i32 retval = ntohl (mp->retval);
1461   if (vam->async_mode)
1462     {
1463       vam->async_errors += (retval < 0);
1464     }
1465   else
1466     {
1467       vam->retval = retval;
1468       vam->result_ready = 1;
1469     }
1470 }
1471
1472 static void vl_api_tap_delete_reply_t_handler_json
1473   (vl_api_tap_delete_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   vat_json_node_t node;
1477
1478   vat_json_init_object (&node);
1479   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->result_ready = 1;
1501     }
1502 }
1503
1504 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1505   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t node;
1509
1510   vat_json_init_object (&node);
1511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1512   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1513                             ntohl (mp->tunnel_sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520 }
1521
1522 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1523   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->sw_if_index = ntohl (mp->sw_if_index);
1535       vam->result_ready = 1;
1536     }
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t node;
1544
1545   vat_json_init_object (&node);
1546   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1547   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1548
1549   vat_json_print (vam->ofp, &node);
1550   vat_json_free (&node);
1551
1552   vam->retval = ntohl (mp->retval);
1553   vam->result_ready = 1;
1554 }
1555
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1574   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1591   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->sw_if_index = ntohl (mp->sw_if_index);
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_gre_add_del_tunnel_reply_t_handler
1625   (vl_api_gre_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_create_vhost_user_if_reply_t_handler
1659   (vl_api_create_vhost_user_if_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler_json
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_ip_address_details_t_handler
1693   (vl_api_ip_address_details_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   static ip_address_details_t empty_ip_address_details = { {0} };
1697   ip_address_details_t *address = NULL;
1698   ip_details_t *current_ip_details = NULL;
1699   ip_details_t *details = NULL;
1700
1701   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1702
1703   if (!details || vam->current_sw_if_index >= vec_len (details)
1704       || !details[vam->current_sw_if_index].present)
1705     {
1706       errmsg ("ip address details arrived but not stored\n");
1707       errmsg ("ip_dump should be called first\n");
1708       return;
1709     }
1710
1711   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1712
1713 #define addresses (current_ip_details->addr)
1714
1715   vec_validate_init_empty (addresses, vec_len (addresses),
1716                            empty_ip_address_details);
1717
1718   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1719
1720   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1721   address->prefix_length = mp->prefix_length;
1722 #undef addresses
1723 }
1724
1725 static void vl_api_ip_address_details_t_handler_json
1726   (vl_api_ip_address_details_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t *node = NULL;
1730   struct in6_addr ip6;
1731   struct in_addr ip4;
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   node = vat_json_array_add (&vam->json_tree);
1739
1740   vat_json_init_object (node);
1741   if (vam->is_ipv6)
1742     {
1743       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1744       vat_json_object_add_ip6 (node, "ip", ip6);
1745     }
1746   else
1747     {
1748       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1749       vat_json_object_add_ip4 (node, "ip", ip4);
1750     }
1751   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1752 }
1753
1754 static void
1755 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   static ip_details_t empty_ip_details = { 0 };
1759   ip_details_t *ip = NULL;
1760   u32 sw_if_index = ~0;
1761
1762   sw_if_index = ntohl (mp->sw_if_index);
1763
1764   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1765                            sw_if_index, empty_ip_details);
1766
1767   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1768                          sw_if_index);
1769
1770   ip->present = 1;
1771 }
1772
1773 static void
1774 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   vat_json_array_add_uint (&vam->json_tree,
1784                            clib_net_to_host_u32 (mp->sw_if_index));
1785 }
1786
1787 static void vl_api_map_domain_details_t_handler_json
1788   (vl_api_map_domain_details_t * mp)
1789 {
1790   vat_json_node_t *node = NULL;
1791   vat_main_t *vam = &vat_main;
1792   struct in6_addr ip6;
1793   struct in_addr ip4;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800
1801   node = vat_json_array_add (&vam->json_tree);
1802   vat_json_init_object (node);
1803
1804   vat_json_object_add_uint (node, "domain_index",
1805                             clib_net_to_host_u32 (mp->domain_index));
1806   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1808   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1809   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1810   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1811   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1812   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1813   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1814   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1815   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1816   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1817   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1818   vat_json_object_add_uint (node, "flags", mp->flags);
1819   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1820   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1821 }
1822
1823 static void vl_api_map_domain_details_t_handler
1824   (vl_api_map_domain_details_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827
1828   if (mp->is_translation)
1829     {
1830       fformat (vam->ofp,
1831                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1832                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1833                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1834                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1835                clib_net_to_host_u32 (mp->domain_index));
1836     }
1837   else
1838     {
1839       fformat (vam->ofp,
1840                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1841                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1842                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1843                format_ip6_address, mp->ip6_src,
1844                clib_net_to_host_u32 (mp->domain_index));
1845     }
1846   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1847            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1848            mp->is_translation ? "map-t" : "");
1849 }
1850
1851 static void vl_api_map_rule_details_t_handler_json
1852   (vl_api_map_rule_details_t * mp)
1853 {
1854   struct in6_addr ip6;
1855   vat_json_node_t *node = NULL;
1856   vat_main_t *vam = &vat_main;
1857
1858   if (VAT_JSON_ARRAY != vam->json_tree.type)
1859     {
1860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1861       vat_json_init_array (&vam->json_tree);
1862     }
1863
1864   node = vat_json_array_add (&vam->json_tree);
1865   vat_json_init_object (node);
1866
1867   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1868   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1869   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1870 }
1871
1872 static void
1873 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1877            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1878 }
1879
1880 static void
1881 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1885           "router_addr %U host_mac %U\n",
1886           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1887           format_ip4_address, &mp->host_address,
1888           format_ip4_address, &mp->router_address,
1889           format_ethernet_address, mp->host_mac);
1890 }
1891
1892 static void vl_api_dhcp_compl_event_t_handler_json
1893   (vl_api_dhcp_compl_event_t * mp)
1894 {
1895   /* JSON output not supported */
1896 }
1897
1898 static void
1899 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                               u32 counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static u64 default_counter = 0;
1904
1905   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1906                            NULL);
1907   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1908                            sw_if_index, default_counter);
1909   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void
1913 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1914                                 interface_counter_t counter)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   static interface_counter_t default_counter = { 0, };
1918
1919   vec_validate_init_empty (vam->combined_interface_counters,
1920                            vnet_counter_type, NULL);
1921   vec_validate_init_empty (vam->combined_interface_counters
1922                            [vnet_counter_type], sw_if_index, default_counter);
1923   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   /* not supported */
1930 }
1931
1932 static void vl_api_vnet_interface_counters_t_handler_json
1933   (vl_api_vnet_interface_counters_t * mp)
1934 {
1935   interface_counter_t counter;
1936   vlib_counter_t *v;
1937   u64 *v_packets;
1938   u64 packets;
1939   u32 count;
1940   u32 first_sw_if_index;
1941   int i;
1942
1943   count = ntohl (mp->count);
1944   first_sw_if_index = ntohl (mp->first_sw_if_index);
1945
1946   if (!mp->is_combined)
1947     {
1948       v_packets = (u64 *) & mp->data;
1949       for (i = 0; i < count; i++)
1950         {
1951           packets =
1952             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1953           set_simple_interface_counter (mp->vnet_counter_type,
1954                                         first_sw_if_index + i, packets);
1955           v_packets++;
1956         }
1957     }
1958   else
1959     {
1960       v = (vlib_counter_t *) & mp->data;
1961       for (i = 0; i < count; i++)
1962         {
1963           counter.packets =
1964             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1965           counter.bytes =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1967           set_combined_interface_counter (mp->vnet_counter_type,
1968                                           first_sw_if_index + i, counter);
1969           v++;
1970         }
1971     }
1972 }
1973
1974 static u32
1975 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static u32
1991 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   u32 i;
1995
1996   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1997     {
1998       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1999         {
2000           return i;
2001         }
2002     }
2003   return ~0;
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2013   (vl_api_vnet_ip4_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip4_fib_counter_t *v;
2017   ip4_fib_counter_t *counter;
2018   struct in_addr ip4;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip4_fib_counters, vrf_index);
2032       vam->ip4_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip4_fib_counters[vrf_index]);
2036   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2041       counter = &vam->ip4_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2043       counter->address = ip4;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2058   (vl_api_vnet_ip6_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip6_fib_counter_t *v;
2062   ip6_fib_counter_t *counter;
2063   struct in6_addr ip6;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip6_fib_counters, vrf_index);
2077       vam->ip6_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip6_fib_counters[vrf_index]);
2081   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2086       counter = &vam->ip6_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2088       counter->address = ip6;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_get_first_msg_id_reply_t_handler
2097   (vl_api_get_first_msg_id_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   i32 retval = ntohl (mp->retval);
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111   if (retval >= 0)
2112     {
2113       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2114     }
2115 }
2116
2117 static void vl_api_get_first_msg_id_reply_t_handler_json
2118   (vl_api_get_first_msg_id_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t node;
2122
2123   vat_json_init_object (&node);
2124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2125   vat_json_object_add_uint (&node, "first_msg_id",
2126                             (uint) ntohs (mp->first_msg_id));
2127
2128   vat_json_print (vam->ofp, &node);
2129   vat_json_free (&node);
2130
2131   vam->retval = ntohl (mp->retval);
2132   vam->result_ready = 1;
2133 }
2134
2135 static void vl_api_get_node_graph_reply_t_handler
2136   (vl_api_get_node_graph_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   api_main_t *am = &api_main;
2140   i32 retval = ntohl (mp->retval);
2141   u8 *pvt_copy, *reply;
2142   void *oldheap;
2143   vlib_node_t *node;
2144   int i;
2145
2146   if (vam->async_mode)
2147     {
2148       vam->async_errors += (retval < 0);
2149     }
2150   else
2151     {
2152       vam->retval = retval;
2153       vam->result_ready = 1;
2154     }
2155
2156   /* "Should never happen..." */
2157   if (retval != 0)
2158     return;
2159
2160   reply = (u8 *) (mp->reply_in_shmem);
2161   pvt_copy = vec_dup (reply);
2162
2163   /* Toss the shared-memory original... */
2164   pthread_mutex_lock (&am->vlib_rp->mutex);
2165   oldheap = svm_push_data_heap (am->vlib_rp);
2166
2167   vec_free (reply);
2168
2169   svm_pop_heap (oldheap);
2170   pthread_mutex_unlock (&am->vlib_rp->mutex);
2171
2172   if (vam->graph_nodes)
2173     {
2174       hash_free (vam->graph_node_index_by_name);
2175
2176       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177         {
2178           node = vam->graph_nodes[i];
2179           vec_free (node->name);
2180           vec_free (node->next_nodes);
2181           vec_free (node);
2182         }
2183       vec_free (vam->graph_nodes);
2184     }
2185
2186   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2187   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2188   vec_free (pvt_copy);
2189
2190   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2191     {
2192       node = vam->graph_nodes[i];
2193       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2194     }
2195 }
2196
2197 static void vl_api_get_node_graph_reply_t_handler_json
2198   (vl_api_get_node_graph_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   void *oldheap;
2203   vat_json_node_t node;
2204   u8 *reply;
2205
2206   /* $$$$ make this real? */
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2210
2211   reply = (u8 *) (mp->reply_in_shmem);
2212
2213   /* Toss the shared-memory original... */
2214   pthread_mutex_lock (&am->vlib_rp->mutex);
2215   oldheap = svm_push_data_heap (am->vlib_rp);
2216
2217   vec_free (reply);
2218
2219   svm_pop_heap (oldheap);
2220   pthread_mutex_unlock (&am->vlib_rp->mutex);
2221
2222   vat_json_print (vam->ofp, &node);
2223   vat_json_free (&node);
2224
2225   vam->retval = ntohl (mp->retval);
2226   vam->result_ready = 1;
2227 }
2228
2229 static void
2230 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   u8 *s = 0;
2234
2235   if (mp->local)
2236     {
2237       s = format (s, "%=16d%=16d%=16d\n",
2238                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2239     }
2240   else
2241     {
2242       s = format (s, "%=16U%=16d%=16d\n",
2243                   mp->is_ipv6 ? format_ip6_address :
2244                   format_ip4_address,
2245                   mp->ip_address, mp->priority, mp->weight);
2246     }
2247
2248   fformat (vam->ofp, "%v", s);
2249   vec_free (s);
2250 }
2251
2252 static void
2253 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2254                                             mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t *node = NULL;
2258   struct in6_addr ip6;
2259   struct in_addr ip4;
2260
2261   if (VAT_JSON_ARRAY != vam->json_tree.type)
2262     {
2263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2264       vat_json_init_array (&vam->json_tree);
2265     }
2266   node = vat_json_array_add (&vam->json_tree);
2267   vat_json_init_object (node);
2268
2269   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2270   vat_json_object_add_uint (node, "priority", mp->priority);
2271   vat_json_object_add_uint (node, "weight", mp->weight);
2272
2273   if (mp->local)
2274     vat_json_object_add_uint (node, "sw_if_index",
2275                               clib_net_to_host_u32 (mp->sw_if_index));
2276   else
2277     {
2278       if (mp->is_ipv6)
2279         {
2280           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2281           vat_json_object_add_ip6 (node, "address", ip6);
2282         }
2283       else
2284         {
2285           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2286           vat_json_object_add_ip4 (node, "address", ip4);
2287         }
2288     }
2289 }
2290
2291 static void
2292 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2293                                            mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299
2300   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2301            ls_name);
2302   vec_free (ls_name);
2303 }
2304
2305 static void
2306   vl_api_lisp_locator_set_details_t_handler_json
2307   (vl_api_lisp_locator_set_details_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   vat_json_node_t *node = 0;
2311   u8 *ls_name = 0;
2312
2313   ls_name = format (0, "%s", mp->ls_name);
2314   vec_add1 (ls_name, 0);
2315
2316   if (VAT_JSON_ARRAY != vam->json_tree.type)
2317     {
2318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2319       vat_json_init_array (&vam->json_tree);
2320     }
2321   node = vat_json_array_add (&vam->json_tree);
2322
2323   vat_json_init_object (node);
2324   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2325   vat_json_object_add_uint (node, "ls_index",
2326                             clib_net_to_host_u32 (mp->ls_index));
2327   vec_free (ls_name);
2328 }
2329
2330 static u8 *
2331 format_lisp_flat_eid (u8 * s, va_list * args)
2332 {
2333   u32 type = va_arg (*args, u32);
2334   u8 *eid = va_arg (*args, u8 *);
2335   u32 eid_len = va_arg (*args, u32);
2336
2337   switch (type)
2338     {
2339     case 0:
2340       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2341     case 1:
2342       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2343     case 2:
2344       return format (s, "%U", format_ethernet_address, eid);
2345     }
2346   return 0;
2347 }
2348
2349 static u8 *
2350 format_lisp_eid_vat (u8 * s, va_list * args)
2351 {
2352   u32 type = va_arg (*args, u32);
2353   u8 *eid = va_arg (*args, u8 *);
2354   u32 eid_len = va_arg (*args, u32);
2355   u8 *seid = va_arg (*args, u8 *);
2356   u32 seid_len = va_arg (*args, u32);
2357   u32 is_src_dst = va_arg (*args, u32);
2358
2359   if (is_src_dst)
2360     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2361
2362   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2363
2364   return s;
2365 }
2366
2367 static void
2368 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   u8 *s = 0, *eid = 0;
2372
2373   if (~0 == mp->locator_set_index)
2374     s = format (0, "action: %d", mp->action);
2375   else
2376     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2377
2378   eid = format (0, "%U", format_lisp_eid_vat,
2379                 mp->eid_type,
2380                 mp->eid,
2381                 mp->eid_prefix_len,
2382                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2383   vec_add1 (eid, 0);
2384
2385   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2386            clib_net_to_host_u32 (mp->vni),
2387            eid,
2388            mp->is_local ? "local" : "remote",
2389            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2390   vec_free (s);
2391   vec_free (eid);
2392 }
2393
2394 static void
2395 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2396                                               * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   vat_json_node_t *node = 0;
2400   u8 *eid = 0;
2401
2402   if (VAT_JSON_ARRAY != vam->json_tree.type)
2403     {
2404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2405       vat_json_init_array (&vam->json_tree);
2406     }
2407   node = vat_json_array_add (&vam->json_tree);
2408
2409   vat_json_init_object (node);
2410   if (~0 == mp->locator_set_index)
2411     vat_json_object_add_uint (node, "action", mp->action);
2412   else
2413     vat_json_object_add_uint (node, "locator_set_index",
2414                               clib_net_to_host_u32 (mp->locator_set_index));
2415
2416   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2417   eid = format (0, "%U", format_lisp_eid_vat,
2418                 mp->eid_type,
2419                 mp->eid,
2420                 mp->eid_prefix_len,
2421                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2422   vec_add1 (eid, 0);
2423   vat_json_object_add_string_copy (node, "eid", eid);
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2426   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2427   vec_free (eid);
2428 }
2429
2430 static void
2431   vl_api_lisp_eid_table_map_details_t_handler
2432   (vl_api_lisp_eid_table_map_details_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435
2436   u8 *line = format (0, "%=10d%=10d",
2437                      clib_net_to_host_u32 (mp->vni),
2438                      clib_net_to_host_u32 (mp->dp_table));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_map_details_t_handler_json
2445   (vl_api_lisp_eid_table_map_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "dp_table",
2458                             clib_net_to_host_u32 (mp->dp_table));
2459   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2460 }
2461
2462 static void
2463   vl_api_lisp_eid_table_vni_details_t_handler
2464   (vl_api_lisp_eid_table_vni_details_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467
2468   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2469   fformat (vam->ofp, "%v\n", line);
2470   vec_free (line);
2471 }
2472
2473 static void
2474   vl_api_lisp_eid_table_vni_details_t_handler_json
2475   (vl_api_lisp_eid_table_vni_details_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t *node = NULL;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485   node = vat_json_array_add (&vam->json_tree);
2486   vat_json_init_object (node);
2487   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2488 }
2489
2490 static u8 *
2491 format_decap_next (u8 * s, va_list * args)
2492 {
2493   u32 next_index = va_arg (*args, u32);
2494
2495   switch (next_index)
2496     {
2497     case LISP_GPE_INPUT_NEXT_DROP:
2498       return format (s, "drop");
2499     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2500       return format (s, "ip4");
2501     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2502       return format (s, "ip6");
2503     default:
2504       return format (s, "unknown %d", next_index);
2505     }
2506   return s;
2507 }
2508
2509 static void
2510 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2511                                           mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *iid_str;
2515   u8 *flag_str = NULL;
2516
2517   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2518
2519 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2520   foreach_lisp_gpe_flag_bit;
2521 #undef _
2522
2523   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2524            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2525            mp->tunnels,
2526            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2527            mp->source_ip,
2528            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2529            mp->destination_ip,
2530            ntohl (mp->encap_fib_id),
2531            ntohl (mp->decap_fib_id),
2532            format_decap_next, ntohl (mp->dcap_next),
2533            mp->ver_res >> 6,
2534            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2535
2536   vec_free (iid_str);
2537 }
2538
2539 static void
2540   vl_api_lisp_gpe_tunnel_details_t_handler_json
2541   (vl_api_lisp_gpe_tunnel_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = NULL;
2545   struct in6_addr ip6;
2546   struct in_addr ip4;
2547   u8 *next_decap_str;
2548
2549   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557
2558   vat_json_init_object (node);
2559   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2560   if (mp->is_ipv6)
2561     {
2562       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2563       vat_json_object_add_ip6 (node, "source address", ip6);
2564       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2565       vat_json_object_add_ip6 (node, "destination address", ip6);
2566     }
2567   else
2568     {
2569       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2570       vat_json_object_add_ip4 (node, "source address", ip4);
2571       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2572       vat_json_object_add_ip4 (node, "destination address", ip4);
2573     }
2574   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2575   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2576   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2577   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2578   vat_json_object_add_uint (node, "flags", mp->flags);
2579   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2580   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2581   vat_json_object_add_uint (node, "res", mp->res);
2582   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2583
2584   vec_free (next_decap_str);
2585 }
2586
2587 static void
2588 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2589                                             * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   fformat (vam->ofp, "%=20U\n",
2594            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2595            mp->ip_address);
2596 }
2597
2598 static void
2599   vl_api_lisp_map_resolver_details_t_handler_json
2600   (vl_api_lisp_map_resolver_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604   struct in6_addr ip6;
2605   struct in_addr ip4;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   if (mp->is_ipv6)
2616     {
2617       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2618       vat_json_object_add_ip6 (node, "map resolver", ip6);
2619     }
2620   else
2621     {
2622       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2623       vat_json_object_add_ip4 (node, "map resolver", ip4);
2624     }
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   i32 retval = ntohl (mp->retval);
2633
2634   if (0 <= retval)
2635     {
2636       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2637                mp->feature_status ? "enabled" : "disabled",
2638                mp->gpe_status ? "enabled" : "disabled");
2639     }
2640
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler_json
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t node;
2651   u8 *gpe_status = NULL;
2652   u8 *feature_status = NULL;
2653
2654   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2655   feature_status = format (0, "%s",
2656                            mp->feature_status ? "enabled" : "disabled");
2657   vec_add1 (gpe_status, 0);
2658   vec_add1 (feature_status, 0);
2659
2660   vat_json_init_object (&node);
2661   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2662   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2663
2664   vec_free (gpe_status);
2665   vec_free (feature_status);
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2676   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   i32 retval = ntohl (mp->retval);
2680
2681   if (retval >= 0)
2682     {
2683       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2684     }
2685
2686   vam->retval = retval;
2687   vam->result_ready = 1;
2688 }
2689
2690 static void
2691   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2692   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t *node = NULL;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2706
2707   vat_json_print (vam->ofp, node);
2708   vat_json_free (node);
2709
2710   vam->retval = ntohl (mp->retval);
2711   vam->result_ready = 1;
2712 }
2713
2714 static u8 *
2715 format_lisp_map_request_mode (u8 * s, va_list * args)
2716 {
2717   u32 mode = va_arg (*args, u32);
2718
2719   switch (mode)
2720     {
2721     case 0:
2722       return format (0, "dst-only");
2723     case 1:
2724       return format (0, "src-dst");
2725     }
2726   return 0;
2727 }
2728
2729 static void
2730   vl_api_show_lisp_map_request_mode_reply_t_handler
2731   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   i32 retval = ntohl (mp->retval);
2735
2736   if (0 <= retval)
2737     {
2738       u32 mode = mp->mode;
2739       fformat (vam->ofp, "map_request_mode: %U\n",
2740                format_lisp_map_request_mode, mode);
2741     }
2742
2743   vam->retval = retval;
2744   vam->result_ready = 1;
2745 }
2746
2747 static void
2748   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2749   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   vat_json_node_t node;
2753   u8 *s = 0;
2754   u32 mode;
2755
2756   mode = mp->mode;
2757   s = format (0, "%U", format_lisp_map_request_mode, mode);
2758   vec_add1 (s, 0);
2759
2760   vat_json_init_object (&node);
2761   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2762   vat_json_print (vam->ofp, &node);
2763   vat_json_free (&node);
2764
2765   vec_free (s);
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static void
2771 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   i32 retval = ntohl (mp->retval);
2775
2776   if (0 <= retval)
2777     {
2778       fformat (vam->ofp, "%-20s%-16s\n",
2779                mp->status ? "enabled" : "disabled",
2780                mp->status ? (char *) mp->locator_set_name : "");
2781     }
2782
2783   vam->retval = retval;
2784   vam->result_ready = 1;
2785 }
2786
2787 static void
2788 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2789                                             mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   vat_json_node_t node;
2793   u8 *status = 0;
2794
2795   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2796   vec_add1 (status, 0);
2797
2798   vat_json_init_object (&node);
2799   vat_json_object_add_string_copy (&node, "status", status);
2800   if (mp->status)
2801     {
2802       vat_json_object_add_string_copy (&node, "locator_set",
2803                                        mp->locator_set_name);
2804     }
2805
2806   vec_free (status);
2807
2808   vat_json_print (vam->ofp, &node);
2809   vat_json_free (&node);
2810
2811   vam->retval = ntohl (mp->retval);
2812   vam->result_ready = 1;
2813 }
2814
2815 static u8 *
2816 format_policer_type (u8 * s, va_list * va)
2817 {
2818   u32 i = va_arg (*va, u32);
2819
2820   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2821     s = format (s, "1r2c");
2822   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2823     s = format (s, "1r3c");
2824   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2825     s = format (s, "2r3c-2698");
2826   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2827     s = format (s, "2r3c-4115");
2828   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2829     s = format (s, "2r3c-mef5cf1");
2830   else
2831     s = format (s, "ILLEGAL");
2832   return s;
2833 }
2834
2835 static u8 *
2836 format_policer_rate_type (u8 * s, va_list * va)
2837 {
2838   u32 i = va_arg (*va, u32);
2839
2840   if (i == SSE2_QOS_RATE_KBPS)
2841     s = format (s, "kbps");
2842   else if (i == SSE2_QOS_RATE_PPS)
2843     s = format (s, "pps");
2844   else
2845     s = format (s, "ILLEGAL");
2846   return s;
2847 }
2848
2849 static u8 *
2850 format_policer_round_type (u8 * s, va_list * va)
2851 {
2852   u32 i = va_arg (*va, u32);
2853
2854   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2855     s = format (s, "closest");
2856   else if (i == SSE2_QOS_ROUND_TO_UP)
2857     s = format (s, "up");
2858   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2859     s = format (s, "down");
2860   else
2861     s = format (s, "ILLEGAL");
2862   return s;
2863 }
2864
2865 static u8 *
2866 format_policer_action_type (u8 * s, va_list * va)
2867 {
2868   u32 i = va_arg (*va, u32);
2869
2870   if (i == SSE2_QOS_ACTION_DROP)
2871     s = format (s, "drop");
2872   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2873     s = format (s, "transmit");
2874   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2875     s = format (s, "mark-and-transmit");
2876   else
2877     s = format (s, "ILLEGAL");
2878   return s;
2879 }
2880
2881 static u8 *
2882 format_dscp (u8 * s, va_list * va)
2883 {
2884   u32 i = va_arg (*va, u32);
2885   char *t = 0;
2886
2887   switch (i)
2888     {
2889 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2890       foreach_vnet_dscp
2891 #undef _
2892     default:
2893       return format (s, "ILLEGAL");
2894     }
2895   s = format (s, "%s", t);
2896   return s;
2897 }
2898
2899 static void
2900 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2904
2905   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2906     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2907   else
2908     conform_dscp_str = format (0, "");
2909
2910   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2911     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2912   else
2913     exceed_dscp_str = format (0, "");
2914
2915   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2916     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2917   else
2918     violate_dscp_str = format (0, "");
2919
2920   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2921            "rate type %U, round type %U, %s rate, %s color-aware, "
2922            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2923            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2924            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2925            mp->name,
2926            format_policer_type, mp->type,
2927            ntohl (mp->cir),
2928            ntohl (mp->eir),
2929            clib_net_to_host_u64 (mp->cb),
2930            clib_net_to_host_u64 (mp->eb),
2931            format_policer_rate_type, mp->rate_type,
2932            format_policer_round_type, mp->round_type,
2933            mp->single_rate ? "single" : "dual",
2934            mp->color_aware ? "is" : "not",
2935            ntohl (mp->cir_tokens_per_period),
2936            ntohl (mp->pir_tokens_per_period),
2937            ntohl (mp->scale),
2938            ntohl (mp->current_limit),
2939            ntohl (mp->current_bucket),
2940            ntohl (mp->extended_limit),
2941            ntohl (mp->extended_bucket),
2942            clib_net_to_host_u64 (mp->last_update_time),
2943            format_policer_action_type, mp->conform_action_type,
2944            conform_dscp_str,
2945            format_policer_action_type, mp->exceed_action_type,
2946            exceed_dscp_str,
2947            format_policer_action_type, mp->violate_action_type,
2948            violate_dscp_str);
2949
2950   vec_free (conform_dscp_str);
2951   vec_free (exceed_dscp_str);
2952   vec_free (violate_dscp_str);
2953 }
2954
2955 static void vl_api_policer_details_t_handler_json
2956   (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   vat_json_node_t *node;
2960   u8 *rate_type_str, *round_type_str, *type_str;
2961   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2962
2963   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2964   round_type_str =
2965     format (0, "%U", format_policer_round_type, mp->round_type);
2966   type_str = format (0, "%U", format_policer_type, mp->type);
2967   conform_action_str = format (0, "%U", format_policer_action_type,
2968                                mp->conform_action_type);
2969   exceed_action_str = format (0, "%U", format_policer_action_type,
2970                               mp->exceed_action_type);
2971   violate_action_str = format (0, "%U", format_policer_action_type,
2972                                mp->violate_action_type);
2973
2974   if (VAT_JSON_ARRAY != vam->json_tree.type)
2975     {
2976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2977       vat_json_init_array (&vam->json_tree);
2978     }
2979   node = vat_json_array_add (&vam->json_tree);
2980
2981   vat_json_init_object (node);
2982   vat_json_object_add_string_copy (node, "name", mp->name);
2983   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2984   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2985   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2986   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2987   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2988   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2989   vat_json_object_add_string_copy (node, "type", type_str);
2990   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2991   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2992   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2993   vat_json_object_add_uint (node, "cir_tokens_per_period",
2994                             ntohl (mp->cir_tokens_per_period));
2995   vat_json_object_add_uint (node, "eir_tokens_per_period",
2996                             ntohl (mp->pir_tokens_per_period));
2997   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2998   vat_json_object_add_uint (node, "current_bucket",
2999                             ntohl (mp->current_bucket));
3000   vat_json_object_add_uint (node, "extended_limit",
3001                             ntohl (mp->extended_limit));
3002   vat_json_object_add_uint (node, "extended_bucket",
3003                             ntohl (mp->extended_bucket));
3004   vat_json_object_add_uint (node, "last_update_time",
3005                             ntohl (mp->last_update_time));
3006   vat_json_object_add_string_copy (node, "conform_action",
3007                                    conform_action_str);
3008   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3009     {
3010       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3011       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3012       vec_free (dscp_str);
3013     }
3014   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3015   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3016     {
3017       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3018       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3019       vec_free (dscp_str);
3020     }
3021   vat_json_object_add_string_copy (node, "violate_action",
3022                                    violate_action_str);
3023   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3024     {
3025       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3026       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3027       vec_free (dscp_str);
3028     }
3029
3030   vec_free (rate_type_str);
3031   vec_free (round_type_str);
3032   vec_free (type_str);
3033   vec_free (conform_action_str);
3034   vec_free (exceed_action_str);
3035   vec_free (violate_action_str);
3036 }
3037
3038 static void
3039 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3040                                            mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   int i, count = ntohl (mp->count);
3044
3045   if (count > 0)
3046     fformat (vam->ofp, "classify table ids (%d) : ", count);
3047   for (i = 0; i < count; i++)
3048     {
3049       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3050       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3051     }
3052   vam->retval = ntohl (mp->retval);
3053   vam->result_ready = 1;
3054 }
3055
3056 static void
3057   vl_api_classify_table_ids_reply_t_handler_json
3058   (vl_api_classify_table_ids_reply_t * mp)
3059 {
3060   vat_main_t *vam = &vat_main;
3061   int i, count = ntohl (mp->count);
3062
3063   if (count > 0)
3064     {
3065       vat_json_node_t node;
3066
3067       vat_json_init_object (&node);
3068       for (i = 0; i < count; i++)
3069         {
3070           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3071         }
3072       vat_json_print (vam->ofp, &node);
3073       vat_json_free (&node);
3074     }
3075   vam->retval = ntohl (mp->retval);
3076   vam->result_ready = 1;
3077 }
3078
3079 static void
3080   vl_api_classify_table_by_interface_reply_t_handler
3081   (vl_api_classify_table_by_interface_reply_t * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   u32 table_id;
3085
3086   table_id = ntohl (mp->l2_table_id);
3087   if (table_id != ~0)
3088     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3089   else
3090     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3091   table_id = ntohl (mp->ip4_table_id);
3092   if (table_id != ~0)
3093     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3094   else
3095     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3096   table_id = ntohl (mp->ip6_table_id);
3097   if (table_id != ~0)
3098     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3099   else
3100     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3101   vam->retval = ntohl (mp->retval);
3102   vam->result_ready = 1;
3103 }
3104
3105 static void
3106   vl_api_classify_table_by_interface_reply_t_handler_json
3107   (vl_api_classify_table_by_interface_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t node;
3111
3112   vat_json_init_object (&node);
3113
3114   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3115   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3116   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3117
3118   vat_json_print (vam->ofp, &node);
3119   vat_json_free (&node);
3120
3121   vam->retval = ntohl (mp->retval);
3122   vam->result_ready = 1;
3123 }
3124
3125 static void vl_api_policer_add_del_reply_t_handler
3126   (vl_api_policer_add_del_reply_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   i32 retval = ntohl (mp->retval);
3130   if (vam->async_mode)
3131     {
3132       vam->async_errors += (retval < 0);
3133     }
3134   else
3135     {
3136       vam->retval = retval;
3137       vam->result_ready = 1;
3138       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3139         /*
3140          * Note: this is just barely thread-safe, depends on
3141          * the main thread spinning waiting for an answer...
3142          */
3143         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3144     }
3145 }
3146
3147 static void vl_api_policer_add_del_reply_t_handler_json
3148   (vl_api_policer_add_del_reply_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t node;
3152
3153   vat_json_init_object (&node);
3154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3155   vat_json_object_add_uint (&node, "policer_index",
3156                             ntohl (mp->policer_index));
3157
3158   vat_json_print (vam->ofp, &node);
3159   vat_json_free (&node);
3160
3161   vam->retval = ntohl (mp->retval);
3162   vam->result_ready = 1;
3163 }
3164
3165 /* Format hex dump. */
3166 u8 *
3167 format_hex_bytes (u8 * s, va_list * va)
3168 {
3169   u8 *bytes = va_arg (*va, u8 *);
3170   int n_bytes = va_arg (*va, int);
3171   uword i;
3172
3173   /* Print short or long form depending on byte count. */
3174   uword short_form = n_bytes <= 32;
3175   uword indent = format_get_indent (s);
3176
3177   if (n_bytes == 0)
3178     return s;
3179
3180   for (i = 0; i < n_bytes; i++)
3181     {
3182       if (!short_form && (i % 32) == 0)
3183         s = format (s, "%08x: ", i);
3184       s = format (s, "%02x", bytes[i]);
3185       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3186         s = format (s, "\n%U", format_white_space, indent);
3187     }
3188
3189   return s;
3190 }
3191
3192 static void
3193 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3194                                             * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   i32 retval = ntohl (mp->retval);
3198   if (retval == 0)
3199     {
3200       fformat (vam->ofp, "classify table info :\n");
3201       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3202                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3203                ntohl (mp->miss_next_index));
3204       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3205                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3206                ntohl (mp->match_n_vectors));
3207       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3208                ntohl (mp->mask_length));
3209     }
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_classify_table_info_reply_t_handler_json
3216   (vl_api_classify_table_info_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220
3221   i32 retval = ntohl (mp->retval);
3222   if (retval == 0)
3223     {
3224       vat_json_init_object (&node);
3225
3226       vat_json_object_add_int (&node, "sessions",
3227                                ntohl (mp->active_sessions));
3228       vat_json_object_add_int (&node, "nexttbl",
3229                                ntohl (mp->next_table_index));
3230       vat_json_object_add_int (&node, "nextnode",
3231                                ntohl (mp->miss_next_index));
3232       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3233       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3234       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3235       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3236                       ntohl (mp->mask_length), 0);
3237       vat_json_object_add_string_copy (&node, "mask", s);
3238
3239       vat_json_print (vam->ofp, &node);
3240       vat_json_free (&node);
3241     }
3242   vam->retval = ntohl (mp->retval);
3243   vam->result_ready = 1;
3244 }
3245
3246 static void
3247 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3248                                            mp)
3249 {
3250   vat_main_t *vam = &vat_main;
3251
3252   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3253            ntohl (mp->hit_next_index), ntohl (mp->advance),
3254            ntohl (mp->opaque_index));
3255   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3256            ntohl (mp->match_length));
3257 }
3258
3259 static void
3260   vl_api_classify_session_details_t_handler_json
3261   (vl_api_classify_session_details_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t *node = NULL;
3265
3266   if (VAT_JSON_ARRAY != vam->json_tree.type)
3267     {
3268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3269       vat_json_init_array (&vam->json_tree);
3270     }
3271   node = vat_json_array_add (&vam->json_tree);
3272
3273   vat_json_init_object (node);
3274   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3275   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3276   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3277   u8 *s =
3278     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3279             0);
3280   vat_json_object_add_string_copy (node, "match", s);
3281 }
3282
3283 static void vl_api_pg_create_interface_reply_t_handler
3284   (vl_api_pg_create_interface_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287
3288   vam->retval = ntohl (mp->retval);
3289   vam->result_ready = 1;
3290 }
3291
3292 static void vl_api_pg_create_interface_reply_t_handler_json
3293   (vl_api_pg_create_interface_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t node;
3297
3298   i32 retval = ntohl (mp->retval);
3299   if (retval == 0)
3300     {
3301       vat_json_init_object (&node);
3302
3303       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3304
3305       vat_json_print (vam->ofp, &node);
3306       vat_json_free (&node);
3307     }
3308   vam->retval = ntohl (mp->retval);
3309   vam->result_ready = 1;
3310 }
3311
3312 static void vl_api_policer_classify_details_t_handler
3313   (vl_api_policer_classify_details_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316
3317   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3318            ntohl (mp->table_index));
3319 }
3320
3321 static void vl_api_policer_classify_details_t_handler_json
3322   (vl_api_policer_classify_details_t * mp)
3323 {
3324   vat_main_t *vam = &vat_main;
3325   vat_json_node_t *node;
3326
3327   if (VAT_JSON_ARRAY != vam->json_tree.type)
3328     {
3329       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3330       vat_json_init_array (&vam->json_tree);
3331     }
3332   node = vat_json_array_add (&vam->json_tree);
3333
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3336   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3337 }
3338
3339 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3340   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (vam->async_mode)
3345     {
3346       vam->async_errors += (retval < 0);
3347     }
3348   else
3349     {
3350       vam->retval = retval;
3351       vam->sw_if_index = ntohl (mp->sw_if_index);
3352       vam->result_ready = 1;
3353     }
3354 }
3355
3356 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3357   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   vat_json_node_t node;
3361
3362   vat_json_init_object (&node);
3363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3364   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3365
3366   vat_json_print (vam->ofp, &node);
3367   vat_json_free (&node);
3368
3369   vam->retval = ntohl (mp->retval);
3370   vam->result_ready = 1;
3371 }
3372
3373 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3374 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3375 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3376 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3377
3378 /*
3379  * Generate boilerplate reply handlers, which
3380  * dig the return value out of the xxx_reply_t API message,
3381  * stick it into vam->retval, and set vam->result_ready
3382  *
3383  * Could also do this by pointing N message decode slots at
3384  * a single function, but that could break in subtle ways.
3385  */
3386
3387 #define foreach_standard_reply_retval_handler           \
3388 _(sw_interface_set_flags_reply)                         \
3389 _(sw_interface_add_del_address_reply)                   \
3390 _(sw_interface_set_table_reply)                         \
3391 _(sw_interface_set_vpath_reply)                         \
3392 _(sw_interface_set_l2_bridge_reply)                     \
3393 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3394 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3395 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3396 _(bridge_domain_add_del_reply)                          \
3397 _(sw_interface_set_l2_xconnect_reply)                   \
3398 _(l2fib_add_del_reply)                                  \
3399 _(ip_add_del_route_reply)                               \
3400 _(proxy_arp_add_del_reply)                              \
3401 _(proxy_arp_intfc_enable_disable_reply)                 \
3402 _(mpls_add_del_encap_reply)                             \
3403 _(mpls_add_del_decap_reply)                             \
3404 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3405 _(sw_interface_set_unnumbered_reply)                    \
3406 _(ip_neighbor_add_del_reply)                            \
3407 _(reset_vrf_reply)                                      \
3408 _(oam_add_del_reply)                                    \
3409 _(reset_fib_reply)                                      \
3410 _(dhcp_proxy_config_reply)                              \
3411 _(dhcp_proxy_config_2_reply)                            \
3412 _(dhcp_proxy_set_vss_reply)                             \
3413 _(dhcp_client_config_reply)                             \
3414 _(set_ip_flow_hash_reply)                               \
3415 _(sw_interface_ip6_enable_disable_reply)                \
3416 _(sw_interface_ip6_set_link_local_address_reply)        \
3417 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3418 _(sw_interface_ip6nd_ra_config_reply)                   \
3419 _(set_arp_neighbor_limit_reply)                         \
3420 _(l2_patch_add_del_reply)                               \
3421 _(sr_tunnel_add_del_reply)                              \
3422 _(sr_policy_add_del_reply)                              \
3423 _(sr_multicast_map_add_del_reply)                       \
3424 _(classify_add_del_session_reply)                       \
3425 _(classify_set_interface_ip_table_reply)                \
3426 _(classify_set_interface_l2_tables_reply)               \
3427 _(l2tpv3_set_tunnel_cookies_reply)                      \
3428 _(l2tpv3_interface_enable_disable_reply)                \
3429 _(l2tpv3_set_lookup_key_reply)                          \
3430 _(l2_fib_clear_table_reply)                             \
3431 _(l2_interface_efp_filter_reply)                        \
3432 _(l2_interface_vlan_tag_rewrite_reply)                  \
3433 _(modify_vhost_user_if_reply)                           \
3434 _(delete_vhost_user_if_reply)                           \
3435 _(want_ip4_arp_events_reply)                            \
3436 _(want_ip6_nd_events_reply)                             \
3437 _(input_acl_set_interface_reply)                        \
3438 _(ipsec_spd_add_del_reply)                              \
3439 _(ipsec_interface_add_del_spd_reply)                    \
3440 _(ipsec_spd_add_del_entry_reply)                        \
3441 _(ipsec_sad_add_del_entry_reply)                        \
3442 _(ipsec_sa_set_key_reply)                               \
3443 _(ikev2_profile_add_del_reply)                          \
3444 _(ikev2_profile_set_auth_reply)                         \
3445 _(ikev2_profile_set_id_reply)                           \
3446 _(ikev2_profile_set_ts_reply)                           \
3447 _(ikev2_set_local_key_reply)                            \
3448 _(delete_loopback_reply)                                \
3449 _(bd_ip_mac_add_del_reply)                              \
3450 _(map_del_domain_reply)                                 \
3451 _(map_add_del_rule_reply)                               \
3452 _(want_interface_events_reply)                          \
3453 _(want_stats_reply)                                     \
3454 _(cop_interface_enable_disable_reply)                   \
3455 _(cop_whitelist_enable_disable_reply)                   \
3456 _(sw_interface_clear_stats_reply)                       \
3457 _(ioam_enable_reply)                              \
3458 _(ioam_disable_reply)                              \
3459 _(lisp_add_del_locator_reply)                           \
3460 _(lisp_add_del_local_eid_reply)                         \
3461 _(lisp_add_del_remote_mapping_reply)                    \
3462 _(lisp_add_del_adjacency_reply)                         \
3463 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3464 _(lisp_add_del_map_resolver_reply)                      \
3465 _(lisp_gpe_enable_disable_reply)                        \
3466 _(lisp_gpe_add_del_iface_reply)                         \
3467 _(lisp_enable_disable_reply)                            \
3468 _(lisp_pitr_set_locator_set_reply)                      \
3469 _(lisp_map_request_mode_reply)                          \
3470 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3471 _(lisp_eid_table_add_del_map_reply)                     \
3472 _(vxlan_gpe_add_del_tunnel_reply)                       \
3473 _(af_packet_delete_reply)                               \
3474 _(policer_classify_set_interface_reply)                 \
3475 _(netmap_create_reply)                                  \
3476 _(netmap_delete_reply)                                  \
3477 _(set_ipfix_exporter_reply)                             \
3478 _(set_ipfix_classify_stream_reply)                      \
3479 _(ipfix_classify_table_add_del_reply)                   \
3480 _(pg_capture_reply)                                     \
3481 _(pg_enable_disable_reply)                              \
3482 _(ip_source_and_port_range_check_add_del_reply)         \
3483 _(ip_source_and_port_range_check_interface_add_del_reply)\
3484 _(delete_subif_reply)                                   \
3485 _(l2_interface_pbb_tag_rewrite_reply)                   \
3486 _(punt_reply)
3487
3488 #define _(n)                                    \
3489     static void vl_api_##n##_t_handler          \
3490     (vl_api_##n##_t * mp)                       \
3491     {                                           \
3492         vat_main_t * vam = &vat_main;           \
3493         i32 retval = ntohl(mp->retval);         \
3494         if (vam->async_mode) {                  \
3495             vam->async_errors += (retval < 0);  \
3496         } else {                                \
3497             vam->retval = retval;               \
3498             vam->result_ready = 1;              \
3499         }                                       \
3500     }
3501 foreach_standard_reply_retval_handler;
3502 #undef _
3503
3504 #define _(n)                                    \
3505     static void vl_api_##n##_t_handler_json     \
3506     (vl_api_##n##_t * mp)                       \
3507     {                                           \
3508         vat_main_t * vam = &vat_main;           \
3509         vat_json_node_t node;                   \
3510         vat_json_init_object(&node);            \
3511         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3512         vat_json_print(vam->ofp, &node);        \
3513         vam->retval = ntohl(mp->retval);        \
3514         vam->result_ready = 1;                  \
3515     }
3516 foreach_standard_reply_retval_handler;
3517 #undef _
3518
3519 /*
3520  * Table of message reply handlers, must include boilerplate handlers
3521  * we just generated
3522  */
3523
3524 #define foreach_vpe_api_reply_msg                                       \
3525 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3526 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3527 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3528 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3529 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3530 _(CLI_REPLY, cli_reply)                                                 \
3531 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3532 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3533   sw_interface_add_del_address_reply)                                   \
3534 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3535 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3536 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3537   sw_interface_set_l2_xconnect_reply)                                   \
3538 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3539   sw_interface_set_l2_bridge_reply)                                     \
3540 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3541   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3542 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3543   sw_interface_set_dpdk_hqos_subport_reply)                             \
3544 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3545   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3546 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3547 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3548 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3549 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3550 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3551 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3552 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3553 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3554 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3555 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3556 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3557 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3558 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3559   proxy_arp_intfc_enable_disable_reply)                                 \
3560 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3561 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3562 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3563 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3564   mpls_ethernet_add_del_tunnel_reply)                                   \
3565 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3566   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3567 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3568   sw_interface_set_unnumbered_reply)                                    \
3569 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3570 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3571 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3572 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3573 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3574 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3575 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3576 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3577 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3578 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3579 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3580 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3581   sw_interface_ip6_enable_disable_reply)                                \
3582 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3583   sw_interface_ip6_set_link_local_address_reply)                        \
3584 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3585   sw_interface_ip6nd_ra_prefix_reply)                                   \
3586 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3587   sw_interface_ip6nd_ra_config_reply)                                   \
3588 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3589 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3590 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3591 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3592 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3593 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3594 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3595 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3596 classify_set_interface_ip_table_reply)                                  \
3597 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3598   classify_set_interface_l2_tables_reply)                               \
3599 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3600 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3601 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3602 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3603 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3604   l2tpv3_interface_enable_disable_reply)                                \
3605 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3606 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3607 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3608 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3609 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3610 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3611 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3612 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3613 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3614 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3615 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3616 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3617 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3618 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3619 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3620 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3621 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3622 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3623 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3624 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3625 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3626 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3627 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3628 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3629 _(IP_DETAILS, ip_details)                                               \
3630 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3631 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3632 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3633 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3634 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3635 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3636 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3637 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3638 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3639 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3640 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3641 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3642 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3643 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3644 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3645 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3646 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3647 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3648 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3649 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3650 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3651 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3652 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3653 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3654 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3655 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3656 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3657 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3658 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3659 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3660 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3661 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3662 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3663 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3664 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3665 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3666 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3667 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3668 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3669 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3670 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3671 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3672 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3673 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3674 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3675 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3676 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3677 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3678 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3679 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3680 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3681 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3682   lisp_add_del_map_request_itr_rlocs_reply)                             \
3683 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3684   lisp_get_map_request_itr_rlocs_reply)                                 \
3685 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3686 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3687 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3688 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3689 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3690 _(POLICER_DETAILS, policer_details)                                     \
3691 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3692 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3693 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3694 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3695 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3696 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3697 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3698 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3699 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3700 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3701 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3702 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3703 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3704 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3705 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3706 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3707 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3708 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3709 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3710 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3711 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3712 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3713 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3714  ip_source_and_port_range_check_add_del_reply)                          \
3715 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3716  ip_source_and_port_range_check_interface_add_del_reply)                \
3717 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3718 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3719 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3720 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3721 _(PUNT_REPLY, punt_reply)
3722
3723 /* M: construct, but don't yet send a message */
3724
3725 #define M(T,t)                                  \
3726 do {                                            \
3727     vam->result_ready = 0;                      \
3728     mp = vl_msg_api_alloc(sizeof(*mp));         \
3729     memset (mp, 0, sizeof (*mp));               \
3730     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3731     mp->client_index = vam->my_client_index;    \
3732 } while(0);
3733
3734 #define M2(T,t,n)                               \
3735 do {                                            \
3736     vam->result_ready = 0;                      \
3737     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3738     memset (mp, 0, sizeof (*mp));               \
3739     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3740     mp->client_index = vam->my_client_index;    \
3741 } while(0);
3742
3743
3744 /* S: send a message */
3745 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3746
3747 /* W: wait for results, with timeout */
3748 #define W                                       \
3749 do {                                            \
3750     timeout = vat_time_now (vam) + 1.0;         \
3751                                                 \
3752     while (vat_time_now (vam) < timeout) {      \
3753         if (vam->result_ready == 1) {           \
3754             return (vam->retval);               \
3755         }                                       \
3756     }                                           \
3757     return -99;                                 \
3758 } while(0);
3759
3760 /* W2: wait for results, with timeout */
3761 #define W2(body)                                \
3762 do {                                            \
3763     timeout = vat_time_now (vam) + 1.0;         \
3764                                                 \
3765     while (vat_time_now (vam) < timeout) {      \
3766         if (vam->result_ready == 1) {           \
3767           (body);                               \
3768           return (vam->retval);                 \
3769         }                                       \
3770     }                                           \
3771     return -99;                                 \
3772 } while(0);
3773
3774 typedef struct
3775 {
3776   u8 *name;
3777   u32 value;
3778 } name_sort_t;
3779
3780
3781 #define STR_VTR_OP_CASE(op)     \
3782     case L2_VTR_ ## op:         \
3783         return "" # op;
3784
3785 static const char *
3786 str_vtr_op (u32 vtr_op)
3787 {
3788   switch (vtr_op)
3789     {
3790       STR_VTR_OP_CASE (DISABLED);
3791       STR_VTR_OP_CASE (PUSH_1);
3792       STR_VTR_OP_CASE (PUSH_2);
3793       STR_VTR_OP_CASE (POP_1);
3794       STR_VTR_OP_CASE (POP_2);
3795       STR_VTR_OP_CASE (TRANSLATE_1_1);
3796       STR_VTR_OP_CASE (TRANSLATE_1_2);
3797       STR_VTR_OP_CASE (TRANSLATE_2_1);
3798       STR_VTR_OP_CASE (TRANSLATE_2_2);
3799     }
3800
3801   return "UNKNOWN";
3802 }
3803
3804 static int
3805 dump_sub_interface_table (vat_main_t * vam)
3806 {
3807   const sw_interface_subif_t *sub = NULL;
3808
3809   if (vam->json_output)
3810     {
3811       clib_warning
3812         ("JSON output supported only for VPE API calls and dump_stats_table");
3813       return -99;
3814     }
3815
3816   fformat (vam->ofp,
3817            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3818            "Interface", "sw_if_index",
3819            "sub id", "dot1ad", "tags", "outer id",
3820            "inner id", "exact", "default", "outer any", "inner any");
3821
3822   vec_foreach (sub, vam->sw_if_subif_table)
3823   {
3824     fformat (vam->ofp,
3825              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3826              sub->interface_name,
3827              sub->sw_if_index,
3828              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3829              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3830              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3831              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3832     if (sub->vtr_op != L2_VTR_DISABLED)
3833       {
3834         fformat (vam->ofp,
3835                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3836                  "tag1: %d tag2: %d ]\n",
3837                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3838                  sub->vtr_tag1, sub->vtr_tag2);
3839       }
3840   }
3841
3842   return 0;
3843 }
3844
3845 static int
3846 name_sort_cmp (void *a1, void *a2)
3847 {
3848   name_sort_t *n1 = a1;
3849   name_sort_t *n2 = a2;
3850
3851   return strcmp ((char *) n1->name, (char *) n2->name);
3852 }
3853
3854 static int
3855 dump_interface_table (vat_main_t * vam)
3856 {
3857   hash_pair_t *p;
3858   name_sort_t *nses = 0, *ns;
3859
3860   if (vam->json_output)
3861     {
3862       clib_warning
3863         ("JSON output supported only for VPE API calls and dump_stats_table");
3864       return -99;
3865     }
3866
3867   /* *INDENT-OFF* */
3868   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3869   ({
3870     vec_add2 (nses, ns, 1);
3871     ns->name = (u8 *)(p->key);
3872     ns->value = (u32) p->value[0];
3873   }));
3874   /* *INDENT-ON* */
3875
3876   vec_sort_with_function (nses, name_sort_cmp);
3877
3878   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3879   vec_foreach (ns, nses)
3880   {
3881     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3882   }
3883   vec_free (nses);
3884   return 0;
3885 }
3886
3887 static int
3888 dump_ip_table (vat_main_t * vam, int is_ipv6)
3889 {
3890   const ip_details_t *det = NULL;
3891   const ip_address_details_t *address = NULL;
3892   u32 i = ~0;
3893
3894   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3895
3896   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3897   {
3898     i++;
3899     if (!det->present)
3900       {
3901         continue;
3902       }
3903     fformat (vam->ofp, "%-12d\n", i);
3904     fformat (vam->ofp,
3905              "            %-30s%-13s\n", "Address", "Prefix length");
3906     if (!det->addr)
3907       {
3908         continue;
3909       }
3910     vec_foreach (address, det->addr)
3911     {
3912       fformat (vam->ofp,
3913                "            %-30U%-13d\n",
3914                is_ipv6 ? format_ip6_address : format_ip4_address,
3915                address->ip, address->prefix_length);
3916     }
3917   }
3918
3919   return 0;
3920 }
3921
3922 static int
3923 dump_ipv4_table (vat_main_t * vam)
3924 {
3925   if (vam->json_output)
3926     {
3927       clib_warning
3928         ("JSON output supported only for VPE API calls and dump_stats_table");
3929       return -99;
3930     }
3931
3932   return dump_ip_table (vam, 0);
3933 }
3934
3935 static int
3936 dump_ipv6_table (vat_main_t * vam)
3937 {
3938   if (vam->json_output)
3939     {
3940       clib_warning
3941         ("JSON output supported only for VPE API calls and dump_stats_table");
3942       return -99;
3943     }
3944
3945   return dump_ip_table (vam, 1);
3946 }
3947
3948 static char *
3949 counter_type_to_str (u8 counter_type, u8 is_combined)
3950 {
3951   if (!is_combined)
3952     {
3953       switch (counter_type)
3954         {
3955         case VNET_INTERFACE_COUNTER_DROP:
3956           return "drop";
3957         case VNET_INTERFACE_COUNTER_PUNT:
3958           return "punt";
3959         case VNET_INTERFACE_COUNTER_IP4:
3960           return "ip4";
3961         case VNET_INTERFACE_COUNTER_IP6:
3962           return "ip6";
3963         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3964           return "rx-no-buf";
3965         case VNET_INTERFACE_COUNTER_RX_MISS:
3966           return "rx-miss";
3967         case VNET_INTERFACE_COUNTER_RX_ERROR:
3968           return "rx-error";
3969         case VNET_INTERFACE_COUNTER_TX_ERROR:
3970           return "tx-error";
3971         default:
3972           return "INVALID-COUNTER-TYPE";
3973         }
3974     }
3975   else
3976     {
3977       switch (counter_type)
3978         {
3979         case VNET_INTERFACE_COUNTER_RX:
3980           return "rx";
3981         case VNET_INTERFACE_COUNTER_TX:
3982           return "tx";
3983         default:
3984           return "INVALID-COUNTER-TYPE";
3985         }
3986     }
3987 }
3988
3989 static int
3990 dump_stats_table (vat_main_t * vam)
3991 {
3992   vat_json_node_t node;
3993   vat_json_node_t *msg_array;
3994   vat_json_node_t *msg;
3995   vat_json_node_t *counter_array;
3996   vat_json_node_t *counter;
3997   interface_counter_t c;
3998   u64 packets;
3999   ip4_fib_counter_t *c4;
4000   ip6_fib_counter_t *c6;
4001   int i, j;
4002
4003   if (!vam->json_output)
4004     {
4005       clib_warning ("dump_stats_table supported only in JSON format");
4006       return -99;
4007     }
4008
4009   vat_json_init_object (&node);
4010
4011   /* interface counters */
4012   msg_array = vat_json_object_add (&node, "interface_counters");
4013   vat_json_init_array (msg_array);
4014   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4015     {
4016       msg = vat_json_array_add (msg_array);
4017       vat_json_init_object (msg);
4018       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4019                                        (u8 *) counter_type_to_str (i, 0));
4020       vat_json_object_add_int (msg, "is_combined", 0);
4021       counter_array = vat_json_object_add (msg, "data");
4022       vat_json_init_array (counter_array);
4023       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4024         {
4025           packets = vam->simple_interface_counters[i][j];
4026           vat_json_array_add_uint (counter_array, packets);
4027         }
4028     }
4029   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4030     {
4031       msg = vat_json_array_add (msg_array);
4032       vat_json_init_object (msg);
4033       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4034                                        (u8 *) counter_type_to_str (i, 1));
4035       vat_json_object_add_int (msg, "is_combined", 1);
4036       counter_array = vat_json_object_add (msg, "data");
4037       vat_json_init_array (counter_array);
4038       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4039         {
4040           c = vam->combined_interface_counters[i][j];
4041           counter = vat_json_array_add (counter_array);
4042           vat_json_init_object (counter);
4043           vat_json_object_add_uint (counter, "packets", c.packets);
4044           vat_json_object_add_uint (counter, "bytes", c.bytes);
4045         }
4046     }
4047
4048   /* ip4 fib counters */
4049   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4050   vat_json_init_array (msg_array);
4051   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4052     {
4053       msg = vat_json_array_add (msg_array);
4054       vat_json_init_object (msg);
4055       vat_json_object_add_uint (msg, "vrf_id",
4056                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4057       counter_array = vat_json_object_add (msg, "c");
4058       vat_json_init_array (counter_array);
4059       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4060         {
4061           counter = vat_json_array_add (counter_array);
4062           vat_json_init_object (counter);
4063           c4 = &vam->ip4_fib_counters[i][j];
4064           vat_json_object_add_ip4 (counter, "address", c4->address);
4065           vat_json_object_add_uint (counter, "address_length",
4066                                     c4->address_length);
4067           vat_json_object_add_uint (counter, "packets", c4->packets);
4068           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4069         }
4070     }
4071
4072   /* ip6 fib counters */
4073   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4074   vat_json_init_array (msg_array);
4075   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4076     {
4077       msg = vat_json_array_add (msg_array);
4078       vat_json_init_object (msg);
4079       vat_json_object_add_uint (msg, "vrf_id",
4080                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4081       counter_array = vat_json_object_add (msg, "c");
4082       vat_json_init_array (counter_array);
4083       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4084         {
4085           counter = vat_json_array_add (counter_array);
4086           vat_json_init_object (counter);
4087           c6 = &vam->ip6_fib_counters[i][j];
4088           vat_json_object_add_ip6 (counter, "address", c6->address);
4089           vat_json_object_add_uint (counter, "address_length",
4090                                     c6->address_length);
4091           vat_json_object_add_uint (counter, "packets", c6->packets);
4092           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4093         }
4094     }
4095
4096   vat_json_print (vam->ofp, &node);
4097   vat_json_free (&node);
4098
4099   return 0;
4100 }
4101
4102 int
4103 exec (vat_main_t * vam)
4104 {
4105   api_main_t *am = &api_main;
4106   vl_api_cli_request_t *mp;
4107   f64 timeout;
4108   void *oldheap;
4109   u8 *cmd = 0;
4110   unformat_input_t *i = vam->input;
4111
4112   if (vec_len (i->buffer) == 0)
4113     return -1;
4114
4115   if (vam->exec_mode == 0 && unformat (i, "mode"))
4116     {
4117       vam->exec_mode = 1;
4118       return 0;
4119     }
4120   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4121     {
4122       vam->exec_mode = 0;
4123       return 0;
4124     }
4125
4126
4127   M (CLI_REQUEST, cli_request);
4128
4129   /*
4130    * Copy cmd into shared memory.
4131    * In order for the CLI command to work, it
4132    * must be a vector ending in \n, not a C-string ending
4133    * in \n\0.
4134    */
4135   pthread_mutex_lock (&am->vlib_rp->mutex);
4136   oldheap = svm_push_data_heap (am->vlib_rp);
4137
4138   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4139   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4140
4141   svm_pop_heap (oldheap);
4142   pthread_mutex_unlock (&am->vlib_rp->mutex);
4143
4144   mp->cmd_in_shmem = (u64) cmd;
4145   S;
4146   timeout = vat_time_now (vam) + 10.0;
4147
4148   while (vat_time_now (vam) < timeout)
4149     {
4150       if (vam->result_ready == 1)
4151         {
4152           u8 *free_me;
4153           if (vam->shmem_result != NULL)
4154             fformat (vam->ofp, "%s", vam->shmem_result);
4155           pthread_mutex_lock (&am->vlib_rp->mutex);
4156           oldheap = svm_push_data_heap (am->vlib_rp);
4157
4158           free_me = (u8 *) vam->shmem_result;
4159           vec_free (free_me);
4160
4161           svm_pop_heap (oldheap);
4162           pthread_mutex_unlock (&am->vlib_rp->mutex);
4163           return 0;
4164         }
4165     }
4166   return -99;
4167 }
4168
4169 /*
4170  * Future replacement of exec() that passes CLI buffers directly in
4171  * the API messages instead of an additional shared memory area.
4172  */
4173 static int
4174 exec_inband (vat_main_t * vam)
4175 {
4176   vl_api_cli_inband_t *mp;
4177   f64 timeout;
4178   unformat_input_t *i = vam->input;
4179
4180   if (vec_len (i->buffer) == 0)
4181     return -1;
4182
4183   if (vam->exec_mode == 0 && unformat (i, "mode"))
4184     {
4185       vam->exec_mode = 1;
4186       return 0;
4187     }
4188   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4189     {
4190       vam->exec_mode = 0;
4191       return 0;
4192     }
4193
4194   /*
4195    * In order for the CLI command to work, it
4196    * must be a vector ending in \n, not a C-string ending
4197    * in \n\0.
4198    */
4199   u32 len = vec_len (vam->input->buffer);
4200   M2 (CLI_INBAND, cli_inband, len);
4201   clib_memcpy (mp->cmd, vam->input->buffer, len);
4202   mp->length = htonl (len);
4203
4204   S;
4205   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4206 }
4207
4208 static int
4209 api_create_loopback (vat_main_t * vam)
4210 {
4211   unformat_input_t *i = vam->input;
4212   vl_api_create_loopback_t *mp;
4213   f64 timeout;
4214   u8 mac_address[6];
4215   u8 mac_set = 0;
4216
4217   memset (mac_address, 0, sizeof (mac_address));
4218
4219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4220     {
4221       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4222         mac_set = 1;
4223       else
4224         break;
4225     }
4226
4227   /* Construct the API message */
4228   M (CREATE_LOOPBACK, create_loopback);
4229   if (mac_set)
4230     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4231
4232   S;
4233   W;
4234 }
4235
4236 static int
4237 api_delete_loopback (vat_main_t * vam)
4238 {
4239   unformat_input_t *i = vam->input;
4240   vl_api_delete_loopback_t *mp;
4241   f64 timeout;
4242   u32 sw_if_index = ~0;
4243
4244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4245     {
4246       if (unformat (i, "sw_if_index %d", &sw_if_index))
4247         ;
4248       else
4249         break;
4250     }
4251
4252   if (sw_if_index == ~0)
4253     {
4254       errmsg ("missing sw_if_index\n");
4255       return -99;
4256     }
4257
4258   /* Construct the API message */
4259   M (DELETE_LOOPBACK, delete_loopback);
4260   mp->sw_if_index = ntohl (sw_if_index);
4261
4262   S;
4263   W;
4264 }
4265
4266 static int
4267 api_want_stats (vat_main_t * vam)
4268 {
4269   unformat_input_t *i = vam->input;
4270   vl_api_want_stats_t *mp;
4271   f64 timeout;
4272   int enable = -1;
4273
4274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4275     {
4276       if (unformat (i, "enable"))
4277         enable = 1;
4278       else if (unformat (i, "disable"))
4279         enable = 0;
4280       else
4281         break;
4282     }
4283
4284   if (enable == -1)
4285     {
4286       errmsg ("missing enable|disable\n");
4287       return -99;
4288     }
4289
4290   M (WANT_STATS, want_stats);
4291   mp->enable_disable = enable;
4292
4293   S;
4294   W;
4295 }
4296
4297 static int
4298 api_want_interface_events (vat_main_t * vam)
4299 {
4300   unformat_input_t *i = vam->input;
4301   vl_api_want_interface_events_t *mp;
4302   f64 timeout;
4303   int enable = -1;
4304
4305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4306     {
4307       if (unformat (i, "enable"))
4308         enable = 1;
4309       else if (unformat (i, "disable"))
4310         enable = 0;
4311       else
4312         break;
4313     }
4314
4315   if (enable == -1)
4316     {
4317       errmsg ("missing enable|disable\n");
4318       return -99;
4319     }
4320
4321   M (WANT_INTERFACE_EVENTS, want_interface_events);
4322   mp->enable_disable = enable;
4323
4324   vam->interface_event_display = enable;
4325
4326   S;
4327   W;
4328 }
4329
4330
4331 /* Note: non-static, called once to set up the initial intfc table */
4332 int
4333 api_sw_interface_dump (vat_main_t * vam)
4334 {
4335   vl_api_sw_interface_dump_t *mp;
4336   f64 timeout;
4337   hash_pair_t *p;
4338   name_sort_t *nses = 0, *ns;
4339   sw_interface_subif_t *sub = NULL;
4340
4341   /* Toss the old name table */
4342   /* *INDENT-OFF* */
4343   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4344   ({
4345     vec_add2 (nses, ns, 1);
4346     ns->name = (u8 *)(p->key);
4347     ns->value = (u32) p->value[0];
4348   }));
4349   /* *INDENT-ON* */
4350
4351   hash_free (vam->sw_if_index_by_interface_name);
4352
4353   vec_foreach (ns, nses) vec_free (ns->name);
4354
4355   vec_free (nses);
4356
4357   vec_foreach (sub, vam->sw_if_subif_table)
4358   {
4359     vec_free (sub->interface_name);
4360   }
4361   vec_free (vam->sw_if_subif_table);
4362
4363   /* recreate the interface name hash table */
4364   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4365
4366   /* Get list of ethernets */
4367   M (SW_INTERFACE_DUMP, sw_interface_dump);
4368   mp->name_filter_valid = 1;
4369   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4370   S;
4371
4372   /* and local / loopback interfaces */
4373   M (SW_INTERFACE_DUMP, sw_interface_dump);
4374   mp->name_filter_valid = 1;
4375   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4376   S;
4377
4378   /* and packet-generator interfaces */
4379   M (SW_INTERFACE_DUMP, sw_interface_dump);
4380   mp->name_filter_valid = 1;
4381   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4382   S;
4383
4384   /* and vxlan-gpe tunnel interfaces */
4385   M (SW_INTERFACE_DUMP, sw_interface_dump);
4386   mp->name_filter_valid = 1;
4387   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4388            sizeof (mp->name_filter) - 1);
4389   S;
4390
4391   /* and vxlan tunnel interfaces */
4392   M (SW_INTERFACE_DUMP, sw_interface_dump);
4393   mp->name_filter_valid = 1;
4394   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4395   S;
4396
4397   /* and host (af_packet) interfaces */
4398   M (SW_INTERFACE_DUMP, sw_interface_dump);
4399   mp->name_filter_valid = 1;
4400   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4401   S;
4402
4403   /* and l2tpv3 tunnel interfaces */
4404   M (SW_INTERFACE_DUMP, sw_interface_dump);
4405   mp->name_filter_valid = 1;
4406   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4407            sizeof (mp->name_filter) - 1);
4408   S;
4409
4410   /* and GRE tunnel interfaces */
4411   M (SW_INTERFACE_DUMP, sw_interface_dump);
4412   mp->name_filter_valid = 1;
4413   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4414   S;
4415
4416   /* and LISP-GPE interfaces */
4417   M (SW_INTERFACE_DUMP, sw_interface_dump);
4418   mp->name_filter_valid = 1;
4419   strncpy ((char *) mp->name_filter, "lisp_gpe",
4420            sizeof (mp->name_filter) - 1);
4421   S;
4422
4423   /* and IPSEC tunnel interfaces */
4424   M (SW_INTERFACE_DUMP, sw_interface_dump);
4425   mp->name_filter_valid = 1;
4426   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4427   S;
4428
4429   /* Use a control ping for synchronization */
4430   {
4431     vl_api_control_ping_t *mp;
4432     M (CONTROL_PING, control_ping);
4433     S;
4434   }
4435   W;
4436 }
4437
4438 static int
4439 api_sw_interface_set_flags (vat_main_t * vam)
4440 {
4441   unformat_input_t *i = vam->input;
4442   vl_api_sw_interface_set_flags_t *mp;
4443   f64 timeout;
4444   u32 sw_if_index;
4445   u8 sw_if_index_set = 0;
4446   u8 admin_up = 0, link_up = 0;
4447
4448   /* Parse args required to build the message */
4449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4450     {
4451       if (unformat (i, "admin-up"))
4452         admin_up = 1;
4453       else if (unformat (i, "admin-down"))
4454         admin_up = 0;
4455       else if (unformat (i, "link-up"))
4456         link_up = 1;
4457       else if (unformat (i, "link-down"))
4458         link_up = 0;
4459       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4460         sw_if_index_set = 1;
4461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4462         sw_if_index_set = 1;
4463       else
4464         break;
4465     }
4466
4467   if (sw_if_index_set == 0)
4468     {
4469       errmsg ("missing interface name or sw_if_index\n");
4470       return -99;
4471     }
4472
4473   /* Construct the API message */
4474   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4475   mp->sw_if_index = ntohl (sw_if_index);
4476   mp->admin_up_down = admin_up;
4477   mp->link_up_down = link_up;
4478
4479   /* send it... */
4480   S;
4481
4482   /* Wait for a reply, return the good/bad news... */
4483   W;
4484 }
4485
4486 static int
4487 api_sw_interface_clear_stats (vat_main_t * vam)
4488 {
4489   unformat_input_t *i = vam->input;
4490   vl_api_sw_interface_clear_stats_t *mp;
4491   f64 timeout;
4492   u32 sw_if_index;
4493   u8 sw_if_index_set = 0;
4494
4495   /* Parse args required to build the message */
4496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4497     {
4498       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4499         sw_if_index_set = 1;
4500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4501         sw_if_index_set = 1;
4502       else
4503         break;
4504     }
4505
4506   /* Construct the API message */
4507   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4508
4509   if (sw_if_index_set == 1)
4510     mp->sw_if_index = ntohl (sw_if_index);
4511   else
4512     mp->sw_if_index = ~0;
4513
4514   /* send it... */
4515   S;
4516
4517   /* Wait for a reply, return the good/bad news... */
4518   W;
4519 }
4520
4521 static int
4522 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4523 {
4524   unformat_input_t *i = vam->input;
4525   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4526   f64 timeout;
4527   u32 sw_if_index;
4528   u8 sw_if_index_set = 0;
4529   u32 subport;
4530   u8 subport_set = 0;
4531   u32 pipe;
4532   u8 pipe_set = 0;
4533   u32 profile;
4534   u8 profile_set = 0;
4535
4536   /* Parse args required to build the message */
4537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4538     {
4539       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4540         sw_if_index_set = 1;
4541       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4542         sw_if_index_set = 1;
4543       else if (unformat (i, "subport %u", &subport))
4544         subport_set = 1;
4545       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4546         sw_if_index_set = 1;
4547       else if (unformat (i, "pipe %u", &pipe))
4548         pipe_set = 1;
4549       else if (unformat (i, "profile %u", &profile))
4550         profile_set = 1;
4551       else
4552         break;
4553     }
4554
4555   if (sw_if_index_set == 0)
4556     {
4557       errmsg ("missing interface name or sw_if_index\n");
4558       return -99;
4559     }
4560
4561   if (subport_set == 0)
4562     {
4563       errmsg ("missing subport \n");
4564       return -99;
4565     }
4566
4567   if (pipe_set == 0)
4568     {
4569       errmsg ("missing pipe\n");
4570       return -99;
4571     }
4572
4573   if (profile_set == 0)
4574     {
4575       errmsg ("missing profile\n");
4576       return -99;
4577     }
4578
4579   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4580
4581   mp->sw_if_index = ntohl (sw_if_index);
4582   mp->subport = ntohl (subport);
4583   mp->pipe = ntohl (pipe);
4584   mp->profile = ntohl (profile);
4585
4586
4587   S;
4588   W;
4589   /* NOTREACHED */
4590   return 0;
4591 }
4592
4593 static int
4594 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4595 {
4596   unformat_input_t *i = vam->input;
4597   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4598   f64 timeout;
4599   u32 sw_if_index;
4600   u8 sw_if_index_set = 0;
4601   u32 subport;
4602   u8 subport_set = 0;
4603   u32 tb_rate = 1250000000;     /* 10GbE */
4604   u32 tb_size = 1000000;
4605   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4606   u32 tc_period = 10;
4607
4608   /* Parse args required to build the message */
4609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4610     {
4611       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4612         sw_if_index_set = 1;
4613       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4614         sw_if_index_set = 1;
4615       else if (unformat (i, "subport %u", &subport))
4616         subport_set = 1;
4617       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4618         sw_if_index_set = 1;
4619       else if (unformat (i, "rate %u", &tb_rate))
4620         {
4621           u32 tc_id;
4622
4623           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4624                tc_id++)
4625             tc_rate[tc_id] = tb_rate;
4626         }
4627       else if (unformat (i, "bktsize %u", &tb_size))
4628         ;
4629       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4630         ;
4631       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4632         ;
4633       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4634         ;
4635       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4636         ;
4637       else if (unformat (i, "period %u", &tc_period))
4638         ;
4639       else
4640         break;
4641     }
4642
4643   if (sw_if_index_set == 0)
4644     {
4645       errmsg ("missing interface name or sw_if_index\n");
4646       return -99;
4647     }
4648
4649   if (subport_set == 0)
4650     {
4651       errmsg ("missing subport \n");
4652       return -99;
4653     }
4654
4655   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4656
4657   mp->sw_if_index = ntohl (sw_if_index);
4658   mp->subport = ntohl (subport);
4659   mp->tb_rate = ntohl (tb_rate);
4660   mp->tb_size = ntohl (tb_size);
4661   mp->tc_rate[0] = ntohl (tc_rate[0]);
4662   mp->tc_rate[1] = ntohl (tc_rate[1]);
4663   mp->tc_rate[2] = ntohl (tc_rate[2]);
4664   mp->tc_rate[3] = ntohl (tc_rate[3]);
4665   mp->tc_period = ntohl (tc_period);
4666
4667   S;
4668   W;
4669   /* NOTREACHED */
4670   return 0;
4671 }
4672
4673 static int
4674 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4675 {
4676   unformat_input_t *i = vam->input;
4677   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4678   f64 timeout;
4679   u32 sw_if_index;
4680   u8 sw_if_index_set = 0;
4681   u8 entry_set = 0;
4682   u8 tc_set = 0;
4683   u8 queue_set = 0;
4684   u32 entry, tc, queue;
4685
4686   /* Parse args required to build the message */
4687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4688     {
4689       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4690         sw_if_index_set = 1;
4691       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4692         sw_if_index_set = 1;
4693       else if (unformat (i, "entry %d", &entry))
4694         entry_set = 1;
4695       else if (unformat (i, "tc %d", &tc))
4696         tc_set = 1;
4697       else if (unformat (i, "queue %d", &queue))
4698         queue_set = 1;
4699       else
4700         break;
4701     }
4702
4703   if (sw_if_index_set == 0)
4704     {
4705       errmsg ("missing interface name or sw_if_index\n");
4706       return -99;
4707     }
4708
4709   if (entry_set == 0)
4710     {
4711       errmsg ("missing entry \n");
4712       return -99;
4713     }
4714
4715   if (tc_set == 0)
4716     {
4717       errmsg ("missing traffic class \n");
4718       return -99;
4719     }
4720
4721   if (queue_set == 0)
4722     {
4723       errmsg ("missing queue \n");
4724       return -99;
4725     }
4726
4727   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4728
4729   mp->sw_if_index = ntohl (sw_if_index);
4730   mp->entry = ntohl (entry);
4731   mp->tc = ntohl (tc);
4732   mp->queue = ntohl (queue);
4733
4734   S;
4735   W;
4736   /* NOTREACHED */
4737   return 0;
4738 }
4739
4740 static int
4741 api_sw_interface_add_del_address (vat_main_t * vam)
4742 {
4743   unformat_input_t *i = vam->input;
4744   vl_api_sw_interface_add_del_address_t *mp;
4745   f64 timeout;
4746   u32 sw_if_index;
4747   u8 sw_if_index_set = 0;
4748   u8 is_add = 1, del_all = 0;
4749   u32 address_length = 0;
4750   u8 v4_address_set = 0;
4751   u8 v6_address_set = 0;
4752   ip4_address_t v4address;
4753   ip6_address_t v6address;
4754
4755   /* Parse args required to build the message */
4756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4757     {
4758       if (unformat (i, "del-all"))
4759         del_all = 1;
4760       else if (unformat (i, "del"))
4761         is_add = 0;
4762       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4765         sw_if_index_set = 1;
4766       else if (unformat (i, "%U/%d",
4767                          unformat_ip4_address, &v4address, &address_length))
4768         v4_address_set = 1;
4769       else if (unformat (i, "%U/%d",
4770                          unformat_ip6_address, &v6address, &address_length))
4771         v6_address_set = 1;
4772       else
4773         break;
4774     }
4775
4776   if (sw_if_index_set == 0)
4777     {
4778       errmsg ("missing interface name or sw_if_index\n");
4779       return -99;
4780     }
4781   if (v4_address_set && v6_address_set)
4782     {
4783       errmsg ("both v4 and v6 addresses set\n");
4784       return -99;
4785     }
4786   if (!v4_address_set && !v6_address_set && !del_all)
4787     {
4788       errmsg ("no addresses set\n");
4789       return -99;
4790     }
4791
4792   /* Construct the API message */
4793   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4794
4795   mp->sw_if_index = ntohl (sw_if_index);
4796   mp->is_add = is_add;
4797   mp->del_all = del_all;
4798   if (v6_address_set)
4799     {
4800       mp->is_ipv6 = 1;
4801       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4802     }
4803   else
4804     {
4805       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4806     }
4807   mp->address_length = address_length;
4808
4809   /* send it... */
4810   S;
4811
4812   /* Wait for a reply, return good/bad news  */
4813   W;
4814 }
4815
4816 static int
4817 api_sw_interface_set_table (vat_main_t * vam)
4818 {
4819   unformat_input_t *i = vam->input;
4820   vl_api_sw_interface_set_table_t *mp;
4821   f64 timeout;
4822   u32 sw_if_index, vrf_id = 0;
4823   u8 sw_if_index_set = 0;
4824   u8 is_ipv6 = 0;
4825
4826   /* Parse args required to build the message */
4827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4828     {
4829       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4830         sw_if_index_set = 1;
4831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4832         sw_if_index_set = 1;
4833       else if (unformat (i, "vrf %d", &vrf_id))
4834         ;
4835       else if (unformat (i, "ipv6"))
4836         is_ipv6 = 1;
4837       else
4838         break;
4839     }
4840
4841   if (sw_if_index_set == 0)
4842     {
4843       errmsg ("missing interface name or sw_if_index\n");
4844       return -99;
4845     }
4846
4847   /* Construct the API message */
4848   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4849
4850   mp->sw_if_index = ntohl (sw_if_index);
4851   mp->is_ipv6 = is_ipv6;
4852   mp->vrf_id = ntohl (vrf_id);
4853
4854   /* send it... */
4855   S;
4856
4857   /* Wait for a reply... */
4858   W;
4859 }
4860
4861 static int
4862 api_sw_interface_set_vpath (vat_main_t * vam)
4863 {
4864   unformat_input_t *i = vam->input;
4865   vl_api_sw_interface_set_vpath_t *mp;
4866   f64 timeout;
4867   u32 sw_if_index = 0;
4868   u8 sw_if_index_set = 0;
4869   u8 is_enable = 0;
4870
4871   /* Parse args required to build the message */
4872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4873     {
4874       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4875         sw_if_index_set = 1;
4876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4877         sw_if_index_set = 1;
4878       else if (unformat (i, "enable"))
4879         is_enable = 1;
4880       else if (unformat (i, "disable"))
4881         is_enable = 0;
4882       else
4883         break;
4884     }
4885
4886   if (sw_if_index_set == 0)
4887     {
4888       errmsg ("missing interface name or sw_if_index\n");
4889       return -99;
4890     }
4891
4892   /* Construct the API message */
4893   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4894
4895   mp->sw_if_index = ntohl (sw_if_index);
4896   mp->enable = is_enable;
4897
4898   /* send it... */
4899   S;
4900
4901   /* Wait for a reply... */
4902   W;
4903 }
4904
4905 static int
4906 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4907 {
4908   unformat_input_t *i = vam->input;
4909   vl_api_sw_interface_set_l2_xconnect_t *mp;
4910   f64 timeout;
4911   u32 rx_sw_if_index;
4912   u8 rx_sw_if_index_set = 0;
4913   u32 tx_sw_if_index;
4914   u8 tx_sw_if_index_set = 0;
4915   u8 enable = 1;
4916
4917   /* Parse args required to build the message */
4918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4919     {
4920       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4921         rx_sw_if_index_set = 1;
4922       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4923         tx_sw_if_index_set = 1;
4924       else if (unformat (i, "rx"))
4925         {
4926           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4927             {
4928               if (unformat (i, "%U", unformat_sw_if_index, vam,
4929                             &rx_sw_if_index))
4930                 rx_sw_if_index_set = 1;
4931             }
4932           else
4933             break;
4934         }
4935       else if (unformat (i, "tx"))
4936         {
4937           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4938             {
4939               if (unformat (i, "%U", unformat_sw_if_index, vam,
4940                             &tx_sw_if_index))
4941                 tx_sw_if_index_set = 1;
4942             }
4943           else
4944             break;
4945         }
4946       else if (unformat (i, "enable"))
4947         enable = 1;
4948       else if (unformat (i, "disable"))
4949         enable = 0;
4950       else
4951         break;
4952     }
4953
4954   if (rx_sw_if_index_set == 0)
4955     {
4956       errmsg ("missing rx interface name or rx_sw_if_index\n");
4957       return -99;
4958     }
4959
4960   if (enable && (tx_sw_if_index_set == 0))
4961     {
4962       errmsg ("missing tx interface name or tx_sw_if_index\n");
4963       return -99;
4964     }
4965
4966   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4967
4968   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4969   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4970   mp->enable = enable;
4971
4972   S;
4973   W;
4974   /* NOTREACHED */
4975   return 0;
4976 }
4977
4978 static int
4979 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4980 {
4981   unformat_input_t *i = vam->input;
4982   vl_api_sw_interface_set_l2_bridge_t *mp;
4983   f64 timeout;
4984   u32 rx_sw_if_index;
4985   u8 rx_sw_if_index_set = 0;
4986   u32 bd_id;
4987   u8 bd_id_set = 0;
4988   u8 bvi = 0;
4989   u32 shg = 0;
4990   u8 enable = 1;
4991
4992   /* Parse args required to build the message */
4993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4994     {
4995       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4996         rx_sw_if_index_set = 1;
4997       else if (unformat (i, "bd_id %d", &bd_id))
4998         bd_id_set = 1;
4999       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5000         rx_sw_if_index_set = 1;
5001       else if (unformat (i, "shg %d", &shg))
5002         ;
5003       else if (unformat (i, "bvi"))
5004         bvi = 1;
5005       else if (unformat (i, "enable"))
5006         enable = 1;
5007       else if (unformat (i, "disable"))
5008         enable = 0;
5009       else
5010         break;
5011     }
5012
5013   if (rx_sw_if_index_set == 0)
5014     {
5015       errmsg ("missing rx interface name or sw_if_index\n");
5016       return -99;
5017     }
5018
5019   if (enable && (bd_id_set == 0))
5020     {
5021       errmsg ("missing bridge domain\n");
5022       return -99;
5023     }
5024
5025   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5026
5027   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5028   mp->bd_id = ntohl (bd_id);
5029   mp->shg = (u8) shg;
5030   mp->bvi = bvi;
5031   mp->enable = enable;
5032
5033   S;
5034   W;
5035   /* NOTREACHED */
5036   return 0;
5037 }
5038
5039 static int
5040 api_bridge_domain_dump (vat_main_t * vam)
5041 {
5042   unformat_input_t *i = vam->input;
5043   vl_api_bridge_domain_dump_t *mp;
5044   f64 timeout;
5045   u32 bd_id = ~0;
5046
5047   /* Parse args required to build the message */
5048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5049     {
5050       if (unformat (i, "bd_id %d", &bd_id))
5051         ;
5052       else
5053         break;
5054     }
5055
5056   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5057   mp->bd_id = ntohl (bd_id);
5058   S;
5059
5060   /* Use a control ping for synchronization */
5061   {
5062     vl_api_control_ping_t *mp;
5063     M (CONTROL_PING, control_ping);
5064     S;
5065   }
5066
5067   W;
5068   /* NOTREACHED */
5069   return 0;
5070 }
5071
5072 static int
5073 api_bridge_domain_add_del (vat_main_t * vam)
5074 {
5075   unformat_input_t *i = vam->input;
5076   vl_api_bridge_domain_add_del_t *mp;
5077   f64 timeout;
5078   u32 bd_id = ~0;
5079   u8 is_add = 1;
5080   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5081
5082   /* Parse args required to build the message */
5083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5084     {
5085       if (unformat (i, "bd_id %d", &bd_id))
5086         ;
5087       else if (unformat (i, "flood %d", &flood))
5088         ;
5089       else if (unformat (i, "uu-flood %d", &uu_flood))
5090         ;
5091       else if (unformat (i, "forward %d", &forward))
5092         ;
5093       else if (unformat (i, "learn %d", &learn))
5094         ;
5095       else if (unformat (i, "arp-term %d", &arp_term))
5096         ;
5097       else if (unformat (i, "del"))
5098         {
5099           is_add = 0;
5100           flood = uu_flood = forward = learn = 0;
5101         }
5102       else
5103         break;
5104     }
5105
5106   if (bd_id == ~0)
5107     {
5108       errmsg ("missing bridge domain\n");
5109       return -99;
5110     }
5111
5112   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5113
5114   mp->bd_id = ntohl (bd_id);
5115   mp->flood = flood;
5116   mp->uu_flood = uu_flood;
5117   mp->forward = forward;
5118   mp->learn = learn;
5119   mp->arp_term = arp_term;
5120   mp->is_add = is_add;
5121
5122   S;
5123   W;
5124   /* NOTREACHED */
5125   return 0;
5126 }
5127
5128 static int
5129 api_l2fib_add_del (vat_main_t * vam)
5130 {
5131   unformat_input_t *i = vam->input;
5132   vl_api_l2fib_add_del_t *mp;
5133   f64 timeout;
5134   u64 mac = 0;
5135   u8 mac_set = 0;
5136   u32 bd_id;
5137   u8 bd_id_set = 0;
5138   u32 sw_if_index;
5139   u8 sw_if_index_set = 0;
5140   u8 is_add = 1;
5141   u8 static_mac = 0;
5142   u8 filter_mac = 0;
5143   u8 bvi_mac = 0;
5144   int count = 1;
5145   f64 before = 0;
5146   int j;
5147
5148   /* Parse args required to build the message */
5149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5150     {
5151       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5152         mac_set = 1;
5153       else if (unformat (i, "bd_id %d", &bd_id))
5154         bd_id_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, "sw_if"))
5158         {
5159           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5160             {
5161               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5162                 sw_if_index_set = 1;
5163             }
5164           else
5165             break;
5166         }
5167       else if (unformat (i, "static"))
5168         static_mac = 1;
5169       else if (unformat (i, "filter"))
5170         {
5171           filter_mac = 1;
5172           static_mac = 1;
5173         }
5174       else if (unformat (i, "bvi"))
5175         {
5176           bvi_mac = 1;
5177           static_mac = 1;
5178         }
5179       else if (unformat (i, "del"))
5180         is_add = 0;
5181       else if (unformat (i, "count %d", &count))
5182         ;
5183       else
5184         break;
5185     }
5186
5187   if (mac_set == 0)
5188     {
5189       errmsg ("missing mac address\n");
5190       return -99;
5191     }
5192
5193   if (bd_id_set == 0)
5194     {
5195       errmsg ("missing bridge domain\n");
5196       return -99;
5197     }
5198
5199   if (is_add && (sw_if_index_set == 0))
5200     {
5201       errmsg ("missing interface name or sw_if_index\n");
5202       return -99;
5203     }
5204
5205   if (count > 1)
5206     {
5207       /* Turn on async mode */
5208       vam->async_mode = 1;
5209       vam->async_errors = 0;
5210       before = vat_time_now (vam);
5211     }
5212
5213   for (j = 0; j < count; j++)
5214     {
5215       M (L2FIB_ADD_DEL, l2fib_add_del);
5216
5217       mp->mac = mac;
5218       mp->bd_id = ntohl (bd_id);
5219       mp->is_add = is_add;
5220
5221       if (is_add)
5222         {
5223           mp->sw_if_index = ntohl (sw_if_index);
5224           mp->static_mac = static_mac;
5225           mp->filter_mac = filter_mac;
5226           mp->bvi_mac = bvi_mac;
5227         }
5228       increment_mac_address (&mac);
5229       /* send it... */
5230       S;
5231     }
5232
5233   if (count > 1)
5234     {
5235       vl_api_control_ping_t *mp;
5236       f64 after;
5237
5238       /* Shut off async mode */
5239       vam->async_mode = 0;
5240
5241       M (CONTROL_PING, control_ping);
5242       S;
5243
5244       timeout = vat_time_now (vam) + 1.0;
5245       while (vat_time_now (vam) < timeout)
5246         if (vam->result_ready == 1)
5247           goto out;
5248       vam->retval = -99;
5249
5250     out:
5251       if (vam->retval == -99)
5252         errmsg ("timeout\n");
5253
5254       if (vam->async_errors > 0)
5255         {
5256           errmsg ("%d asynchronous errors\n", vam->async_errors);
5257           vam->retval = -98;
5258         }
5259       vam->async_errors = 0;
5260       after = vat_time_now (vam);
5261
5262       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5263                count, after - before, count / (after - before));
5264     }
5265   else
5266     {
5267       /* Wait for a reply... */
5268       W;
5269     }
5270   /* Return the good/bad news */
5271   return (vam->retval);
5272 }
5273
5274 static int
5275 api_l2_flags (vat_main_t * vam)
5276 {
5277   unformat_input_t *i = vam->input;
5278   vl_api_l2_flags_t *mp;
5279   f64 timeout;
5280   u32 sw_if_index;
5281   u32 feature_bitmap = 0;
5282   u8 sw_if_index_set = 0;
5283
5284   /* Parse args required to build the message */
5285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5286     {
5287       if (unformat (i, "sw_if_index %d", &sw_if_index))
5288         sw_if_index_set = 1;
5289       else if (unformat (i, "sw_if"))
5290         {
5291           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5292             {
5293               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5294                 sw_if_index_set = 1;
5295             }
5296           else
5297             break;
5298         }
5299       else if (unformat (i, "learn"))
5300         feature_bitmap |= L2INPUT_FEAT_LEARN;
5301       else if (unformat (i, "forward"))
5302         feature_bitmap |= L2INPUT_FEAT_FWD;
5303       else if (unformat (i, "flood"))
5304         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5305       else if (unformat (i, "uu-flood"))
5306         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5307       else
5308         break;
5309     }
5310
5311   if (sw_if_index_set == 0)
5312     {
5313       errmsg ("missing interface name or sw_if_index\n");
5314       return -99;
5315     }
5316
5317   M (L2_FLAGS, l2_flags);
5318
5319   mp->sw_if_index = ntohl (sw_if_index);
5320   mp->feature_bitmap = ntohl (feature_bitmap);
5321
5322   S;
5323   W;
5324   /* NOTREACHED */
5325   return 0;
5326 }
5327
5328 static int
5329 api_bridge_flags (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_bridge_flags_t *mp;
5333   f64 timeout;
5334   u32 bd_id;
5335   u8 bd_id_set = 0;
5336   u8 is_set = 1;
5337   u32 flags = 0;
5338
5339   /* Parse args required to build the message */
5340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5341     {
5342       if (unformat (i, "bd_id %d", &bd_id))
5343         bd_id_set = 1;
5344       else if (unformat (i, "learn"))
5345         flags |= L2_LEARN;
5346       else if (unformat (i, "forward"))
5347         flags |= L2_FWD;
5348       else if (unformat (i, "flood"))
5349         flags |= L2_FLOOD;
5350       else if (unformat (i, "uu-flood"))
5351         flags |= L2_UU_FLOOD;
5352       else if (unformat (i, "arp-term"))
5353         flags |= L2_ARP_TERM;
5354       else if (unformat (i, "off"))
5355         is_set = 0;
5356       else if (unformat (i, "disable"))
5357         is_set = 0;
5358       else
5359         break;
5360     }
5361
5362   if (bd_id_set == 0)
5363     {
5364       errmsg ("missing bridge domain\n");
5365       return -99;
5366     }
5367
5368   M (BRIDGE_FLAGS, bridge_flags);
5369
5370   mp->bd_id = ntohl (bd_id);
5371   mp->feature_bitmap = ntohl (flags);
5372   mp->is_set = is_set;
5373
5374   S;
5375   W;
5376   /* NOTREACHED */
5377   return 0;
5378 }
5379
5380 static int
5381 api_bd_ip_mac_add_del (vat_main_t * vam)
5382 {
5383   unformat_input_t *i = vam->input;
5384   vl_api_bd_ip_mac_add_del_t *mp;
5385   f64 timeout;
5386   u32 bd_id;
5387   u8 is_ipv6 = 0;
5388   u8 is_add = 1;
5389   u8 bd_id_set = 0;
5390   u8 ip_set = 0;
5391   u8 mac_set = 0;
5392   ip4_address_t v4addr;
5393   ip6_address_t v6addr;
5394   u8 macaddr[6];
5395
5396
5397   /* Parse args required to build the message */
5398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5399     {
5400       if (unformat (i, "bd_id %d", &bd_id))
5401         {
5402           bd_id_set++;
5403         }
5404       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5405         {
5406           ip_set++;
5407         }
5408       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5409         {
5410           ip_set++;
5411           is_ipv6++;
5412         }
5413       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5414         {
5415           mac_set++;
5416         }
5417       else if (unformat (i, "del"))
5418         is_add = 0;
5419       else
5420         break;
5421     }
5422
5423   if (bd_id_set == 0)
5424     {
5425       errmsg ("missing bridge domain\n");
5426       return -99;
5427     }
5428   else if (ip_set == 0)
5429     {
5430       errmsg ("missing IP address\n");
5431       return -99;
5432     }
5433   else if (mac_set == 0)
5434     {
5435       errmsg ("missing MAC address\n");
5436       return -99;
5437     }
5438
5439   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5440
5441   mp->bd_id = ntohl (bd_id);
5442   mp->is_ipv6 = is_ipv6;
5443   mp->is_add = is_add;
5444   if (is_ipv6)
5445     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5446   else
5447     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5448   clib_memcpy (mp->mac_address, macaddr, 6);
5449   S;
5450   W;
5451   /* NOTREACHED */
5452   return 0;
5453 }
5454
5455 static int
5456 api_tap_connect (vat_main_t * vam)
5457 {
5458   unformat_input_t *i = vam->input;
5459   vl_api_tap_connect_t *mp;
5460   f64 timeout;
5461   u8 mac_address[6];
5462   u8 random_mac = 1;
5463   u8 name_set = 0;
5464   u8 *tap_name;
5465
5466   memset (mac_address, 0, sizeof (mac_address));
5467
5468   /* Parse args required to build the message */
5469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5470     {
5471       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5472         {
5473           random_mac = 0;
5474         }
5475       else if (unformat (i, "random-mac"))
5476         random_mac = 1;
5477       else if (unformat (i, "tapname %s", &tap_name))
5478         name_set = 1;
5479       else
5480         break;
5481     }
5482
5483   if (name_set == 0)
5484     {
5485       errmsg ("missing tap name\n");
5486       return -99;
5487     }
5488   if (vec_len (tap_name) > 63)
5489     {
5490       errmsg ("tap name too long\n");
5491     }
5492   vec_add1 (tap_name, 0);
5493
5494   /* Construct the API message */
5495   M (TAP_CONNECT, tap_connect);
5496
5497   mp->use_random_mac = random_mac;
5498   clib_memcpy (mp->mac_address, mac_address, 6);
5499   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5500   vec_free (tap_name);
5501
5502   /* send it... */
5503   S;
5504
5505   /* Wait for a reply... */
5506   W;
5507 }
5508
5509 static int
5510 api_tap_modify (vat_main_t * vam)
5511 {
5512   unformat_input_t *i = vam->input;
5513   vl_api_tap_modify_t *mp;
5514   f64 timeout;
5515   u8 mac_address[6];
5516   u8 random_mac = 1;
5517   u8 name_set = 0;
5518   u8 *tap_name;
5519   u32 sw_if_index = ~0;
5520   u8 sw_if_index_set = 0;
5521
5522   memset (mac_address, 0, sizeof (mac_address));
5523
5524   /* Parse args required to build the message */
5525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5526     {
5527       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5528         sw_if_index_set = 1;
5529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5530         sw_if_index_set = 1;
5531       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5532         {
5533           random_mac = 0;
5534         }
5535       else if (unformat (i, "random-mac"))
5536         random_mac = 1;
5537       else if (unformat (i, "tapname %s", &tap_name))
5538         name_set = 1;
5539       else
5540         break;
5541     }
5542
5543   if (sw_if_index_set == 0)
5544     {
5545       errmsg ("missing vpp interface name");
5546       return -99;
5547     }
5548   if (name_set == 0)
5549     {
5550       errmsg ("missing tap name\n");
5551       return -99;
5552     }
5553   if (vec_len (tap_name) > 63)
5554     {
5555       errmsg ("tap name too long\n");
5556     }
5557   vec_add1 (tap_name, 0);
5558
5559   /* Construct the API message */
5560   M (TAP_MODIFY, tap_modify);
5561
5562   mp->use_random_mac = random_mac;
5563   mp->sw_if_index = ntohl (sw_if_index);
5564   clib_memcpy (mp->mac_address, mac_address, 6);
5565   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5566   vec_free (tap_name);
5567
5568   /* send it... */
5569   S;
5570
5571   /* Wait for a reply... */
5572   W;
5573 }
5574
5575 static int
5576 api_tap_delete (vat_main_t * vam)
5577 {
5578   unformat_input_t *i = vam->input;
5579   vl_api_tap_delete_t *mp;
5580   f64 timeout;
5581   u32 sw_if_index = ~0;
5582   u8 sw_if_index_set = 0;
5583
5584   /* Parse args required to build the message */
5585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5586     {
5587       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5588         sw_if_index_set = 1;
5589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5590         sw_if_index_set = 1;
5591       else
5592         break;
5593     }
5594
5595   if (sw_if_index_set == 0)
5596     {
5597       errmsg ("missing vpp interface name");
5598       return -99;
5599     }
5600
5601   /* Construct the API message */
5602   M (TAP_DELETE, tap_delete);
5603
5604   mp->sw_if_index = ntohl (sw_if_index);
5605
5606   /* send it... */
5607   S;
5608
5609   /* Wait for a reply... */
5610   W;
5611 }
5612
5613 static int
5614 api_ip_add_del_route (vat_main_t * vam)
5615 {
5616   unformat_input_t *i = vam->input;
5617   vl_api_ip_add_del_route_t *mp;
5618   f64 timeout;
5619   u32 sw_if_index = ~0, vrf_id = 0;
5620   u8 sw_if_index_set = 0;
5621   u8 is_ipv6 = 0;
5622   u8 is_local = 0, is_drop = 0;
5623   u8 create_vrf_if_needed = 0;
5624   u8 is_add = 1;
5625   u8 next_hop_weight = 1;
5626   u8 not_last = 0;
5627   u8 is_multipath = 0;
5628   u8 address_set = 0;
5629   u8 address_length_set = 0;
5630   u32 lookup_in_vrf = 0;
5631   u32 resolve_attempts = 0;
5632   u32 dst_address_length = 0;
5633   u8 next_hop_set = 0;
5634   ip4_address_t v4_dst_address, v4_next_hop_address;
5635   ip6_address_t v6_dst_address, v6_next_hop_address;
5636   int count = 1;
5637   int j;
5638   f64 before = 0;
5639   u32 random_add_del = 0;
5640   u32 *random_vector = 0;
5641   uword *random_hash;
5642   u32 random_seed = 0xdeaddabe;
5643   u32 classify_table_index = ~0;
5644   u8 is_classify = 0;
5645   u8 resolve_host = 0, resolve_attached = 0;
5646
5647   /* Parse args required to build the message */
5648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649     {
5650       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5651         sw_if_index_set = 1;
5652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5653         sw_if_index_set = 1;
5654       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5655         {
5656           address_set = 1;
5657           is_ipv6 = 0;
5658         }
5659       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5660         {
5661           address_set = 1;
5662           is_ipv6 = 1;
5663         }
5664       else if (unformat (i, "/%d", &dst_address_length))
5665         {
5666           address_length_set = 1;
5667         }
5668
5669       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5670                                          &v4_next_hop_address))
5671         {
5672           next_hop_set = 1;
5673         }
5674       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5675                                          &v6_next_hop_address))
5676         {
5677           next_hop_set = 1;
5678         }
5679       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5680         ;
5681       else if (unformat (i, "weight %d", &next_hop_weight))
5682         ;
5683       else if (unformat (i, "drop"))
5684         {
5685           is_drop = 1;
5686         }
5687       else if (unformat (i, "local"))
5688         {
5689           is_local = 1;
5690         }
5691       else if (unformat (i, "classify %d", &classify_table_index))
5692         {
5693           is_classify = 1;
5694         }
5695       else if (unformat (i, "del"))
5696         is_add = 0;
5697       else if (unformat (i, "add"))
5698         is_add = 1;
5699       else if (unformat (i, "not-last"))
5700         not_last = 1;
5701       else if (unformat (i, "resolve-via-host"))
5702         resolve_host = 1;
5703       else if (unformat (i, "resolve-via-attached"))
5704         resolve_attached = 1;
5705       else if (unformat (i, "multipath"))
5706         is_multipath = 1;
5707       else if (unformat (i, "vrf %d", &vrf_id))
5708         ;
5709       else if (unformat (i, "create-vrf"))
5710         create_vrf_if_needed = 1;
5711       else if (unformat (i, "count %d", &count))
5712         ;
5713       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5714         ;
5715       else if (unformat (i, "random"))
5716         random_add_del = 1;
5717       else if (unformat (i, "seed %d", &random_seed))
5718         ;
5719       else
5720         {
5721           clib_warning ("parse error '%U'", format_unformat_error, i);
5722           return -99;
5723         }
5724     }
5725
5726   if (resolve_attempts > 0 && sw_if_index_set == 0)
5727     {
5728       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5729       return -99;
5730     }
5731
5732   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5733     {
5734       errmsg ("next hop / local / drop / classify not set\n");
5735       return -99;
5736     }
5737
5738   if (address_set == 0)
5739     {
5740       errmsg ("missing addresses\n");
5741       return -99;
5742     }
5743
5744   if (address_length_set == 0)
5745     {
5746       errmsg ("missing address length\n");
5747       return -99;
5748     }
5749
5750   /* Generate a pile of unique, random routes */
5751   if (random_add_del)
5752     {
5753       u32 this_random_address;
5754       random_hash = hash_create (count, sizeof (uword));
5755
5756       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5757       for (j = 0; j <= count; j++)
5758         {
5759           do
5760             {
5761               this_random_address = random_u32 (&random_seed);
5762               this_random_address =
5763                 clib_host_to_net_u32 (this_random_address);
5764             }
5765           while (hash_get (random_hash, this_random_address));
5766           vec_add1 (random_vector, this_random_address);
5767           hash_set (random_hash, this_random_address, 1);
5768         }
5769       hash_free (random_hash);
5770       v4_dst_address.as_u32 = random_vector[0];
5771     }
5772
5773   if (count > 1)
5774     {
5775       /* Turn on async mode */
5776       vam->async_mode = 1;
5777       vam->async_errors = 0;
5778       before = vat_time_now (vam);
5779     }
5780
5781   for (j = 0; j < count; j++)
5782     {
5783       /* Construct the API message */
5784       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5785
5786       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5787       mp->vrf_id = ntohl (vrf_id);
5788       if (resolve_attempts > 0)
5789         {
5790           mp->resolve_attempts = ntohl (resolve_attempts);
5791           mp->resolve_if_needed = 1;
5792         }
5793       mp->create_vrf_if_needed = create_vrf_if_needed;
5794
5795       mp->is_add = is_add;
5796       mp->is_drop = is_drop;
5797       mp->is_ipv6 = is_ipv6;
5798       mp->is_local = is_local;
5799       mp->is_classify = is_classify;
5800       mp->is_multipath = is_multipath;
5801       mp->is_resolve_host = resolve_host;
5802       mp->is_resolve_attached = resolve_attached;
5803       mp->not_last = not_last;
5804       mp->next_hop_weight = next_hop_weight;
5805       mp->dst_address_length = dst_address_length;
5806       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5807       mp->classify_table_index = ntohl (classify_table_index);
5808
5809       if (is_ipv6)
5810         {
5811           clib_memcpy (mp->dst_address, &v6_dst_address,
5812                        sizeof (v6_dst_address));
5813           if (next_hop_set)
5814             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5815                          sizeof (v6_next_hop_address));
5816           increment_v6_address (&v6_dst_address);
5817         }
5818       else
5819         {
5820           clib_memcpy (mp->dst_address, &v4_dst_address,
5821                        sizeof (v4_dst_address));
5822           if (next_hop_set)
5823             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5824                          sizeof (v4_next_hop_address));
5825           if (random_add_del)
5826             v4_dst_address.as_u32 = random_vector[j + 1];
5827           else
5828             increment_v4_address (&v4_dst_address);
5829         }
5830       /* send it... */
5831       S;
5832       /* If we receive SIGTERM, stop now... */
5833       if (vam->do_exit)
5834         break;
5835     }
5836
5837   /* When testing multiple add/del ops, use a control-ping to sync */
5838   if (count > 1)
5839     {
5840       vl_api_control_ping_t *mp;
5841       f64 after;
5842
5843       /* Shut off async mode */
5844       vam->async_mode = 0;
5845
5846       M (CONTROL_PING, control_ping);
5847       S;
5848
5849       timeout = vat_time_now (vam) + 1.0;
5850       while (vat_time_now (vam) < timeout)
5851         if (vam->result_ready == 1)
5852           goto out;
5853       vam->retval = -99;
5854
5855     out:
5856       if (vam->retval == -99)
5857         errmsg ("timeout\n");
5858
5859       if (vam->async_errors > 0)
5860         {
5861           errmsg ("%d asynchronous errors\n", vam->async_errors);
5862           vam->retval = -98;
5863         }
5864       vam->async_errors = 0;
5865       after = vat_time_now (vam);
5866
5867       /* slim chance, but we might have eaten SIGTERM on the first iteration */
5868       if (j > 0)
5869         count = j;
5870
5871       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5872                count, after - before, count / (after - before));
5873     }
5874   else
5875     {
5876       /* Wait for a reply... */
5877       W;
5878     }
5879
5880   /* Return the good/bad news */
5881   return (vam->retval);
5882 }
5883
5884 static int
5885 api_proxy_arp_add_del (vat_main_t * vam)
5886 {
5887   unformat_input_t *i = vam->input;
5888   vl_api_proxy_arp_add_del_t *mp;
5889   f64 timeout;
5890   u32 vrf_id = 0;
5891   u8 is_add = 1;
5892   ip4_address_t lo, hi;
5893   u8 range_set = 0;
5894
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "vrf %d", &vrf_id))
5898         ;
5899       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5900                          unformat_ip4_address, &hi))
5901         range_set = 1;
5902       else if (unformat (i, "del"))
5903         is_add = 0;
5904       else
5905         {
5906           clib_warning ("parse error '%U'", format_unformat_error, i);
5907           return -99;
5908         }
5909     }
5910
5911   if (range_set == 0)
5912     {
5913       errmsg ("address range not set\n");
5914       return -99;
5915     }
5916
5917   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5918
5919   mp->vrf_id = ntohl (vrf_id);
5920   mp->is_add = is_add;
5921   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5922   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5923
5924   S;
5925   W;
5926   /* NOTREACHED */
5927   return 0;
5928 }
5929
5930 static int
5931 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5932 {
5933   unformat_input_t *i = vam->input;
5934   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5935   f64 timeout;
5936   u32 sw_if_index;
5937   u8 enable = 1;
5938   u8 sw_if_index_set = 0;
5939
5940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5941     {
5942       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5943         sw_if_index_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else if (unformat (i, "enable"))
5947         enable = 1;
5948       else if (unformat (i, "disable"))
5949         enable = 0;
5950       else
5951         {
5952           clib_warning ("parse error '%U'", format_unformat_error, i);
5953           return -99;
5954         }
5955     }
5956
5957   if (sw_if_index_set == 0)
5958     {
5959       errmsg ("missing interface name or sw_if_index\n");
5960       return -99;
5961     }
5962
5963   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5964
5965   mp->sw_if_index = ntohl (sw_if_index);
5966   mp->enable_disable = enable;
5967
5968   S;
5969   W;
5970   /* NOTREACHED */
5971   return 0;
5972 }
5973
5974 static int
5975 api_mpls_add_del_decap (vat_main_t * vam)
5976 {
5977   unformat_input_t *i = vam->input;
5978   vl_api_mpls_add_del_decap_t *mp;
5979   f64 timeout;
5980   u32 rx_vrf_id = 0;
5981   u32 tx_vrf_id = 0;
5982   u32 label = 0;
5983   u8 is_add = 1;
5984   u8 s_bit = 1;
5985   u32 next_index = 1;
5986
5987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5988     {
5989       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5990         ;
5991       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5992         ;
5993       else if (unformat (i, "label %d", &label))
5994         ;
5995       else if (unformat (i, "next-index %d", &next_index))
5996         ;
5997       else if (unformat (i, "del"))
5998         is_add = 0;
5999       else if (unformat (i, "s-bit-clear"))
6000         s_bit = 0;
6001       else
6002         {
6003           clib_warning ("parse error '%U'", format_unformat_error, i);
6004           return -99;
6005         }
6006     }
6007
6008   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
6009
6010   mp->rx_vrf_id = ntohl (rx_vrf_id);
6011   mp->tx_vrf_id = ntohl (tx_vrf_id);
6012   mp->label = ntohl (label);
6013   mp->next_index = ntohl (next_index);
6014   mp->s_bit = s_bit;
6015   mp->is_add = is_add;
6016
6017   S;
6018   W;
6019   /* NOTREACHED */
6020   return 0;
6021 }
6022
6023 static int
6024 api_mpls_add_del_encap (vat_main_t * vam)
6025 {
6026   unformat_input_t *i = vam->input;
6027   vl_api_mpls_add_del_encap_t *mp;
6028   f64 timeout;
6029   u32 vrf_id = 0;
6030   u32 *labels = 0;
6031   u32 label;
6032   ip4_address_t dst_address;
6033   u8 is_add = 1;
6034
6035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6036     {
6037       if (unformat (i, "vrf %d", &vrf_id))
6038         ;
6039       else if (unformat (i, "label %d", &label))
6040         vec_add1 (labels, ntohl (label));
6041       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6042         ;
6043       else if (unformat (i, "del"))
6044         is_add = 0;
6045       else
6046         {
6047           clib_warning ("parse error '%U'", format_unformat_error, i);
6048           return -99;
6049         }
6050     }
6051
6052   if (vec_len (labels) == 0)
6053     {
6054       errmsg ("missing encap label stack\n");
6055       return -99;
6056     }
6057
6058   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6059       sizeof (u32) * vec_len (labels));
6060
6061   mp->vrf_id = ntohl (vrf_id);
6062   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6063   mp->is_add = is_add;
6064   mp->nlabels = vec_len (labels);
6065   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6066
6067   vec_free (labels);
6068
6069   S;
6070   W;
6071   /* NOTREACHED */
6072   return 0;
6073 }
6074
6075 static int
6076 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6077 {
6078   unformat_input_t *i = vam->input;
6079   vl_api_mpls_gre_add_del_tunnel_t *mp;
6080   f64 timeout;
6081   u32 inner_vrf_id = 0;
6082   u32 outer_vrf_id = 0;
6083   ip4_address_t src_address;
6084   ip4_address_t dst_address;
6085   ip4_address_t intfc_address;
6086   u32 tmp;
6087   u8 intfc_address_length = 0;
6088   u8 is_add = 1;
6089   u8 l2_only = 0;
6090
6091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6092     {
6093       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6094         ;
6095       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6096         ;
6097       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6098         ;
6099       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6100         ;
6101       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6102                          &intfc_address, &tmp))
6103         intfc_address_length = tmp;
6104       else if (unformat (i, "l2-only"))
6105         l2_only = 1;
6106       else if (unformat (i, "del"))
6107         is_add = 0;
6108       else
6109         {
6110           clib_warning ("parse error '%U'", format_unformat_error, i);
6111           return -99;
6112         }
6113     }
6114
6115   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6116
6117   mp->inner_vrf_id = ntohl (inner_vrf_id);
6118   mp->outer_vrf_id = ntohl (outer_vrf_id);
6119   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6120   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6121   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6122   mp->intfc_address_length = intfc_address_length;
6123   mp->l2_only = l2_only;
6124   mp->is_add = is_add;
6125
6126   S;
6127   W;
6128   /* NOTREACHED */
6129   return 0;
6130 }
6131
6132 static int
6133 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6134 {
6135   unformat_input_t *i = vam->input;
6136   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6137   f64 timeout;
6138   u32 inner_vrf_id = 0;
6139   ip4_address_t intfc_address;
6140   u8 dst_mac_address[6];
6141   int dst_set = 1;
6142   u32 tmp;
6143   u8 intfc_address_length = 0;
6144   u8 is_add = 1;
6145   u8 l2_only = 0;
6146   u32 tx_sw_if_index;
6147   int tx_sw_if_index_set = 0;
6148
6149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6150     {
6151       if (unformat (i, "vrf %d", &inner_vrf_id))
6152         ;
6153       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6154                          &intfc_address, &tmp))
6155         intfc_address_length = tmp;
6156       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6157         tx_sw_if_index_set = 1;
6158       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6159         tx_sw_if_index_set = 1;
6160       else if (unformat (i, "dst %U", unformat_ethernet_address,
6161                          dst_mac_address))
6162         dst_set = 1;
6163       else if (unformat (i, "l2-only"))
6164         l2_only = 1;
6165       else if (unformat (i, "del"))
6166         is_add = 0;
6167       else
6168         {
6169           clib_warning ("parse error '%U'", format_unformat_error, i);
6170           return -99;
6171         }
6172     }
6173
6174   if (!dst_set)
6175     {
6176       errmsg ("dst (mac address) not set\n");
6177       return -99;
6178     }
6179   if (!tx_sw_if_index_set)
6180     {
6181       errmsg ("tx-intfc not set\n");
6182       return -99;
6183     }
6184
6185   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6186
6187   mp->vrf_id = ntohl (inner_vrf_id);
6188   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6189   mp->adj_address_length = intfc_address_length;
6190   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6191                sizeof (dst_mac_address));
6192   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6193   mp->l2_only = l2_only;
6194   mp->is_add = is_add;
6195
6196   S;
6197   W;
6198   /* NOTREACHED */
6199   return 0;
6200 }
6201
6202 static int
6203 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6204 {
6205   unformat_input_t *i = vam->input;
6206   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6207   f64 timeout;
6208   u32 inner_vrf_id = 0;
6209   u32 outer_vrf_id = 0;
6210   ip4_address_t adj_address;
6211   int adj_address_set = 0;
6212   ip4_address_t next_hop_address;
6213   int next_hop_address_set = 0;
6214   u32 tmp;
6215   u8 adj_address_length = 0;
6216   u8 l2_only = 0;
6217   u8 is_add = 1;
6218   u32 resolve_attempts = 5;
6219   u8 resolve_if_needed = 1;
6220
6221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6222     {
6223       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6224         ;
6225       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6226         ;
6227       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6228                          &adj_address, &tmp))
6229         {
6230           adj_address_length = tmp;
6231           adj_address_set = 1;
6232         }
6233       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6234                          &next_hop_address))
6235         next_hop_address_set = 1;
6236       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6237         ;
6238       else if (unformat (i, "resolve-if-needed %d", &tmp))
6239         resolve_if_needed = tmp;
6240       else if (unformat (i, "l2-only"))
6241         l2_only = 1;
6242       else if (unformat (i, "del"))
6243         is_add = 0;
6244       else
6245         {
6246           clib_warning ("parse error '%U'", format_unformat_error, i);
6247           return -99;
6248         }
6249     }
6250
6251   if (!adj_address_set)
6252     {
6253       errmsg ("adjacency address/mask not set\n");
6254       return -99;
6255     }
6256   if (!next_hop_address_set)
6257     {
6258       errmsg ("ip4 next hop address (in outer fib) not set\n");
6259       return -99;
6260     }
6261
6262   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6263
6264   mp->inner_vrf_id = ntohl (inner_vrf_id);
6265   mp->outer_vrf_id = ntohl (outer_vrf_id);
6266   mp->resolve_attempts = ntohl (resolve_attempts);
6267   mp->resolve_if_needed = resolve_if_needed;
6268   mp->is_add = is_add;
6269   mp->l2_only = l2_only;
6270   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6271   mp->adj_address_length = adj_address_length;
6272   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6273                sizeof (next_hop_address));
6274
6275   S;
6276   W;
6277   /* NOTREACHED */
6278   return 0;
6279 }
6280
6281 static int
6282 api_sw_interface_set_unnumbered (vat_main_t * vam)
6283 {
6284   unformat_input_t *i = vam->input;
6285   vl_api_sw_interface_set_unnumbered_t *mp;
6286   f64 timeout;
6287   u32 sw_if_index;
6288   u32 unnum_sw_index = ~0;
6289   u8 is_add = 1;
6290   u8 sw_if_index_set = 0;
6291
6292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6293     {
6294       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6295         sw_if_index_set = 1;
6296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6297         sw_if_index_set = 1;
6298       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6299         ;
6300       else if (unformat (i, "del"))
6301         is_add = 0;
6302       else
6303         {
6304           clib_warning ("parse error '%U'", format_unformat_error, i);
6305           return -99;
6306         }
6307     }
6308
6309   if (sw_if_index_set == 0)
6310     {
6311       errmsg ("missing interface name or sw_if_index\n");
6312       return -99;
6313     }
6314
6315   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6316
6317   mp->sw_if_index = ntohl (sw_if_index);
6318   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6319   mp->is_add = is_add;
6320
6321   S;
6322   W;
6323   /* NOTREACHED */
6324   return 0;
6325 }
6326
6327 static int
6328 api_ip_neighbor_add_del (vat_main_t * vam)
6329 {
6330   unformat_input_t *i = vam->input;
6331   vl_api_ip_neighbor_add_del_t *mp;
6332   f64 timeout;
6333   u32 sw_if_index;
6334   u8 sw_if_index_set = 0;
6335   u32 vrf_id = 0;
6336   u8 is_add = 1;
6337   u8 is_static = 0;
6338   u8 mac_address[6];
6339   u8 mac_set = 0;
6340   u8 v4_address_set = 0;
6341   u8 v6_address_set = 0;
6342   ip4_address_t v4address;
6343   ip6_address_t v6address;
6344
6345   memset (mac_address, 0, sizeof (mac_address));
6346
6347   /* Parse args required to build the message */
6348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6349     {
6350       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6351         {
6352           mac_set = 1;
6353         }
6354       else if (unformat (i, "del"))
6355         is_add = 0;
6356       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6359         sw_if_index_set = 1;
6360       else if (unformat (i, "is_static"))
6361         is_static = 1;
6362       else if (unformat (i, "vrf %d", &vrf_id))
6363         ;
6364       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6365         v4_address_set = 1;
6366       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6367         v6_address_set = 1;
6368       else
6369         {
6370           clib_warning ("parse error '%U'", format_unformat_error, i);
6371           return -99;
6372         }
6373     }
6374
6375   if (sw_if_index_set == 0)
6376     {
6377       errmsg ("missing interface name or sw_if_index\n");
6378       return -99;
6379     }
6380   if (v4_address_set && v6_address_set)
6381     {
6382       errmsg ("both v4 and v6 addresses set\n");
6383       return -99;
6384     }
6385   if (!v4_address_set && !v6_address_set)
6386     {
6387       errmsg ("no address set\n");
6388       return -99;
6389     }
6390
6391   /* Construct the API message */
6392   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6393
6394   mp->sw_if_index = ntohl (sw_if_index);
6395   mp->is_add = is_add;
6396   mp->vrf_id = ntohl (vrf_id);
6397   mp->is_static = is_static;
6398   if (mac_set)
6399     clib_memcpy (mp->mac_address, mac_address, 6);
6400   if (v6_address_set)
6401     {
6402       mp->is_ipv6 = 1;
6403       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6404     }
6405   else
6406     {
6407       /* mp->is_ipv6 = 0; via memset in M macro above */
6408       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6409     }
6410
6411   /* send it... */
6412   S;
6413
6414   /* Wait for a reply, return good/bad news  */
6415   W;
6416
6417   /* NOTREACHED */
6418   return 0;
6419 }
6420
6421 static int
6422 api_reset_vrf (vat_main_t * vam)
6423 {
6424   unformat_input_t *i = vam->input;
6425   vl_api_reset_vrf_t *mp;
6426   f64 timeout;
6427   u32 vrf_id = 0;
6428   u8 is_ipv6 = 0;
6429   u8 vrf_id_set = 0;
6430
6431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6432     {
6433       if (unformat (i, "vrf %d", &vrf_id))
6434         vrf_id_set = 1;
6435       else if (unformat (i, "ipv6"))
6436         is_ipv6 = 1;
6437       else
6438         {
6439           clib_warning ("parse error '%U'", format_unformat_error, i);
6440           return -99;
6441         }
6442     }
6443
6444   if (vrf_id_set == 0)
6445     {
6446       errmsg ("missing vrf id\n");
6447       return -99;
6448     }
6449
6450   M (RESET_VRF, reset_vrf);
6451
6452   mp->vrf_id = ntohl (vrf_id);
6453   mp->is_ipv6 = is_ipv6;
6454
6455   S;
6456   W;
6457   /* NOTREACHED */
6458   return 0;
6459 }
6460
6461 static int
6462 api_create_vlan_subif (vat_main_t * vam)
6463 {
6464   unformat_input_t *i = vam->input;
6465   vl_api_create_vlan_subif_t *mp;
6466   f64 timeout;
6467   u32 sw_if_index;
6468   u8 sw_if_index_set = 0;
6469   u32 vlan_id;
6470   u8 vlan_id_set = 0;
6471
6472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6473     {
6474       if (unformat (i, "sw_if_index %d", &sw_if_index))
6475         sw_if_index_set = 1;
6476       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6477         sw_if_index_set = 1;
6478       else if (unformat (i, "vlan %d", &vlan_id))
6479         vlan_id_set = 1;
6480       else
6481         {
6482           clib_warning ("parse error '%U'", format_unformat_error, i);
6483           return -99;
6484         }
6485     }
6486
6487   if (sw_if_index_set == 0)
6488     {
6489       errmsg ("missing interface name or sw_if_index\n");
6490       return -99;
6491     }
6492
6493   if (vlan_id_set == 0)
6494     {
6495       errmsg ("missing vlan_id\n");
6496       return -99;
6497     }
6498   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6499
6500   mp->sw_if_index = ntohl (sw_if_index);
6501   mp->vlan_id = ntohl (vlan_id);
6502
6503   S;
6504   W;
6505   /* NOTREACHED */
6506   return 0;
6507 }
6508
6509 #define foreach_create_subif_bit                \
6510 _(no_tags)                                      \
6511 _(one_tag)                                      \
6512 _(two_tags)                                     \
6513 _(dot1ad)                                       \
6514 _(exact_match)                                  \
6515 _(default_sub)                                  \
6516 _(outer_vlan_id_any)                            \
6517 _(inner_vlan_id_any)
6518
6519 static int
6520 api_create_subif (vat_main_t * vam)
6521 {
6522   unformat_input_t *i = vam->input;
6523   vl_api_create_subif_t *mp;
6524   f64 timeout;
6525   u32 sw_if_index;
6526   u8 sw_if_index_set = 0;
6527   u32 sub_id;
6528   u8 sub_id_set = 0;
6529   u32 no_tags = 0;
6530   u32 one_tag = 0;
6531   u32 two_tags = 0;
6532   u32 dot1ad = 0;
6533   u32 exact_match = 0;
6534   u32 default_sub = 0;
6535   u32 outer_vlan_id_any = 0;
6536   u32 inner_vlan_id_any = 0;
6537   u32 tmp;
6538   u16 outer_vlan_id = 0;
6539   u16 inner_vlan_id = 0;
6540
6541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6542     {
6543       if (unformat (i, "sw_if_index %d", &sw_if_index))
6544         sw_if_index_set = 1;
6545       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6546         sw_if_index_set = 1;
6547       else if (unformat (i, "sub_id %d", &sub_id))
6548         sub_id_set = 1;
6549       else if (unformat (i, "outer_vlan_id %d", &tmp))
6550         outer_vlan_id = tmp;
6551       else if (unformat (i, "inner_vlan_id %d", &tmp))
6552         inner_vlan_id = tmp;
6553
6554 #define _(a) else if (unformat (i, #a)) a = 1 ;
6555       foreach_create_subif_bit
6556 #undef _
6557         else
6558         {
6559           clib_warning ("parse error '%U'", format_unformat_error, i);
6560           return -99;
6561         }
6562     }
6563
6564   if (sw_if_index_set == 0)
6565     {
6566       errmsg ("missing interface name or sw_if_index\n");
6567       return -99;
6568     }
6569
6570   if (sub_id_set == 0)
6571     {
6572       errmsg ("missing sub_id\n");
6573       return -99;
6574     }
6575   M (CREATE_SUBIF, create_subif);
6576
6577   mp->sw_if_index = ntohl (sw_if_index);
6578   mp->sub_id = ntohl (sub_id);
6579
6580 #define _(a) mp->a = a;
6581   foreach_create_subif_bit;
6582 #undef _
6583
6584   mp->outer_vlan_id = ntohs (outer_vlan_id);
6585   mp->inner_vlan_id = ntohs (inner_vlan_id);
6586
6587   S;
6588   W;
6589   /* NOTREACHED */
6590   return 0;
6591 }
6592
6593 static int
6594 api_oam_add_del (vat_main_t * vam)
6595 {
6596   unformat_input_t *i = vam->input;
6597   vl_api_oam_add_del_t *mp;
6598   f64 timeout;
6599   u32 vrf_id = 0;
6600   u8 is_add = 1;
6601   ip4_address_t src, dst;
6602   u8 src_set = 0;
6603   u8 dst_set = 0;
6604
6605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6606     {
6607       if (unformat (i, "vrf %d", &vrf_id))
6608         ;
6609       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6610         src_set = 1;
6611       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6612         dst_set = 1;
6613       else if (unformat (i, "del"))
6614         is_add = 0;
6615       else
6616         {
6617           clib_warning ("parse error '%U'", format_unformat_error, i);
6618           return -99;
6619         }
6620     }
6621
6622   if (src_set == 0)
6623     {
6624       errmsg ("missing src addr\n");
6625       return -99;
6626     }
6627
6628   if (dst_set == 0)
6629     {
6630       errmsg ("missing dst addr\n");
6631       return -99;
6632     }
6633
6634   M (OAM_ADD_DEL, oam_add_del);
6635
6636   mp->vrf_id = ntohl (vrf_id);
6637   mp->is_add = is_add;
6638   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6639   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6640
6641   S;
6642   W;
6643   /* NOTREACHED */
6644   return 0;
6645 }
6646
6647 static int
6648 api_reset_fib (vat_main_t * vam)
6649 {
6650   unformat_input_t *i = vam->input;
6651   vl_api_reset_fib_t *mp;
6652   f64 timeout;
6653   u32 vrf_id = 0;
6654   u8 is_ipv6 = 0;
6655   u8 vrf_id_set = 0;
6656
6657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6658     {
6659       if (unformat (i, "vrf %d", &vrf_id))
6660         vrf_id_set = 1;
6661       else if (unformat (i, "ipv6"))
6662         is_ipv6 = 1;
6663       else
6664         {
6665           clib_warning ("parse error '%U'", format_unformat_error, i);
6666           return -99;
6667         }
6668     }
6669
6670   if (vrf_id_set == 0)
6671     {
6672       errmsg ("missing vrf id\n");
6673       return -99;
6674     }
6675
6676   M (RESET_FIB, reset_fib);
6677
6678   mp->vrf_id = ntohl (vrf_id);
6679   mp->is_ipv6 = is_ipv6;
6680
6681   S;
6682   W;
6683   /* NOTREACHED */
6684   return 0;
6685 }
6686
6687 static int
6688 api_dhcp_proxy_config (vat_main_t * vam)
6689 {
6690   unformat_input_t *i = vam->input;
6691   vl_api_dhcp_proxy_config_t *mp;
6692   f64 timeout;
6693   u32 vrf_id = 0;
6694   u8 is_add = 1;
6695   u8 insert_cid = 1;
6696   u8 v4_address_set = 0;
6697   u8 v6_address_set = 0;
6698   ip4_address_t v4address;
6699   ip6_address_t v6address;
6700   u8 v4_src_address_set = 0;
6701   u8 v6_src_address_set = 0;
6702   ip4_address_t v4srcaddress;
6703   ip6_address_t v6srcaddress;
6704
6705   /* Parse args required to build the message */
6706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6707     {
6708       if (unformat (i, "del"))
6709         is_add = 0;
6710       else if (unformat (i, "vrf %d", &vrf_id))
6711         ;
6712       else if (unformat (i, "insert-cid %d", &insert_cid))
6713         ;
6714       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6715         v4_address_set = 1;
6716       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6717         v6_address_set = 1;
6718       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6719         v4_src_address_set = 1;
6720       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6721         v6_src_address_set = 1;
6722       else
6723         break;
6724     }
6725
6726   if (v4_address_set && v6_address_set)
6727     {
6728       errmsg ("both v4 and v6 server addresses set\n");
6729       return -99;
6730     }
6731   if (!v4_address_set && !v6_address_set)
6732     {
6733       errmsg ("no server addresses set\n");
6734       return -99;
6735     }
6736
6737   if (v4_src_address_set && v6_src_address_set)
6738     {
6739       errmsg ("both v4 and v6  src addresses set\n");
6740       return -99;
6741     }
6742   if (!v4_src_address_set && !v6_src_address_set)
6743     {
6744       errmsg ("no src addresses set\n");
6745       return -99;
6746     }
6747
6748   if (!(v4_src_address_set && v4_address_set) &&
6749       !(v6_src_address_set && v6_address_set))
6750     {
6751       errmsg ("no matching server and src addresses set\n");
6752       return -99;
6753     }
6754
6755   /* Construct the API message */
6756   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6757
6758   mp->insert_circuit_id = insert_cid;
6759   mp->is_add = is_add;
6760   mp->vrf_id = ntohl (vrf_id);
6761   if (v6_address_set)
6762     {
6763       mp->is_ipv6 = 1;
6764       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6765       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6766     }
6767   else
6768     {
6769       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6770       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6771     }
6772
6773   /* send it... */
6774   S;
6775
6776   /* Wait for a reply, return good/bad news  */
6777   W;
6778   /* NOTREACHED */
6779   return 0;
6780 }
6781
6782 static int
6783 api_dhcp_proxy_config_2 (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_dhcp_proxy_config_2_t *mp;
6787   f64 timeout;
6788   u32 rx_vrf_id = 0;
6789   u32 server_vrf_id = 0;
6790   u8 is_add = 1;
6791   u8 insert_cid = 1;
6792   u8 v4_address_set = 0;
6793   u8 v6_address_set = 0;
6794   ip4_address_t v4address;
6795   ip6_address_t v6address;
6796   u8 v4_src_address_set = 0;
6797   u8 v6_src_address_set = 0;
6798   ip4_address_t v4srcaddress;
6799   ip6_address_t v6srcaddress;
6800
6801   /* Parse args required to build the message */
6802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6803     {
6804       if (unformat (i, "del"))
6805         is_add = 0;
6806       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6807         ;
6808       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6809         ;
6810       else if (unformat (i, "insert-cid %d", &insert_cid))
6811         ;
6812       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6813         v4_address_set = 1;
6814       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6815         v6_address_set = 1;
6816       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6817         v4_src_address_set = 1;
6818       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6819         v6_src_address_set = 1;
6820       else
6821         break;
6822     }
6823
6824   if (v4_address_set && v6_address_set)
6825     {
6826       errmsg ("both v4 and v6 server addresses set\n");
6827       return -99;
6828     }
6829   if (!v4_address_set && !v6_address_set)
6830     {
6831       errmsg ("no server addresses set\n");
6832       return -99;
6833     }
6834
6835   if (v4_src_address_set && v6_src_address_set)
6836     {
6837       errmsg ("both v4 and v6  src addresses set\n");
6838       return -99;
6839     }
6840   if (!v4_src_address_set && !v6_src_address_set)
6841     {
6842       errmsg ("no src addresses set\n");
6843       return -99;
6844     }
6845
6846   if (!(v4_src_address_set && v4_address_set) &&
6847       !(v6_src_address_set && v6_address_set))
6848     {
6849       errmsg ("no matching server and src addresses set\n");
6850       return -99;
6851     }
6852
6853   /* Construct the API message */
6854   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6855
6856   mp->insert_circuit_id = insert_cid;
6857   mp->is_add = is_add;
6858   mp->rx_vrf_id = ntohl (rx_vrf_id);
6859   mp->server_vrf_id = ntohl (server_vrf_id);
6860   if (v6_address_set)
6861     {
6862       mp->is_ipv6 = 1;
6863       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6864       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6865     }
6866   else
6867     {
6868       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6869       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6870     }
6871
6872   /* send it... */
6873   S;
6874
6875   /* Wait for a reply, return good/bad news  */
6876   W;
6877   /* NOTREACHED */
6878   return 0;
6879 }
6880
6881 static int
6882 api_dhcp_proxy_set_vss (vat_main_t * vam)
6883 {
6884   unformat_input_t *i = vam->input;
6885   vl_api_dhcp_proxy_set_vss_t *mp;
6886   f64 timeout;
6887   u8 is_ipv6 = 0;
6888   u8 is_add = 1;
6889   u32 tbl_id;
6890   u8 tbl_id_set = 0;
6891   u32 oui;
6892   u8 oui_set = 0;
6893   u32 fib_id;
6894   u8 fib_id_set = 0;
6895
6896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6897     {
6898       if (unformat (i, "tbl_id %d", &tbl_id))
6899         tbl_id_set = 1;
6900       if (unformat (i, "fib_id %d", &fib_id))
6901         fib_id_set = 1;
6902       if (unformat (i, "oui %d", &oui))
6903         oui_set = 1;
6904       else if (unformat (i, "ipv6"))
6905         is_ipv6 = 1;
6906       else if (unformat (i, "del"))
6907         is_add = 0;
6908       else
6909         {
6910           clib_warning ("parse error '%U'", format_unformat_error, i);
6911           return -99;
6912         }
6913     }
6914
6915   if (tbl_id_set == 0)
6916     {
6917       errmsg ("missing tbl id\n");
6918       return -99;
6919     }
6920
6921   if (fib_id_set == 0)
6922     {
6923       errmsg ("missing fib id\n");
6924       return -99;
6925     }
6926   if (oui_set == 0)
6927     {
6928       errmsg ("missing oui\n");
6929       return -99;
6930     }
6931
6932   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6933   mp->tbl_id = ntohl (tbl_id);
6934   mp->fib_id = ntohl (fib_id);
6935   mp->oui = ntohl (oui);
6936   mp->is_ipv6 = is_ipv6;
6937   mp->is_add = is_add;
6938
6939   S;
6940   W;
6941   /* NOTREACHED */
6942   return 0;
6943 }
6944
6945 static int
6946 api_dhcp_client_config (vat_main_t * vam)
6947 {
6948   unformat_input_t *i = vam->input;
6949   vl_api_dhcp_client_config_t *mp;
6950   f64 timeout;
6951   u32 sw_if_index;
6952   u8 sw_if_index_set = 0;
6953   u8 is_add = 1;
6954   u8 *hostname = 0;
6955   u8 disable_event = 0;
6956
6957   /* Parse args required to build the message */
6958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6959     {
6960       if (unformat (i, "del"))
6961         is_add = 0;
6962       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6963         sw_if_index_set = 1;
6964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6965         sw_if_index_set = 1;
6966       else if (unformat (i, "hostname %s", &hostname))
6967         ;
6968       else if (unformat (i, "disable_event"))
6969         disable_event = 1;
6970       else
6971         break;
6972     }
6973
6974   if (sw_if_index_set == 0)
6975     {
6976       errmsg ("missing interface name or sw_if_index\n");
6977       return -99;
6978     }
6979
6980   if (vec_len (hostname) > 63)
6981     {
6982       errmsg ("hostname too long\n");
6983     }
6984   vec_add1 (hostname, 0);
6985
6986   /* Construct the API message */
6987   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6988
6989   mp->sw_if_index = ntohl (sw_if_index);
6990   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6991   vec_free (hostname);
6992   mp->is_add = is_add;
6993   mp->want_dhcp_event = disable_event ? 0 : 1;
6994   mp->pid = getpid ();
6995
6996   /* send it... */
6997   S;
6998
6999   /* Wait for a reply, return good/bad news  */
7000   W;
7001   /* NOTREACHED */
7002   return 0;
7003 }
7004
7005 static int
7006 api_set_ip_flow_hash (vat_main_t * vam)
7007 {
7008   unformat_input_t *i = vam->input;
7009   vl_api_set_ip_flow_hash_t *mp;
7010   f64 timeout;
7011   u32 vrf_id = 0;
7012   u8 is_ipv6 = 0;
7013   u8 vrf_id_set = 0;
7014   u8 src = 0;
7015   u8 dst = 0;
7016   u8 sport = 0;
7017   u8 dport = 0;
7018   u8 proto = 0;
7019   u8 reverse = 0;
7020
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "vrf %d", &vrf_id))
7024         vrf_id_set = 1;
7025       else if (unformat (i, "ipv6"))
7026         is_ipv6 = 1;
7027       else if (unformat (i, "src"))
7028         src = 1;
7029       else if (unformat (i, "dst"))
7030         dst = 1;
7031       else if (unformat (i, "sport"))
7032         sport = 1;
7033       else if (unformat (i, "dport"))
7034         dport = 1;
7035       else if (unformat (i, "proto"))
7036         proto = 1;
7037       else if (unformat (i, "reverse"))
7038         reverse = 1;
7039
7040       else
7041         {
7042           clib_warning ("parse error '%U'", format_unformat_error, i);
7043           return -99;
7044         }
7045     }
7046
7047   if (vrf_id_set == 0)
7048     {
7049       errmsg ("missing vrf id\n");
7050       return -99;
7051     }
7052
7053   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7054   mp->src = src;
7055   mp->dst = dst;
7056   mp->sport = sport;
7057   mp->dport = dport;
7058   mp->proto = proto;
7059   mp->reverse = reverse;
7060   mp->vrf_id = ntohl (vrf_id);
7061   mp->is_ipv6 = is_ipv6;
7062
7063   S;
7064   W;
7065   /* NOTREACHED */
7066   return 0;
7067 }
7068
7069 static int
7070 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7071 {
7072   unformat_input_t *i = vam->input;
7073   vl_api_sw_interface_ip6_enable_disable_t *mp;
7074   f64 timeout;
7075   u32 sw_if_index;
7076   u8 sw_if_index_set = 0;
7077   u8 enable = 0;
7078
7079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7080     {
7081       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7082         sw_if_index_set = 1;
7083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7084         sw_if_index_set = 1;
7085       else if (unformat (i, "enable"))
7086         enable = 1;
7087       else if (unformat (i, "disable"))
7088         enable = 0;
7089       else
7090         {
7091           clib_warning ("parse error '%U'", format_unformat_error, i);
7092           return -99;
7093         }
7094     }
7095
7096   if (sw_if_index_set == 0)
7097     {
7098       errmsg ("missing interface name or sw_if_index\n");
7099       return -99;
7100     }
7101
7102   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7103
7104   mp->sw_if_index = ntohl (sw_if_index);
7105   mp->enable = enable;
7106
7107   S;
7108   W;
7109   /* NOTREACHED */
7110   return 0;
7111 }
7112
7113 static int
7114 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7118   f64 timeout;
7119   u32 sw_if_index;
7120   u8 sw_if_index_set = 0;
7121   u32 address_length = 0;
7122   u8 v6_address_set = 0;
7123   ip6_address_t v6address;
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7129         sw_if_index_set = 1;
7130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7131         sw_if_index_set = 1;
7132       else if (unformat (i, "%U/%d",
7133                          unformat_ip6_address, &v6address, &address_length))
7134         v6_address_set = 1;
7135       else
7136         break;
7137     }
7138
7139   if (sw_if_index_set == 0)
7140     {
7141       errmsg ("missing interface name or sw_if_index\n");
7142       return -99;
7143     }
7144   if (!v6_address_set)
7145     {
7146       errmsg ("no address set\n");
7147       return -99;
7148     }
7149
7150   /* Construct the API message */
7151   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7152      sw_interface_ip6_set_link_local_address);
7153
7154   mp->sw_if_index = ntohl (sw_if_index);
7155   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7156   mp->address_length = address_length;
7157
7158   /* send it... */
7159   S;
7160
7161   /* Wait for a reply, return good/bad news  */
7162   W;
7163
7164   /* NOTREACHED */
7165   return 0;
7166 }
7167
7168
7169 static int
7170 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7171 {
7172   unformat_input_t *i = vam->input;
7173   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7174   f64 timeout;
7175   u32 sw_if_index;
7176   u8 sw_if_index_set = 0;
7177   u32 address_length = 0;
7178   u8 v6_address_set = 0;
7179   ip6_address_t v6address;
7180   u8 use_default = 0;
7181   u8 no_advertise = 0;
7182   u8 off_link = 0;
7183   u8 no_autoconfig = 0;
7184   u8 no_onlink = 0;
7185   u8 is_no = 0;
7186   u32 val_lifetime = 0;
7187   u32 pref_lifetime = 0;
7188
7189   /* Parse args required to build the message */
7190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7191     {
7192       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7193         sw_if_index_set = 1;
7194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7195         sw_if_index_set = 1;
7196       else if (unformat (i, "%U/%d",
7197                          unformat_ip6_address, &v6address, &address_length))
7198         v6_address_set = 1;
7199       else if (unformat (i, "val_life %d", &val_lifetime))
7200         ;
7201       else if (unformat (i, "pref_life %d", &pref_lifetime))
7202         ;
7203       else if (unformat (i, "def"))
7204         use_default = 1;
7205       else if (unformat (i, "noadv"))
7206         no_advertise = 1;
7207       else if (unformat (i, "offl"))
7208         off_link = 1;
7209       else if (unformat (i, "noauto"))
7210         no_autoconfig = 1;
7211       else if (unformat (i, "nolink"))
7212         no_onlink = 1;
7213       else if (unformat (i, "isno"))
7214         is_no = 1;
7215       else
7216         {
7217           clib_warning ("parse error '%U'", format_unformat_error, i);
7218           return -99;
7219         }
7220     }
7221
7222   if (sw_if_index_set == 0)
7223     {
7224       errmsg ("missing interface name or sw_if_index\n");
7225       return -99;
7226     }
7227   if (!v6_address_set)
7228     {
7229       errmsg ("no address set\n");
7230       return -99;
7231     }
7232
7233   /* Construct the API message */
7234   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7235
7236   mp->sw_if_index = ntohl (sw_if_index);
7237   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7238   mp->address_length = address_length;
7239   mp->use_default = use_default;
7240   mp->no_advertise = no_advertise;
7241   mp->off_link = off_link;
7242   mp->no_autoconfig = no_autoconfig;
7243   mp->no_onlink = no_onlink;
7244   mp->is_no = is_no;
7245   mp->val_lifetime = ntohl (val_lifetime);
7246   mp->pref_lifetime = ntohl (pref_lifetime);
7247
7248   /* send it... */
7249   S;
7250
7251   /* Wait for a reply, return good/bad news  */
7252   W;
7253
7254   /* NOTREACHED */
7255   return 0;
7256 }
7257
7258 static int
7259 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7260 {
7261   unformat_input_t *i = vam->input;
7262   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7263   f64 timeout;
7264   u32 sw_if_index;
7265   u8 sw_if_index_set = 0;
7266   u8 suppress = 0;
7267   u8 managed = 0;
7268   u8 other = 0;
7269   u8 ll_option = 0;
7270   u8 send_unicast = 0;
7271   u8 cease = 0;
7272   u8 is_no = 0;
7273   u8 default_router = 0;
7274   u32 max_interval = 0;
7275   u32 min_interval = 0;
7276   u32 lifetime = 0;
7277   u32 initial_count = 0;
7278   u32 initial_interval = 0;
7279
7280
7281   /* Parse args required to build the message */
7282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7283     {
7284       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7285         sw_if_index_set = 1;
7286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7287         sw_if_index_set = 1;
7288       else if (unformat (i, "maxint %d", &max_interval))
7289         ;
7290       else if (unformat (i, "minint %d", &min_interval))
7291         ;
7292       else if (unformat (i, "life %d", &lifetime))
7293         ;
7294       else if (unformat (i, "count %d", &initial_count))
7295         ;
7296       else if (unformat (i, "interval %d", &initial_interval))
7297         ;
7298       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7299         suppress = 1;
7300       else if (unformat (i, "managed"))
7301         managed = 1;
7302       else if (unformat (i, "other"))
7303         other = 1;
7304       else if (unformat (i, "ll"))
7305         ll_option = 1;
7306       else if (unformat (i, "send"))
7307         send_unicast = 1;
7308       else if (unformat (i, "cease"))
7309         cease = 1;
7310       else if (unformat (i, "isno"))
7311         is_no = 1;
7312       else if (unformat (i, "def"))
7313         default_router = 1;
7314       else
7315         {
7316           clib_warning ("parse error '%U'", format_unformat_error, i);
7317           return -99;
7318         }
7319     }
7320
7321   if (sw_if_index_set == 0)
7322     {
7323       errmsg ("missing interface name or sw_if_index\n");
7324       return -99;
7325     }
7326
7327   /* Construct the API message */
7328   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7329
7330   mp->sw_if_index = ntohl (sw_if_index);
7331   mp->max_interval = ntohl (max_interval);
7332   mp->min_interval = ntohl (min_interval);
7333   mp->lifetime = ntohl (lifetime);
7334   mp->initial_count = ntohl (initial_count);
7335   mp->initial_interval = ntohl (initial_interval);
7336   mp->suppress = suppress;
7337   mp->managed = managed;
7338   mp->other = other;
7339   mp->ll_option = ll_option;
7340   mp->send_unicast = send_unicast;
7341   mp->cease = cease;
7342   mp->is_no = is_no;
7343   mp->default_router = default_router;
7344
7345   /* send it... */
7346   S;
7347
7348   /* Wait for a reply, return good/bad news  */
7349   W;
7350
7351   /* NOTREACHED */
7352   return 0;
7353 }
7354
7355 static int
7356 api_set_arp_neighbor_limit (vat_main_t * vam)
7357 {
7358   unformat_input_t *i = vam->input;
7359   vl_api_set_arp_neighbor_limit_t *mp;
7360   f64 timeout;
7361   u32 arp_nbr_limit;
7362   u8 limit_set = 0;
7363   u8 is_ipv6 = 0;
7364
7365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7368         limit_set = 1;
7369       else if (unformat (i, "ipv6"))
7370         is_ipv6 = 1;
7371       else
7372         {
7373           clib_warning ("parse error '%U'", format_unformat_error, i);
7374           return -99;
7375         }
7376     }
7377
7378   if (limit_set == 0)
7379     {
7380       errmsg ("missing limit value\n");
7381       return -99;
7382     }
7383
7384   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7385
7386   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7387   mp->is_ipv6 = is_ipv6;
7388
7389   S;
7390   W;
7391   /* NOTREACHED */
7392   return 0;
7393 }
7394
7395 static int
7396 api_l2_patch_add_del (vat_main_t * vam)
7397 {
7398   unformat_input_t *i = vam->input;
7399   vl_api_l2_patch_add_del_t *mp;
7400   f64 timeout;
7401   u32 rx_sw_if_index;
7402   u8 rx_sw_if_index_set = 0;
7403   u32 tx_sw_if_index;
7404   u8 tx_sw_if_index_set = 0;
7405   u8 is_add = 1;
7406
7407   /* Parse args required to build the message */
7408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7409     {
7410       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7411         rx_sw_if_index_set = 1;
7412       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7413         tx_sw_if_index_set = 1;
7414       else if (unformat (i, "rx"))
7415         {
7416           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417             {
7418               if (unformat (i, "%U", unformat_sw_if_index, vam,
7419                             &rx_sw_if_index))
7420                 rx_sw_if_index_set = 1;
7421             }
7422           else
7423             break;
7424         }
7425       else if (unformat (i, "tx"))
7426         {
7427           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7428             {
7429               if (unformat (i, "%U", unformat_sw_if_index, vam,
7430                             &tx_sw_if_index))
7431                 tx_sw_if_index_set = 1;
7432             }
7433           else
7434             break;
7435         }
7436       else if (unformat (i, "del"))
7437         is_add = 0;
7438       else
7439         break;
7440     }
7441
7442   if (rx_sw_if_index_set == 0)
7443     {
7444       errmsg ("missing rx interface name or rx_sw_if_index\n");
7445       return -99;
7446     }
7447
7448   if (tx_sw_if_index_set == 0)
7449     {
7450       errmsg ("missing tx interface name or tx_sw_if_index\n");
7451       return -99;
7452     }
7453
7454   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7455
7456   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7457   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7458   mp->is_add = is_add;
7459
7460   S;
7461   W;
7462   /* NOTREACHED */
7463   return 0;
7464 }
7465
7466 static int
7467 api_ioam_enable (vat_main_t * vam)
7468 {
7469   unformat_input_t *input = vam->input;
7470   vl_api_ioam_enable_t *mp;
7471   f64 timeout;
7472   u32 id = 0;
7473   int has_trace_option = 0;
7474   int has_pow_option = 0;
7475   int has_ppc_option = 0;
7476
7477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7478     {
7479       if (unformat (input, "trace"))
7480         has_trace_option = 1;
7481       else if (unformat (input, "pow"))
7482         has_pow_option = 1;
7483       else if (unformat (input, "ppc encap"))
7484         has_ppc_option = PPC_ENCAP;
7485       else if (unformat (input, "ppc decap"))
7486         has_ppc_option = PPC_DECAP;
7487       else if (unformat (input, "ppc none"))
7488         has_ppc_option = PPC_NONE;
7489       else
7490         break;
7491     }
7492   M (IOAM_ENABLE, ioam_enable);
7493   mp->id = htons (id);
7494   mp->trace_ppc = has_ppc_option;
7495   mp->pow_enable = has_pow_option;
7496   mp->trace_enable = has_trace_option;
7497
7498   S;
7499   W;
7500
7501   return (0);
7502
7503 }
7504
7505
7506 static int
7507 api_ioam_disable (vat_main_t * vam)
7508 {
7509   vl_api_ioam_disable_t *mp;
7510   f64 timeout;
7511
7512   M (IOAM_DISABLE, ioam_disable);
7513   S;
7514   W;
7515   return 0;
7516 }
7517
7518 static int
7519 api_sr_tunnel_add_del (vat_main_t * vam)
7520 {
7521   unformat_input_t *i = vam->input;
7522   vl_api_sr_tunnel_add_del_t *mp;
7523   f64 timeout;
7524   int is_del = 0;
7525   int pl_index;
7526   ip6_address_t src_address;
7527   int src_address_set = 0;
7528   ip6_address_t dst_address;
7529   u32 dst_mask_width;
7530   int dst_address_set = 0;
7531   u16 flags = 0;
7532   u32 rx_table_id = 0;
7533   u32 tx_table_id = 0;
7534   ip6_address_t *segments = 0;
7535   ip6_address_t *this_seg;
7536   ip6_address_t *tags = 0;
7537   ip6_address_t *this_tag;
7538   ip6_address_t next_address, tag;
7539   u8 *name = 0;
7540   u8 *policy_name = 0;
7541
7542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7543     {
7544       if (unformat (i, "del"))
7545         is_del = 1;
7546       else if (unformat (i, "name %s", &name))
7547         ;
7548       else if (unformat (i, "policy %s", &policy_name))
7549         ;
7550       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7551         ;
7552       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7553         ;
7554       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7555         src_address_set = 1;
7556       else if (unformat (i, "dst %U/%d",
7557                          unformat_ip6_address, &dst_address, &dst_mask_width))
7558         dst_address_set = 1;
7559       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7560         {
7561           vec_add2 (segments, this_seg, 1);
7562           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7563                        sizeof (*this_seg));
7564         }
7565       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7566         {
7567           vec_add2 (tags, this_tag, 1);
7568           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7569         }
7570       else if (unformat (i, "clean"))
7571         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7572       else if (unformat (i, "protected"))
7573         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7574       else if (unformat (i, "InPE %d", &pl_index))
7575         {
7576           if (pl_index <= 0 || pl_index > 4)
7577             {
7578             pl_index_range_error:
7579               errmsg ("pl index %d out of range\n", pl_index);
7580               return -99;
7581             }
7582           flags |=
7583             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7584         }
7585       else if (unformat (i, "EgPE %d", &pl_index))
7586         {
7587           if (pl_index <= 0 || pl_index > 4)
7588             goto pl_index_range_error;
7589           flags |=
7590             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7591         }
7592       else if (unformat (i, "OrgSrc %d", &pl_index))
7593         {
7594           if (pl_index <= 0 || pl_index > 4)
7595             goto pl_index_range_error;
7596           flags |=
7597             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7598         }
7599       else
7600         break;
7601     }
7602
7603   if (!src_address_set)
7604     {
7605       errmsg ("src address required\n");
7606       return -99;
7607     }
7608
7609   if (!dst_address_set)
7610     {
7611       errmsg ("dst address required\n");
7612       return -99;
7613     }
7614
7615   if (!segments)
7616     {
7617       errmsg ("at least one sr segment required\n");
7618       return -99;
7619     }
7620
7621   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7622       vec_len (segments) * sizeof (ip6_address_t)
7623       + vec_len (tags) * sizeof (ip6_address_t));
7624
7625   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7626   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7627   mp->dst_mask_width = dst_mask_width;
7628   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7629   mp->n_segments = vec_len (segments);
7630   mp->n_tags = vec_len (tags);
7631   mp->is_add = is_del == 0;
7632   clib_memcpy (mp->segs_and_tags, segments,
7633                vec_len (segments) * sizeof (ip6_address_t));
7634   clib_memcpy (mp->segs_and_tags +
7635                vec_len (segments) * sizeof (ip6_address_t), tags,
7636                vec_len (tags) * sizeof (ip6_address_t));
7637
7638   mp->outer_vrf_id = ntohl (rx_table_id);
7639   mp->inner_vrf_id = ntohl (tx_table_id);
7640   memcpy (mp->name, name, vec_len (name));
7641   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7642
7643   vec_free (segments);
7644   vec_free (tags);
7645
7646   S;
7647   W;
7648   /* NOTREACHED */
7649 }
7650
7651 static int
7652 api_sr_policy_add_del (vat_main_t * vam)
7653 {
7654   unformat_input_t *input = vam->input;
7655   vl_api_sr_policy_add_del_t *mp;
7656   f64 timeout;
7657   int is_del = 0;
7658   u8 *name = 0;
7659   u8 *tunnel_name = 0;
7660   u8 **tunnel_names = 0;
7661
7662   int name_set = 0;
7663   int tunnel_set = 0;
7664   int j = 0;
7665   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7666   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7667
7668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (input, "del"))
7671         is_del = 1;
7672       else if (unformat (input, "name %s", &name))
7673         name_set = 1;
7674       else if (unformat (input, "tunnel %s", &tunnel_name))
7675         {
7676           if (tunnel_name)
7677             {
7678               vec_add1 (tunnel_names, tunnel_name);
7679               /* For serializer:
7680                  - length = #bytes to store in serial vector
7681                  - +1 = byte to store that length
7682                */
7683               tunnel_names_length += (vec_len (tunnel_name) + 1);
7684               tunnel_set = 1;
7685               tunnel_name = 0;
7686             }
7687         }
7688       else
7689         break;
7690     }
7691
7692   if (!name_set)
7693     {
7694       errmsg ("policy name required\n");
7695       return -99;
7696     }
7697
7698   if ((!tunnel_set) && (!is_del))
7699     {
7700       errmsg ("tunnel name required\n");
7701       return -99;
7702     }
7703
7704   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7705
7706
7707
7708   mp->is_add = !is_del;
7709
7710   memcpy (mp->name, name, vec_len (name));
7711   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7712   u8 *serial_orig = 0;
7713   vec_validate (serial_orig, tunnel_names_length);
7714   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7715   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7716
7717   for (j = 0; j < vec_len (tunnel_names); j++)
7718     {
7719       tun_name_len = vec_len (tunnel_names[j]);
7720       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7721       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7722       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7723       serial_orig += tun_name_len;      // Advance past the copy
7724     }
7725   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7726
7727   vec_free (tunnel_names);
7728   vec_free (tunnel_name);
7729
7730   S;
7731   W;
7732   /* NOTREACHED */
7733 }
7734
7735 static int
7736 api_sr_multicast_map_add_del (vat_main_t * vam)
7737 {
7738   unformat_input_t *input = vam->input;
7739   vl_api_sr_multicast_map_add_del_t *mp;
7740   f64 timeout;
7741   int is_del = 0;
7742   ip6_address_t multicast_address;
7743   u8 *policy_name = 0;
7744   int multicast_address_set = 0;
7745
7746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7747     {
7748       if (unformat (input, "del"))
7749         is_del = 1;
7750       else
7751         if (unformat
7752             (input, "address %U", unformat_ip6_address, &multicast_address))
7753         multicast_address_set = 1;
7754       else if (unformat (input, "sr-policy %s", &policy_name))
7755         ;
7756       else
7757         break;
7758     }
7759
7760   if (!is_del && !policy_name)
7761     {
7762       errmsg ("sr-policy name required\n");
7763       return -99;
7764     }
7765
7766
7767   if (!multicast_address_set)
7768     {
7769       errmsg ("address required\n");
7770       return -99;
7771     }
7772
7773   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7774
7775   mp->is_add = !is_del;
7776   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7777   clib_memcpy (mp->multicast_address, &multicast_address,
7778                sizeof (mp->multicast_address));
7779
7780
7781   vec_free (policy_name);
7782
7783   S;
7784   W;
7785   /* NOTREACHED */
7786 }
7787
7788
7789 #define foreach_ip4_proto_field                 \
7790 _(src_address)                                  \
7791 _(dst_address)                                  \
7792 _(tos)                                          \
7793 _(length)                                       \
7794 _(fragment_id)                                  \
7795 _(ttl)                                          \
7796 _(protocol)                                     \
7797 _(checksum)
7798
7799 uword
7800 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7801 {
7802   u8 **maskp = va_arg (*args, u8 **);
7803   u8 *mask = 0;
7804   u8 found_something = 0;
7805   ip4_header_t *ip;
7806
7807 #define _(a) u8 a=0;
7808   foreach_ip4_proto_field;
7809 #undef _
7810   u8 version = 0;
7811   u8 hdr_length = 0;
7812
7813
7814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (input, "version"))
7817         version = 1;
7818       else if (unformat (input, "hdr_length"))
7819         hdr_length = 1;
7820       else if (unformat (input, "src"))
7821         src_address = 1;
7822       else if (unformat (input, "dst"))
7823         dst_address = 1;
7824       else if (unformat (input, "proto"))
7825         protocol = 1;
7826
7827 #define _(a) else if (unformat (input, #a)) a=1;
7828       foreach_ip4_proto_field
7829 #undef _
7830         else
7831         break;
7832     }
7833
7834 #define _(a) found_something += a;
7835   foreach_ip4_proto_field;
7836 #undef _
7837
7838   if (found_something == 0)
7839     return 0;
7840
7841   vec_validate (mask, sizeof (*ip) - 1);
7842
7843   ip = (ip4_header_t *) mask;
7844
7845 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7846   foreach_ip4_proto_field;
7847 #undef _
7848
7849   ip->ip_version_and_header_length = 0;
7850
7851   if (version)
7852     ip->ip_version_and_header_length |= 0xF0;
7853
7854   if (hdr_length)
7855     ip->ip_version_and_header_length |= 0x0F;
7856
7857   *maskp = mask;
7858   return 1;
7859 }
7860
7861 #define foreach_ip6_proto_field                 \
7862 _(src_address)                                  \
7863 _(dst_address)                                  \
7864 _(payload_length)                               \
7865 _(hop_limit)                                    \
7866 _(protocol)
7867
7868 uword
7869 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7870 {
7871   u8 **maskp = va_arg (*args, u8 **);
7872   u8 *mask = 0;
7873   u8 found_something = 0;
7874   ip6_header_t *ip;
7875   u32 ip_version_traffic_class_and_flow_label;
7876
7877 #define _(a) u8 a=0;
7878   foreach_ip6_proto_field;
7879 #undef _
7880   u8 version = 0;
7881   u8 traffic_class = 0;
7882   u8 flow_label = 0;
7883
7884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7885     {
7886       if (unformat (input, "version"))
7887         version = 1;
7888       else if (unformat (input, "traffic-class"))
7889         traffic_class = 1;
7890       else if (unformat (input, "flow-label"))
7891         flow_label = 1;
7892       else if (unformat (input, "src"))
7893         src_address = 1;
7894       else if (unformat (input, "dst"))
7895         dst_address = 1;
7896       else if (unformat (input, "proto"))
7897         protocol = 1;
7898
7899 #define _(a) else if (unformat (input, #a)) a=1;
7900       foreach_ip6_proto_field
7901 #undef _
7902         else
7903         break;
7904     }
7905
7906 #define _(a) found_something += a;
7907   foreach_ip6_proto_field;
7908 #undef _
7909
7910   if (found_something == 0)
7911     return 0;
7912
7913   vec_validate (mask, sizeof (*ip) - 1);
7914
7915   ip = (ip6_header_t *) mask;
7916
7917 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7918   foreach_ip6_proto_field;
7919 #undef _
7920
7921   ip_version_traffic_class_and_flow_label = 0;
7922
7923   if (version)
7924     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7925
7926   if (traffic_class)
7927     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7928
7929   if (flow_label)
7930     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7931
7932   ip->ip_version_traffic_class_and_flow_label =
7933     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7934
7935   *maskp = mask;
7936   return 1;
7937 }
7938
7939 uword
7940 unformat_l3_mask (unformat_input_t * input, va_list * args)
7941 {
7942   u8 **maskp = va_arg (*args, u8 **);
7943
7944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7945     {
7946       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7947         return 1;
7948       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7949         return 1;
7950       else
7951         break;
7952     }
7953   return 0;
7954 }
7955
7956 uword
7957 unformat_l2_mask (unformat_input_t * input, va_list * args)
7958 {
7959   u8 **maskp = va_arg (*args, u8 **);
7960   u8 *mask = 0;
7961   u8 src = 0;
7962   u8 dst = 0;
7963   u8 proto = 0;
7964   u8 tag1 = 0;
7965   u8 tag2 = 0;
7966   u8 ignore_tag1 = 0;
7967   u8 ignore_tag2 = 0;
7968   u8 cos1 = 0;
7969   u8 cos2 = 0;
7970   u8 dot1q = 0;
7971   u8 dot1ad = 0;
7972   int len = 14;
7973
7974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7975     {
7976       if (unformat (input, "src"))
7977         src = 1;
7978       else if (unformat (input, "dst"))
7979         dst = 1;
7980       else if (unformat (input, "proto"))
7981         proto = 1;
7982       else if (unformat (input, "tag1"))
7983         tag1 = 1;
7984       else if (unformat (input, "tag2"))
7985         tag2 = 1;
7986       else if (unformat (input, "ignore-tag1"))
7987         ignore_tag1 = 1;
7988       else if (unformat (input, "ignore-tag2"))
7989         ignore_tag2 = 1;
7990       else if (unformat (input, "cos1"))
7991         cos1 = 1;
7992       else if (unformat (input, "cos2"))
7993         cos2 = 1;
7994       else if (unformat (input, "dot1q"))
7995         dot1q = 1;
7996       else if (unformat (input, "dot1ad"))
7997         dot1ad = 1;
7998       else
7999         break;
8000     }
8001   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8002        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8003     return 0;
8004
8005   if (tag1 || ignore_tag1 || cos1 || dot1q)
8006     len = 18;
8007   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8008     len = 22;
8009
8010   vec_validate (mask, len - 1);
8011
8012   if (dst)
8013     memset (mask, 0xff, 6);
8014
8015   if (src)
8016     memset (mask + 6, 0xff, 6);
8017
8018   if (tag2 || dot1ad)
8019     {
8020       /* inner vlan tag */
8021       if (tag2)
8022         {
8023           mask[19] = 0xff;
8024           mask[18] = 0x0f;
8025         }
8026       if (cos2)
8027         mask[18] |= 0xe0;
8028       if (proto)
8029         mask[21] = mask[20] = 0xff;
8030       if (tag1)
8031         {
8032           mask[15] = 0xff;
8033           mask[14] = 0x0f;
8034         }
8035       if (cos1)
8036         mask[14] |= 0xe0;
8037       *maskp = mask;
8038       return 1;
8039     }
8040   if (tag1 | dot1q)
8041     {
8042       if (tag1)
8043         {
8044           mask[15] = 0xff;
8045           mask[14] = 0x0f;
8046         }
8047       if (cos1)
8048         mask[14] |= 0xe0;
8049       if (proto)
8050         mask[16] = mask[17] = 0xff;
8051
8052       *maskp = mask;
8053       return 1;
8054     }
8055   if (cos2)
8056     mask[18] |= 0xe0;
8057   if (cos1)
8058     mask[14] |= 0xe0;
8059   if (proto)
8060     mask[12] = mask[13] = 0xff;
8061
8062   *maskp = mask;
8063   return 1;
8064 }
8065
8066 uword
8067 unformat_classify_mask (unformat_input_t * input, va_list * args)
8068 {
8069   u8 **maskp = va_arg (*args, u8 **);
8070   u32 *skipp = va_arg (*args, u32 *);
8071   u32 *matchp = va_arg (*args, u32 *);
8072   u32 match;
8073   u8 *mask = 0;
8074   u8 *l2 = 0;
8075   u8 *l3 = 0;
8076   int i;
8077
8078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8079     {
8080       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8081         ;
8082       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8083         ;
8084       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8085         ;
8086       else
8087         break;
8088     }
8089
8090   if (mask || l2 || l3)
8091     {
8092       if (l2 || l3)
8093         {
8094           /* "With a free Ethernet header in every package" */
8095           if (l2 == 0)
8096             vec_validate (l2, 13);
8097           mask = l2;
8098           if (vec_len (l3))
8099             {
8100               vec_append (mask, l3);
8101               vec_free (l3);
8102             }
8103         }
8104
8105       /* Scan forward looking for the first significant mask octet */
8106       for (i = 0; i < vec_len (mask); i++)
8107         if (mask[i])
8108           break;
8109
8110       /* compute (skip, match) params */
8111       *skipp = i / sizeof (u32x4);
8112       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8113
8114       /* Pad mask to an even multiple of the vector size */
8115       while (vec_len (mask) % sizeof (u32x4))
8116         vec_add1 (mask, 0);
8117
8118       match = vec_len (mask) / sizeof (u32x4);
8119
8120       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8121         {
8122           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8123           if (*tmp || *(tmp + 1))
8124             break;
8125           match--;
8126         }
8127       if (match == 0)
8128         clib_warning ("BUG: match 0");
8129
8130       _vec_len (mask) = match * sizeof (u32x4);
8131
8132       *matchp = match;
8133       *maskp = mask;
8134
8135       return 1;
8136     }
8137
8138   return 0;
8139 }
8140
8141 #define foreach_l2_next                         \
8142 _(drop, DROP)                                   \
8143 _(ethernet, ETHERNET_INPUT)                     \
8144 _(ip4, IP4_INPUT)                               \
8145 _(ip6, IP6_INPUT)
8146
8147 uword
8148 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8149 {
8150   u32 *miss_next_indexp = va_arg (*args, u32 *);
8151   u32 next_index = 0;
8152   u32 tmp;
8153
8154 #define _(n,N) \
8155   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8156   foreach_l2_next;
8157 #undef _
8158
8159   if (unformat (input, "%d", &tmp))
8160     {
8161       next_index = tmp;
8162       goto out;
8163     }
8164
8165   return 0;
8166
8167 out:
8168   *miss_next_indexp = next_index;
8169   return 1;
8170 }
8171
8172 #define foreach_ip_next                         \
8173 _(drop, DROP)                                   \
8174 _(local, LOCAL)                                 \
8175 _(rewrite, REWRITE)
8176
8177 uword
8178 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8179 {
8180   u32 *miss_next_indexp = va_arg (*args, u32 *);
8181   u32 next_index = 0;
8182   u32 tmp;
8183
8184 #define _(n,N) \
8185   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8186   foreach_ip_next;
8187 #undef _
8188
8189   if (unformat (input, "%d", &tmp))
8190     {
8191       next_index = tmp;
8192       goto out;
8193     }
8194
8195   return 0;
8196
8197 out:
8198   *miss_next_indexp = next_index;
8199   return 1;
8200 }
8201
8202 #define foreach_acl_next                        \
8203 _(deny, DENY)
8204
8205 uword
8206 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8207 {
8208   u32 *miss_next_indexp = va_arg (*args, u32 *);
8209   u32 next_index = 0;
8210   u32 tmp;
8211
8212 #define _(n,N) \
8213   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8214   foreach_acl_next;
8215 #undef _
8216
8217   if (unformat (input, "permit"))
8218     {
8219       next_index = ~0;
8220       goto out;
8221     }
8222   else if (unformat (input, "%d", &tmp))
8223     {
8224       next_index = tmp;
8225       goto out;
8226     }
8227
8228   return 0;
8229
8230 out:
8231   *miss_next_indexp = next_index;
8232   return 1;
8233 }
8234
8235 uword
8236 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8237 {
8238   u32 *r = va_arg (*args, u32 *);
8239
8240   if (unformat (input, "conform-color"))
8241     *r = POLICE_CONFORM;
8242   else if (unformat (input, "exceed-color"))
8243     *r = POLICE_EXCEED;
8244   else
8245     return 0;
8246
8247   return 1;
8248 }
8249
8250 static int
8251 api_classify_add_del_table (vat_main_t * vam)
8252 {
8253   unformat_input_t *i = vam->input;
8254   vl_api_classify_add_del_table_t *mp;
8255
8256   u32 nbuckets = 2;
8257   u32 skip = ~0;
8258   u32 match = ~0;
8259   int is_add = 1;
8260   u32 table_index = ~0;
8261   u32 next_table_index = ~0;
8262   u32 miss_next_index = ~0;
8263   u32 memory_size = 32 << 20;
8264   u8 *mask = 0;
8265   f64 timeout;
8266
8267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8268     {
8269       if (unformat (i, "del"))
8270         is_add = 0;
8271       else if (unformat (i, "buckets %d", &nbuckets))
8272         ;
8273       else if (unformat (i, "memory_size %d", &memory_size))
8274         ;
8275       else if (unformat (i, "skip %d", &skip))
8276         ;
8277       else if (unformat (i, "match %d", &match))
8278         ;
8279       else if (unformat (i, "table %d", &table_index))
8280         ;
8281       else if (unformat (i, "mask %U", unformat_classify_mask,
8282                          &mask, &skip, &match))
8283         ;
8284       else if (unformat (i, "next-table %d", &next_table_index))
8285         ;
8286       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8287                          &miss_next_index))
8288         ;
8289       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8290                          &miss_next_index))
8291         ;
8292       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8293                          &miss_next_index))
8294         ;
8295       else
8296         break;
8297     }
8298
8299   if (is_add && mask == 0)
8300     {
8301       errmsg ("Mask required\n");
8302       return -99;
8303     }
8304
8305   if (is_add && skip == ~0)
8306     {
8307       errmsg ("skip count required\n");
8308       return -99;
8309     }
8310
8311   if (is_add && match == ~0)
8312     {
8313       errmsg ("match count required\n");
8314       return -99;
8315     }
8316
8317   if (!is_add && table_index == ~0)
8318     {
8319       errmsg ("table index required for delete\n");
8320       return -99;
8321     }
8322
8323   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8324
8325   mp->is_add = is_add;
8326   mp->table_index = ntohl (table_index);
8327   mp->nbuckets = ntohl (nbuckets);
8328   mp->memory_size = ntohl (memory_size);
8329   mp->skip_n_vectors = ntohl (skip);
8330   mp->match_n_vectors = ntohl (match);
8331   mp->next_table_index = ntohl (next_table_index);
8332   mp->miss_next_index = ntohl (miss_next_index);
8333   clib_memcpy (mp->mask, mask, vec_len (mask));
8334
8335   vec_free (mask);
8336
8337   S;
8338   W;
8339   /* NOTREACHED */
8340 }
8341
8342 uword
8343 unformat_ip4_match (unformat_input_t * input, va_list * args)
8344 {
8345   u8 **matchp = va_arg (*args, u8 **);
8346   u8 *match = 0;
8347   ip4_header_t *ip;
8348   int version = 0;
8349   u32 version_val;
8350   int hdr_length = 0;
8351   u32 hdr_length_val;
8352   int src = 0, dst = 0;
8353   ip4_address_t src_val, dst_val;
8354   int proto = 0;
8355   u32 proto_val;
8356   int tos = 0;
8357   u32 tos_val;
8358   int length = 0;
8359   u32 length_val;
8360   int fragment_id = 0;
8361   u32 fragment_id_val;
8362   int ttl = 0;
8363   int ttl_val;
8364   int checksum = 0;
8365   u32 checksum_val;
8366
8367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8368     {
8369       if (unformat (input, "version %d", &version_val))
8370         version = 1;
8371       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8372         hdr_length = 1;
8373       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8374         src = 1;
8375       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8376         dst = 1;
8377       else if (unformat (input, "proto %d", &proto_val))
8378         proto = 1;
8379       else if (unformat (input, "tos %d", &tos_val))
8380         tos = 1;
8381       else if (unformat (input, "length %d", &length_val))
8382         length = 1;
8383       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8384         fragment_id = 1;
8385       else if (unformat (input, "ttl %d", &ttl_val))
8386         ttl = 1;
8387       else if (unformat (input, "checksum %d", &checksum_val))
8388         checksum = 1;
8389       else
8390         break;
8391     }
8392
8393   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8394       + ttl + checksum == 0)
8395     return 0;
8396
8397   /*
8398    * Aligned because we use the real comparison functions
8399    */
8400   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8401
8402   ip = (ip4_header_t *) match;
8403
8404   /* These are realistically matched in practice */
8405   if (src)
8406     ip->src_address.as_u32 = src_val.as_u32;
8407
8408   if (dst)
8409     ip->dst_address.as_u32 = dst_val.as_u32;
8410
8411   if (proto)
8412     ip->protocol = proto_val;
8413
8414
8415   /* These are not, but they're included for completeness */
8416   if (version)
8417     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8418
8419   if (hdr_length)
8420     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8421
8422   if (tos)
8423     ip->tos = tos_val;
8424
8425   if (length)
8426     ip->length = length_val;
8427
8428   if (ttl)
8429     ip->ttl = ttl_val;
8430
8431   if (checksum)
8432     ip->checksum = checksum_val;
8433
8434   *matchp = match;
8435   return 1;
8436 }
8437
8438 uword
8439 unformat_ip6_match (unformat_input_t * input, va_list * args)
8440 {
8441   u8 **matchp = va_arg (*args, u8 **);
8442   u8 *match = 0;
8443   ip6_header_t *ip;
8444   int version = 0;
8445   u32 version_val;
8446   u8 traffic_class = 0;
8447   u32 traffic_class_val = 0;
8448   u8 flow_label = 0;
8449   u8 flow_label_val;
8450   int src = 0, dst = 0;
8451   ip6_address_t src_val, dst_val;
8452   int proto = 0;
8453   u32 proto_val;
8454   int payload_length = 0;
8455   u32 payload_length_val;
8456   int hop_limit = 0;
8457   int hop_limit_val;
8458   u32 ip_version_traffic_class_and_flow_label;
8459
8460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8461     {
8462       if (unformat (input, "version %d", &version_val))
8463         version = 1;
8464       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8465         traffic_class = 1;
8466       else if (unformat (input, "flow_label %d", &flow_label_val))
8467         flow_label = 1;
8468       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8469         src = 1;
8470       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8471         dst = 1;
8472       else if (unformat (input, "proto %d", &proto_val))
8473         proto = 1;
8474       else if (unformat (input, "payload_length %d", &payload_length_val))
8475         payload_length = 1;
8476       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8477         hop_limit = 1;
8478       else
8479         break;
8480     }
8481
8482   if (version + traffic_class + flow_label + src + dst + proto +
8483       payload_length + hop_limit == 0)
8484     return 0;
8485
8486   /*
8487    * Aligned because we use the real comparison functions
8488    */
8489   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8490
8491   ip = (ip6_header_t *) match;
8492
8493   if (src)
8494     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8495
8496   if (dst)
8497     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8498
8499   if (proto)
8500     ip->protocol = proto_val;
8501
8502   ip_version_traffic_class_and_flow_label = 0;
8503
8504   if (version)
8505     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8506
8507   if (traffic_class)
8508     ip_version_traffic_class_and_flow_label |=
8509       (traffic_class_val & 0xFF) << 20;
8510
8511   if (flow_label)
8512     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8513
8514   ip->ip_version_traffic_class_and_flow_label =
8515     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8516
8517   if (payload_length)
8518     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8519
8520   if (hop_limit)
8521     ip->hop_limit = hop_limit_val;
8522
8523   *matchp = match;
8524   return 1;
8525 }
8526
8527 uword
8528 unformat_l3_match (unformat_input_t * input, va_list * args)
8529 {
8530   u8 **matchp = va_arg (*args, u8 **);
8531
8532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8533     {
8534       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8535         return 1;
8536       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8537         return 1;
8538       else
8539         break;
8540     }
8541   return 0;
8542 }
8543
8544 uword
8545 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8546 {
8547   u8 *tagp = va_arg (*args, u8 *);
8548   u32 tag;
8549
8550   if (unformat (input, "%d", &tag))
8551     {
8552       tagp[0] = (tag >> 8) & 0x0F;
8553       tagp[1] = tag & 0xFF;
8554       return 1;
8555     }
8556
8557   return 0;
8558 }
8559
8560 uword
8561 unformat_l2_match (unformat_input_t * input, va_list * args)
8562 {
8563   u8 **matchp = va_arg (*args, u8 **);
8564   u8 *match = 0;
8565   u8 src = 0;
8566   u8 src_val[6];
8567   u8 dst = 0;
8568   u8 dst_val[6];
8569   u8 proto = 0;
8570   u16 proto_val;
8571   u8 tag1 = 0;
8572   u8 tag1_val[2];
8573   u8 tag2 = 0;
8574   u8 tag2_val[2];
8575   int len = 14;
8576   u8 ignore_tag1 = 0;
8577   u8 ignore_tag2 = 0;
8578   u8 cos1 = 0;
8579   u8 cos2 = 0;
8580   u32 cos1_val = 0;
8581   u32 cos2_val = 0;
8582
8583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8584     {
8585       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8586         src = 1;
8587       else
8588         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8589         dst = 1;
8590       else if (unformat (input, "proto %U",
8591                          unformat_ethernet_type_host_byte_order, &proto_val))
8592         proto = 1;
8593       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8594         tag1 = 1;
8595       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8596         tag2 = 1;
8597       else if (unformat (input, "ignore-tag1"))
8598         ignore_tag1 = 1;
8599       else if (unformat (input, "ignore-tag2"))
8600         ignore_tag2 = 1;
8601       else if (unformat (input, "cos1 %d", &cos1_val))
8602         cos1 = 1;
8603       else if (unformat (input, "cos2 %d", &cos2_val))
8604         cos2 = 1;
8605       else
8606         break;
8607     }
8608   if ((src + dst + proto + tag1 + tag2 +
8609        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8610     return 0;
8611
8612   if (tag1 || ignore_tag1 || cos1)
8613     len = 18;
8614   if (tag2 || ignore_tag2 || cos2)
8615     len = 22;
8616
8617   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8618
8619   if (dst)
8620     clib_memcpy (match, dst_val, 6);
8621
8622   if (src)
8623     clib_memcpy (match + 6, src_val, 6);
8624
8625   if (tag2)
8626     {
8627       /* inner vlan tag */
8628       match[19] = tag2_val[1];
8629       match[18] = tag2_val[0];
8630       if (cos2)
8631         match[18] |= (cos2_val & 0x7) << 5;
8632       if (proto)
8633         {
8634           match[21] = proto_val & 0xff;
8635           match[20] = proto_val >> 8;
8636         }
8637       if (tag1)
8638         {
8639           match[15] = tag1_val[1];
8640           match[14] = tag1_val[0];
8641         }
8642       if (cos1)
8643         match[14] |= (cos1_val & 0x7) << 5;
8644       *matchp = match;
8645       return 1;
8646     }
8647   if (tag1)
8648     {
8649       match[15] = tag1_val[1];
8650       match[14] = tag1_val[0];
8651       if (proto)
8652         {
8653           match[17] = proto_val & 0xff;
8654           match[16] = proto_val >> 8;
8655         }
8656       if (cos1)
8657         match[14] |= (cos1_val & 0x7) << 5;
8658
8659       *matchp = match;
8660       return 1;
8661     }
8662   if (cos2)
8663     match[18] |= (cos2_val & 0x7) << 5;
8664   if (cos1)
8665     match[14] |= (cos1_val & 0x7) << 5;
8666   if (proto)
8667     {
8668       match[13] = proto_val & 0xff;
8669       match[12] = proto_val >> 8;
8670     }
8671
8672   *matchp = match;
8673   return 1;
8674 }
8675
8676
8677 uword
8678 unformat_classify_match (unformat_input_t * input, va_list * args)
8679 {
8680   u8 **matchp = va_arg (*args, u8 **);
8681   u32 skip_n_vectors = va_arg (*args, u32);
8682   u32 match_n_vectors = va_arg (*args, u32);
8683
8684   u8 *match = 0;
8685   u8 *l2 = 0;
8686   u8 *l3 = 0;
8687
8688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8689     {
8690       if (unformat (input, "hex %U", unformat_hex_string, &match))
8691         ;
8692       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8693         ;
8694       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8695         ;
8696       else
8697         break;
8698     }
8699
8700   if (match || l2 || l3)
8701     {
8702       if (l2 || l3)
8703         {
8704           /* "Win a free Ethernet header in every packet" */
8705           if (l2 == 0)
8706             vec_validate_aligned (l2, 13, sizeof (u32x4));
8707           match = l2;
8708           if (vec_len (l3))
8709             {
8710               vec_append_aligned (match, l3, sizeof (u32x4));
8711               vec_free (l3);
8712             }
8713         }
8714
8715       /* Make sure the vector is big enough even if key is all 0's */
8716       vec_validate_aligned
8717         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8718          sizeof (u32x4));
8719
8720       /* Set size, include skipped vectors */
8721       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8722
8723       *matchp = match;
8724
8725       return 1;
8726     }
8727
8728   return 0;
8729 }
8730
8731 static int
8732 api_classify_add_del_session (vat_main_t * vam)
8733 {
8734   unformat_input_t *i = vam->input;
8735   vl_api_classify_add_del_session_t *mp;
8736   int is_add = 1;
8737   u32 table_index = ~0;
8738   u32 hit_next_index = ~0;
8739   u32 opaque_index = ~0;
8740   u8 *match = 0;
8741   i32 advance = 0;
8742   f64 timeout;
8743   u32 skip_n_vectors = 0;
8744   u32 match_n_vectors = 0;
8745
8746   /*
8747    * Warning: you have to supply skip_n and match_n
8748    * because the API client cant simply look at the classify
8749    * table object.
8750    */
8751
8752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8753     {
8754       if (unformat (i, "del"))
8755         is_add = 0;
8756       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8757                          &hit_next_index))
8758         ;
8759       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8760                          &hit_next_index))
8761         ;
8762       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8763                          &hit_next_index))
8764         ;
8765       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8766         ;
8767       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8768         ;
8769       else if (unformat (i, "opaque-index %d", &opaque_index))
8770         ;
8771       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8772         ;
8773       else if (unformat (i, "match_n %d", &match_n_vectors))
8774         ;
8775       else if (unformat (i, "match %U", unformat_classify_match,
8776                          &match, skip_n_vectors, match_n_vectors))
8777         ;
8778       else if (unformat (i, "advance %d", &advance))
8779         ;
8780       else if (unformat (i, "table-index %d", &table_index))
8781         ;
8782       else
8783         break;
8784     }
8785
8786   if (table_index == ~0)
8787     {
8788       errmsg ("Table index required\n");
8789       return -99;
8790     }
8791
8792   if (is_add && match == 0)
8793     {
8794       errmsg ("Match value required\n");
8795       return -99;
8796     }
8797
8798   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8799
8800   mp->is_add = is_add;
8801   mp->table_index = ntohl (table_index);
8802   mp->hit_next_index = ntohl (hit_next_index);
8803   mp->opaque_index = ntohl (opaque_index);
8804   mp->advance = ntohl (advance);
8805   clib_memcpy (mp->match, match, vec_len (match));
8806   vec_free (match);
8807
8808   S;
8809   W;
8810   /* NOTREACHED */
8811 }
8812
8813 static int
8814 api_classify_set_interface_ip_table (vat_main_t * vam)
8815 {
8816   unformat_input_t *i = vam->input;
8817   vl_api_classify_set_interface_ip_table_t *mp;
8818   f64 timeout;
8819   u32 sw_if_index;
8820   int sw_if_index_set;
8821   u32 table_index = ~0;
8822   u8 is_ipv6 = 0;
8823
8824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8825     {
8826       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8827         sw_if_index_set = 1;
8828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8829         sw_if_index_set = 1;
8830       else if (unformat (i, "table %d", &table_index))
8831         ;
8832       else
8833         {
8834           clib_warning ("parse error '%U'", format_unformat_error, i);
8835           return -99;
8836         }
8837     }
8838
8839   if (sw_if_index_set == 0)
8840     {
8841       errmsg ("missing interface name or sw_if_index\n");
8842       return -99;
8843     }
8844
8845
8846   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8847
8848   mp->sw_if_index = ntohl (sw_if_index);
8849   mp->table_index = ntohl (table_index);
8850   mp->is_ipv6 = is_ipv6;
8851
8852   S;
8853   W;
8854   /* NOTREACHED */
8855   return 0;
8856 }
8857
8858 static int
8859 api_classify_set_interface_l2_tables (vat_main_t * vam)
8860 {
8861   unformat_input_t *i = vam->input;
8862   vl_api_classify_set_interface_l2_tables_t *mp;
8863   f64 timeout;
8864   u32 sw_if_index;
8865   int sw_if_index_set;
8866   u32 ip4_table_index = ~0;
8867   u32 ip6_table_index = ~0;
8868   u32 other_table_index = ~0;
8869   u32 is_input = 1;
8870
8871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8872     {
8873       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8874         sw_if_index_set = 1;
8875       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8876         sw_if_index_set = 1;
8877       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8878         ;
8879       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8880         ;
8881       else if (unformat (i, "other-table %d", &other_table_index))
8882         ;
8883       else if (unformat (i, "is-input %d", &is_input))
8884         ;
8885       else
8886         {
8887           clib_warning ("parse error '%U'", format_unformat_error, i);
8888           return -99;
8889         }
8890     }
8891
8892   if (sw_if_index_set == 0)
8893     {
8894       errmsg ("missing interface name or sw_if_index\n");
8895       return -99;
8896     }
8897
8898
8899   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8900
8901   mp->sw_if_index = ntohl (sw_if_index);
8902   mp->ip4_table_index = ntohl (ip4_table_index);
8903   mp->ip6_table_index = ntohl (ip6_table_index);
8904   mp->other_table_index = ntohl (other_table_index);
8905   mp->is_input = (u8) is_input;
8906
8907   S;
8908   W;
8909   /* NOTREACHED */
8910   return 0;
8911 }
8912
8913 static int
8914 api_set_ipfix_exporter (vat_main_t * vam)
8915 {
8916   unformat_input_t *i = vam->input;
8917   vl_api_set_ipfix_exporter_t *mp;
8918   ip4_address_t collector_address;
8919   u8 collector_address_set = 0;
8920   u32 collector_port = ~0;
8921   ip4_address_t src_address;
8922   u8 src_address_set = 0;
8923   u32 vrf_id = ~0;
8924   u32 path_mtu = ~0;
8925   u32 template_interval = ~0;
8926   u8 udp_checksum = 0;
8927   f64 timeout;
8928
8929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (i, "collector_address %U", unformat_ip4_address,
8932                     &collector_address))
8933         collector_address_set = 1;
8934       else if (unformat (i, "collector_port %d", &collector_port))
8935         ;
8936       else if (unformat (i, "src_address %U", unformat_ip4_address,
8937                          &src_address))
8938         src_address_set = 1;
8939       else if (unformat (i, "vrf_id %d", &vrf_id))
8940         ;
8941       else if (unformat (i, "path_mtu %d", &path_mtu))
8942         ;
8943       else if (unformat (i, "template_interval %d", &template_interval))
8944         ;
8945       else if (unformat (i, "udp_checksum"))
8946         udp_checksum = 1;
8947       else
8948         break;
8949     }
8950
8951   if (collector_address_set == 0)
8952     {
8953       errmsg ("collector_address required\n");
8954       return -99;
8955     }
8956
8957   if (src_address_set == 0)
8958     {
8959       errmsg ("src_address required\n");
8960       return -99;
8961     }
8962
8963   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8964
8965   memcpy (mp->collector_address, collector_address.data,
8966           sizeof (collector_address.data));
8967   mp->collector_port = htons ((u16) collector_port);
8968   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8969   mp->vrf_id = htonl (vrf_id);
8970   mp->path_mtu = htonl (path_mtu);
8971   mp->template_interval = htonl (template_interval);
8972   mp->udp_checksum = udp_checksum;
8973
8974   S;
8975   W;
8976   /* NOTREACHED */
8977 }
8978
8979 static int
8980 api_set_ipfix_classify_stream (vat_main_t * vam)
8981 {
8982   unformat_input_t *i = vam->input;
8983   vl_api_set_ipfix_classify_stream_t *mp;
8984   u32 domain_id = 0;
8985   u32 src_port = UDP_DST_PORT_ipfix;
8986   f64 timeout;
8987
8988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (i, "domain %d", &domain_id))
8991         ;
8992       else if (unformat (i, "src_port %d", &src_port))
8993         ;
8994       else
8995         {
8996           errmsg ("unknown input `%U'", format_unformat_error, i);
8997           return -99;
8998         }
8999     }
9000
9001   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9002
9003   mp->domain_id = htonl (domain_id);
9004   mp->src_port = htons ((u16) src_port);
9005
9006   S;
9007   W;
9008   /* NOTREACHED */
9009 }
9010
9011 static int
9012 api_ipfix_classify_table_add_del (vat_main_t * vam)
9013 {
9014   unformat_input_t *i = vam->input;
9015   vl_api_ipfix_classify_table_add_del_t *mp;
9016   int is_add = -1;
9017   u32 classify_table_index = ~0;
9018   u8 ip_version = 0;
9019   u8 transport_protocol = 255;
9020   f64 timeout;
9021
9022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9023     {
9024       if (unformat (i, "add"))
9025         is_add = 1;
9026       else if (unformat (i, "del"))
9027         is_add = 0;
9028       else if (unformat (i, "table %d", &classify_table_index))
9029         ;
9030       else if (unformat (i, "ip4"))
9031         ip_version = 4;
9032       else if (unformat (i, "ip6"))
9033         ip_version = 6;
9034       else if (unformat (i, "tcp"))
9035         transport_protocol = 6;
9036       else if (unformat (i, "udp"))
9037         transport_protocol = 17;
9038       else
9039         {
9040           errmsg ("unknown input `%U'", format_unformat_error, i);
9041           return -99;
9042         }
9043     }
9044
9045   if (is_add == -1)
9046     {
9047       errmsg ("expecting: add|del");
9048       return -99;
9049     }
9050   if (classify_table_index == ~0)
9051     {
9052       errmsg ("classifier table not specified");
9053       return -99;
9054     }
9055   if (ip_version == 0)
9056     {
9057       errmsg ("IP version not specified");
9058       return -99;
9059     }
9060
9061   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9062
9063   mp->is_add = is_add;
9064   mp->table_id = htonl (classify_table_index);
9065   mp->ip_version = ip_version;
9066   mp->transport_protocol = transport_protocol;
9067
9068   S;
9069   W;
9070   /* NOTREACHED */
9071 }
9072
9073 static int
9074 api_get_node_index (vat_main_t * vam)
9075 {
9076   unformat_input_t *i = vam->input;
9077   vl_api_get_node_index_t *mp;
9078   f64 timeout;
9079   u8 *name = 0;
9080
9081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9082     {
9083       if (unformat (i, "node %s", &name))
9084         ;
9085       else
9086         break;
9087     }
9088   if (name == 0)
9089     {
9090       errmsg ("node name required\n");
9091       return -99;
9092     }
9093   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9094     {
9095       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9096       return -99;
9097     }
9098
9099   M (GET_NODE_INDEX, get_node_index);
9100   clib_memcpy (mp->node_name, name, vec_len (name));
9101   vec_free (name);
9102
9103   S;
9104   W;
9105   /* NOTREACHED */
9106   return 0;
9107 }
9108
9109 static int
9110 api_get_next_index (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_get_next_index_t *mp;
9114   f64 timeout;
9115   u8 *node_name = 0, *next_node_name = 0;
9116
9117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (i, "node-name %s", &node_name))
9120         ;
9121       else if (unformat (i, "next-node-name %s", &next_node_name))
9122         break;
9123     }
9124
9125   if (node_name == 0)
9126     {
9127       errmsg ("node name required\n");
9128       return -99;
9129     }
9130   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9131     {
9132       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9133       return -99;
9134     }
9135
9136   if (next_node_name == 0)
9137     {
9138       errmsg ("next node name required\n");
9139       return -99;
9140     }
9141   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9142     {
9143       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9144       return -99;
9145     }
9146
9147   M (GET_NEXT_INDEX, get_next_index);
9148   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9149   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9150   vec_free (node_name);
9151   vec_free (next_node_name);
9152
9153   S;
9154   W;
9155   /* NOTREACHED */
9156   return 0;
9157 }
9158
9159 static int
9160 api_add_node_next (vat_main_t * vam)
9161 {
9162   unformat_input_t *i = vam->input;
9163   vl_api_add_node_next_t *mp;
9164   f64 timeout;
9165   u8 *name = 0;
9166   u8 *next = 0;
9167
9168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9169     {
9170       if (unformat (i, "node %s", &name))
9171         ;
9172       else if (unformat (i, "next %s", &next))
9173         ;
9174       else
9175         break;
9176     }
9177   if (name == 0)
9178     {
9179       errmsg ("node name required\n");
9180       return -99;
9181     }
9182   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9183     {
9184       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9185       return -99;
9186     }
9187   if (next == 0)
9188     {
9189       errmsg ("next node required\n");
9190       return -99;
9191     }
9192   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9193     {
9194       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9195       return -99;
9196     }
9197
9198   M (ADD_NODE_NEXT, add_node_next);
9199   clib_memcpy (mp->node_name, name, vec_len (name));
9200   clib_memcpy (mp->next_name, next, vec_len (next));
9201   vec_free (name);
9202   vec_free (next);
9203
9204   S;
9205   W;
9206   /* NOTREACHED */
9207   return 0;
9208 }
9209
9210 static int
9211 api_l2tpv3_create_tunnel (vat_main_t * vam)
9212 {
9213   unformat_input_t *i = vam->input;
9214   ip6_address_t client_address, our_address;
9215   int client_address_set = 0;
9216   int our_address_set = 0;
9217   u32 local_session_id = 0;
9218   u32 remote_session_id = 0;
9219   u64 local_cookie = 0;
9220   u64 remote_cookie = 0;
9221   u8 l2_sublayer_present = 0;
9222   vl_api_l2tpv3_create_tunnel_t *mp;
9223   f64 timeout;
9224
9225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9226     {
9227       if (unformat (i, "client_address %U", unformat_ip6_address,
9228                     &client_address))
9229         client_address_set = 1;
9230       else if (unformat (i, "our_address %U", unformat_ip6_address,
9231                          &our_address))
9232         our_address_set = 1;
9233       else if (unformat (i, "local_session_id %d", &local_session_id))
9234         ;
9235       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9236         ;
9237       else if (unformat (i, "local_cookie %lld", &local_cookie))
9238         ;
9239       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9240         ;
9241       else if (unformat (i, "l2-sublayer-present"))
9242         l2_sublayer_present = 1;
9243       else
9244         break;
9245     }
9246
9247   if (client_address_set == 0)
9248     {
9249       errmsg ("client_address required\n");
9250       return -99;
9251     }
9252
9253   if (our_address_set == 0)
9254     {
9255       errmsg ("our_address required\n");
9256       return -99;
9257     }
9258
9259   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9260
9261   clib_memcpy (mp->client_address, client_address.as_u8,
9262                sizeof (mp->client_address));
9263
9264   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9265
9266   mp->local_session_id = ntohl (local_session_id);
9267   mp->remote_session_id = ntohl (remote_session_id);
9268   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9269   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9270   mp->l2_sublayer_present = l2_sublayer_present;
9271   mp->is_ipv6 = 1;
9272
9273   S;
9274   W;
9275   /* NOTREACHED */
9276   return 0;
9277 }
9278
9279 static int
9280 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9281 {
9282   unformat_input_t *i = vam->input;
9283   u32 sw_if_index;
9284   u8 sw_if_index_set = 0;
9285   u64 new_local_cookie = 0;
9286   u64 new_remote_cookie = 0;
9287   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9288   f64 timeout;
9289
9290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9291     {
9292       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9293         sw_if_index_set = 1;
9294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9295         sw_if_index_set = 1;
9296       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9297         ;
9298       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9299         ;
9300       else
9301         break;
9302     }
9303
9304   if (sw_if_index_set == 0)
9305     {
9306       errmsg ("missing interface name or sw_if_index\n");
9307       return -99;
9308     }
9309
9310   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9311
9312   mp->sw_if_index = ntohl (sw_if_index);
9313   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9314   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9315
9316   S;
9317   W;
9318   /* NOTREACHED */
9319   return 0;
9320 }
9321
9322 static int
9323 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9324 {
9325   unformat_input_t *i = vam->input;
9326   vl_api_l2tpv3_interface_enable_disable_t *mp;
9327   f64 timeout;
9328   u32 sw_if_index;
9329   u8 sw_if_index_set = 0;
9330   u8 enable_disable = 1;
9331
9332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9333     {
9334       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9335         sw_if_index_set = 1;
9336       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9337         sw_if_index_set = 1;
9338       else if (unformat (i, "enable"))
9339         enable_disable = 1;
9340       else if (unformat (i, "disable"))
9341         enable_disable = 0;
9342       else
9343         break;
9344     }
9345
9346   if (sw_if_index_set == 0)
9347     {
9348       errmsg ("missing interface name or sw_if_index\n");
9349       return -99;
9350     }
9351
9352   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9353
9354   mp->sw_if_index = ntohl (sw_if_index);
9355   mp->enable_disable = enable_disable;
9356
9357   S;
9358   W;
9359   /* NOTREACHED */
9360   return 0;
9361 }
9362
9363 static int
9364 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9365 {
9366   unformat_input_t *i = vam->input;
9367   vl_api_l2tpv3_set_lookup_key_t *mp;
9368   f64 timeout;
9369   u8 key = ~0;
9370
9371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (i, "lookup_v6_src"))
9374         key = L2T_LOOKUP_SRC_ADDRESS;
9375       else if (unformat (i, "lookup_v6_dst"))
9376         key = L2T_LOOKUP_DST_ADDRESS;
9377       else if (unformat (i, "lookup_session_id"))
9378         key = L2T_LOOKUP_SESSION_ID;
9379       else
9380         break;
9381     }
9382
9383   if (key == (u8) ~ 0)
9384     {
9385       errmsg ("l2tp session lookup key unset\n");
9386       return -99;
9387     }
9388
9389   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9390
9391   mp->key = key;
9392
9393   S;
9394   W;
9395   /* NOTREACHED */
9396   return 0;
9397 }
9398
9399 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9400   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9401 {
9402   vat_main_t *vam = &vat_main;
9403
9404   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9405            format_ip6_address, mp->our_address,
9406            format_ip6_address, mp->client_address,
9407            clib_net_to_host_u32 (mp->sw_if_index));
9408
9409   fformat (vam->ofp,
9410            "   local cookies %016llx %016llx remote cookie %016llx\n",
9411            clib_net_to_host_u64 (mp->local_cookie[0]),
9412            clib_net_to_host_u64 (mp->local_cookie[1]),
9413            clib_net_to_host_u64 (mp->remote_cookie));
9414
9415   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9416            clib_net_to_host_u32 (mp->local_session_id),
9417            clib_net_to_host_u32 (mp->remote_session_id));
9418
9419   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9420            mp->l2_sublayer_present ? "preset" : "absent");
9421
9422 }
9423
9424 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9425   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9426 {
9427   vat_main_t *vam = &vat_main;
9428   vat_json_node_t *node = NULL;
9429   struct in6_addr addr;
9430
9431   if (VAT_JSON_ARRAY != vam->json_tree.type)
9432     {
9433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9434       vat_json_init_array (&vam->json_tree);
9435     }
9436   node = vat_json_array_add (&vam->json_tree);
9437
9438   vat_json_init_object (node);
9439
9440   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9441   vat_json_object_add_ip6 (node, "our_address", addr);
9442   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9443   vat_json_object_add_ip6 (node, "client_address", addr);
9444
9445   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9446   vat_json_init_array (lc);
9447   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9448   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9449   vat_json_object_add_uint (node, "remote_cookie",
9450                             clib_net_to_host_u64 (mp->remote_cookie));
9451
9452   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9453   vat_json_object_add_uint (node, "local_session_id",
9454                             clib_net_to_host_u32 (mp->local_session_id));
9455   vat_json_object_add_uint (node, "remote_session_id",
9456                             clib_net_to_host_u32 (mp->remote_session_id));
9457   vat_json_object_add_string_copy (node, "l2_sublayer",
9458                                    mp->l2_sublayer_present ? (u8 *) "present"
9459                                    : (u8 *) "absent");
9460 }
9461
9462 static int
9463 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9464 {
9465   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9466   f64 timeout;
9467
9468   /* Get list of l2tpv3-tunnel interfaces */
9469   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9470   S;
9471
9472   /* Use a control ping for synchronization */
9473   {
9474     vl_api_control_ping_t *mp;
9475     M (CONTROL_PING, control_ping);
9476     S;
9477   }
9478   W;
9479 }
9480
9481
9482 static void vl_api_sw_interface_tap_details_t_handler
9483   (vl_api_sw_interface_tap_details_t * mp)
9484 {
9485   vat_main_t *vam = &vat_main;
9486
9487   fformat (vam->ofp, "%-16s %d\n",
9488            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9489 }
9490
9491 static void vl_api_sw_interface_tap_details_t_handler_json
9492   (vl_api_sw_interface_tap_details_t * mp)
9493 {
9494   vat_main_t *vam = &vat_main;
9495   vat_json_node_t *node = NULL;
9496
9497   if (VAT_JSON_ARRAY != vam->json_tree.type)
9498     {
9499       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9500       vat_json_init_array (&vam->json_tree);
9501     }
9502   node = vat_json_array_add (&vam->json_tree);
9503
9504   vat_json_init_object (node);
9505   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9506   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9507 }
9508
9509 static int
9510 api_sw_interface_tap_dump (vat_main_t * vam)
9511 {
9512   vl_api_sw_interface_tap_dump_t *mp;
9513   f64 timeout;
9514
9515   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9516   /* Get list of tap interfaces */
9517   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9518   S;
9519
9520   /* Use a control ping for synchronization */
9521   {
9522     vl_api_control_ping_t *mp;
9523     M (CONTROL_PING, control_ping);
9524     S;
9525   }
9526   W;
9527 }
9528
9529 static uword unformat_vxlan_decap_next
9530   (unformat_input_t * input, va_list * args)
9531 {
9532   u32 *result = va_arg (*args, u32 *);
9533   u32 tmp;
9534
9535   if (unformat (input, "drop"))
9536     *result = VXLAN_INPUT_NEXT_DROP;
9537   else if (unformat (input, "ip4"))
9538     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9539   else if (unformat (input, "ip6"))
9540     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9541   else if (unformat (input, "l2"))
9542     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9543   else if (unformat (input, "%d", &tmp))
9544     *result = tmp;
9545   else
9546     return 0;
9547   return 1;
9548 }
9549
9550 static int
9551 api_vxlan_add_del_tunnel (vat_main_t * vam)
9552 {
9553   unformat_input_t *line_input = vam->input;
9554   vl_api_vxlan_add_del_tunnel_t *mp;
9555   f64 timeout;
9556   ip4_address_t src4, dst4;
9557   ip6_address_t src6, dst6;
9558   u8 is_add = 1;
9559   u8 ipv4_set = 0, ipv6_set = 0;
9560   u8 src_set = 0;
9561   u8 dst_set = 0;
9562   u32 encap_vrf_id = 0;
9563   u32 decap_next_index = ~0;
9564   u32 vni = 0;
9565
9566   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9567     {
9568       if (unformat (line_input, "del"))
9569         is_add = 0;
9570       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9571         {
9572           ipv4_set = 1;
9573           src_set = 1;
9574         }
9575       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9576         {
9577           ipv4_set = 1;
9578           dst_set = 1;
9579         }
9580       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9581         {
9582           ipv6_set = 1;
9583           src_set = 1;
9584         }
9585       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9586         {
9587           ipv6_set = 1;
9588           dst_set = 1;
9589         }
9590       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9591         ;
9592       else if (unformat (line_input, "decap-next %U",
9593                          unformat_vxlan_decap_next, &decap_next_index))
9594         ;
9595       else if (unformat (line_input, "vni %d", &vni))
9596         ;
9597       else
9598         {
9599           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9600           return -99;
9601         }
9602     }
9603
9604   if (src_set == 0)
9605     {
9606       errmsg ("tunnel src address not specified\n");
9607       return -99;
9608     }
9609   if (dst_set == 0)
9610     {
9611       errmsg ("tunnel dst address not specified\n");
9612       return -99;
9613     }
9614
9615   if (ipv4_set && ipv6_set)
9616     {
9617       errmsg ("both IPv4 and IPv6 addresses specified");
9618       return -99;
9619     }
9620
9621   if ((vni == 0) || (vni >> 24))
9622     {
9623       errmsg ("vni not specified or out of range\n");
9624       return -99;
9625     }
9626
9627   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9628
9629   if (ipv6_set)
9630     {
9631       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9632       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9633     }
9634   else
9635     {
9636       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9637       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9638     }
9639   mp->encap_vrf_id = ntohl (encap_vrf_id);
9640   mp->decap_next_index = ntohl (decap_next_index);
9641   mp->vni = ntohl (vni);
9642   mp->is_add = is_add;
9643   mp->is_ipv6 = ipv6_set;
9644
9645   S;
9646   W;
9647   /* NOTREACHED */
9648   return 0;
9649 }
9650
9651 static void vl_api_vxlan_tunnel_details_t_handler
9652   (vl_api_vxlan_tunnel_details_t * mp)
9653 {
9654   vat_main_t *vam = &vat_main;
9655
9656   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9657            ntohl (mp->sw_if_index),
9658            format_ip46_address, &(mp->src_address[0]),
9659            IP46_TYPE_ANY,
9660            format_ip46_address, &(mp->dst_address[0]),
9661            IP46_TYPE_ANY,
9662            ntohl (mp->encap_vrf_id),
9663            ntohl (mp->decap_next_index), ntohl (mp->vni));
9664 }
9665
9666 static void vl_api_vxlan_tunnel_details_t_handler_json
9667   (vl_api_vxlan_tunnel_details_t * mp)
9668 {
9669   vat_main_t *vam = &vat_main;
9670   vat_json_node_t *node = NULL;
9671   struct in_addr ip4;
9672   struct in6_addr ip6;
9673
9674   if (VAT_JSON_ARRAY != vam->json_tree.type)
9675     {
9676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9677       vat_json_init_array (&vam->json_tree);
9678     }
9679   node = vat_json_array_add (&vam->json_tree);
9680
9681   vat_json_init_object (node);
9682   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9683   if (mp->is_ipv6)
9684     {
9685       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9686       vat_json_object_add_ip6 (node, "src_address", ip6);
9687       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9688       vat_json_object_add_ip6 (node, "dst_address", ip6);
9689     }
9690   else
9691     {
9692       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9693       vat_json_object_add_ip4 (node, "src_address", ip4);
9694       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9695       vat_json_object_add_ip4 (node, "dst_address", ip4);
9696     }
9697   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9698   vat_json_object_add_uint (node, "decap_next_index",
9699                             ntohl (mp->decap_next_index));
9700   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9701   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9702 }
9703
9704 static int
9705 api_vxlan_tunnel_dump (vat_main_t * vam)
9706 {
9707   unformat_input_t *i = vam->input;
9708   vl_api_vxlan_tunnel_dump_t *mp;
9709   f64 timeout;
9710   u32 sw_if_index;
9711   u8 sw_if_index_set = 0;
9712
9713   /* Parse args required to build the message */
9714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9715     {
9716       if (unformat (i, "sw_if_index %d", &sw_if_index))
9717         sw_if_index_set = 1;
9718       else
9719         break;
9720     }
9721
9722   if (sw_if_index_set == 0)
9723     {
9724       sw_if_index = ~0;
9725     }
9726
9727   if (!vam->json_output)
9728     {
9729       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9730                "sw_if_index", "src_address", "dst_address",
9731                "encap_vrf_id", "decap_next_index", "vni");
9732     }
9733
9734   /* Get list of vxlan-tunnel interfaces */
9735   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9736
9737   mp->sw_if_index = htonl (sw_if_index);
9738
9739   S;
9740
9741   /* Use a control ping for synchronization */
9742   {
9743     vl_api_control_ping_t *mp;
9744     M (CONTROL_PING, control_ping);
9745     S;
9746   }
9747   W;
9748 }
9749
9750 static int
9751 api_gre_add_del_tunnel (vat_main_t * vam)
9752 {
9753   unformat_input_t *line_input = vam->input;
9754   vl_api_gre_add_del_tunnel_t *mp;
9755   f64 timeout;
9756   ip4_address_t src4, dst4;
9757   u8 is_add = 1;
9758   u8 teb = 0;
9759   u8 src_set = 0;
9760   u8 dst_set = 0;
9761   u32 outer_fib_id = 0;
9762
9763   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9764     {
9765       if (unformat (line_input, "del"))
9766         is_add = 0;
9767       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9768         src_set = 1;
9769       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9770         dst_set = 1;
9771       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9772         ;
9773       else if (unformat (line_input, "teb"))
9774         teb = 1;
9775       else
9776         {
9777           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9778           return -99;
9779         }
9780     }
9781
9782   if (src_set == 0)
9783     {
9784       errmsg ("tunnel src address not specified\n");
9785       return -99;
9786     }
9787   if (dst_set == 0)
9788     {
9789       errmsg ("tunnel dst address not specified\n");
9790       return -99;
9791     }
9792
9793
9794   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9795
9796   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9797   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9798   mp->outer_fib_id = ntohl (outer_fib_id);
9799   mp->is_add = is_add;
9800   mp->teb = teb;
9801
9802   S;
9803   W;
9804   /* NOTREACHED */
9805   return 0;
9806 }
9807
9808 static void vl_api_gre_tunnel_details_t_handler
9809   (vl_api_gre_tunnel_details_t * mp)
9810 {
9811   vat_main_t *vam = &vat_main;
9812
9813   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9814            ntohl (mp->sw_if_index),
9815            format_ip4_address, &mp->src_address,
9816            format_ip4_address, &mp->dst_address,
9817            mp->teb, ntohl (mp->outer_fib_id));
9818 }
9819
9820 static void vl_api_gre_tunnel_details_t_handler_json
9821   (vl_api_gre_tunnel_details_t * mp)
9822 {
9823   vat_main_t *vam = &vat_main;
9824   vat_json_node_t *node = NULL;
9825   struct in_addr ip4;
9826
9827   if (VAT_JSON_ARRAY != vam->json_tree.type)
9828     {
9829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9830       vat_json_init_array (&vam->json_tree);
9831     }
9832   node = vat_json_array_add (&vam->json_tree);
9833
9834   vat_json_init_object (node);
9835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9836   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9837   vat_json_object_add_ip4 (node, "src_address", ip4);
9838   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9839   vat_json_object_add_ip4 (node, "dst_address", ip4);
9840   vat_json_object_add_uint (node, "teb", mp->teb);
9841   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9842 }
9843
9844 static int
9845 api_gre_tunnel_dump (vat_main_t * vam)
9846 {
9847   unformat_input_t *i = vam->input;
9848   vl_api_gre_tunnel_dump_t *mp;
9849   f64 timeout;
9850   u32 sw_if_index;
9851   u8 sw_if_index_set = 0;
9852
9853   /* Parse args required to build the message */
9854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9855     {
9856       if (unformat (i, "sw_if_index %d", &sw_if_index))
9857         sw_if_index_set = 1;
9858       else
9859         break;
9860     }
9861
9862   if (sw_if_index_set == 0)
9863     {
9864       sw_if_index = ~0;
9865     }
9866
9867   if (!vam->json_output)
9868     {
9869       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9870                "sw_if_index", "src_address", "dst_address", "teb",
9871                "outer_fib_id");
9872     }
9873
9874   /* Get list of gre-tunnel interfaces */
9875   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9876
9877   mp->sw_if_index = htonl (sw_if_index);
9878
9879   S;
9880
9881   /* Use a control ping for synchronization */
9882   {
9883     vl_api_control_ping_t *mp;
9884     M (CONTROL_PING, control_ping);
9885     S;
9886   }
9887   W;
9888 }
9889
9890 static int
9891 api_l2_fib_clear_table (vat_main_t * vam)
9892 {
9893 //  unformat_input_t * i = vam->input;
9894   vl_api_l2_fib_clear_table_t *mp;
9895   f64 timeout;
9896
9897   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9898
9899   S;
9900   W;
9901   /* NOTREACHED */
9902   return 0;
9903 }
9904
9905 static int
9906 api_l2_interface_efp_filter (vat_main_t * vam)
9907 {
9908   unformat_input_t *i = vam->input;
9909   vl_api_l2_interface_efp_filter_t *mp;
9910   f64 timeout;
9911   u32 sw_if_index;
9912   u8 enable = 1;
9913   u8 sw_if_index_set = 0;
9914
9915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9916     {
9917       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9918         sw_if_index_set = 1;
9919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9920         sw_if_index_set = 1;
9921       else if (unformat (i, "enable"))
9922         enable = 1;
9923       else if (unformat (i, "disable"))
9924         enable = 0;
9925       else
9926         {
9927           clib_warning ("parse error '%U'", format_unformat_error, i);
9928           return -99;
9929         }
9930     }
9931
9932   if (sw_if_index_set == 0)
9933     {
9934       errmsg ("missing sw_if_index\n");
9935       return -99;
9936     }
9937
9938   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9939
9940   mp->sw_if_index = ntohl (sw_if_index);
9941   mp->enable_disable = enable;
9942
9943   S;
9944   W;
9945   /* NOTREACHED */
9946   return 0;
9947 }
9948
9949 #define foreach_vtr_op                          \
9950 _("disable",  L2_VTR_DISABLED)                  \
9951 _("push-1",  L2_VTR_PUSH_1)                     \
9952 _("push-2",  L2_VTR_PUSH_2)                     \
9953 _("pop-1",  L2_VTR_POP_1)                       \
9954 _("pop-2",  L2_VTR_POP_2)                       \
9955 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9956 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9957 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9958 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9959
9960 static int
9961 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9962 {
9963   unformat_input_t *i = vam->input;
9964   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9965   f64 timeout;
9966   u32 sw_if_index;
9967   u8 sw_if_index_set = 0;
9968   u8 vtr_op_set = 0;
9969   u32 vtr_op = 0;
9970   u32 push_dot1q = 1;
9971   u32 tag1 = ~0;
9972   u32 tag2 = ~0;
9973
9974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9975     {
9976       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9977         sw_if_index_set = 1;
9978       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9979         sw_if_index_set = 1;
9980       else if (unformat (i, "vtr_op %d", &vtr_op))
9981         vtr_op_set = 1;
9982 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9983       foreach_vtr_op
9984 #undef _
9985         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9986         ;
9987       else if (unformat (i, "tag1 %d", &tag1))
9988         ;
9989       else if (unformat (i, "tag2 %d", &tag2))
9990         ;
9991       else
9992         {
9993           clib_warning ("parse error '%U'", format_unformat_error, i);
9994           return -99;
9995         }
9996     }
9997
9998   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9999     {
10000       errmsg ("missing vtr operation or sw_if_index\n");
10001       return -99;
10002     }
10003
10004   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10005     mp->sw_if_index = ntohl (sw_if_index);
10006   mp->vtr_op = ntohl (vtr_op);
10007   mp->push_dot1q = ntohl (push_dot1q);
10008   mp->tag1 = ntohl (tag1);
10009   mp->tag2 = ntohl (tag2);
10010
10011   S;
10012   W;
10013   /* NOTREACHED */
10014   return 0;
10015 }
10016
10017 static int
10018 api_create_vhost_user_if (vat_main_t * vam)
10019 {
10020   unformat_input_t *i = vam->input;
10021   vl_api_create_vhost_user_if_t *mp;
10022   f64 timeout;
10023   u8 *file_name;
10024   u8 is_server = 0;
10025   u8 file_name_set = 0;
10026   u32 custom_dev_instance = ~0;
10027   u8 hwaddr[6];
10028   u8 use_custom_mac = 0;
10029
10030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10031     {
10032       if (unformat (i, "socket %s", &file_name))
10033         {
10034           file_name_set = 1;
10035         }
10036       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10037         ;
10038       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10039         use_custom_mac = 1;
10040       else if (unformat (i, "server"))
10041         is_server = 1;
10042       else
10043         break;
10044     }
10045
10046   if (file_name_set == 0)
10047     {
10048       errmsg ("missing socket file name\n");
10049       return -99;
10050     }
10051
10052   if (vec_len (file_name) > 255)
10053     {
10054       errmsg ("socket file name too long\n");
10055       return -99;
10056     }
10057   vec_add1 (file_name, 0);
10058
10059   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10060
10061   mp->is_server = is_server;
10062   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10063   vec_free (file_name);
10064   if (custom_dev_instance != ~0)
10065     {
10066       mp->renumber = 1;
10067       mp->custom_dev_instance = ntohl (custom_dev_instance);
10068     }
10069   mp->use_custom_mac = use_custom_mac;
10070   clib_memcpy (mp->mac_address, hwaddr, 6);
10071
10072   S;
10073   W;
10074   /* NOTREACHED */
10075   return 0;
10076 }
10077
10078 static int
10079 api_modify_vhost_user_if (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_modify_vhost_user_if_t *mp;
10083   f64 timeout;
10084   u8 *file_name;
10085   u8 is_server = 0;
10086   u8 file_name_set = 0;
10087   u32 custom_dev_instance = ~0;
10088   u8 sw_if_index_set = 0;
10089   u32 sw_if_index = (u32) ~ 0;
10090
10091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10092     {
10093       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10094         sw_if_index_set = 1;
10095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10096         sw_if_index_set = 1;
10097       else if (unformat (i, "socket %s", &file_name))
10098         {
10099           file_name_set = 1;
10100         }
10101       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10102         ;
10103       else if (unformat (i, "server"))
10104         is_server = 1;
10105       else
10106         break;
10107     }
10108
10109   if (sw_if_index_set == 0)
10110     {
10111       errmsg ("missing sw_if_index or interface name\n");
10112       return -99;
10113     }
10114
10115   if (file_name_set == 0)
10116     {
10117       errmsg ("missing socket file name\n");
10118       return -99;
10119     }
10120
10121   if (vec_len (file_name) > 255)
10122     {
10123       errmsg ("socket file name too long\n");
10124       return -99;
10125     }
10126   vec_add1 (file_name, 0);
10127
10128   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10129
10130   mp->sw_if_index = ntohl (sw_if_index);
10131   mp->is_server = is_server;
10132   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10133   vec_free (file_name);
10134   if (custom_dev_instance != ~0)
10135     {
10136       mp->renumber = 1;
10137       mp->custom_dev_instance = ntohl (custom_dev_instance);
10138     }
10139
10140   S;
10141   W;
10142   /* NOTREACHED */
10143   return 0;
10144 }
10145
10146 static int
10147 api_delete_vhost_user_if (vat_main_t * vam)
10148 {
10149   unformat_input_t *i = vam->input;
10150   vl_api_delete_vhost_user_if_t *mp;
10151   f64 timeout;
10152   u32 sw_if_index = ~0;
10153   u8 sw_if_index_set = 0;
10154
10155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10158         sw_if_index_set = 1;
10159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10160         sw_if_index_set = 1;
10161       else
10162         break;
10163     }
10164
10165   if (sw_if_index_set == 0)
10166     {
10167       errmsg ("missing sw_if_index or interface name\n");
10168       return -99;
10169     }
10170
10171
10172   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10173
10174   mp->sw_if_index = ntohl (sw_if_index);
10175
10176   S;
10177   W;
10178   /* NOTREACHED */
10179   return 0;
10180 }
10181
10182 static void vl_api_sw_interface_vhost_user_details_t_handler
10183   (vl_api_sw_interface_vhost_user_details_t * mp)
10184 {
10185   vat_main_t *vam = &vat_main;
10186
10187   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10188            (char *) mp->interface_name,
10189            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10190            clib_net_to_host_u64 (mp->features), mp->is_server,
10191            ntohl (mp->num_regions), (char *) mp->sock_filename);
10192   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10193 }
10194
10195 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10196   (vl_api_sw_interface_vhost_user_details_t * mp)
10197 {
10198   vat_main_t *vam = &vat_main;
10199   vat_json_node_t *node = NULL;
10200
10201   if (VAT_JSON_ARRAY != vam->json_tree.type)
10202     {
10203       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10204       vat_json_init_array (&vam->json_tree);
10205     }
10206   node = vat_json_array_add (&vam->json_tree);
10207
10208   vat_json_init_object (node);
10209   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10210   vat_json_object_add_string_copy (node, "interface_name",
10211                                    mp->interface_name);
10212   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10213                             ntohl (mp->virtio_net_hdr_sz));
10214   vat_json_object_add_uint (node, "features",
10215                             clib_net_to_host_u64 (mp->features));
10216   vat_json_object_add_uint (node, "is_server", mp->is_server);
10217   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10218   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10219   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10220 }
10221
10222 static int
10223 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10224 {
10225   vl_api_sw_interface_vhost_user_dump_t *mp;
10226   f64 timeout;
10227   fformat (vam->ofp,
10228            "Interface name           idx hdr_sz features server regions filename\n");
10229
10230   /* Get list of vhost-user interfaces */
10231   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10232   S;
10233
10234   /* Use a control ping for synchronization */
10235   {
10236     vl_api_control_ping_t *mp;
10237     M (CONTROL_PING, control_ping);
10238     S;
10239   }
10240   W;
10241 }
10242
10243 static int
10244 api_show_version (vat_main_t * vam)
10245 {
10246   vl_api_show_version_t *mp;
10247   f64 timeout;
10248
10249   M (SHOW_VERSION, show_version);
10250
10251   S;
10252   W;
10253   /* NOTREACHED */
10254   return 0;
10255 }
10256
10257
10258 static int
10259 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10260 {
10261   unformat_input_t *line_input = vam->input;
10262   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10263   f64 timeout;
10264   ip4_address_t local4, remote4;
10265   ip6_address_t local6, remote6;
10266   u8 is_add = 1;
10267   u8 ipv4_set = 0, ipv6_set = 0;
10268   u8 local_set = 0;
10269   u8 remote_set = 0;
10270   u32 encap_vrf_id = 0;
10271   u32 decap_vrf_id = 0;
10272   u8 protocol = ~0;
10273   u32 vni;
10274   u8 vni_set = 0;
10275
10276   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10277     {
10278       if (unformat (line_input, "del"))
10279         is_add = 0;
10280       else if (unformat (line_input, "local %U",
10281                          unformat_ip4_address, &local4))
10282         {
10283           local_set = 1;
10284           ipv4_set = 1;
10285         }
10286       else if (unformat (line_input, "remote %U",
10287                          unformat_ip4_address, &remote4))
10288         {
10289           remote_set = 1;
10290           ipv4_set = 1;
10291         }
10292       else if (unformat (line_input, "local %U",
10293                          unformat_ip6_address, &local6))
10294         {
10295           local_set = 1;
10296           ipv6_set = 1;
10297         }
10298       else if (unformat (line_input, "remote %U",
10299                          unformat_ip6_address, &remote6))
10300         {
10301           remote_set = 1;
10302           ipv6_set = 1;
10303         }
10304       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10305         ;
10306       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10307         ;
10308       else if (unformat (line_input, "vni %d", &vni))
10309         vni_set = 1;
10310       else if (unformat (line_input, "next-ip4"))
10311         protocol = 1;
10312       else if (unformat (line_input, "next-ip6"))
10313         protocol = 2;
10314       else if (unformat (line_input, "next-ethernet"))
10315         protocol = 3;
10316       else if (unformat (line_input, "next-nsh"))
10317         protocol = 4;
10318       else
10319         {
10320           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10321           return -99;
10322         }
10323     }
10324
10325   if (local_set == 0)
10326     {
10327       errmsg ("tunnel local address not specified\n");
10328       return -99;
10329     }
10330   if (remote_set == 0)
10331     {
10332       errmsg ("tunnel remote address not specified\n");
10333       return -99;
10334     }
10335   if (ipv4_set && ipv6_set)
10336     {
10337       errmsg ("both IPv4 and IPv6 addresses specified");
10338       return -99;
10339     }
10340
10341   if (vni_set == 0)
10342     {
10343       errmsg ("vni not specified\n");
10344       return -99;
10345     }
10346
10347   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10348
10349
10350   if (ipv6_set)
10351     {
10352       clib_memcpy (&mp->local, &local6, sizeof (local6));
10353       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10354     }
10355   else
10356     {
10357       clib_memcpy (&mp->local, &local4, sizeof (local4));
10358       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10359     }
10360
10361   mp->encap_vrf_id = ntohl (encap_vrf_id);
10362   mp->decap_vrf_id = ntohl (decap_vrf_id);
10363   mp->protocol = ntohl (protocol);
10364   mp->vni = ntohl (vni);
10365   mp->is_add = is_add;
10366   mp->is_ipv6 = ipv6_set;
10367
10368   S;
10369   W;
10370   /* NOTREACHED */
10371   return 0;
10372 }
10373
10374 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10375   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10376 {
10377   vat_main_t *vam = &vat_main;
10378
10379   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10380            ntohl (mp->sw_if_index),
10381            format_ip46_address, &(mp->local[0]),
10382            format_ip46_address, &(mp->remote[0]),
10383            ntohl (mp->vni),
10384            ntohl (mp->protocol),
10385            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10386 }
10387
10388 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10389   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10390 {
10391   vat_main_t *vam = &vat_main;
10392   vat_json_node_t *node = NULL;
10393   struct in_addr ip4;
10394   struct in6_addr ip6;
10395
10396   if (VAT_JSON_ARRAY != vam->json_tree.type)
10397     {
10398       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10399       vat_json_init_array (&vam->json_tree);
10400     }
10401   node = vat_json_array_add (&vam->json_tree);
10402
10403   vat_json_init_object (node);
10404   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10405   if (mp->is_ipv6)
10406     {
10407       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10408       vat_json_object_add_ip6 (node, "local", ip6);
10409       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10410       vat_json_object_add_ip6 (node, "remote", ip6);
10411     }
10412   else
10413     {
10414       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10415       vat_json_object_add_ip4 (node, "local", ip4);
10416       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10417       vat_json_object_add_ip4 (node, "remote", ip4);
10418     }
10419   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10420   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10421   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10422   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10423   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10424 }
10425
10426 static int
10427 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10428 {
10429   unformat_input_t *i = vam->input;
10430   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10431   f64 timeout;
10432   u32 sw_if_index;
10433   u8 sw_if_index_set = 0;
10434
10435   /* Parse args required to build the message */
10436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10437     {
10438       if (unformat (i, "sw_if_index %d", &sw_if_index))
10439         sw_if_index_set = 1;
10440       else
10441         break;
10442     }
10443
10444   if (sw_if_index_set == 0)
10445     {
10446       sw_if_index = ~0;
10447     }
10448
10449   if (!vam->json_output)
10450     {
10451       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10452                "sw_if_index", "local", "remote", "vni",
10453                "protocol", "encap_vrf_id", "decap_vrf_id");
10454     }
10455
10456   /* Get list of vxlan-tunnel interfaces */
10457   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10458
10459   mp->sw_if_index = htonl (sw_if_index);
10460
10461   S;
10462
10463   /* Use a control ping for synchronization */
10464   {
10465     vl_api_control_ping_t *mp;
10466     M (CONTROL_PING, control_ping);
10467     S;
10468   }
10469   W;
10470 }
10471
10472 u8 *
10473 format_l2_fib_mac_address (u8 * s, va_list * args)
10474 {
10475   u8 *a = va_arg (*args, u8 *);
10476
10477   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10478                  a[2], a[3], a[4], a[5], a[6], a[7]);
10479 }
10480
10481 static void vl_api_l2_fib_table_entry_t_handler
10482   (vl_api_l2_fib_table_entry_t * mp)
10483 {
10484   vat_main_t *vam = &vat_main;
10485
10486   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10487            "       %d       %d     %d\n",
10488            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10489            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10490            mp->bvi_mac);
10491 }
10492
10493 static void vl_api_l2_fib_table_entry_t_handler_json
10494   (vl_api_l2_fib_table_entry_t * mp)
10495 {
10496   vat_main_t *vam = &vat_main;
10497   vat_json_node_t *node = NULL;
10498
10499   if (VAT_JSON_ARRAY != vam->json_tree.type)
10500     {
10501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10502       vat_json_init_array (&vam->json_tree);
10503     }
10504   node = vat_json_array_add (&vam->json_tree);
10505
10506   vat_json_init_object (node);
10507   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10508   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10509   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10510   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10511   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10512   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10513 }
10514
10515 static int
10516 api_l2_fib_table_dump (vat_main_t * vam)
10517 {
10518   unformat_input_t *i = vam->input;
10519   vl_api_l2_fib_table_dump_t *mp;
10520   f64 timeout;
10521   u32 bd_id;
10522   u8 bd_id_set = 0;
10523
10524   /* Parse args required to build the message */
10525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10526     {
10527       if (unformat (i, "bd_id %d", &bd_id))
10528         bd_id_set = 1;
10529       else
10530         break;
10531     }
10532
10533   if (bd_id_set == 0)
10534     {
10535       errmsg ("missing bridge domain\n");
10536       return -99;
10537     }
10538
10539   fformat (vam->ofp,
10540            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10541
10542   /* Get list of l2 fib entries */
10543   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10544
10545   mp->bd_id = ntohl (bd_id);
10546   S;
10547
10548   /* Use a control ping for synchronization */
10549   {
10550     vl_api_control_ping_t *mp;
10551     M (CONTROL_PING, control_ping);
10552     S;
10553   }
10554   W;
10555 }
10556
10557
10558 static int
10559 api_interface_name_renumber (vat_main_t * vam)
10560 {
10561   unformat_input_t *line_input = vam->input;
10562   vl_api_interface_name_renumber_t *mp;
10563   u32 sw_if_index = ~0;
10564   f64 timeout;
10565   u32 new_show_dev_instance = ~0;
10566
10567   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10568     {
10569       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10570                     &sw_if_index))
10571         ;
10572       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10573         ;
10574       else if (unformat (line_input, "new_show_dev_instance %d",
10575                          &new_show_dev_instance))
10576         ;
10577       else
10578         break;
10579     }
10580
10581   if (sw_if_index == ~0)
10582     {
10583       errmsg ("missing interface name or sw_if_index\n");
10584       return -99;
10585     }
10586
10587   if (new_show_dev_instance == ~0)
10588     {
10589       errmsg ("missing new_show_dev_instance\n");
10590       return -99;
10591     }
10592
10593   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10594
10595   mp->sw_if_index = ntohl (sw_if_index);
10596   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10597
10598   S;
10599   W;
10600 }
10601
10602 static int
10603 api_want_ip4_arp_events (vat_main_t * vam)
10604 {
10605   unformat_input_t *line_input = vam->input;
10606   vl_api_want_ip4_arp_events_t *mp;
10607   f64 timeout;
10608   ip4_address_t address;
10609   int address_set = 0;
10610   u32 enable_disable = 1;
10611
10612   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10613     {
10614       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10615         address_set = 1;
10616       else if (unformat (line_input, "del"))
10617         enable_disable = 0;
10618       else
10619         break;
10620     }
10621
10622   if (address_set == 0)
10623     {
10624       errmsg ("missing addresses\n");
10625       return -99;
10626     }
10627
10628   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10629   mp->enable_disable = enable_disable;
10630   mp->pid = getpid ();
10631   mp->address = address.as_u32;
10632
10633   S;
10634   W;
10635 }
10636
10637 static int
10638 api_want_ip6_nd_events (vat_main_t * vam)
10639 {
10640   unformat_input_t *line_input = vam->input;
10641   vl_api_want_ip6_nd_events_t *mp;
10642   f64 timeout;
10643   ip6_address_t address;
10644   int address_set = 0;
10645   u32 enable_disable = 1;
10646
10647   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10648     {
10649       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10650         address_set = 1;
10651       else if (unformat (line_input, "del"))
10652         enable_disable = 0;
10653       else
10654         break;
10655     }
10656
10657   if (address_set == 0)
10658     {
10659       errmsg ("missing addresses\n");
10660       return -99;
10661     }
10662
10663   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10664   mp->enable_disable = enable_disable;
10665   mp->pid = getpid ();
10666   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10667
10668   S;
10669   W;
10670 }
10671
10672 static int
10673 api_input_acl_set_interface (vat_main_t * vam)
10674 {
10675   unformat_input_t *i = vam->input;
10676   vl_api_input_acl_set_interface_t *mp;
10677   f64 timeout;
10678   u32 sw_if_index;
10679   int sw_if_index_set;
10680   u32 ip4_table_index = ~0;
10681   u32 ip6_table_index = ~0;
10682   u32 l2_table_index = ~0;
10683   u8 is_add = 1;
10684
10685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10686     {
10687       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10688         sw_if_index_set = 1;
10689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10690         sw_if_index_set = 1;
10691       else if (unformat (i, "del"))
10692         is_add = 0;
10693       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10694         ;
10695       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10696         ;
10697       else if (unformat (i, "l2-table %d", &l2_table_index))
10698         ;
10699       else
10700         {
10701           clib_warning ("parse error '%U'", format_unformat_error, i);
10702           return -99;
10703         }
10704     }
10705
10706   if (sw_if_index_set == 0)
10707     {
10708       errmsg ("missing interface name or sw_if_index\n");
10709       return -99;
10710     }
10711
10712   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10713
10714   mp->sw_if_index = ntohl (sw_if_index);
10715   mp->ip4_table_index = ntohl (ip4_table_index);
10716   mp->ip6_table_index = ntohl (ip6_table_index);
10717   mp->l2_table_index = ntohl (l2_table_index);
10718   mp->is_add = is_add;
10719
10720   S;
10721   W;
10722   /* NOTREACHED */
10723   return 0;
10724 }
10725
10726 static int
10727 api_ip_address_dump (vat_main_t * vam)
10728 {
10729   unformat_input_t *i = vam->input;
10730   vl_api_ip_address_dump_t *mp;
10731   u32 sw_if_index = ~0;
10732   u8 sw_if_index_set = 0;
10733   u8 ipv4_set = 0;
10734   u8 ipv6_set = 0;
10735   f64 timeout;
10736
10737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10738     {
10739       if (unformat (i, "sw_if_index %d", &sw_if_index))
10740         sw_if_index_set = 1;
10741       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10742         sw_if_index_set = 1;
10743       else if (unformat (i, "ipv4"))
10744         ipv4_set = 1;
10745       else if (unformat (i, "ipv6"))
10746         ipv6_set = 1;
10747       else
10748         break;
10749     }
10750
10751   if (ipv4_set && ipv6_set)
10752     {
10753       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10754       return -99;
10755     }
10756
10757   if ((!ipv4_set) && (!ipv6_set))
10758     {
10759       errmsg ("no ipv4 nor ipv6 flag set\n");
10760       return -99;
10761     }
10762
10763   if (sw_if_index_set == 0)
10764     {
10765       errmsg ("missing interface name or sw_if_index\n");
10766       return -99;
10767     }
10768
10769   vam->current_sw_if_index = sw_if_index;
10770   vam->is_ipv6 = ipv6_set;
10771
10772   M (IP_ADDRESS_DUMP, ip_address_dump);
10773   mp->sw_if_index = ntohl (sw_if_index);
10774   mp->is_ipv6 = ipv6_set;
10775   S;
10776
10777   /* Use a control ping for synchronization */
10778   {
10779     vl_api_control_ping_t *mp;
10780     M (CONTROL_PING, control_ping);
10781     S;
10782   }
10783   W;
10784 }
10785
10786 static int
10787 api_ip_dump (vat_main_t * vam)
10788 {
10789   vl_api_ip_dump_t *mp;
10790   unformat_input_t *in = vam->input;
10791   int ipv4_set = 0;
10792   int ipv6_set = 0;
10793   int is_ipv6;
10794   f64 timeout;
10795   int i;
10796
10797   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10798     {
10799       if (unformat (in, "ipv4"))
10800         ipv4_set = 1;
10801       else if (unformat (in, "ipv6"))
10802         ipv6_set = 1;
10803       else
10804         break;
10805     }
10806
10807   if (ipv4_set && ipv6_set)
10808     {
10809       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10810       return -99;
10811     }
10812
10813   if ((!ipv4_set) && (!ipv6_set))
10814     {
10815       errmsg ("no ipv4 nor ipv6 flag set\n");
10816       return -99;
10817     }
10818
10819   is_ipv6 = ipv6_set;
10820   vam->is_ipv6 = is_ipv6;
10821
10822   /* free old data */
10823   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10824     {
10825       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10826     }
10827   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10828
10829   M (IP_DUMP, ip_dump);
10830   mp->is_ipv6 = ipv6_set;
10831   S;
10832
10833   /* Use a control ping for synchronization */
10834   {
10835     vl_api_control_ping_t *mp;
10836     M (CONTROL_PING, control_ping);
10837     S;
10838   }
10839   W;
10840 }
10841
10842 static int
10843 api_ipsec_spd_add_del (vat_main_t * vam)
10844 {
10845 #if DPDK > 0
10846   unformat_input_t *i = vam->input;
10847   vl_api_ipsec_spd_add_del_t *mp;
10848   f64 timeout;
10849   u32 spd_id = ~0;
10850   u8 is_add = 1;
10851
10852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (i, "spd_id %d", &spd_id))
10855         ;
10856       else if (unformat (i, "del"))
10857         is_add = 0;
10858       else
10859         {
10860           clib_warning ("parse error '%U'", format_unformat_error, i);
10861           return -99;
10862         }
10863     }
10864   if (spd_id == ~0)
10865     {
10866       errmsg ("spd_id must be set\n");
10867       return -99;
10868     }
10869
10870   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10871
10872   mp->spd_id = ntohl (spd_id);
10873   mp->is_add = is_add;
10874
10875   S;
10876   W;
10877   /* NOTREACHED */
10878   return 0;
10879 #else
10880   clib_warning ("unsupported (no dpdk)");
10881   return -99;
10882 #endif
10883 }
10884
10885 static int
10886 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10887 {
10888 #if DPDK > 0
10889   unformat_input_t *i = vam->input;
10890   vl_api_ipsec_interface_add_del_spd_t *mp;
10891   f64 timeout;
10892   u32 sw_if_index;
10893   u8 sw_if_index_set = 0;
10894   u32 spd_id = (u32) ~ 0;
10895   u8 is_add = 1;
10896
10897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10898     {
10899       if (unformat (i, "del"))
10900         is_add = 0;
10901       else if (unformat (i, "spd_id %d", &spd_id))
10902         ;
10903       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10904         sw_if_index_set = 1;
10905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10906         sw_if_index_set = 1;
10907       else
10908         {
10909           clib_warning ("parse error '%U'", format_unformat_error, i);
10910           return -99;
10911         }
10912
10913     }
10914
10915   if (spd_id == (u32) ~ 0)
10916     {
10917       errmsg ("spd_id must be set\n");
10918       return -99;
10919     }
10920
10921   if (sw_if_index_set == 0)
10922     {
10923       errmsg ("missing interface name or sw_if_index\n");
10924       return -99;
10925     }
10926
10927   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10928
10929   mp->spd_id = ntohl (spd_id);
10930   mp->sw_if_index = ntohl (sw_if_index);
10931   mp->is_add = is_add;
10932
10933   S;
10934   W;
10935   /* NOTREACHED */
10936   return 0;
10937 #else
10938   clib_warning ("unsupported (no dpdk)");
10939   return -99;
10940 #endif
10941 }
10942
10943 static int
10944 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10945 {
10946 #if DPDK > 0
10947   unformat_input_t *i = vam->input;
10948   vl_api_ipsec_spd_add_del_entry_t *mp;
10949   f64 timeout;
10950   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10951   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10952   i32 priority = 0;
10953   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10954   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10955   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10956   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10957
10958   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10959   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10960   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10961   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10962   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10963   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10964
10965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10966     {
10967       if (unformat (i, "del"))
10968         is_add = 0;
10969       if (unformat (i, "outbound"))
10970         is_outbound = 1;
10971       if (unformat (i, "inbound"))
10972         is_outbound = 0;
10973       else if (unformat (i, "spd_id %d", &spd_id))
10974         ;
10975       else if (unformat (i, "sa_id %d", &sa_id))
10976         ;
10977       else if (unformat (i, "priority %d", &priority))
10978         ;
10979       else if (unformat (i, "protocol %d", &protocol))
10980         ;
10981       else if (unformat (i, "lport_start %d", &lport_start))
10982         ;
10983       else if (unformat (i, "lport_stop %d", &lport_stop))
10984         ;
10985       else if (unformat (i, "rport_start %d", &rport_start))
10986         ;
10987       else if (unformat (i, "rport_stop %d", &rport_stop))
10988         ;
10989       else
10990         if (unformat
10991             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10992         {
10993           is_ipv6 = 0;
10994           is_ip_any = 0;
10995         }
10996       else
10997         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10998         {
10999           is_ipv6 = 0;
11000           is_ip_any = 0;
11001         }
11002       else
11003         if (unformat
11004             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11005         {
11006           is_ipv6 = 0;
11007           is_ip_any = 0;
11008         }
11009       else
11010         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11011         {
11012           is_ipv6 = 0;
11013           is_ip_any = 0;
11014         }
11015       else
11016         if (unformat
11017             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11018         {
11019           is_ipv6 = 1;
11020           is_ip_any = 0;
11021         }
11022       else
11023         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11024         {
11025           is_ipv6 = 1;
11026           is_ip_any = 0;
11027         }
11028       else
11029         if (unformat
11030             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11031         {
11032           is_ipv6 = 1;
11033           is_ip_any = 0;
11034         }
11035       else
11036         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11037         {
11038           is_ipv6 = 1;
11039           is_ip_any = 0;
11040         }
11041       else
11042         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11043         {
11044           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11045             {
11046               clib_warning ("unsupported action: 'resolve'");
11047               return -99;
11048             }
11049         }
11050       else
11051         {
11052           clib_warning ("parse error '%U'", format_unformat_error, i);
11053           return -99;
11054         }
11055
11056     }
11057
11058   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11059
11060   mp->spd_id = ntohl (spd_id);
11061   mp->priority = ntohl (priority);
11062   mp->is_outbound = is_outbound;
11063
11064   mp->is_ipv6 = is_ipv6;
11065   if (is_ipv6 || is_ip_any)
11066     {
11067       clib_memcpy (mp->remote_address_start, &raddr6_start,
11068                    sizeof (ip6_address_t));
11069       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11070                    sizeof (ip6_address_t));
11071       clib_memcpy (mp->local_address_start, &laddr6_start,
11072                    sizeof (ip6_address_t));
11073       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11074                    sizeof (ip6_address_t));
11075     }
11076   else
11077     {
11078       clib_memcpy (mp->remote_address_start, &raddr4_start,
11079                    sizeof (ip4_address_t));
11080       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11081                    sizeof (ip4_address_t));
11082       clib_memcpy (mp->local_address_start, &laddr4_start,
11083                    sizeof (ip4_address_t));
11084       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11085                    sizeof (ip4_address_t));
11086     }
11087   mp->protocol = (u8) protocol;
11088   mp->local_port_start = ntohs ((u16) lport_start);
11089   mp->local_port_stop = ntohs ((u16) lport_stop);
11090   mp->remote_port_start = ntohs ((u16) rport_start);
11091   mp->remote_port_stop = ntohs ((u16) rport_stop);
11092   mp->policy = (u8) policy;
11093   mp->sa_id = ntohl (sa_id);
11094   mp->is_add = is_add;
11095   mp->is_ip_any = is_ip_any;
11096   S;
11097   W;
11098   /* NOTREACHED */
11099   return 0;
11100 #else
11101   clib_warning ("unsupported (no dpdk)");
11102   return -99;
11103 #endif
11104 }
11105
11106 static int
11107 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11108 {
11109 #if DPDK > 0
11110   unformat_input_t *i = vam->input;
11111   vl_api_ipsec_sad_add_del_entry_t *mp;
11112   f64 timeout;
11113   u32 sad_id = 0, spi = 0;
11114   u8 *ck = 0, *ik = 0;
11115   u8 is_add = 1;
11116
11117   u8 protocol = IPSEC_PROTOCOL_AH;
11118   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11119   u32 crypto_alg = 0, integ_alg = 0;
11120   ip4_address_t tun_src4;
11121   ip4_address_t tun_dst4;
11122   ip6_address_t tun_src6;
11123   ip6_address_t tun_dst6;
11124
11125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11126     {
11127       if (unformat (i, "del"))
11128         is_add = 0;
11129       else if (unformat (i, "sad_id %d", &sad_id))
11130         ;
11131       else if (unformat (i, "spi %d", &spi))
11132         ;
11133       else if (unformat (i, "esp"))
11134         protocol = IPSEC_PROTOCOL_ESP;
11135       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11136         {
11137           is_tunnel = 1;
11138           is_tunnel_ipv6 = 0;
11139         }
11140       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11141         {
11142           is_tunnel = 1;
11143           is_tunnel_ipv6 = 0;
11144         }
11145       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11146         {
11147           is_tunnel = 1;
11148           is_tunnel_ipv6 = 1;
11149         }
11150       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11151         {
11152           is_tunnel = 1;
11153           is_tunnel_ipv6 = 1;
11154         }
11155       else
11156         if (unformat
11157             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11158         {
11159           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11160               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11161             {
11162               clib_warning ("unsupported crypto-alg: '%U'",
11163                             format_ipsec_crypto_alg, crypto_alg);
11164               return -99;
11165             }
11166         }
11167       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11168         ;
11169       else
11170         if (unformat
11171             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11172         {
11173           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11174               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11175             {
11176               clib_warning ("unsupported integ-alg: '%U'",
11177                             format_ipsec_integ_alg, integ_alg);
11178               return -99;
11179             }
11180         }
11181       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11182         ;
11183       else
11184         {
11185           clib_warning ("parse error '%U'", format_unformat_error, i);
11186           return -99;
11187         }
11188
11189     }
11190
11191   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11192
11193   mp->sad_id = ntohl (sad_id);
11194   mp->is_add = is_add;
11195   mp->protocol = protocol;
11196   mp->spi = ntohl (spi);
11197   mp->is_tunnel = is_tunnel;
11198   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11199   mp->crypto_algorithm = crypto_alg;
11200   mp->integrity_algorithm = integ_alg;
11201   mp->crypto_key_length = vec_len (ck);
11202   mp->integrity_key_length = vec_len (ik);
11203
11204   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11205     mp->crypto_key_length = sizeof (mp->crypto_key);
11206
11207   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11208     mp->integrity_key_length = sizeof (mp->integrity_key);
11209
11210   if (ck)
11211     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11212   if (ik)
11213     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11214
11215   if (is_tunnel)
11216     {
11217       if (is_tunnel_ipv6)
11218         {
11219           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11220                        sizeof (ip6_address_t));
11221           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11222                        sizeof (ip6_address_t));
11223         }
11224       else
11225         {
11226           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11227                        sizeof (ip4_address_t));
11228           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11229                        sizeof (ip4_address_t));
11230         }
11231     }
11232
11233   S;
11234   W;
11235   /* NOTREACHED */
11236   return 0;
11237 #else
11238   clib_warning ("unsupported (no dpdk)");
11239   return -99;
11240 #endif
11241 }
11242
11243 static int
11244 api_ipsec_sa_set_key (vat_main_t * vam)
11245 {
11246 #if DPDK > 0
11247   unformat_input_t *i = vam->input;
11248   vl_api_ipsec_sa_set_key_t *mp;
11249   f64 timeout;
11250   u32 sa_id;
11251   u8 *ck = 0, *ik = 0;
11252
11253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11254     {
11255       if (unformat (i, "sa_id %d", &sa_id))
11256         ;
11257       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11258         ;
11259       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11260         ;
11261       else
11262         {
11263           clib_warning ("parse error '%U'", format_unformat_error, i);
11264           return -99;
11265         }
11266     }
11267
11268   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11269
11270   mp->sa_id = ntohl (sa_id);
11271   mp->crypto_key_length = vec_len (ck);
11272   mp->integrity_key_length = vec_len (ik);
11273
11274   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11275     mp->crypto_key_length = sizeof (mp->crypto_key);
11276
11277   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11278     mp->integrity_key_length = sizeof (mp->integrity_key);
11279
11280   if (ck)
11281     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11282   if (ik)
11283     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11284
11285   S;
11286   W;
11287   /* NOTREACHED */
11288   return 0;
11289 #else
11290   clib_warning ("unsupported (no dpdk)");
11291   return -99;
11292 #endif
11293 }
11294
11295 static int
11296 api_ikev2_profile_add_del (vat_main_t * vam)
11297 {
11298 #if DPDK > 0
11299   unformat_input_t *i = vam->input;
11300   vl_api_ikev2_profile_add_del_t *mp;
11301   f64 timeout;
11302   u8 is_add = 1;
11303   u8 *name = 0;
11304
11305   const char *valid_chars = "a-zA-Z0-9_";
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "del"))
11310         is_add = 0;
11311       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11312         vec_add1 (name, 0);
11313       else
11314         {
11315           errmsg ("parse error '%U'", format_unformat_error, i);
11316           return -99;
11317         }
11318     }
11319
11320   if (!vec_len (name))
11321     {
11322       errmsg ("profile name must be specified");
11323       return -99;
11324     }
11325
11326   if (vec_len (name) > 64)
11327     {
11328       errmsg ("profile name too long");
11329       return -99;
11330     }
11331
11332   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11333
11334   clib_memcpy (mp->name, name, vec_len (name));
11335   mp->is_add = is_add;
11336   vec_free (name);
11337
11338   S;
11339   W;
11340   /* NOTREACHED */
11341   return 0;
11342 #else
11343   clib_warning ("unsupported (no dpdk)");
11344   return -99;
11345 #endif
11346 }
11347
11348 static int
11349 api_ikev2_profile_set_auth (vat_main_t * vam)
11350 {
11351 #if DPDK > 0
11352   unformat_input_t *i = vam->input;
11353   vl_api_ikev2_profile_set_auth_t *mp;
11354   f64 timeout;
11355   u8 *name = 0;
11356   u8 *data = 0;
11357   u32 auth_method = 0;
11358   u8 is_hex = 0;
11359
11360   const char *valid_chars = "a-zA-Z0-9_";
11361
11362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11363     {
11364       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11365         vec_add1 (name, 0);
11366       else if (unformat (i, "auth_method %U",
11367                          unformat_ikev2_auth_method, &auth_method))
11368         ;
11369       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11370         is_hex = 1;
11371       else if (unformat (i, "auth_data %v", &data))
11372         ;
11373       else
11374         {
11375           errmsg ("parse error '%U'", format_unformat_error, i);
11376           return -99;
11377         }
11378     }
11379
11380   if (!vec_len (name))
11381     {
11382       errmsg ("profile name must be specified");
11383       return -99;
11384     }
11385
11386   if (vec_len (name) > 64)
11387     {
11388       errmsg ("profile name too long");
11389       return -99;
11390     }
11391
11392   if (!vec_len (data))
11393     {
11394       errmsg ("auth_data must be specified");
11395       return -99;
11396     }
11397
11398   if (!auth_method)
11399     {
11400       errmsg ("auth_method must be specified");
11401       return -99;
11402     }
11403
11404   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11405
11406   mp->is_hex = is_hex;
11407   mp->auth_method = (u8) auth_method;
11408   mp->data_len = vec_len (data);
11409   clib_memcpy (mp->name, name, vec_len (name));
11410   clib_memcpy (mp->data, data, vec_len (data));
11411   vec_free (name);
11412   vec_free (data);
11413
11414   S;
11415   W;
11416   /* NOTREACHED */
11417   return 0;
11418 #else
11419   clib_warning ("unsupported (no dpdk)");
11420   return -99;
11421 #endif
11422 }
11423
11424 static int
11425 api_ikev2_profile_set_id (vat_main_t * vam)
11426 {
11427 #if DPDK > 0
11428   unformat_input_t *i = vam->input;
11429   vl_api_ikev2_profile_set_id_t *mp;
11430   f64 timeout;
11431   u8 *name = 0;
11432   u8 *data = 0;
11433   u8 is_local = 0;
11434   u32 id_type = 0;
11435   ip4_address_t ip4;
11436
11437   const char *valid_chars = "a-zA-Z0-9_";
11438
11439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11440     {
11441       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11442         vec_add1 (name, 0);
11443       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11444         ;
11445       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11446         {
11447           data = vec_new (u8, 4);
11448           clib_memcpy (data, ip4.as_u8, 4);
11449         }
11450       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11451         ;
11452       else if (unformat (i, "id_data %v", &data))
11453         ;
11454       else if (unformat (i, "local"))
11455         is_local = 1;
11456       else if (unformat (i, "remote"))
11457         is_local = 0;
11458       else
11459         {
11460           errmsg ("parse error '%U'", format_unformat_error, i);
11461           return -99;
11462         }
11463     }
11464
11465   if (!vec_len (name))
11466     {
11467       errmsg ("profile name must be specified");
11468       return -99;
11469     }
11470
11471   if (vec_len (name) > 64)
11472     {
11473       errmsg ("profile name too long");
11474       return -99;
11475     }
11476
11477   if (!vec_len (data))
11478     {
11479       errmsg ("id_data must be specified");
11480       return -99;
11481     }
11482
11483   if (!id_type)
11484     {
11485       errmsg ("id_type must be specified");
11486       return -99;
11487     }
11488
11489   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11490
11491   mp->is_local = is_local;
11492   mp->id_type = (u8) id_type;
11493   mp->data_len = vec_len (data);
11494   clib_memcpy (mp->name, name, vec_len (name));
11495   clib_memcpy (mp->data, data, vec_len (data));
11496   vec_free (name);
11497   vec_free (data);
11498
11499   S;
11500   W;
11501   /* NOTREACHED */
11502   return 0;
11503 #else
11504   clib_warning ("unsupported (no dpdk)");
11505   return -99;
11506 #endif
11507 }
11508
11509 static int
11510 api_ikev2_profile_set_ts (vat_main_t * vam)
11511 {
11512 #if DPDK > 0
11513   unformat_input_t *i = vam->input;
11514   vl_api_ikev2_profile_set_ts_t *mp;
11515   f64 timeout;
11516   u8 *name = 0;
11517   u8 is_local = 0;
11518   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11519   ip4_address_t start_addr, end_addr;
11520
11521   const char *valid_chars = "a-zA-Z0-9_";
11522
11523   start_addr.as_u32 = 0;
11524   end_addr.as_u32 = (u32) ~ 0;
11525
11526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11527     {
11528       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11529         vec_add1 (name, 0);
11530       else if (unformat (i, "protocol %d", &proto))
11531         ;
11532       else if (unformat (i, "start_port %d", &start_port))
11533         ;
11534       else if (unformat (i, "end_port %d", &end_port))
11535         ;
11536       else
11537         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11538         ;
11539       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11540         ;
11541       else if (unformat (i, "local"))
11542         is_local = 1;
11543       else if (unformat (i, "remote"))
11544         is_local = 0;
11545       else
11546         {
11547           errmsg ("parse error '%U'", format_unformat_error, i);
11548           return -99;
11549         }
11550     }
11551
11552   if (!vec_len (name))
11553     {
11554       errmsg ("profile name must be specified");
11555       return -99;
11556     }
11557
11558   if (vec_len (name) > 64)
11559     {
11560       errmsg ("profile name too long");
11561       return -99;
11562     }
11563
11564   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11565
11566   mp->is_local = is_local;
11567   mp->proto = (u8) proto;
11568   mp->start_port = (u16) start_port;
11569   mp->end_port = (u16) end_port;
11570   mp->start_addr = start_addr.as_u32;
11571   mp->end_addr = end_addr.as_u32;
11572   clib_memcpy (mp->name, name, vec_len (name));
11573   vec_free (name);
11574
11575   S;
11576   W;
11577   /* NOTREACHED */
11578   return 0;
11579 #else
11580   clib_warning ("unsupported (no dpdk)");
11581   return -99;
11582 #endif
11583 }
11584
11585 static int
11586 api_ikev2_set_local_key (vat_main_t * vam)
11587 {
11588 #if DPDK > 0
11589   unformat_input_t *i = vam->input;
11590   vl_api_ikev2_set_local_key_t *mp;
11591   f64 timeout;
11592   u8 *file = 0;
11593
11594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11595     {
11596       if (unformat (i, "file %v", &file))
11597         vec_add1 (file, 0);
11598       else
11599         {
11600           errmsg ("parse error '%U'", format_unformat_error, i);
11601           return -99;
11602         }
11603     }
11604
11605   if (!vec_len (file))
11606     {
11607       errmsg ("RSA key file must be specified");
11608       return -99;
11609     }
11610
11611   if (vec_len (file) > 256)
11612     {
11613       errmsg ("file name too long");
11614       return -99;
11615     }
11616
11617   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11618
11619   clib_memcpy (mp->key_file, file, vec_len (file));
11620   vec_free (file);
11621
11622   S;
11623   W;
11624   /* NOTREACHED */
11625   return 0;
11626 #else
11627   clib_warning ("unsupported (no dpdk)");
11628   return -99;
11629 #endif
11630 }
11631
11632 /*
11633  * MAP
11634  */
11635 static int
11636 api_map_add_domain (vat_main_t * vam)
11637 {
11638   unformat_input_t *i = vam->input;
11639   vl_api_map_add_domain_t *mp;
11640   f64 timeout;
11641
11642   ip4_address_t ip4_prefix;
11643   ip6_address_t ip6_prefix;
11644   ip6_address_t ip6_src;
11645   u32 num_m_args = 0;
11646   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11647     0, psid_length = 0;
11648   u8 is_translation = 0;
11649   u32 mtu = 0;
11650   u32 ip6_src_len = 128;
11651
11652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11653     {
11654       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11655                     &ip4_prefix, &ip4_prefix_len))
11656         num_m_args++;
11657       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11658                          &ip6_prefix, &ip6_prefix_len))
11659         num_m_args++;
11660       else
11661         if (unformat
11662             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11663              &ip6_src_len))
11664         num_m_args++;
11665       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11666         num_m_args++;
11667       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11668         num_m_args++;
11669       else if (unformat (i, "psid-offset %d", &psid_offset))
11670         num_m_args++;
11671       else if (unformat (i, "psid-len %d", &psid_length))
11672         num_m_args++;
11673       else if (unformat (i, "mtu %d", &mtu))
11674         num_m_args++;
11675       else if (unformat (i, "map-t"))
11676         is_translation = 1;
11677       else
11678         {
11679           clib_warning ("parse error '%U'", format_unformat_error, i);
11680           return -99;
11681         }
11682     }
11683
11684   if (num_m_args < 3)
11685     {
11686       errmsg ("mandatory argument(s) missing\n");
11687       return -99;
11688     }
11689
11690   /* Construct the API message */
11691   M (MAP_ADD_DOMAIN, map_add_domain);
11692
11693   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11694   mp->ip4_prefix_len = ip4_prefix_len;
11695
11696   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11697   mp->ip6_prefix_len = ip6_prefix_len;
11698
11699   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11700   mp->ip6_src_prefix_len = ip6_src_len;
11701
11702   mp->ea_bits_len = ea_bits_len;
11703   mp->psid_offset = psid_offset;
11704   mp->psid_length = psid_length;
11705   mp->is_translation = is_translation;
11706   mp->mtu = htons (mtu);
11707
11708   /* send it... */
11709   S;
11710
11711   /* Wait for a reply, return good/bad news  */
11712   W;
11713 }
11714
11715 static int
11716 api_map_del_domain (vat_main_t * vam)
11717 {
11718   unformat_input_t *i = vam->input;
11719   vl_api_map_del_domain_t *mp;
11720   f64 timeout;
11721
11722   u32 num_m_args = 0;
11723   u32 index;
11724
11725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11726     {
11727       if (unformat (i, "index %d", &index))
11728         num_m_args++;
11729       else
11730         {
11731           clib_warning ("parse error '%U'", format_unformat_error, i);
11732           return -99;
11733         }
11734     }
11735
11736   if (num_m_args != 1)
11737     {
11738       errmsg ("mandatory argument(s) missing\n");
11739       return -99;
11740     }
11741
11742   /* Construct the API message */
11743   M (MAP_DEL_DOMAIN, map_del_domain);
11744
11745   mp->index = ntohl (index);
11746
11747   /* send it... */
11748   S;
11749
11750   /* Wait for a reply, return good/bad news  */
11751   W;
11752 }
11753
11754 static int
11755 api_map_add_del_rule (vat_main_t * vam)
11756 {
11757   unformat_input_t *i = vam->input;
11758   vl_api_map_add_del_rule_t *mp;
11759   f64 timeout;
11760   u8 is_add = 1;
11761   ip6_address_t ip6_dst;
11762   u32 num_m_args = 0, index, psid = 0;
11763
11764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11765     {
11766       if (unformat (i, "index %d", &index))
11767         num_m_args++;
11768       else if (unformat (i, "psid %d", &psid))
11769         num_m_args++;
11770       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11771         num_m_args++;
11772       else if (unformat (i, "del"))
11773         {
11774           is_add = 0;
11775         }
11776       else
11777         {
11778           clib_warning ("parse error '%U'", format_unformat_error, i);
11779           return -99;
11780         }
11781     }
11782
11783   /* Construct the API message */
11784   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11785
11786   mp->index = ntohl (index);
11787   mp->is_add = is_add;
11788   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11789   mp->psid = ntohs (psid);
11790
11791   /* send it... */
11792   S;
11793
11794   /* Wait for a reply, return good/bad news  */
11795   W;
11796 }
11797
11798 static int
11799 api_map_domain_dump (vat_main_t * vam)
11800 {
11801   vl_api_map_domain_dump_t *mp;
11802   f64 timeout;
11803
11804   /* Construct the API message */
11805   M (MAP_DOMAIN_DUMP, map_domain_dump);
11806
11807   /* send it... */
11808   S;
11809
11810   /* Use a control ping for synchronization */
11811   {
11812     vl_api_control_ping_t *mp;
11813     M (CONTROL_PING, control_ping);
11814     S;
11815   }
11816   W;
11817 }
11818
11819 static int
11820 api_map_rule_dump (vat_main_t * vam)
11821 {
11822   unformat_input_t *i = vam->input;
11823   vl_api_map_rule_dump_t *mp;
11824   f64 timeout;
11825   u32 domain_index = ~0;
11826
11827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11828     {
11829       if (unformat (i, "index %u", &domain_index))
11830         ;
11831       else
11832         break;
11833     }
11834
11835   if (domain_index == ~0)
11836     {
11837       clib_warning ("parse error: domain index expected");
11838       return -99;
11839     }
11840
11841   /* Construct the API message */
11842   M (MAP_RULE_DUMP, map_rule_dump);
11843
11844   mp->domain_index = htonl (domain_index);
11845
11846   /* send it... */
11847   S;
11848
11849   /* Use a control ping for synchronization */
11850   {
11851     vl_api_control_ping_t *mp;
11852     M (CONTROL_PING, control_ping);
11853     S;
11854   }
11855   W;
11856 }
11857
11858 static void vl_api_map_add_domain_reply_t_handler
11859   (vl_api_map_add_domain_reply_t * mp)
11860 {
11861   vat_main_t *vam = &vat_main;
11862   i32 retval = ntohl (mp->retval);
11863
11864   if (vam->async_mode)
11865     {
11866       vam->async_errors += (retval < 0);
11867     }
11868   else
11869     {
11870       vam->retval = retval;
11871       vam->result_ready = 1;
11872     }
11873 }
11874
11875 static void vl_api_map_add_domain_reply_t_handler_json
11876   (vl_api_map_add_domain_reply_t * mp)
11877 {
11878   vat_main_t *vam = &vat_main;
11879   vat_json_node_t node;
11880
11881   vat_json_init_object (&node);
11882   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11883   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11884
11885   vat_json_print (vam->ofp, &node);
11886   vat_json_free (&node);
11887
11888   vam->retval = ntohl (mp->retval);
11889   vam->result_ready = 1;
11890 }
11891
11892 static int
11893 api_get_first_msg_id (vat_main_t * vam)
11894 {
11895   vl_api_get_first_msg_id_t *mp;
11896   f64 timeout;
11897   unformat_input_t *i = vam->input;
11898   u8 *name;
11899   u8 name_set = 0;
11900
11901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11902     {
11903       if (unformat (i, "client %s", &name))
11904         name_set = 1;
11905       else
11906         break;
11907     }
11908
11909   if (name_set == 0)
11910     {
11911       errmsg ("missing client name\n");
11912       return -99;
11913     }
11914   vec_add1 (name, 0);
11915
11916   if (vec_len (name) > 63)
11917     {
11918       errmsg ("client name too long\n");
11919       return -99;
11920     }
11921
11922   M (GET_FIRST_MSG_ID, get_first_msg_id);
11923   clib_memcpy (mp->name, name, vec_len (name));
11924   S;
11925   W;
11926   /* NOTREACHED */
11927   return 0;
11928 }
11929
11930 static int
11931 api_cop_interface_enable_disable (vat_main_t * vam)
11932 {
11933   unformat_input_t *line_input = vam->input;
11934   vl_api_cop_interface_enable_disable_t *mp;
11935   f64 timeout;
11936   u32 sw_if_index = ~0;
11937   u8 enable_disable = 1;
11938
11939   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11940     {
11941       if (unformat (line_input, "disable"))
11942         enable_disable = 0;
11943       if (unformat (line_input, "enable"))
11944         enable_disable = 1;
11945       else if (unformat (line_input, "%U", unformat_sw_if_index,
11946                          vam, &sw_if_index))
11947         ;
11948       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11949         ;
11950       else
11951         break;
11952     }
11953
11954   if (sw_if_index == ~0)
11955     {
11956       errmsg ("missing interface name or sw_if_index\n");
11957       return -99;
11958     }
11959
11960   /* Construct the API message */
11961   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11962   mp->sw_if_index = ntohl (sw_if_index);
11963   mp->enable_disable = enable_disable;
11964
11965   /* send it... */
11966   S;
11967   /* Wait for the reply */
11968   W;
11969 }
11970
11971 static int
11972 api_cop_whitelist_enable_disable (vat_main_t * vam)
11973 {
11974   unformat_input_t *line_input = vam->input;
11975   vl_api_cop_whitelist_enable_disable_t *mp;
11976   f64 timeout;
11977   u32 sw_if_index = ~0;
11978   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11979   u32 fib_id = 0;
11980
11981   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11982     {
11983       if (unformat (line_input, "ip4"))
11984         ip4 = 1;
11985       else if (unformat (line_input, "ip6"))
11986         ip6 = 1;
11987       else if (unformat (line_input, "default"))
11988         default_cop = 1;
11989       else if (unformat (line_input, "%U", unformat_sw_if_index,
11990                          vam, &sw_if_index))
11991         ;
11992       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11993         ;
11994       else if (unformat (line_input, "fib-id %d", &fib_id))
11995         ;
11996       else
11997         break;
11998     }
11999
12000   if (sw_if_index == ~0)
12001     {
12002       errmsg ("missing interface name or sw_if_index\n");
12003       return -99;
12004     }
12005
12006   /* Construct the API message */
12007   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12008   mp->sw_if_index = ntohl (sw_if_index);
12009   mp->fib_id = ntohl (fib_id);
12010   mp->ip4 = ip4;
12011   mp->ip6 = ip6;
12012   mp->default_cop = default_cop;
12013
12014   /* send it... */
12015   S;
12016   /* Wait for the reply */
12017   W;
12018 }
12019
12020 static int
12021 api_get_node_graph (vat_main_t * vam)
12022 {
12023   vl_api_get_node_graph_t *mp;
12024   f64 timeout;
12025
12026   M (GET_NODE_GRAPH, get_node_graph);
12027
12028   /* send it... */
12029   S;
12030   /* Wait for the reply */
12031   W;
12032 }
12033
12034 /* *INDENT-OFF* */
12035 /** Used for parsing LISP eids */
12036 typedef CLIB_PACKED(struct{
12037   u8 addr[16];   /**< eid address */
12038   u32 len;       /**< prefix length if IP */
12039   u8 type;      /**< type of eid */
12040 }) lisp_eid_vat_t;
12041 /* *INDENT-ON* */
12042
12043 static uword
12044 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12045 {
12046   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12047
12048   memset (a, 0, sizeof (a[0]));
12049
12050   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12051     {
12052       a->type = 0;              /* ipv4 type */
12053     }
12054   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12055     {
12056       a->type = 1;              /* ipv6 type */
12057     }
12058   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12059     {
12060       a->type = 2;              /* mac type */
12061     }
12062   else
12063     {
12064       return 0;
12065     }
12066
12067   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12068     {
12069       return 0;
12070     }
12071
12072   return 1;
12073 }
12074
12075 static int
12076 lisp_eid_size_vat (u8 type)
12077 {
12078   switch (type)
12079     {
12080     case 0:
12081       return 4;
12082     case 1:
12083       return 16;
12084     case 2:
12085       return 6;
12086     }
12087   return 0;
12088 }
12089
12090 static void
12091 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12092 {
12093   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12094 }
12095
12096 /* *INDENT-OFF* */
12097 /** Used for transferring locators via VPP API */
12098 typedef CLIB_PACKED(struct
12099 {
12100   u32 sw_if_index; /**< locator sw_if_index */
12101   u8 priority; /**< locator priority */
12102   u8 weight;   /**< locator weight */
12103 }) ls_locator_t;
12104 /* *INDENT-ON* */
12105
12106 static int
12107 api_lisp_add_del_locator_set (vat_main_t * vam)
12108 {
12109   unformat_input_t *input = vam->input;
12110   vl_api_lisp_add_del_locator_set_t *mp;
12111   f64 timeout = ~0;
12112   u8 is_add = 1;
12113   u8 *locator_set_name = NULL;
12114   u8 locator_set_name_set = 0;
12115   ls_locator_t locator, *locators = 0;
12116   u32 sw_if_index, priority, weight;
12117   u32 data_len = 0;
12118
12119   /* Parse args required to build the message */
12120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12121     {
12122       if (unformat (input, "del"))
12123         {
12124           is_add = 0;
12125         }
12126       else if (unformat (input, "locator-set %s", &locator_set_name))
12127         {
12128           locator_set_name_set = 1;
12129         }
12130       else if (unformat (input, "sw_if_index %u p %u w %u",
12131                          &sw_if_index, &priority, &weight))
12132         {
12133           locator.sw_if_index = htonl (sw_if_index);
12134           locator.priority = priority;
12135           locator.weight = weight;
12136           vec_add1 (locators, locator);
12137         }
12138       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12139                          vam, &sw_if_index, &priority, &weight))
12140         {
12141           locator.sw_if_index = htonl (sw_if_index);
12142           locator.priority = priority;
12143           locator.weight = weight;
12144           vec_add1 (locators, locator);
12145         }
12146       else
12147         break;
12148     }
12149
12150   if (locator_set_name_set == 0)
12151     {
12152       errmsg ("missing locator-set name");
12153       vec_free (locators);
12154       return -99;
12155     }
12156
12157   if (vec_len (locator_set_name) > 64)
12158     {
12159       errmsg ("locator-set name too long\n");
12160       vec_free (locator_set_name);
12161       vec_free (locators);
12162       return -99;
12163     }
12164   vec_add1 (locator_set_name, 0);
12165
12166   data_len = sizeof (ls_locator_t) * vec_len (locators);
12167
12168   /* Construct the API message */
12169   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12170
12171   mp->is_add = is_add;
12172   clib_memcpy (mp->locator_set_name, locator_set_name,
12173                vec_len (locator_set_name));
12174   vec_free (locator_set_name);
12175
12176   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12177   if (locators)
12178     clib_memcpy (mp->locators, locators, data_len);
12179   vec_free (locators);
12180
12181   /* send it... */
12182   S;
12183
12184   /* Wait for a reply... */
12185   W;
12186
12187   /* NOTREACHED */
12188   return 0;
12189 }
12190
12191 static int
12192 api_lisp_add_del_locator (vat_main_t * vam)
12193 {
12194   unformat_input_t *input = vam->input;
12195   vl_api_lisp_add_del_locator_t *mp;
12196   f64 timeout = ~0;
12197   u32 tmp_if_index = ~0;
12198   u32 sw_if_index = ~0;
12199   u8 sw_if_index_set = 0;
12200   u8 sw_if_index_if_name_set = 0;
12201   u32 priority = ~0;
12202   u8 priority_set = 0;
12203   u32 weight = ~0;
12204   u8 weight_set = 0;
12205   u8 is_add = 1;
12206   u8 *locator_set_name = NULL;
12207   u8 locator_set_name_set = 0;
12208
12209   /* Parse args required to build the message */
12210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12211     {
12212       if (unformat (input, "del"))
12213         {
12214           is_add = 0;
12215         }
12216       else if (unformat (input, "locator-set %s", &locator_set_name))
12217         {
12218           locator_set_name_set = 1;
12219         }
12220       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12221                          &tmp_if_index))
12222         {
12223           sw_if_index_if_name_set = 1;
12224           sw_if_index = tmp_if_index;
12225         }
12226       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12227         {
12228           sw_if_index_set = 1;
12229           sw_if_index = tmp_if_index;
12230         }
12231       else if (unformat (input, "p %d", &priority))
12232         {
12233           priority_set = 1;
12234         }
12235       else if (unformat (input, "w %d", &weight))
12236         {
12237           weight_set = 1;
12238         }
12239       else
12240         break;
12241     }
12242
12243   if (locator_set_name_set == 0)
12244     {
12245       errmsg ("missing locator-set name");
12246       return -99;
12247     }
12248
12249   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12250     {
12251       errmsg ("missing sw_if_index");
12252       vec_free (locator_set_name);
12253       return -99;
12254     }
12255
12256   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12257     {
12258       errmsg ("cannot use both params interface name and sw_if_index");
12259       vec_free (locator_set_name);
12260       return -99;
12261     }
12262
12263   if (priority_set == 0)
12264     {
12265       errmsg ("missing locator-set priority\n");
12266       vec_free (locator_set_name);
12267       return -99;
12268     }
12269
12270   if (weight_set == 0)
12271     {
12272       errmsg ("missing locator-set weight\n");
12273       vec_free (locator_set_name);
12274       return -99;
12275     }
12276
12277   if (vec_len (locator_set_name) > 64)
12278     {
12279       errmsg ("locator-set name too long\n");
12280       vec_free (locator_set_name);
12281       return -99;
12282     }
12283   vec_add1 (locator_set_name, 0);
12284
12285   /* Construct the API message */
12286   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12287
12288   mp->is_add = is_add;
12289   mp->sw_if_index = ntohl (sw_if_index);
12290   mp->priority = priority;
12291   mp->weight = weight;
12292   clib_memcpy (mp->locator_set_name, locator_set_name,
12293                vec_len (locator_set_name));
12294   vec_free (locator_set_name);
12295
12296   /* send it... */
12297   S;
12298
12299   /* Wait for a reply... */
12300   W;
12301
12302   /* NOTREACHED */
12303   return 0;
12304 }
12305
12306 static int
12307 api_lisp_add_del_local_eid (vat_main_t * vam)
12308 {
12309   unformat_input_t *input = vam->input;
12310   vl_api_lisp_add_del_local_eid_t *mp;
12311   f64 timeout = ~0;
12312   u8 is_add = 1;
12313   u8 eid_set = 0;
12314   lisp_eid_vat_t _eid, *eid = &_eid;
12315   u8 *locator_set_name = 0;
12316   u8 locator_set_name_set = 0;
12317   u32 vni = 0;
12318
12319   /* Parse args required to build the message */
12320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12321     {
12322       if (unformat (input, "del"))
12323         {
12324           is_add = 0;
12325         }
12326       else if (unformat (input, "vni %d", &vni))
12327         {
12328           ;
12329         }
12330       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12331         {
12332           eid_set = 1;
12333         }
12334       else if (unformat (input, "locator-set %s", &locator_set_name))
12335         {
12336           locator_set_name_set = 1;
12337         }
12338       else
12339         break;
12340     }
12341
12342   if (locator_set_name_set == 0)
12343     {
12344       errmsg ("missing locator-set name\n");
12345       return -99;
12346     }
12347
12348   if (0 == eid_set)
12349     {
12350       errmsg ("EID address not set!");
12351       vec_free (locator_set_name);
12352       return -99;
12353     }
12354
12355   if (vec_len (locator_set_name) > 64)
12356     {
12357       errmsg ("locator-set name too long\n");
12358       vec_free (locator_set_name);
12359       return -99;
12360     }
12361   vec_add1 (locator_set_name, 0);
12362
12363   /* Construct the API message */
12364   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12365
12366   mp->is_add = is_add;
12367   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12368   mp->eid_type = eid->type;
12369   mp->prefix_len = eid->len;
12370   mp->vni = clib_host_to_net_u32 (vni);
12371   clib_memcpy (mp->locator_set_name, locator_set_name,
12372                vec_len (locator_set_name));
12373
12374   vec_free (locator_set_name);
12375
12376   /* send it... */
12377   S;
12378
12379   /* Wait for a reply... */
12380   W;
12381
12382   /* NOTREACHED */
12383   return 0;
12384 }
12385
12386 /* *INDENT-OFF* */
12387 /** Used for transferring locators via VPP API */
12388 typedef CLIB_PACKED(struct
12389 {
12390   u8 is_ip4; /**< is locator an IPv4 address? */
12391   u8 priority; /**< locator priority */
12392   u8 weight;   /**< locator weight */
12393   u8 addr[16]; /**< IPv4/IPv6 address */
12394 }) rloc_t;
12395 /* *INDENT-ON* */
12396
12397 static int
12398 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12399 {
12400   unformat_input_t *input = vam->input;
12401   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12402   f64 timeout = ~0;
12403   u8 is_add = 1;
12404   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12405   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12406   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12407   u32 action = ~0, p, w;
12408   ip4_address_t rmt_rloc4, lcl_rloc4;
12409   ip6_address_t rmt_rloc6, lcl_rloc6;
12410   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12411
12412   memset (&rloc, 0, sizeof (rloc));
12413
12414   /* Parse args required to build the message */
12415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12416     {
12417       if (unformat (input, "del"))
12418         {
12419           is_add = 0;
12420         }
12421       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12422         {
12423           rmt_eid_set = 1;
12424         }
12425       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12426         {
12427           lcl_eid_set = 1;
12428         }
12429       else if (unformat (input, "p %d w %d", &p, &w))
12430         {
12431           if (!curr_rloc)
12432             {
12433               errmsg ("No RLOC configured for setting priority/weight!");
12434               return -99;
12435             }
12436           curr_rloc->priority = p;
12437           curr_rloc->weight = w;
12438         }
12439       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12440                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12441         {
12442           rloc.is_ip4 = 1;
12443
12444           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12445           rloc.priority = rloc.weight = 0;
12446           vec_add1 (lcl_locs, rloc);
12447
12448           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12449           vec_add1 (rmt_locs, rloc);
12450           /* priority and weight saved in rmt loc */
12451           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12452         }
12453       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12454                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12455         {
12456           rloc.is_ip4 = 0;
12457           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12458           rloc.priority = rloc.weight = 0;
12459           vec_add1 (lcl_locs, rloc);
12460
12461           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12462           vec_add1 (rmt_locs, rloc);
12463           /* priority and weight saved in rmt loc */
12464           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12465         }
12466       else if (unformat (input, "action %d", &action))
12467         {
12468           ;
12469         }
12470       else
12471         {
12472           clib_warning ("parse error '%U'", format_unformat_error, input);
12473           return -99;
12474         }
12475     }
12476
12477   if (!rmt_eid_set)
12478     {
12479       errmsg ("remote eid addresses not set\n");
12480       return -99;
12481     }
12482
12483   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12484     {
12485       errmsg ("eid types don't match\n");
12486       return -99;
12487     }
12488
12489   if (0 == rmt_locs && (u32) ~ 0 == action)
12490     {
12491       errmsg ("action not set for negative mapping\n");
12492       return -99;
12493     }
12494
12495   /* Construct the API message */
12496   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12497
12498   mp->is_add = is_add;
12499   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12500   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12501   mp->eid_type = rmt_eid->type;
12502   mp->rmt_len = rmt_eid->len;
12503   mp->lcl_len = lcl_eid->len;
12504   mp->action = action;
12505
12506   if (0 != rmt_locs && 0 != lcl_locs)
12507     {
12508       mp->loc_num = vec_len (rmt_locs);
12509       clib_memcpy (mp->lcl_locs, lcl_locs,
12510                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12511       clib_memcpy (mp->rmt_locs, rmt_locs,
12512                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12513     }
12514   vec_free (lcl_locs);
12515   vec_free (rmt_locs);
12516
12517   /* send it... */
12518   S;
12519
12520   /* Wait for a reply... */
12521   W;
12522
12523   /* NOTREACHED */
12524   return 0;
12525 }
12526
12527 static int
12528 api_lisp_add_del_map_resolver (vat_main_t * vam)
12529 {
12530   unformat_input_t *input = vam->input;
12531   vl_api_lisp_add_del_map_resolver_t *mp;
12532   f64 timeout = ~0;
12533   u8 is_add = 1;
12534   u8 ipv4_set = 0;
12535   u8 ipv6_set = 0;
12536   ip4_address_t ipv4;
12537   ip6_address_t ipv6;
12538
12539   /* Parse args required to build the message */
12540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12541     {
12542       if (unformat (input, "del"))
12543         {
12544           is_add = 0;
12545         }
12546       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12547         {
12548           ipv4_set = 1;
12549         }
12550       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12551         {
12552           ipv6_set = 1;
12553         }
12554       else
12555         break;
12556     }
12557
12558   if (ipv4_set && ipv6_set)
12559     {
12560       errmsg ("both eid v4 and v6 addresses set\n");
12561       return -99;
12562     }
12563
12564   if (!ipv4_set && !ipv6_set)
12565     {
12566       errmsg ("eid addresses not set\n");
12567       return -99;
12568     }
12569
12570   /* Construct the API message */
12571   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12572
12573   mp->is_add = is_add;
12574   if (ipv6_set)
12575     {
12576       mp->is_ipv6 = 1;
12577       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12578     }
12579   else
12580     {
12581       mp->is_ipv6 = 0;
12582       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12583     }
12584
12585   /* send it... */
12586   S;
12587
12588   /* Wait for a reply... */
12589   W;
12590
12591   /* NOTREACHED */
12592   return 0;
12593 }
12594
12595 static int
12596 api_lisp_gpe_enable_disable (vat_main_t * vam)
12597 {
12598   unformat_input_t *input = vam->input;
12599   vl_api_lisp_gpe_enable_disable_t *mp;
12600   f64 timeout = ~0;
12601   u8 is_set = 0;
12602   u8 is_en = 1;
12603
12604   /* Parse args required to build the message */
12605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12606     {
12607       if (unformat (input, "enable"))
12608         {
12609           is_set = 1;
12610           is_en = 1;
12611         }
12612       else if (unformat (input, "disable"))
12613         {
12614           is_set = 1;
12615           is_en = 0;
12616         }
12617       else
12618         break;
12619     }
12620
12621   if (is_set == 0)
12622     {
12623       errmsg ("Value not set\n");
12624       return -99;
12625     }
12626
12627   /* Construct the API message */
12628   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12629
12630   mp->is_en = is_en;
12631
12632   /* send it... */
12633   S;
12634
12635   /* Wait for a reply... */
12636   W;
12637
12638   /* NOTREACHED */
12639   return 0;
12640 }
12641
12642 static int
12643 api_lisp_enable_disable (vat_main_t * vam)
12644 {
12645   unformat_input_t *input = vam->input;
12646   vl_api_lisp_enable_disable_t *mp;
12647   f64 timeout = ~0;
12648   u8 is_set = 0;
12649   u8 is_en = 0;
12650
12651   /* Parse args required to build the message */
12652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12653     {
12654       if (unformat (input, "enable"))
12655         {
12656           is_set = 1;
12657           is_en = 1;
12658         }
12659       else if (unformat (input, "disable"))
12660         {
12661           is_set = 1;
12662         }
12663       else
12664         break;
12665     }
12666
12667   if (!is_set)
12668     {
12669       errmsg ("Value not set\n");
12670       return -99;
12671     }
12672
12673   /* Construct the API message */
12674   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12675
12676   mp->is_en = is_en;
12677
12678   /* send it... */
12679   S;
12680
12681   /* Wait for a reply... */
12682   W;
12683
12684   /* NOTREACHED */
12685   return 0;
12686 }
12687
12688 static int
12689 api_show_lisp_map_request_mode (vat_main_t * vam)
12690 {
12691   f64 timeout = ~0;
12692   vl_api_show_lisp_map_request_mode_t *mp;
12693
12694   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12695
12696   /* send */
12697   S;
12698
12699   /* wait for reply */
12700   W;
12701
12702   return 0;
12703 }
12704
12705 static int
12706 api_lisp_map_request_mode (vat_main_t * vam)
12707 {
12708   f64 timeout = ~0;
12709   unformat_input_t *input = vam->input;
12710   vl_api_lisp_map_request_mode_t *mp;
12711   u8 mode = 0;
12712
12713   /* Parse args required to build the message */
12714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12715     {
12716       if (unformat (input, "dst-only"))
12717         mode = 0;
12718       else if (unformat (input, "src-dst"))
12719         mode = 1;
12720       else
12721         {
12722           errmsg ("parse error '%U'", format_unformat_error, input);
12723           return -99;
12724         }
12725     }
12726
12727   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12728
12729   mp->mode = mode;
12730
12731   /* send */
12732   S;
12733
12734   /* wait for reply */
12735   W;
12736
12737   /* notreached */
12738   return 0;
12739 }
12740
12741 /**
12742  * Enable/disable LISP proxy ITR.
12743  *
12744  * @param vam vpp API test context
12745  * @return return code
12746  */
12747 static int
12748 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12749 {
12750   f64 timeout = ~0;
12751   u8 ls_name_set = 0;
12752   unformat_input_t *input = vam->input;
12753   vl_api_lisp_pitr_set_locator_set_t *mp;
12754   u8 is_add = 1;
12755   u8 *ls_name = 0;
12756
12757   /* Parse args required to build the message */
12758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12759     {
12760       if (unformat (input, "del"))
12761         is_add = 0;
12762       else if (unformat (input, "locator-set %s", &ls_name))
12763         ls_name_set = 1;
12764       else
12765         {
12766           errmsg ("parse error '%U'", format_unformat_error, input);
12767           return -99;
12768         }
12769     }
12770
12771   if (!ls_name_set)
12772     {
12773       errmsg ("locator-set name not set!");
12774       return -99;
12775     }
12776
12777   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12778
12779   mp->is_add = is_add;
12780   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12781   vec_free (ls_name);
12782
12783   /* send */
12784   S;
12785
12786   /* wait for reply */
12787   W;
12788
12789   /* notreached */
12790   return 0;
12791 }
12792
12793 static int
12794 api_show_lisp_pitr (vat_main_t * vam)
12795 {
12796   vl_api_show_lisp_pitr_t *mp;
12797   f64 timeout = ~0;
12798
12799   if (!vam->json_output)
12800     {
12801       fformat (vam->ofp, "%=20s\n", "lisp status:");
12802     }
12803
12804   M (SHOW_LISP_PITR, show_lisp_pitr);
12805   /* send it... */
12806   S;
12807
12808   /* Wait for a reply... */
12809   W;
12810
12811   /* NOTREACHED */
12812   return 0;
12813 }
12814
12815 /**
12816  * Add/delete mapping between vni and vrf
12817  */
12818 static int
12819 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12820 {
12821   f64 timeout = ~0;
12822   unformat_input_t *input = vam->input;
12823   vl_api_lisp_eid_table_add_del_map_t *mp;
12824   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12825   u32 vni, vrf, bd_index;
12826
12827   /* Parse args required to build the message */
12828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12829     {
12830       if (unformat (input, "del"))
12831         is_add = 0;
12832       else if (unformat (input, "vrf %d", &vrf))
12833         vrf_set = 1;
12834       else if (unformat (input, "bd_index %d", &bd_index))
12835         bd_index_set = 1;
12836       else if (unformat (input, "vni %d", &vni))
12837         vni_set = 1;
12838       else
12839         break;
12840     }
12841
12842   if (!vni_set || (!vrf_set && !bd_index_set))
12843     {
12844       errmsg ("missing arguments!");
12845       return -99;
12846     }
12847
12848   if (vrf_set && bd_index_set)
12849     {
12850       errmsg ("error: both vrf and bd entered!");
12851       return -99;
12852     }
12853
12854   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12855
12856   mp->is_add = is_add;
12857   mp->vni = htonl (vni);
12858   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12859   mp->is_l2 = bd_index_set;
12860
12861   /* send */
12862   S;
12863
12864   /* wait for reply */
12865   W;
12866
12867   /* notreached */
12868   return 0;
12869 }
12870
12871 uword
12872 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12873 {
12874   u32 *action = va_arg (*args, u32 *);
12875   u8 *s = 0;
12876
12877   if (unformat (input, "%s", &s))
12878     {
12879       if (!strcmp ((char *) s, "no-action"))
12880         action[0] = 0;
12881       else if (!strcmp ((char *) s, "natively-forward"))
12882         action[0] = 1;
12883       else if (!strcmp ((char *) s, "send-map-request"))
12884         action[0] = 2;
12885       else if (!strcmp ((char *) s, "drop"))
12886         action[0] = 3;
12887       else
12888         {
12889           clib_warning ("invalid action: '%s'", s);
12890           action[0] = 3;
12891         }
12892     }
12893   else
12894     return 0;
12895
12896   vec_free (s);
12897   return 1;
12898 }
12899
12900 /**
12901  * Add/del remote mapping to/from LISP control plane
12902  *
12903  * @param vam vpp API test context
12904  * @return return code
12905  */
12906 static int
12907 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12908 {
12909   unformat_input_t *input = vam->input;
12910   vl_api_lisp_add_del_remote_mapping_t *mp;
12911   f64 timeout = ~0;
12912   u32 vni = 0;
12913   lisp_eid_vat_t _eid, *eid = &_eid;
12914   lisp_eid_vat_t _seid, *seid = &_seid;
12915   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12916   u32 action = ~0, p, w, data_len;
12917   ip4_address_t rloc4;
12918   ip6_address_t rloc6;
12919   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12920
12921   memset (&rloc, 0, sizeof (rloc));
12922
12923   /* Parse args required to build the message */
12924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12925     {
12926       if (unformat (input, "del-all"))
12927         {
12928           del_all = 1;
12929         }
12930       else if (unformat (input, "del"))
12931         {
12932           is_add = 0;
12933         }
12934       else if (unformat (input, "add"))
12935         {
12936           is_add = 1;
12937         }
12938       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12939         {
12940           eid_set = 1;
12941         }
12942       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12943         {
12944           seid_set = 1;
12945         }
12946       else if (unformat (input, "vni %d", &vni))
12947         {
12948           ;
12949         }
12950       else if (unformat (input, "p %d w %d", &p, &w))
12951         {
12952           if (!curr_rloc)
12953             {
12954               errmsg ("No RLOC configured for setting priority/weight!");
12955               return -99;
12956             }
12957           curr_rloc->priority = p;
12958           curr_rloc->weight = w;
12959         }
12960       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12961         {
12962           rloc.is_ip4 = 1;
12963           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12964           vec_add1 (rlocs, rloc);
12965           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12966         }
12967       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12968         {
12969           rloc.is_ip4 = 0;
12970           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12971           vec_add1 (rlocs, rloc);
12972           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12973         }
12974       else if (unformat (input, "action %U",
12975                          unformat_negative_mapping_action, &action))
12976         {
12977           ;
12978         }
12979       else
12980         {
12981           clib_warning ("parse error '%U'", format_unformat_error, input);
12982           return -99;
12983         }
12984     }
12985
12986   if (0 == eid_set)
12987     {
12988       errmsg ("missing params!");
12989       return -99;
12990     }
12991
12992   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12993     {
12994       errmsg ("no action set for negative map-reply!");
12995       return -99;
12996     }
12997
12998   data_len = vec_len (rlocs) * sizeof (rloc_t);
12999
13000   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13001   mp->is_add = is_add;
13002   mp->vni = htonl (vni);
13003   mp->action = (u8) action;
13004   mp->is_src_dst = seid_set;
13005   mp->eid_len = eid->len;
13006   mp->seid_len = seid->len;
13007   mp->del_all = del_all;
13008   mp->eid_type = eid->type;
13009   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13010   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13011
13012   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13013   clib_memcpy (mp->rlocs, rlocs, data_len);
13014   vec_free (rlocs);
13015
13016   /* send it... */
13017   S;
13018
13019   /* Wait for a reply... */
13020   W;
13021
13022   /* NOTREACHED */
13023   return 0;
13024 }
13025
13026 /**
13027  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13028  * forwarding entries in data-plane accordingly.
13029  *
13030  * @param vam vpp API test context
13031  * @return return code
13032  */
13033 static int
13034 api_lisp_add_del_adjacency (vat_main_t * vam)
13035 {
13036   unformat_input_t *input = vam->input;
13037   vl_api_lisp_add_del_adjacency_t *mp;
13038   f64 timeout = ~0;
13039   u32 vni = 0;
13040   ip4_address_t leid4, reid4;
13041   ip6_address_t leid6, reid6;
13042   u8 reid_mac[6] = { 0 };
13043   u8 leid_mac[6] = { 0 };
13044   u8 reid_type, leid_type;
13045   u32 leid_len = 0, reid_len = 0, len;
13046   u8 is_add = 1;
13047
13048   leid_type = reid_type = (u8) ~ 0;
13049
13050   /* Parse args required to build the message */
13051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13052     {
13053       if (unformat (input, "del"))
13054         {
13055           is_add = 0;
13056         }
13057       else if (unformat (input, "add"))
13058         {
13059           is_add = 1;
13060         }
13061       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13062                          &reid4, &len))
13063         {
13064           reid_type = 0;        /* ipv4 */
13065           reid_len = len;
13066         }
13067       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13068                          &reid6, &len))
13069         {
13070           reid_type = 1;        /* ipv6 */
13071           reid_len = len;
13072         }
13073       else if (unformat (input, "reid %U", unformat_ethernet_address,
13074                          reid_mac))
13075         {
13076           reid_type = 2;        /* mac */
13077         }
13078       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13079                          &leid4, &len))
13080         {
13081           leid_type = 0;        /* ipv4 */
13082           leid_len = len;
13083         }
13084       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13085                          &leid6, &len))
13086         {
13087           leid_type = 1;        /* ipv6 */
13088           leid_len = len;
13089         }
13090       else if (unformat (input, "leid %U", unformat_ethernet_address,
13091                          leid_mac))
13092         {
13093           leid_type = 2;        /* mac */
13094         }
13095       else if (unformat (input, "vni %d", &vni))
13096         {
13097           ;
13098         }
13099       else
13100         {
13101           errmsg ("parse error '%U'", format_unformat_error, input);
13102           return -99;
13103         }
13104     }
13105
13106   if ((u8) ~ 0 == reid_type)
13107     {
13108       errmsg ("missing params!");
13109       return -99;
13110     }
13111
13112   if (leid_type != reid_type)
13113     {
13114       errmsg ("remote and local EIDs are of different types!");
13115       return -99;
13116     }
13117
13118   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13119   mp->is_add = is_add;
13120   mp->vni = htonl (vni);
13121   mp->leid_len = leid_len;
13122   mp->reid_len = reid_len;
13123   mp->eid_type = reid_type;
13124
13125   switch (mp->eid_type)
13126     {
13127     case 0:
13128       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13129       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13130       break;
13131     case 1:
13132       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13133       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13134       break;
13135     case 2:
13136       clib_memcpy (mp->leid, leid_mac, 6);
13137       clib_memcpy (mp->reid, reid_mac, 6);
13138       break;
13139     default:
13140       errmsg ("unknown EID type %d!", mp->eid_type);
13141       return 0;
13142     }
13143
13144   /* send it... */
13145   S;
13146
13147   /* Wait for a reply... */
13148   W;
13149
13150   /* NOTREACHED */
13151   return 0;
13152 }
13153
13154 static int
13155 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13156 {
13157   unformat_input_t *input = vam->input;
13158   vl_api_lisp_gpe_add_del_iface_t *mp;
13159   f64 timeout = ~0;
13160   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13161   u32 dp_table = 0, vni = 0;
13162
13163   /* Parse args required to build the message */
13164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13165     {
13166       if (unformat (input, "up"))
13167         {
13168           action_set = 1;
13169           is_add = 1;
13170         }
13171       else if (unformat (input, "down"))
13172         {
13173           action_set = 1;
13174           is_add = 0;
13175         }
13176       else if (unformat (input, "table_id %d", &dp_table))
13177         {
13178           dp_table_set = 1;
13179         }
13180       else if (unformat (input, "bd_id %d", &dp_table))
13181         {
13182           dp_table_set = 1;
13183           is_l2 = 1;
13184         }
13185       else if (unformat (input, "vni %d", &vni))
13186         {
13187           vni_set = 1;
13188         }
13189       else
13190         break;
13191     }
13192
13193   if (action_set == 0)
13194     {
13195       errmsg ("Action not set\n");
13196       return -99;
13197     }
13198   if (dp_table_set == 0 || vni_set == 0)
13199     {
13200       errmsg ("vni and dp_table must be set\n");
13201       return -99;
13202     }
13203
13204   /* Construct the API message */
13205   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13206
13207   mp->is_add = is_add;
13208   mp->dp_table = dp_table;
13209   mp->is_l2 = is_l2;
13210   mp->vni = vni;
13211
13212   /* send it... */
13213   S;
13214
13215   /* Wait for a reply... */
13216   W;
13217
13218   /* NOTREACHED */
13219   return 0;
13220 }
13221
13222 /**
13223  * Add/del map request itr rlocs from LISP control plane and updates
13224  *
13225  * @param vam vpp API test context
13226  * @return return code
13227  */
13228 static int
13229 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13230 {
13231   unformat_input_t *input = vam->input;
13232   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13233   f64 timeout = ~0;
13234   u8 *locator_set_name = 0;
13235   u8 locator_set_name_set = 0;
13236   u8 is_add = 1;
13237
13238   /* Parse args required to build the message */
13239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13240     {
13241       if (unformat (input, "del"))
13242         {
13243           is_add = 0;
13244         }
13245       else if (unformat (input, "%_%v%_", &locator_set_name))
13246         {
13247           locator_set_name_set = 1;
13248         }
13249       else
13250         {
13251           clib_warning ("parse error '%U'", format_unformat_error, input);
13252           return -99;
13253         }
13254     }
13255
13256   if (is_add && !locator_set_name_set)
13257     {
13258       errmsg ("itr-rloc is not set!");
13259       return -99;
13260     }
13261
13262   if (is_add && vec_len (locator_set_name) > 64)
13263     {
13264       errmsg ("itr-rloc locator-set name too long\n");
13265       vec_free (locator_set_name);
13266       return -99;
13267     }
13268
13269   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13270   mp->is_add = is_add;
13271   if (is_add)
13272     {
13273       clib_memcpy (mp->locator_set_name, locator_set_name,
13274                    vec_len (locator_set_name));
13275     }
13276   else
13277     {
13278       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13279     }
13280   vec_free (locator_set_name);
13281
13282   /* send it... */
13283   S;
13284
13285   /* Wait for a reply... */
13286   W;
13287
13288   /* NOTREACHED */
13289   return 0;
13290 }
13291
13292 static int
13293 api_lisp_locator_dump (vat_main_t * vam)
13294 {
13295   unformat_input_t *input = vam->input;
13296   vl_api_lisp_locator_dump_t *mp;
13297   f64 timeout = ~0;
13298   u8 is_index_set = 0, is_name_set = 0;
13299   u8 *ls_name = 0;
13300   u32 ls_index = ~0;
13301
13302   /* Parse args required to build the message */
13303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13304     {
13305       if (unformat (input, "ls_name %_%v%_", &ls_name))
13306         {
13307           is_name_set = 1;
13308         }
13309       else if (unformat (input, "ls_index %d", &ls_index))
13310         {
13311           is_index_set = 1;
13312         }
13313       else
13314         {
13315           errmsg ("parse error '%U'", format_unformat_error, input);
13316           return -99;
13317         }
13318     }
13319
13320   if (!is_index_set && !is_name_set)
13321     {
13322       errmsg ("error: expected one of index or name!\n");
13323       return -99;
13324     }
13325
13326   if (is_index_set && is_name_set)
13327     {
13328       errmsg ("error: only one param expected!\n");
13329       return -99;
13330     }
13331
13332   if (vec_len (ls_name) > 62)
13333     {
13334       errmsg ("error: locator set name too long!");
13335       return -99;
13336     }
13337
13338   if (!vam->json_output)
13339     {
13340       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13341                "weight");
13342     }
13343
13344   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13345   mp->is_index_set = is_index_set;
13346
13347   if (is_index_set)
13348     mp->ls_index = clib_host_to_net_u32 (ls_index);
13349   else
13350     {
13351       vec_add1 (ls_name, 0);
13352       strncpy ((char *) mp->ls_name, (char *) ls_name,
13353                sizeof (mp->ls_name) - 1);
13354     }
13355
13356   /* send it... */
13357   S;
13358
13359   /* Use a control ping for synchronization */
13360   {
13361     vl_api_control_ping_t *mp;
13362     M (CONTROL_PING, control_ping);
13363     S;
13364   }
13365   /* Wait for a reply... */
13366   W;
13367
13368   /* NOTREACHED */
13369   return 0;
13370 }
13371
13372 static int
13373 api_lisp_locator_set_dump (vat_main_t * vam)
13374 {
13375   vl_api_lisp_locator_set_dump_t *mp;
13376   unformat_input_t *input = vam->input;
13377   f64 timeout = ~0;
13378   u8 filter = 0;
13379
13380   /* Parse args required to build the message */
13381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13382     {
13383       if (unformat (input, "local"))
13384         {
13385           filter = 1;
13386         }
13387       else if (unformat (input, "remote"))
13388         {
13389           filter = 2;
13390         }
13391       else
13392         {
13393           errmsg ("parse error '%U'", format_unformat_error, input);
13394           return -99;
13395         }
13396     }
13397
13398   if (!vam->json_output)
13399     {
13400       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13401     }
13402
13403   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13404
13405   mp->filter = filter;
13406
13407   /* send it... */
13408   S;
13409
13410   /* Use a control ping for synchronization */
13411   {
13412     vl_api_control_ping_t *mp;
13413     M (CONTROL_PING, control_ping);
13414     S;
13415   }
13416   /* Wait for a reply... */
13417   W;
13418
13419   /* NOTREACHED */
13420   return 0;
13421 }
13422
13423 static int
13424 api_lisp_eid_table_map_dump (vat_main_t * vam)
13425 {
13426   u8 is_l2 = 0;
13427   u8 mode_set = 0;
13428   unformat_input_t *input = vam->input;
13429   vl_api_lisp_eid_table_map_dump_t *mp;
13430   f64 timeout = ~0;
13431
13432   /* Parse args required to build the message */
13433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13434     {
13435       if (unformat (input, "l2"))
13436         {
13437           is_l2 = 1;
13438           mode_set = 1;
13439         }
13440       else if (unformat (input, "l3"))
13441         {
13442           is_l2 = 0;
13443           mode_set = 1;
13444         }
13445       else
13446         {
13447           errmsg ("parse error '%U'", format_unformat_error, input);
13448           return -99;
13449         }
13450     }
13451
13452   if (!mode_set)
13453     {
13454       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13455       return -99;
13456     }
13457
13458   if (!vam->json_output)
13459     {
13460       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13461     }
13462
13463   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13464   mp->is_l2 = is_l2;
13465
13466   /* send it... */
13467   S;
13468
13469   /* Use a control ping for synchronization */
13470   {
13471     vl_api_control_ping_t *mp;
13472     M (CONTROL_PING, control_ping);
13473     S;
13474   }
13475   /* Wait for a reply... */
13476   W;
13477
13478   /* NOTREACHED */
13479   return 0;
13480 }
13481
13482 static int
13483 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13484 {
13485   vl_api_lisp_eid_table_vni_dump_t *mp;
13486   f64 timeout = ~0;
13487
13488   if (!vam->json_output)
13489     {
13490       fformat (vam->ofp, "VNI\n");
13491     }
13492
13493   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13494
13495   /* send it... */
13496   S;
13497
13498   /* Use a control ping for synchronization */
13499   {
13500     vl_api_control_ping_t *mp;
13501     M (CONTROL_PING, control_ping);
13502     S;
13503   }
13504   /* Wait for a reply... */
13505   W;
13506
13507   /* NOTREACHED */
13508   return 0;
13509 }
13510
13511 static int
13512 api_lisp_eid_table_dump (vat_main_t * vam)
13513 {
13514   unformat_input_t *i = vam->input;
13515   vl_api_lisp_eid_table_dump_t *mp;
13516   f64 timeout = ~0;
13517   struct in_addr ip4;
13518   struct in6_addr ip6;
13519   u8 mac[6];
13520   u8 eid_type = ~0, eid_set = 0;
13521   u32 prefix_length = ~0, t, vni = 0;
13522   u8 filter = 0;
13523
13524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13525     {
13526       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13527         {
13528           eid_set = 1;
13529           eid_type = 0;
13530           prefix_length = t;
13531         }
13532       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13533         {
13534           eid_set = 1;
13535           eid_type = 1;
13536           prefix_length = t;
13537         }
13538       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13539         {
13540           eid_set = 1;
13541           eid_type = 2;
13542         }
13543       else if (unformat (i, "vni %d", &t))
13544         {
13545           vni = t;
13546         }
13547       else if (unformat (i, "local"))
13548         {
13549           filter = 1;
13550         }
13551       else if (unformat (i, "remote"))
13552         {
13553           filter = 2;
13554         }
13555       else
13556         {
13557           errmsg ("parse error '%U'", format_unformat_error, i);
13558           return -99;
13559         }
13560     }
13561
13562   if (!vam->json_output)
13563     {
13564       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13565                "ls_index", "ttl", "authoritative");
13566     }
13567
13568   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13569
13570   mp->filter = filter;
13571   if (eid_set)
13572     {
13573       mp->eid_set = 1;
13574       mp->vni = htonl (vni);
13575       mp->eid_type = eid_type;
13576       switch (eid_type)
13577         {
13578         case 0:
13579           mp->prefix_length = prefix_length;
13580           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13581           break;
13582         case 1:
13583           mp->prefix_length = prefix_length;
13584           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13585           break;
13586         case 2:
13587           clib_memcpy (mp->eid, mac, sizeof (mac));
13588           break;
13589         default:
13590           errmsg ("unknown EID type %d!", eid_type);
13591           return -99;
13592         }
13593     }
13594
13595   /* send it... */
13596   S;
13597
13598   /* Use a control ping for synchronization */
13599   {
13600     vl_api_control_ping_t *mp;
13601     M (CONTROL_PING, control_ping);
13602     S;
13603   }
13604
13605   /* Wait for a reply... */
13606   W;
13607
13608   /* NOTREACHED */
13609   return 0;
13610 }
13611
13612 static int
13613 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13614 {
13615   vl_api_lisp_gpe_tunnel_dump_t *mp;
13616   f64 timeout = ~0;
13617
13618   if (!vam->json_output)
13619     {
13620       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13621                "%=16s%=16s%=16s%=16s%=16s\n",
13622                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13623                "Decap next", "Lisp version", "Flags", "Next protocol",
13624                "ver_res", "res", "iid");
13625     }
13626
13627   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13628   /* send it... */
13629   S;
13630
13631   /* Use a control ping for synchronization */
13632   {
13633     vl_api_control_ping_t *mp;
13634     M (CONTROL_PING, control_ping);
13635     S;
13636   }
13637   /* Wait for a reply... */
13638   W;
13639
13640   /* NOTREACHED */
13641   return 0;
13642 }
13643
13644 static int
13645 api_lisp_map_resolver_dump (vat_main_t * vam)
13646 {
13647   vl_api_lisp_map_resolver_dump_t *mp;
13648   f64 timeout = ~0;
13649
13650   if (!vam->json_output)
13651     {
13652       fformat (vam->ofp, "%=20s\n", "Map resolver");
13653     }
13654
13655   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13656   /* send it... */
13657   S;
13658
13659   /* Use a control ping for synchronization */
13660   {
13661     vl_api_control_ping_t *mp;
13662     M (CONTROL_PING, control_ping);
13663     S;
13664   }
13665   /* Wait for a reply... */
13666   W;
13667
13668   /* NOTREACHED */
13669   return 0;
13670 }
13671
13672 static int
13673 api_show_lisp_status (vat_main_t * vam)
13674 {
13675   vl_api_show_lisp_status_t *mp;
13676   f64 timeout = ~0;
13677
13678   if (!vam->json_output)
13679     {
13680       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13681     }
13682
13683   M (SHOW_LISP_STATUS, show_lisp_status);
13684   /* send it... */
13685   S;
13686   /* Wait for a reply... */
13687   W;
13688
13689   /* NOTREACHED */
13690   return 0;
13691 }
13692
13693 static int
13694 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13695 {
13696   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13697   f64 timeout = ~0;
13698
13699   if (!vam->json_output)
13700     {
13701       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13702     }
13703
13704   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13705   /* send it... */
13706   S;
13707   /* Wait for a reply... */
13708   W;
13709
13710   /* NOTREACHED */
13711   return 0;
13712 }
13713
13714 static int
13715 api_af_packet_create (vat_main_t * vam)
13716 {
13717   unformat_input_t *i = vam->input;
13718   vl_api_af_packet_create_t *mp;
13719   f64 timeout;
13720   u8 *host_if_name = 0;
13721   u8 hw_addr[6];
13722   u8 random_hw_addr = 1;
13723
13724   memset (hw_addr, 0, sizeof (hw_addr));
13725
13726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13727     {
13728       if (unformat (i, "name %s", &host_if_name))
13729         vec_add1 (host_if_name, 0);
13730       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13731         random_hw_addr = 0;
13732       else
13733         break;
13734     }
13735
13736   if (!vec_len (host_if_name))
13737     {
13738       errmsg ("host-interface name must be specified");
13739       return -99;
13740     }
13741
13742   if (vec_len (host_if_name) > 64)
13743     {
13744       errmsg ("host-interface name too long");
13745       return -99;
13746     }
13747
13748   M (AF_PACKET_CREATE, af_packet_create);
13749
13750   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13751   clib_memcpy (mp->hw_addr, hw_addr, 6);
13752   mp->use_random_hw_addr = random_hw_addr;
13753   vec_free (host_if_name);
13754
13755   S;
13756   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13757   /* NOTREACHED */
13758   return 0;
13759 }
13760
13761 static int
13762 api_af_packet_delete (vat_main_t * vam)
13763 {
13764   unformat_input_t *i = vam->input;
13765   vl_api_af_packet_delete_t *mp;
13766   f64 timeout;
13767   u8 *host_if_name = 0;
13768
13769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13770     {
13771       if (unformat (i, "name %s", &host_if_name))
13772         vec_add1 (host_if_name, 0);
13773       else
13774         break;
13775     }
13776
13777   if (!vec_len (host_if_name))
13778     {
13779       errmsg ("host-interface name must be specified");
13780       return -99;
13781     }
13782
13783   if (vec_len (host_if_name) > 64)
13784     {
13785       errmsg ("host-interface name too long");
13786       return -99;
13787     }
13788
13789   M (AF_PACKET_DELETE, af_packet_delete);
13790
13791   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13792   vec_free (host_if_name);
13793
13794   S;
13795   W;
13796   /* NOTREACHED */
13797   return 0;
13798 }
13799
13800 static int
13801 api_policer_add_del (vat_main_t * vam)
13802 {
13803   unformat_input_t *i = vam->input;
13804   vl_api_policer_add_del_t *mp;
13805   f64 timeout;
13806   u8 is_add = 1;
13807   u8 *name = 0;
13808   u32 cir = 0;
13809   u32 eir = 0;
13810   u64 cb = 0;
13811   u64 eb = 0;
13812   u8 rate_type = 0;
13813   u8 round_type = 0;
13814   u8 type = 0;
13815   u8 color_aware = 0;
13816   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13817
13818   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13819   conform_action.dscp = 0;
13820   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13821   exceed_action.dscp = 0;
13822   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13823   violate_action.dscp = 0;
13824
13825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13826     {
13827       if (unformat (i, "del"))
13828         is_add = 0;
13829       else if (unformat (i, "name %s", &name))
13830         vec_add1 (name, 0);
13831       else if (unformat (i, "cir %u", &cir))
13832         ;
13833       else if (unformat (i, "eir %u", &eir))
13834         ;
13835       else if (unformat (i, "cb %u", &cb))
13836         ;
13837       else if (unformat (i, "eb %u", &eb))
13838         ;
13839       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13840                          &rate_type))
13841         ;
13842       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13843                          &round_type))
13844         ;
13845       else if (unformat (i, "type %U", unformat_policer_type, &type))
13846         ;
13847       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13848                          &conform_action))
13849         ;
13850       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13851                          &exceed_action))
13852         ;
13853       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13854                          &violate_action))
13855         ;
13856       else if (unformat (i, "color-aware"))
13857         color_aware = 1;
13858       else
13859         break;
13860     }
13861
13862   if (!vec_len (name))
13863     {
13864       errmsg ("policer name must be specified");
13865       return -99;
13866     }
13867
13868   if (vec_len (name) > 64)
13869     {
13870       errmsg ("policer name too long");
13871       return -99;
13872     }
13873
13874   M (POLICER_ADD_DEL, policer_add_del);
13875
13876   clib_memcpy (mp->name, name, vec_len (name));
13877   vec_free (name);
13878   mp->is_add = is_add;
13879   mp->cir = cir;
13880   mp->eir = eir;
13881   mp->cb = cb;
13882   mp->eb = eb;
13883   mp->rate_type = rate_type;
13884   mp->round_type = round_type;
13885   mp->type = type;
13886   mp->conform_action_type = conform_action.action_type;
13887   mp->conform_dscp = conform_action.dscp;
13888   mp->exceed_action_type = exceed_action.action_type;
13889   mp->exceed_dscp = exceed_action.dscp;
13890   mp->violate_action_type = violate_action.action_type;
13891   mp->violate_dscp = violate_action.dscp;
13892   mp->color_aware = color_aware;
13893
13894   S;
13895   W;
13896   /* NOTREACHED */
13897   return 0;
13898 }
13899
13900 static int
13901 api_policer_dump (vat_main_t * vam)
13902 {
13903   unformat_input_t *i = vam->input;
13904   vl_api_policer_dump_t *mp;
13905   f64 timeout = ~0;
13906   u8 *match_name = 0;
13907   u8 match_name_valid = 0;
13908
13909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13910     {
13911       if (unformat (i, "name %s", &match_name))
13912         {
13913           vec_add1 (match_name, 0);
13914           match_name_valid = 1;
13915         }
13916       else
13917         break;
13918     }
13919
13920   M (POLICER_DUMP, policer_dump);
13921   mp->match_name_valid = match_name_valid;
13922   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13923   vec_free (match_name);
13924   /* send it... */
13925   S;
13926
13927   /* Use a control ping for synchronization */
13928   {
13929     vl_api_control_ping_t *mp;
13930     M (CONTROL_PING, control_ping);
13931     S;
13932   }
13933   /* Wait for a reply... */
13934   W;
13935
13936   /* NOTREACHED */
13937   return 0;
13938 }
13939
13940 static int
13941 api_policer_classify_set_interface (vat_main_t * vam)
13942 {
13943   unformat_input_t *i = vam->input;
13944   vl_api_policer_classify_set_interface_t *mp;
13945   f64 timeout;
13946   u32 sw_if_index;
13947   int sw_if_index_set;
13948   u32 ip4_table_index = ~0;
13949   u32 ip6_table_index = ~0;
13950   u32 l2_table_index = ~0;
13951   u8 is_add = 1;
13952
13953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13954     {
13955       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13956         sw_if_index_set = 1;
13957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13958         sw_if_index_set = 1;
13959       else if (unformat (i, "del"))
13960         is_add = 0;
13961       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13962         ;
13963       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13964         ;
13965       else if (unformat (i, "l2-table %d", &l2_table_index))
13966         ;
13967       else
13968         {
13969           clib_warning ("parse error '%U'", format_unformat_error, i);
13970           return -99;
13971         }
13972     }
13973
13974   if (sw_if_index_set == 0)
13975     {
13976       errmsg ("missing interface name or sw_if_index\n");
13977       return -99;
13978     }
13979
13980   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13981
13982   mp->sw_if_index = ntohl (sw_if_index);
13983   mp->ip4_table_index = ntohl (ip4_table_index);
13984   mp->ip6_table_index = ntohl (ip6_table_index);
13985   mp->l2_table_index = ntohl (l2_table_index);
13986   mp->is_add = is_add;
13987
13988   S;
13989   W;
13990   /* NOTREACHED */
13991   return 0;
13992 }
13993
13994 static int
13995 api_policer_classify_dump (vat_main_t * vam)
13996 {
13997   unformat_input_t *i = vam->input;
13998   vl_api_policer_classify_dump_t *mp;
13999   f64 timeout = ~0;
14000   u8 type = POLICER_CLASSIFY_N_TABLES;
14001
14002   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14003     ;
14004   else
14005     {
14006       errmsg ("classify table type must be specified\n");
14007       return -99;
14008     }
14009
14010   if (!vam->json_output)
14011     {
14012       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14013     }
14014
14015   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14016   mp->type = type;
14017   /* send it... */
14018   S;
14019
14020   /* Use a control ping for synchronization */
14021   {
14022     vl_api_control_ping_t *mp;
14023     M (CONTROL_PING, control_ping);
14024     S;
14025   }
14026   /* Wait for a reply... */
14027   W;
14028
14029   /* NOTREACHED */
14030   return 0;
14031 }
14032
14033 static int
14034 api_netmap_create (vat_main_t * vam)
14035 {
14036   unformat_input_t *i = vam->input;
14037   vl_api_netmap_create_t *mp;
14038   f64 timeout;
14039   u8 *if_name = 0;
14040   u8 hw_addr[6];
14041   u8 random_hw_addr = 1;
14042   u8 is_pipe = 0;
14043   u8 is_master = 0;
14044
14045   memset (hw_addr, 0, sizeof (hw_addr));
14046
14047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14048     {
14049       if (unformat (i, "name %s", &if_name))
14050         vec_add1 (if_name, 0);
14051       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14052         random_hw_addr = 0;
14053       else if (unformat (i, "pipe"))
14054         is_pipe = 1;
14055       else if (unformat (i, "master"))
14056         is_master = 1;
14057       else if (unformat (i, "slave"))
14058         is_master = 0;
14059       else
14060         break;
14061     }
14062
14063   if (!vec_len (if_name))
14064     {
14065       errmsg ("interface name must be specified");
14066       return -99;
14067     }
14068
14069   if (vec_len (if_name) > 64)
14070     {
14071       errmsg ("interface name too long");
14072       return -99;
14073     }
14074
14075   M (NETMAP_CREATE, netmap_create);
14076
14077   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14078   clib_memcpy (mp->hw_addr, hw_addr, 6);
14079   mp->use_random_hw_addr = random_hw_addr;
14080   mp->is_pipe = is_pipe;
14081   mp->is_master = is_master;
14082   vec_free (if_name);
14083
14084   S;
14085   W;
14086   /* NOTREACHED */
14087   return 0;
14088 }
14089
14090 static int
14091 api_netmap_delete (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_netmap_delete_t *mp;
14095   f64 timeout;
14096   u8 *if_name = 0;
14097
14098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14099     {
14100       if (unformat (i, "name %s", &if_name))
14101         vec_add1 (if_name, 0);
14102       else
14103         break;
14104     }
14105
14106   if (!vec_len (if_name))
14107     {
14108       errmsg ("interface name must be specified");
14109       return -99;
14110     }
14111
14112   if (vec_len (if_name) > 64)
14113     {
14114       errmsg ("interface name too long");
14115       return -99;
14116     }
14117
14118   M (NETMAP_DELETE, netmap_delete);
14119
14120   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14121   vec_free (if_name);
14122
14123   S;
14124   W;
14125   /* NOTREACHED */
14126   return 0;
14127 }
14128
14129 static void vl_api_mpls_gre_tunnel_details_t_handler
14130   (vl_api_mpls_gre_tunnel_details_t * mp)
14131 {
14132   vat_main_t *vam = &vat_main;
14133   i32 i;
14134   i32 len = ntohl (mp->nlabels);
14135
14136   if (mp->l2_only == 0)
14137     {
14138       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14139                ntohl (mp->tunnel_index),
14140                format_ip4_address, &mp->tunnel_src,
14141                format_ip4_address, &mp->tunnel_dst,
14142                format_ip4_address, &mp->intfc_address,
14143                ntohl (mp->mask_width));
14144       for (i = 0; i < len; i++)
14145         {
14146           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14147         }
14148       fformat (vam->ofp, "\n");
14149       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14150                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14151     }
14152   else
14153     {
14154       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14155                ntohl (mp->tunnel_index),
14156                format_ip4_address, &mp->tunnel_src,
14157                format_ip4_address, &mp->tunnel_dst,
14158                format_ip4_address, &mp->intfc_address);
14159       for (i = 0; i < len; i++)
14160         {
14161           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14162         }
14163       fformat (vam->ofp, "\n");
14164       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14165                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14166     }
14167 }
14168
14169 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14170   (vl_api_mpls_gre_tunnel_details_t * mp)
14171 {
14172   vat_main_t *vam = &vat_main;
14173   vat_json_node_t *node = NULL;
14174   struct in_addr ip4;
14175   i32 i;
14176   i32 len = ntohl (mp->nlabels);
14177
14178   if (VAT_JSON_ARRAY != vam->json_tree.type)
14179     {
14180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14181       vat_json_init_array (&vam->json_tree);
14182     }
14183   node = vat_json_array_add (&vam->json_tree);
14184
14185   vat_json_init_object (node);
14186   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14187   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14188   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14189   vat_json_object_add_uint (node, "inner_fib_index",
14190                             ntohl (mp->inner_fib_index));
14191   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14192   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14193   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14194   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14195   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14196   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14197   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14198   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14199   vat_json_object_add_uint (node, "outer_fib_index",
14200                             ntohl (mp->outer_fib_index));
14201   vat_json_object_add_uint (node, "label_count", len);
14202   for (i = 0; i < len; i++)
14203     {
14204       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14205     }
14206 }
14207
14208 static int
14209 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14210 {
14211   vl_api_mpls_gre_tunnel_dump_t *mp;
14212   f64 timeout;
14213   i32 index = -1;
14214
14215   /* Parse args required to build the message */
14216   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14217     {
14218       if (!unformat (vam->input, "tunnel_index %d", &index))
14219         {
14220           index = -1;
14221           break;
14222         }
14223     }
14224
14225   fformat (vam->ofp, "  tunnel_index %d\n", index);
14226
14227   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14228   mp->tunnel_index = htonl (index);
14229   S;
14230
14231   /* Use a control ping for synchronization */
14232   {
14233     vl_api_control_ping_t *mp;
14234     M (CONTROL_PING, control_ping);
14235     S;
14236   }
14237   W;
14238 }
14239
14240 static void vl_api_mpls_eth_tunnel_details_t_handler
14241   (vl_api_mpls_eth_tunnel_details_t * mp)
14242 {
14243   vat_main_t *vam = &vat_main;
14244   i32 i;
14245   i32 len = ntohl (mp->nlabels);
14246
14247   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14248            ntohl (mp->tunnel_index),
14249            format_ethernet_address, &mp->tunnel_dst_mac,
14250            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14251   for (i = 0; i < len; i++)
14252     {
14253       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14254     }
14255   fformat (vam->ofp, "\n");
14256   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14257            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14258 }
14259
14260 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14261   (vl_api_mpls_eth_tunnel_details_t * mp)
14262 {
14263   vat_main_t *vam = &vat_main;
14264   vat_json_node_t *node = NULL;
14265   struct in_addr ip4;
14266   i32 i;
14267   i32 len = ntohl (mp->nlabels);
14268
14269   if (VAT_JSON_ARRAY != vam->json_tree.type)
14270     {
14271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14272       vat_json_init_array (&vam->json_tree);
14273     }
14274   node = vat_json_array_add (&vam->json_tree);
14275
14276   vat_json_init_object (node);
14277   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14278   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14279   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14280   vat_json_object_add_uint (node, "inner_fib_index",
14281                             ntohl (mp->inner_fib_index));
14282   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14283   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14284   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14285   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14286   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14287                                    format (0, "%U", format_ethernet_address,
14288                                            &mp->tunnel_dst_mac));
14289   vat_json_object_add_uint (node, "tx_sw_if_index",
14290                             ntohl (mp->tx_sw_if_index));
14291   vat_json_object_add_uint (node, "label_count", len);
14292   for (i = 0; i < len; i++)
14293     {
14294       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14295     }
14296 }
14297
14298 static int
14299 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14300 {
14301   vl_api_mpls_eth_tunnel_dump_t *mp;
14302   f64 timeout;
14303   i32 index = -1;
14304
14305   /* Parse args required to build the message */
14306   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (!unformat (vam->input, "tunnel_index %d", &index))
14309         {
14310           index = -1;
14311           break;
14312         }
14313     }
14314
14315   fformat (vam->ofp, "  tunnel_index %d\n", index);
14316
14317   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14318   mp->tunnel_index = htonl (index);
14319   S;
14320
14321   /* Use a control ping for synchronization */
14322   {
14323     vl_api_control_ping_t *mp;
14324     M (CONTROL_PING, control_ping);
14325     S;
14326   }
14327   W;
14328 }
14329
14330 static void vl_api_mpls_fib_encap_details_t_handler
14331   (vl_api_mpls_fib_encap_details_t * mp)
14332 {
14333   vat_main_t *vam = &vat_main;
14334   i32 i;
14335   i32 len = ntohl (mp->nlabels);
14336
14337   fformat (vam->ofp, "table %d, dest %U, label ",
14338            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14339   for (i = 0; i < len; i++)
14340     {
14341       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14342     }
14343   fformat (vam->ofp, "\n");
14344 }
14345
14346 static void vl_api_mpls_fib_encap_details_t_handler_json
14347   (vl_api_mpls_fib_encap_details_t * mp)
14348 {
14349   vat_main_t *vam = &vat_main;
14350   vat_json_node_t *node = NULL;
14351   i32 i;
14352   i32 len = ntohl (mp->nlabels);
14353   struct in_addr ip4;
14354
14355   if (VAT_JSON_ARRAY != vam->json_tree.type)
14356     {
14357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14358       vat_json_init_array (&vam->json_tree);
14359     }
14360   node = vat_json_array_add (&vam->json_tree);
14361
14362   vat_json_init_object (node);
14363   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14364   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14365   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14366   vat_json_object_add_ip4 (node, "dest", ip4);
14367   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14368   vat_json_object_add_uint (node, "label_count", len);
14369   for (i = 0; i < len; i++)
14370     {
14371       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14372     }
14373 }
14374
14375 static int
14376 api_mpls_fib_encap_dump (vat_main_t * vam)
14377 {
14378   vl_api_mpls_fib_encap_dump_t *mp;
14379   f64 timeout;
14380
14381   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14382   S;
14383
14384   /* Use a control ping for synchronization */
14385   {
14386     vl_api_control_ping_t *mp;
14387     M (CONTROL_PING, control_ping);
14388     S;
14389   }
14390   W;
14391 }
14392
14393 static void vl_api_mpls_fib_decap_details_t_handler
14394   (vl_api_mpls_fib_decap_details_t * mp)
14395 {
14396   vat_main_t *vam = &vat_main;
14397
14398   fformat (vam->ofp,
14399            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14400            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14401            ntohl (mp->label), ntohl (mp->s_bit));
14402 }
14403
14404 static void vl_api_mpls_fib_decap_details_t_handler_json
14405   (vl_api_mpls_fib_decap_details_t * mp)
14406 {
14407   vat_main_t *vam = &vat_main;
14408   vat_json_node_t *node = NULL;
14409   struct in_addr ip4;
14410
14411   if (VAT_JSON_ARRAY != vam->json_tree.type)
14412     {
14413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14414       vat_json_init_array (&vam->json_tree);
14415     }
14416   node = vat_json_array_add (&vam->json_tree);
14417
14418   vat_json_init_object (node);
14419   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14420   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14421   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14422   vat_json_object_add_ip4 (node, "dest", ip4);
14423   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14424   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14425   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14426   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14427   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14428 }
14429
14430 static int
14431 api_mpls_fib_decap_dump (vat_main_t * vam)
14432 {
14433   vl_api_mpls_fib_decap_dump_t *mp;
14434   f64 timeout;
14435
14436   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14437   S;
14438
14439   /* Use a control ping for synchronization */
14440   {
14441     vl_api_control_ping_t *mp;
14442     M (CONTROL_PING, control_ping);
14443     S;
14444   }
14445   W;
14446 }
14447
14448 int
14449 api_classify_table_ids (vat_main_t * vam)
14450 {
14451   vl_api_classify_table_ids_t *mp;
14452   f64 timeout;
14453
14454   /* Construct the API message */
14455   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14456   mp->context = 0;
14457
14458   S;
14459   W;
14460   /* NOTREACHED */
14461   return 0;
14462 }
14463
14464 int
14465 api_classify_table_by_interface (vat_main_t * vam)
14466 {
14467   unformat_input_t *input = vam->input;
14468   vl_api_classify_table_by_interface_t *mp;
14469   f64 timeout;
14470
14471   u32 sw_if_index = ~0;
14472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14473     {
14474       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14475         ;
14476       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14477         ;
14478       else
14479         break;
14480     }
14481   if (sw_if_index == ~0)
14482     {
14483       errmsg ("missing interface name or sw_if_index\n");
14484       return -99;
14485     }
14486
14487   /* Construct the API message */
14488   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14489   mp->context = 0;
14490   mp->sw_if_index = ntohl (sw_if_index);
14491
14492   S;
14493   W;
14494   /* NOTREACHED */
14495   return 0;
14496 }
14497
14498 int
14499 api_classify_table_info (vat_main_t * vam)
14500 {
14501   unformat_input_t *input = vam->input;
14502   vl_api_classify_table_info_t *mp;
14503   f64 timeout;
14504
14505   u32 table_id = ~0;
14506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14507     {
14508       if (unformat (input, "table_id %d", &table_id))
14509         ;
14510       else
14511         break;
14512     }
14513   if (table_id == ~0)
14514     {
14515       errmsg ("missing table id\n");
14516       return -99;
14517     }
14518
14519   /* Construct the API message */
14520   M (CLASSIFY_TABLE_INFO, classify_table_info);
14521   mp->context = 0;
14522   mp->table_id = ntohl (table_id);
14523
14524   S;
14525   W;
14526   /* NOTREACHED */
14527   return 0;
14528 }
14529
14530 int
14531 api_classify_session_dump (vat_main_t * vam)
14532 {
14533   unformat_input_t *input = vam->input;
14534   vl_api_classify_session_dump_t *mp;
14535   f64 timeout;
14536
14537   u32 table_id = ~0;
14538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (input, "table_id %d", &table_id))
14541         ;
14542       else
14543         break;
14544     }
14545   if (table_id == ~0)
14546     {
14547       errmsg ("missing table id\n");
14548       return -99;
14549     }
14550
14551   /* Construct the API message */
14552   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14553   mp->context = 0;
14554   mp->table_id = ntohl (table_id);
14555   S;
14556
14557   /* Use a control ping for synchronization */
14558   {
14559     vl_api_control_ping_t *mp;
14560     M (CONTROL_PING, control_ping);
14561     S;
14562   }
14563   W;
14564   /* NOTREACHED */
14565   return 0;
14566 }
14567
14568 static void
14569 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14570 {
14571   vat_main_t *vam = &vat_main;
14572
14573   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14574            "src_address %U, vrf_id %d, path_mtu %u, "
14575            "template_interval %u, udp_checksum %d\n",
14576            format_ip4_address, mp->collector_address,
14577            ntohs (mp->collector_port),
14578            format_ip4_address, mp->src_address,
14579            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14580            ntohl (mp->template_interval), mp->udp_checksum);
14581
14582   vam->retval = 0;
14583   vam->result_ready = 1;
14584 }
14585
14586 static void
14587   vl_api_ipfix_exporter_details_t_handler_json
14588   (vl_api_ipfix_exporter_details_t * mp)
14589 {
14590   vat_main_t *vam = &vat_main;
14591   vat_json_node_t node;
14592   struct in_addr collector_address;
14593   struct in_addr src_address;
14594
14595   vat_json_init_object (&node);
14596   clib_memcpy (&collector_address, &mp->collector_address,
14597                sizeof (collector_address));
14598   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14599   vat_json_object_add_uint (&node, "collector_port",
14600                             ntohs (mp->collector_port));
14601   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14602   vat_json_object_add_ip4 (&node, "src_address", src_address);
14603   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14604   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14605   vat_json_object_add_uint (&node, "template_interval",
14606                             ntohl (mp->template_interval));
14607   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14608
14609   vat_json_print (vam->ofp, &node);
14610   vat_json_free (&node);
14611   vam->retval = 0;
14612   vam->result_ready = 1;
14613 }
14614
14615 int
14616 api_ipfix_exporter_dump (vat_main_t * vam)
14617 {
14618   vl_api_ipfix_exporter_dump_t *mp;
14619   f64 timeout;
14620
14621   /* Construct the API message */
14622   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14623   mp->context = 0;
14624
14625   S;
14626   W;
14627   /* NOTREACHED */
14628   return 0;
14629 }
14630
14631 static int
14632 api_ipfix_classify_stream_dump (vat_main_t * vam)
14633 {
14634   vl_api_ipfix_classify_stream_dump_t *mp;
14635   f64 timeout;
14636
14637   /* Construct the API message */
14638   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14639   mp->context = 0;
14640
14641   S;
14642   W;
14643   /* NOTREACHED */
14644   return 0;
14645 }
14646
14647 static void
14648   vl_api_ipfix_classify_stream_details_t_handler
14649   (vl_api_ipfix_classify_stream_details_t * mp)
14650 {
14651   vat_main_t *vam = &vat_main;
14652   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14653            ntohl (mp->domain_id), ntohs (mp->src_port));
14654   vam->retval = 0;
14655   vam->result_ready = 1;
14656 }
14657
14658 static void
14659   vl_api_ipfix_classify_stream_details_t_handler_json
14660   (vl_api_ipfix_classify_stream_details_t * mp)
14661 {
14662   vat_main_t *vam = &vat_main;
14663   vat_json_node_t node;
14664
14665   vat_json_init_object (&node);
14666   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14667   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14668
14669   vat_json_print (vam->ofp, &node);
14670   vat_json_free (&node);
14671   vam->retval = 0;
14672   vam->result_ready = 1;
14673 }
14674
14675 static int
14676 api_ipfix_classify_table_dump (vat_main_t * vam)
14677 {
14678   vl_api_ipfix_classify_table_dump_t *mp;
14679   f64 timeout;
14680
14681   if (!vam->json_output)
14682     {
14683       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14684                "transport_protocol");
14685     }
14686
14687   /* Construct the API message */
14688   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14689
14690   /* send it... */
14691   S;
14692
14693   /* Use a control ping for synchronization */
14694   {
14695     vl_api_control_ping_t *mp;
14696     M (CONTROL_PING, control_ping);
14697     S;
14698   }
14699   W;
14700 }
14701
14702 static void
14703   vl_api_ipfix_classify_table_details_t_handler
14704   (vl_api_ipfix_classify_table_details_t * mp)
14705 {
14706   vat_main_t *vam = &vat_main;
14707   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14708            mp->transport_protocol);
14709 }
14710
14711 static void
14712   vl_api_ipfix_classify_table_details_t_handler_json
14713   (vl_api_ipfix_classify_table_details_t * mp)
14714 {
14715   vat_json_node_t *node = NULL;
14716   vat_main_t *vam = &vat_main;
14717
14718   if (VAT_JSON_ARRAY != vam->json_tree.type)
14719     {
14720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14721       vat_json_init_array (&vam->json_tree);
14722     }
14723
14724   node = vat_json_array_add (&vam->json_tree);
14725   vat_json_init_object (node);
14726
14727   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14728   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14729   vat_json_object_add_uint (node, "transport_protocol",
14730                             mp->transport_protocol);
14731 }
14732
14733 int
14734 api_pg_create_interface (vat_main_t * vam)
14735 {
14736   unformat_input_t *input = vam->input;
14737   vl_api_pg_create_interface_t *mp;
14738   f64 timeout;
14739
14740   u32 if_id = ~0;
14741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14742     {
14743       if (unformat (input, "if_id %d", &if_id))
14744         ;
14745       else
14746         break;
14747     }
14748   if (if_id == ~0)
14749     {
14750       errmsg ("missing pg interface index\n");
14751       return -99;
14752     }
14753
14754   /* Construct the API message */
14755   M (PG_CREATE_INTERFACE, pg_create_interface);
14756   mp->context = 0;
14757   mp->interface_id = ntohl (if_id);
14758
14759   S;
14760   W;
14761   /* NOTREACHED */
14762   return 0;
14763 }
14764
14765 int
14766 api_pg_capture (vat_main_t * vam)
14767 {
14768   unformat_input_t *input = vam->input;
14769   vl_api_pg_capture_t *mp;
14770   f64 timeout;
14771
14772   u32 if_id = ~0;
14773   u8 enable = 1;
14774   u32 count = 1;
14775   u8 pcap_file_set = 0;
14776   u8 *pcap_file = 0;
14777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14778     {
14779       if (unformat (input, "if_id %d", &if_id))
14780         ;
14781       else if (unformat (input, "pcap %s", &pcap_file))
14782         pcap_file_set = 1;
14783       else if (unformat (input, "count %d", &count))
14784         ;
14785       else if (unformat (input, "disable"))
14786         enable = 0;
14787       else
14788         break;
14789     }
14790   if (if_id == ~0)
14791     {
14792       errmsg ("missing pg interface index\n");
14793       return -99;
14794     }
14795   if (pcap_file_set > 0)
14796     {
14797       if (vec_len (pcap_file) > 255)
14798         {
14799           errmsg ("pcap file name is too long\n");
14800           return -99;
14801         }
14802     }
14803
14804   u32 name_len = vec_len (pcap_file);
14805   /* Construct the API message */
14806   M (PG_CAPTURE, pg_capture);
14807   mp->context = 0;
14808   mp->interface_id = ntohl (if_id);
14809   mp->is_enabled = enable;
14810   mp->count = ntohl (count);
14811   mp->pcap_name_length = ntohl (name_len);
14812   if (pcap_file_set != 0)
14813     {
14814       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14815     }
14816   vec_free (pcap_file);
14817
14818   S;
14819   W;
14820   /* NOTREACHED */
14821   return 0;
14822 }
14823
14824 int
14825 api_pg_enable_disable (vat_main_t * vam)
14826 {
14827   unformat_input_t *input = vam->input;
14828   vl_api_pg_enable_disable_t *mp;
14829   f64 timeout;
14830
14831   u8 enable = 1;
14832   u8 stream_name_set = 0;
14833   u8 *stream_name = 0;
14834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14835     {
14836       if (unformat (input, "stream %s", &stream_name))
14837         stream_name_set = 1;
14838       else if (unformat (input, "disable"))
14839         enable = 0;
14840       else
14841         break;
14842     }
14843
14844   if (stream_name_set > 0)
14845     {
14846       if (vec_len (stream_name) > 255)
14847         {
14848           errmsg ("stream name too long\n");
14849           return -99;
14850         }
14851     }
14852
14853   u32 name_len = vec_len (stream_name);
14854   /* Construct the API message */
14855   M (PG_ENABLE_DISABLE, pg_enable_disable);
14856   mp->context = 0;
14857   mp->is_enabled = enable;
14858   if (stream_name_set != 0)
14859     {
14860       mp->stream_name_length = ntohl (name_len);
14861       clib_memcpy (mp->stream_name, stream_name, name_len);
14862     }
14863   vec_free (stream_name);
14864
14865   S;
14866   W;
14867   /* NOTREACHED */
14868   return 0;
14869 }
14870
14871 int
14872 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14873 {
14874   unformat_input_t *input = vam->input;
14875   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14876   f64 timeout;
14877
14878   u16 *low_ports = 0;
14879   u16 *high_ports = 0;
14880   u16 this_low;
14881   u16 this_hi;
14882   ip4_address_t ip4_addr;
14883   ip6_address_t ip6_addr;
14884   u32 length;
14885   u32 tmp, tmp2;
14886   u8 prefix_set = 0;
14887   u32 vrf_id = ~0;
14888   u8 is_add = 1;
14889   u8 is_ipv6 = 0;
14890
14891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14892     {
14893       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14894         {
14895           prefix_set = 1;
14896         }
14897       else
14898         if (unformat
14899             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14900         {
14901           prefix_set = 1;
14902           is_ipv6 = 1;
14903         }
14904       else if (unformat (input, "vrf %d", &vrf_id))
14905         ;
14906       else if (unformat (input, "del"))
14907         is_add = 0;
14908       else if (unformat (input, "port %d", &tmp))
14909         {
14910           if (tmp == 0 || tmp > 65535)
14911             {
14912               errmsg ("port %d out of range", tmp);
14913               return -99;
14914             }
14915           this_low = tmp;
14916           this_hi = this_low + 1;
14917           vec_add1 (low_ports, this_low);
14918           vec_add1 (high_ports, this_hi);
14919         }
14920       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14921         {
14922           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14923             {
14924               errmsg ("incorrect range parameters\n");
14925               return -99;
14926             }
14927           this_low = tmp;
14928           /* Note: in debug CLI +1 is added to high before
14929              passing to real fn that does "the work"
14930              (ip_source_and_port_range_check_add_del).
14931              This fn is a wrapper around the binary API fn a
14932              control plane will call, which expects this increment
14933              to have occurred. Hence letting the binary API control
14934              plane fn do the increment for consistency between VAT
14935              and other control planes.
14936            */
14937           this_hi = tmp2;
14938           vec_add1 (low_ports, this_low);
14939           vec_add1 (high_ports, this_hi);
14940         }
14941       else
14942         break;
14943     }
14944
14945   if (prefix_set == 0)
14946     {
14947       errmsg ("<address>/<mask> not specified\n");
14948       return -99;
14949     }
14950
14951   if (vrf_id == ~0)
14952     {
14953       errmsg ("VRF ID required, not specified\n");
14954       return -99;
14955     }
14956
14957   if (vrf_id == 0)
14958     {
14959       errmsg
14960         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14961       return -99;
14962     }
14963
14964   if (vec_len (low_ports) == 0)
14965     {
14966       errmsg ("At least one port or port range required\n");
14967       return -99;
14968     }
14969
14970   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14971      ip_source_and_port_range_check_add_del);
14972
14973   mp->is_add = is_add;
14974
14975   if (is_ipv6)
14976     {
14977       mp->is_ipv6 = 1;
14978       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14979     }
14980   else
14981     {
14982       mp->is_ipv6 = 0;
14983       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14984     }
14985
14986   mp->mask_length = length;
14987   mp->number_of_ranges = vec_len (low_ports);
14988
14989   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14990   vec_free (low_ports);
14991
14992   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14993   vec_free (high_ports);
14994
14995   mp->vrf_id = ntohl (vrf_id);
14996
14997   S;
14998   W;
14999   /* NOTREACHED */
15000   return 0;
15001 }
15002
15003 int
15004 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15005 {
15006   unformat_input_t *input = vam->input;
15007   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15008   f64 timeout;
15009   u32 sw_if_index = ~0;
15010   int vrf_set = 0;
15011   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15012   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15013   u8 is_add = 1;
15014
15015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15016     {
15017       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15018         ;
15019       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15020         ;
15021       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15022         vrf_set = 1;
15023       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15024         vrf_set = 1;
15025       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15026         vrf_set = 1;
15027       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15028         vrf_set = 1;
15029       else if (unformat (input, "del"))
15030         is_add = 0;
15031       else
15032         break;
15033     }
15034
15035   if (sw_if_index == ~0)
15036     {
15037       errmsg ("Interface required but not specified\n");
15038       return -99;
15039     }
15040
15041   if (vrf_set == 0)
15042     {
15043       errmsg ("VRF ID required but not specified\n");
15044       return -99;
15045     }
15046
15047   if (tcp_out_vrf_id == 0
15048       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15049     {
15050       errmsg
15051         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15052       return -99;
15053     }
15054
15055   /* Construct the API message */
15056   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15057      ip_source_and_port_range_check_interface_add_del);
15058
15059   mp->sw_if_index = ntohl (sw_if_index);
15060   mp->is_add = is_add;
15061   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15062   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15063   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15064   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15065
15066   /* send it... */
15067   S;
15068
15069   /* Wait for a reply... */
15070   W;
15071 }
15072
15073 static int
15074 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15075 {
15076   unformat_input_t *i = vam->input;
15077   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15078   f64 timeout;
15079   u32 local_sa_id = 0;
15080   u32 remote_sa_id = 0;
15081   ip4_address_t src_address;
15082   ip4_address_t dst_address;
15083   u8 is_add = 1;
15084
15085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15086     {
15087       if (unformat (i, "local_sa %d", &local_sa_id))
15088         ;
15089       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15090         ;
15091       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15092         ;
15093       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15094         ;
15095       else if (unformat (i, "del"))
15096         is_add = 0;
15097       else
15098         {
15099           clib_warning ("parse error '%U'", format_unformat_error, i);
15100           return -99;
15101         }
15102     }
15103
15104   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15105
15106   mp->local_sa_id = ntohl (local_sa_id);
15107   mp->remote_sa_id = ntohl (remote_sa_id);
15108   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15109   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15110   mp->is_add = is_add;
15111
15112   S;
15113   W;
15114   /* NOTREACHED */
15115   return 0;
15116 }
15117
15118 static int
15119 api_punt (vat_main_t * vam)
15120 {
15121   unformat_input_t *i = vam->input;
15122   vl_api_punt_t *mp;
15123   f64 timeout;
15124   u32 ipv = ~0;
15125   u32 protocol = ~0;
15126   u32 port = ~0;
15127   int is_add = 1;
15128
15129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15130     {
15131       if (unformat (i, "ip %d", &ipv))
15132         ;
15133       else if (unformat (i, "protocol %d", &protocol))
15134         ;
15135       else if (unformat (i, "port %d", &port))
15136         ;
15137       else if (unformat (i, "del"))
15138         is_add = 0;
15139       else
15140         {
15141           clib_warning ("parse error '%U'", format_unformat_error, i);
15142           return -99;
15143         }
15144     }
15145
15146   M (PUNT, punt);
15147
15148   mp->is_add = (u8) is_add;
15149   mp->ipv = (u8) ipv;
15150   mp->l4_protocol = (u8) protocol;
15151   mp->l4_port = htons ((u16) port);
15152
15153   S;
15154   W;
15155   /* NOTREACHED */
15156   return 0;
15157 }
15158
15159 static void vl_api_ipsec_gre_tunnel_details_t_handler
15160   (vl_api_ipsec_gre_tunnel_details_t * mp)
15161 {
15162   vat_main_t *vam = &vat_main;
15163
15164   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15165            ntohl (mp->sw_if_index),
15166            format_ip4_address, &mp->src_address,
15167            format_ip4_address, &mp->dst_address,
15168            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15169 }
15170
15171 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15172   (vl_api_ipsec_gre_tunnel_details_t * mp)
15173 {
15174   vat_main_t *vam = &vat_main;
15175   vat_json_node_t *node = NULL;
15176   struct in_addr ip4;
15177
15178   if (VAT_JSON_ARRAY != vam->json_tree.type)
15179     {
15180       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15181       vat_json_init_array (&vam->json_tree);
15182     }
15183   node = vat_json_array_add (&vam->json_tree);
15184
15185   vat_json_init_object (node);
15186   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15187   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15188   vat_json_object_add_ip4 (node, "src_address", ip4);
15189   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15190   vat_json_object_add_ip4 (node, "dst_address", ip4);
15191   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15192   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15193 }
15194
15195 static int
15196 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15197 {
15198   unformat_input_t *i = vam->input;
15199   vl_api_ipsec_gre_tunnel_dump_t *mp;
15200   f64 timeout;
15201   u32 sw_if_index;
15202   u8 sw_if_index_set = 0;
15203
15204   /* Parse args required to build the message */
15205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15206     {
15207       if (unformat (i, "sw_if_index %d", &sw_if_index))
15208         sw_if_index_set = 1;
15209       else
15210         break;
15211     }
15212
15213   if (sw_if_index_set == 0)
15214     {
15215       sw_if_index = ~0;
15216     }
15217
15218   if (!vam->json_output)
15219     {
15220       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15221                "sw_if_index", "src_address", "dst_address",
15222                "local_sa_id", "remote_sa_id");
15223     }
15224
15225   /* Get list of gre-tunnel interfaces */
15226   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15227
15228   mp->sw_if_index = htonl (sw_if_index);
15229
15230   S;
15231
15232   /* Use a control ping for synchronization */
15233   {
15234     vl_api_control_ping_t *mp;
15235     M (CONTROL_PING, control_ping);
15236     S;
15237   }
15238   W;
15239 }
15240
15241 static int
15242 api_delete_subif (vat_main_t * vam)
15243 {
15244   unformat_input_t *i = vam->input;
15245   vl_api_delete_subif_t *mp;
15246   f64 timeout;
15247   u32 sw_if_index = ~0;
15248
15249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15250     {
15251       if (unformat (i, "sw_if_index %d", &sw_if_index))
15252         ;
15253       else
15254         break;
15255     }
15256
15257   if (sw_if_index == ~0)
15258     {
15259       errmsg ("missing sw_if_index\n");
15260       return -99;
15261     }
15262
15263   /* Construct the API message */
15264   M (DELETE_SUBIF, delete_subif);
15265   mp->sw_if_index = ntohl (sw_if_index);
15266
15267   S;
15268   W;
15269 }
15270
15271 #define foreach_pbb_vtr_op      \
15272 _("disable",  L2_VTR_DISABLED)  \
15273 _("pop",  L2_VTR_POP_2)         \
15274 _("push",  L2_VTR_PUSH_2)
15275
15276 static int
15277 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15278 {
15279   unformat_input_t *i = vam->input;
15280   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15281   f64 timeout;
15282   u32 sw_if_index = ~0, vtr_op = ~0;
15283   u16 outer_tag = ~0;
15284   u8 dmac[6], smac[6];
15285   u8 dmac_set = 0, smac_set = 0;
15286   u16 vlanid = 0;
15287   u32 sid = ~0;
15288   u32 tmp;
15289
15290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15291     {
15292       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15293         ;
15294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15295         ;
15296       else if (unformat (i, "vtr_op %d", &vtr_op))
15297         ;
15298 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15299       foreach_pbb_vtr_op
15300 #undef _
15301         else if (unformat (i, "translate_pbb_stag"))
15302         {
15303           if (unformat (i, "%d", &tmp))
15304             {
15305               vtr_op = L2_VTR_TRANSLATE_2_1;
15306               outer_tag = tmp;
15307             }
15308           else
15309             {
15310               errmsg
15311                 ("translate_pbb_stag operation requires outer tag definition\n");
15312               return -99;
15313             }
15314         }
15315       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15316         dmac_set++;
15317       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15318         smac_set++;
15319       else if (unformat (i, "sid %d", &sid))
15320         ;
15321       else if (unformat (i, "vlanid %d", &tmp))
15322         vlanid = tmp;
15323       else
15324         {
15325           clib_warning ("parse error '%U'", format_unformat_error, i);
15326           return -99;
15327         }
15328     }
15329
15330   if ((sw_if_index == ~0) || (vtr_op == ~0))
15331     {
15332       errmsg ("missing sw_if_index or vtr operation\n");
15333       return -99;
15334     }
15335   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15336       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15337     {
15338       errmsg
15339         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15340       return -99;
15341     }
15342
15343   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15344   mp->sw_if_index = ntohl (sw_if_index);
15345   mp->vtr_op = ntohl (vtr_op);
15346   mp->outer_tag = ntohs (outer_tag);
15347   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15348   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15349   mp->b_vlanid = ntohs (vlanid);
15350   mp->i_sid = ntohl (sid);
15351
15352   S;
15353   W;
15354   /* NOTREACHED */
15355   return 0;
15356 }
15357
15358 static int
15359 q_or_quit (vat_main_t * vam)
15360 {
15361   longjmp (vam->jump_buf, 1);
15362   return 0;                     /* not so much */
15363 }
15364
15365 static int
15366 q (vat_main_t * vam)
15367 {
15368   return q_or_quit (vam);
15369 }
15370
15371 static int
15372 quit (vat_main_t * vam)
15373 {
15374   return q_or_quit (vam);
15375 }
15376
15377 static int
15378 comment (vat_main_t * vam)
15379 {
15380   return 0;
15381 }
15382
15383 static int
15384 cmd_cmp (void *a1, void *a2)
15385 {
15386   u8 **c1 = a1;
15387   u8 **c2 = a2;
15388
15389   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15390 }
15391
15392 static int
15393 help (vat_main_t * vam)
15394 {
15395   u8 **cmds = 0;
15396   u8 *name = 0;
15397   hash_pair_t *p;
15398   unformat_input_t *i = vam->input;
15399   int j;
15400
15401   if (unformat (i, "%s", &name))
15402     {
15403       uword *hs;
15404
15405       vec_add1 (name, 0);
15406
15407       hs = hash_get_mem (vam->help_by_name, name);
15408       if (hs)
15409         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15410       else
15411         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15412       vec_free (name);
15413       return 0;
15414     }
15415
15416   fformat (vam->ofp, "Help is available for the following:\n");
15417
15418     /* *INDENT-OFF* */
15419     hash_foreach_pair (p, vam->function_by_name,
15420     ({
15421       vec_add1 (cmds, (u8 *)(p->key));
15422     }));
15423     /* *INDENT-ON* */
15424
15425   vec_sort_with_function (cmds, cmd_cmp);
15426
15427   for (j = 0; j < vec_len (cmds); j++)
15428     fformat (vam->ofp, "%s\n", cmds[j]);
15429
15430   vec_free (cmds);
15431   return 0;
15432 }
15433
15434 static int
15435 set (vat_main_t * vam)
15436 {
15437   u8 *name = 0, *value = 0;
15438   unformat_input_t *i = vam->input;
15439
15440   if (unformat (i, "%s", &name))
15441     {
15442       /* The input buffer is a vector, not a string. */
15443       value = vec_dup (i->buffer);
15444       vec_delete (value, i->index, 0);
15445       /* Almost certainly has a trailing newline */
15446       if (value[vec_len (value) - 1] == '\n')
15447         value[vec_len (value) - 1] = 0;
15448       /* Make sure it's a proper string, one way or the other */
15449       vec_add1 (value, 0);
15450       (void) clib_macro_set_value (&vam->macro_main,
15451                                    (char *) name, (char *) value);
15452     }
15453   else
15454     errmsg ("usage: set <name> <value>\n");
15455
15456   vec_free (name);
15457   vec_free (value);
15458   return 0;
15459 }
15460
15461 static int
15462 unset (vat_main_t * vam)
15463 {
15464   u8 *name = 0;
15465
15466   if (unformat (vam->input, "%s", &name))
15467     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15468       errmsg ("unset: %s wasn't set\n", name);
15469   vec_free (name);
15470   return 0;
15471 }
15472
15473 typedef struct
15474 {
15475   u8 *name;
15476   u8 *value;
15477 } macro_sort_t;
15478
15479
15480 static int
15481 macro_sort_cmp (void *a1, void *a2)
15482 {
15483   macro_sort_t *s1 = a1;
15484   macro_sort_t *s2 = a2;
15485
15486   return strcmp ((char *) (s1->name), (char *) (s2->name));
15487 }
15488
15489 static int
15490 dump_macro_table (vat_main_t * vam)
15491 {
15492   macro_sort_t *sort_me = 0, *sm;
15493   int i;
15494   hash_pair_t *p;
15495
15496     /* *INDENT-OFF* */
15497     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15498     ({
15499       vec_add2 (sort_me, sm, 1);
15500       sm->name = (u8 *)(p->key);
15501       sm->value = (u8 *) (p->value[0]);
15502     }));
15503     /* *INDENT-ON* */
15504
15505   vec_sort_with_function (sort_me, macro_sort_cmp);
15506
15507   if (vec_len (sort_me))
15508     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15509   else
15510     fformat (vam->ofp, "The macro table is empty...\n");
15511
15512   for (i = 0; i < vec_len (sort_me); i++)
15513     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15514   return 0;
15515 }
15516
15517 static int
15518 dump_node_table (vat_main_t * vam)
15519 {
15520   int i, j;
15521   vlib_node_t *node, *next_node;
15522
15523   if (vec_len (vam->graph_nodes) == 0)
15524     {
15525       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15526       return 0;
15527     }
15528
15529   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15530     {
15531       node = vam->graph_nodes[i];
15532       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15533       for (j = 0; j < vec_len (node->next_nodes); j++)
15534         {
15535           if (node->next_nodes[j] != ~0)
15536             {
15537               next_node = vam->graph_nodes[node->next_nodes[j]];
15538               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15539             }
15540         }
15541     }
15542   return 0;
15543 }
15544
15545 static int
15546 search_node_table (vat_main_t * vam)
15547 {
15548   unformat_input_t *line_input = vam->input;
15549   u8 *node_to_find;
15550   int j;
15551   vlib_node_t *node, *next_node;
15552   uword *p;
15553
15554   if (vam->graph_node_index_by_name == 0)
15555     {
15556       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15557       return 0;
15558     }
15559
15560   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15561     {
15562       if (unformat (line_input, "%s", &node_to_find))
15563         {
15564           vec_add1 (node_to_find, 0);
15565           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15566           if (p == 0)
15567             {
15568               fformat (vam->ofp, "%s not found...\n", node_to_find);
15569               goto out;
15570             }
15571           node = vam->graph_nodes[p[0]];
15572           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15573           for (j = 0; j < vec_len (node->next_nodes); j++)
15574             {
15575               if (node->next_nodes[j] != ~0)
15576                 {
15577                   next_node = vam->graph_nodes[node->next_nodes[j]];
15578                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15579                 }
15580             }
15581         }
15582
15583       else
15584         {
15585           clib_warning ("parse error '%U'", format_unformat_error,
15586                         line_input);
15587           return -99;
15588         }
15589
15590     out:
15591       vec_free (node_to_find);
15592
15593     }
15594
15595   return 0;
15596 }
15597
15598
15599 static int
15600 script (vat_main_t * vam)
15601 {
15602   u8 *s = 0;
15603   char *save_current_file;
15604   unformat_input_t save_input;
15605   jmp_buf save_jump_buf;
15606   u32 save_line_number;
15607
15608   FILE *new_fp, *save_ifp;
15609
15610   if (unformat (vam->input, "%s", &s))
15611     {
15612       new_fp = fopen ((char *) s, "r");
15613       if (new_fp == 0)
15614         {
15615           errmsg ("Couldn't open script file %s\n", s);
15616           vec_free (s);
15617           return -99;
15618         }
15619     }
15620   else
15621     {
15622       errmsg ("Missing script name\n");
15623       return -99;
15624     }
15625
15626   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15627   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15628   save_ifp = vam->ifp;
15629   save_line_number = vam->input_line_number;
15630   save_current_file = (char *) vam->current_file;
15631
15632   vam->input_line_number = 0;
15633   vam->ifp = new_fp;
15634   vam->current_file = s;
15635   do_one_file (vam);
15636
15637   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15638   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15639   vam->ifp = save_ifp;
15640   vam->input_line_number = save_line_number;
15641   vam->current_file = (u8 *) save_current_file;
15642   vec_free (s);
15643
15644   return 0;
15645 }
15646
15647 static int
15648 echo (vat_main_t * vam)
15649 {
15650   fformat (vam->ofp, "%v", vam->input->buffer);
15651   return 0;
15652 }
15653
15654 /* List of API message constructors, CLI names map to api_xxx */
15655 #define foreach_vpe_api_msg                                             \
15656 _(create_loopback,"[mac <mac-addr>]")                                   \
15657 _(sw_interface_dump,"")                                                 \
15658 _(sw_interface_set_flags,                                               \
15659   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15660 _(sw_interface_add_del_address,                                         \
15661   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15662 _(sw_interface_set_table,                                               \
15663   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15664 _(sw_interface_set_vpath,                                               \
15665   "<intfc> | sw_if_index <id> enable | disable")                        \
15666 _(sw_interface_set_l2_xconnect,                                         \
15667   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15668   "enable | disable")                                                   \
15669 _(sw_interface_set_l2_bridge,                                           \
15670   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15671   "[shg <split-horizon-group>] [bvi]\n"                                 \
15672   "enable | disable")                                                   \
15673 _(sw_interface_set_dpdk_hqos_pipe,                                      \
15674   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
15675   "profile <profile-id>\n")                                             \
15676 _(sw_interface_set_dpdk_hqos_subport,                                   \
15677   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
15678   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
15679 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
15680   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
15681 _(bridge_domain_add_del,                                                \
15682   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15683 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15684 _(l2fib_add_del,                                                        \
15685   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15686 _(l2_flags,                                                             \
15687   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15688 _(bridge_flags,                                                         \
15689   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15690 _(tap_connect,                                                          \
15691   "tapname <name> mac <mac-addr> | random-mac")                         \
15692 _(tap_modify,                                                           \
15693   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15694 _(tap_delete,                                                           \
15695   "<vpp-if-name> | sw_if_index <id>")                                   \
15696 _(sw_interface_tap_dump, "")                                            \
15697 _(ip_add_del_route,                                                     \
15698   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15699   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15700   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15701   "[multipath] [count <n>]")                                            \
15702 _(proxy_arp_add_del,                                                    \
15703   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15704 _(proxy_arp_intfc_enable_disable,                                       \
15705   "<intfc> | sw_if_index <id> enable | disable")                        \
15706 _(mpls_add_del_encap,                                                   \
15707   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15708 _(mpls_add_del_decap,                                                   \
15709   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15710 _(mpls_gre_add_del_tunnel,                                              \
15711   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15712   "adj <ip4-address>/<mask-width> [del]")                               \
15713 _(sw_interface_set_unnumbered,                                          \
15714   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15715 _(ip_neighbor_add_del,                                                  \
15716   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15717   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15718 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15719 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15720 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15721   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15722   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15723   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15724 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15725 _(reset_fib, "vrf <n> [ipv6]")                                          \
15726 _(dhcp_proxy_config,                                                    \
15727   "svr <v46-address> src <v46-address>\n"                               \
15728    "insert-cid <n> [del]")                                              \
15729 _(dhcp_proxy_config_2,                                                  \
15730   "svr <v46-address> src <v46-address>\n"                               \
15731    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15732 _(dhcp_proxy_set_vss,                                                   \
15733   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15734 _(dhcp_client_config,                                                   \
15735   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15736 _(set_ip_flow_hash,                                                     \
15737   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15738 _(sw_interface_ip6_enable_disable,                                      \
15739   "<intfc> | sw_if_index <id> enable | disable")                        \
15740 _(sw_interface_ip6_set_link_local_address,                              \
15741   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15742 _(sw_interface_ip6nd_ra_prefix,                                         \
15743   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15744   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15745   "[nolink] [isno]")                                                    \
15746 _(sw_interface_ip6nd_ra_config,                                         \
15747   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15748   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15749   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15750 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15751 _(l2_patch_add_del,                                                     \
15752   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15753   "enable | disable")                                                   \
15754 _(mpls_ethernet_add_del_tunnel,                                         \
15755   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15756   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15757 _(mpls_ethernet_add_del_tunnel_2,                                       \
15758   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15759   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15760 _(sr_tunnel_add_del,                                                    \
15761   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15762   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15763   "[policy <policy_name>]")                                             \
15764 _(sr_policy_add_del,                                                    \
15765   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15766 _(sr_multicast_map_add_del,                                             \
15767   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15768 _(classify_add_del_table,                                               \
15769   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15770   "[del] mask <mask-value>\n"                                           \
15771   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15772 _(classify_add_del_session,                                             \
15773   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15774   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15775   "  [l3 [ip4|ip6]]")                                                   \
15776 _(classify_set_interface_ip_table,                                      \
15777   "<intfc> | sw_if_index <nn> table <nn>")                              \
15778 _(classify_set_interface_l2_tables,                                     \
15779   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15780   "  [other-table <nn>]")                                               \
15781 _(get_node_index, "node <node-name")                                    \
15782 _(add_node_next, "node <node-name> next <next-node-name>")              \
15783 _(l2tpv3_create_tunnel,                                                 \
15784   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15785   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15786   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15787 _(l2tpv3_set_tunnel_cookies,                                            \
15788   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15789   "[new_remote_cookie <nn>]\n")                                         \
15790 _(l2tpv3_interface_enable_disable,                                      \
15791   "<intfc> | sw_if_index <nn> enable | disable")                        \
15792 _(l2tpv3_set_lookup_key,                                                \
15793   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15794 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15795 _(vxlan_add_del_tunnel,                                                 \
15796   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15797   " [decap-next l2|ip4|ip6] [del]")                                     \
15798 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15799 _(gre_add_del_tunnel,                                                   \
15800   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15801 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15802 _(l2_fib_clear_table, "")                                               \
15803 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15804 _(l2_interface_vlan_tag_rewrite,                                        \
15805   "<intfc> | sw_if_index <nn> \n"                                       \
15806   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15807   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15808 _(create_vhost_user_if,                                                 \
15809         "socket <filename> [server] [renumber <dev_instance>] "         \
15810         "[mac <mac_address>]")                                          \
15811 _(modify_vhost_user_if,                                                 \
15812         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15813         "[server] [renumber <dev_instance>]")                           \
15814 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15815 _(sw_interface_vhost_user_dump, "")                                     \
15816 _(show_version, "")                                                     \
15817 _(vxlan_gpe_add_del_tunnel,                                             \
15818   "local <addr> remote <addr> vni <nn>\n"                               \
15819     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15820   "[next-ethernet] [next-nsh]\n")                                       \
15821 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15822 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15823 _(interface_name_renumber,                                              \
15824   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15825 _(input_acl_set_interface,                                              \
15826   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15827   "  [l2-table <nn>] [del]")                                            \
15828 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15829 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15830 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15831 _(ip_dump, "ipv4 | ipv6")                                               \
15832 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15833 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15834   "  spid_id <n> ")                                                     \
15835 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15836   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15837   "  integ_alg <alg> integ_key <hex>")                                  \
15838 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15839   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15840   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15841   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15842 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15843 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15844 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15845   "(auth_data 0x<data> | auth_data <data>)")                            \
15846 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15847   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15848 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15849   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15850   "(local|remote)")                                                     \
15851 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15852 _(delete_loopback,"sw_if_index <nn>")                                   \
15853 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15854 _(map_add_domain,                                                       \
15855   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15856   "ip6-src <ip6addr> "                                                  \
15857   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15858 _(map_del_domain, "index <n>")                                          \
15859 _(map_add_del_rule,                                                     \
15860   "index <n> psid <n> dst <ip6addr> [del]")                             \
15861 _(map_domain_dump, "")                                                  \
15862 _(map_rule_dump, "index <map-domain>")                                  \
15863 _(want_interface_events,  "enable|disable")                             \
15864 _(want_stats,"enable|disable")                                          \
15865 _(get_first_msg_id, "client <name>")                                    \
15866 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15867 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15868   "fib-id <nn> [ip4][ip6][default]")                                    \
15869 _(get_node_graph, " ")                                                  \
15870 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15871 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15872 _(ioam_disable, "")                                                \
15873 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15874                             " sw_if_index <sw_if_index> p <priority> "  \
15875                             "w <weight>] [del]")                        \
15876 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15877                         "iface <intf> | sw_if_index <sw_if_index> "     \
15878                         "p <priority> w <weight> [del]")                \
15879 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15880                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15881                           "locator-set <locator_name> [del]")           \
15882 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15883   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15884 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15885 _(lisp_gpe_enable_disable, "enable|disable")                            \
15886 _(lisp_enable_disable, "enable|disable")                                \
15887 _(lisp_gpe_add_del_iface, "up|down")                                    \
15888 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15889                                "[seid <seid>] "                         \
15890                                "rloc <locator> p <prio> "               \
15891                                "w <weight> [rloc <loc> ... ] "          \
15892                                "action <action> [del-all]")             \
15893 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
15894                           "<local-eid>")                                \
15895 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15896 _(lisp_map_request_mode, "src-dst|dst-only")                            \
15897 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15898 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15899 _(lisp_locator_set_dump, "[local | remote]")                            \
15900 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15901 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15902                        "[local] | [remote]")                            \
15903 _(lisp_eid_table_vni_dump, "")                                          \
15904 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15905 _(lisp_gpe_tunnel_dump, "")                                             \
15906 _(lisp_map_resolver_dump, "")                                           \
15907 _(show_lisp_status, "")                                                 \
15908 _(lisp_get_map_request_itr_rlocs, "")                                   \
15909 _(show_lisp_pitr, "")                                                   \
15910 _(show_lisp_map_request_mode, "")                                       \
15911 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15912 _(af_packet_delete, "name <host interface name>")                       \
15913 _(policer_add_del, "name <policer name> <params> [del]")                \
15914 _(policer_dump, "[name <policer name>]")                                \
15915 _(policer_classify_set_interface,                                       \
15916   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15917   "  [l2-table <nn>] [del]")                                            \
15918 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15919 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15920     "[master|slave]")                                                   \
15921 _(netmap_delete, "name <interface name>")                               \
15922 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15923 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15924 _(mpls_fib_encap_dump, "")                                              \
15925 _(mpls_fib_decap_dump, "")                                              \
15926 _(classify_table_ids, "")                                               \
15927 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15928 _(classify_table_info, "table_id <nn>")                                 \
15929 _(classify_session_dump, "table_id <nn>")                               \
15930 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15931     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15932     "[template_interval <nn>] [udp_checksum]")                          \
15933 _(ipfix_exporter_dump, "")                                              \
15934 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15935 _(ipfix_classify_stream_dump, "")                                       \
15936 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15937 _(ipfix_classify_table_dump, "")                                        \
15938 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15939 _(pg_create_interface, "if_id <nn>")                                    \
15940 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15941 _(pg_enable_disable, "[stream <id>] disable")                           \
15942 _(ip_source_and_port_range_check_add_del,                               \
15943   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15944 _(ip_source_and_port_range_check_interface_add_del,                     \
15945   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15946   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15947 _(ipsec_gre_add_del_tunnel,                                             \
15948   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15949 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15950 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
15951 _(l2_interface_pbb_tag_rewrite,                                         \
15952   "<intfc> | sw_if_index <nn> \n"                                       \
15953   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
15954   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
15955 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")
15956
15957 /* List of command functions, CLI names map directly to functions */
15958 #define foreach_cli_function                                    \
15959 _(comment, "usage: comment <ignore-rest-of-line>")              \
15960 _(dump_interface_table, "usage: dump_interface_table")          \
15961 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15962 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15963 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15964 _(dump_stats_table, "usage: dump_stats_table")                  \
15965 _(dump_macro_table, "usage: dump_macro_table ")                 \
15966 _(dump_node_table, "usage: dump_node_table")                    \
15967 _(echo, "usage: echo <message>")                                \
15968 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15969 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15970 _(help, "usage: help")                                          \
15971 _(q, "usage: quit")                                             \
15972 _(quit, "usage: quit")                                          \
15973 _(search_node_table, "usage: search_node_table <name>...")      \
15974 _(set, "usage: set <variable-name> <value>")                    \
15975 _(script, "usage: script <file-name>")                          \
15976 _(unset, "usage: unset <variable-name>")
15977
15978 #define _(N,n)                                  \
15979     static void vl_api_##n##_t_handler_uni      \
15980     (vl_api_##n##_t * mp)                       \
15981     {                                           \
15982         vat_main_t * vam = &vat_main;           \
15983         if (vam->json_output) {                 \
15984             vl_api_##n##_t_handler_json(mp);    \
15985         } else {                                \
15986             vl_api_##n##_t_handler(mp);         \
15987         }                                       \
15988     }
15989 foreach_vpe_api_reply_msg;
15990 #undef _
15991
15992 void
15993 vat_api_hookup (vat_main_t * vam)
15994 {
15995 #define _(N,n)                                                  \
15996     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15997                            vl_api_##n##_t_handler_uni,          \
15998                            vl_noop_handler,                     \
15999                            vl_api_##n##_t_endian,               \
16000                            vl_api_##n##_t_print,                \
16001                            sizeof(vl_api_##n##_t), 1);
16002   foreach_vpe_api_reply_msg;
16003 #undef _
16004
16005   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16006
16007   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16008
16009   vam->function_by_name = hash_create_string (0, sizeof (uword));
16010
16011   vam->help_by_name = hash_create_string (0, sizeof (uword));
16012
16013   /* API messages we can send */
16014 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16015   foreach_vpe_api_msg;
16016 #undef _
16017
16018   /* Help strings */
16019 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16020   foreach_vpe_api_msg;
16021 #undef _
16022
16023   /* CLI functions */
16024 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16025   foreach_cli_function;
16026 #undef _
16027
16028   /* Help strings */
16029 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16030   foreach_cli_function;
16031 #undef _
16032 }
16033
16034 #undef vl_api_version
16035 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16036 #include <vpp-api/vpe.api.h>
16037 #undef vl_api_version
16038
16039 void
16040 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16041 {
16042   /*
16043    * Send the main API signature in slot 0. This bit of code must
16044    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16045    */
16046   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16047 }
16048
16049 /*
16050  * fd.io coding-style-patch-verification: ON
16051  *
16052  * Local Variables:
16053  * eval: (c-set-style "gnu")
16054  * End:
16055  */