FIB2.0: memory leaks during load-balance update (VPP-475)
[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     }
5833
5834   /* When testing multiple add/del ops, use a control-ping to sync */
5835   if (count > 1)
5836     {
5837       vl_api_control_ping_t *mp;
5838       f64 after;
5839
5840       /* Shut off async mode */
5841       vam->async_mode = 0;
5842
5843       M (CONTROL_PING, control_ping);
5844       S;
5845
5846       timeout = vat_time_now (vam) + 1.0;
5847       while (vat_time_now (vam) < timeout)
5848         if (vam->result_ready == 1)
5849           goto out;
5850       vam->retval = -99;
5851
5852     out:
5853       if (vam->retval == -99)
5854         errmsg ("timeout\n");
5855
5856       if (vam->async_errors > 0)
5857         {
5858           errmsg ("%d asynchronous errors\n", vam->async_errors);
5859           vam->retval = -98;
5860         }
5861       vam->async_errors = 0;
5862       after = vat_time_now (vam);
5863
5864       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5865                count, after - before, count / (after - before));
5866     }
5867   else
5868     {
5869       /* Wait for a reply... */
5870       W;
5871     }
5872
5873   /* Return the good/bad news */
5874   return (vam->retval);
5875 }
5876
5877 static int
5878 api_proxy_arp_add_del (vat_main_t * vam)
5879 {
5880   unformat_input_t *i = vam->input;
5881   vl_api_proxy_arp_add_del_t *mp;
5882   f64 timeout;
5883   u32 vrf_id = 0;
5884   u8 is_add = 1;
5885   ip4_address_t lo, hi;
5886   u8 range_set = 0;
5887
5888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5889     {
5890       if (unformat (i, "vrf %d", &vrf_id))
5891         ;
5892       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5893                          unformat_ip4_address, &hi))
5894         range_set = 1;
5895       else if (unformat (i, "del"))
5896         is_add = 0;
5897       else
5898         {
5899           clib_warning ("parse error '%U'", format_unformat_error, i);
5900           return -99;
5901         }
5902     }
5903
5904   if (range_set == 0)
5905     {
5906       errmsg ("address range not set\n");
5907       return -99;
5908     }
5909
5910   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5911
5912   mp->vrf_id = ntohl (vrf_id);
5913   mp->is_add = is_add;
5914   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5915   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5916
5917   S;
5918   W;
5919   /* NOTREACHED */
5920   return 0;
5921 }
5922
5923 static int
5924 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5928   f64 timeout;
5929   u32 sw_if_index;
5930   u8 enable = 1;
5931   u8 sw_if_index_set = 0;
5932
5933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5934     {
5935       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5936         sw_if_index_set = 1;
5937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5938         sw_if_index_set = 1;
5939       else if (unformat (i, "enable"))
5940         enable = 1;
5941       else if (unformat (i, "disable"))
5942         enable = 0;
5943       else
5944         {
5945           clib_warning ("parse error '%U'", format_unformat_error, i);
5946           return -99;
5947         }
5948     }
5949
5950   if (sw_if_index_set == 0)
5951     {
5952       errmsg ("missing interface name or sw_if_index\n");
5953       return -99;
5954     }
5955
5956   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5957
5958   mp->sw_if_index = ntohl (sw_if_index);
5959   mp->enable_disable = enable;
5960
5961   S;
5962   W;
5963   /* NOTREACHED */
5964   return 0;
5965 }
5966
5967 static int
5968 api_mpls_add_del_decap (vat_main_t * vam)
5969 {
5970   unformat_input_t *i = vam->input;
5971   vl_api_mpls_add_del_decap_t *mp;
5972   f64 timeout;
5973   u32 rx_vrf_id = 0;
5974   u32 tx_vrf_id = 0;
5975   u32 label = 0;
5976   u8 is_add = 1;
5977   u8 s_bit = 1;
5978   u32 next_index = 1;
5979
5980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5981     {
5982       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5983         ;
5984       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5985         ;
5986       else if (unformat (i, "label %d", &label))
5987         ;
5988       else if (unformat (i, "next-index %d", &next_index))
5989         ;
5990       else if (unformat (i, "del"))
5991         is_add = 0;
5992       else if (unformat (i, "s-bit-clear"))
5993         s_bit = 0;
5994       else
5995         {
5996           clib_warning ("parse error '%U'", format_unformat_error, i);
5997           return -99;
5998         }
5999     }
6000
6001   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
6002
6003   mp->rx_vrf_id = ntohl (rx_vrf_id);
6004   mp->tx_vrf_id = ntohl (tx_vrf_id);
6005   mp->label = ntohl (label);
6006   mp->next_index = ntohl (next_index);
6007   mp->s_bit = s_bit;
6008   mp->is_add = is_add;
6009
6010   S;
6011   W;
6012   /* NOTREACHED */
6013   return 0;
6014 }
6015
6016 static int
6017 api_mpls_add_del_encap (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_mpls_add_del_encap_t *mp;
6021   f64 timeout;
6022   u32 vrf_id = 0;
6023   u32 *labels = 0;
6024   u32 label;
6025   ip4_address_t dst_address;
6026   u8 is_add = 1;
6027
6028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6029     {
6030       if (unformat (i, "vrf %d", &vrf_id))
6031         ;
6032       else if (unformat (i, "label %d", &label))
6033         vec_add1 (labels, ntohl (label));
6034       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6035         ;
6036       else if (unformat (i, "del"))
6037         is_add = 0;
6038       else
6039         {
6040           clib_warning ("parse error '%U'", format_unformat_error, i);
6041           return -99;
6042         }
6043     }
6044
6045   if (vec_len (labels) == 0)
6046     {
6047       errmsg ("missing encap label stack\n");
6048       return -99;
6049     }
6050
6051   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6052       sizeof (u32) * vec_len (labels));
6053
6054   mp->vrf_id = ntohl (vrf_id);
6055   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6056   mp->is_add = is_add;
6057   mp->nlabels = vec_len (labels);
6058   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6059
6060   vec_free (labels);
6061
6062   S;
6063   W;
6064   /* NOTREACHED */
6065   return 0;
6066 }
6067
6068 static int
6069 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6070 {
6071   unformat_input_t *i = vam->input;
6072   vl_api_mpls_gre_add_del_tunnel_t *mp;
6073   f64 timeout;
6074   u32 inner_vrf_id = 0;
6075   u32 outer_vrf_id = 0;
6076   ip4_address_t src_address;
6077   ip4_address_t dst_address;
6078   ip4_address_t intfc_address;
6079   u32 tmp;
6080   u8 intfc_address_length = 0;
6081   u8 is_add = 1;
6082   u8 l2_only = 0;
6083
6084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6085     {
6086       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6087         ;
6088       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6089         ;
6090       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6091         ;
6092       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6093         ;
6094       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6095                          &intfc_address, &tmp))
6096         intfc_address_length = tmp;
6097       else if (unformat (i, "l2-only"))
6098         l2_only = 1;
6099       else if (unformat (i, "del"))
6100         is_add = 0;
6101       else
6102         {
6103           clib_warning ("parse error '%U'", format_unformat_error, i);
6104           return -99;
6105         }
6106     }
6107
6108   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6109
6110   mp->inner_vrf_id = ntohl (inner_vrf_id);
6111   mp->outer_vrf_id = ntohl (outer_vrf_id);
6112   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6113   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6114   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6115   mp->intfc_address_length = intfc_address_length;
6116   mp->l2_only = l2_only;
6117   mp->is_add = is_add;
6118
6119   S;
6120   W;
6121   /* NOTREACHED */
6122   return 0;
6123 }
6124
6125 static int
6126 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6127 {
6128   unformat_input_t *i = vam->input;
6129   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6130   f64 timeout;
6131   u32 inner_vrf_id = 0;
6132   ip4_address_t intfc_address;
6133   u8 dst_mac_address[6];
6134   int dst_set = 1;
6135   u32 tmp;
6136   u8 intfc_address_length = 0;
6137   u8 is_add = 1;
6138   u8 l2_only = 0;
6139   u32 tx_sw_if_index;
6140   int tx_sw_if_index_set = 0;
6141
6142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6143     {
6144       if (unformat (i, "vrf %d", &inner_vrf_id))
6145         ;
6146       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6147                          &intfc_address, &tmp))
6148         intfc_address_length = tmp;
6149       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6150         tx_sw_if_index_set = 1;
6151       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6152         tx_sw_if_index_set = 1;
6153       else if (unformat (i, "dst %U", unformat_ethernet_address,
6154                          dst_mac_address))
6155         dst_set = 1;
6156       else if (unformat (i, "l2-only"))
6157         l2_only = 1;
6158       else if (unformat (i, "del"))
6159         is_add = 0;
6160       else
6161         {
6162           clib_warning ("parse error '%U'", format_unformat_error, i);
6163           return -99;
6164         }
6165     }
6166
6167   if (!dst_set)
6168     {
6169       errmsg ("dst (mac address) not set\n");
6170       return -99;
6171     }
6172   if (!tx_sw_if_index_set)
6173     {
6174       errmsg ("tx-intfc not set\n");
6175       return -99;
6176     }
6177
6178   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6179
6180   mp->vrf_id = ntohl (inner_vrf_id);
6181   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6182   mp->adj_address_length = intfc_address_length;
6183   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6184                sizeof (dst_mac_address));
6185   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6186   mp->l2_only = l2_only;
6187   mp->is_add = is_add;
6188
6189   S;
6190   W;
6191   /* NOTREACHED */
6192   return 0;
6193 }
6194
6195 static int
6196 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6197 {
6198   unformat_input_t *i = vam->input;
6199   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6200   f64 timeout;
6201   u32 inner_vrf_id = 0;
6202   u32 outer_vrf_id = 0;
6203   ip4_address_t adj_address;
6204   int adj_address_set = 0;
6205   ip4_address_t next_hop_address;
6206   int next_hop_address_set = 0;
6207   u32 tmp;
6208   u8 adj_address_length = 0;
6209   u8 l2_only = 0;
6210   u8 is_add = 1;
6211   u32 resolve_attempts = 5;
6212   u8 resolve_if_needed = 1;
6213
6214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6215     {
6216       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6217         ;
6218       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6219         ;
6220       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6221                          &adj_address, &tmp))
6222         {
6223           adj_address_length = tmp;
6224           adj_address_set = 1;
6225         }
6226       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6227                          &next_hop_address))
6228         next_hop_address_set = 1;
6229       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6230         ;
6231       else if (unformat (i, "resolve-if-needed %d", &tmp))
6232         resolve_if_needed = tmp;
6233       else if (unformat (i, "l2-only"))
6234         l2_only = 1;
6235       else if (unformat (i, "del"))
6236         is_add = 0;
6237       else
6238         {
6239           clib_warning ("parse error '%U'", format_unformat_error, i);
6240           return -99;
6241         }
6242     }
6243
6244   if (!adj_address_set)
6245     {
6246       errmsg ("adjacency address/mask not set\n");
6247       return -99;
6248     }
6249   if (!next_hop_address_set)
6250     {
6251       errmsg ("ip4 next hop address (in outer fib) not set\n");
6252       return -99;
6253     }
6254
6255   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6256
6257   mp->inner_vrf_id = ntohl (inner_vrf_id);
6258   mp->outer_vrf_id = ntohl (outer_vrf_id);
6259   mp->resolve_attempts = ntohl (resolve_attempts);
6260   mp->resolve_if_needed = resolve_if_needed;
6261   mp->is_add = is_add;
6262   mp->l2_only = l2_only;
6263   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6264   mp->adj_address_length = adj_address_length;
6265   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6266                sizeof (next_hop_address));
6267
6268   S;
6269   W;
6270   /* NOTREACHED */
6271   return 0;
6272 }
6273
6274 static int
6275 api_sw_interface_set_unnumbered (vat_main_t * vam)
6276 {
6277   unformat_input_t *i = vam->input;
6278   vl_api_sw_interface_set_unnumbered_t *mp;
6279   f64 timeout;
6280   u32 sw_if_index;
6281   u32 unnum_sw_index = ~0;
6282   u8 is_add = 1;
6283   u8 sw_if_index_set = 0;
6284
6285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6286     {
6287       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6288         sw_if_index_set = 1;
6289       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6290         sw_if_index_set = 1;
6291       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6292         ;
6293       else if (unformat (i, "del"))
6294         is_add = 0;
6295       else
6296         {
6297           clib_warning ("parse error '%U'", format_unformat_error, i);
6298           return -99;
6299         }
6300     }
6301
6302   if (sw_if_index_set == 0)
6303     {
6304       errmsg ("missing interface name or sw_if_index\n");
6305       return -99;
6306     }
6307
6308   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6309
6310   mp->sw_if_index = ntohl (sw_if_index);
6311   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6312   mp->is_add = is_add;
6313
6314   S;
6315   W;
6316   /* NOTREACHED */
6317   return 0;
6318 }
6319
6320 static int
6321 api_ip_neighbor_add_del (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_ip_neighbor_add_del_t *mp;
6325   f64 timeout;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u32 vrf_id = 0;
6329   u8 is_add = 1;
6330   u8 is_static = 0;
6331   u8 mac_address[6];
6332   u8 mac_set = 0;
6333   u8 v4_address_set = 0;
6334   u8 v6_address_set = 0;
6335   ip4_address_t v4address;
6336   ip6_address_t v6address;
6337
6338   memset (mac_address, 0, sizeof (mac_address));
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6344         {
6345           mac_set = 1;
6346         }
6347       else if (unformat (i, "del"))
6348         is_add = 0;
6349       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6350         sw_if_index_set = 1;
6351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6352         sw_if_index_set = 1;
6353       else if (unformat (i, "is_static"))
6354         is_static = 1;
6355       else if (unformat (i, "vrf %d", &vrf_id))
6356         ;
6357       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6358         v4_address_set = 1;
6359       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6360         v6_address_set = 1;
6361       else
6362         {
6363           clib_warning ("parse error '%U'", format_unformat_error, i);
6364           return -99;
6365         }
6366     }
6367
6368   if (sw_if_index_set == 0)
6369     {
6370       errmsg ("missing interface name or sw_if_index\n");
6371       return -99;
6372     }
6373   if (v4_address_set && v6_address_set)
6374     {
6375       errmsg ("both v4 and v6 addresses set\n");
6376       return -99;
6377     }
6378   if (!v4_address_set && !v6_address_set)
6379     {
6380       errmsg ("no address set\n");
6381       return -99;
6382     }
6383
6384   /* Construct the API message */
6385   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6386
6387   mp->sw_if_index = ntohl (sw_if_index);
6388   mp->is_add = is_add;
6389   mp->vrf_id = ntohl (vrf_id);
6390   mp->is_static = is_static;
6391   if (mac_set)
6392     clib_memcpy (mp->mac_address, mac_address, 6);
6393   if (v6_address_set)
6394     {
6395       mp->is_ipv6 = 1;
6396       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6397     }
6398   else
6399     {
6400       /* mp->is_ipv6 = 0; via memset in M macro above */
6401       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6402     }
6403
6404   /* send it... */
6405   S;
6406
6407   /* Wait for a reply, return good/bad news  */
6408   W;
6409
6410   /* NOTREACHED */
6411   return 0;
6412 }
6413
6414 static int
6415 api_reset_vrf (vat_main_t * vam)
6416 {
6417   unformat_input_t *i = vam->input;
6418   vl_api_reset_vrf_t *mp;
6419   f64 timeout;
6420   u32 vrf_id = 0;
6421   u8 is_ipv6 = 0;
6422   u8 vrf_id_set = 0;
6423
6424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6425     {
6426       if (unformat (i, "vrf %d", &vrf_id))
6427         vrf_id_set = 1;
6428       else if (unformat (i, "ipv6"))
6429         is_ipv6 = 1;
6430       else
6431         {
6432           clib_warning ("parse error '%U'", format_unformat_error, i);
6433           return -99;
6434         }
6435     }
6436
6437   if (vrf_id_set == 0)
6438     {
6439       errmsg ("missing vrf id\n");
6440       return -99;
6441     }
6442
6443   M (RESET_VRF, reset_vrf);
6444
6445   mp->vrf_id = ntohl (vrf_id);
6446   mp->is_ipv6 = is_ipv6;
6447
6448   S;
6449   W;
6450   /* NOTREACHED */
6451   return 0;
6452 }
6453
6454 static int
6455 api_create_vlan_subif (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_create_vlan_subif_t *mp;
6459   f64 timeout;
6460   u32 sw_if_index;
6461   u8 sw_if_index_set = 0;
6462   u32 vlan_id;
6463   u8 vlan_id_set = 0;
6464
6465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6466     {
6467       if (unformat (i, "sw_if_index %d", &sw_if_index))
6468         sw_if_index_set = 1;
6469       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6470         sw_if_index_set = 1;
6471       else if (unformat (i, "vlan %d", &vlan_id))
6472         vlan_id_set = 1;
6473       else
6474         {
6475           clib_warning ("parse error '%U'", format_unformat_error, i);
6476           return -99;
6477         }
6478     }
6479
6480   if (sw_if_index_set == 0)
6481     {
6482       errmsg ("missing interface name or sw_if_index\n");
6483       return -99;
6484     }
6485
6486   if (vlan_id_set == 0)
6487     {
6488       errmsg ("missing vlan_id\n");
6489       return -99;
6490     }
6491   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6492
6493   mp->sw_if_index = ntohl (sw_if_index);
6494   mp->vlan_id = ntohl (vlan_id);
6495
6496   S;
6497   W;
6498   /* NOTREACHED */
6499   return 0;
6500 }
6501
6502 #define foreach_create_subif_bit                \
6503 _(no_tags)                                      \
6504 _(one_tag)                                      \
6505 _(two_tags)                                     \
6506 _(dot1ad)                                       \
6507 _(exact_match)                                  \
6508 _(default_sub)                                  \
6509 _(outer_vlan_id_any)                            \
6510 _(inner_vlan_id_any)
6511
6512 static int
6513 api_create_subif (vat_main_t * vam)
6514 {
6515   unformat_input_t *i = vam->input;
6516   vl_api_create_subif_t *mp;
6517   f64 timeout;
6518   u32 sw_if_index;
6519   u8 sw_if_index_set = 0;
6520   u32 sub_id;
6521   u8 sub_id_set = 0;
6522   u32 no_tags = 0;
6523   u32 one_tag = 0;
6524   u32 two_tags = 0;
6525   u32 dot1ad = 0;
6526   u32 exact_match = 0;
6527   u32 default_sub = 0;
6528   u32 outer_vlan_id_any = 0;
6529   u32 inner_vlan_id_any = 0;
6530   u32 tmp;
6531   u16 outer_vlan_id = 0;
6532   u16 inner_vlan_id = 0;
6533
6534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6535     {
6536       if (unformat (i, "sw_if_index %d", &sw_if_index))
6537         sw_if_index_set = 1;
6538       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "sub_id %d", &sub_id))
6541         sub_id_set = 1;
6542       else if (unformat (i, "outer_vlan_id %d", &tmp))
6543         outer_vlan_id = tmp;
6544       else if (unformat (i, "inner_vlan_id %d", &tmp))
6545         inner_vlan_id = tmp;
6546
6547 #define _(a) else if (unformat (i, #a)) a = 1 ;
6548       foreach_create_subif_bit
6549 #undef _
6550         else
6551         {
6552           clib_warning ("parse error '%U'", format_unformat_error, i);
6553           return -99;
6554         }
6555     }
6556
6557   if (sw_if_index_set == 0)
6558     {
6559       errmsg ("missing interface name or sw_if_index\n");
6560       return -99;
6561     }
6562
6563   if (sub_id_set == 0)
6564     {
6565       errmsg ("missing sub_id\n");
6566       return -99;
6567     }
6568   M (CREATE_SUBIF, create_subif);
6569
6570   mp->sw_if_index = ntohl (sw_if_index);
6571   mp->sub_id = ntohl (sub_id);
6572
6573 #define _(a) mp->a = a;
6574   foreach_create_subif_bit;
6575 #undef _
6576
6577   mp->outer_vlan_id = ntohs (outer_vlan_id);
6578   mp->inner_vlan_id = ntohs (inner_vlan_id);
6579
6580   S;
6581   W;
6582   /* NOTREACHED */
6583   return 0;
6584 }
6585
6586 static int
6587 api_oam_add_del (vat_main_t * vam)
6588 {
6589   unformat_input_t *i = vam->input;
6590   vl_api_oam_add_del_t *mp;
6591   f64 timeout;
6592   u32 vrf_id = 0;
6593   u8 is_add = 1;
6594   ip4_address_t src, dst;
6595   u8 src_set = 0;
6596   u8 dst_set = 0;
6597
6598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599     {
6600       if (unformat (i, "vrf %d", &vrf_id))
6601         ;
6602       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6603         src_set = 1;
6604       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6605         dst_set = 1;
6606       else if (unformat (i, "del"))
6607         is_add = 0;
6608       else
6609         {
6610           clib_warning ("parse error '%U'", format_unformat_error, i);
6611           return -99;
6612         }
6613     }
6614
6615   if (src_set == 0)
6616     {
6617       errmsg ("missing src addr\n");
6618       return -99;
6619     }
6620
6621   if (dst_set == 0)
6622     {
6623       errmsg ("missing dst addr\n");
6624       return -99;
6625     }
6626
6627   M (OAM_ADD_DEL, oam_add_del);
6628
6629   mp->vrf_id = ntohl (vrf_id);
6630   mp->is_add = is_add;
6631   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6632   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6633
6634   S;
6635   W;
6636   /* NOTREACHED */
6637   return 0;
6638 }
6639
6640 static int
6641 api_reset_fib (vat_main_t * vam)
6642 {
6643   unformat_input_t *i = vam->input;
6644   vl_api_reset_fib_t *mp;
6645   f64 timeout;
6646   u32 vrf_id = 0;
6647   u8 is_ipv6 = 0;
6648   u8 vrf_id_set = 0;
6649
6650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651     {
6652       if (unformat (i, "vrf %d", &vrf_id))
6653         vrf_id_set = 1;
6654       else if (unformat (i, "ipv6"))
6655         is_ipv6 = 1;
6656       else
6657         {
6658           clib_warning ("parse error '%U'", format_unformat_error, i);
6659           return -99;
6660         }
6661     }
6662
6663   if (vrf_id_set == 0)
6664     {
6665       errmsg ("missing vrf id\n");
6666       return -99;
6667     }
6668
6669   M (RESET_FIB, reset_fib);
6670
6671   mp->vrf_id = ntohl (vrf_id);
6672   mp->is_ipv6 = is_ipv6;
6673
6674   S;
6675   W;
6676   /* NOTREACHED */
6677   return 0;
6678 }
6679
6680 static int
6681 api_dhcp_proxy_config (vat_main_t * vam)
6682 {
6683   unformat_input_t *i = vam->input;
6684   vl_api_dhcp_proxy_config_t *mp;
6685   f64 timeout;
6686   u32 vrf_id = 0;
6687   u8 is_add = 1;
6688   u8 insert_cid = 1;
6689   u8 v4_address_set = 0;
6690   u8 v6_address_set = 0;
6691   ip4_address_t v4address;
6692   ip6_address_t v6address;
6693   u8 v4_src_address_set = 0;
6694   u8 v6_src_address_set = 0;
6695   ip4_address_t v4srcaddress;
6696   ip6_address_t v6srcaddress;
6697
6698   /* Parse args required to build the message */
6699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6700     {
6701       if (unformat (i, "del"))
6702         is_add = 0;
6703       else if (unformat (i, "vrf %d", &vrf_id))
6704         ;
6705       else if (unformat (i, "insert-cid %d", &insert_cid))
6706         ;
6707       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6708         v4_address_set = 1;
6709       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6710         v6_address_set = 1;
6711       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6712         v4_src_address_set = 1;
6713       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6714         v6_src_address_set = 1;
6715       else
6716         break;
6717     }
6718
6719   if (v4_address_set && v6_address_set)
6720     {
6721       errmsg ("both v4 and v6 server addresses set\n");
6722       return -99;
6723     }
6724   if (!v4_address_set && !v6_address_set)
6725     {
6726       errmsg ("no server addresses set\n");
6727       return -99;
6728     }
6729
6730   if (v4_src_address_set && v6_src_address_set)
6731     {
6732       errmsg ("both v4 and v6  src addresses set\n");
6733       return -99;
6734     }
6735   if (!v4_src_address_set && !v6_src_address_set)
6736     {
6737       errmsg ("no src addresses set\n");
6738       return -99;
6739     }
6740
6741   if (!(v4_src_address_set && v4_address_set) &&
6742       !(v6_src_address_set && v6_address_set))
6743     {
6744       errmsg ("no matching server and src addresses set\n");
6745       return -99;
6746     }
6747
6748   /* Construct the API message */
6749   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6750
6751   mp->insert_circuit_id = insert_cid;
6752   mp->is_add = is_add;
6753   mp->vrf_id = ntohl (vrf_id);
6754   if (v6_address_set)
6755     {
6756       mp->is_ipv6 = 1;
6757       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6758       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6759     }
6760   else
6761     {
6762       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6763       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6764     }
6765
6766   /* send it... */
6767   S;
6768
6769   /* Wait for a reply, return good/bad news  */
6770   W;
6771   /* NOTREACHED */
6772   return 0;
6773 }
6774
6775 static int
6776 api_dhcp_proxy_config_2 (vat_main_t * vam)
6777 {
6778   unformat_input_t *i = vam->input;
6779   vl_api_dhcp_proxy_config_2_t *mp;
6780   f64 timeout;
6781   u32 rx_vrf_id = 0;
6782   u32 server_vrf_id = 0;
6783   u8 is_add = 1;
6784   u8 insert_cid = 1;
6785   u8 v4_address_set = 0;
6786   u8 v6_address_set = 0;
6787   ip4_address_t v4address;
6788   ip6_address_t v6address;
6789   u8 v4_src_address_set = 0;
6790   u8 v6_src_address_set = 0;
6791   ip4_address_t v4srcaddress;
6792   ip6_address_t v6srcaddress;
6793
6794   /* Parse args required to build the message */
6795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6796     {
6797       if (unformat (i, "del"))
6798         is_add = 0;
6799       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6800         ;
6801       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6802         ;
6803       else if (unformat (i, "insert-cid %d", &insert_cid))
6804         ;
6805       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6806         v4_address_set = 1;
6807       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6808         v6_address_set = 1;
6809       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6810         v4_src_address_set = 1;
6811       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6812         v6_src_address_set = 1;
6813       else
6814         break;
6815     }
6816
6817   if (v4_address_set && v6_address_set)
6818     {
6819       errmsg ("both v4 and v6 server addresses set\n");
6820       return -99;
6821     }
6822   if (!v4_address_set && !v6_address_set)
6823     {
6824       errmsg ("no server addresses set\n");
6825       return -99;
6826     }
6827
6828   if (v4_src_address_set && v6_src_address_set)
6829     {
6830       errmsg ("both v4 and v6  src addresses set\n");
6831       return -99;
6832     }
6833   if (!v4_src_address_set && !v6_src_address_set)
6834     {
6835       errmsg ("no src addresses set\n");
6836       return -99;
6837     }
6838
6839   if (!(v4_src_address_set && v4_address_set) &&
6840       !(v6_src_address_set && v6_address_set))
6841     {
6842       errmsg ("no matching server and src addresses set\n");
6843       return -99;
6844     }
6845
6846   /* Construct the API message */
6847   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6848
6849   mp->insert_circuit_id = insert_cid;
6850   mp->is_add = is_add;
6851   mp->rx_vrf_id = ntohl (rx_vrf_id);
6852   mp->server_vrf_id = ntohl (server_vrf_id);
6853   if (v6_address_set)
6854     {
6855       mp->is_ipv6 = 1;
6856       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6857       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6858     }
6859   else
6860     {
6861       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6862       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6863     }
6864
6865   /* send it... */
6866   S;
6867
6868   /* Wait for a reply, return good/bad news  */
6869   W;
6870   /* NOTREACHED */
6871   return 0;
6872 }
6873
6874 static int
6875 api_dhcp_proxy_set_vss (vat_main_t * vam)
6876 {
6877   unformat_input_t *i = vam->input;
6878   vl_api_dhcp_proxy_set_vss_t *mp;
6879   f64 timeout;
6880   u8 is_ipv6 = 0;
6881   u8 is_add = 1;
6882   u32 tbl_id;
6883   u8 tbl_id_set = 0;
6884   u32 oui;
6885   u8 oui_set = 0;
6886   u32 fib_id;
6887   u8 fib_id_set = 0;
6888
6889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6890     {
6891       if (unformat (i, "tbl_id %d", &tbl_id))
6892         tbl_id_set = 1;
6893       if (unformat (i, "fib_id %d", &fib_id))
6894         fib_id_set = 1;
6895       if (unformat (i, "oui %d", &oui))
6896         oui_set = 1;
6897       else if (unformat (i, "ipv6"))
6898         is_ipv6 = 1;
6899       else if (unformat (i, "del"))
6900         is_add = 0;
6901       else
6902         {
6903           clib_warning ("parse error '%U'", format_unformat_error, i);
6904           return -99;
6905         }
6906     }
6907
6908   if (tbl_id_set == 0)
6909     {
6910       errmsg ("missing tbl id\n");
6911       return -99;
6912     }
6913
6914   if (fib_id_set == 0)
6915     {
6916       errmsg ("missing fib id\n");
6917       return -99;
6918     }
6919   if (oui_set == 0)
6920     {
6921       errmsg ("missing oui\n");
6922       return -99;
6923     }
6924
6925   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6926   mp->tbl_id = ntohl (tbl_id);
6927   mp->fib_id = ntohl (fib_id);
6928   mp->oui = ntohl (oui);
6929   mp->is_ipv6 = is_ipv6;
6930   mp->is_add = is_add;
6931
6932   S;
6933   W;
6934   /* NOTREACHED */
6935   return 0;
6936 }
6937
6938 static int
6939 api_dhcp_client_config (vat_main_t * vam)
6940 {
6941   unformat_input_t *i = vam->input;
6942   vl_api_dhcp_client_config_t *mp;
6943   f64 timeout;
6944   u32 sw_if_index;
6945   u8 sw_if_index_set = 0;
6946   u8 is_add = 1;
6947   u8 *hostname = 0;
6948   u8 disable_event = 0;
6949
6950   /* Parse args required to build the message */
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "del"))
6954         is_add = 0;
6955       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6956         sw_if_index_set = 1;
6957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6958         sw_if_index_set = 1;
6959       else if (unformat (i, "hostname %s", &hostname))
6960         ;
6961       else if (unformat (i, "disable_event"))
6962         disable_event = 1;
6963       else
6964         break;
6965     }
6966
6967   if (sw_if_index_set == 0)
6968     {
6969       errmsg ("missing interface name or sw_if_index\n");
6970       return -99;
6971     }
6972
6973   if (vec_len (hostname) > 63)
6974     {
6975       errmsg ("hostname too long\n");
6976     }
6977   vec_add1 (hostname, 0);
6978
6979   /* Construct the API message */
6980   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6981
6982   mp->sw_if_index = ntohl (sw_if_index);
6983   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6984   vec_free (hostname);
6985   mp->is_add = is_add;
6986   mp->want_dhcp_event = disable_event ? 0 : 1;
6987   mp->pid = getpid ();
6988
6989   /* send it... */
6990   S;
6991
6992   /* Wait for a reply, return good/bad news  */
6993   W;
6994   /* NOTREACHED */
6995   return 0;
6996 }
6997
6998 static int
6999 api_set_ip_flow_hash (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_set_ip_flow_hash_t *mp;
7003   f64 timeout;
7004   u32 vrf_id = 0;
7005   u8 is_ipv6 = 0;
7006   u8 vrf_id_set = 0;
7007   u8 src = 0;
7008   u8 dst = 0;
7009   u8 sport = 0;
7010   u8 dport = 0;
7011   u8 proto = 0;
7012   u8 reverse = 0;
7013
7014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7015     {
7016       if (unformat (i, "vrf %d", &vrf_id))
7017         vrf_id_set = 1;
7018       else if (unformat (i, "ipv6"))
7019         is_ipv6 = 1;
7020       else if (unformat (i, "src"))
7021         src = 1;
7022       else if (unformat (i, "dst"))
7023         dst = 1;
7024       else if (unformat (i, "sport"))
7025         sport = 1;
7026       else if (unformat (i, "dport"))
7027         dport = 1;
7028       else if (unformat (i, "proto"))
7029         proto = 1;
7030       else if (unformat (i, "reverse"))
7031         reverse = 1;
7032
7033       else
7034         {
7035           clib_warning ("parse error '%U'", format_unformat_error, i);
7036           return -99;
7037         }
7038     }
7039
7040   if (vrf_id_set == 0)
7041     {
7042       errmsg ("missing vrf id\n");
7043       return -99;
7044     }
7045
7046   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7047   mp->src = src;
7048   mp->dst = dst;
7049   mp->sport = sport;
7050   mp->dport = dport;
7051   mp->proto = proto;
7052   mp->reverse = reverse;
7053   mp->vrf_id = ntohl (vrf_id);
7054   mp->is_ipv6 = is_ipv6;
7055
7056   S;
7057   W;
7058   /* NOTREACHED */
7059   return 0;
7060 }
7061
7062 static int
7063 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7064 {
7065   unformat_input_t *i = vam->input;
7066   vl_api_sw_interface_ip6_enable_disable_t *mp;
7067   f64 timeout;
7068   u32 sw_if_index;
7069   u8 sw_if_index_set = 0;
7070   u8 enable = 0;
7071
7072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7073     {
7074       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7075         sw_if_index_set = 1;
7076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7077         sw_if_index_set = 1;
7078       else if (unformat (i, "enable"))
7079         enable = 1;
7080       else if (unformat (i, "disable"))
7081         enable = 0;
7082       else
7083         {
7084           clib_warning ("parse error '%U'", format_unformat_error, i);
7085           return -99;
7086         }
7087     }
7088
7089   if (sw_if_index_set == 0)
7090     {
7091       errmsg ("missing interface name or sw_if_index\n");
7092       return -99;
7093     }
7094
7095   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7096
7097   mp->sw_if_index = ntohl (sw_if_index);
7098   mp->enable = enable;
7099
7100   S;
7101   W;
7102   /* NOTREACHED */
7103   return 0;
7104 }
7105
7106 static int
7107 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7108 {
7109   unformat_input_t *i = vam->input;
7110   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7111   f64 timeout;
7112   u32 sw_if_index;
7113   u8 sw_if_index_set = 0;
7114   u32 address_length = 0;
7115   u8 v6_address_set = 0;
7116   ip6_address_t v6address;
7117
7118   /* Parse args required to build the message */
7119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7120     {
7121       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7122         sw_if_index_set = 1;
7123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7124         sw_if_index_set = 1;
7125       else if (unformat (i, "%U/%d",
7126                          unformat_ip6_address, &v6address, &address_length))
7127         v6_address_set = 1;
7128       else
7129         break;
7130     }
7131
7132   if (sw_if_index_set == 0)
7133     {
7134       errmsg ("missing interface name or sw_if_index\n");
7135       return -99;
7136     }
7137   if (!v6_address_set)
7138     {
7139       errmsg ("no address set\n");
7140       return -99;
7141     }
7142
7143   /* Construct the API message */
7144   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7145      sw_interface_ip6_set_link_local_address);
7146
7147   mp->sw_if_index = ntohl (sw_if_index);
7148   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7149   mp->address_length = address_length;
7150
7151   /* send it... */
7152   S;
7153
7154   /* Wait for a reply, return good/bad news  */
7155   W;
7156
7157   /* NOTREACHED */
7158   return 0;
7159 }
7160
7161
7162 static int
7163 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7164 {
7165   unformat_input_t *i = vam->input;
7166   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7167   f64 timeout;
7168   u32 sw_if_index;
7169   u8 sw_if_index_set = 0;
7170   u32 address_length = 0;
7171   u8 v6_address_set = 0;
7172   ip6_address_t v6address;
7173   u8 use_default = 0;
7174   u8 no_advertise = 0;
7175   u8 off_link = 0;
7176   u8 no_autoconfig = 0;
7177   u8 no_onlink = 0;
7178   u8 is_no = 0;
7179   u32 val_lifetime = 0;
7180   u32 pref_lifetime = 0;
7181
7182   /* Parse args required to build the message */
7183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7186         sw_if_index_set = 1;
7187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7188         sw_if_index_set = 1;
7189       else if (unformat (i, "%U/%d",
7190                          unformat_ip6_address, &v6address, &address_length))
7191         v6_address_set = 1;
7192       else if (unformat (i, "val_life %d", &val_lifetime))
7193         ;
7194       else if (unformat (i, "pref_life %d", &pref_lifetime))
7195         ;
7196       else if (unformat (i, "def"))
7197         use_default = 1;
7198       else if (unformat (i, "noadv"))
7199         no_advertise = 1;
7200       else if (unformat (i, "offl"))
7201         off_link = 1;
7202       else if (unformat (i, "noauto"))
7203         no_autoconfig = 1;
7204       else if (unformat (i, "nolink"))
7205         no_onlink = 1;
7206       else if (unformat (i, "isno"))
7207         is_no = 1;
7208       else
7209         {
7210           clib_warning ("parse error '%U'", format_unformat_error, i);
7211           return -99;
7212         }
7213     }
7214
7215   if (sw_if_index_set == 0)
7216     {
7217       errmsg ("missing interface name or sw_if_index\n");
7218       return -99;
7219     }
7220   if (!v6_address_set)
7221     {
7222       errmsg ("no address set\n");
7223       return -99;
7224     }
7225
7226   /* Construct the API message */
7227   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7228
7229   mp->sw_if_index = ntohl (sw_if_index);
7230   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7231   mp->address_length = address_length;
7232   mp->use_default = use_default;
7233   mp->no_advertise = no_advertise;
7234   mp->off_link = off_link;
7235   mp->no_autoconfig = no_autoconfig;
7236   mp->no_onlink = no_onlink;
7237   mp->is_no = is_no;
7238   mp->val_lifetime = ntohl (val_lifetime);
7239   mp->pref_lifetime = ntohl (pref_lifetime);
7240
7241   /* send it... */
7242   S;
7243
7244   /* Wait for a reply, return good/bad news  */
7245   W;
7246
7247   /* NOTREACHED */
7248   return 0;
7249 }
7250
7251 static int
7252 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7253 {
7254   unformat_input_t *i = vam->input;
7255   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7256   f64 timeout;
7257   u32 sw_if_index;
7258   u8 sw_if_index_set = 0;
7259   u8 suppress = 0;
7260   u8 managed = 0;
7261   u8 other = 0;
7262   u8 ll_option = 0;
7263   u8 send_unicast = 0;
7264   u8 cease = 0;
7265   u8 is_no = 0;
7266   u8 default_router = 0;
7267   u32 max_interval = 0;
7268   u32 min_interval = 0;
7269   u32 lifetime = 0;
7270   u32 initial_count = 0;
7271   u32 initial_interval = 0;
7272
7273
7274   /* Parse args required to build the message */
7275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7276     {
7277       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7278         sw_if_index_set = 1;
7279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7280         sw_if_index_set = 1;
7281       else if (unformat (i, "maxint %d", &max_interval))
7282         ;
7283       else if (unformat (i, "minint %d", &min_interval))
7284         ;
7285       else if (unformat (i, "life %d", &lifetime))
7286         ;
7287       else if (unformat (i, "count %d", &initial_count))
7288         ;
7289       else if (unformat (i, "interval %d", &initial_interval))
7290         ;
7291       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7292         suppress = 1;
7293       else if (unformat (i, "managed"))
7294         managed = 1;
7295       else if (unformat (i, "other"))
7296         other = 1;
7297       else if (unformat (i, "ll"))
7298         ll_option = 1;
7299       else if (unformat (i, "send"))
7300         send_unicast = 1;
7301       else if (unformat (i, "cease"))
7302         cease = 1;
7303       else if (unformat (i, "isno"))
7304         is_no = 1;
7305       else if (unformat (i, "def"))
7306         default_router = 1;
7307       else
7308         {
7309           clib_warning ("parse error '%U'", format_unformat_error, i);
7310           return -99;
7311         }
7312     }
7313
7314   if (sw_if_index_set == 0)
7315     {
7316       errmsg ("missing interface name or sw_if_index\n");
7317       return -99;
7318     }
7319
7320   /* Construct the API message */
7321   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7322
7323   mp->sw_if_index = ntohl (sw_if_index);
7324   mp->max_interval = ntohl (max_interval);
7325   mp->min_interval = ntohl (min_interval);
7326   mp->lifetime = ntohl (lifetime);
7327   mp->initial_count = ntohl (initial_count);
7328   mp->initial_interval = ntohl (initial_interval);
7329   mp->suppress = suppress;
7330   mp->managed = managed;
7331   mp->other = other;
7332   mp->ll_option = ll_option;
7333   mp->send_unicast = send_unicast;
7334   mp->cease = cease;
7335   mp->is_no = is_no;
7336   mp->default_router = default_router;
7337
7338   /* send it... */
7339   S;
7340
7341   /* Wait for a reply, return good/bad news  */
7342   W;
7343
7344   /* NOTREACHED */
7345   return 0;
7346 }
7347
7348 static int
7349 api_set_arp_neighbor_limit (vat_main_t * vam)
7350 {
7351   unformat_input_t *i = vam->input;
7352   vl_api_set_arp_neighbor_limit_t *mp;
7353   f64 timeout;
7354   u32 arp_nbr_limit;
7355   u8 limit_set = 0;
7356   u8 is_ipv6 = 0;
7357
7358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7359     {
7360       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7361         limit_set = 1;
7362       else if (unformat (i, "ipv6"))
7363         is_ipv6 = 1;
7364       else
7365         {
7366           clib_warning ("parse error '%U'", format_unformat_error, i);
7367           return -99;
7368         }
7369     }
7370
7371   if (limit_set == 0)
7372     {
7373       errmsg ("missing limit value\n");
7374       return -99;
7375     }
7376
7377   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7378
7379   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7380   mp->is_ipv6 = is_ipv6;
7381
7382   S;
7383   W;
7384   /* NOTREACHED */
7385   return 0;
7386 }
7387
7388 static int
7389 api_l2_patch_add_del (vat_main_t * vam)
7390 {
7391   unformat_input_t *i = vam->input;
7392   vl_api_l2_patch_add_del_t *mp;
7393   f64 timeout;
7394   u32 rx_sw_if_index;
7395   u8 rx_sw_if_index_set = 0;
7396   u32 tx_sw_if_index;
7397   u8 tx_sw_if_index_set = 0;
7398   u8 is_add = 1;
7399
7400   /* Parse args required to build the message */
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7404         rx_sw_if_index_set = 1;
7405       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7406         tx_sw_if_index_set = 1;
7407       else if (unformat (i, "rx"))
7408         {
7409           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7410             {
7411               if (unformat (i, "%U", unformat_sw_if_index, vam,
7412                             &rx_sw_if_index))
7413                 rx_sw_if_index_set = 1;
7414             }
7415           else
7416             break;
7417         }
7418       else if (unformat (i, "tx"))
7419         {
7420           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7421             {
7422               if (unformat (i, "%U", unformat_sw_if_index, vam,
7423                             &tx_sw_if_index))
7424                 tx_sw_if_index_set = 1;
7425             }
7426           else
7427             break;
7428         }
7429       else if (unformat (i, "del"))
7430         is_add = 0;
7431       else
7432         break;
7433     }
7434
7435   if (rx_sw_if_index_set == 0)
7436     {
7437       errmsg ("missing rx interface name or rx_sw_if_index\n");
7438       return -99;
7439     }
7440
7441   if (tx_sw_if_index_set == 0)
7442     {
7443       errmsg ("missing tx interface name or tx_sw_if_index\n");
7444       return -99;
7445     }
7446
7447   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7448
7449   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7450   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7451   mp->is_add = is_add;
7452
7453   S;
7454   W;
7455   /* NOTREACHED */
7456   return 0;
7457 }
7458
7459 static int
7460 api_ioam_enable (vat_main_t * vam)
7461 {
7462   unformat_input_t *input = vam->input;
7463   vl_api_ioam_enable_t *mp;
7464   f64 timeout;
7465   u32 id = 0;
7466   int has_trace_option = 0;
7467   int has_pow_option = 0;
7468   int has_ppc_option = 0;
7469
7470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7471     {
7472       if (unformat (input, "trace"))
7473         has_trace_option = 1;
7474       else if (unformat (input, "pow"))
7475         has_pow_option = 1;
7476       else if (unformat (input, "ppc encap"))
7477         has_ppc_option = PPC_ENCAP;
7478       else if (unformat (input, "ppc decap"))
7479         has_ppc_option = PPC_DECAP;
7480       else if (unformat (input, "ppc none"))
7481         has_ppc_option = PPC_NONE;
7482       else
7483         break;
7484     }
7485   M (IOAM_ENABLE, ioam_enable);
7486   mp->id = htons (id);
7487   mp->trace_ppc = has_ppc_option;
7488   mp->pow_enable = has_pow_option;
7489   mp->trace_enable = has_trace_option;
7490
7491   S;
7492   W;
7493
7494   return (0);
7495
7496 }
7497
7498
7499 static int
7500 api_ioam_disable (vat_main_t * vam)
7501 {
7502   vl_api_ioam_disable_t *mp;
7503   f64 timeout;
7504
7505   M (IOAM_DISABLE, ioam_disable);
7506   S;
7507   W;
7508   return 0;
7509 }
7510
7511 static int
7512 api_sr_tunnel_add_del (vat_main_t * vam)
7513 {
7514   unformat_input_t *i = vam->input;
7515   vl_api_sr_tunnel_add_del_t *mp;
7516   f64 timeout;
7517   int is_del = 0;
7518   int pl_index;
7519   ip6_address_t src_address;
7520   int src_address_set = 0;
7521   ip6_address_t dst_address;
7522   u32 dst_mask_width;
7523   int dst_address_set = 0;
7524   u16 flags = 0;
7525   u32 rx_table_id = 0;
7526   u32 tx_table_id = 0;
7527   ip6_address_t *segments = 0;
7528   ip6_address_t *this_seg;
7529   ip6_address_t *tags = 0;
7530   ip6_address_t *this_tag;
7531   ip6_address_t next_address, tag;
7532   u8 *name = 0;
7533   u8 *policy_name = 0;
7534
7535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7536     {
7537       if (unformat (i, "del"))
7538         is_del = 1;
7539       else if (unformat (i, "name %s", &name))
7540         ;
7541       else if (unformat (i, "policy %s", &policy_name))
7542         ;
7543       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7544         ;
7545       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7546         ;
7547       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7548         src_address_set = 1;
7549       else if (unformat (i, "dst %U/%d",
7550                          unformat_ip6_address, &dst_address, &dst_mask_width))
7551         dst_address_set = 1;
7552       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7553         {
7554           vec_add2 (segments, this_seg, 1);
7555           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7556                        sizeof (*this_seg));
7557         }
7558       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7559         {
7560           vec_add2 (tags, this_tag, 1);
7561           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7562         }
7563       else if (unformat (i, "clean"))
7564         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7565       else if (unformat (i, "protected"))
7566         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7567       else if (unformat (i, "InPE %d", &pl_index))
7568         {
7569           if (pl_index <= 0 || pl_index > 4)
7570             {
7571             pl_index_range_error:
7572               errmsg ("pl index %d out of range\n", pl_index);
7573               return -99;
7574             }
7575           flags |=
7576             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7577         }
7578       else if (unformat (i, "EgPE %d", &pl_index))
7579         {
7580           if (pl_index <= 0 || pl_index > 4)
7581             goto pl_index_range_error;
7582           flags |=
7583             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7584         }
7585       else if (unformat (i, "OrgSrc %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_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7591         }
7592       else
7593         break;
7594     }
7595
7596   if (!src_address_set)
7597     {
7598       errmsg ("src address required\n");
7599       return -99;
7600     }
7601
7602   if (!dst_address_set)
7603     {
7604       errmsg ("dst address required\n");
7605       return -99;
7606     }
7607
7608   if (!segments)
7609     {
7610       errmsg ("at least one sr segment required\n");
7611       return -99;
7612     }
7613
7614   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7615       vec_len (segments) * sizeof (ip6_address_t)
7616       + vec_len (tags) * sizeof (ip6_address_t));
7617
7618   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7619   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7620   mp->dst_mask_width = dst_mask_width;
7621   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7622   mp->n_segments = vec_len (segments);
7623   mp->n_tags = vec_len (tags);
7624   mp->is_add = is_del == 0;
7625   clib_memcpy (mp->segs_and_tags, segments,
7626                vec_len (segments) * sizeof (ip6_address_t));
7627   clib_memcpy (mp->segs_and_tags +
7628                vec_len (segments) * sizeof (ip6_address_t), tags,
7629                vec_len (tags) * sizeof (ip6_address_t));
7630
7631   mp->outer_vrf_id = ntohl (rx_table_id);
7632   mp->inner_vrf_id = ntohl (tx_table_id);
7633   memcpy (mp->name, name, vec_len (name));
7634   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7635
7636   vec_free (segments);
7637   vec_free (tags);
7638
7639   S;
7640   W;
7641   /* NOTREACHED */
7642 }
7643
7644 static int
7645 api_sr_policy_add_del (vat_main_t * vam)
7646 {
7647   unformat_input_t *input = vam->input;
7648   vl_api_sr_policy_add_del_t *mp;
7649   f64 timeout;
7650   int is_del = 0;
7651   u8 *name = 0;
7652   u8 *tunnel_name = 0;
7653   u8 **tunnel_names = 0;
7654
7655   int name_set = 0;
7656   int tunnel_set = 0;
7657   int j = 0;
7658   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7659   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7660
7661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7662     {
7663       if (unformat (input, "del"))
7664         is_del = 1;
7665       else if (unformat (input, "name %s", &name))
7666         name_set = 1;
7667       else if (unformat (input, "tunnel %s", &tunnel_name))
7668         {
7669           if (tunnel_name)
7670             {
7671               vec_add1 (tunnel_names, tunnel_name);
7672               /* For serializer:
7673                  - length = #bytes to store in serial vector
7674                  - +1 = byte to store that length
7675                */
7676               tunnel_names_length += (vec_len (tunnel_name) + 1);
7677               tunnel_set = 1;
7678               tunnel_name = 0;
7679             }
7680         }
7681       else
7682         break;
7683     }
7684
7685   if (!name_set)
7686     {
7687       errmsg ("policy name required\n");
7688       return -99;
7689     }
7690
7691   if ((!tunnel_set) && (!is_del))
7692     {
7693       errmsg ("tunnel name required\n");
7694       return -99;
7695     }
7696
7697   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7698
7699
7700
7701   mp->is_add = !is_del;
7702
7703   memcpy (mp->name, name, vec_len (name));
7704   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7705   u8 *serial_orig = 0;
7706   vec_validate (serial_orig, tunnel_names_length);
7707   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7708   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7709
7710   for (j = 0; j < vec_len (tunnel_names); j++)
7711     {
7712       tun_name_len = vec_len (tunnel_names[j]);
7713       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7714       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7715       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7716       serial_orig += tun_name_len;      // Advance past the copy
7717     }
7718   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7719
7720   vec_free (tunnel_names);
7721   vec_free (tunnel_name);
7722
7723   S;
7724   W;
7725   /* NOTREACHED */
7726 }
7727
7728 static int
7729 api_sr_multicast_map_add_del (vat_main_t * vam)
7730 {
7731   unformat_input_t *input = vam->input;
7732   vl_api_sr_multicast_map_add_del_t *mp;
7733   f64 timeout;
7734   int is_del = 0;
7735   ip6_address_t multicast_address;
7736   u8 *policy_name = 0;
7737   int multicast_address_set = 0;
7738
7739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (input, "del"))
7742         is_del = 1;
7743       else
7744         if (unformat
7745             (input, "address %U", unformat_ip6_address, &multicast_address))
7746         multicast_address_set = 1;
7747       else if (unformat (input, "sr-policy %s", &policy_name))
7748         ;
7749       else
7750         break;
7751     }
7752
7753   if (!is_del && !policy_name)
7754     {
7755       errmsg ("sr-policy name required\n");
7756       return -99;
7757     }
7758
7759
7760   if (!multicast_address_set)
7761     {
7762       errmsg ("address required\n");
7763       return -99;
7764     }
7765
7766   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7767
7768   mp->is_add = !is_del;
7769   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7770   clib_memcpy (mp->multicast_address, &multicast_address,
7771                sizeof (mp->multicast_address));
7772
7773
7774   vec_free (policy_name);
7775
7776   S;
7777   W;
7778   /* NOTREACHED */
7779 }
7780
7781
7782 #define foreach_ip4_proto_field                 \
7783 _(src_address)                                  \
7784 _(dst_address)                                  \
7785 _(tos)                                          \
7786 _(length)                                       \
7787 _(fragment_id)                                  \
7788 _(ttl)                                          \
7789 _(protocol)                                     \
7790 _(checksum)
7791
7792 uword
7793 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7794 {
7795   u8 **maskp = va_arg (*args, u8 **);
7796   u8 *mask = 0;
7797   u8 found_something = 0;
7798   ip4_header_t *ip;
7799
7800 #define _(a) u8 a=0;
7801   foreach_ip4_proto_field;
7802 #undef _
7803   u8 version = 0;
7804   u8 hdr_length = 0;
7805
7806
7807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7808     {
7809       if (unformat (input, "version"))
7810         version = 1;
7811       else if (unformat (input, "hdr_length"))
7812         hdr_length = 1;
7813       else if (unformat (input, "src"))
7814         src_address = 1;
7815       else if (unformat (input, "dst"))
7816         dst_address = 1;
7817       else if (unformat (input, "proto"))
7818         protocol = 1;
7819
7820 #define _(a) else if (unformat (input, #a)) a=1;
7821       foreach_ip4_proto_field
7822 #undef _
7823         else
7824         break;
7825     }
7826
7827 #define _(a) found_something += a;
7828   foreach_ip4_proto_field;
7829 #undef _
7830
7831   if (found_something == 0)
7832     return 0;
7833
7834   vec_validate (mask, sizeof (*ip) - 1);
7835
7836   ip = (ip4_header_t *) mask;
7837
7838 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7839   foreach_ip4_proto_field;
7840 #undef _
7841
7842   ip->ip_version_and_header_length = 0;
7843
7844   if (version)
7845     ip->ip_version_and_header_length |= 0xF0;
7846
7847   if (hdr_length)
7848     ip->ip_version_and_header_length |= 0x0F;
7849
7850   *maskp = mask;
7851   return 1;
7852 }
7853
7854 #define foreach_ip6_proto_field                 \
7855 _(src_address)                                  \
7856 _(dst_address)                                  \
7857 _(payload_length)                               \
7858 _(hop_limit)                                    \
7859 _(protocol)
7860
7861 uword
7862 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7863 {
7864   u8 **maskp = va_arg (*args, u8 **);
7865   u8 *mask = 0;
7866   u8 found_something = 0;
7867   ip6_header_t *ip;
7868   u32 ip_version_traffic_class_and_flow_label;
7869
7870 #define _(a) u8 a=0;
7871   foreach_ip6_proto_field;
7872 #undef _
7873   u8 version = 0;
7874   u8 traffic_class = 0;
7875   u8 flow_label = 0;
7876
7877   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7878     {
7879       if (unformat (input, "version"))
7880         version = 1;
7881       else if (unformat (input, "traffic-class"))
7882         traffic_class = 1;
7883       else if (unformat (input, "flow-label"))
7884         flow_label = 1;
7885       else if (unformat (input, "src"))
7886         src_address = 1;
7887       else if (unformat (input, "dst"))
7888         dst_address = 1;
7889       else if (unformat (input, "proto"))
7890         protocol = 1;
7891
7892 #define _(a) else if (unformat (input, #a)) a=1;
7893       foreach_ip6_proto_field
7894 #undef _
7895         else
7896         break;
7897     }
7898
7899 #define _(a) found_something += a;
7900   foreach_ip6_proto_field;
7901 #undef _
7902
7903   if (found_something == 0)
7904     return 0;
7905
7906   vec_validate (mask, sizeof (*ip) - 1);
7907
7908   ip = (ip6_header_t *) mask;
7909
7910 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7911   foreach_ip6_proto_field;
7912 #undef _
7913
7914   ip_version_traffic_class_and_flow_label = 0;
7915
7916   if (version)
7917     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7918
7919   if (traffic_class)
7920     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7921
7922   if (flow_label)
7923     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7924
7925   ip->ip_version_traffic_class_and_flow_label =
7926     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7927
7928   *maskp = mask;
7929   return 1;
7930 }
7931
7932 uword
7933 unformat_l3_mask (unformat_input_t * input, va_list * args)
7934 {
7935   u8 **maskp = va_arg (*args, u8 **);
7936
7937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7938     {
7939       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7940         return 1;
7941       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7942         return 1;
7943       else
7944         break;
7945     }
7946   return 0;
7947 }
7948
7949 uword
7950 unformat_l2_mask (unformat_input_t * input, va_list * args)
7951 {
7952   u8 **maskp = va_arg (*args, u8 **);
7953   u8 *mask = 0;
7954   u8 src = 0;
7955   u8 dst = 0;
7956   u8 proto = 0;
7957   u8 tag1 = 0;
7958   u8 tag2 = 0;
7959   u8 ignore_tag1 = 0;
7960   u8 ignore_tag2 = 0;
7961   u8 cos1 = 0;
7962   u8 cos2 = 0;
7963   u8 dot1q = 0;
7964   u8 dot1ad = 0;
7965   int len = 14;
7966
7967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7968     {
7969       if (unformat (input, "src"))
7970         src = 1;
7971       else if (unformat (input, "dst"))
7972         dst = 1;
7973       else if (unformat (input, "proto"))
7974         proto = 1;
7975       else if (unformat (input, "tag1"))
7976         tag1 = 1;
7977       else if (unformat (input, "tag2"))
7978         tag2 = 1;
7979       else if (unformat (input, "ignore-tag1"))
7980         ignore_tag1 = 1;
7981       else if (unformat (input, "ignore-tag2"))
7982         ignore_tag2 = 1;
7983       else if (unformat (input, "cos1"))
7984         cos1 = 1;
7985       else if (unformat (input, "cos2"))
7986         cos2 = 1;
7987       else if (unformat (input, "dot1q"))
7988         dot1q = 1;
7989       else if (unformat (input, "dot1ad"))
7990         dot1ad = 1;
7991       else
7992         break;
7993     }
7994   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7995        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7996     return 0;
7997
7998   if (tag1 || ignore_tag1 || cos1 || dot1q)
7999     len = 18;
8000   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8001     len = 22;
8002
8003   vec_validate (mask, len - 1);
8004
8005   if (dst)
8006     memset (mask, 0xff, 6);
8007
8008   if (src)
8009     memset (mask + 6, 0xff, 6);
8010
8011   if (tag2 || dot1ad)
8012     {
8013       /* inner vlan tag */
8014       if (tag2)
8015         {
8016           mask[19] = 0xff;
8017           mask[18] = 0x0f;
8018         }
8019       if (cos2)
8020         mask[18] |= 0xe0;
8021       if (proto)
8022         mask[21] = mask[20] = 0xff;
8023       if (tag1)
8024         {
8025           mask[15] = 0xff;
8026           mask[14] = 0x0f;
8027         }
8028       if (cos1)
8029         mask[14] |= 0xe0;
8030       *maskp = mask;
8031       return 1;
8032     }
8033   if (tag1 | dot1q)
8034     {
8035       if (tag1)
8036         {
8037           mask[15] = 0xff;
8038           mask[14] = 0x0f;
8039         }
8040       if (cos1)
8041         mask[14] |= 0xe0;
8042       if (proto)
8043         mask[16] = mask[17] = 0xff;
8044
8045       *maskp = mask;
8046       return 1;
8047     }
8048   if (cos2)
8049     mask[18] |= 0xe0;
8050   if (cos1)
8051     mask[14] |= 0xe0;
8052   if (proto)
8053     mask[12] = mask[13] = 0xff;
8054
8055   *maskp = mask;
8056   return 1;
8057 }
8058
8059 uword
8060 unformat_classify_mask (unformat_input_t * input, va_list * args)
8061 {
8062   u8 **maskp = va_arg (*args, u8 **);
8063   u32 *skipp = va_arg (*args, u32 *);
8064   u32 *matchp = va_arg (*args, u32 *);
8065   u32 match;
8066   u8 *mask = 0;
8067   u8 *l2 = 0;
8068   u8 *l3 = 0;
8069   int i;
8070
8071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8074         ;
8075       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8076         ;
8077       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8078         ;
8079       else
8080         break;
8081     }
8082
8083   if (mask || l2 || l3)
8084     {
8085       if (l2 || l3)
8086         {
8087           /* "With a free Ethernet header in every package" */
8088           if (l2 == 0)
8089             vec_validate (l2, 13);
8090           mask = l2;
8091           if (vec_len (l3))
8092             {
8093               vec_append (mask, l3);
8094               vec_free (l3);
8095             }
8096         }
8097
8098       /* Scan forward looking for the first significant mask octet */
8099       for (i = 0; i < vec_len (mask); i++)
8100         if (mask[i])
8101           break;
8102
8103       /* compute (skip, match) params */
8104       *skipp = i / sizeof (u32x4);
8105       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8106
8107       /* Pad mask to an even multiple of the vector size */
8108       while (vec_len (mask) % sizeof (u32x4))
8109         vec_add1 (mask, 0);
8110
8111       match = vec_len (mask) / sizeof (u32x4);
8112
8113       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8114         {
8115           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8116           if (*tmp || *(tmp + 1))
8117             break;
8118           match--;
8119         }
8120       if (match == 0)
8121         clib_warning ("BUG: match 0");
8122
8123       _vec_len (mask) = match * sizeof (u32x4);
8124
8125       *matchp = match;
8126       *maskp = mask;
8127
8128       return 1;
8129     }
8130
8131   return 0;
8132 }
8133
8134 #define foreach_l2_next                         \
8135 _(drop, DROP)                                   \
8136 _(ethernet, ETHERNET_INPUT)                     \
8137 _(ip4, IP4_INPUT)                               \
8138 _(ip6, IP6_INPUT)
8139
8140 uword
8141 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8142 {
8143   u32 *miss_next_indexp = va_arg (*args, u32 *);
8144   u32 next_index = 0;
8145   u32 tmp;
8146
8147 #define _(n,N) \
8148   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8149   foreach_l2_next;
8150 #undef _
8151
8152   if (unformat (input, "%d", &tmp))
8153     {
8154       next_index = tmp;
8155       goto out;
8156     }
8157
8158   return 0;
8159
8160 out:
8161   *miss_next_indexp = next_index;
8162   return 1;
8163 }
8164
8165 #define foreach_ip_next                         \
8166 _(drop, DROP)                                   \
8167 _(local, LOCAL)                                 \
8168 _(rewrite, REWRITE)
8169
8170 uword
8171 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8172 {
8173   u32 *miss_next_indexp = va_arg (*args, u32 *);
8174   u32 next_index = 0;
8175   u32 tmp;
8176
8177 #define _(n,N) \
8178   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8179   foreach_ip_next;
8180 #undef _
8181
8182   if (unformat (input, "%d", &tmp))
8183     {
8184       next_index = tmp;
8185       goto out;
8186     }
8187
8188   return 0;
8189
8190 out:
8191   *miss_next_indexp = next_index;
8192   return 1;
8193 }
8194
8195 #define foreach_acl_next                        \
8196 _(deny, DENY)
8197
8198 uword
8199 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8200 {
8201   u32 *miss_next_indexp = va_arg (*args, u32 *);
8202   u32 next_index = 0;
8203   u32 tmp;
8204
8205 #define _(n,N) \
8206   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8207   foreach_acl_next;
8208 #undef _
8209
8210   if (unformat (input, "permit"))
8211     {
8212       next_index = ~0;
8213       goto out;
8214     }
8215   else if (unformat (input, "%d", &tmp))
8216     {
8217       next_index = tmp;
8218       goto out;
8219     }
8220
8221   return 0;
8222
8223 out:
8224   *miss_next_indexp = next_index;
8225   return 1;
8226 }
8227
8228 uword
8229 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8230 {
8231   u32 *r = va_arg (*args, u32 *);
8232
8233   if (unformat (input, "conform-color"))
8234     *r = POLICE_CONFORM;
8235   else if (unformat (input, "exceed-color"))
8236     *r = POLICE_EXCEED;
8237   else
8238     return 0;
8239
8240   return 1;
8241 }
8242
8243 static int
8244 api_classify_add_del_table (vat_main_t * vam)
8245 {
8246   unformat_input_t *i = vam->input;
8247   vl_api_classify_add_del_table_t *mp;
8248
8249   u32 nbuckets = 2;
8250   u32 skip = ~0;
8251   u32 match = ~0;
8252   int is_add = 1;
8253   u32 table_index = ~0;
8254   u32 next_table_index = ~0;
8255   u32 miss_next_index = ~0;
8256   u32 memory_size = 32 << 20;
8257   u8 *mask = 0;
8258   f64 timeout;
8259
8260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8261     {
8262       if (unformat (i, "del"))
8263         is_add = 0;
8264       else if (unformat (i, "buckets %d", &nbuckets))
8265         ;
8266       else if (unformat (i, "memory_size %d", &memory_size))
8267         ;
8268       else if (unformat (i, "skip %d", &skip))
8269         ;
8270       else if (unformat (i, "match %d", &match))
8271         ;
8272       else if (unformat (i, "table %d", &table_index))
8273         ;
8274       else if (unformat (i, "mask %U", unformat_classify_mask,
8275                          &mask, &skip, &match))
8276         ;
8277       else if (unformat (i, "next-table %d", &next_table_index))
8278         ;
8279       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8280                          &miss_next_index))
8281         ;
8282       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8283                          &miss_next_index))
8284         ;
8285       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8286                          &miss_next_index))
8287         ;
8288       else
8289         break;
8290     }
8291
8292   if (is_add && mask == 0)
8293     {
8294       errmsg ("Mask required\n");
8295       return -99;
8296     }
8297
8298   if (is_add && skip == ~0)
8299     {
8300       errmsg ("skip count required\n");
8301       return -99;
8302     }
8303
8304   if (is_add && match == ~0)
8305     {
8306       errmsg ("match count required\n");
8307       return -99;
8308     }
8309
8310   if (!is_add && table_index == ~0)
8311     {
8312       errmsg ("table index required for delete\n");
8313       return -99;
8314     }
8315
8316   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8317
8318   mp->is_add = is_add;
8319   mp->table_index = ntohl (table_index);
8320   mp->nbuckets = ntohl (nbuckets);
8321   mp->memory_size = ntohl (memory_size);
8322   mp->skip_n_vectors = ntohl (skip);
8323   mp->match_n_vectors = ntohl (match);
8324   mp->next_table_index = ntohl (next_table_index);
8325   mp->miss_next_index = ntohl (miss_next_index);
8326   clib_memcpy (mp->mask, mask, vec_len (mask));
8327
8328   vec_free (mask);
8329
8330   S;
8331   W;
8332   /* NOTREACHED */
8333 }
8334
8335 uword
8336 unformat_ip4_match (unformat_input_t * input, va_list * args)
8337 {
8338   u8 **matchp = va_arg (*args, u8 **);
8339   u8 *match = 0;
8340   ip4_header_t *ip;
8341   int version = 0;
8342   u32 version_val;
8343   int hdr_length = 0;
8344   u32 hdr_length_val;
8345   int src = 0, dst = 0;
8346   ip4_address_t src_val, dst_val;
8347   int proto = 0;
8348   u32 proto_val;
8349   int tos = 0;
8350   u32 tos_val;
8351   int length = 0;
8352   u32 length_val;
8353   int fragment_id = 0;
8354   u32 fragment_id_val;
8355   int ttl = 0;
8356   int ttl_val;
8357   int checksum = 0;
8358   u32 checksum_val;
8359
8360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8361     {
8362       if (unformat (input, "version %d", &version_val))
8363         version = 1;
8364       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8365         hdr_length = 1;
8366       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8367         src = 1;
8368       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8369         dst = 1;
8370       else if (unformat (input, "proto %d", &proto_val))
8371         proto = 1;
8372       else if (unformat (input, "tos %d", &tos_val))
8373         tos = 1;
8374       else if (unformat (input, "length %d", &length_val))
8375         length = 1;
8376       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8377         fragment_id = 1;
8378       else if (unformat (input, "ttl %d", &ttl_val))
8379         ttl = 1;
8380       else if (unformat (input, "checksum %d", &checksum_val))
8381         checksum = 1;
8382       else
8383         break;
8384     }
8385
8386   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8387       + ttl + checksum == 0)
8388     return 0;
8389
8390   /*
8391    * Aligned because we use the real comparison functions
8392    */
8393   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8394
8395   ip = (ip4_header_t *) match;
8396
8397   /* These are realistically matched in practice */
8398   if (src)
8399     ip->src_address.as_u32 = src_val.as_u32;
8400
8401   if (dst)
8402     ip->dst_address.as_u32 = dst_val.as_u32;
8403
8404   if (proto)
8405     ip->protocol = proto_val;
8406
8407
8408   /* These are not, but they're included for completeness */
8409   if (version)
8410     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8411
8412   if (hdr_length)
8413     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8414
8415   if (tos)
8416     ip->tos = tos_val;
8417
8418   if (length)
8419     ip->length = length_val;
8420
8421   if (ttl)
8422     ip->ttl = ttl_val;
8423
8424   if (checksum)
8425     ip->checksum = checksum_val;
8426
8427   *matchp = match;
8428   return 1;
8429 }
8430
8431 uword
8432 unformat_ip6_match (unformat_input_t * input, va_list * args)
8433 {
8434   u8 **matchp = va_arg (*args, u8 **);
8435   u8 *match = 0;
8436   ip6_header_t *ip;
8437   int version = 0;
8438   u32 version_val;
8439   u8 traffic_class = 0;
8440   u32 traffic_class_val = 0;
8441   u8 flow_label = 0;
8442   u8 flow_label_val;
8443   int src = 0, dst = 0;
8444   ip6_address_t src_val, dst_val;
8445   int proto = 0;
8446   u32 proto_val;
8447   int payload_length = 0;
8448   u32 payload_length_val;
8449   int hop_limit = 0;
8450   int hop_limit_val;
8451   u32 ip_version_traffic_class_and_flow_label;
8452
8453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8454     {
8455       if (unformat (input, "version %d", &version_val))
8456         version = 1;
8457       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8458         traffic_class = 1;
8459       else if (unformat (input, "flow_label %d", &flow_label_val))
8460         flow_label = 1;
8461       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8462         src = 1;
8463       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8464         dst = 1;
8465       else if (unformat (input, "proto %d", &proto_val))
8466         proto = 1;
8467       else if (unformat (input, "payload_length %d", &payload_length_val))
8468         payload_length = 1;
8469       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8470         hop_limit = 1;
8471       else
8472         break;
8473     }
8474
8475   if (version + traffic_class + flow_label + src + dst + proto +
8476       payload_length + hop_limit == 0)
8477     return 0;
8478
8479   /*
8480    * Aligned because we use the real comparison functions
8481    */
8482   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8483
8484   ip = (ip6_header_t *) match;
8485
8486   if (src)
8487     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8488
8489   if (dst)
8490     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8491
8492   if (proto)
8493     ip->protocol = proto_val;
8494
8495   ip_version_traffic_class_and_flow_label = 0;
8496
8497   if (version)
8498     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8499
8500   if (traffic_class)
8501     ip_version_traffic_class_and_flow_label |=
8502       (traffic_class_val & 0xFF) << 20;
8503
8504   if (flow_label)
8505     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8506
8507   ip->ip_version_traffic_class_and_flow_label =
8508     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8509
8510   if (payload_length)
8511     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8512
8513   if (hop_limit)
8514     ip->hop_limit = hop_limit_val;
8515
8516   *matchp = match;
8517   return 1;
8518 }
8519
8520 uword
8521 unformat_l3_match (unformat_input_t * input, va_list * args)
8522 {
8523   u8 **matchp = va_arg (*args, u8 **);
8524
8525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8526     {
8527       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8528         return 1;
8529       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8530         return 1;
8531       else
8532         break;
8533     }
8534   return 0;
8535 }
8536
8537 uword
8538 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8539 {
8540   u8 *tagp = va_arg (*args, u8 *);
8541   u32 tag;
8542
8543   if (unformat (input, "%d", &tag))
8544     {
8545       tagp[0] = (tag >> 8) & 0x0F;
8546       tagp[1] = tag & 0xFF;
8547       return 1;
8548     }
8549
8550   return 0;
8551 }
8552
8553 uword
8554 unformat_l2_match (unformat_input_t * input, va_list * args)
8555 {
8556   u8 **matchp = va_arg (*args, u8 **);
8557   u8 *match = 0;
8558   u8 src = 0;
8559   u8 src_val[6];
8560   u8 dst = 0;
8561   u8 dst_val[6];
8562   u8 proto = 0;
8563   u16 proto_val;
8564   u8 tag1 = 0;
8565   u8 tag1_val[2];
8566   u8 tag2 = 0;
8567   u8 tag2_val[2];
8568   int len = 14;
8569   u8 ignore_tag1 = 0;
8570   u8 ignore_tag2 = 0;
8571   u8 cos1 = 0;
8572   u8 cos2 = 0;
8573   u32 cos1_val = 0;
8574   u32 cos2_val = 0;
8575
8576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8577     {
8578       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8579         src = 1;
8580       else
8581         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8582         dst = 1;
8583       else if (unformat (input, "proto %U",
8584                          unformat_ethernet_type_host_byte_order, &proto_val))
8585         proto = 1;
8586       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8587         tag1 = 1;
8588       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8589         tag2 = 1;
8590       else if (unformat (input, "ignore-tag1"))
8591         ignore_tag1 = 1;
8592       else if (unformat (input, "ignore-tag2"))
8593         ignore_tag2 = 1;
8594       else if (unformat (input, "cos1 %d", &cos1_val))
8595         cos1 = 1;
8596       else if (unformat (input, "cos2 %d", &cos2_val))
8597         cos2 = 1;
8598       else
8599         break;
8600     }
8601   if ((src + dst + proto + tag1 + tag2 +
8602        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8603     return 0;
8604
8605   if (tag1 || ignore_tag1 || cos1)
8606     len = 18;
8607   if (tag2 || ignore_tag2 || cos2)
8608     len = 22;
8609
8610   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8611
8612   if (dst)
8613     clib_memcpy (match, dst_val, 6);
8614
8615   if (src)
8616     clib_memcpy (match + 6, src_val, 6);
8617
8618   if (tag2)
8619     {
8620       /* inner vlan tag */
8621       match[19] = tag2_val[1];
8622       match[18] = tag2_val[0];
8623       if (cos2)
8624         match[18] |= (cos2_val & 0x7) << 5;
8625       if (proto)
8626         {
8627           match[21] = proto_val & 0xff;
8628           match[20] = proto_val >> 8;
8629         }
8630       if (tag1)
8631         {
8632           match[15] = tag1_val[1];
8633           match[14] = tag1_val[0];
8634         }
8635       if (cos1)
8636         match[14] |= (cos1_val & 0x7) << 5;
8637       *matchp = match;
8638       return 1;
8639     }
8640   if (tag1)
8641     {
8642       match[15] = tag1_val[1];
8643       match[14] = tag1_val[0];
8644       if (proto)
8645         {
8646           match[17] = proto_val & 0xff;
8647           match[16] = proto_val >> 8;
8648         }
8649       if (cos1)
8650         match[14] |= (cos1_val & 0x7) << 5;
8651
8652       *matchp = match;
8653       return 1;
8654     }
8655   if (cos2)
8656     match[18] |= (cos2_val & 0x7) << 5;
8657   if (cos1)
8658     match[14] |= (cos1_val & 0x7) << 5;
8659   if (proto)
8660     {
8661       match[13] = proto_val & 0xff;
8662       match[12] = proto_val >> 8;
8663     }
8664
8665   *matchp = match;
8666   return 1;
8667 }
8668
8669
8670 uword
8671 unformat_classify_match (unformat_input_t * input, va_list * args)
8672 {
8673   u8 **matchp = va_arg (*args, u8 **);
8674   u32 skip_n_vectors = va_arg (*args, u32);
8675   u32 match_n_vectors = va_arg (*args, u32);
8676
8677   u8 *match = 0;
8678   u8 *l2 = 0;
8679   u8 *l3 = 0;
8680
8681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8682     {
8683       if (unformat (input, "hex %U", unformat_hex_string, &match))
8684         ;
8685       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8686         ;
8687       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8688         ;
8689       else
8690         break;
8691     }
8692
8693   if (match || l2 || l3)
8694     {
8695       if (l2 || l3)
8696         {
8697           /* "Win a free Ethernet header in every packet" */
8698           if (l2 == 0)
8699             vec_validate_aligned (l2, 13, sizeof (u32x4));
8700           match = l2;
8701           if (vec_len (l3))
8702             {
8703               vec_append_aligned (match, l3, sizeof (u32x4));
8704               vec_free (l3);
8705             }
8706         }
8707
8708       /* Make sure the vector is big enough even if key is all 0's */
8709       vec_validate_aligned
8710         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8711          sizeof (u32x4));
8712
8713       /* Set size, include skipped vectors */
8714       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8715
8716       *matchp = match;
8717
8718       return 1;
8719     }
8720
8721   return 0;
8722 }
8723
8724 static int
8725 api_classify_add_del_session (vat_main_t * vam)
8726 {
8727   unformat_input_t *i = vam->input;
8728   vl_api_classify_add_del_session_t *mp;
8729   int is_add = 1;
8730   u32 table_index = ~0;
8731   u32 hit_next_index = ~0;
8732   u32 opaque_index = ~0;
8733   u8 *match = 0;
8734   i32 advance = 0;
8735   f64 timeout;
8736   u32 skip_n_vectors = 0;
8737   u32 match_n_vectors = 0;
8738
8739   /*
8740    * Warning: you have to supply skip_n and match_n
8741    * because the API client cant simply look at the classify
8742    * table object.
8743    */
8744
8745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8746     {
8747       if (unformat (i, "del"))
8748         is_add = 0;
8749       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8750                          &hit_next_index))
8751         ;
8752       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8753                          &hit_next_index))
8754         ;
8755       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8756                          &hit_next_index))
8757         ;
8758       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8759         ;
8760       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8761         ;
8762       else if (unformat (i, "opaque-index %d", &opaque_index))
8763         ;
8764       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8765         ;
8766       else if (unformat (i, "match_n %d", &match_n_vectors))
8767         ;
8768       else if (unformat (i, "match %U", unformat_classify_match,
8769                          &match, skip_n_vectors, match_n_vectors))
8770         ;
8771       else if (unformat (i, "advance %d", &advance))
8772         ;
8773       else if (unformat (i, "table-index %d", &table_index))
8774         ;
8775       else
8776         break;
8777     }
8778
8779   if (table_index == ~0)
8780     {
8781       errmsg ("Table index required\n");
8782       return -99;
8783     }
8784
8785   if (is_add && match == 0)
8786     {
8787       errmsg ("Match value required\n");
8788       return -99;
8789     }
8790
8791   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8792
8793   mp->is_add = is_add;
8794   mp->table_index = ntohl (table_index);
8795   mp->hit_next_index = ntohl (hit_next_index);
8796   mp->opaque_index = ntohl (opaque_index);
8797   mp->advance = ntohl (advance);
8798   clib_memcpy (mp->match, match, vec_len (match));
8799   vec_free (match);
8800
8801   S;
8802   W;
8803   /* NOTREACHED */
8804 }
8805
8806 static int
8807 api_classify_set_interface_ip_table (vat_main_t * vam)
8808 {
8809   unformat_input_t *i = vam->input;
8810   vl_api_classify_set_interface_ip_table_t *mp;
8811   f64 timeout;
8812   u32 sw_if_index;
8813   int sw_if_index_set;
8814   u32 table_index = ~0;
8815   u8 is_ipv6 = 0;
8816
8817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8818     {
8819       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8820         sw_if_index_set = 1;
8821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8822         sw_if_index_set = 1;
8823       else if (unformat (i, "table %d", &table_index))
8824         ;
8825       else
8826         {
8827           clib_warning ("parse error '%U'", format_unformat_error, i);
8828           return -99;
8829         }
8830     }
8831
8832   if (sw_if_index_set == 0)
8833     {
8834       errmsg ("missing interface name or sw_if_index\n");
8835       return -99;
8836     }
8837
8838
8839   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8840
8841   mp->sw_if_index = ntohl (sw_if_index);
8842   mp->table_index = ntohl (table_index);
8843   mp->is_ipv6 = is_ipv6;
8844
8845   S;
8846   W;
8847   /* NOTREACHED */
8848   return 0;
8849 }
8850
8851 static int
8852 api_classify_set_interface_l2_tables (vat_main_t * vam)
8853 {
8854   unformat_input_t *i = vam->input;
8855   vl_api_classify_set_interface_l2_tables_t *mp;
8856   f64 timeout;
8857   u32 sw_if_index;
8858   int sw_if_index_set;
8859   u32 ip4_table_index = ~0;
8860   u32 ip6_table_index = ~0;
8861   u32 other_table_index = ~0;
8862   u32 is_input = 1;
8863
8864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8865     {
8866       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8867         sw_if_index_set = 1;
8868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8869         sw_if_index_set = 1;
8870       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8871         ;
8872       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8873         ;
8874       else if (unformat (i, "other-table %d", &other_table_index))
8875         ;
8876       else if (unformat (i, "is-input %d", &is_input))
8877         ;
8878       else
8879         {
8880           clib_warning ("parse error '%U'", format_unformat_error, i);
8881           return -99;
8882         }
8883     }
8884
8885   if (sw_if_index_set == 0)
8886     {
8887       errmsg ("missing interface name or sw_if_index\n");
8888       return -99;
8889     }
8890
8891
8892   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8893
8894   mp->sw_if_index = ntohl (sw_if_index);
8895   mp->ip4_table_index = ntohl (ip4_table_index);
8896   mp->ip6_table_index = ntohl (ip6_table_index);
8897   mp->other_table_index = ntohl (other_table_index);
8898   mp->is_input = (u8) is_input;
8899
8900   S;
8901   W;
8902   /* NOTREACHED */
8903   return 0;
8904 }
8905
8906 static int
8907 api_set_ipfix_exporter (vat_main_t * vam)
8908 {
8909   unformat_input_t *i = vam->input;
8910   vl_api_set_ipfix_exporter_t *mp;
8911   ip4_address_t collector_address;
8912   u8 collector_address_set = 0;
8913   u32 collector_port = ~0;
8914   ip4_address_t src_address;
8915   u8 src_address_set = 0;
8916   u32 vrf_id = ~0;
8917   u32 path_mtu = ~0;
8918   u32 template_interval = ~0;
8919   u8 udp_checksum = 0;
8920   f64 timeout;
8921
8922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (i, "collector_address %U", unformat_ip4_address,
8925                     &collector_address))
8926         collector_address_set = 1;
8927       else if (unformat (i, "collector_port %d", &collector_port))
8928         ;
8929       else if (unformat (i, "src_address %U", unformat_ip4_address,
8930                          &src_address))
8931         src_address_set = 1;
8932       else if (unformat (i, "vrf_id %d", &vrf_id))
8933         ;
8934       else if (unformat (i, "path_mtu %d", &path_mtu))
8935         ;
8936       else if (unformat (i, "template_interval %d", &template_interval))
8937         ;
8938       else if (unformat (i, "udp_checksum"))
8939         udp_checksum = 1;
8940       else
8941         break;
8942     }
8943
8944   if (collector_address_set == 0)
8945     {
8946       errmsg ("collector_address required\n");
8947       return -99;
8948     }
8949
8950   if (src_address_set == 0)
8951     {
8952       errmsg ("src_address required\n");
8953       return -99;
8954     }
8955
8956   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8957
8958   memcpy (mp->collector_address, collector_address.data,
8959           sizeof (collector_address.data));
8960   mp->collector_port = htons ((u16) collector_port);
8961   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8962   mp->vrf_id = htonl (vrf_id);
8963   mp->path_mtu = htonl (path_mtu);
8964   mp->template_interval = htonl (template_interval);
8965   mp->udp_checksum = udp_checksum;
8966
8967   S;
8968   W;
8969   /* NOTREACHED */
8970 }
8971
8972 static int
8973 api_set_ipfix_classify_stream (vat_main_t * vam)
8974 {
8975   unformat_input_t *i = vam->input;
8976   vl_api_set_ipfix_classify_stream_t *mp;
8977   u32 domain_id = 0;
8978   u32 src_port = UDP_DST_PORT_ipfix;
8979   f64 timeout;
8980
8981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8982     {
8983       if (unformat (i, "domain %d", &domain_id))
8984         ;
8985       else if (unformat (i, "src_port %d", &src_port))
8986         ;
8987       else
8988         {
8989           errmsg ("unknown input `%U'", format_unformat_error, i);
8990           return -99;
8991         }
8992     }
8993
8994   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8995
8996   mp->domain_id = htonl (domain_id);
8997   mp->src_port = htons ((u16) src_port);
8998
8999   S;
9000   W;
9001   /* NOTREACHED */
9002 }
9003
9004 static int
9005 api_ipfix_classify_table_add_del (vat_main_t * vam)
9006 {
9007   unformat_input_t *i = vam->input;
9008   vl_api_ipfix_classify_table_add_del_t *mp;
9009   int is_add = -1;
9010   u32 classify_table_index = ~0;
9011   u8 ip_version = 0;
9012   u8 transport_protocol = 255;
9013   f64 timeout;
9014
9015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9016     {
9017       if (unformat (i, "add"))
9018         is_add = 1;
9019       else if (unformat (i, "del"))
9020         is_add = 0;
9021       else if (unformat (i, "table %d", &classify_table_index))
9022         ;
9023       else if (unformat (i, "ip4"))
9024         ip_version = 4;
9025       else if (unformat (i, "ip6"))
9026         ip_version = 6;
9027       else if (unformat (i, "tcp"))
9028         transport_protocol = 6;
9029       else if (unformat (i, "udp"))
9030         transport_protocol = 17;
9031       else
9032         {
9033           errmsg ("unknown input `%U'", format_unformat_error, i);
9034           return -99;
9035         }
9036     }
9037
9038   if (is_add == -1)
9039     {
9040       errmsg ("expecting: add|del");
9041       return -99;
9042     }
9043   if (classify_table_index == ~0)
9044     {
9045       errmsg ("classifier table not specified");
9046       return -99;
9047     }
9048   if (ip_version == 0)
9049     {
9050       errmsg ("IP version not specified");
9051       return -99;
9052     }
9053
9054   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9055
9056   mp->is_add = is_add;
9057   mp->table_id = htonl (classify_table_index);
9058   mp->ip_version = ip_version;
9059   mp->transport_protocol = transport_protocol;
9060
9061   S;
9062   W;
9063   /* NOTREACHED */
9064 }
9065
9066 static int
9067 api_get_node_index (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_get_node_index_t *mp;
9071   f64 timeout;
9072   u8 *name = 0;
9073
9074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9075     {
9076       if (unformat (i, "node %s", &name))
9077         ;
9078       else
9079         break;
9080     }
9081   if (name == 0)
9082     {
9083       errmsg ("node name required\n");
9084       return -99;
9085     }
9086   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9087     {
9088       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9089       return -99;
9090     }
9091
9092   M (GET_NODE_INDEX, get_node_index);
9093   clib_memcpy (mp->node_name, name, vec_len (name));
9094   vec_free (name);
9095
9096   S;
9097   W;
9098   /* NOTREACHED */
9099   return 0;
9100 }
9101
9102 static int
9103 api_get_next_index (vat_main_t * vam)
9104 {
9105   unformat_input_t *i = vam->input;
9106   vl_api_get_next_index_t *mp;
9107   f64 timeout;
9108   u8 *node_name = 0, *next_node_name = 0;
9109
9110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (i, "node-name %s", &node_name))
9113         ;
9114       else if (unformat (i, "next-node-name %s", &next_node_name))
9115         break;
9116     }
9117
9118   if (node_name == 0)
9119     {
9120       errmsg ("node name required\n");
9121       return -99;
9122     }
9123   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9124     {
9125       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9126       return -99;
9127     }
9128
9129   if (next_node_name == 0)
9130     {
9131       errmsg ("next node name required\n");
9132       return -99;
9133     }
9134   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9135     {
9136       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9137       return -99;
9138     }
9139
9140   M (GET_NEXT_INDEX, get_next_index);
9141   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9142   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9143   vec_free (node_name);
9144   vec_free (next_node_name);
9145
9146   S;
9147   W;
9148   /* NOTREACHED */
9149   return 0;
9150 }
9151
9152 static int
9153 api_add_node_next (vat_main_t * vam)
9154 {
9155   unformat_input_t *i = vam->input;
9156   vl_api_add_node_next_t *mp;
9157   f64 timeout;
9158   u8 *name = 0;
9159   u8 *next = 0;
9160
9161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (i, "node %s", &name))
9164         ;
9165       else if (unformat (i, "next %s", &next))
9166         ;
9167       else
9168         break;
9169     }
9170   if (name == 0)
9171     {
9172       errmsg ("node name required\n");
9173       return -99;
9174     }
9175   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9176     {
9177       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9178       return -99;
9179     }
9180   if (next == 0)
9181     {
9182       errmsg ("next node required\n");
9183       return -99;
9184     }
9185   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9186     {
9187       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9188       return -99;
9189     }
9190
9191   M (ADD_NODE_NEXT, add_node_next);
9192   clib_memcpy (mp->node_name, name, vec_len (name));
9193   clib_memcpy (mp->next_name, next, vec_len (next));
9194   vec_free (name);
9195   vec_free (next);
9196
9197   S;
9198   W;
9199   /* NOTREACHED */
9200   return 0;
9201 }
9202
9203 static int
9204 api_l2tpv3_create_tunnel (vat_main_t * vam)
9205 {
9206   unformat_input_t *i = vam->input;
9207   ip6_address_t client_address, our_address;
9208   int client_address_set = 0;
9209   int our_address_set = 0;
9210   u32 local_session_id = 0;
9211   u32 remote_session_id = 0;
9212   u64 local_cookie = 0;
9213   u64 remote_cookie = 0;
9214   u8 l2_sublayer_present = 0;
9215   vl_api_l2tpv3_create_tunnel_t *mp;
9216   f64 timeout;
9217
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "client_address %U", unformat_ip6_address,
9221                     &client_address))
9222         client_address_set = 1;
9223       else if (unformat (i, "our_address %U", unformat_ip6_address,
9224                          &our_address))
9225         our_address_set = 1;
9226       else if (unformat (i, "local_session_id %d", &local_session_id))
9227         ;
9228       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9229         ;
9230       else if (unformat (i, "local_cookie %lld", &local_cookie))
9231         ;
9232       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9233         ;
9234       else if (unformat (i, "l2-sublayer-present"))
9235         l2_sublayer_present = 1;
9236       else
9237         break;
9238     }
9239
9240   if (client_address_set == 0)
9241     {
9242       errmsg ("client_address required\n");
9243       return -99;
9244     }
9245
9246   if (our_address_set == 0)
9247     {
9248       errmsg ("our_address required\n");
9249       return -99;
9250     }
9251
9252   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9253
9254   clib_memcpy (mp->client_address, client_address.as_u8,
9255                sizeof (mp->client_address));
9256
9257   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9258
9259   mp->local_session_id = ntohl (local_session_id);
9260   mp->remote_session_id = ntohl (remote_session_id);
9261   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9262   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9263   mp->l2_sublayer_present = l2_sublayer_present;
9264   mp->is_ipv6 = 1;
9265
9266   S;
9267   W;
9268   /* NOTREACHED */
9269   return 0;
9270 }
9271
9272 static int
9273 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9274 {
9275   unformat_input_t *i = vam->input;
9276   u32 sw_if_index;
9277   u8 sw_if_index_set = 0;
9278   u64 new_local_cookie = 0;
9279   u64 new_remote_cookie = 0;
9280   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9281   f64 timeout;
9282
9283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9284     {
9285       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9286         sw_if_index_set = 1;
9287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9288         sw_if_index_set = 1;
9289       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9290         ;
9291       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9292         ;
9293       else
9294         break;
9295     }
9296
9297   if (sw_if_index_set == 0)
9298     {
9299       errmsg ("missing interface name or sw_if_index\n");
9300       return -99;
9301     }
9302
9303   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9304
9305   mp->sw_if_index = ntohl (sw_if_index);
9306   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9307   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9308
9309   S;
9310   W;
9311   /* NOTREACHED */
9312   return 0;
9313 }
9314
9315 static int
9316 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9317 {
9318   unformat_input_t *i = vam->input;
9319   vl_api_l2tpv3_interface_enable_disable_t *mp;
9320   f64 timeout;
9321   u32 sw_if_index;
9322   u8 sw_if_index_set = 0;
9323   u8 enable_disable = 1;
9324
9325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9326     {
9327       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9328         sw_if_index_set = 1;
9329       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9330         sw_if_index_set = 1;
9331       else if (unformat (i, "enable"))
9332         enable_disable = 1;
9333       else if (unformat (i, "disable"))
9334         enable_disable = 0;
9335       else
9336         break;
9337     }
9338
9339   if (sw_if_index_set == 0)
9340     {
9341       errmsg ("missing interface name or sw_if_index\n");
9342       return -99;
9343     }
9344
9345   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9346
9347   mp->sw_if_index = ntohl (sw_if_index);
9348   mp->enable_disable = enable_disable;
9349
9350   S;
9351   W;
9352   /* NOTREACHED */
9353   return 0;
9354 }
9355
9356 static int
9357 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9358 {
9359   unformat_input_t *i = vam->input;
9360   vl_api_l2tpv3_set_lookup_key_t *mp;
9361   f64 timeout;
9362   u8 key = ~0;
9363
9364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9365     {
9366       if (unformat (i, "lookup_v6_src"))
9367         key = L2T_LOOKUP_SRC_ADDRESS;
9368       else if (unformat (i, "lookup_v6_dst"))
9369         key = L2T_LOOKUP_DST_ADDRESS;
9370       else if (unformat (i, "lookup_session_id"))
9371         key = L2T_LOOKUP_SESSION_ID;
9372       else
9373         break;
9374     }
9375
9376   if (key == (u8) ~ 0)
9377     {
9378       errmsg ("l2tp session lookup key unset\n");
9379       return -99;
9380     }
9381
9382   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9383
9384   mp->key = key;
9385
9386   S;
9387   W;
9388   /* NOTREACHED */
9389   return 0;
9390 }
9391
9392 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9393   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9394 {
9395   vat_main_t *vam = &vat_main;
9396
9397   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9398            format_ip6_address, mp->our_address,
9399            format_ip6_address, mp->client_address,
9400            clib_net_to_host_u32 (mp->sw_if_index));
9401
9402   fformat (vam->ofp,
9403            "   local cookies %016llx %016llx remote cookie %016llx\n",
9404            clib_net_to_host_u64 (mp->local_cookie[0]),
9405            clib_net_to_host_u64 (mp->local_cookie[1]),
9406            clib_net_to_host_u64 (mp->remote_cookie));
9407
9408   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9409            clib_net_to_host_u32 (mp->local_session_id),
9410            clib_net_to_host_u32 (mp->remote_session_id));
9411
9412   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9413            mp->l2_sublayer_present ? "preset" : "absent");
9414
9415 }
9416
9417 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9418   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9419 {
9420   vat_main_t *vam = &vat_main;
9421   vat_json_node_t *node = NULL;
9422   struct in6_addr addr;
9423
9424   if (VAT_JSON_ARRAY != vam->json_tree.type)
9425     {
9426       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9427       vat_json_init_array (&vam->json_tree);
9428     }
9429   node = vat_json_array_add (&vam->json_tree);
9430
9431   vat_json_init_object (node);
9432
9433   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9434   vat_json_object_add_ip6 (node, "our_address", addr);
9435   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9436   vat_json_object_add_ip6 (node, "client_address", addr);
9437
9438   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9439   vat_json_init_array (lc);
9440   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9441   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9442   vat_json_object_add_uint (node, "remote_cookie",
9443                             clib_net_to_host_u64 (mp->remote_cookie));
9444
9445   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9446   vat_json_object_add_uint (node, "local_session_id",
9447                             clib_net_to_host_u32 (mp->local_session_id));
9448   vat_json_object_add_uint (node, "remote_session_id",
9449                             clib_net_to_host_u32 (mp->remote_session_id));
9450   vat_json_object_add_string_copy (node, "l2_sublayer",
9451                                    mp->l2_sublayer_present ? (u8 *) "present"
9452                                    : (u8 *) "absent");
9453 }
9454
9455 static int
9456 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9457 {
9458   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9459   f64 timeout;
9460
9461   /* Get list of l2tpv3-tunnel interfaces */
9462   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9463   S;
9464
9465   /* Use a control ping for synchronization */
9466   {
9467     vl_api_control_ping_t *mp;
9468     M (CONTROL_PING, control_ping);
9469     S;
9470   }
9471   W;
9472 }
9473
9474
9475 static void vl_api_sw_interface_tap_details_t_handler
9476   (vl_api_sw_interface_tap_details_t * mp)
9477 {
9478   vat_main_t *vam = &vat_main;
9479
9480   fformat (vam->ofp, "%-16s %d\n",
9481            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9482 }
9483
9484 static void vl_api_sw_interface_tap_details_t_handler_json
9485   (vl_api_sw_interface_tap_details_t * mp)
9486 {
9487   vat_main_t *vam = &vat_main;
9488   vat_json_node_t *node = NULL;
9489
9490   if (VAT_JSON_ARRAY != vam->json_tree.type)
9491     {
9492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9493       vat_json_init_array (&vam->json_tree);
9494     }
9495   node = vat_json_array_add (&vam->json_tree);
9496
9497   vat_json_init_object (node);
9498   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9499   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9500 }
9501
9502 static int
9503 api_sw_interface_tap_dump (vat_main_t * vam)
9504 {
9505   vl_api_sw_interface_tap_dump_t *mp;
9506   f64 timeout;
9507
9508   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9509   /* Get list of tap interfaces */
9510   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9511   S;
9512
9513   /* Use a control ping for synchronization */
9514   {
9515     vl_api_control_ping_t *mp;
9516     M (CONTROL_PING, control_ping);
9517     S;
9518   }
9519   W;
9520 }
9521
9522 static uword unformat_vxlan_decap_next
9523   (unformat_input_t * input, va_list * args)
9524 {
9525   u32 *result = va_arg (*args, u32 *);
9526   u32 tmp;
9527
9528   if (unformat (input, "drop"))
9529     *result = VXLAN_INPUT_NEXT_DROP;
9530   else if (unformat (input, "ip4"))
9531     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9532   else if (unformat (input, "ip6"))
9533     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9534   else if (unformat (input, "l2"))
9535     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9536   else if (unformat (input, "%d", &tmp))
9537     *result = tmp;
9538   else
9539     return 0;
9540   return 1;
9541 }
9542
9543 static int
9544 api_vxlan_add_del_tunnel (vat_main_t * vam)
9545 {
9546   unformat_input_t *line_input = vam->input;
9547   vl_api_vxlan_add_del_tunnel_t *mp;
9548   f64 timeout;
9549   ip4_address_t src4, dst4;
9550   ip6_address_t src6, dst6;
9551   u8 is_add = 1;
9552   u8 ipv4_set = 0, ipv6_set = 0;
9553   u8 src_set = 0;
9554   u8 dst_set = 0;
9555   u32 encap_vrf_id = 0;
9556   u32 decap_next_index = ~0;
9557   u32 vni = 0;
9558
9559   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (line_input, "del"))
9562         is_add = 0;
9563       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9564         {
9565           ipv4_set = 1;
9566           src_set = 1;
9567         }
9568       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9569         {
9570           ipv4_set = 1;
9571           dst_set = 1;
9572         }
9573       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9574         {
9575           ipv6_set = 1;
9576           src_set = 1;
9577         }
9578       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9579         {
9580           ipv6_set = 1;
9581           dst_set = 1;
9582         }
9583       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9584         ;
9585       else if (unformat (line_input, "decap-next %U",
9586                          unformat_vxlan_decap_next, &decap_next_index))
9587         ;
9588       else if (unformat (line_input, "vni %d", &vni))
9589         ;
9590       else
9591         {
9592           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9593           return -99;
9594         }
9595     }
9596
9597   if (src_set == 0)
9598     {
9599       errmsg ("tunnel src address not specified\n");
9600       return -99;
9601     }
9602   if (dst_set == 0)
9603     {
9604       errmsg ("tunnel dst address not specified\n");
9605       return -99;
9606     }
9607
9608   if (ipv4_set && ipv6_set)
9609     {
9610       errmsg ("both IPv4 and IPv6 addresses specified");
9611       return -99;
9612     }
9613
9614   if ((vni == 0) || (vni >> 24))
9615     {
9616       errmsg ("vni not specified or out of range\n");
9617       return -99;
9618     }
9619
9620   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9621
9622   if (ipv6_set)
9623     {
9624       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9625       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9626     }
9627   else
9628     {
9629       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9630       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9631     }
9632   mp->encap_vrf_id = ntohl (encap_vrf_id);
9633   mp->decap_next_index = ntohl (decap_next_index);
9634   mp->vni = ntohl (vni);
9635   mp->is_add = is_add;
9636   mp->is_ipv6 = ipv6_set;
9637
9638   S;
9639   W;
9640   /* NOTREACHED */
9641   return 0;
9642 }
9643
9644 static void vl_api_vxlan_tunnel_details_t_handler
9645   (vl_api_vxlan_tunnel_details_t * mp)
9646 {
9647   vat_main_t *vam = &vat_main;
9648
9649   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9650            ntohl (mp->sw_if_index),
9651            format_ip46_address, &(mp->src_address[0]),
9652            IP46_TYPE_ANY,
9653            format_ip46_address, &(mp->dst_address[0]),
9654            IP46_TYPE_ANY,
9655            ntohl (mp->encap_vrf_id),
9656            ntohl (mp->decap_next_index), ntohl (mp->vni));
9657 }
9658
9659 static void vl_api_vxlan_tunnel_details_t_handler_json
9660   (vl_api_vxlan_tunnel_details_t * mp)
9661 {
9662   vat_main_t *vam = &vat_main;
9663   vat_json_node_t *node = NULL;
9664   struct in_addr ip4;
9665   struct in6_addr ip6;
9666
9667   if (VAT_JSON_ARRAY != vam->json_tree.type)
9668     {
9669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9670       vat_json_init_array (&vam->json_tree);
9671     }
9672   node = vat_json_array_add (&vam->json_tree);
9673
9674   vat_json_init_object (node);
9675   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9676   if (mp->is_ipv6)
9677     {
9678       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9679       vat_json_object_add_ip6 (node, "src_address", ip6);
9680       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9681       vat_json_object_add_ip6 (node, "dst_address", ip6);
9682     }
9683   else
9684     {
9685       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9686       vat_json_object_add_ip4 (node, "src_address", ip4);
9687       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9688       vat_json_object_add_ip4 (node, "dst_address", ip4);
9689     }
9690   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9691   vat_json_object_add_uint (node, "decap_next_index",
9692                             ntohl (mp->decap_next_index));
9693   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9694   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9695 }
9696
9697 static int
9698 api_vxlan_tunnel_dump (vat_main_t * vam)
9699 {
9700   unformat_input_t *i = vam->input;
9701   vl_api_vxlan_tunnel_dump_t *mp;
9702   f64 timeout;
9703   u32 sw_if_index;
9704   u8 sw_if_index_set = 0;
9705
9706   /* Parse args required to build the message */
9707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708     {
9709       if (unformat (i, "sw_if_index %d", &sw_if_index))
9710         sw_if_index_set = 1;
9711       else
9712         break;
9713     }
9714
9715   if (sw_if_index_set == 0)
9716     {
9717       sw_if_index = ~0;
9718     }
9719
9720   if (!vam->json_output)
9721     {
9722       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9723                "sw_if_index", "src_address", "dst_address",
9724                "encap_vrf_id", "decap_next_index", "vni");
9725     }
9726
9727   /* Get list of vxlan-tunnel interfaces */
9728   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9729
9730   mp->sw_if_index = htonl (sw_if_index);
9731
9732   S;
9733
9734   /* Use a control ping for synchronization */
9735   {
9736     vl_api_control_ping_t *mp;
9737     M (CONTROL_PING, control_ping);
9738     S;
9739   }
9740   W;
9741 }
9742
9743 static int
9744 api_gre_add_del_tunnel (vat_main_t * vam)
9745 {
9746   unformat_input_t *line_input = vam->input;
9747   vl_api_gre_add_del_tunnel_t *mp;
9748   f64 timeout;
9749   ip4_address_t src4, dst4;
9750   u8 is_add = 1;
9751   u8 teb = 0;
9752   u8 src_set = 0;
9753   u8 dst_set = 0;
9754   u32 outer_fib_id = 0;
9755
9756   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9757     {
9758       if (unformat (line_input, "del"))
9759         is_add = 0;
9760       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9761         src_set = 1;
9762       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9763         dst_set = 1;
9764       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9765         ;
9766       else if (unformat (line_input, "teb"))
9767         teb = 1;
9768       else
9769         {
9770           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9771           return -99;
9772         }
9773     }
9774
9775   if (src_set == 0)
9776     {
9777       errmsg ("tunnel src address not specified\n");
9778       return -99;
9779     }
9780   if (dst_set == 0)
9781     {
9782       errmsg ("tunnel dst address not specified\n");
9783       return -99;
9784     }
9785
9786
9787   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9788
9789   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9790   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9791   mp->outer_fib_id = ntohl (outer_fib_id);
9792   mp->is_add = is_add;
9793   mp->teb = teb;
9794
9795   S;
9796   W;
9797   /* NOTREACHED */
9798   return 0;
9799 }
9800
9801 static void vl_api_gre_tunnel_details_t_handler
9802   (vl_api_gre_tunnel_details_t * mp)
9803 {
9804   vat_main_t *vam = &vat_main;
9805
9806   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9807            ntohl (mp->sw_if_index),
9808            format_ip4_address, &mp->src_address,
9809            format_ip4_address, &mp->dst_address,
9810            mp->teb, ntohl (mp->outer_fib_id));
9811 }
9812
9813 static void vl_api_gre_tunnel_details_t_handler_json
9814   (vl_api_gre_tunnel_details_t * mp)
9815 {
9816   vat_main_t *vam = &vat_main;
9817   vat_json_node_t *node = NULL;
9818   struct in_addr ip4;
9819
9820   if (VAT_JSON_ARRAY != vam->json_tree.type)
9821     {
9822       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9823       vat_json_init_array (&vam->json_tree);
9824     }
9825   node = vat_json_array_add (&vam->json_tree);
9826
9827   vat_json_init_object (node);
9828   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9829   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9830   vat_json_object_add_ip4 (node, "src_address", ip4);
9831   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9832   vat_json_object_add_ip4 (node, "dst_address", ip4);
9833   vat_json_object_add_uint (node, "teb", mp->teb);
9834   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9835 }
9836
9837 static int
9838 api_gre_tunnel_dump (vat_main_t * vam)
9839 {
9840   unformat_input_t *i = vam->input;
9841   vl_api_gre_tunnel_dump_t *mp;
9842   f64 timeout;
9843   u32 sw_if_index;
9844   u8 sw_if_index_set = 0;
9845
9846   /* Parse args required to build the message */
9847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9848     {
9849       if (unformat (i, "sw_if_index %d", &sw_if_index))
9850         sw_if_index_set = 1;
9851       else
9852         break;
9853     }
9854
9855   if (sw_if_index_set == 0)
9856     {
9857       sw_if_index = ~0;
9858     }
9859
9860   if (!vam->json_output)
9861     {
9862       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9863                "sw_if_index", "src_address", "dst_address", "teb",
9864                "outer_fib_id");
9865     }
9866
9867   /* Get list of gre-tunnel interfaces */
9868   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9869
9870   mp->sw_if_index = htonl (sw_if_index);
9871
9872   S;
9873
9874   /* Use a control ping for synchronization */
9875   {
9876     vl_api_control_ping_t *mp;
9877     M (CONTROL_PING, control_ping);
9878     S;
9879   }
9880   W;
9881 }
9882
9883 static int
9884 api_l2_fib_clear_table (vat_main_t * vam)
9885 {
9886 //  unformat_input_t * i = vam->input;
9887   vl_api_l2_fib_clear_table_t *mp;
9888   f64 timeout;
9889
9890   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9891
9892   S;
9893   W;
9894   /* NOTREACHED */
9895   return 0;
9896 }
9897
9898 static int
9899 api_l2_interface_efp_filter (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_l2_interface_efp_filter_t *mp;
9903   f64 timeout;
9904   u32 sw_if_index;
9905   u8 enable = 1;
9906   u8 sw_if_index_set = 0;
9907
9908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9909     {
9910       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9911         sw_if_index_set = 1;
9912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9913         sw_if_index_set = 1;
9914       else if (unformat (i, "enable"))
9915         enable = 1;
9916       else if (unformat (i, "disable"))
9917         enable = 0;
9918       else
9919         {
9920           clib_warning ("parse error '%U'", format_unformat_error, i);
9921           return -99;
9922         }
9923     }
9924
9925   if (sw_if_index_set == 0)
9926     {
9927       errmsg ("missing sw_if_index\n");
9928       return -99;
9929     }
9930
9931   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9932
9933   mp->sw_if_index = ntohl (sw_if_index);
9934   mp->enable_disable = enable;
9935
9936   S;
9937   W;
9938   /* NOTREACHED */
9939   return 0;
9940 }
9941
9942 #define foreach_vtr_op                          \
9943 _("disable",  L2_VTR_DISABLED)                  \
9944 _("push-1",  L2_VTR_PUSH_1)                     \
9945 _("push-2",  L2_VTR_PUSH_2)                     \
9946 _("pop-1",  L2_VTR_POP_1)                       \
9947 _("pop-2",  L2_VTR_POP_2)                       \
9948 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9949 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9950 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9951 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9952
9953 static int
9954 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9955 {
9956   unformat_input_t *i = vam->input;
9957   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9958   f64 timeout;
9959   u32 sw_if_index;
9960   u8 sw_if_index_set = 0;
9961   u8 vtr_op_set = 0;
9962   u32 vtr_op = 0;
9963   u32 push_dot1q = 1;
9964   u32 tag1 = ~0;
9965   u32 tag2 = ~0;
9966
9967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9968     {
9969       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9970         sw_if_index_set = 1;
9971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9972         sw_if_index_set = 1;
9973       else if (unformat (i, "vtr_op %d", &vtr_op))
9974         vtr_op_set = 1;
9975 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9976       foreach_vtr_op
9977 #undef _
9978         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9979         ;
9980       else if (unformat (i, "tag1 %d", &tag1))
9981         ;
9982       else if (unformat (i, "tag2 %d", &tag2))
9983         ;
9984       else
9985         {
9986           clib_warning ("parse error '%U'", format_unformat_error, i);
9987           return -99;
9988         }
9989     }
9990
9991   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9992     {
9993       errmsg ("missing vtr operation or sw_if_index\n");
9994       return -99;
9995     }
9996
9997   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9998     mp->sw_if_index = ntohl (sw_if_index);
9999   mp->vtr_op = ntohl (vtr_op);
10000   mp->push_dot1q = ntohl (push_dot1q);
10001   mp->tag1 = ntohl (tag1);
10002   mp->tag2 = ntohl (tag2);
10003
10004   S;
10005   W;
10006   /* NOTREACHED */
10007   return 0;
10008 }
10009
10010 static int
10011 api_create_vhost_user_if (vat_main_t * vam)
10012 {
10013   unformat_input_t *i = vam->input;
10014   vl_api_create_vhost_user_if_t *mp;
10015   f64 timeout;
10016   u8 *file_name;
10017   u8 is_server = 0;
10018   u8 file_name_set = 0;
10019   u32 custom_dev_instance = ~0;
10020   u8 hwaddr[6];
10021   u8 use_custom_mac = 0;
10022
10023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10024     {
10025       if (unformat (i, "socket %s", &file_name))
10026         {
10027           file_name_set = 1;
10028         }
10029       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10030         ;
10031       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10032         use_custom_mac = 1;
10033       else if (unformat (i, "server"))
10034         is_server = 1;
10035       else
10036         break;
10037     }
10038
10039   if (file_name_set == 0)
10040     {
10041       errmsg ("missing socket file name\n");
10042       return -99;
10043     }
10044
10045   if (vec_len (file_name) > 255)
10046     {
10047       errmsg ("socket file name too long\n");
10048       return -99;
10049     }
10050   vec_add1 (file_name, 0);
10051
10052   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10053
10054   mp->is_server = is_server;
10055   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10056   vec_free (file_name);
10057   if (custom_dev_instance != ~0)
10058     {
10059       mp->renumber = 1;
10060       mp->custom_dev_instance = ntohl (custom_dev_instance);
10061     }
10062   mp->use_custom_mac = use_custom_mac;
10063   clib_memcpy (mp->mac_address, hwaddr, 6);
10064
10065   S;
10066   W;
10067   /* NOTREACHED */
10068   return 0;
10069 }
10070
10071 static int
10072 api_modify_vhost_user_if (vat_main_t * vam)
10073 {
10074   unformat_input_t *i = vam->input;
10075   vl_api_modify_vhost_user_if_t *mp;
10076   f64 timeout;
10077   u8 *file_name;
10078   u8 is_server = 0;
10079   u8 file_name_set = 0;
10080   u32 custom_dev_instance = ~0;
10081   u8 sw_if_index_set = 0;
10082   u32 sw_if_index = (u32) ~ 0;
10083
10084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10085     {
10086       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10087         sw_if_index_set = 1;
10088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10089         sw_if_index_set = 1;
10090       else if (unformat (i, "socket %s", &file_name))
10091         {
10092           file_name_set = 1;
10093         }
10094       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10095         ;
10096       else if (unformat (i, "server"))
10097         is_server = 1;
10098       else
10099         break;
10100     }
10101
10102   if (sw_if_index_set == 0)
10103     {
10104       errmsg ("missing sw_if_index or interface name\n");
10105       return -99;
10106     }
10107
10108   if (file_name_set == 0)
10109     {
10110       errmsg ("missing socket file name\n");
10111       return -99;
10112     }
10113
10114   if (vec_len (file_name) > 255)
10115     {
10116       errmsg ("socket file name too long\n");
10117       return -99;
10118     }
10119   vec_add1 (file_name, 0);
10120
10121   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10122
10123   mp->sw_if_index = ntohl (sw_if_index);
10124   mp->is_server = is_server;
10125   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10126   vec_free (file_name);
10127   if (custom_dev_instance != ~0)
10128     {
10129       mp->renumber = 1;
10130       mp->custom_dev_instance = ntohl (custom_dev_instance);
10131     }
10132
10133   S;
10134   W;
10135   /* NOTREACHED */
10136   return 0;
10137 }
10138
10139 static int
10140 api_delete_vhost_user_if (vat_main_t * vam)
10141 {
10142   unformat_input_t *i = vam->input;
10143   vl_api_delete_vhost_user_if_t *mp;
10144   f64 timeout;
10145   u32 sw_if_index = ~0;
10146   u8 sw_if_index_set = 0;
10147
10148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10149     {
10150       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10151         sw_if_index_set = 1;
10152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10153         sw_if_index_set = 1;
10154       else
10155         break;
10156     }
10157
10158   if (sw_if_index_set == 0)
10159     {
10160       errmsg ("missing sw_if_index or interface name\n");
10161       return -99;
10162     }
10163
10164
10165   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10166
10167   mp->sw_if_index = ntohl (sw_if_index);
10168
10169   S;
10170   W;
10171   /* NOTREACHED */
10172   return 0;
10173 }
10174
10175 static void vl_api_sw_interface_vhost_user_details_t_handler
10176   (vl_api_sw_interface_vhost_user_details_t * mp)
10177 {
10178   vat_main_t *vam = &vat_main;
10179
10180   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10181            (char *) mp->interface_name,
10182            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10183            clib_net_to_host_u64 (mp->features), mp->is_server,
10184            ntohl (mp->num_regions), (char *) mp->sock_filename);
10185   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10186 }
10187
10188 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10189   (vl_api_sw_interface_vhost_user_details_t * mp)
10190 {
10191   vat_main_t *vam = &vat_main;
10192   vat_json_node_t *node = NULL;
10193
10194   if (VAT_JSON_ARRAY != vam->json_tree.type)
10195     {
10196       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10197       vat_json_init_array (&vam->json_tree);
10198     }
10199   node = vat_json_array_add (&vam->json_tree);
10200
10201   vat_json_init_object (node);
10202   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10203   vat_json_object_add_string_copy (node, "interface_name",
10204                                    mp->interface_name);
10205   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10206                             ntohl (mp->virtio_net_hdr_sz));
10207   vat_json_object_add_uint (node, "features",
10208                             clib_net_to_host_u64 (mp->features));
10209   vat_json_object_add_uint (node, "is_server", mp->is_server);
10210   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10211   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10212   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10213 }
10214
10215 static int
10216 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10217 {
10218   vl_api_sw_interface_vhost_user_dump_t *mp;
10219   f64 timeout;
10220   fformat (vam->ofp,
10221            "Interface name           idx hdr_sz features server regions filename\n");
10222
10223   /* Get list of vhost-user interfaces */
10224   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10225   S;
10226
10227   /* Use a control ping for synchronization */
10228   {
10229     vl_api_control_ping_t *mp;
10230     M (CONTROL_PING, control_ping);
10231     S;
10232   }
10233   W;
10234 }
10235
10236 static int
10237 api_show_version (vat_main_t * vam)
10238 {
10239   vl_api_show_version_t *mp;
10240   f64 timeout;
10241
10242   M (SHOW_VERSION, show_version);
10243
10244   S;
10245   W;
10246   /* NOTREACHED */
10247   return 0;
10248 }
10249
10250
10251 static int
10252 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10253 {
10254   unformat_input_t *line_input = vam->input;
10255   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10256   f64 timeout;
10257   ip4_address_t local4, remote4;
10258   ip6_address_t local6, remote6;
10259   u8 is_add = 1;
10260   u8 ipv4_set = 0, ipv6_set = 0;
10261   u8 local_set = 0;
10262   u8 remote_set = 0;
10263   u32 encap_vrf_id = 0;
10264   u32 decap_vrf_id = 0;
10265   u8 protocol = ~0;
10266   u32 vni;
10267   u8 vni_set = 0;
10268
10269   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10270     {
10271       if (unformat (line_input, "del"))
10272         is_add = 0;
10273       else if (unformat (line_input, "local %U",
10274                          unformat_ip4_address, &local4))
10275         {
10276           local_set = 1;
10277           ipv4_set = 1;
10278         }
10279       else if (unformat (line_input, "remote %U",
10280                          unformat_ip4_address, &remote4))
10281         {
10282           remote_set = 1;
10283           ipv4_set = 1;
10284         }
10285       else if (unformat (line_input, "local %U",
10286                          unformat_ip6_address, &local6))
10287         {
10288           local_set = 1;
10289           ipv6_set = 1;
10290         }
10291       else if (unformat (line_input, "remote %U",
10292                          unformat_ip6_address, &remote6))
10293         {
10294           remote_set = 1;
10295           ipv6_set = 1;
10296         }
10297       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10298         ;
10299       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10300         ;
10301       else if (unformat (line_input, "vni %d", &vni))
10302         vni_set = 1;
10303       else if (unformat (line_input, "next-ip4"))
10304         protocol = 1;
10305       else if (unformat (line_input, "next-ip6"))
10306         protocol = 2;
10307       else if (unformat (line_input, "next-ethernet"))
10308         protocol = 3;
10309       else if (unformat (line_input, "next-nsh"))
10310         protocol = 4;
10311       else
10312         {
10313           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10314           return -99;
10315         }
10316     }
10317
10318   if (local_set == 0)
10319     {
10320       errmsg ("tunnel local address not specified\n");
10321       return -99;
10322     }
10323   if (remote_set == 0)
10324     {
10325       errmsg ("tunnel remote address not specified\n");
10326       return -99;
10327     }
10328   if (ipv4_set && ipv6_set)
10329     {
10330       errmsg ("both IPv4 and IPv6 addresses specified");
10331       return -99;
10332     }
10333
10334   if (vni_set == 0)
10335     {
10336       errmsg ("vni not specified\n");
10337       return -99;
10338     }
10339
10340   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10341
10342
10343   if (ipv6_set)
10344     {
10345       clib_memcpy (&mp->local, &local6, sizeof (local6));
10346       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10347     }
10348   else
10349     {
10350       clib_memcpy (&mp->local, &local4, sizeof (local4));
10351       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10352     }
10353
10354   mp->encap_vrf_id = ntohl (encap_vrf_id);
10355   mp->decap_vrf_id = ntohl (decap_vrf_id);
10356   mp->protocol = ntohl (protocol);
10357   mp->vni = ntohl (vni);
10358   mp->is_add = is_add;
10359   mp->is_ipv6 = ipv6_set;
10360
10361   S;
10362   W;
10363   /* NOTREACHED */
10364   return 0;
10365 }
10366
10367 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10368   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10369 {
10370   vat_main_t *vam = &vat_main;
10371
10372   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10373            ntohl (mp->sw_if_index),
10374            format_ip46_address, &(mp->local[0]),
10375            format_ip46_address, &(mp->remote[0]),
10376            ntohl (mp->vni),
10377            ntohl (mp->protocol),
10378            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10379 }
10380
10381 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10382   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10383 {
10384   vat_main_t *vam = &vat_main;
10385   vat_json_node_t *node = NULL;
10386   struct in_addr ip4;
10387   struct in6_addr ip6;
10388
10389   if (VAT_JSON_ARRAY != vam->json_tree.type)
10390     {
10391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10392       vat_json_init_array (&vam->json_tree);
10393     }
10394   node = vat_json_array_add (&vam->json_tree);
10395
10396   vat_json_init_object (node);
10397   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10398   if (mp->is_ipv6)
10399     {
10400       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10401       vat_json_object_add_ip6 (node, "local", ip6);
10402       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10403       vat_json_object_add_ip6 (node, "remote", ip6);
10404     }
10405   else
10406     {
10407       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10408       vat_json_object_add_ip4 (node, "local", ip4);
10409       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10410       vat_json_object_add_ip4 (node, "remote", ip4);
10411     }
10412   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10413   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10414   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10415   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10416   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10417 }
10418
10419 static int
10420 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10421 {
10422   unformat_input_t *i = vam->input;
10423   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10424   f64 timeout;
10425   u32 sw_if_index;
10426   u8 sw_if_index_set = 0;
10427
10428   /* Parse args required to build the message */
10429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10430     {
10431       if (unformat (i, "sw_if_index %d", &sw_if_index))
10432         sw_if_index_set = 1;
10433       else
10434         break;
10435     }
10436
10437   if (sw_if_index_set == 0)
10438     {
10439       sw_if_index = ~0;
10440     }
10441
10442   if (!vam->json_output)
10443     {
10444       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10445                "sw_if_index", "local", "remote", "vni",
10446                "protocol", "encap_vrf_id", "decap_vrf_id");
10447     }
10448
10449   /* Get list of vxlan-tunnel interfaces */
10450   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10451
10452   mp->sw_if_index = htonl (sw_if_index);
10453
10454   S;
10455
10456   /* Use a control ping for synchronization */
10457   {
10458     vl_api_control_ping_t *mp;
10459     M (CONTROL_PING, control_ping);
10460     S;
10461   }
10462   W;
10463 }
10464
10465 u8 *
10466 format_l2_fib_mac_address (u8 * s, va_list * args)
10467 {
10468   u8 *a = va_arg (*args, u8 *);
10469
10470   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10471                  a[2], a[3], a[4], a[5], a[6], a[7]);
10472 }
10473
10474 static void vl_api_l2_fib_table_entry_t_handler
10475   (vl_api_l2_fib_table_entry_t * mp)
10476 {
10477   vat_main_t *vam = &vat_main;
10478
10479   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10480            "       %d       %d     %d\n",
10481            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10482            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10483            mp->bvi_mac);
10484 }
10485
10486 static void vl_api_l2_fib_table_entry_t_handler_json
10487   (vl_api_l2_fib_table_entry_t * mp)
10488 {
10489   vat_main_t *vam = &vat_main;
10490   vat_json_node_t *node = NULL;
10491
10492   if (VAT_JSON_ARRAY != vam->json_tree.type)
10493     {
10494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10495       vat_json_init_array (&vam->json_tree);
10496     }
10497   node = vat_json_array_add (&vam->json_tree);
10498
10499   vat_json_init_object (node);
10500   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10501   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10502   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10503   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10504   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10505   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10506 }
10507
10508 static int
10509 api_l2_fib_table_dump (vat_main_t * vam)
10510 {
10511   unformat_input_t *i = vam->input;
10512   vl_api_l2_fib_table_dump_t *mp;
10513   f64 timeout;
10514   u32 bd_id;
10515   u8 bd_id_set = 0;
10516
10517   /* Parse args required to build the message */
10518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10519     {
10520       if (unformat (i, "bd_id %d", &bd_id))
10521         bd_id_set = 1;
10522       else
10523         break;
10524     }
10525
10526   if (bd_id_set == 0)
10527     {
10528       errmsg ("missing bridge domain\n");
10529       return -99;
10530     }
10531
10532   fformat (vam->ofp,
10533            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10534
10535   /* Get list of l2 fib entries */
10536   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10537
10538   mp->bd_id = ntohl (bd_id);
10539   S;
10540
10541   /* Use a control ping for synchronization */
10542   {
10543     vl_api_control_ping_t *mp;
10544     M (CONTROL_PING, control_ping);
10545     S;
10546   }
10547   W;
10548 }
10549
10550
10551 static int
10552 api_interface_name_renumber (vat_main_t * vam)
10553 {
10554   unformat_input_t *line_input = vam->input;
10555   vl_api_interface_name_renumber_t *mp;
10556   u32 sw_if_index = ~0;
10557   f64 timeout;
10558   u32 new_show_dev_instance = ~0;
10559
10560   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10563                     &sw_if_index))
10564         ;
10565       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10566         ;
10567       else if (unformat (line_input, "new_show_dev_instance %d",
10568                          &new_show_dev_instance))
10569         ;
10570       else
10571         break;
10572     }
10573
10574   if (sw_if_index == ~0)
10575     {
10576       errmsg ("missing interface name or sw_if_index\n");
10577       return -99;
10578     }
10579
10580   if (new_show_dev_instance == ~0)
10581     {
10582       errmsg ("missing new_show_dev_instance\n");
10583       return -99;
10584     }
10585
10586   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10587
10588   mp->sw_if_index = ntohl (sw_if_index);
10589   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10590
10591   S;
10592   W;
10593 }
10594
10595 static int
10596 api_want_ip4_arp_events (vat_main_t * vam)
10597 {
10598   unformat_input_t *line_input = vam->input;
10599   vl_api_want_ip4_arp_events_t *mp;
10600   f64 timeout;
10601   ip4_address_t address;
10602   int address_set = 0;
10603   u32 enable_disable = 1;
10604
10605   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10606     {
10607       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10608         address_set = 1;
10609       else if (unformat (line_input, "del"))
10610         enable_disable = 0;
10611       else
10612         break;
10613     }
10614
10615   if (address_set == 0)
10616     {
10617       errmsg ("missing addresses\n");
10618       return -99;
10619     }
10620
10621   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10622   mp->enable_disable = enable_disable;
10623   mp->pid = getpid ();
10624   mp->address = address.as_u32;
10625
10626   S;
10627   W;
10628 }
10629
10630 static int
10631 api_want_ip6_nd_events (vat_main_t * vam)
10632 {
10633   unformat_input_t *line_input = vam->input;
10634   vl_api_want_ip6_nd_events_t *mp;
10635   f64 timeout;
10636   ip6_address_t address;
10637   int address_set = 0;
10638   u32 enable_disable = 1;
10639
10640   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10641     {
10642       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10643         address_set = 1;
10644       else if (unformat (line_input, "del"))
10645         enable_disable = 0;
10646       else
10647         break;
10648     }
10649
10650   if (address_set == 0)
10651     {
10652       errmsg ("missing addresses\n");
10653       return -99;
10654     }
10655
10656   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10657   mp->enable_disable = enable_disable;
10658   mp->pid = getpid ();
10659   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10660
10661   S;
10662   W;
10663 }
10664
10665 static int
10666 api_input_acl_set_interface (vat_main_t * vam)
10667 {
10668   unformat_input_t *i = vam->input;
10669   vl_api_input_acl_set_interface_t *mp;
10670   f64 timeout;
10671   u32 sw_if_index;
10672   int sw_if_index_set;
10673   u32 ip4_table_index = ~0;
10674   u32 ip6_table_index = ~0;
10675   u32 l2_table_index = ~0;
10676   u8 is_add = 1;
10677
10678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10679     {
10680       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10681         sw_if_index_set = 1;
10682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10683         sw_if_index_set = 1;
10684       else if (unformat (i, "del"))
10685         is_add = 0;
10686       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10687         ;
10688       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10689         ;
10690       else if (unformat (i, "l2-table %d", &l2_table_index))
10691         ;
10692       else
10693         {
10694           clib_warning ("parse error '%U'", format_unformat_error, i);
10695           return -99;
10696         }
10697     }
10698
10699   if (sw_if_index_set == 0)
10700     {
10701       errmsg ("missing interface name or sw_if_index\n");
10702       return -99;
10703     }
10704
10705   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10706
10707   mp->sw_if_index = ntohl (sw_if_index);
10708   mp->ip4_table_index = ntohl (ip4_table_index);
10709   mp->ip6_table_index = ntohl (ip6_table_index);
10710   mp->l2_table_index = ntohl (l2_table_index);
10711   mp->is_add = is_add;
10712
10713   S;
10714   W;
10715   /* NOTREACHED */
10716   return 0;
10717 }
10718
10719 static int
10720 api_ip_address_dump (vat_main_t * vam)
10721 {
10722   unformat_input_t *i = vam->input;
10723   vl_api_ip_address_dump_t *mp;
10724   u32 sw_if_index = ~0;
10725   u8 sw_if_index_set = 0;
10726   u8 ipv4_set = 0;
10727   u8 ipv6_set = 0;
10728   f64 timeout;
10729
10730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10731     {
10732       if (unformat (i, "sw_if_index %d", &sw_if_index))
10733         sw_if_index_set = 1;
10734       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10735         sw_if_index_set = 1;
10736       else if (unformat (i, "ipv4"))
10737         ipv4_set = 1;
10738       else if (unformat (i, "ipv6"))
10739         ipv6_set = 1;
10740       else
10741         break;
10742     }
10743
10744   if (ipv4_set && ipv6_set)
10745     {
10746       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10747       return -99;
10748     }
10749
10750   if ((!ipv4_set) && (!ipv6_set))
10751     {
10752       errmsg ("no ipv4 nor ipv6 flag set\n");
10753       return -99;
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       errmsg ("missing interface name or sw_if_index\n");
10759       return -99;
10760     }
10761
10762   vam->current_sw_if_index = sw_if_index;
10763   vam->is_ipv6 = ipv6_set;
10764
10765   M (IP_ADDRESS_DUMP, ip_address_dump);
10766   mp->sw_if_index = ntohl (sw_if_index);
10767   mp->is_ipv6 = ipv6_set;
10768   S;
10769
10770   /* Use a control ping for synchronization */
10771   {
10772     vl_api_control_ping_t *mp;
10773     M (CONTROL_PING, control_ping);
10774     S;
10775   }
10776   W;
10777 }
10778
10779 static int
10780 api_ip_dump (vat_main_t * vam)
10781 {
10782   vl_api_ip_dump_t *mp;
10783   unformat_input_t *in = vam->input;
10784   int ipv4_set = 0;
10785   int ipv6_set = 0;
10786   int is_ipv6;
10787   f64 timeout;
10788   int i;
10789
10790   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10791     {
10792       if (unformat (in, "ipv4"))
10793         ipv4_set = 1;
10794       else if (unformat (in, "ipv6"))
10795         ipv6_set = 1;
10796       else
10797         break;
10798     }
10799
10800   if (ipv4_set && ipv6_set)
10801     {
10802       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10803       return -99;
10804     }
10805
10806   if ((!ipv4_set) && (!ipv6_set))
10807     {
10808       errmsg ("no ipv4 nor ipv6 flag set\n");
10809       return -99;
10810     }
10811
10812   is_ipv6 = ipv6_set;
10813   vam->is_ipv6 = is_ipv6;
10814
10815   /* free old data */
10816   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10817     {
10818       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10819     }
10820   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10821
10822   M (IP_DUMP, ip_dump);
10823   mp->is_ipv6 = ipv6_set;
10824   S;
10825
10826   /* Use a control ping for synchronization */
10827   {
10828     vl_api_control_ping_t *mp;
10829     M (CONTROL_PING, control_ping);
10830     S;
10831   }
10832   W;
10833 }
10834
10835 static int
10836 api_ipsec_spd_add_del (vat_main_t * vam)
10837 {
10838 #if DPDK > 0
10839   unformat_input_t *i = vam->input;
10840   vl_api_ipsec_spd_add_del_t *mp;
10841   f64 timeout;
10842   u32 spd_id = ~0;
10843   u8 is_add = 1;
10844
10845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10846     {
10847       if (unformat (i, "spd_id %d", &spd_id))
10848         ;
10849       else if (unformat (i, "del"))
10850         is_add = 0;
10851       else
10852         {
10853           clib_warning ("parse error '%U'", format_unformat_error, i);
10854           return -99;
10855         }
10856     }
10857   if (spd_id == ~0)
10858     {
10859       errmsg ("spd_id must be set\n");
10860       return -99;
10861     }
10862
10863   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10864
10865   mp->spd_id = ntohl (spd_id);
10866   mp->is_add = is_add;
10867
10868   S;
10869   W;
10870   /* NOTREACHED */
10871   return 0;
10872 #else
10873   clib_warning ("unsupported (no dpdk)");
10874   return -99;
10875 #endif
10876 }
10877
10878 static int
10879 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10880 {
10881 #if DPDK > 0
10882   unformat_input_t *i = vam->input;
10883   vl_api_ipsec_interface_add_del_spd_t *mp;
10884   f64 timeout;
10885   u32 sw_if_index;
10886   u8 sw_if_index_set = 0;
10887   u32 spd_id = (u32) ~ 0;
10888   u8 is_add = 1;
10889
10890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10891     {
10892       if (unformat (i, "del"))
10893         is_add = 0;
10894       else if (unformat (i, "spd_id %d", &spd_id))
10895         ;
10896       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10897         sw_if_index_set = 1;
10898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10899         sw_if_index_set = 1;
10900       else
10901         {
10902           clib_warning ("parse error '%U'", format_unformat_error, i);
10903           return -99;
10904         }
10905
10906     }
10907
10908   if (spd_id == (u32) ~ 0)
10909     {
10910       errmsg ("spd_id must be set\n");
10911       return -99;
10912     }
10913
10914   if (sw_if_index_set == 0)
10915     {
10916       errmsg ("missing interface name or sw_if_index\n");
10917       return -99;
10918     }
10919
10920   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10921
10922   mp->spd_id = ntohl (spd_id);
10923   mp->sw_if_index = ntohl (sw_if_index);
10924   mp->is_add = is_add;
10925
10926   S;
10927   W;
10928   /* NOTREACHED */
10929   return 0;
10930 #else
10931   clib_warning ("unsupported (no dpdk)");
10932   return -99;
10933 #endif
10934 }
10935
10936 static int
10937 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10938 {
10939 #if DPDK > 0
10940   unformat_input_t *i = vam->input;
10941   vl_api_ipsec_spd_add_del_entry_t *mp;
10942   f64 timeout;
10943   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10944   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10945   i32 priority = 0;
10946   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10947   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10948   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10949   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10950
10951   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10952   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10953   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10954   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10955   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10956   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10957
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "del"))
10961         is_add = 0;
10962       if (unformat (i, "outbound"))
10963         is_outbound = 1;
10964       if (unformat (i, "inbound"))
10965         is_outbound = 0;
10966       else if (unformat (i, "spd_id %d", &spd_id))
10967         ;
10968       else if (unformat (i, "sa_id %d", &sa_id))
10969         ;
10970       else if (unformat (i, "priority %d", &priority))
10971         ;
10972       else if (unformat (i, "protocol %d", &protocol))
10973         ;
10974       else if (unformat (i, "lport_start %d", &lport_start))
10975         ;
10976       else if (unformat (i, "lport_stop %d", &lport_stop))
10977         ;
10978       else if (unformat (i, "rport_start %d", &rport_start))
10979         ;
10980       else if (unformat (i, "rport_stop %d", &rport_stop))
10981         ;
10982       else
10983         if (unformat
10984             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10985         {
10986           is_ipv6 = 0;
10987           is_ip_any = 0;
10988         }
10989       else
10990         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10991         {
10992           is_ipv6 = 0;
10993           is_ip_any = 0;
10994         }
10995       else
10996         if (unformat
10997             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10998         {
10999           is_ipv6 = 0;
11000           is_ip_any = 0;
11001         }
11002       else
11003         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11004         {
11005           is_ipv6 = 0;
11006           is_ip_any = 0;
11007         }
11008       else
11009         if (unformat
11010             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11011         {
11012           is_ipv6 = 1;
11013           is_ip_any = 0;
11014         }
11015       else
11016         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11017         {
11018           is_ipv6 = 1;
11019           is_ip_any = 0;
11020         }
11021       else
11022         if (unformat
11023             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11024         {
11025           is_ipv6 = 1;
11026           is_ip_any = 0;
11027         }
11028       else
11029         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11030         {
11031           is_ipv6 = 1;
11032           is_ip_any = 0;
11033         }
11034       else
11035         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11036         {
11037           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11038             {
11039               clib_warning ("unsupported action: 'resolve'");
11040               return -99;
11041             }
11042         }
11043       else
11044         {
11045           clib_warning ("parse error '%U'", format_unformat_error, i);
11046           return -99;
11047         }
11048
11049     }
11050
11051   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11052
11053   mp->spd_id = ntohl (spd_id);
11054   mp->priority = ntohl (priority);
11055   mp->is_outbound = is_outbound;
11056
11057   mp->is_ipv6 = is_ipv6;
11058   if (is_ipv6 || is_ip_any)
11059     {
11060       clib_memcpy (mp->remote_address_start, &raddr6_start,
11061                    sizeof (ip6_address_t));
11062       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11063                    sizeof (ip6_address_t));
11064       clib_memcpy (mp->local_address_start, &laddr6_start,
11065                    sizeof (ip6_address_t));
11066       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11067                    sizeof (ip6_address_t));
11068     }
11069   else
11070     {
11071       clib_memcpy (mp->remote_address_start, &raddr4_start,
11072                    sizeof (ip4_address_t));
11073       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11074                    sizeof (ip4_address_t));
11075       clib_memcpy (mp->local_address_start, &laddr4_start,
11076                    sizeof (ip4_address_t));
11077       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11078                    sizeof (ip4_address_t));
11079     }
11080   mp->protocol = (u8) protocol;
11081   mp->local_port_start = ntohs ((u16) lport_start);
11082   mp->local_port_stop = ntohs ((u16) lport_stop);
11083   mp->remote_port_start = ntohs ((u16) rport_start);
11084   mp->remote_port_stop = ntohs ((u16) rport_stop);
11085   mp->policy = (u8) policy;
11086   mp->sa_id = ntohl (sa_id);
11087   mp->is_add = is_add;
11088   mp->is_ip_any = is_ip_any;
11089   S;
11090   W;
11091   /* NOTREACHED */
11092   return 0;
11093 #else
11094   clib_warning ("unsupported (no dpdk)");
11095   return -99;
11096 #endif
11097 }
11098
11099 static int
11100 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11101 {
11102 #if DPDK > 0
11103   unformat_input_t *i = vam->input;
11104   vl_api_ipsec_sad_add_del_entry_t *mp;
11105   f64 timeout;
11106   u32 sad_id = 0, spi = 0;
11107   u8 *ck = 0, *ik = 0;
11108   u8 is_add = 1;
11109
11110   u8 protocol = IPSEC_PROTOCOL_AH;
11111   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11112   u32 crypto_alg = 0, integ_alg = 0;
11113   ip4_address_t tun_src4;
11114   ip4_address_t tun_dst4;
11115   ip6_address_t tun_src6;
11116   ip6_address_t tun_dst6;
11117
11118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11119     {
11120       if (unformat (i, "del"))
11121         is_add = 0;
11122       else if (unformat (i, "sad_id %d", &sad_id))
11123         ;
11124       else if (unformat (i, "spi %d", &spi))
11125         ;
11126       else if (unformat (i, "esp"))
11127         protocol = IPSEC_PROTOCOL_ESP;
11128       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11129         {
11130           is_tunnel = 1;
11131           is_tunnel_ipv6 = 0;
11132         }
11133       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11134         {
11135           is_tunnel = 1;
11136           is_tunnel_ipv6 = 0;
11137         }
11138       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11139         {
11140           is_tunnel = 1;
11141           is_tunnel_ipv6 = 1;
11142         }
11143       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11144         {
11145           is_tunnel = 1;
11146           is_tunnel_ipv6 = 1;
11147         }
11148       else
11149         if (unformat
11150             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11151         {
11152           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11153               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11154             {
11155               clib_warning ("unsupported crypto-alg: '%U'",
11156                             format_ipsec_crypto_alg, crypto_alg);
11157               return -99;
11158             }
11159         }
11160       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11161         ;
11162       else
11163         if (unformat
11164             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11165         {
11166           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11167               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11168             {
11169               clib_warning ("unsupported integ-alg: '%U'",
11170                             format_ipsec_integ_alg, integ_alg);
11171               return -99;
11172             }
11173         }
11174       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11175         ;
11176       else
11177         {
11178           clib_warning ("parse error '%U'", format_unformat_error, i);
11179           return -99;
11180         }
11181
11182     }
11183
11184   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11185
11186   mp->sad_id = ntohl (sad_id);
11187   mp->is_add = is_add;
11188   mp->protocol = protocol;
11189   mp->spi = ntohl (spi);
11190   mp->is_tunnel = is_tunnel;
11191   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11192   mp->crypto_algorithm = crypto_alg;
11193   mp->integrity_algorithm = integ_alg;
11194   mp->crypto_key_length = vec_len (ck);
11195   mp->integrity_key_length = vec_len (ik);
11196
11197   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11198     mp->crypto_key_length = sizeof (mp->crypto_key);
11199
11200   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11201     mp->integrity_key_length = sizeof (mp->integrity_key);
11202
11203   if (ck)
11204     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11205   if (ik)
11206     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11207
11208   if (is_tunnel)
11209     {
11210       if (is_tunnel_ipv6)
11211         {
11212           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11213                        sizeof (ip6_address_t));
11214           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11215                        sizeof (ip6_address_t));
11216         }
11217       else
11218         {
11219           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11220                        sizeof (ip4_address_t));
11221           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11222                        sizeof (ip4_address_t));
11223         }
11224     }
11225
11226   S;
11227   W;
11228   /* NOTREACHED */
11229   return 0;
11230 #else
11231   clib_warning ("unsupported (no dpdk)");
11232   return -99;
11233 #endif
11234 }
11235
11236 static int
11237 api_ipsec_sa_set_key (vat_main_t * vam)
11238 {
11239 #if DPDK > 0
11240   unformat_input_t *i = vam->input;
11241   vl_api_ipsec_sa_set_key_t *mp;
11242   f64 timeout;
11243   u32 sa_id;
11244   u8 *ck = 0, *ik = 0;
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "sa_id %d", &sa_id))
11249         ;
11250       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11251         ;
11252       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11253         ;
11254       else
11255         {
11256           clib_warning ("parse error '%U'", format_unformat_error, i);
11257           return -99;
11258         }
11259     }
11260
11261   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11262
11263   mp->sa_id = ntohl (sa_id);
11264   mp->crypto_key_length = vec_len (ck);
11265   mp->integrity_key_length = vec_len (ik);
11266
11267   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11268     mp->crypto_key_length = sizeof (mp->crypto_key);
11269
11270   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11271     mp->integrity_key_length = sizeof (mp->integrity_key);
11272
11273   if (ck)
11274     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11275   if (ik)
11276     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11277
11278   S;
11279   W;
11280   /* NOTREACHED */
11281   return 0;
11282 #else
11283   clib_warning ("unsupported (no dpdk)");
11284   return -99;
11285 #endif
11286 }
11287
11288 static int
11289 api_ikev2_profile_add_del (vat_main_t * vam)
11290 {
11291 #if DPDK > 0
11292   unformat_input_t *i = vam->input;
11293   vl_api_ikev2_profile_add_del_t *mp;
11294   f64 timeout;
11295   u8 is_add = 1;
11296   u8 *name = 0;
11297
11298   const char *valid_chars = "a-zA-Z0-9_";
11299
11300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (i, "del"))
11303         is_add = 0;
11304       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11305         vec_add1 (name, 0);
11306       else
11307         {
11308           errmsg ("parse error '%U'", format_unformat_error, i);
11309           return -99;
11310         }
11311     }
11312
11313   if (!vec_len (name))
11314     {
11315       errmsg ("profile name must be specified");
11316       return -99;
11317     }
11318
11319   if (vec_len (name) > 64)
11320     {
11321       errmsg ("profile name too long");
11322       return -99;
11323     }
11324
11325   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11326
11327   clib_memcpy (mp->name, name, vec_len (name));
11328   mp->is_add = is_add;
11329   vec_free (name);
11330
11331   S;
11332   W;
11333   /* NOTREACHED */
11334   return 0;
11335 #else
11336   clib_warning ("unsupported (no dpdk)");
11337   return -99;
11338 #endif
11339 }
11340
11341 static int
11342 api_ikev2_profile_set_auth (vat_main_t * vam)
11343 {
11344 #if DPDK > 0
11345   unformat_input_t *i = vam->input;
11346   vl_api_ikev2_profile_set_auth_t *mp;
11347   f64 timeout;
11348   u8 *name = 0;
11349   u8 *data = 0;
11350   u32 auth_method = 0;
11351   u8 is_hex = 0;
11352
11353   const char *valid_chars = "a-zA-Z0-9_";
11354
11355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11356     {
11357       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11358         vec_add1 (name, 0);
11359       else if (unformat (i, "auth_method %U",
11360                          unformat_ikev2_auth_method, &auth_method))
11361         ;
11362       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11363         is_hex = 1;
11364       else if (unformat (i, "auth_data %v", &data))
11365         ;
11366       else
11367         {
11368           errmsg ("parse error '%U'", format_unformat_error, i);
11369           return -99;
11370         }
11371     }
11372
11373   if (!vec_len (name))
11374     {
11375       errmsg ("profile name must be specified");
11376       return -99;
11377     }
11378
11379   if (vec_len (name) > 64)
11380     {
11381       errmsg ("profile name too long");
11382       return -99;
11383     }
11384
11385   if (!vec_len (data))
11386     {
11387       errmsg ("auth_data must be specified");
11388       return -99;
11389     }
11390
11391   if (!auth_method)
11392     {
11393       errmsg ("auth_method must be specified");
11394       return -99;
11395     }
11396
11397   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11398
11399   mp->is_hex = is_hex;
11400   mp->auth_method = (u8) auth_method;
11401   mp->data_len = vec_len (data);
11402   clib_memcpy (mp->name, name, vec_len (name));
11403   clib_memcpy (mp->data, data, vec_len (data));
11404   vec_free (name);
11405   vec_free (data);
11406
11407   S;
11408   W;
11409   /* NOTREACHED */
11410   return 0;
11411 #else
11412   clib_warning ("unsupported (no dpdk)");
11413   return -99;
11414 #endif
11415 }
11416
11417 static int
11418 api_ikev2_profile_set_id (vat_main_t * vam)
11419 {
11420 #if DPDK > 0
11421   unformat_input_t *i = vam->input;
11422   vl_api_ikev2_profile_set_id_t *mp;
11423   f64 timeout;
11424   u8 *name = 0;
11425   u8 *data = 0;
11426   u8 is_local = 0;
11427   u32 id_type = 0;
11428   ip4_address_t ip4;
11429
11430   const char *valid_chars = "a-zA-Z0-9_";
11431
11432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11433     {
11434       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11435         vec_add1 (name, 0);
11436       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11437         ;
11438       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11439         {
11440           data = vec_new (u8, 4);
11441           clib_memcpy (data, ip4.as_u8, 4);
11442         }
11443       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11444         ;
11445       else if (unformat (i, "id_data %v", &data))
11446         ;
11447       else if (unformat (i, "local"))
11448         is_local = 1;
11449       else if (unformat (i, "remote"))
11450         is_local = 0;
11451       else
11452         {
11453           errmsg ("parse error '%U'", format_unformat_error, i);
11454           return -99;
11455         }
11456     }
11457
11458   if (!vec_len (name))
11459     {
11460       errmsg ("profile name must be specified");
11461       return -99;
11462     }
11463
11464   if (vec_len (name) > 64)
11465     {
11466       errmsg ("profile name too long");
11467       return -99;
11468     }
11469
11470   if (!vec_len (data))
11471     {
11472       errmsg ("id_data must be specified");
11473       return -99;
11474     }
11475
11476   if (!id_type)
11477     {
11478       errmsg ("id_type must be specified");
11479       return -99;
11480     }
11481
11482   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11483
11484   mp->is_local = is_local;
11485   mp->id_type = (u8) id_type;
11486   mp->data_len = vec_len (data);
11487   clib_memcpy (mp->name, name, vec_len (name));
11488   clib_memcpy (mp->data, data, vec_len (data));
11489   vec_free (name);
11490   vec_free (data);
11491
11492   S;
11493   W;
11494   /* NOTREACHED */
11495   return 0;
11496 #else
11497   clib_warning ("unsupported (no dpdk)");
11498   return -99;
11499 #endif
11500 }
11501
11502 static int
11503 api_ikev2_profile_set_ts (vat_main_t * vam)
11504 {
11505 #if DPDK > 0
11506   unformat_input_t *i = vam->input;
11507   vl_api_ikev2_profile_set_ts_t *mp;
11508   f64 timeout;
11509   u8 *name = 0;
11510   u8 is_local = 0;
11511   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11512   ip4_address_t start_addr, end_addr;
11513
11514   const char *valid_chars = "a-zA-Z0-9_";
11515
11516   start_addr.as_u32 = 0;
11517   end_addr.as_u32 = (u32) ~ 0;
11518
11519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11520     {
11521       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11522         vec_add1 (name, 0);
11523       else if (unformat (i, "protocol %d", &proto))
11524         ;
11525       else if (unformat (i, "start_port %d", &start_port))
11526         ;
11527       else if (unformat (i, "end_port %d", &end_port))
11528         ;
11529       else
11530         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11531         ;
11532       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11533         ;
11534       else if (unformat (i, "local"))
11535         is_local = 1;
11536       else if (unformat (i, "remote"))
11537         is_local = 0;
11538       else
11539         {
11540           errmsg ("parse error '%U'", format_unformat_error, i);
11541           return -99;
11542         }
11543     }
11544
11545   if (!vec_len (name))
11546     {
11547       errmsg ("profile name must be specified");
11548       return -99;
11549     }
11550
11551   if (vec_len (name) > 64)
11552     {
11553       errmsg ("profile name too long");
11554       return -99;
11555     }
11556
11557   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11558
11559   mp->is_local = is_local;
11560   mp->proto = (u8) proto;
11561   mp->start_port = (u16) start_port;
11562   mp->end_port = (u16) end_port;
11563   mp->start_addr = start_addr.as_u32;
11564   mp->end_addr = end_addr.as_u32;
11565   clib_memcpy (mp->name, name, vec_len (name));
11566   vec_free (name);
11567
11568   S;
11569   W;
11570   /* NOTREACHED */
11571   return 0;
11572 #else
11573   clib_warning ("unsupported (no dpdk)");
11574   return -99;
11575 #endif
11576 }
11577
11578 static int
11579 api_ikev2_set_local_key (vat_main_t * vam)
11580 {
11581 #if DPDK > 0
11582   unformat_input_t *i = vam->input;
11583   vl_api_ikev2_set_local_key_t *mp;
11584   f64 timeout;
11585   u8 *file = 0;
11586
11587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11588     {
11589       if (unformat (i, "file %v", &file))
11590         vec_add1 (file, 0);
11591       else
11592         {
11593           errmsg ("parse error '%U'", format_unformat_error, i);
11594           return -99;
11595         }
11596     }
11597
11598   if (!vec_len (file))
11599     {
11600       errmsg ("RSA key file must be specified");
11601       return -99;
11602     }
11603
11604   if (vec_len (file) > 256)
11605     {
11606       errmsg ("file name too long");
11607       return -99;
11608     }
11609
11610   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11611
11612   clib_memcpy (mp->key_file, file, vec_len (file));
11613   vec_free (file);
11614
11615   S;
11616   W;
11617   /* NOTREACHED */
11618   return 0;
11619 #else
11620   clib_warning ("unsupported (no dpdk)");
11621   return -99;
11622 #endif
11623 }
11624
11625 /*
11626  * MAP
11627  */
11628 static int
11629 api_map_add_domain (vat_main_t * vam)
11630 {
11631   unformat_input_t *i = vam->input;
11632   vl_api_map_add_domain_t *mp;
11633   f64 timeout;
11634
11635   ip4_address_t ip4_prefix;
11636   ip6_address_t ip6_prefix;
11637   ip6_address_t ip6_src;
11638   u32 num_m_args = 0;
11639   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11640     0, psid_length = 0;
11641   u8 is_translation = 0;
11642   u32 mtu = 0;
11643   u32 ip6_src_len = 128;
11644
11645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11646     {
11647       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11648                     &ip4_prefix, &ip4_prefix_len))
11649         num_m_args++;
11650       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11651                          &ip6_prefix, &ip6_prefix_len))
11652         num_m_args++;
11653       else
11654         if (unformat
11655             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11656              &ip6_src_len))
11657         num_m_args++;
11658       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11659         num_m_args++;
11660       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11661         num_m_args++;
11662       else if (unformat (i, "psid-offset %d", &psid_offset))
11663         num_m_args++;
11664       else if (unformat (i, "psid-len %d", &psid_length))
11665         num_m_args++;
11666       else if (unformat (i, "mtu %d", &mtu))
11667         num_m_args++;
11668       else if (unformat (i, "map-t"))
11669         is_translation = 1;
11670       else
11671         {
11672           clib_warning ("parse error '%U'", format_unformat_error, i);
11673           return -99;
11674         }
11675     }
11676
11677   if (num_m_args < 3)
11678     {
11679       errmsg ("mandatory argument(s) missing\n");
11680       return -99;
11681     }
11682
11683   /* Construct the API message */
11684   M (MAP_ADD_DOMAIN, map_add_domain);
11685
11686   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11687   mp->ip4_prefix_len = ip4_prefix_len;
11688
11689   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11690   mp->ip6_prefix_len = ip6_prefix_len;
11691
11692   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11693   mp->ip6_src_prefix_len = ip6_src_len;
11694
11695   mp->ea_bits_len = ea_bits_len;
11696   mp->psid_offset = psid_offset;
11697   mp->psid_length = psid_length;
11698   mp->is_translation = is_translation;
11699   mp->mtu = htons (mtu);
11700
11701   /* send it... */
11702   S;
11703
11704   /* Wait for a reply, return good/bad news  */
11705   W;
11706 }
11707
11708 static int
11709 api_map_del_domain (vat_main_t * vam)
11710 {
11711   unformat_input_t *i = vam->input;
11712   vl_api_map_del_domain_t *mp;
11713   f64 timeout;
11714
11715   u32 num_m_args = 0;
11716   u32 index;
11717
11718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11719     {
11720       if (unformat (i, "index %d", &index))
11721         num_m_args++;
11722       else
11723         {
11724           clib_warning ("parse error '%U'", format_unformat_error, i);
11725           return -99;
11726         }
11727     }
11728
11729   if (num_m_args != 1)
11730     {
11731       errmsg ("mandatory argument(s) missing\n");
11732       return -99;
11733     }
11734
11735   /* Construct the API message */
11736   M (MAP_DEL_DOMAIN, map_del_domain);
11737
11738   mp->index = ntohl (index);
11739
11740   /* send it... */
11741   S;
11742
11743   /* Wait for a reply, return good/bad news  */
11744   W;
11745 }
11746
11747 static int
11748 api_map_add_del_rule (vat_main_t * vam)
11749 {
11750   unformat_input_t *i = vam->input;
11751   vl_api_map_add_del_rule_t *mp;
11752   f64 timeout;
11753   u8 is_add = 1;
11754   ip6_address_t ip6_dst;
11755   u32 num_m_args = 0, index, psid = 0;
11756
11757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11758     {
11759       if (unformat (i, "index %d", &index))
11760         num_m_args++;
11761       else if (unformat (i, "psid %d", &psid))
11762         num_m_args++;
11763       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11764         num_m_args++;
11765       else if (unformat (i, "del"))
11766         {
11767           is_add = 0;
11768         }
11769       else
11770         {
11771           clib_warning ("parse error '%U'", format_unformat_error, i);
11772           return -99;
11773         }
11774     }
11775
11776   /* Construct the API message */
11777   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11778
11779   mp->index = ntohl (index);
11780   mp->is_add = is_add;
11781   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11782   mp->psid = ntohs (psid);
11783
11784   /* send it... */
11785   S;
11786
11787   /* Wait for a reply, return good/bad news  */
11788   W;
11789 }
11790
11791 static int
11792 api_map_domain_dump (vat_main_t * vam)
11793 {
11794   vl_api_map_domain_dump_t *mp;
11795   f64 timeout;
11796
11797   /* Construct the API message */
11798   M (MAP_DOMAIN_DUMP, map_domain_dump);
11799
11800   /* send it... */
11801   S;
11802
11803   /* Use a control ping for synchronization */
11804   {
11805     vl_api_control_ping_t *mp;
11806     M (CONTROL_PING, control_ping);
11807     S;
11808   }
11809   W;
11810 }
11811
11812 static int
11813 api_map_rule_dump (vat_main_t * vam)
11814 {
11815   unformat_input_t *i = vam->input;
11816   vl_api_map_rule_dump_t *mp;
11817   f64 timeout;
11818   u32 domain_index = ~0;
11819
11820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11821     {
11822       if (unformat (i, "index %u", &domain_index))
11823         ;
11824       else
11825         break;
11826     }
11827
11828   if (domain_index == ~0)
11829     {
11830       clib_warning ("parse error: domain index expected");
11831       return -99;
11832     }
11833
11834   /* Construct the API message */
11835   M (MAP_RULE_DUMP, map_rule_dump);
11836
11837   mp->domain_index = htonl (domain_index);
11838
11839   /* send it... */
11840   S;
11841
11842   /* Use a control ping for synchronization */
11843   {
11844     vl_api_control_ping_t *mp;
11845     M (CONTROL_PING, control_ping);
11846     S;
11847   }
11848   W;
11849 }
11850
11851 static void vl_api_map_add_domain_reply_t_handler
11852   (vl_api_map_add_domain_reply_t * mp)
11853 {
11854   vat_main_t *vam = &vat_main;
11855   i32 retval = ntohl (mp->retval);
11856
11857   if (vam->async_mode)
11858     {
11859       vam->async_errors += (retval < 0);
11860     }
11861   else
11862     {
11863       vam->retval = retval;
11864       vam->result_ready = 1;
11865     }
11866 }
11867
11868 static void vl_api_map_add_domain_reply_t_handler_json
11869   (vl_api_map_add_domain_reply_t * mp)
11870 {
11871   vat_main_t *vam = &vat_main;
11872   vat_json_node_t node;
11873
11874   vat_json_init_object (&node);
11875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11876   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11877
11878   vat_json_print (vam->ofp, &node);
11879   vat_json_free (&node);
11880
11881   vam->retval = ntohl (mp->retval);
11882   vam->result_ready = 1;
11883 }
11884
11885 static int
11886 api_get_first_msg_id (vat_main_t * vam)
11887 {
11888   vl_api_get_first_msg_id_t *mp;
11889   f64 timeout;
11890   unformat_input_t *i = vam->input;
11891   u8 *name;
11892   u8 name_set = 0;
11893
11894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11895     {
11896       if (unformat (i, "client %s", &name))
11897         name_set = 1;
11898       else
11899         break;
11900     }
11901
11902   if (name_set == 0)
11903     {
11904       errmsg ("missing client name\n");
11905       return -99;
11906     }
11907   vec_add1 (name, 0);
11908
11909   if (vec_len (name) > 63)
11910     {
11911       errmsg ("client name too long\n");
11912       return -99;
11913     }
11914
11915   M (GET_FIRST_MSG_ID, get_first_msg_id);
11916   clib_memcpy (mp->name, name, vec_len (name));
11917   S;
11918   W;
11919   /* NOTREACHED */
11920   return 0;
11921 }
11922
11923 static int
11924 api_cop_interface_enable_disable (vat_main_t * vam)
11925 {
11926   unformat_input_t *line_input = vam->input;
11927   vl_api_cop_interface_enable_disable_t *mp;
11928   f64 timeout;
11929   u32 sw_if_index = ~0;
11930   u8 enable_disable = 1;
11931
11932   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11933     {
11934       if (unformat (line_input, "disable"))
11935         enable_disable = 0;
11936       if (unformat (line_input, "enable"))
11937         enable_disable = 1;
11938       else if (unformat (line_input, "%U", unformat_sw_if_index,
11939                          vam, &sw_if_index))
11940         ;
11941       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11942         ;
11943       else
11944         break;
11945     }
11946
11947   if (sw_if_index == ~0)
11948     {
11949       errmsg ("missing interface name or sw_if_index\n");
11950       return -99;
11951     }
11952
11953   /* Construct the API message */
11954   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11955   mp->sw_if_index = ntohl (sw_if_index);
11956   mp->enable_disable = enable_disable;
11957
11958   /* send it... */
11959   S;
11960   /* Wait for the reply */
11961   W;
11962 }
11963
11964 static int
11965 api_cop_whitelist_enable_disable (vat_main_t * vam)
11966 {
11967   unformat_input_t *line_input = vam->input;
11968   vl_api_cop_whitelist_enable_disable_t *mp;
11969   f64 timeout;
11970   u32 sw_if_index = ~0;
11971   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11972   u32 fib_id = 0;
11973
11974   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11975     {
11976       if (unformat (line_input, "ip4"))
11977         ip4 = 1;
11978       else if (unformat (line_input, "ip6"))
11979         ip6 = 1;
11980       else if (unformat (line_input, "default"))
11981         default_cop = 1;
11982       else if (unformat (line_input, "%U", unformat_sw_if_index,
11983                          vam, &sw_if_index))
11984         ;
11985       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11986         ;
11987       else if (unformat (line_input, "fib-id %d", &fib_id))
11988         ;
11989       else
11990         break;
11991     }
11992
11993   if (sw_if_index == ~0)
11994     {
11995       errmsg ("missing interface name or sw_if_index\n");
11996       return -99;
11997     }
11998
11999   /* Construct the API message */
12000   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12001   mp->sw_if_index = ntohl (sw_if_index);
12002   mp->fib_id = ntohl (fib_id);
12003   mp->ip4 = ip4;
12004   mp->ip6 = ip6;
12005   mp->default_cop = default_cop;
12006
12007   /* send it... */
12008   S;
12009   /* Wait for the reply */
12010   W;
12011 }
12012
12013 static int
12014 api_get_node_graph (vat_main_t * vam)
12015 {
12016   vl_api_get_node_graph_t *mp;
12017   f64 timeout;
12018
12019   M (GET_NODE_GRAPH, get_node_graph);
12020
12021   /* send it... */
12022   S;
12023   /* Wait for the reply */
12024   W;
12025 }
12026
12027 /* *INDENT-OFF* */
12028 /** Used for parsing LISP eids */
12029 typedef CLIB_PACKED(struct{
12030   u8 addr[16];   /**< eid address */
12031   u32 len;       /**< prefix length if IP */
12032   u8 type;      /**< type of eid */
12033 }) lisp_eid_vat_t;
12034 /* *INDENT-ON* */
12035
12036 static uword
12037 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12038 {
12039   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12040
12041   memset (a, 0, sizeof (a[0]));
12042
12043   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12044     {
12045       a->type = 0;              /* ipv4 type */
12046     }
12047   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12048     {
12049       a->type = 1;              /* ipv6 type */
12050     }
12051   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12052     {
12053       a->type = 2;              /* mac type */
12054     }
12055   else
12056     {
12057       return 0;
12058     }
12059
12060   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12061     {
12062       return 0;
12063     }
12064
12065   return 1;
12066 }
12067
12068 static int
12069 lisp_eid_size_vat (u8 type)
12070 {
12071   switch (type)
12072     {
12073     case 0:
12074       return 4;
12075     case 1:
12076       return 16;
12077     case 2:
12078       return 6;
12079     }
12080   return 0;
12081 }
12082
12083 static void
12084 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12085 {
12086   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12087 }
12088
12089 /* *INDENT-OFF* */
12090 /** Used for transferring locators via VPP API */
12091 typedef CLIB_PACKED(struct
12092 {
12093   u32 sw_if_index; /**< locator sw_if_index */
12094   u8 priority; /**< locator priority */
12095   u8 weight;   /**< locator weight */
12096 }) ls_locator_t;
12097 /* *INDENT-ON* */
12098
12099 static int
12100 api_lisp_add_del_locator_set (vat_main_t * vam)
12101 {
12102   unformat_input_t *input = vam->input;
12103   vl_api_lisp_add_del_locator_set_t *mp;
12104   f64 timeout = ~0;
12105   u8 is_add = 1;
12106   u8 *locator_set_name = NULL;
12107   u8 locator_set_name_set = 0;
12108   ls_locator_t locator, *locators = 0;
12109   u32 sw_if_index, priority, weight;
12110   u32 data_len = 0;
12111
12112   /* Parse args required to build the message */
12113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12114     {
12115       if (unformat (input, "del"))
12116         {
12117           is_add = 0;
12118         }
12119       else if (unformat (input, "locator-set %s", &locator_set_name))
12120         {
12121           locator_set_name_set = 1;
12122         }
12123       else if (unformat (input, "sw_if_index %u p %u w %u",
12124                          &sw_if_index, &priority, &weight))
12125         {
12126           locator.sw_if_index = htonl (sw_if_index);
12127           locator.priority = priority;
12128           locator.weight = weight;
12129           vec_add1 (locators, locator);
12130         }
12131       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12132                          vam, &sw_if_index, &priority, &weight))
12133         {
12134           locator.sw_if_index = htonl (sw_if_index);
12135           locator.priority = priority;
12136           locator.weight = weight;
12137           vec_add1 (locators, locator);
12138         }
12139       else
12140         break;
12141     }
12142
12143   if (locator_set_name_set == 0)
12144     {
12145       errmsg ("missing locator-set name");
12146       vec_free (locators);
12147       return -99;
12148     }
12149
12150   if (vec_len (locator_set_name) > 64)
12151     {
12152       errmsg ("locator-set name too long\n");
12153       vec_free (locator_set_name);
12154       vec_free (locators);
12155       return -99;
12156     }
12157   vec_add1 (locator_set_name, 0);
12158
12159   data_len = sizeof (ls_locator_t) * vec_len (locators);
12160
12161   /* Construct the API message */
12162   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12163
12164   mp->is_add = is_add;
12165   clib_memcpy (mp->locator_set_name, locator_set_name,
12166                vec_len (locator_set_name));
12167   vec_free (locator_set_name);
12168
12169   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12170   if (locators)
12171     clib_memcpy (mp->locators, locators, data_len);
12172   vec_free (locators);
12173
12174   /* send it... */
12175   S;
12176
12177   /* Wait for a reply... */
12178   W;
12179
12180   /* NOTREACHED */
12181   return 0;
12182 }
12183
12184 static int
12185 api_lisp_add_del_locator (vat_main_t * vam)
12186 {
12187   unformat_input_t *input = vam->input;
12188   vl_api_lisp_add_del_locator_t *mp;
12189   f64 timeout = ~0;
12190   u32 tmp_if_index = ~0;
12191   u32 sw_if_index = ~0;
12192   u8 sw_if_index_set = 0;
12193   u8 sw_if_index_if_name_set = 0;
12194   u32 priority = ~0;
12195   u8 priority_set = 0;
12196   u32 weight = ~0;
12197   u8 weight_set = 0;
12198   u8 is_add = 1;
12199   u8 *locator_set_name = NULL;
12200   u8 locator_set_name_set = 0;
12201
12202   /* Parse args required to build the message */
12203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12204     {
12205       if (unformat (input, "del"))
12206         {
12207           is_add = 0;
12208         }
12209       else if (unformat (input, "locator-set %s", &locator_set_name))
12210         {
12211           locator_set_name_set = 1;
12212         }
12213       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12214                          &tmp_if_index))
12215         {
12216           sw_if_index_if_name_set = 1;
12217           sw_if_index = tmp_if_index;
12218         }
12219       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12220         {
12221           sw_if_index_set = 1;
12222           sw_if_index = tmp_if_index;
12223         }
12224       else if (unformat (input, "p %d", &priority))
12225         {
12226           priority_set = 1;
12227         }
12228       else if (unformat (input, "w %d", &weight))
12229         {
12230           weight_set = 1;
12231         }
12232       else
12233         break;
12234     }
12235
12236   if (locator_set_name_set == 0)
12237     {
12238       errmsg ("missing locator-set name");
12239       return -99;
12240     }
12241
12242   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12243     {
12244       errmsg ("missing sw_if_index");
12245       vec_free (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 ("cannot use both params interface name and sw_if_index");
12252       vec_free (locator_set_name);
12253       return -99;
12254     }
12255
12256   if (priority_set == 0)
12257     {
12258       errmsg ("missing locator-set priority\n");
12259       vec_free (locator_set_name);
12260       return -99;
12261     }
12262
12263   if (weight_set == 0)
12264     {
12265       errmsg ("missing locator-set weight\n");
12266       vec_free (locator_set_name);
12267       return -99;
12268     }
12269
12270   if (vec_len (locator_set_name) > 64)
12271     {
12272       errmsg ("locator-set name too long\n");
12273       vec_free (locator_set_name);
12274       return -99;
12275     }
12276   vec_add1 (locator_set_name, 0);
12277
12278   /* Construct the API message */
12279   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12280
12281   mp->is_add = is_add;
12282   mp->sw_if_index = ntohl (sw_if_index);
12283   mp->priority = priority;
12284   mp->weight = weight;
12285   clib_memcpy (mp->locator_set_name, locator_set_name,
12286                vec_len (locator_set_name));
12287   vec_free (locator_set_name);
12288
12289   /* send it... */
12290   S;
12291
12292   /* Wait for a reply... */
12293   W;
12294
12295   /* NOTREACHED */
12296   return 0;
12297 }
12298
12299 static int
12300 api_lisp_add_del_local_eid (vat_main_t * vam)
12301 {
12302   unformat_input_t *input = vam->input;
12303   vl_api_lisp_add_del_local_eid_t *mp;
12304   f64 timeout = ~0;
12305   u8 is_add = 1;
12306   u8 eid_set = 0;
12307   lisp_eid_vat_t _eid, *eid = &_eid;
12308   u8 *locator_set_name = 0;
12309   u8 locator_set_name_set = 0;
12310   u32 vni = 0;
12311
12312   /* Parse args required to build the message */
12313   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12314     {
12315       if (unformat (input, "del"))
12316         {
12317           is_add = 0;
12318         }
12319       else if (unformat (input, "vni %d", &vni))
12320         {
12321           ;
12322         }
12323       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12324         {
12325           eid_set = 1;
12326         }
12327       else if (unformat (input, "locator-set %s", &locator_set_name))
12328         {
12329           locator_set_name_set = 1;
12330         }
12331       else
12332         break;
12333     }
12334
12335   if (locator_set_name_set == 0)
12336     {
12337       errmsg ("missing locator-set name\n");
12338       return -99;
12339     }
12340
12341   if (0 == eid_set)
12342     {
12343       errmsg ("EID address not set!");
12344       vec_free (locator_set_name);
12345       return -99;
12346     }
12347
12348   if (vec_len (locator_set_name) > 64)
12349     {
12350       errmsg ("locator-set name too long\n");
12351       vec_free (locator_set_name);
12352       return -99;
12353     }
12354   vec_add1 (locator_set_name, 0);
12355
12356   /* Construct the API message */
12357   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12358
12359   mp->is_add = is_add;
12360   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12361   mp->eid_type = eid->type;
12362   mp->prefix_len = eid->len;
12363   mp->vni = clib_host_to_net_u32 (vni);
12364   clib_memcpy (mp->locator_set_name, locator_set_name,
12365                vec_len (locator_set_name));
12366
12367   vec_free (locator_set_name);
12368
12369   /* send it... */
12370   S;
12371
12372   /* Wait for a reply... */
12373   W;
12374
12375   /* NOTREACHED */
12376   return 0;
12377 }
12378
12379 /* *INDENT-OFF* */
12380 /** Used for transferring locators via VPP API */
12381 typedef CLIB_PACKED(struct
12382 {
12383   u8 is_ip4; /**< is locator an IPv4 address? */
12384   u8 priority; /**< locator priority */
12385   u8 weight;   /**< locator weight */
12386   u8 addr[16]; /**< IPv4/IPv6 address */
12387 }) rloc_t;
12388 /* *INDENT-ON* */
12389
12390 static int
12391 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12392 {
12393   unformat_input_t *input = vam->input;
12394   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12395   f64 timeout = ~0;
12396   u8 is_add = 1;
12397   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12398   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12399   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12400   u32 action = ~0, p, w;
12401   ip4_address_t rmt_rloc4, lcl_rloc4;
12402   ip6_address_t rmt_rloc6, lcl_rloc6;
12403   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12404
12405   memset (&rloc, 0, sizeof (rloc));
12406
12407   /* Parse args required to build the message */
12408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12409     {
12410       if (unformat (input, "del"))
12411         {
12412           is_add = 0;
12413         }
12414       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12415         {
12416           rmt_eid_set = 1;
12417         }
12418       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12419         {
12420           lcl_eid_set = 1;
12421         }
12422       else if (unformat (input, "p %d w %d", &p, &w))
12423         {
12424           if (!curr_rloc)
12425             {
12426               errmsg ("No RLOC configured for setting priority/weight!");
12427               return -99;
12428             }
12429           curr_rloc->priority = p;
12430           curr_rloc->weight = w;
12431         }
12432       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12433                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12434         {
12435           rloc.is_ip4 = 1;
12436
12437           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12438           rloc.priority = rloc.weight = 0;
12439           vec_add1 (lcl_locs, rloc);
12440
12441           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12442           vec_add1 (rmt_locs, rloc);
12443           /* priority and weight saved in rmt loc */
12444           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12445         }
12446       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12447                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12448         {
12449           rloc.is_ip4 = 0;
12450           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12451           rloc.priority = rloc.weight = 0;
12452           vec_add1 (lcl_locs, rloc);
12453
12454           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12455           vec_add1 (rmt_locs, rloc);
12456           /* priority and weight saved in rmt loc */
12457           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12458         }
12459       else if (unformat (input, "action %d", &action))
12460         {
12461           ;
12462         }
12463       else
12464         {
12465           clib_warning ("parse error '%U'", format_unformat_error, input);
12466           return -99;
12467         }
12468     }
12469
12470   if (!rmt_eid_set)
12471     {
12472       errmsg ("remote eid addresses not set\n");
12473       return -99;
12474     }
12475
12476   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12477     {
12478       errmsg ("eid types don't match\n");
12479       return -99;
12480     }
12481
12482   if (0 == rmt_locs && (u32) ~ 0 == action)
12483     {
12484       errmsg ("action not set for negative mapping\n");
12485       return -99;
12486     }
12487
12488   /* Construct the API message */
12489   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12490
12491   mp->is_add = is_add;
12492   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12493   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12494   mp->eid_type = rmt_eid->type;
12495   mp->rmt_len = rmt_eid->len;
12496   mp->lcl_len = lcl_eid->len;
12497   mp->action = action;
12498
12499   if (0 != rmt_locs && 0 != lcl_locs)
12500     {
12501       mp->loc_num = vec_len (rmt_locs);
12502       clib_memcpy (mp->lcl_locs, lcl_locs,
12503                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12504       clib_memcpy (mp->rmt_locs, rmt_locs,
12505                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12506     }
12507   vec_free (lcl_locs);
12508   vec_free (rmt_locs);
12509
12510   /* send it... */
12511   S;
12512
12513   /* Wait for a reply... */
12514   W;
12515
12516   /* NOTREACHED */
12517   return 0;
12518 }
12519
12520 static int
12521 api_lisp_add_del_map_resolver (vat_main_t * vam)
12522 {
12523   unformat_input_t *input = vam->input;
12524   vl_api_lisp_add_del_map_resolver_t *mp;
12525   f64 timeout = ~0;
12526   u8 is_add = 1;
12527   u8 ipv4_set = 0;
12528   u8 ipv6_set = 0;
12529   ip4_address_t ipv4;
12530   ip6_address_t ipv6;
12531
12532   /* Parse args required to build the message */
12533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12534     {
12535       if (unformat (input, "del"))
12536         {
12537           is_add = 0;
12538         }
12539       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12540         {
12541           ipv4_set = 1;
12542         }
12543       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12544         {
12545           ipv6_set = 1;
12546         }
12547       else
12548         break;
12549     }
12550
12551   if (ipv4_set && ipv6_set)
12552     {
12553       errmsg ("both eid v4 and v6 addresses set\n");
12554       return -99;
12555     }
12556
12557   if (!ipv4_set && !ipv6_set)
12558     {
12559       errmsg ("eid addresses not set\n");
12560       return -99;
12561     }
12562
12563   /* Construct the API message */
12564   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12565
12566   mp->is_add = is_add;
12567   if (ipv6_set)
12568     {
12569       mp->is_ipv6 = 1;
12570       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12571     }
12572   else
12573     {
12574       mp->is_ipv6 = 0;
12575       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12576     }
12577
12578   /* send it... */
12579   S;
12580
12581   /* Wait for a reply... */
12582   W;
12583
12584   /* NOTREACHED */
12585   return 0;
12586 }
12587
12588 static int
12589 api_lisp_gpe_enable_disable (vat_main_t * vam)
12590 {
12591   unformat_input_t *input = vam->input;
12592   vl_api_lisp_gpe_enable_disable_t *mp;
12593   f64 timeout = ~0;
12594   u8 is_set = 0;
12595   u8 is_en = 1;
12596
12597   /* Parse args required to build the message */
12598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12599     {
12600       if (unformat (input, "enable"))
12601         {
12602           is_set = 1;
12603           is_en = 1;
12604         }
12605       else if (unformat (input, "disable"))
12606         {
12607           is_set = 1;
12608           is_en = 0;
12609         }
12610       else
12611         break;
12612     }
12613
12614   if (is_set == 0)
12615     {
12616       errmsg ("Value not set\n");
12617       return -99;
12618     }
12619
12620   /* Construct the API message */
12621   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12622
12623   mp->is_en = is_en;
12624
12625   /* send it... */
12626   S;
12627
12628   /* Wait for a reply... */
12629   W;
12630
12631   /* NOTREACHED */
12632   return 0;
12633 }
12634
12635 static int
12636 api_lisp_enable_disable (vat_main_t * vam)
12637 {
12638   unformat_input_t *input = vam->input;
12639   vl_api_lisp_enable_disable_t *mp;
12640   f64 timeout = ~0;
12641   u8 is_set = 0;
12642   u8 is_en = 0;
12643
12644   /* Parse args required to build the message */
12645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12646     {
12647       if (unformat (input, "enable"))
12648         {
12649           is_set = 1;
12650           is_en = 1;
12651         }
12652       else if (unformat (input, "disable"))
12653         {
12654           is_set = 1;
12655         }
12656       else
12657         break;
12658     }
12659
12660   if (!is_set)
12661     {
12662       errmsg ("Value not set\n");
12663       return -99;
12664     }
12665
12666   /* Construct the API message */
12667   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12668
12669   mp->is_en = is_en;
12670
12671   /* send it... */
12672   S;
12673
12674   /* Wait for a reply... */
12675   W;
12676
12677   /* NOTREACHED */
12678   return 0;
12679 }
12680
12681 static int
12682 api_show_lisp_map_request_mode (vat_main_t * vam)
12683 {
12684   f64 timeout = ~0;
12685   vl_api_show_lisp_map_request_mode_t *mp;
12686
12687   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12688
12689   /* send */
12690   S;
12691
12692   /* wait for reply */
12693   W;
12694
12695   return 0;
12696 }
12697
12698 static int
12699 api_lisp_map_request_mode (vat_main_t * vam)
12700 {
12701   f64 timeout = ~0;
12702   unformat_input_t *input = vam->input;
12703   vl_api_lisp_map_request_mode_t *mp;
12704   u8 mode = 0;
12705
12706   /* Parse args required to build the message */
12707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12708     {
12709       if (unformat (input, "dst-only"))
12710         mode = 0;
12711       else if (unformat (input, "src-dst"))
12712         mode = 1;
12713       else
12714         {
12715           errmsg ("parse error '%U'", format_unformat_error, input);
12716           return -99;
12717         }
12718     }
12719
12720   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12721
12722   mp->mode = mode;
12723
12724   /* send */
12725   S;
12726
12727   /* wait for reply */
12728   W;
12729
12730   /* notreached */
12731   return 0;
12732 }
12733
12734 /**
12735  * Enable/disable LISP proxy ITR.
12736  *
12737  * @param vam vpp API test context
12738  * @return return code
12739  */
12740 static int
12741 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12742 {
12743   f64 timeout = ~0;
12744   u8 ls_name_set = 0;
12745   unformat_input_t *input = vam->input;
12746   vl_api_lisp_pitr_set_locator_set_t *mp;
12747   u8 is_add = 1;
12748   u8 *ls_name = 0;
12749
12750   /* Parse args required to build the message */
12751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12752     {
12753       if (unformat (input, "del"))
12754         is_add = 0;
12755       else if (unformat (input, "locator-set %s", &ls_name))
12756         ls_name_set = 1;
12757       else
12758         {
12759           errmsg ("parse error '%U'", format_unformat_error, input);
12760           return -99;
12761         }
12762     }
12763
12764   if (!ls_name_set)
12765     {
12766       errmsg ("locator-set name not set!");
12767       return -99;
12768     }
12769
12770   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12771
12772   mp->is_add = is_add;
12773   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12774   vec_free (ls_name);
12775
12776   /* send */
12777   S;
12778
12779   /* wait for reply */
12780   W;
12781
12782   /* notreached */
12783   return 0;
12784 }
12785
12786 static int
12787 api_show_lisp_pitr (vat_main_t * vam)
12788 {
12789   vl_api_show_lisp_pitr_t *mp;
12790   f64 timeout = ~0;
12791
12792   if (!vam->json_output)
12793     {
12794       fformat (vam->ofp, "%=20s\n", "lisp status:");
12795     }
12796
12797   M (SHOW_LISP_PITR, show_lisp_pitr);
12798   /* send it... */
12799   S;
12800
12801   /* Wait for a reply... */
12802   W;
12803
12804   /* NOTREACHED */
12805   return 0;
12806 }
12807
12808 /**
12809  * Add/delete mapping between vni and vrf
12810  */
12811 static int
12812 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12813 {
12814   f64 timeout = ~0;
12815   unformat_input_t *input = vam->input;
12816   vl_api_lisp_eid_table_add_del_map_t *mp;
12817   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12818   u32 vni, vrf, bd_index;
12819
12820   /* Parse args required to build the message */
12821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12822     {
12823       if (unformat (input, "del"))
12824         is_add = 0;
12825       else if (unformat (input, "vrf %d", &vrf))
12826         vrf_set = 1;
12827       else if (unformat (input, "bd_index %d", &bd_index))
12828         bd_index_set = 1;
12829       else if (unformat (input, "vni %d", &vni))
12830         vni_set = 1;
12831       else
12832         break;
12833     }
12834
12835   if (!vni_set || (!vrf_set && !bd_index_set))
12836     {
12837       errmsg ("missing arguments!");
12838       return -99;
12839     }
12840
12841   if (vrf_set && bd_index_set)
12842     {
12843       errmsg ("error: both vrf and bd entered!");
12844       return -99;
12845     }
12846
12847   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12848
12849   mp->is_add = is_add;
12850   mp->vni = htonl (vni);
12851   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12852   mp->is_l2 = bd_index_set;
12853
12854   /* send */
12855   S;
12856
12857   /* wait for reply */
12858   W;
12859
12860   /* notreached */
12861   return 0;
12862 }
12863
12864 uword
12865 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12866 {
12867   u32 *action = va_arg (*args, u32 *);
12868   u8 *s = 0;
12869
12870   if (unformat (input, "%s", &s))
12871     {
12872       if (!strcmp ((char *) s, "no-action"))
12873         action[0] = 0;
12874       else if (!strcmp ((char *) s, "natively-forward"))
12875         action[0] = 1;
12876       else if (!strcmp ((char *) s, "send-map-request"))
12877         action[0] = 2;
12878       else if (!strcmp ((char *) s, "drop"))
12879         action[0] = 3;
12880       else
12881         {
12882           clib_warning ("invalid action: '%s'", s);
12883           action[0] = 3;
12884         }
12885     }
12886   else
12887     return 0;
12888
12889   vec_free (s);
12890   return 1;
12891 }
12892
12893 /**
12894  * Add/del remote mapping to/from LISP control plane
12895  *
12896  * @param vam vpp API test context
12897  * @return return code
12898  */
12899 static int
12900 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12901 {
12902   unformat_input_t *input = vam->input;
12903   vl_api_lisp_add_del_remote_mapping_t *mp;
12904   f64 timeout = ~0;
12905   u32 vni = 0;
12906   lisp_eid_vat_t _eid, *eid = &_eid;
12907   lisp_eid_vat_t _seid, *seid = &_seid;
12908   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12909   u32 action = ~0, p, w, data_len;
12910   ip4_address_t rloc4;
12911   ip6_address_t rloc6;
12912   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12913
12914   memset (&rloc, 0, sizeof (rloc));
12915
12916   /* Parse args required to build the message */
12917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12918     {
12919       if (unformat (input, "del-all"))
12920         {
12921           del_all = 1;
12922         }
12923       else if (unformat (input, "del"))
12924         {
12925           is_add = 0;
12926         }
12927       else if (unformat (input, "add"))
12928         {
12929           is_add = 1;
12930         }
12931       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12932         {
12933           eid_set = 1;
12934         }
12935       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12936         {
12937           seid_set = 1;
12938         }
12939       else if (unformat (input, "vni %d", &vni))
12940         {
12941           ;
12942         }
12943       else if (unformat (input, "p %d w %d", &p, &w))
12944         {
12945           if (!curr_rloc)
12946             {
12947               errmsg ("No RLOC configured for setting priority/weight!");
12948               return -99;
12949             }
12950           curr_rloc->priority = p;
12951           curr_rloc->weight = w;
12952         }
12953       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12954         {
12955           rloc.is_ip4 = 1;
12956           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12957           vec_add1 (rlocs, rloc);
12958           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12959         }
12960       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12961         {
12962           rloc.is_ip4 = 0;
12963           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12964           vec_add1 (rlocs, rloc);
12965           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12966         }
12967       else if (unformat (input, "action %U",
12968                          unformat_negative_mapping_action, &action))
12969         {
12970           ;
12971         }
12972       else
12973         {
12974           clib_warning ("parse error '%U'", format_unformat_error, input);
12975           return -99;
12976         }
12977     }
12978
12979   if (0 == eid_set)
12980     {
12981       errmsg ("missing params!");
12982       return -99;
12983     }
12984
12985   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12986     {
12987       errmsg ("no action set for negative map-reply!");
12988       return -99;
12989     }
12990
12991   data_len = vec_len (rlocs) * sizeof (rloc_t);
12992
12993   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
12994   mp->is_add = is_add;
12995   mp->vni = htonl (vni);
12996   mp->action = (u8) action;
12997   mp->is_src_dst = seid_set;
12998   mp->eid_len = eid->len;
12999   mp->seid_len = seid->len;
13000   mp->del_all = del_all;
13001   mp->eid_type = eid->type;
13002   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13003   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13004
13005   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13006   clib_memcpy (mp->rlocs, rlocs, data_len);
13007   vec_free (rlocs);
13008
13009   /* send it... */
13010   S;
13011
13012   /* Wait for a reply... */
13013   W;
13014
13015   /* NOTREACHED */
13016   return 0;
13017 }
13018
13019 /**
13020  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13021  * forwarding entries in data-plane accordingly.
13022  *
13023  * @param vam vpp API test context
13024  * @return return code
13025  */
13026 static int
13027 api_lisp_add_del_adjacency (vat_main_t * vam)
13028 {
13029   unformat_input_t *input = vam->input;
13030   vl_api_lisp_add_del_adjacency_t *mp;
13031   f64 timeout = ~0;
13032   u32 vni = 0;
13033   ip4_address_t leid4, reid4;
13034   ip6_address_t leid6, reid6;
13035   u8 reid_mac[6] = { 0 };
13036   u8 leid_mac[6] = { 0 };
13037   u8 reid_type, leid_type;
13038   u32 leid_len = 0, reid_len = 0, len;
13039   u8 is_add = 1;
13040
13041   leid_type = reid_type = (u8) ~ 0;
13042
13043   /* Parse args required to build the message */
13044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13045     {
13046       if (unformat (input, "del"))
13047         {
13048           is_add = 0;
13049         }
13050       else if (unformat (input, "add"))
13051         {
13052           is_add = 1;
13053         }
13054       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13055                          &reid4, &len))
13056         {
13057           reid_type = 0;        /* ipv4 */
13058           reid_len = len;
13059         }
13060       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13061                          &reid6, &len))
13062         {
13063           reid_type = 1;        /* ipv6 */
13064           reid_len = len;
13065         }
13066       else if (unformat (input, "reid %U", unformat_ethernet_address,
13067                          reid_mac))
13068         {
13069           reid_type = 2;        /* mac */
13070         }
13071       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13072                          &leid4, &len))
13073         {
13074           leid_type = 0;        /* ipv4 */
13075           leid_len = len;
13076         }
13077       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13078                          &leid6, &len))
13079         {
13080           leid_type = 1;        /* ipv6 */
13081           leid_len = len;
13082         }
13083       else if (unformat (input, "leid %U", unformat_ethernet_address,
13084                          leid_mac))
13085         {
13086           leid_type = 2;        /* mac */
13087         }
13088       else if (unformat (input, "vni %d", &vni))
13089         {
13090           ;
13091         }
13092       else
13093         {
13094           errmsg ("parse error '%U'", format_unformat_error, input);
13095           return -99;
13096         }
13097     }
13098
13099   if ((u8) ~ 0 == reid_type)
13100     {
13101       errmsg ("missing params!");
13102       return -99;
13103     }
13104
13105   if (leid_type != reid_type)
13106     {
13107       errmsg ("remote and local EIDs are of different types!");
13108       return -99;
13109     }
13110
13111   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13112   mp->is_add = is_add;
13113   mp->vni = htonl (vni);
13114   mp->leid_len = leid_len;
13115   mp->reid_len = reid_len;
13116   mp->eid_type = reid_type;
13117
13118   switch (mp->eid_type)
13119     {
13120     case 0:
13121       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13122       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13123       break;
13124     case 1:
13125       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13126       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13127       break;
13128     case 2:
13129       clib_memcpy (mp->leid, leid_mac, 6);
13130       clib_memcpy (mp->reid, reid_mac, 6);
13131       break;
13132     default:
13133       errmsg ("unknown EID type %d!", mp->eid_type);
13134       return 0;
13135     }
13136
13137   /* send it... */
13138   S;
13139
13140   /* Wait for a reply... */
13141   W;
13142
13143   /* NOTREACHED */
13144   return 0;
13145 }
13146
13147 static int
13148 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13149 {
13150   unformat_input_t *input = vam->input;
13151   vl_api_lisp_gpe_add_del_iface_t *mp;
13152   f64 timeout = ~0;
13153   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13154   u32 dp_table = 0, vni = 0;
13155
13156   /* Parse args required to build the message */
13157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13158     {
13159       if (unformat (input, "up"))
13160         {
13161           action_set = 1;
13162           is_add = 1;
13163         }
13164       else if (unformat (input, "down"))
13165         {
13166           action_set = 1;
13167           is_add = 0;
13168         }
13169       else if (unformat (input, "table_id %d", &dp_table))
13170         {
13171           dp_table_set = 1;
13172         }
13173       else if (unformat (input, "bd_id %d", &dp_table))
13174         {
13175           dp_table_set = 1;
13176           is_l2 = 1;
13177         }
13178       else if (unformat (input, "vni %d", &vni))
13179         {
13180           vni_set = 1;
13181         }
13182       else
13183         break;
13184     }
13185
13186   if (action_set == 0)
13187     {
13188       errmsg ("Action not set\n");
13189       return -99;
13190     }
13191   if (dp_table_set == 0 || vni_set == 0)
13192     {
13193       errmsg ("vni and dp_table must be set\n");
13194       return -99;
13195     }
13196
13197   /* Construct the API message */
13198   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13199
13200   mp->is_add = is_add;
13201   mp->dp_table = dp_table;
13202   mp->is_l2 = is_l2;
13203   mp->vni = vni;
13204
13205   /* send it... */
13206   S;
13207
13208   /* Wait for a reply... */
13209   W;
13210
13211   /* NOTREACHED */
13212   return 0;
13213 }
13214
13215 /**
13216  * Add/del map request itr rlocs from LISP control plane and updates
13217  *
13218  * @param vam vpp API test context
13219  * @return return code
13220  */
13221 static int
13222 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13223 {
13224   unformat_input_t *input = vam->input;
13225   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13226   f64 timeout = ~0;
13227   u8 *locator_set_name = 0;
13228   u8 locator_set_name_set = 0;
13229   u8 is_add = 1;
13230
13231   /* Parse args required to build the message */
13232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13233     {
13234       if (unformat (input, "del"))
13235         {
13236           is_add = 0;
13237         }
13238       else if (unformat (input, "%_%v%_", &locator_set_name))
13239         {
13240           locator_set_name_set = 1;
13241         }
13242       else
13243         {
13244           clib_warning ("parse error '%U'", format_unformat_error, input);
13245           return -99;
13246         }
13247     }
13248
13249   if (is_add && !locator_set_name_set)
13250     {
13251       errmsg ("itr-rloc is not set!");
13252       return -99;
13253     }
13254
13255   if (is_add && vec_len (locator_set_name) > 64)
13256     {
13257       errmsg ("itr-rloc locator-set name too long\n");
13258       vec_free (locator_set_name);
13259       return -99;
13260     }
13261
13262   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13263   mp->is_add = is_add;
13264   if (is_add)
13265     {
13266       clib_memcpy (mp->locator_set_name, locator_set_name,
13267                    vec_len (locator_set_name));
13268     }
13269   else
13270     {
13271       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13272     }
13273   vec_free (locator_set_name);
13274
13275   /* send it... */
13276   S;
13277
13278   /* Wait for a reply... */
13279   W;
13280
13281   /* NOTREACHED */
13282   return 0;
13283 }
13284
13285 static int
13286 api_lisp_locator_dump (vat_main_t * vam)
13287 {
13288   unformat_input_t *input = vam->input;
13289   vl_api_lisp_locator_dump_t *mp;
13290   f64 timeout = ~0;
13291   u8 is_index_set = 0, is_name_set = 0;
13292   u8 *ls_name = 0;
13293   u32 ls_index = ~0;
13294
13295   /* Parse args required to build the message */
13296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (input, "ls_name %_%v%_", &ls_name))
13299         {
13300           is_name_set = 1;
13301         }
13302       else if (unformat (input, "ls_index %d", &ls_index))
13303         {
13304           is_index_set = 1;
13305         }
13306       else
13307         {
13308           errmsg ("parse error '%U'", format_unformat_error, input);
13309           return -99;
13310         }
13311     }
13312
13313   if (!is_index_set && !is_name_set)
13314     {
13315       errmsg ("error: expected one of index or name!\n");
13316       return -99;
13317     }
13318
13319   if (is_index_set && is_name_set)
13320     {
13321       errmsg ("error: only one param expected!\n");
13322       return -99;
13323     }
13324
13325   if (vec_len (ls_name) > 62)
13326     {
13327       errmsg ("error: locator set name too long!");
13328       return -99;
13329     }
13330
13331   if (!vam->json_output)
13332     {
13333       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13334                "weight");
13335     }
13336
13337   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13338   mp->is_index_set = is_index_set;
13339
13340   if (is_index_set)
13341     mp->ls_index = clib_host_to_net_u32 (ls_index);
13342   else
13343     {
13344       vec_add1 (ls_name, 0);
13345       strncpy ((char *) mp->ls_name, (char *) ls_name,
13346                sizeof (mp->ls_name) - 1);
13347     }
13348
13349   /* send it... */
13350   S;
13351
13352   /* Use a control ping for synchronization */
13353   {
13354     vl_api_control_ping_t *mp;
13355     M (CONTROL_PING, control_ping);
13356     S;
13357   }
13358   /* Wait for a reply... */
13359   W;
13360
13361   /* NOTREACHED */
13362   return 0;
13363 }
13364
13365 static int
13366 api_lisp_locator_set_dump (vat_main_t * vam)
13367 {
13368   vl_api_lisp_locator_set_dump_t *mp;
13369   unformat_input_t *input = vam->input;
13370   f64 timeout = ~0;
13371   u8 filter = 0;
13372
13373   /* Parse args required to build the message */
13374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13375     {
13376       if (unformat (input, "local"))
13377         {
13378           filter = 1;
13379         }
13380       else if (unformat (input, "remote"))
13381         {
13382           filter = 2;
13383         }
13384       else
13385         {
13386           errmsg ("parse error '%U'", format_unformat_error, input);
13387           return -99;
13388         }
13389     }
13390
13391   if (!vam->json_output)
13392     {
13393       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13394     }
13395
13396   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13397
13398   mp->filter = filter;
13399
13400   /* send it... */
13401   S;
13402
13403   /* Use a control ping for synchronization */
13404   {
13405     vl_api_control_ping_t *mp;
13406     M (CONTROL_PING, control_ping);
13407     S;
13408   }
13409   /* Wait for a reply... */
13410   W;
13411
13412   /* NOTREACHED */
13413   return 0;
13414 }
13415
13416 static int
13417 api_lisp_eid_table_map_dump (vat_main_t * vam)
13418 {
13419   u8 is_l2 = 0;
13420   u8 mode_set = 0;
13421   unformat_input_t *input = vam->input;
13422   vl_api_lisp_eid_table_map_dump_t *mp;
13423   f64 timeout = ~0;
13424
13425   /* Parse args required to build the message */
13426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13427     {
13428       if (unformat (input, "l2"))
13429         {
13430           is_l2 = 1;
13431           mode_set = 1;
13432         }
13433       else if (unformat (input, "l3"))
13434         {
13435           is_l2 = 0;
13436           mode_set = 1;
13437         }
13438       else
13439         {
13440           errmsg ("parse error '%U'", format_unformat_error, input);
13441           return -99;
13442         }
13443     }
13444
13445   if (!mode_set)
13446     {
13447       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13448       return -99;
13449     }
13450
13451   if (!vam->json_output)
13452     {
13453       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13454     }
13455
13456   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13457   mp->is_l2 = is_l2;
13458
13459   /* send it... */
13460   S;
13461
13462   /* Use a control ping for synchronization */
13463   {
13464     vl_api_control_ping_t *mp;
13465     M (CONTROL_PING, control_ping);
13466     S;
13467   }
13468   /* Wait for a reply... */
13469   W;
13470
13471   /* NOTREACHED */
13472   return 0;
13473 }
13474
13475 static int
13476 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13477 {
13478   vl_api_lisp_eid_table_vni_dump_t *mp;
13479   f64 timeout = ~0;
13480
13481   if (!vam->json_output)
13482     {
13483       fformat (vam->ofp, "VNI\n");
13484     }
13485
13486   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13487
13488   /* send it... */
13489   S;
13490
13491   /* Use a control ping for synchronization */
13492   {
13493     vl_api_control_ping_t *mp;
13494     M (CONTROL_PING, control_ping);
13495     S;
13496   }
13497   /* Wait for a reply... */
13498   W;
13499
13500   /* NOTREACHED */
13501   return 0;
13502 }
13503
13504 static int
13505 api_lisp_eid_table_dump (vat_main_t * vam)
13506 {
13507   unformat_input_t *i = vam->input;
13508   vl_api_lisp_eid_table_dump_t *mp;
13509   f64 timeout = ~0;
13510   struct in_addr ip4;
13511   struct in6_addr ip6;
13512   u8 mac[6];
13513   u8 eid_type = ~0, eid_set = 0;
13514   u32 prefix_length = ~0, t, vni = 0;
13515   u8 filter = 0;
13516
13517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13518     {
13519       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13520         {
13521           eid_set = 1;
13522           eid_type = 0;
13523           prefix_length = t;
13524         }
13525       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13526         {
13527           eid_set = 1;
13528           eid_type = 1;
13529           prefix_length = t;
13530         }
13531       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13532         {
13533           eid_set = 1;
13534           eid_type = 2;
13535         }
13536       else if (unformat (i, "vni %d", &t))
13537         {
13538           vni = t;
13539         }
13540       else if (unformat (i, "local"))
13541         {
13542           filter = 1;
13543         }
13544       else if (unformat (i, "remote"))
13545         {
13546           filter = 2;
13547         }
13548       else
13549         {
13550           errmsg ("parse error '%U'", format_unformat_error, i);
13551           return -99;
13552         }
13553     }
13554
13555   if (!vam->json_output)
13556     {
13557       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13558                "ls_index", "ttl", "authoritative");
13559     }
13560
13561   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13562
13563   mp->filter = filter;
13564   if (eid_set)
13565     {
13566       mp->eid_set = 1;
13567       mp->vni = htonl (vni);
13568       mp->eid_type = eid_type;
13569       switch (eid_type)
13570         {
13571         case 0:
13572           mp->prefix_length = prefix_length;
13573           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13574           break;
13575         case 1:
13576           mp->prefix_length = prefix_length;
13577           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13578           break;
13579         case 2:
13580           clib_memcpy (mp->eid, mac, sizeof (mac));
13581           break;
13582         default:
13583           errmsg ("unknown EID type %d!", eid_type);
13584           return -99;
13585         }
13586     }
13587
13588   /* send it... */
13589   S;
13590
13591   /* Use a control ping for synchronization */
13592   {
13593     vl_api_control_ping_t *mp;
13594     M (CONTROL_PING, control_ping);
13595     S;
13596   }
13597
13598   /* Wait for a reply... */
13599   W;
13600
13601   /* NOTREACHED */
13602   return 0;
13603 }
13604
13605 static int
13606 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13607 {
13608   vl_api_lisp_gpe_tunnel_dump_t *mp;
13609   f64 timeout = ~0;
13610
13611   if (!vam->json_output)
13612     {
13613       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13614                "%=16s%=16s%=16s%=16s%=16s\n",
13615                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13616                "Decap next", "Lisp version", "Flags", "Next protocol",
13617                "ver_res", "res", "iid");
13618     }
13619
13620   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13621   /* send it... */
13622   S;
13623
13624   /* Use a control ping for synchronization */
13625   {
13626     vl_api_control_ping_t *mp;
13627     M (CONTROL_PING, control_ping);
13628     S;
13629   }
13630   /* Wait for a reply... */
13631   W;
13632
13633   /* NOTREACHED */
13634   return 0;
13635 }
13636
13637 static int
13638 api_lisp_map_resolver_dump (vat_main_t * vam)
13639 {
13640   vl_api_lisp_map_resolver_dump_t *mp;
13641   f64 timeout = ~0;
13642
13643   if (!vam->json_output)
13644     {
13645       fformat (vam->ofp, "%=20s\n", "Map resolver");
13646     }
13647
13648   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13649   /* send it... */
13650   S;
13651
13652   /* Use a control ping for synchronization */
13653   {
13654     vl_api_control_ping_t *mp;
13655     M (CONTROL_PING, control_ping);
13656     S;
13657   }
13658   /* Wait for a reply... */
13659   W;
13660
13661   /* NOTREACHED */
13662   return 0;
13663 }
13664
13665 static int
13666 api_show_lisp_status (vat_main_t * vam)
13667 {
13668   vl_api_show_lisp_status_t *mp;
13669   f64 timeout = ~0;
13670
13671   if (!vam->json_output)
13672     {
13673       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13674     }
13675
13676   M (SHOW_LISP_STATUS, show_lisp_status);
13677   /* send it... */
13678   S;
13679   /* Wait for a reply... */
13680   W;
13681
13682   /* NOTREACHED */
13683   return 0;
13684 }
13685
13686 static int
13687 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13688 {
13689   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13690   f64 timeout = ~0;
13691
13692   if (!vam->json_output)
13693     {
13694       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13695     }
13696
13697   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13698   /* send it... */
13699   S;
13700   /* Wait for a reply... */
13701   W;
13702
13703   /* NOTREACHED */
13704   return 0;
13705 }
13706
13707 static int
13708 api_af_packet_create (vat_main_t * vam)
13709 {
13710   unformat_input_t *i = vam->input;
13711   vl_api_af_packet_create_t *mp;
13712   f64 timeout;
13713   u8 *host_if_name = 0;
13714   u8 hw_addr[6];
13715   u8 random_hw_addr = 1;
13716
13717   memset (hw_addr, 0, sizeof (hw_addr));
13718
13719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13720     {
13721       if (unformat (i, "name %s", &host_if_name))
13722         vec_add1 (host_if_name, 0);
13723       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13724         random_hw_addr = 0;
13725       else
13726         break;
13727     }
13728
13729   if (!vec_len (host_if_name))
13730     {
13731       errmsg ("host-interface name must be specified");
13732       return -99;
13733     }
13734
13735   if (vec_len (host_if_name) > 64)
13736     {
13737       errmsg ("host-interface name too long");
13738       return -99;
13739     }
13740
13741   M (AF_PACKET_CREATE, af_packet_create);
13742
13743   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13744   clib_memcpy (mp->hw_addr, hw_addr, 6);
13745   mp->use_random_hw_addr = random_hw_addr;
13746   vec_free (host_if_name);
13747
13748   S;
13749   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13750   /* NOTREACHED */
13751   return 0;
13752 }
13753
13754 static int
13755 api_af_packet_delete (vat_main_t * vam)
13756 {
13757   unformat_input_t *i = vam->input;
13758   vl_api_af_packet_delete_t *mp;
13759   f64 timeout;
13760   u8 *host_if_name = 0;
13761
13762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13763     {
13764       if (unformat (i, "name %s", &host_if_name))
13765         vec_add1 (host_if_name, 0);
13766       else
13767         break;
13768     }
13769
13770   if (!vec_len (host_if_name))
13771     {
13772       errmsg ("host-interface name must be specified");
13773       return -99;
13774     }
13775
13776   if (vec_len (host_if_name) > 64)
13777     {
13778       errmsg ("host-interface name too long");
13779       return -99;
13780     }
13781
13782   M (AF_PACKET_DELETE, af_packet_delete);
13783
13784   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13785   vec_free (host_if_name);
13786
13787   S;
13788   W;
13789   /* NOTREACHED */
13790   return 0;
13791 }
13792
13793 static int
13794 api_policer_add_del (vat_main_t * vam)
13795 {
13796   unformat_input_t *i = vam->input;
13797   vl_api_policer_add_del_t *mp;
13798   f64 timeout;
13799   u8 is_add = 1;
13800   u8 *name = 0;
13801   u32 cir = 0;
13802   u32 eir = 0;
13803   u64 cb = 0;
13804   u64 eb = 0;
13805   u8 rate_type = 0;
13806   u8 round_type = 0;
13807   u8 type = 0;
13808   u8 color_aware = 0;
13809   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13810
13811   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13812   conform_action.dscp = 0;
13813   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13814   exceed_action.dscp = 0;
13815   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13816   violate_action.dscp = 0;
13817
13818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13819     {
13820       if (unformat (i, "del"))
13821         is_add = 0;
13822       else if (unformat (i, "name %s", &name))
13823         vec_add1 (name, 0);
13824       else if (unformat (i, "cir %u", &cir))
13825         ;
13826       else if (unformat (i, "eir %u", &eir))
13827         ;
13828       else if (unformat (i, "cb %u", &cb))
13829         ;
13830       else if (unformat (i, "eb %u", &eb))
13831         ;
13832       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13833                          &rate_type))
13834         ;
13835       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13836                          &round_type))
13837         ;
13838       else if (unformat (i, "type %U", unformat_policer_type, &type))
13839         ;
13840       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13841                          &conform_action))
13842         ;
13843       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13844                          &exceed_action))
13845         ;
13846       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13847                          &violate_action))
13848         ;
13849       else if (unformat (i, "color-aware"))
13850         color_aware = 1;
13851       else
13852         break;
13853     }
13854
13855   if (!vec_len (name))
13856     {
13857       errmsg ("policer name must be specified");
13858       return -99;
13859     }
13860
13861   if (vec_len (name) > 64)
13862     {
13863       errmsg ("policer name too long");
13864       return -99;
13865     }
13866
13867   M (POLICER_ADD_DEL, policer_add_del);
13868
13869   clib_memcpy (mp->name, name, vec_len (name));
13870   vec_free (name);
13871   mp->is_add = is_add;
13872   mp->cir = cir;
13873   mp->eir = eir;
13874   mp->cb = cb;
13875   mp->eb = eb;
13876   mp->rate_type = rate_type;
13877   mp->round_type = round_type;
13878   mp->type = type;
13879   mp->conform_action_type = conform_action.action_type;
13880   mp->conform_dscp = conform_action.dscp;
13881   mp->exceed_action_type = exceed_action.action_type;
13882   mp->exceed_dscp = exceed_action.dscp;
13883   mp->violate_action_type = violate_action.action_type;
13884   mp->violate_dscp = violate_action.dscp;
13885   mp->color_aware = color_aware;
13886
13887   S;
13888   W;
13889   /* NOTREACHED */
13890   return 0;
13891 }
13892
13893 static int
13894 api_policer_dump (vat_main_t * vam)
13895 {
13896   unformat_input_t *i = vam->input;
13897   vl_api_policer_dump_t *mp;
13898   f64 timeout = ~0;
13899   u8 *match_name = 0;
13900   u8 match_name_valid = 0;
13901
13902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13903     {
13904       if (unformat (i, "name %s", &match_name))
13905         {
13906           vec_add1 (match_name, 0);
13907           match_name_valid = 1;
13908         }
13909       else
13910         break;
13911     }
13912
13913   M (POLICER_DUMP, policer_dump);
13914   mp->match_name_valid = match_name_valid;
13915   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13916   vec_free (match_name);
13917   /* send it... */
13918   S;
13919
13920   /* Use a control ping for synchronization */
13921   {
13922     vl_api_control_ping_t *mp;
13923     M (CONTROL_PING, control_ping);
13924     S;
13925   }
13926   /* Wait for a reply... */
13927   W;
13928
13929   /* NOTREACHED */
13930   return 0;
13931 }
13932
13933 static int
13934 api_policer_classify_set_interface (vat_main_t * vam)
13935 {
13936   unformat_input_t *i = vam->input;
13937   vl_api_policer_classify_set_interface_t *mp;
13938   f64 timeout;
13939   u32 sw_if_index;
13940   int sw_if_index_set;
13941   u32 ip4_table_index = ~0;
13942   u32 ip6_table_index = ~0;
13943   u32 l2_table_index = ~0;
13944   u8 is_add = 1;
13945
13946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13947     {
13948       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13949         sw_if_index_set = 1;
13950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13951         sw_if_index_set = 1;
13952       else if (unformat (i, "del"))
13953         is_add = 0;
13954       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13955         ;
13956       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13957         ;
13958       else if (unformat (i, "l2-table %d", &l2_table_index))
13959         ;
13960       else
13961         {
13962           clib_warning ("parse error '%U'", format_unformat_error, i);
13963           return -99;
13964         }
13965     }
13966
13967   if (sw_if_index_set == 0)
13968     {
13969       errmsg ("missing interface name or sw_if_index\n");
13970       return -99;
13971     }
13972
13973   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13974
13975   mp->sw_if_index = ntohl (sw_if_index);
13976   mp->ip4_table_index = ntohl (ip4_table_index);
13977   mp->ip6_table_index = ntohl (ip6_table_index);
13978   mp->l2_table_index = ntohl (l2_table_index);
13979   mp->is_add = is_add;
13980
13981   S;
13982   W;
13983   /* NOTREACHED */
13984   return 0;
13985 }
13986
13987 static int
13988 api_policer_classify_dump (vat_main_t * vam)
13989 {
13990   unformat_input_t *i = vam->input;
13991   vl_api_policer_classify_dump_t *mp;
13992   f64 timeout = ~0;
13993   u8 type = POLICER_CLASSIFY_N_TABLES;
13994
13995   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13996     ;
13997   else
13998     {
13999       errmsg ("classify table type must be specified\n");
14000       return -99;
14001     }
14002
14003   if (!vam->json_output)
14004     {
14005       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14006     }
14007
14008   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14009   mp->type = type;
14010   /* send it... */
14011   S;
14012
14013   /* Use a control ping for synchronization */
14014   {
14015     vl_api_control_ping_t *mp;
14016     M (CONTROL_PING, control_ping);
14017     S;
14018   }
14019   /* Wait for a reply... */
14020   W;
14021
14022   /* NOTREACHED */
14023   return 0;
14024 }
14025
14026 static int
14027 api_netmap_create (vat_main_t * vam)
14028 {
14029   unformat_input_t *i = vam->input;
14030   vl_api_netmap_create_t *mp;
14031   f64 timeout;
14032   u8 *if_name = 0;
14033   u8 hw_addr[6];
14034   u8 random_hw_addr = 1;
14035   u8 is_pipe = 0;
14036   u8 is_master = 0;
14037
14038   memset (hw_addr, 0, sizeof (hw_addr));
14039
14040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14041     {
14042       if (unformat (i, "name %s", &if_name))
14043         vec_add1 (if_name, 0);
14044       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14045         random_hw_addr = 0;
14046       else if (unformat (i, "pipe"))
14047         is_pipe = 1;
14048       else if (unformat (i, "master"))
14049         is_master = 1;
14050       else if (unformat (i, "slave"))
14051         is_master = 0;
14052       else
14053         break;
14054     }
14055
14056   if (!vec_len (if_name))
14057     {
14058       errmsg ("interface name must be specified");
14059       return -99;
14060     }
14061
14062   if (vec_len (if_name) > 64)
14063     {
14064       errmsg ("interface name too long");
14065       return -99;
14066     }
14067
14068   M (NETMAP_CREATE, netmap_create);
14069
14070   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14071   clib_memcpy (mp->hw_addr, hw_addr, 6);
14072   mp->use_random_hw_addr = random_hw_addr;
14073   mp->is_pipe = is_pipe;
14074   mp->is_master = is_master;
14075   vec_free (if_name);
14076
14077   S;
14078   W;
14079   /* NOTREACHED */
14080   return 0;
14081 }
14082
14083 static int
14084 api_netmap_delete (vat_main_t * vam)
14085 {
14086   unformat_input_t *i = vam->input;
14087   vl_api_netmap_delete_t *mp;
14088   f64 timeout;
14089   u8 *if_name = 0;
14090
14091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14092     {
14093       if (unformat (i, "name %s", &if_name))
14094         vec_add1 (if_name, 0);
14095       else
14096         break;
14097     }
14098
14099   if (!vec_len (if_name))
14100     {
14101       errmsg ("interface name must be specified");
14102       return -99;
14103     }
14104
14105   if (vec_len (if_name) > 64)
14106     {
14107       errmsg ("interface name too long");
14108       return -99;
14109     }
14110
14111   M (NETMAP_DELETE, netmap_delete);
14112
14113   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14114   vec_free (if_name);
14115
14116   S;
14117   W;
14118   /* NOTREACHED */
14119   return 0;
14120 }
14121
14122 static void vl_api_mpls_gre_tunnel_details_t_handler
14123   (vl_api_mpls_gre_tunnel_details_t * mp)
14124 {
14125   vat_main_t *vam = &vat_main;
14126   i32 i;
14127   i32 len = ntohl (mp->nlabels);
14128
14129   if (mp->l2_only == 0)
14130     {
14131       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14132                ntohl (mp->tunnel_index),
14133                format_ip4_address, &mp->tunnel_src,
14134                format_ip4_address, &mp->tunnel_dst,
14135                format_ip4_address, &mp->intfc_address,
14136                ntohl (mp->mask_width));
14137       for (i = 0; i < len; i++)
14138         {
14139           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14140         }
14141       fformat (vam->ofp, "\n");
14142       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14143                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14144     }
14145   else
14146     {
14147       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14148                ntohl (mp->tunnel_index),
14149                format_ip4_address, &mp->tunnel_src,
14150                format_ip4_address, &mp->tunnel_dst,
14151                format_ip4_address, &mp->intfc_address);
14152       for (i = 0; i < len; i++)
14153         {
14154           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14155         }
14156       fformat (vam->ofp, "\n");
14157       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14158                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14159     }
14160 }
14161
14162 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14163   (vl_api_mpls_gre_tunnel_details_t * mp)
14164 {
14165   vat_main_t *vam = &vat_main;
14166   vat_json_node_t *node = NULL;
14167   struct in_addr ip4;
14168   i32 i;
14169   i32 len = ntohl (mp->nlabels);
14170
14171   if (VAT_JSON_ARRAY != vam->json_tree.type)
14172     {
14173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14174       vat_json_init_array (&vam->json_tree);
14175     }
14176   node = vat_json_array_add (&vam->json_tree);
14177
14178   vat_json_init_object (node);
14179   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14180   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14181   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14182   vat_json_object_add_uint (node, "inner_fib_index",
14183                             ntohl (mp->inner_fib_index));
14184   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14185   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14186   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14187   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14188   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14189   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14190   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14191   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14192   vat_json_object_add_uint (node, "outer_fib_index",
14193                             ntohl (mp->outer_fib_index));
14194   vat_json_object_add_uint (node, "label_count", len);
14195   for (i = 0; i < len; i++)
14196     {
14197       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14198     }
14199 }
14200
14201 static int
14202 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14203 {
14204   vl_api_mpls_gre_tunnel_dump_t *mp;
14205   f64 timeout;
14206   i32 index = -1;
14207
14208   /* Parse args required to build the message */
14209   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14210     {
14211       if (!unformat (vam->input, "tunnel_index %d", &index))
14212         {
14213           index = -1;
14214           break;
14215         }
14216     }
14217
14218   fformat (vam->ofp, "  tunnel_index %d\n", index);
14219
14220   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14221   mp->tunnel_index = htonl (index);
14222   S;
14223
14224   /* Use a control ping for synchronization */
14225   {
14226     vl_api_control_ping_t *mp;
14227     M (CONTROL_PING, control_ping);
14228     S;
14229   }
14230   W;
14231 }
14232
14233 static void vl_api_mpls_eth_tunnel_details_t_handler
14234   (vl_api_mpls_eth_tunnel_details_t * mp)
14235 {
14236   vat_main_t *vam = &vat_main;
14237   i32 i;
14238   i32 len = ntohl (mp->nlabels);
14239
14240   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14241            ntohl (mp->tunnel_index),
14242            format_ethernet_address, &mp->tunnel_dst_mac,
14243            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14244   for (i = 0; i < len; i++)
14245     {
14246       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14247     }
14248   fformat (vam->ofp, "\n");
14249   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14250            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14251 }
14252
14253 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14254   (vl_api_mpls_eth_tunnel_details_t * mp)
14255 {
14256   vat_main_t *vam = &vat_main;
14257   vat_json_node_t *node = NULL;
14258   struct in_addr ip4;
14259   i32 i;
14260   i32 len = ntohl (mp->nlabels);
14261
14262   if (VAT_JSON_ARRAY != vam->json_tree.type)
14263     {
14264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14265       vat_json_init_array (&vam->json_tree);
14266     }
14267   node = vat_json_array_add (&vam->json_tree);
14268
14269   vat_json_init_object (node);
14270   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14271   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14272   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14273   vat_json_object_add_uint (node, "inner_fib_index",
14274                             ntohl (mp->inner_fib_index));
14275   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14276   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14277   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14278   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14279   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14280                                    format (0, "%U", format_ethernet_address,
14281                                            &mp->tunnel_dst_mac));
14282   vat_json_object_add_uint (node, "tx_sw_if_index",
14283                             ntohl (mp->tx_sw_if_index));
14284   vat_json_object_add_uint (node, "label_count", len);
14285   for (i = 0; i < len; i++)
14286     {
14287       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14288     }
14289 }
14290
14291 static int
14292 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14293 {
14294   vl_api_mpls_eth_tunnel_dump_t *mp;
14295   f64 timeout;
14296   i32 index = -1;
14297
14298   /* Parse args required to build the message */
14299   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14300     {
14301       if (!unformat (vam->input, "tunnel_index %d", &index))
14302         {
14303           index = -1;
14304           break;
14305         }
14306     }
14307
14308   fformat (vam->ofp, "  tunnel_index %d\n", index);
14309
14310   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14311   mp->tunnel_index = htonl (index);
14312   S;
14313
14314   /* Use a control ping for synchronization */
14315   {
14316     vl_api_control_ping_t *mp;
14317     M (CONTROL_PING, control_ping);
14318     S;
14319   }
14320   W;
14321 }
14322
14323 static void vl_api_mpls_fib_encap_details_t_handler
14324   (vl_api_mpls_fib_encap_details_t * mp)
14325 {
14326   vat_main_t *vam = &vat_main;
14327   i32 i;
14328   i32 len = ntohl (mp->nlabels);
14329
14330   fformat (vam->ofp, "table %d, dest %U, label ",
14331            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14332   for (i = 0; i < len; i++)
14333     {
14334       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14335     }
14336   fformat (vam->ofp, "\n");
14337 }
14338
14339 static void vl_api_mpls_fib_encap_details_t_handler_json
14340   (vl_api_mpls_fib_encap_details_t * mp)
14341 {
14342   vat_main_t *vam = &vat_main;
14343   vat_json_node_t *node = NULL;
14344   i32 i;
14345   i32 len = ntohl (mp->nlabels);
14346   struct in_addr ip4;
14347
14348   if (VAT_JSON_ARRAY != vam->json_tree.type)
14349     {
14350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14351       vat_json_init_array (&vam->json_tree);
14352     }
14353   node = vat_json_array_add (&vam->json_tree);
14354
14355   vat_json_init_object (node);
14356   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14357   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14358   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14359   vat_json_object_add_ip4 (node, "dest", ip4);
14360   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14361   vat_json_object_add_uint (node, "label_count", len);
14362   for (i = 0; i < len; i++)
14363     {
14364       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14365     }
14366 }
14367
14368 static int
14369 api_mpls_fib_encap_dump (vat_main_t * vam)
14370 {
14371   vl_api_mpls_fib_encap_dump_t *mp;
14372   f64 timeout;
14373
14374   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14375   S;
14376
14377   /* Use a control ping for synchronization */
14378   {
14379     vl_api_control_ping_t *mp;
14380     M (CONTROL_PING, control_ping);
14381     S;
14382   }
14383   W;
14384 }
14385
14386 static void vl_api_mpls_fib_decap_details_t_handler
14387   (vl_api_mpls_fib_decap_details_t * mp)
14388 {
14389   vat_main_t *vam = &vat_main;
14390
14391   fformat (vam->ofp,
14392            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14393            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14394            ntohl (mp->label), ntohl (mp->s_bit));
14395 }
14396
14397 static void vl_api_mpls_fib_decap_details_t_handler_json
14398   (vl_api_mpls_fib_decap_details_t * mp)
14399 {
14400   vat_main_t *vam = &vat_main;
14401   vat_json_node_t *node = NULL;
14402   struct in_addr ip4;
14403
14404   if (VAT_JSON_ARRAY != vam->json_tree.type)
14405     {
14406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14407       vat_json_init_array (&vam->json_tree);
14408     }
14409   node = vat_json_array_add (&vam->json_tree);
14410
14411   vat_json_init_object (node);
14412   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14413   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14414   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14415   vat_json_object_add_ip4 (node, "dest", ip4);
14416   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14417   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14418   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14419   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14420   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14421 }
14422
14423 static int
14424 api_mpls_fib_decap_dump (vat_main_t * vam)
14425 {
14426   vl_api_mpls_fib_decap_dump_t *mp;
14427   f64 timeout;
14428
14429   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14430   S;
14431
14432   /* Use a control ping for synchronization */
14433   {
14434     vl_api_control_ping_t *mp;
14435     M (CONTROL_PING, control_ping);
14436     S;
14437   }
14438   W;
14439 }
14440
14441 int
14442 api_classify_table_ids (vat_main_t * vam)
14443 {
14444   vl_api_classify_table_ids_t *mp;
14445   f64 timeout;
14446
14447   /* Construct the API message */
14448   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14449   mp->context = 0;
14450
14451   S;
14452   W;
14453   /* NOTREACHED */
14454   return 0;
14455 }
14456
14457 int
14458 api_classify_table_by_interface (vat_main_t * vam)
14459 {
14460   unformat_input_t *input = vam->input;
14461   vl_api_classify_table_by_interface_t *mp;
14462   f64 timeout;
14463
14464   u32 sw_if_index = ~0;
14465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14466     {
14467       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14468         ;
14469       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14470         ;
14471       else
14472         break;
14473     }
14474   if (sw_if_index == ~0)
14475     {
14476       errmsg ("missing interface name or sw_if_index\n");
14477       return -99;
14478     }
14479
14480   /* Construct the API message */
14481   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14482   mp->context = 0;
14483   mp->sw_if_index = ntohl (sw_if_index);
14484
14485   S;
14486   W;
14487   /* NOTREACHED */
14488   return 0;
14489 }
14490
14491 int
14492 api_classify_table_info (vat_main_t * vam)
14493 {
14494   unformat_input_t *input = vam->input;
14495   vl_api_classify_table_info_t *mp;
14496   f64 timeout;
14497
14498   u32 table_id = ~0;
14499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14500     {
14501       if (unformat (input, "table_id %d", &table_id))
14502         ;
14503       else
14504         break;
14505     }
14506   if (table_id == ~0)
14507     {
14508       errmsg ("missing table id\n");
14509       return -99;
14510     }
14511
14512   /* Construct the API message */
14513   M (CLASSIFY_TABLE_INFO, classify_table_info);
14514   mp->context = 0;
14515   mp->table_id = ntohl (table_id);
14516
14517   S;
14518   W;
14519   /* NOTREACHED */
14520   return 0;
14521 }
14522
14523 int
14524 api_classify_session_dump (vat_main_t * vam)
14525 {
14526   unformat_input_t *input = vam->input;
14527   vl_api_classify_session_dump_t *mp;
14528   f64 timeout;
14529
14530   u32 table_id = ~0;
14531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14532     {
14533       if (unformat (input, "table_id %d", &table_id))
14534         ;
14535       else
14536         break;
14537     }
14538   if (table_id == ~0)
14539     {
14540       errmsg ("missing table id\n");
14541       return -99;
14542     }
14543
14544   /* Construct the API message */
14545   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14546   mp->context = 0;
14547   mp->table_id = ntohl (table_id);
14548   S;
14549
14550   /* Use a control ping for synchronization */
14551   {
14552     vl_api_control_ping_t *mp;
14553     M (CONTROL_PING, control_ping);
14554     S;
14555   }
14556   W;
14557   /* NOTREACHED */
14558   return 0;
14559 }
14560
14561 static void
14562 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14563 {
14564   vat_main_t *vam = &vat_main;
14565
14566   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14567            "src_address %U, vrf_id %d, path_mtu %u, "
14568            "template_interval %u, udp_checksum %d\n",
14569            format_ip4_address, mp->collector_address,
14570            ntohs (mp->collector_port),
14571            format_ip4_address, mp->src_address,
14572            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14573            ntohl (mp->template_interval), mp->udp_checksum);
14574
14575   vam->retval = 0;
14576   vam->result_ready = 1;
14577 }
14578
14579 static void
14580   vl_api_ipfix_exporter_details_t_handler_json
14581   (vl_api_ipfix_exporter_details_t * mp)
14582 {
14583   vat_main_t *vam = &vat_main;
14584   vat_json_node_t node;
14585   struct in_addr collector_address;
14586   struct in_addr src_address;
14587
14588   vat_json_init_object (&node);
14589   clib_memcpy (&collector_address, &mp->collector_address,
14590                sizeof (collector_address));
14591   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14592   vat_json_object_add_uint (&node, "collector_port",
14593                             ntohs (mp->collector_port));
14594   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14595   vat_json_object_add_ip4 (&node, "src_address", src_address);
14596   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14597   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14598   vat_json_object_add_uint (&node, "template_interval",
14599                             ntohl (mp->template_interval));
14600   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14601
14602   vat_json_print (vam->ofp, &node);
14603   vat_json_free (&node);
14604   vam->retval = 0;
14605   vam->result_ready = 1;
14606 }
14607
14608 int
14609 api_ipfix_exporter_dump (vat_main_t * vam)
14610 {
14611   vl_api_ipfix_exporter_dump_t *mp;
14612   f64 timeout;
14613
14614   /* Construct the API message */
14615   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14616   mp->context = 0;
14617
14618   S;
14619   W;
14620   /* NOTREACHED */
14621   return 0;
14622 }
14623
14624 static int
14625 api_ipfix_classify_stream_dump (vat_main_t * vam)
14626 {
14627   vl_api_ipfix_classify_stream_dump_t *mp;
14628   f64 timeout;
14629
14630   /* Construct the API message */
14631   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14632   mp->context = 0;
14633
14634   S;
14635   W;
14636   /* NOTREACHED */
14637   return 0;
14638 }
14639
14640 static void
14641   vl_api_ipfix_classify_stream_details_t_handler
14642   (vl_api_ipfix_classify_stream_details_t * mp)
14643 {
14644   vat_main_t *vam = &vat_main;
14645   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14646            ntohl (mp->domain_id), ntohs (mp->src_port));
14647   vam->retval = 0;
14648   vam->result_ready = 1;
14649 }
14650
14651 static void
14652   vl_api_ipfix_classify_stream_details_t_handler_json
14653   (vl_api_ipfix_classify_stream_details_t * mp)
14654 {
14655   vat_main_t *vam = &vat_main;
14656   vat_json_node_t node;
14657
14658   vat_json_init_object (&node);
14659   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14660   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14661
14662   vat_json_print (vam->ofp, &node);
14663   vat_json_free (&node);
14664   vam->retval = 0;
14665   vam->result_ready = 1;
14666 }
14667
14668 static int
14669 api_ipfix_classify_table_dump (vat_main_t * vam)
14670 {
14671   vl_api_ipfix_classify_table_dump_t *mp;
14672   f64 timeout;
14673
14674   if (!vam->json_output)
14675     {
14676       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14677                "transport_protocol");
14678     }
14679
14680   /* Construct the API message */
14681   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14682
14683   /* send it... */
14684   S;
14685
14686   /* Use a control ping for synchronization */
14687   {
14688     vl_api_control_ping_t *mp;
14689     M (CONTROL_PING, control_ping);
14690     S;
14691   }
14692   W;
14693 }
14694
14695 static void
14696   vl_api_ipfix_classify_table_details_t_handler
14697   (vl_api_ipfix_classify_table_details_t * mp)
14698 {
14699   vat_main_t *vam = &vat_main;
14700   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14701            mp->transport_protocol);
14702 }
14703
14704 static void
14705   vl_api_ipfix_classify_table_details_t_handler_json
14706   (vl_api_ipfix_classify_table_details_t * mp)
14707 {
14708   vat_json_node_t *node = NULL;
14709   vat_main_t *vam = &vat_main;
14710
14711   if (VAT_JSON_ARRAY != vam->json_tree.type)
14712     {
14713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14714       vat_json_init_array (&vam->json_tree);
14715     }
14716
14717   node = vat_json_array_add (&vam->json_tree);
14718   vat_json_init_object (node);
14719
14720   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14721   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14722   vat_json_object_add_uint (node, "transport_protocol",
14723                             mp->transport_protocol);
14724 }
14725
14726 int
14727 api_pg_create_interface (vat_main_t * vam)
14728 {
14729   unformat_input_t *input = vam->input;
14730   vl_api_pg_create_interface_t *mp;
14731   f64 timeout;
14732
14733   u32 if_id = ~0;
14734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14735     {
14736       if (unformat (input, "if_id %d", &if_id))
14737         ;
14738       else
14739         break;
14740     }
14741   if (if_id == ~0)
14742     {
14743       errmsg ("missing pg interface index\n");
14744       return -99;
14745     }
14746
14747   /* Construct the API message */
14748   M (PG_CREATE_INTERFACE, pg_create_interface);
14749   mp->context = 0;
14750   mp->interface_id = ntohl (if_id);
14751
14752   S;
14753   W;
14754   /* NOTREACHED */
14755   return 0;
14756 }
14757
14758 int
14759 api_pg_capture (vat_main_t * vam)
14760 {
14761   unformat_input_t *input = vam->input;
14762   vl_api_pg_capture_t *mp;
14763   f64 timeout;
14764
14765   u32 if_id = ~0;
14766   u8 enable = 1;
14767   u32 count = 1;
14768   u8 pcap_file_set = 0;
14769   u8 *pcap_file = 0;
14770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14771     {
14772       if (unformat (input, "if_id %d", &if_id))
14773         ;
14774       else if (unformat (input, "pcap %s", &pcap_file))
14775         pcap_file_set = 1;
14776       else if (unformat (input, "count %d", &count))
14777         ;
14778       else if (unformat (input, "disable"))
14779         enable = 0;
14780       else
14781         break;
14782     }
14783   if (if_id == ~0)
14784     {
14785       errmsg ("missing pg interface index\n");
14786       return -99;
14787     }
14788   if (pcap_file_set > 0)
14789     {
14790       if (vec_len (pcap_file) > 255)
14791         {
14792           errmsg ("pcap file name is too long\n");
14793           return -99;
14794         }
14795     }
14796
14797   u32 name_len = vec_len (pcap_file);
14798   /* Construct the API message */
14799   M (PG_CAPTURE, pg_capture);
14800   mp->context = 0;
14801   mp->interface_id = ntohl (if_id);
14802   mp->is_enabled = enable;
14803   mp->count = ntohl (count);
14804   mp->pcap_name_length = ntohl (name_len);
14805   if (pcap_file_set != 0)
14806     {
14807       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14808     }
14809   vec_free (pcap_file);
14810
14811   S;
14812   W;
14813   /* NOTREACHED */
14814   return 0;
14815 }
14816
14817 int
14818 api_pg_enable_disable (vat_main_t * vam)
14819 {
14820   unformat_input_t *input = vam->input;
14821   vl_api_pg_enable_disable_t *mp;
14822   f64 timeout;
14823
14824   u8 enable = 1;
14825   u8 stream_name_set = 0;
14826   u8 *stream_name = 0;
14827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (input, "stream %s", &stream_name))
14830         stream_name_set = 1;
14831       else if (unformat (input, "disable"))
14832         enable = 0;
14833       else
14834         break;
14835     }
14836
14837   if (stream_name_set > 0)
14838     {
14839       if (vec_len (stream_name) > 255)
14840         {
14841           errmsg ("stream name too long\n");
14842           return -99;
14843         }
14844     }
14845
14846   u32 name_len = vec_len (stream_name);
14847   /* Construct the API message */
14848   M (PG_ENABLE_DISABLE, pg_enable_disable);
14849   mp->context = 0;
14850   mp->is_enabled = enable;
14851   if (stream_name_set != 0)
14852     {
14853       mp->stream_name_length = ntohl (name_len);
14854       clib_memcpy (mp->stream_name, stream_name, name_len);
14855     }
14856   vec_free (stream_name);
14857
14858   S;
14859   W;
14860   /* NOTREACHED */
14861   return 0;
14862 }
14863
14864 int
14865 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14866 {
14867   unformat_input_t *input = vam->input;
14868   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14869   f64 timeout;
14870
14871   u16 *low_ports = 0;
14872   u16 *high_ports = 0;
14873   u16 this_low;
14874   u16 this_hi;
14875   ip4_address_t ip4_addr;
14876   ip6_address_t ip6_addr;
14877   u32 length;
14878   u32 tmp, tmp2;
14879   u8 prefix_set = 0;
14880   u32 vrf_id = ~0;
14881   u8 is_add = 1;
14882   u8 is_ipv6 = 0;
14883
14884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14885     {
14886       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14887         {
14888           prefix_set = 1;
14889         }
14890       else
14891         if (unformat
14892             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14893         {
14894           prefix_set = 1;
14895           is_ipv6 = 1;
14896         }
14897       else if (unformat (input, "vrf %d", &vrf_id))
14898         ;
14899       else if (unformat (input, "del"))
14900         is_add = 0;
14901       else if (unformat (input, "port %d", &tmp))
14902         {
14903           if (tmp == 0 || tmp > 65535)
14904             {
14905               errmsg ("port %d out of range", tmp);
14906               return -99;
14907             }
14908           this_low = tmp;
14909           this_hi = this_low + 1;
14910           vec_add1 (low_ports, this_low);
14911           vec_add1 (high_ports, this_hi);
14912         }
14913       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14914         {
14915           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14916             {
14917               errmsg ("incorrect range parameters\n");
14918               return -99;
14919             }
14920           this_low = tmp;
14921           /* Note: in debug CLI +1 is added to high before
14922              passing to real fn that does "the work"
14923              (ip_source_and_port_range_check_add_del).
14924              This fn is a wrapper around the binary API fn a
14925              control plane will call, which expects this increment
14926              to have occurred. Hence letting the binary API control
14927              plane fn do the increment for consistency between VAT
14928              and other control planes.
14929            */
14930           this_hi = tmp2;
14931           vec_add1 (low_ports, this_low);
14932           vec_add1 (high_ports, this_hi);
14933         }
14934       else
14935         break;
14936     }
14937
14938   if (prefix_set == 0)
14939     {
14940       errmsg ("<address>/<mask> not specified\n");
14941       return -99;
14942     }
14943
14944   if (vrf_id == ~0)
14945     {
14946       errmsg ("VRF ID required, not specified\n");
14947       return -99;
14948     }
14949
14950   if (vrf_id == 0)
14951     {
14952       errmsg
14953         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14954       return -99;
14955     }
14956
14957   if (vec_len (low_ports) == 0)
14958     {
14959       errmsg ("At least one port or port range required\n");
14960       return -99;
14961     }
14962
14963   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14964      ip_source_and_port_range_check_add_del);
14965
14966   mp->is_add = is_add;
14967
14968   if (is_ipv6)
14969     {
14970       mp->is_ipv6 = 1;
14971       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14972     }
14973   else
14974     {
14975       mp->is_ipv6 = 0;
14976       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14977     }
14978
14979   mp->mask_length = length;
14980   mp->number_of_ranges = vec_len (low_ports);
14981
14982   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14983   vec_free (low_ports);
14984
14985   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14986   vec_free (high_ports);
14987
14988   mp->vrf_id = ntohl (vrf_id);
14989
14990   S;
14991   W;
14992   /* NOTREACHED */
14993   return 0;
14994 }
14995
14996 int
14997 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14998 {
14999   unformat_input_t *input = vam->input;
15000   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15001   f64 timeout;
15002   u32 sw_if_index = ~0;
15003   int vrf_set = 0;
15004   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15005   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15006   u8 is_add = 1;
15007
15008   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15009     {
15010       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15011         ;
15012       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15013         ;
15014       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15015         vrf_set = 1;
15016       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15017         vrf_set = 1;
15018       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15019         vrf_set = 1;
15020       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15021         vrf_set = 1;
15022       else if (unformat (input, "del"))
15023         is_add = 0;
15024       else
15025         break;
15026     }
15027
15028   if (sw_if_index == ~0)
15029     {
15030       errmsg ("Interface required but not specified\n");
15031       return -99;
15032     }
15033
15034   if (vrf_set == 0)
15035     {
15036       errmsg ("VRF ID required but not specified\n");
15037       return -99;
15038     }
15039
15040   if (tcp_out_vrf_id == 0
15041       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15042     {
15043       errmsg
15044         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15045       return -99;
15046     }
15047
15048   /* Construct the API message */
15049   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15050      ip_source_and_port_range_check_interface_add_del);
15051
15052   mp->sw_if_index = ntohl (sw_if_index);
15053   mp->is_add = is_add;
15054   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15055   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15056   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15057   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15058
15059   /* send it... */
15060   S;
15061
15062   /* Wait for a reply... */
15063   W;
15064 }
15065
15066 static int
15067 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15068 {
15069   unformat_input_t *i = vam->input;
15070   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15071   f64 timeout;
15072   u32 local_sa_id = 0;
15073   u32 remote_sa_id = 0;
15074   ip4_address_t src_address;
15075   ip4_address_t dst_address;
15076   u8 is_add = 1;
15077
15078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (i, "local_sa %d", &local_sa_id))
15081         ;
15082       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15083         ;
15084       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15085         ;
15086       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15087         ;
15088       else if (unformat (i, "del"))
15089         is_add = 0;
15090       else
15091         {
15092           clib_warning ("parse error '%U'", format_unformat_error, i);
15093           return -99;
15094         }
15095     }
15096
15097   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15098
15099   mp->local_sa_id = ntohl (local_sa_id);
15100   mp->remote_sa_id = ntohl (remote_sa_id);
15101   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15102   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15103   mp->is_add = is_add;
15104
15105   S;
15106   W;
15107   /* NOTREACHED */
15108   return 0;
15109 }
15110
15111 static int
15112 api_punt (vat_main_t * vam)
15113 {
15114   unformat_input_t *i = vam->input;
15115   vl_api_punt_t *mp;
15116   f64 timeout;
15117   u32 ipv = ~0;
15118   u32 protocol = ~0;
15119   u32 port = ~0;
15120   int is_add = 1;
15121
15122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15123     {
15124       if (unformat (i, "ip %d", &ipv))
15125         ;
15126       else if (unformat (i, "protocol %d", &protocol))
15127         ;
15128       else if (unformat (i, "port %d", &port))
15129         ;
15130       else if (unformat (i, "del"))
15131         is_add = 0;
15132       else
15133         {
15134           clib_warning ("parse error '%U'", format_unformat_error, i);
15135           return -99;
15136         }
15137     }
15138
15139   M (PUNT, punt);
15140
15141   mp->is_add = (u8) is_add;
15142   mp->ipv = (u8) ipv;
15143   mp->l4_protocol = (u8) protocol;
15144   mp->l4_port = htons ((u16) port);
15145
15146   S;
15147   W;
15148   /* NOTREACHED */
15149   return 0;
15150 }
15151
15152 static void vl_api_ipsec_gre_tunnel_details_t_handler
15153   (vl_api_ipsec_gre_tunnel_details_t * mp)
15154 {
15155   vat_main_t *vam = &vat_main;
15156
15157   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15158            ntohl (mp->sw_if_index),
15159            format_ip4_address, &mp->src_address,
15160            format_ip4_address, &mp->dst_address,
15161            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15162 }
15163
15164 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15165   (vl_api_ipsec_gre_tunnel_details_t * mp)
15166 {
15167   vat_main_t *vam = &vat_main;
15168   vat_json_node_t *node = NULL;
15169   struct in_addr ip4;
15170
15171   if (VAT_JSON_ARRAY != vam->json_tree.type)
15172     {
15173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15174       vat_json_init_array (&vam->json_tree);
15175     }
15176   node = vat_json_array_add (&vam->json_tree);
15177
15178   vat_json_init_object (node);
15179   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15180   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15181   vat_json_object_add_ip4 (node, "src_address", ip4);
15182   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15183   vat_json_object_add_ip4 (node, "dst_address", ip4);
15184   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15185   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15186 }
15187
15188 static int
15189 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15190 {
15191   unformat_input_t *i = vam->input;
15192   vl_api_ipsec_gre_tunnel_dump_t *mp;
15193   f64 timeout;
15194   u32 sw_if_index;
15195   u8 sw_if_index_set = 0;
15196
15197   /* Parse args required to build the message */
15198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15199     {
15200       if (unformat (i, "sw_if_index %d", &sw_if_index))
15201         sw_if_index_set = 1;
15202       else
15203         break;
15204     }
15205
15206   if (sw_if_index_set == 0)
15207     {
15208       sw_if_index = ~0;
15209     }
15210
15211   if (!vam->json_output)
15212     {
15213       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15214                "sw_if_index", "src_address", "dst_address",
15215                "local_sa_id", "remote_sa_id");
15216     }
15217
15218   /* Get list of gre-tunnel interfaces */
15219   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15220
15221   mp->sw_if_index = htonl (sw_if_index);
15222
15223   S;
15224
15225   /* Use a control ping for synchronization */
15226   {
15227     vl_api_control_ping_t *mp;
15228     M (CONTROL_PING, control_ping);
15229     S;
15230   }
15231   W;
15232 }
15233
15234 static int
15235 api_delete_subif (vat_main_t * vam)
15236 {
15237   unformat_input_t *i = vam->input;
15238   vl_api_delete_subif_t *mp;
15239   f64 timeout;
15240   u32 sw_if_index = ~0;
15241
15242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15243     {
15244       if (unformat (i, "sw_if_index %d", &sw_if_index))
15245         ;
15246       else
15247         break;
15248     }
15249
15250   if (sw_if_index == ~0)
15251     {
15252       errmsg ("missing sw_if_index\n");
15253       return -99;
15254     }
15255
15256   /* Construct the API message */
15257   M (DELETE_SUBIF, delete_subif);
15258   mp->sw_if_index = ntohl (sw_if_index);
15259
15260   S;
15261   W;
15262 }
15263
15264 #define foreach_pbb_vtr_op      \
15265 _("disable",  L2_VTR_DISABLED)  \
15266 _("pop",  L2_VTR_POP_2)         \
15267 _("push",  L2_VTR_PUSH_2)
15268
15269 static int
15270 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
15271 {
15272   unformat_input_t *i = vam->input;
15273   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
15274   f64 timeout;
15275   u32 sw_if_index = ~0, vtr_op = ~0;
15276   u16 outer_tag = ~0;
15277   u8 dmac[6], smac[6];
15278   u8 dmac_set = 0, smac_set = 0;
15279   u16 vlanid = 0;
15280   u32 sid = ~0;
15281   u32 tmp;
15282
15283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15284     {
15285       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15286         ;
15287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15288         ;
15289       else if (unformat (i, "vtr_op %d", &vtr_op))
15290         ;
15291 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
15292       foreach_pbb_vtr_op
15293 #undef _
15294         else if (unformat (i, "translate_pbb_stag"))
15295         {
15296           if (unformat (i, "%d", &tmp))
15297             {
15298               vtr_op = L2_VTR_TRANSLATE_2_1;
15299               outer_tag = tmp;
15300             }
15301           else
15302             {
15303               errmsg
15304                 ("translate_pbb_stag operation requires outer tag definition\n");
15305               return -99;
15306             }
15307         }
15308       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
15309         dmac_set++;
15310       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
15311         smac_set++;
15312       else if (unformat (i, "sid %d", &sid))
15313         ;
15314       else if (unformat (i, "vlanid %d", &tmp))
15315         vlanid = tmp;
15316       else
15317         {
15318           clib_warning ("parse error '%U'", format_unformat_error, i);
15319           return -99;
15320         }
15321     }
15322
15323   if ((sw_if_index == ~0) || (vtr_op == ~0))
15324     {
15325       errmsg ("missing sw_if_index or vtr operation\n");
15326       return -99;
15327     }
15328   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
15329       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
15330     {
15331       errmsg
15332         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
15333       return -99;
15334     }
15335
15336   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
15337   mp->sw_if_index = ntohl (sw_if_index);
15338   mp->vtr_op = ntohl (vtr_op);
15339   mp->outer_tag = ntohs (outer_tag);
15340   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
15341   clib_memcpy (mp->b_smac, smac, sizeof (smac));
15342   mp->b_vlanid = ntohs (vlanid);
15343   mp->i_sid = ntohl (sid);
15344
15345   S;
15346   W;
15347   /* NOTREACHED */
15348   return 0;
15349 }
15350
15351 static int
15352 q_or_quit (vat_main_t * vam)
15353 {
15354   longjmp (vam->jump_buf, 1);
15355   return 0;                     /* not so much */
15356 }
15357
15358 static int
15359 q (vat_main_t * vam)
15360 {
15361   return q_or_quit (vam);
15362 }
15363
15364 static int
15365 quit (vat_main_t * vam)
15366 {
15367   return q_or_quit (vam);
15368 }
15369
15370 static int
15371 comment (vat_main_t * vam)
15372 {
15373   return 0;
15374 }
15375
15376 static int
15377 cmd_cmp (void *a1, void *a2)
15378 {
15379   u8 **c1 = a1;
15380   u8 **c2 = a2;
15381
15382   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15383 }
15384
15385 static int
15386 help (vat_main_t * vam)
15387 {
15388   u8 **cmds = 0;
15389   u8 *name = 0;
15390   hash_pair_t *p;
15391   unformat_input_t *i = vam->input;
15392   int j;
15393
15394   if (unformat (i, "%s", &name))
15395     {
15396       uword *hs;
15397
15398       vec_add1 (name, 0);
15399
15400       hs = hash_get_mem (vam->help_by_name, name);
15401       if (hs)
15402         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15403       else
15404         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15405       vec_free (name);
15406       return 0;
15407     }
15408
15409   fformat (vam->ofp, "Help is available for the following:\n");
15410
15411     /* *INDENT-OFF* */
15412     hash_foreach_pair (p, vam->function_by_name,
15413     ({
15414       vec_add1 (cmds, (u8 *)(p->key));
15415     }));
15416     /* *INDENT-ON* */
15417
15418   vec_sort_with_function (cmds, cmd_cmp);
15419
15420   for (j = 0; j < vec_len (cmds); j++)
15421     fformat (vam->ofp, "%s\n", cmds[j]);
15422
15423   vec_free (cmds);
15424   return 0;
15425 }
15426
15427 static int
15428 set (vat_main_t * vam)
15429 {
15430   u8 *name = 0, *value = 0;
15431   unformat_input_t *i = vam->input;
15432
15433   if (unformat (i, "%s", &name))
15434     {
15435       /* The input buffer is a vector, not a string. */
15436       value = vec_dup (i->buffer);
15437       vec_delete (value, i->index, 0);
15438       /* Almost certainly has a trailing newline */
15439       if (value[vec_len (value) - 1] == '\n')
15440         value[vec_len (value) - 1] = 0;
15441       /* Make sure it's a proper string, one way or the other */
15442       vec_add1 (value, 0);
15443       (void) clib_macro_set_value (&vam->macro_main,
15444                                    (char *) name, (char *) value);
15445     }
15446   else
15447     errmsg ("usage: set <name> <value>\n");
15448
15449   vec_free (name);
15450   vec_free (value);
15451   return 0;
15452 }
15453
15454 static int
15455 unset (vat_main_t * vam)
15456 {
15457   u8 *name = 0;
15458
15459   if (unformat (vam->input, "%s", &name))
15460     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15461       errmsg ("unset: %s wasn't set\n", name);
15462   vec_free (name);
15463   return 0;
15464 }
15465
15466 typedef struct
15467 {
15468   u8 *name;
15469   u8 *value;
15470 } macro_sort_t;
15471
15472
15473 static int
15474 macro_sort_cmp (void *a1, void *a2)
15475 {
15476   macro_sort_t *s1 = a1;
15477   macro_sort_t *s2 = a2;
15478
15479   return strcmp ((char *) (s1->name), (char *) (s2->name));
15480 }
15481
15482 static int
15483 dump_macro_table (vat_main_t * vam)
15484 {
15485   macro_sort_t *sort_me = 0, *sm;
15486   int i;
15487   hash_pair_t *p;
15488
15489     /* *INDENT-OFF* */
15490     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15491     ({
15492       vec_add2 (sort_me, sm, 1);
15493       sm->name = (u8 *)(p->key);
15494       sm->value = (u8 *) (p->value[0]);
15495     }));
15496     /* *INDENT-ON* */
15497
15498   vec_sort_with_function (sort_me, macro_sort_cmp);
15499
15500   if (vec_len (sort_me))
15501     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15502   else
15503     fformat (vam->ofp, "The macro table is empty...\n");
15504
15505   for (i = 0; i < vec_len (sort_me); i++)
15506     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15507   return 0;
15508 }
15509
15510 static int
15511 dump_node_table (vat_main_t * vam)
15512 {
15513   int i, j;
15514   vlib_node_t *node, *next_node;
15515
15516   if (vec_len (vam->graph_nodes) == 0)
15517     {
15518       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15519       return 0;
15520     }
15521
15522   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15523     {
15524       node = vam->graph_nodes[i];
15525       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15526       for (j = 0; j < vec_len (node->next_nodes); j++)
15527         {
15528           if (node->next_nodes[j] != ~0)
15529             {
15530               next_node = vam->graph_nodes[node->next_nodes[j]];
15531               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15532             }
15533         }
15534     }
15535   return 0;
15536 }
15537
15538 static int
15539 search_node_table (vat_main_t * vam)
15540 {
15541   unformat_input_t *line_input = vam->input;
15542   u8 *node_to_find;
15543   int j;
15544   vlib_node_t *node, *next_node;
15545   uword *p;
15546
15547   if (vam->graph_node_index_by_name == 0)
15548     {
15549       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15550       return 0;
15551     }
15552
15553   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15554     {
15555       if (unformat (line_input, "%s", &node_to_find))
15556         {
15557           vec_add1 (node_to_find, 0);
15558           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15559           if (p == 0)
15560             {
15561               fformat (vam->ofp, "%s not found...\n", node_to_find);
15562               goto out;
15563             }
15564           node = vam->graph_nodes[p[0]];
15565           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15566           for (j = 0; j < vec_len (node->next_nodes); j++)
15567             {
15568               if (node->next_nodes[j] != ~0)
15569                 {
15570                   next_node = vam->graph_nodes[node->next_nodes[j]];
15571                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15572                 }
15573             }
15574         }
15575
15576       else
15577         {
15578           clib_warning ("parse error '%U'", format_unformat_error,
15579                         line_input);
15580           return -99;
15581         }
15582
15583     out:
15584       vec_free (node_to_find);
15585
15586     }
15587
15588   return 0;
15589 }
15590
15591
15592 static int
15593 script (vat_main_t * vam)
15594 {
15595   u8 *s = 0;
15596   char *save_current_file;
15597   unformat_input_t save_input;
15598   jmp_buf save_jump_buf;
15599   u32 save_line_number;
15600
15601   FILE *new_fp, *save_ifp;
15602
15603   if (unformat (vam->input, "%s", &s))
15604     {
15605       new_fp = fopen ((char *) s, "r");
15606       if (new_fp == 0)
15607         {
15608           errmsg ("Couldn't open script file %s\n", s);
15609           vec_free (s);
15610           return -99;
15611         }
15612     }
15613   else
15614     {
15615       errmsg ("Missing script name\n");
15616       return -99;
15617     }
15618
15619   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15620   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15621   save_ifp = vam->ifp;
15622   save_line_number = vam->input_line_number;
15623   save_current_file = (char *) vam->current_file;
15624
15625   vam->input_line_number = 0;
15626   vam->ifp = new_fp;
15627   vam->current_file = s;
15628   do_one_file (vam);
15629
15630   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15631   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15632   vam->ifp = save_ifp;
15633   vam->input_line_number = save_line_number;
15634   vam->current_file = (u8 *) save_current_file;
15635   vec_free (s);
15636
15637   return 0;
15638 }
15639
15640 static int
15641 echo (vat_main_t * vam)
15642 {
15643   fformat (vam->ofp, "%v", vam->input->buffer);
15644   return 0;
15645 }
15646
15647 /* List of API message constructors, CLI names map to api_xxx */
15648 #define foreach_vpe_api_msg                                             \
15649 _(create_loopback,"[mac <mac-addr>]")                                   \
15650 _(sw_interface_dump,"")                                                 \
15651 _(sw_interface_set_flags,                                               \
15652   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15653 _(sw_interface_add_del_address,                                         \
15654   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15655 _(sw_interface_set_table,                                               \
15656   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15657 _(sw_interface_set_vpath,                                               \
15658   "<intfc> | sw_if_index <id> enable | disable")                        \
15659 _(sw_interface_set_l2_xconnect,                                         \
15660   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15661   "enable | disable")                                                   \
15662 _(sw_interface_set_l2_bridge,                                           \
15663   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15664   "[shg <split-horizon-group>] [bvi]\n"                                 \
15665   "enable | disable")                                                   \
15666 _(sw_interface_set_dpdk_hqos_pipe,                                      \
15667   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
15668   "profile <profile-id>\n")                                             \
15669 _(sw_interface_set_dpdk_hqos_subport,                                   \
15670   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
15671   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
15672 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
15673   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
15674 _(bridge_domain_add_del,                                                \
15675   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15676 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15677 _(l2fib_add_del,                                                        \
15678   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15679 _(l2_flags,                                                             \
15680   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15681 _(bridge_flags,                                                         \
15682   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15683 _(tap_connect,                                                          \
15684   "tapname <name> mac <mac-addr> | random-mac")                         \
15685 _(tap_modify,                                                           \
15686   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15687 _(tap_delete,                                                           \
15688   "<vpp-if-name> | sw_if_index <id>")                                   \
15689 _(sw_interface_tap_dump, "")                                            \
15690 _(ip_add_del_route,                                                     \
15691   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15692   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15693   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15694   "[multipath] [count <n>]")                                            \
15695 _(proxy_arp_add_del,                                                    \
15696   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15697 _(proxy_arp_intfc_enable_disable,                                       \
15698   "<intfc> | sw_if_index <id> enable | disable")                        \
15699 _(mpls_add_del_encap,                                                   \
15700   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15701 _(mpls_add_del_decap,                                                   \
15702   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15703 _(mpls_gre_add_del_tunnel,                                              \
15704   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15705   "adj <ip4-address>/<mask-width> [del]")                               \
15706 _(sw_interface_set_unnumbered,                                          \
15707   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15708 _(ip_neighbor_add_del,                                                  \
15709   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15710   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15711 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15712 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15713 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15714   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15715   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15716   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15717 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15718 _(reset_fib, "vrf <n> [ipv6]")                                          \
15719 _(dhcp_proxy_config,                                                    \
15720   "svr <v46-address> src <v46-address>\n"                               \
15721    "insert-cid <n> [del]")                                              \
15722 _(dhcp_proxy_config_2,                                                  \
15723   "svr <v46-address> src <v46-address>\n"                               \
15724    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15725 _(dhcp_proxy_set_vss,                                                   \
15726   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15727 _(dhcp_client_config,                                                   \
15728   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15729 _(set_ip_flow_hash,                                                     \
15730   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15731 _(sw_interface_ip6_enable_disable,                                      \
15732   "<intfc> | sw_if_index <id> enable | disable")                        \
15733 _(sw_interface_ip6_set_link_local_address,                              \
15734   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15735 _(sw_interface_ip6nd_ra_prefix,                                         \
15736   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15737   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15738   "[nolink] [isno]")                                                    \
15739 _(sw_interface_ip6nd_ra_config,                                         \
15740   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15741   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15742   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15743 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15744 _(l2_patch_add_del,                                                     \
15745   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15746   "enable | disable")                                                   \
15747 _(mpls_ethernet_add_del_tunnel,                                         \
15748   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15749   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15750 _(mpls_ethernet_add_del_tunnel_2,                                       \
15751   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15752   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15753 _(sr_tunnel_add_del,                                                    \
15754   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15755   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15756   "[policy <policy_name>]")                                             \
15757 _(sr_policy_add_del,                                                    \
15758   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15759 _(sr_multicast_map_add_del,                                             \
15760   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15761 _(classify_add_del_table,                                               \
15762   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15763   "[del] mask <mask-value>\n"                                           \
15764   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15765 _(classify_add_del_session,                                             \
15766   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15767   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15768   "  [l3 [ip4|ip6]]")                                                   \
15769 _(classify_set_interface_ip_table,                                      \
15770   "<intfc> | sw_if_index <nn> table <nn>")                              \
15771 _(classify_set_interface_l2_tables,                                     \
15772   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15773   "  [other-table <nn>]")                                               \
15774 _(get_node_index, "node <node-name")                                    \
15775 _(add_node_next, "node <node-name> next <next-node-name>")              \
15776 _(l2tpv3_create_tunnel,                                                 \
15777   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15778   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15779   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15780 _(l2tpv3_set_tunnel_cookies,                                            \
15781   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15782   "[new_remote_cookie <nn>]\n")                                         \
15783 _(l2tpv3_interface_enable_disable,                                      \
15784   "<intfc> | sw_if_index <nn> enable | disable")                        \
15785 _(l2tpv3_set_lookup_key,                                                \
15786   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15787 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15788 _(vxlan_add_del_tunnel,                                                 \
15789   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15790   " [decap-next l2|ip4|ip6] [del]")                                     \
15791 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15792 _(gre_add_del_tunnel,                                                   \
15793   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15794 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15795 _(l2_fib_clear_table, "")                                               \
15796 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15797 _(l2_interface_vlan_tag_rewrite,                                        \
15798   "<intfc> | sw_if_index <nn> \n"                                       \
15799   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15800   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15801 _(create_vhost_user_if,                                                 \
15802         "socket <filename> [server] [renumber <dev_instance>] "         \
15803         "[mac <mac_address>]")                                          \
15804 _(modify_vhost_user_if,                                                 \
15805         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15806         "[server] [renumber <dev_instance>]")                           \
15807 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15808 _(sw_interface_vhost_user_dump, "")                                     \
15809 _(show_version, "")                                                     \
15810 _(vxlan_gpe_add_del_tunnel,                                             \
15811   "local <addr> remote <addr> vni <nn>\n"                               \
15812     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15813   "[next-ethernet] [next-nsh]\n")                                       \
15814 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15815 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15816 _(interface_name_renumber,                                              \
15817   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15818 _(input_acl_set_interface,                                              \
15819   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15820   "  [l2-table <nn>] [del]")                                            \
15821 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15822 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15823 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15824 _(ip_dump, "ipv4 | ipv6")                                               \
15825 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15826 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15827   "  spid_id <n> ")                                                     \
15828 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15829   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15830   "  integ_alg <alg> integ_key <hex>")                                  \
15831 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15832   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15833   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15834   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15835 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15836 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15837 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15838   "(auth_data 0x<data> | auth_data <data>)")                            \
15839 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15840   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15841 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15842   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15843   "(local|remote)")                                                     \
15844 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15845 _(delete_loopback,"sw_if_index <nn>")                                   \
15846 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15847 _(map_add_domain,                                                       \
15848   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15849   "ip6-src <ip6addr> "                                                  \
15850   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15851 _(map_del_domain, "index <n>")                                          \
15852 _(map_add_del_rule,                                                     \
15853   "index <n> psid <n> dst <ip6addr> [del]")                             \
15854 _(map_domain_dump, "")                                                  \
15855 _(map_rule_dump, "index <map-domain>")                                  \
15856 _(want_interface_events,  "enable|disable")                             \
15857 _(want_stats,"enable|disable")                                          \
15858 _(get_first_msg_id, "client <name>")                                    \
15859 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15860 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15861   "fib-id <nn> [ip4][ip6][default]")                                    \
15862 _(get_node_graph, " ")                                                  \
15863 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15864 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15865 _(ioam_disable, "")                                                \
15866 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15867                             " sw_if_index <sw_if_index> p <priority> "  \
15868                             "w <weight>] [del]")                        \
15869 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15870                         "iface <intf> | sw_if_index <sw_if_index> "     \
15871                         "p <priority> w <weight> [del]")                \
15872 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15873                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15874                           "locator-set <locator_name> [del]")           \
15875 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15876   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15877 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15878 _(lisp_gpe_enable_disable, "enable|disable")                            \
15879 _(lisp_enable_disable, "enable|disable")                                \
15880 _(lisp_gpe_add_del_iface, "up|down")                                    \
15881 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15882                                "[seid <seid>] "                         \
15883                                "rloc <locator> p <prio> "               \
15884                                "w <weight> [rloc <loc> ... ] "          \
15885                                "action <action> [del-all]")             \
15886 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
15887                           "<local-eid>")                                \
15888 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15889 _(lisp_map_request_mode, "src-dst|dst-only")                            \
15890 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15891 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15892 _(lisp_locator_set_dump, "[local | remote]")                            \
15893 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15894 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15895                        "[local] | [remote]")                            \
15896 _(lisp_eid_table_vni_dump, "")                                          \
15897 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15898 _(lisp_gpe_tunnel_dump, "")                                             \
15899 _(lisp_map_resolver_dump, "")                                           \
15900 _(show_lisp_status, "")                                                 \
15901 _(lisp_get_map_request_itr_rlocs, "")                                   \
15902 _(show_lisp_pitr, "")                                                   \
15903 _(show_lisp_map_request_mode, "")                                       \
15904 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15905 _(af_packet_delete, "name <host interface name>")                       \
15906 _(policer_add_del, "name <policer name> <params> [del]")                \
15907 _(policer_dump, "[name <policer name>]")                                \
15908 _(policer_classify_set_interface,                                       \
15909   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15910   "  [l2-table <nn>] [del]")                                            \
15911 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15912 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15913     "[master|slave]")                                                   \
15914 _(netmap_delete, "name <interface name>")                               \
15915 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15916 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15917 _(mpls_fib_encap_dump, "")                                              \
15918 _(mpls_fib_decap_dump, "")                                              \
15919 _(classify_table_ids, "")                                               \
15920 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15921 _(classify_table_info, "table_id <nn>")                                 \
15922 _(classify_session_dump, "table_id <nn>")                               \
15923 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15924     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15925     "[template_interval <nn>] [udp_checksum]")                          \
15926 _(ipfix_exporter_dump, "")                                              \
15927 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15928 _(ipfix_classify_stream_dump, "")                                       \
15929 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15930 _(ipfix_classify_table_dump, "")                                        \
15931 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15932 _(pg_create_interface, "if_id <nn>")                                    \
15933 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15934 _(pg_enable_disable, "[stream <id>] disable")                           \
15935 _(ip_source_and_port_range_check_add_del,                               \
15936   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15937 _(ip_source_and_port_range_check_interface_add_del,                     \
15938   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15939   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15940 _(ipsec_gre_add_del_tunnel,                                             \
15941   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15942 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15943 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")                   \
15944 _(l2_interface_pbb_tag_rewrite,                                         \
15945   "<intfc> | sw_if_index <nn> \n"                                       \
15946   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
15947   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
15948 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")
15949
15950 /* List of command functions, CLI names map directly to functions */
15951 #define foreach_cli_function                                    \
15952 _(comment, "usage: comment <ignore-rest-of-line>")              \
15953 _(dump_interface_table, "usage: dump_interface_table")          \
15954 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15955 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15956 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15957 _(dump_stats_table, "usage: dump_stats_table")                  \
15958 _(dump_macro_table, "usage: dump_macro_table ")                 \
15959 _(dump_node_table, "usage: dump_node_table")                    \
15960 _(echo, "usage: echo <message>")                                \
15961 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15962 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15963 _(help, "usage: help")                                          \
15964 _(q, "usage: quit")                                             \
15965 _(quit, "usage: quit")                                          \
15966 _(search_node_table, "usage: search_node_table <name>...")      \
15967 _(set, "usage: set <variable-name> <value>")                    \
15968 _(script, "usage: script <file-name>")                          \
15969 _(unset, "usage: unset <variable-name>")
15970
15971 #define _(N,n)                                  \
15972     static void vl_api_##n##_t_handler_uni      \
15973     (vl_api_##n##_t * mp)                       \
15974     {                                           \
15975         vat_main_t * vam = &vat_main;           \
15976         if (vam->json_output) {                 \
15977             vl_api_##n##_t_handler_json(mp);    \
15978         } else {                                \
15979             vl_api_##n##_t_handler(mp);         \
15980         }                                       \
15981     }
15982 foreach_vpe_api_reply_msg;
15983 #undef _
15984
15985 void
15986 vat_api_hookup (vat_main_t * vam)
15987 {
15988 #define _(N,n)                                                  \
15989     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15990                            vl_api_##n##_t_handler_uni,          \
15991                            vl_noop_handler,                     \
15992                            vl_api_##n##_t_endian,               \
15993                            vl_api_##n##_t_print,                \
15994                            sizeof(vl_api_##n##_t), 1);
15995   foreach_vpe_api_reply_msg;
15996 #undef _
15997
15998   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15999
16000   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16001
16002   vam->function_by_name = hash_create_string (0, sizeof (uword));
16003
16004   vam->help_by_name = hash_create_string (0, sizeof (uword));
16005
16006   /* API messages we can send */
16007 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16008   foreach_vpe_api_msg;
16009 #undef _
16010
16011   /* Help strings */
16012 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16013   foreach_vpe_api_msg;
16014 #undef _
16015
16016   /* CLI functions */
16017 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16018   foreach_cli_function;
16019 #undef _
16020
16021   /* Help strings */
16022 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16023   foreach_cli_function;
16024 #undef _
16025 }
16026
16027 #undef vl_api_version
16028 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16029 #include <vpp-api/vpe.api.h>
16030 #undef vl_api_version
16031
16032 void
16033 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16034 {
16035   /*
16036    * Send the main API signature in slot 0. This bit of code must
16037    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16038    */
16039   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16040 }
16041
16042 /*
16043  * fd.io coding-style-patch-verification: ON
16044  *
16045  * Local Variables:
16046  * eval: (c-set-style "gnu")
16047  * End:
16048  */