0f93af5142117a7ab6503574dcf685e00b0eabb7
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 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
3486 #define _(n)                                    \
3487     static void vl_api_##n##_t_handler          \
3488     (vl_api_##n##_t * mp)                       \
3489     {                                           \
3490         vat_main_t * vam = &vat_main;           \
3491         i32 retval = ntohl(mp->retval);         \
3492         if (vam->async_mode) {                  \
3493             vam->async_errors += (retval < 0);  \
3494         } else {                                \
3495             vam->retval = retval;               \
3496             vam->result_ready = 1;              \
3497         }                                       \
3498     }
3499 foreach_standard_reply_retval_handler;
3500 #undef _
3501
3502 #define _(n)                                    \
3503     static void vl_api_##n##_t_handler_json     \
3504     (vl_api_##n##_t * mp)                       \
3505     {                                           \
3506         vat_main_t * vam = &vat_main;           \
3507         vat_json_node_t node;                   \
3508         vat_json_init_object(&node);            \
3509         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3510         vat_json_print(vam->ofp, &node);        \
3511         vam->retval = ntohl(mp->retval);        \
3512         vam->result_ready = 1;                  \
3513     }
3514 foreach_standard_reply_retval_handler;
3515 #undef _
3516
3517 /*
3518  * Table of message reply handlers, must include boilerplate handlers
3519  * we just generated
3520  */
3521
3522 #define foreach_vpe_api_reply_msg                                       \
3523 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3524 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3525 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3526 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3527 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3528 _(CLI_REPLY, cli_reply)                                                 \
3529 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3530 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3531   sw_interface_add_del_address_reply)                                   \
3532 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3533 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3534 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3535   sw_interface_set_l2_xconnect_reply)                                   \
3536 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3537   sw_interface_set_l2_bridge_reply)                                     \
3538 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3539   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3540 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3541   sw_interface_set_dpdk_hqos_subport_reply)                             \
3542 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3543   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3544 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3545 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3546 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3547 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3548 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3549 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3550 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3551 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3552 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3553 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3554 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3555 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3556 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3557   proxy_arp_intfc_enable_disable_reply)                                 \
3558 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3559 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3560 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3561 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3562   mpls_ethernet_add_del_tunnel_reply)                                   \
3563 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3564   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3565 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3566   sw_interface_set_unnumbered_reply)                                    \
3567 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3568 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3569 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3570 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3571 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3572 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3573 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3574 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3575 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3576 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3577 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3578 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3579   sw_interface_ip6_enable_disable_reply)                                \
3580 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3581   sw_interface_ip6_set_link_local_address_reply)                        \
3582 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3583   sw_interface_ip6nd_ra_prefix_reply)                                   \
3584 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3585   sw_interface_ip6nd_ra_config_reply)                                   \
3586 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3587 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3588 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3589 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3590 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3591 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3592 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3593 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3594 classify_set_interface_ip_table_reply)                                  \
3595 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3596   classify_set_interface_l2_tables_reply)                               \
3597 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3598 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3599 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3600 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3601 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3602   l2tpv3_interface_enable_disable_reply)                                \
3603 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3604 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3605 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3606 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3607 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3608 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3609 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3610 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3611 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3612 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3613 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3614 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3615 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3616 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3617 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3618 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3619 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3620 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3621 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3622 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3623 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3624 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3625 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3626 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3627 _(IP_DETAILS, ip_details)                                               \
3628 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3629 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3630 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3631 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3632 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3633 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3634 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3635 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3636 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3637 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3638 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3639 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3640 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3641 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3642 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3643 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3644 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3645 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3646 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3647 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3648 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3649 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3650 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3651 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3652 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3653 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3654 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3655 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3656 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3657 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3658 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3659 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3660 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3661 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3662 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3663 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3664 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3665 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3666 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3667 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3668 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3669 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3670 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3671 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3672 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3673 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3674 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3675 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3676 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3677 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3678 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3679 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3680   lisp_add_del_map_request_itr_rlocs_reply)                             \
3681 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3682   lisp_get_map_request_itr_rlocs_reply)                                 \
3683 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3684 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3685 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3686 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3687 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3688 _(POLICER_DETAILS, policer_details)                                     \
3689 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3690 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3691 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3692 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3693 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3694 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3695 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3696 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3697 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3698 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3699 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3700 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3701 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3702 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3703 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3704 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3705 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3706 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3707 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3708 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3709 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3710 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3711 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3712  ip_source_and_port_range_check_add_del_reply)                          \
3713 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3714  ip_source_and_port_range_check_interface_add_del_reply)                \
3715 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3716 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3717 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3718
3719 /* M: construct, but don't yet send a message */
3720
3721 #define M(T,t)                                  \
3722 do {                                            \
3723     vam->result_ready = 0;                      \
3724     mp = vl_msg_api_alloc(sizeof(*mp));         \
3725     memset (mp, 0, sizeof (*mp));               \
3726     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3727     mp->client_index = vam->my_client_index;    \
3728 } while(0);
3729
3730 #define M2(T,t,n)                               \
3731 do {                                            \
3732     vam->result_ready = 0;                      \
3733     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3734     memset (mp, 0, sizeof (*mp));               \
3735     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3736     mp->client_index = vam->my_client_index;    \
3737 } while(0);
3738
3739
3740 /* S: send a message */
3741 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3742
3743 /* W: wait for results, with timeout */
3744 #define W                                       \
3745 do {                                            \
3746     timeout = vat_time_now (vam) + 1.0;         \
3747                                                 \
3748     while (vat_time_now (vam) < timeout) {      \
3749         if (vam->result_ready == 1) {           \
3750             return (vam->retval);               \
3751         }                                       \
3752     }                                           \
3753     return -99;                                 \
3754 } while(0);
3755
3756 /* W2: wait for results, with timeout */
3757 #define W2(body)                                \
3758 do {                                            \
3759     timeout = vat_time_now (vam) + 1.0;         \
3760                                                 \
3761     while (vat_time_now (vam) < timeout) {      \
3762         if (vam->result_ready == 1) {           \
3763           (body);                               \
3764           return (vam->retval);                 \
3765         }                                       \
3766     }                                           \
3767     return -99;                                 \
3768 } while(0);
3769
3770 typedef struct
3771 {
3772   u8 *name;
3773   u32 value;
3774 } name_sort_t;
3775
3776
3777 #define STR_VTR_OP_CASE(op)     \
3778     case L2_VTR_ ## op:         \
3779         return "" # op;
3780
3781 static const char *
3782 str_vtr_op (u32 vtr_op)
3783 {
3784   switch (vtr_op)
3785     {
3786       STR_VTR_OP_CASE (DISABLED);
3787       STR_VTR_OP_CASE (PUSH_1);
3788       STR_VTR_OP_CASE (PUSH_2);
3789       STR_VTR_OP_CASE (POP_1);
3790       STR_VTR_OP_CASE (POP_2);
3791       STR_VTR_OP_CASE (TRANSLATE_1_1);
3792       STR_VTR_OP_CASE (TRANSLATE_1_2);
3793       STR_VTR_OP_CASE (TRANSLATE_2_1);
3794       STR_VTR_OP_CASE (TRANSLATE_2_2);
3795     }
3796
3797   return "UNKNOWN";
3798 }
3799
3800 static int
3801 dump_sub_interface_table (vat_main_t * vam)
3802 {
3803   const sw_interface_subif_t *sub = NULL;
3804
3805   if (vam->json_output)
3806     {
3807       clib_warning
3808         ("JSON output supported only for VPE API calls and dump_stats_table");
3809       return -99;
3810     }
3811
3812   fformat (vam->ofp,
3813            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3814            "Interface", "sw_if_index",
3815            "sub id", "dot1ad", "tags", "outer id",
3816            "inner id", "exact", "default", "outer any", "inner any");
3817
3818   vec_foreach (sub, vam->sw_if_subif_table)
3819   {
3820     fformat (vam->ofp,
3821              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3822              sub->interface_name,
3823              sub->sw_if_index,
3824              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3825              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3826              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3827              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3828     if (sub->vtr_op != L2_VTR_DISABLED)
3829       {
3830         fformat (vam->ofp,
3831                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3832                  "tag1: %d tag2: %d ]\n",
3833                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3834                  sub->vtr_tag1, sub->vtr_tag2);
3835       }
3836   }
3837
3838   return 0;
3839 }
3840
3841 static int
3842 name_sort_cmp (void *a1, void *a2)
3843 {
3844   name_sort_t *n1 = a1;
3845   name_sort_t *n2 = a2;
3846
3847   return strcmp ((char *) n1->name, (char *) n2->name);
3848 }
3849
3850 static int
3851 dump_interface_table (vat_main_t * vam)
3852 {
3853   hash_pair_t *p;
3854   name_sort_t *nses = 0, *ns;
3855
3856   if (vam->json_output)
3857     {
3858       clib_warning
3859         ("JSON output supported only for VPE API calls and dump_stats_table");
3860       return -99;
3861     }
3862
3863   /* *INDENT-OFF* */
3864   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3865   ({
3866     vec_add2 (nses, ns, 1);
3867     ns->name = (u8 *)(p->key);
3868     ns->value = (u32) p->value[0];
3869   }));
3870   /* *INDENT-ON* */
3871
3872   vec_sort_with_function (nses, name_sort_cmp);
3873
3874   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3875   vec_foreach (ns, nses)
3876   {
3877     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3878   }
3879   vec_free (nses);
3880   return 0;
3881 }
3882
3883 static int
3884 dump_ip_table (vat_main_t * vam, int is_ipv6)
3885 {
3886   const ip_details_t *det = NULL;
3887   const ip_address_details_t *address = NULL;
3888   u32 i = ~0;
3889
3890   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3891
3892   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3893   {
3894     i++;
3895     if (!det->present)
3896       {
3897         continue;
3898       }
3899     fformat (vam->ofp, "%-12d\n", i);
3900     fformat (vam->ofp,
3901              "            %-30s%-13s\n", "Address", "Prefix length");
3902     if (!det->addr)
3903       {
3904         continue;
3905       }
3906     vec_foreach (address, det->addr)
3907     {
3908       fformat (vam->ofp,
3909                "            %-30U%-13d\n",
3910                is_ipv6 ? format_ip6_address : format_ip4_address,
3911                address->ip, address->prefix_length);
3912     }
3913   }
3914
3915   return 0;
3916 }
3917
3918 static int
3919 dump_ipv4_table (vat_main_t * vam)
3920 {
3921   if (vam->json_output)
3922     {
3923       clib_warning
3924         ("JSON output supported only for VPE API calls and dump_stats_table");
3925       return -99;
3926     }
3927
3928   return dump_ip_table (vam, 0);
3929 }
3930
3931 static int
3932 dump_ipv6_table (vat_main_t * vam)
3933 {
3934   if (vam->json_output)
3935     {
3936       clib_warning
3937         ("JSON output supported only for VPE API calls and dump_stats_table");
3938       return -99;
3939     }
3940
3941   return dump_ip_table (vam, 1);
3942 }
3943
3944 static char *
3945 counter_type_to_str (u8 counter_type, u8 is_combined)
3946 {
3947   if (!is_combined)
3948     {
3949       switch (counter_type)
3950         {
3951         case VNET_INTERFACE_COUNTER_DROP:
3952           return "drop";
3953         case VNET_INTERFACE_COUNTER_PUNT:
3954           return "punt";
3955         case VNET_INTERFACE_COUNTER_IP4:
3956           return "ip4";
3957         case VNET_INTERFACE_COUNTER_IP6:
3958           return "ip6";
3959         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3960           return "rx-no-buf";
3961         case VNET_INTERFACE_COUNTER_RX_MISS:
3962           return "rx-miss";
3963         case VNET_INTERFACE_COUNTER_RX_ERROR:
3964           return "rx-error";
3965         case VNET_INTERFACE_COUNTER_TX_ERROR:
3966           return "tx-error";
3967         default:
3968           return "INVALID-COUNTER-TYPE";
3969         }
3970     }
3971   else
3972     {
3973       switch (counter_type)
3974         {
3975         case VNET_INTERFACE_COUNTER_RX:
3976           return "rx";
3977         case VNET_INTERFACE_COUNTER_TX:
3978           return "tx";
3979         default:
3980           return "INVALID-COUNTER-TYPE";
3981         }
3982     }
3983 }
3984
3985 static int
3986 dump_stats_table (vat_main_t * vam)
3987 {
3988   vat_json_node_t node;
3989   vat_json_node_t *msg_array;
3990   vat_json_node_t *msg;
3991   vat_json_node_t *counter_array;
3992   vat_json_node_t *counter;
3993   interface_counter_t c;
3994   u64 packets;
3995   ip4_fib_counter_t *c4;
3996   ip6_fib_counter_t *c6;
3997   int i, j;
3998
3999   if (!vam->json_output)
4000     {
4001       clib_warning ("dump_stats_table supported only in JSON format");
4002       return -99;
4003     }
4004
4005   vat_json_init_object (&node);
4006
4007   /* interface counters */
4008   msg_array = vat_json_object_add (&node, "interface_counters");
4009   vat_json_init_array (msg_array);
4010   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4011     {
4012       msg = vat_json_array_add (msg_array);
4013       vat_json_init_object (msg);
4014       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4015                                        (u8 *) counter_type_to_str (i, 0));
4016       vat_json_object_add_int (msg, "is_combined", 0);
4017       counter_array = vat_json_object_add (msg, "data");
4018       vat_json_init_array (counter_array);
4019       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4020         {
4021           packets = vam->simple_interface_counters[i][j];
4022           vat_json_array_add_uint (counter_array, packets);
4023         }
4024     }
4025   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4026     {
4027       msg = vat_json_array_add (msg_array);
4028       vat_json_init_object (msg);
4029       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4030                                        (u8 *) counter_type_to_str (i, 1));
4031       vat_json_object_add_int (msg, "is_combined", 1);
4032       counter_array = vat_json_object_add (msg, "data");
4033       vat_json_init_array (counter_array);
4034       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4035         {
4036           c = vam->combined_interface_counters[i][j];
4037           counter = vat_json_array_add (counter_array);
4038           vat_json_init_object (counter);
4039           vat_json_object_add_uint (counter, "packets", c.packets);
4040           vat_json_object_add_uint (counter, "bytes", c.bytes);
4041         }
4042     }
4043
4044   /* ip4 fib counters */
4045   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4046   vat_json_init_array (msg_array);
4047   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4048     {
4049       msg = vat_json_array_add (msg_array);
4050       vat_json_init_object (msg);
4051       vat_json_object_add_uint (msg, "vrf_id",
4052                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4053       counter_array = vat_json_object_add (msg, "c");
4054       vat_json_init_array (counter_array);
4055       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4056         {
4057           counter = vat_json_array_add (counter_array);
4058           vat_json_init_object (counter);
4059           c4 = &vam->ip4_fib_counters[i][j];
4060           vat_json_object_add_ip4 (counter, "address", c4->address);
4061           vat_json_object_add_uint (counter, "address_length",
4062                                     c4->address_length);
4063           vat_json_object_add_uint (counter, "packets", c4->packets);
4064           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4065         }
4066     }
4067
4068   /* ip6 fib counters */
4069   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4070   vat_json_init_array (msg_array);
4071   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4072     {
4073       msg = vat_json_array_add (msg_array);
4074       vat_json_init_object (msg);
4075       vat_json_object_add_uint (msg, "vrf_id",
4076                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4077       counter_array = vat_json_object_add (msg, "c");
4078       vat_json_init_array (counter_array);
4079       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4080         {
4081           counter = vat_json_array_add (counter_array);
4082           vat_json_init_object (counter);
4083           c6 = &vam->ip6_fib_counters[i][j];
4084           vat_json_object_add_ip6 (counter, "address", c6->address);
4085           vat_json_object_add_uint (counter, "address_length",
4086                                     c6->address_length);
4087           vat_json_object_add_uint (counter, "packets", c6->packets);
4088           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4089         }
4090     }
4091
4092   vat_json_print (vam->ofp, &node);
4093   vat_json_free (&node);
4094
4095   return 0;
4096 }
4097
4098 int
4099 exec (vat_main_t * vam)
4100 {
4101   api_main_t *am = &api_main;
4102   vl_api_cli_request_t *mp;
4103   f64 timeout;
4104   void *oldheap;
4105   u8 *cmd = 0;
4106   unformat_input_t *i = vam->input;
4107
4108   if (vec_len (i->buffer) == 0)
4109     return -1;
4110
4111   if (vam->exec_mode == 0 && unformat (i, "mode"))
4112     {
4113       vam->exec_mode = 1;
4114       return 0;
4115     }
4116   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4117     {
4118       vam->exec_mode = 0;
4119       return 0;
4120     }
4121
4122
4123   M (CLI_REQUEST, cli_request);
4124
4125   /*
4126    * Copy cmd into shared memory.
4127    * In order for the CLI command to work, it
4128    * must be a vector ending in \n, not a C-string ending
4129    * in \n\0.
4130    */
4131   pthread_mutex_lock (&am->vlib_rp->mutex);
4132   oldheap = svm_push_data_heap (am->vlib_rp);
4133
4134   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4135   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4136
4137   svm_pop_heap (oldheap);
4138   pthread_mutex_unlock (&am->vlib_rp->mutex);
4139
4140   mp->cmd_in_shmem = (u64) cmd;
4141   S;
4142   timeout = vat_time_now (vam) + 10.0;
4143
4144   while (vat_time_now (vam) < timeout)
4145     {
4146       if (vam->result_ready == 1)
4147         {
4148           u8 *free_me;
4149           if (vam->shmem_result != NULL)
4150             fformat (vam->ofp, "%s", vam->shmem_result);
4151           pthread_mutex_lock (&am->vlib_rp->mutex);
4152           oldheap = svm_push_data_heap (am->vlib_rp);
4153
4154           free_me = (u8 *) vam->shmem_result;
4155           vec_free (free_me);
4156
4157           svm_pop_heap (oldheap);
4158           pthread_mutex_unlock (&am->vlib_rp->mutex);
4159           return 0;
4160         }
4161     }
4162   return -99;
4163 }
4164
4165 /*
4166  * Future replacement of exec() that passes CLI buffers directly in
4167  * the API messages instead of an additional shared memory area.
4168  */
4169 static int
4170 exec_inband (vat_main_t * vam)
4171 {
4172   vl_api_cli_inband_t *mp;
4173   f64 timeout;
4174   unformat_input_t *i = vam->input;
4175
4176   if (vec_len (i->buffer) == 0)
4177     return -1;
4178
4179   if (vam->exec_mode == 0 && unformat (i, "mode"))
4180     {
4181       vam->exec_mode = 1;
4182       return 0;
4183     }
4184   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4185     {
4186       vam->exec_mode = 0;
4187       return 0;
4188     }
4189
4190   /*
4191    * In order for the CLI command to work, it
4192    * must be a vector ending in \n, not a C-string ending
4193    * in \n\0.
4194    */
4195   u32 len = vec_len (vam->input->buffer);
4196   M2 (CLI_INBAND, cli_inband, len);
4197   clib_memcpy (mp->cmd, vam->input->buffer, len);
4198   mp->length = htonl (len);
4199
4200   S;
4201   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4202 }
4203
4204 static int
4205 api_create_loopback (vat_main_t * vam)
4206 {
4207   unformat_input_t *i = vam->input;
4208   vl_api_create_loopback_t *mp;
4209   f64 timeout;
4210   u8 mac_address[6];
4211   u8 mac_set = 0;
4212
4213   memset (mac_address, 0, sizeof (mac_address));
4214
4215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4216     {
4217       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4218         mac_set = 1;
4219       else
4220         break;
4221     }
4222
4223   /* Construct the API message */
4224   M (CREATE_LOOPBACK, create_loopback);
4225   if (mac_set)
4226     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4227
4228   S;
4229   W;
4230 }
4231
4232 static int
4233 api_delete_loopback (vat_main_t * vam)
4234 {
4235   unformat_input_t *i = vam->input;
4236   vl_api_delete_loopback_t *mp;
4237   f64 timeout;
4238   u32 sw_if_index = ~0;
4239
4240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4241     {
4242       if (unformat (i, "sw_if_index %d", &sw_if_index))
4243         ;
4244       else
4245         break;
4246     }
4247
4248   if (sw_if_index == ~0)
4249     {
4250       errmsg ("missing sw_if_index\n");
4251       return -99;
4252     }
4253
4254   /* Construct the API message */
4255   M (DELETE_LOOPBACK, delete_loopback);
4256   mp->sw_if_index = ntohl (sw_if_index);
4257
4258   S;
4259   W;
4260 }
4261
4262 static int
4263 api_want_stats (vat_main_t * vam)
4264 {
4265   unformat_input_t *i = vam->input;
4266   vl_api_want_stats_t *mp;
4267   f64 timeout;
4268   int enable = -1;
4269
4270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4271     {
4272       if (unformat (i, "enable"))
4273         enable = 1;
4274       else if (unformat (i, "disable"))
4275         enable = 0;
4276       else
4277         break;
4278     }
4279
4280   if (enable == -1)
4281     {
4282       errmsg ("missing enable|disable\n");
4283       return -99;
4284     }
4285
4286   M (WANT_STATS, want_stats);
4287   mp->enable_disable = enable;
4288
4289   S;
4290   W;
4291 }
4292
4293 static int
4294 api_want_interface_events (vat_main_t * vam)
4295 {
4296   unformat_input_t *i = vam->input;
4297   vl_api_want_interface_events_t *mp;
4298   f64 timeout;
4299   int enable = -1;
4300
4301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4302     {
4303       if (unformat (i, "enable"))
4304         enable = 1;
4305       else if (unformat (i, "disable"))
4306         enable = 0;
4307       else
4308         break;
4309     }
4310
4311   if (enable == -1)
4312     {
4313       errmsg ("missing enable|disable\n");
4314       return -99;
4315     }
4316
4317   M (WANT_INTERFACE_EVENTS, want_interface_events);
4318   mp->enable_disable = enable;
4319
4320   vam->interface_event_display = enable;
4321
4322   S;
4323   W;
4324 }
4325
4326
4327 /* Note: non-static, called once to set up the initial intfc table */
4328 int
4329 api_sw_interface_dump (vat_main_t * vam)
4330 {
4331   vl_api_sw_interface_dump_t *mp;
4332   f64 timeout;
4333   hash_pair_t *p;
4334   name_sort_t *nses = 0, *ns;
4335   sw_interface_subif_t *sub = NULL;
4336
4337   /* Toss the old name table */
4338   /* *INDENT-OFF* */
4339   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4340   ({
4341     vec_add2 (nses, ns, 1);
4342     ns->name = (u8 *)(p->key);
4343     ns->value = (u32) p->value[0];
4344   }));
4345   /* *INDENT-ON* */
4346
4347   hash_free (vam->sw_if_index_by_interface_name);
4348
4349   vec_foreach (ns, nses) vec_free (ns->name);
4350
4351   vec_free (nses);
4352
4353   vec_foreach (sub, vam->sw_if_subif_table)
4354   {
4355     vec_free (sub->interface_name);
4356   }
4357   vec_free (vam->sw_if_subif_table);
4358
4359   /* recreate the interface name hash table */
4360   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4361
4362   /* Get list of ethernets */
4363   M (SW_INTERFACE_DUMP, sw_interface_dump);
4364   mp->name_filter_valid = 1;
4365   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4366   S;
4367
4368   /* and local / loopback interfaces */
4369   M (SW_INTERFACE_DUMP, sw_interface_dump);
4370   mp->name_filter_valid = 1;
4371   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4372   S;
4373
4374
4375   /* and vxlan-gpe tunnel interfaces */
4376   M (SW_INTERFACE_DUMP, sw_interface_dump);
4377   mp->name_filter_valid = 1;
4378   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4379            sizeof (mp->name_filter) - 1);
4380   S;
4381
4382   /* and vxlan tunnel interfaces */
4383   M (SW_INTERFACE_DUMP, sw_interface_dump);
4384   mp->name_filter_valid = 1;
4385   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4386   S;
4387
4388   /* and host (af_packet) interfaces */
4389   M (SW_INTERFACE_DUMP, sw_interface_dump);
4390   mp->name_filter_valid = 1;
4391   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4392   S;
4393
4394   /* and l2tpv3 tunnel interfaces */
4395   M (SW_INTERFACE_DUMP, sw_interface_dump);
4396   mp->name_filter_valid = 1;
4397   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4398            sizeof (mp->name_filter) - 1);
4399   S;
4400
4401   /* and GRE tunnel interfaces */
4402   M (SW_INTERFACE_DUMP, sw_interface_dump);
4403   mp->name_filter_valid = 1;
4404   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4405   S;
4406
4407   /* and LISP-GPE interfaces */
4408   M (SW_INTERFACE_DUMP, sw_interface_dump);
4409   mp->name_filter_valid = 1;
4410   strncpy ((char *) mp->name_filter, "lisp_gpe",
4411            sizeof (mp->name_filter) - 1);
4412   S;
4413
4414   /* and IPSEC tunnel interfaces */
4415   M (SW_INTERFACE_DUMP, sw_interface_dump);
4416   mp->name_filter_valid = 1;
4417   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4418   S;
4419
4420   /* Use a control ping for synchronization */
4421   {
4422     vl_api_control_ping_t *mp;
4423     M (CONTROL_PING, control_ping);
4424     S;
4425   }
4426   W;
4427 }
4428
4429 static int
4430 api_sw_interface_set_flags (vat_main_t * vam)
4431 {
4432   unformat_input_t *i = vam->input;
4433   vl_api_sw_interface_set_flags_t *mp;
4434   f64 timeout;
4435   u32 sw_if_index;
4436   u8 sw_if_index_set = 0;
4437   u8 admin_up = 0, link_up = 0;
4438
4439   /* Parse args required to build the message */
4440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4441     {
4442       if (unformat (i, "admin-up"))
4443         admin_up = 1;
4444       else if (unformat (i, "admin-down"))
4445         admin_up = 0;
4446       else if (unformat (i, "link-up"))
4447         link_up = 1;
4448       else if (unformat (i, "link-down"))
4449         link_up = 0;
4450       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4451         sw_if_index_set = 1;
4452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4453         sw_if_index_set = 1;
4454       else
4455         break;
4456     }
4457
4458   if (sw_if_index_set == 0)
4459     {
4460       errmsg ("missing interface name or sw_if_index\n");
4461       return -99;
4462     }
4463
4464   /* Construct the API message */
4465   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4466   mp->sw_if_index = ntohl (sw_if_index);
4467   mp->admin_up_down = admin_up;
4468   mp->link_up_down = link_up;
4469
4470   /* send it... */
4471   S;
4472
4473   /* Wait for a reply, return the good/bad news... */
4474   W;
4475 }
4476
4477 static int
4478 api_sw_interface_clear_stats (vat_main_t * vam)
4479 {
4480   unformat_input_t *i = vam->input;
4481   vl_api_sw_interface_clear_stats_t *mp;
4482   f64 timeout;
4483   u32 sw_if_index;
4484   u8 sw_if_index_set = 0;
4485
4486   /* Parse args required to build the message */
4487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4488     {
4489       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4490         sw_if_index_set = 1;
4491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4492         sw_if_index_set = 1;
4493       else
4494         break;
4495     }
4496
4497   /* Construct the API message */
4498   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4499
4500   if (sw_if_index_set == 1)
4501     mp->sw_if_index = ntohl (sw_if_index);
4502   else
4503     mp->sw_if_index = ~0;
4504
4505   /* send it... */
4506   S;
4507
4508   /* Wait for a reply, return the good/bad news... */
4509   W;
4510 }
4511
4512 static int
4513 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4514 {
4515   unformat_input_t *i = vam->input;
4516   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4517   f64 timeout;
4518   u32 sw_if_index;
4519   u8 sw_if_index_set = 0;
4520   u32 subport;
4521   u8 subport_set = 0;
4522   u32 pipe;
4523   u8 pipe_set = 0;
4524   u32 profile;
4525   u8 profile_set = 0;
4526
4527   /* Parse args required to build the message */
4528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4529     {
4530       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4531         sw_if_index_set = 1;
4532       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4533         sw_if_index_set = 1;
4534       else if (unformat (i, "subport %u", &subport))
4535         subport_set = 1;
4536       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4537         sw_if_index_set = 1;
4538       else if (unformat (i, "pipe %u", &pipe))
4539         pipe_set = 1;
4540       else if (unformat (i, "profile %u", &profile))
4541         profile_set = 1;
4542       else
4543         break;
4544     }
4545
4546   if (sw_if_index_set == 0)
4547     {
4548       errmsg ("missing interface name or sw_if_index\n");
4549       return -99;
4550     }
4551
4552   if (subport_set == 0)
4553     {
4554       errmsg ("missing subport \n");
4555       return -99;
4556     }
4557
4558   if (pipe_set == 0)
4559     {
4560       errmsg ("missing pipe\n");
4561       return -99;
4562     }
4563
4564   if (profile_set == 0)
4565     {
4566       errmsg ("missing profile\n");
4567       return -99;
4568     }
4569
4570   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4571
4572   mp->sw_if_index = ntohl (sw_if_index);
4573   mp->subport = ntohl (subport);
4574   mp->pipe = ntohl (pipe);
4575   mp->profile = ntohl (profile);
4576
4577
4578   S;
4579   W;
4580   /* NOTREACHED */
4581   return 0;
4582 }
4583
4584 static int
4585 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4586 {
4587   unformat_input_t *i = vam->input;
4588   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4589   f64 timeout;
4590   u32 sw_if_index;
4591   u8 sw_if_index_set = 0;
4592   u32 subport;
4593   u8 subport_set = 0;
4594   u32 tb_rate = 1250000000;     /* 10GbE */
4595   u32 tb_size = 1000000;
4596   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4597   u32 tc_period = 10;
4598
4599   /* Parse args required to build the message */
4600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4601     {
4602       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4603         sw_if_index_set = 1;
4604       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4605         sw_if_index_set = 1;
4606       else if (unformat (i, "subport %u", &subport))
4607         subport_set = 1;
4608       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4609         sw_if_index_set = 1;
4610       else if (unformat (i, "rate %u", &tb_rate))
4611         {
4612           u32 tc_id;
4613
4614           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4615                tc_id++)
4616             tc_rate[tc_id] = tb_rate;
4617         }
4618       else if (unformat (i, "bktsize %u", &tb_size))
4619         ;
4620       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4621         ;
4622       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4623         ;
4624       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4625         ;
4626       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4627         ;
4628       else if (unformat (i, "period %u", &tc_period))
4629         ;
4630       else
4631         break;
4632     }
4633
4634   if (sw_if_index_set == 0)
4635     {
4636       errmsg ("missing interface name or sw_if_index\n");
4637       return -99;
4638     }
4639
4640   if (subport_set == 0)
4641     {
4642       errmsg ("missing subport \n");
4643       return -99;
4644     }
4645
4646   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4647
4648   mp->sw_if_index = ntohl (sw_if_index);
4649   mp->subport = ntohl (subport);
4650   mp->tb_rate = ntohl (tb_rate);
4651   mp->tb_size = ntohl (tb_size);
4652   mp->tc_rate[0] = ntohl (tc_rate[0]);
4653   mp->tc_rate[1] = ntohl (tc_rate[1]);
4654   mp->tc_rate[2] = ntohl (tc_rate[2]);
4655   mp->tc_rate[3] = ntohl (tc_rate[3]);
4656   mp->tc_period = ntohl (tc_period);
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4669   f64 timeout;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u8 entry_set = 0;
4673   u8 tc_set = 0;
4674   u8 queue_set = 0;
4675   u32 entry, tc, queue;
4676
4677   /* Parse args required to build the message */
4678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4679     {
4680       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4681         sw_if_index_set = 1;
4682       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4683         sw_if_index_set = 1;
4684       else if (unformat (i, "entry %d", &entry))
4685         entry_set = 1;
4686       else if (unformat (i, "tc %d", &tc))
4687         tc_set = 1;
4688       else if (unformat (i, "queue %d", &queue))
4689         queue_set = 1;
4690       else
4691         break;
4692     }
4693
4694   if (sw_if_index_set == 0)
4695     {
4696       errmsg ("missing interface name or sw_if_index\n");
4697       return -99;
4698     }
4699
4700   if (entry_set == 0)
4701     {
4702       errmsg ("missing entry \n");
4703       return -99;
4704     }
4705
4706   if (tc_set == 0)
4707     {
4708       errmsg ("missing traffic class \n");
4709       return -99;
4710     }
4711
4712   if (queue_set == 0)
4713     {
4714       errmsg ("missing queue \n");
4715       return -99;
4716     }
4717
4718   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4719
4720   mp->sw_if_index = ntohl (sw_if_index);
4721   mp->entry = ntohl (entry);
4722   mp->tc = ntohl (tc);
4723   mp->queue = ntohl (queue);
4724
4725   S;
4726   W;
4727   /* NOTREACHED */
4728   return 0;
4729 }
4730
4731 static int
4732 api_sw_interface_add_del_address (vat_main_t * vam)
4733 {
4734   unformat_input_t *i = vam->input;
4735   vl_api_sw_interface_add_del_address_t *mp;
4736   f64 timeout;
4737   u32 sw_if_index;
4738   u8 sw_if_index_set = 0;
4739   u8 is_add = 1, del_all = 0;
4740   u32 address_length = 0;
4741   u8 v4_address_set = 0;
4742   u8 v6_address_set = 0;
4743   ip4_address_t v4address;
4744   ip6_address_t v6address;
4745
4746   /* Parse args required to build the message */
4747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4748     {
4749       if (unformat (i, "del-all"))
4750         del_all = 1;
4751       else if (unformat (i, "del"))
4752         is_add = 0;
4753       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4754         sw_if_index_set = 1;
4755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4756         sw_if_index_set = 1;
4757       else if (unformat (i, "%U/%d",
4758                          unformat_ip4_address, &v4address, &address_length))
4759         v4_address_set = 1;
4760       else if (unformat (i, "%U/%d",
4761                          unformat_ip6_address, &v6address, &address_length))
4762         v6_address_set = 1;
4763       else
4764         break;
4765     }
4766
4767   if (sw_if_index_set == 0)
4768     {
4769       errmsg ("missing interface name or sw_if_index\n");
4770       return -99;
4771     }
4772   if (v4_address_set && v6_address_set)
4773     {
4774       errmsg ("both v4 and v6 addresses set\n");
4775       return -99;
4776     }
4777   if (!v4_address_set && !v6_address_set && !del_all)
4778     {
4779       errmsg ("no addresses set\n");
4780       return -99;
4781     }
4782
4783   /* Construct the API message */
4784   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4785
4786   mp->sw_if_index = ntohl (sw_if_index);
4787   mp->is_add = is_add;
4788   mp->del_all = del_all;
4789   if (v6_address_set)
4790     {
4791       mp->is_ipv6 = 1;
4792       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4793     }
4794   else
4795     {
4796       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4797     }
4798   mp->address_length = address_length;
4799
4800   /* send it... */
4801   S;
4802
4803   /* Wait for a reply, return good/bad news  */
4804   W;
4805 }
4806
4807 static int
4808 api_sw_interface_set_table (vat_main_t * vam)
4809 {
4810   unformat_input_t *i = vam->input;
4811   vl_api_sw_interface_set_table_t *mp;
4812   f64 timeout;
4813   u32 sw_if_index, vrf_id = 0;
4814   u8 sw_if_index_set = 0;
4815   u8 is_ipv6 = 0;
4816
4817   /* Parse args required to build the message */
4818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4819     {
4820       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4821         sw_if_index_set = 1;
4822       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4823         sw_if_index_set = 1;
4824       else if (unformat (i, "vrf %d", &vrf_id))
4825         ;
4826       else if (unformat (i, "ipv6"))
4827         is_ipv6 = 1;
4828       else
4829         break;
4830     }
4831
4832   if (sw_if_index_set == 0)
4833     {
4834       errmsg ("missing interface name or sw_if_index\n");
4835       return -99;
4836     }
4837
4838   /* Construct the API message */
4839   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4840
4841   mp->sw_if_index = ntohl (sw_if_index);
4842   mp->is_ipv6 = is_ipv6;
4843   mp->vrf_id = ntohl (vrf_id);
4844
4845   /* send it... */
4846   S;
4847
4848   /* Wait for a reply... */
4849   W;
4850 }
4851
4852 static int
4853 api_sw_interface_set_vpath (vat_main_t * vam)
4854 {
4855   unformat_input_t *i = vam->input;
4856   vl_api_sw_interface_set_vpath_t *mp;
4857   f64 timeout;
4858   u32 sw_if_index = 0;
4859   u8 sw_if_index_set = 0;
4860   u8 is_enable = 0;
4861
4862   /* Parse args required to build the message */
4863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4864     {
4865       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4866         sw_if_index_set = 1;
4867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4868         sw_if_index_set = 1;
4869       else if (unformat (i, "enable"))
4870         is_enable = 1;
4871       else if (unformat (i, "disable"))
4872         is_enable = 0;
4873       else
4874         break;
4875     }
4876
4877   if (sw_if_index_set == 0)
4878     {
4879       errmsg ("missing interface name or sw_if_index\n");
4880       return -99;
4881     }
4882
4883   /* Construct the API message */
4884   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4885
4886   mp->sw_if_index = ntohl (sw_if_index);
4887   mp->enable = is_enable;
4888
4889   /* send it... */
4890   S;
4891
4892   /* Wait for a reply... */
4893   W;
4894 }
4895
4896 static int
4897 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4898 {
4899   unformat_input_t *i = vam->input;
4900   vl_api_sw_interface_set_l2_xconnect_t *mp;
4901   f64 timeout;
4902   u32 rx_sw_if_index;
4903   u8 rx_sw_if_index_set = 0;
4904   u32 tx_sw_if_index;
4905   u8 tx_sw_if_index_set = 0;
4906   u8 enable = 1;
4907
4908   /* Parse args required to build the message */
4909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4910     {
4911       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4912         rx_sw_if_index_set = 1;
4913       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4914         tx_sw_if_index_set = 1;
4915       else if (unformat (i, "rx"))
4916         {
4917           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4918             {
4919               if (unformat (i, "%U", unformat_sw_if_index, vam,
4920                             &rx_sw_if_index))
4921                 rx_sw_if_index_set = 1;
4922             }
4923           else
4924             break;
4925         }
4926       else if (unformat (i, "tx"))
4927         {
4928           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4929             {
4930               if (unformat (i, "%U", unformat_sw_if_index, vam,
4931                             &tx_sw_if_index))
4932                 tx_sw_if_index_set = 1;
4933             }
4934           else
4935             break;
4936         }
4937       else if (unformat (i, "enable"))
4938         enable = 1;
4939       else if (unformat (i, "disable"))
4940         enable = 0;
4941       else
4942         break;
4943     }
4944
4945   if (rx_sw_if_index_set == 0)
4946     {
4947       errmsg ("missing rx interface name or rx_sw_if_index\n");
4948       return -99;
4949     }
4950
4951   if (enable && (tx_sw_if_index_set == 0))
4952     {
4953       errmsg ("missing tx interface name or tx_sw_if_index\n");
4954       return -99;
4955     }
4956
4957   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4958
4959   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4960   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4961   mp->enable = enable;
4962
4963   S;
4964   W;
4965   /* NOTREACHED */
4966   return 0;
4967 }
4968
4969 static int
4970 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4971 {
4972   unformat_input_t *i = vam->input;
4973   vl_api_sw_interface_set_l2_bridge_t *mp;
4974   f64 timeout;
4975   u32 rx_sw_if_index;
4976   u8 rx_sw_if_index_set = 0;
4977   u32 bd_id;
4978   u8 bd_id_set = 0;
4979   u8 bvi = 0;
4980   u32 shg = 0;
4981   u8 enable = 1;
4982
4983   /* Parse args required to build the message */
4984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4985     {
4986       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4987         rx_sw_if_index_set = 1;
4988       else if (unformat (i, "bd_id %d", &bd_id))
4989         bd_id_set = 1;
4990       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4991         rx_sw_if_index_set = 1;
4992       else if (unformat (i, "shg %d", &shg))
4993         ;
4994       else if (unformat (i, "bvi"))
4995         bvi = 1;
4996       else if (unformat (i, "enable"))
4997         enable = 1;
4998       else if (unformat (i, "disable"))
4999         enable = 0;
5000       else
5001         break;
5002     }
5003
5004   if (rx_sw_if_index_set == 0)
5005     {
5006       errmsg ("missing rx interface name or sw_if_index\n");
5007       return -99;
5008     }
5009
5010   if (enable && (bd_id_set == 0))
5011     {
5012       errmsg ("missing bridge domain\n");
5013       return -99;
5014     }
5015
5016   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5017
5018   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5019   mp->bd_id = ntohl (bd_id);
5020   mp->shg = (u8) shg;
5021   mp->bvi = bvi;
5022   mp->enable = enable;
5023
5024   S;
5025   W;
5026   /* NOTREACHED */
5027   return 0;
5028 }
5029
5030 static int
5031 api_bridge_domain_dump (vat_main_t * vam)
5032 {
5033   unformat_input_t *i = vam->input;
5034   vl_api_bridge_domain_dump_t *mp;
5035   f64 timeout;
5036   u32 bd_id = ~0;
5037
5038   /* Parse args required to build the message */
5039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5040     {
5041       if (unformat (i, "bd_id %d", &bd_id))
5042         ;
5043       else
5044         break;
5045     }
5046
5047   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5048   mp->bd_id = ntohl (bd_id);
5049   S;
5050
5051   /* Use a control ping for synchronization */
5052   {
5053     vl_api_control_ping_t *mp;
5054     M (CONTROL_PING, control_ping);
5055     S;
5056   }
5057
5058   W;
5059   /* NOTREACHED */
5060   return 0;
5061 }
5062
5063 static int
5064 api_bridge_domain_add_del (vat_main_t * vam)
5065 {
5066   unformat_input_t *i = vam->input;
5067   vl_api_bridge_domain_add_del_t *mp;
5068   f64 timeout;
5069   u32 bd_id = ~0;
5070   u8 is_add = 1;
5071   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5072
5073   /* Parse args required to build the message */
5074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075     {
5076       if (unformat (i, "bd_id %d", &bd_id))
5077         ;
5078       else if (unformat (i, "flood %d", &flood))
5079         ;
5080       else if (unformat (i, "uu-flood %d", &uu_flood))
5081         ;
5082       else if (unformat (i, "forward %d", &forward))
5083         ;
5084       else if (unformat (i, "learn %d", &learn))
5085         ;
5086       else if (unformat (i, "arp-term %d", &arp_term))
5087         ;
5088       else if (unformat (i, "del"))
5089         {
5090           is_add = 0;
5091           flood = uu_flood = forward = learn = 0;
5092         }
5093       else
5094         break;
5095     }
5096
5097   if (bd_id == ~0)
5098     {
5099       errmsg ("missing bridge domain\n");
5100       return -99;
5101     }
5102
5103   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5104
5105   mp->bd_id = ntohl (bd_id);
5106   mp->flood = flood;
5107   mp->uu_flood = uu_flood;
5108   mp->forward = forward;
5109   mp->learn = learn;
5110   mp->arp_term = arp_term;
5111   mp->is_add = is_add;
5112
5113   S;
5114   W;
5115   /* NOTREACHED */
5116   return 0;
5117 }
5118
5119 static int
5120 api_l2fib_add_del (vat_main_t * vam)
5121 {
5122   unformat_input_t *i = vam->input;
5123   vl_api_l2fib_add_del_t *mp;
5124   f64 timeout;
5125   u64 mac = 0;
5126   u8 mac_set = 0;
5127   u32 bd_id;
5128   u8 bd_id_set = 0;
5129   u32 sw_if_index;
5130   u8 sw_if_index_set = 0;
5131   u8 is_add = 1;
5132   u8 static_mac = 0;
5133   u8 filter_mac = 0;
5134   u8 bvi_mac = 0;
5135   int count = 1;
5136   f64 before = 0;
5137   int j;
5138
5139   /* Parse args required to build the message */
5140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5141     {
5142       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5143         mac_set = 1;
5144       else if (unformat (i, "bd_id %d", &bd_id))
5145         bd_id_set = 1;
5146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5147         sw_if_index_set = 1;
5148       else if (unformat (i, "sw_if"))
5149         {
5150           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5151             {
5152               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5153                 sw_if_index_set = 1;
5154             }
5155           else
5156             break;
5157         }
5158       else if (unformat (i, "static"))
5159         static_mac = 1;
5160       else if (unformat (i, "filter"))
5161         {
5162           filter_mac = 1;
5163           static_mac = 1;
5164         }
5165       else if (unformat (i, "bvi"))
5166         {
5167           bvi_mac = 1;
5168           static_mac = 1;
5169         }
5170       else if (unformat (i, "del"))
5171         is_add = 0;
5172       else if (unformat (i, "count %d", &count))
5173         ;
5174       else
5175         break;
5176     }
5177
5178   if (mac_set == 0)
5179     {
5180       errmsg ("missing mac address\n");
5181       return -99;
5182     }
5183
5184   if (bd_id_set == 0)
5185     {
5186       errmsg ("missing bridge domain\n");
5187       return -99;
5188     }
5189
5190   if (is_add && (sw_if_index_set == 0))
5191     {
5192       errmsg ("missing interface name or sw_if_index\n");
5193       return -99;
5194     }
5195
5196   if (count > 1)
5197     {
5198       /* Turn on async mode */
5199       vam->async_mode = 1;
5200       vam->async_errors = 0;
5201       before = vat_time_now (vam);
5202     }
5203
5204   for (j = 0; j < count; j++)
5205     {
5206       M (L2FIB_ADD_DEL, l2fib_add_del);
5207
5208       mp->mac = mac;
5209       mp->bd_id = ntohl (bd_id);
5210       mp->is_add = is_add;
5211
5212       if (is_add)
5213         {
5214           mp->sw_if_index = ntohl (sw_if_index);
5215           mp->static_mac = static_mac;
5216           mp->filter_mac = filter_mac;
5217           mp->bvi_mac = bvi_mac;
5218         }
5219       increment_mac_address (&mac);
5220       /* send it... */
5221       S;
5222     }
5223
5224   if (count > 1)
5225     {
5226       vl_api_control_ping_t *mp;
5227       f64 after;
5228
5229       /* Shut off async mode */
5230       vam->async_mode = 0;
5231
5232       M (CONTROL_PING, control_ping);
5233       S;
5234
5235       timeout = vat_time_now (vam) + 1.0;
5236       while (vat_time_now (vam) < timeout)
5237         if (vam->result_ready == 1)
5238           goto out;
5239       vam->retval = -99;
5240
5241     out:
5242       if (vam->retval == -99)
5243         errmsg ("timeout\n");
5244
5245       if (vam->async_errors > 0)
5246         {
5247           errmsg ("%d asynchronous errors\n", vam->async_errors);
5248           vam->retval = -98;
5249         }
5250       vam->async_errors = 0;
5251       after = vat_time_now (vam);
5252
5253       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5254                count, after - before, count / (after - before));
5255     }
5256   else
5257     {
5258       /* Wait for a reply... */
5259       W;
5260     }
5261   /* Return the good/bad news */
5262   return (vam->retval);
5263 }
5264
5265 static int
5266 api_l2_flags (vat_main_t * vam)
5267 {
5268   unformat_input_t *i = vam->input;
5269   vl_api_l2_flags_t *mp;
5270   f64 timeout;
5271   u32 sw_if_index;
5272   u32 feature_bitmap = 0;
5273   u8 sw_if_index_set = 0;
5274
5275   /* Parse args required to build the message */
5276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5277     {
5278       if (unformat (i, "sw_if_index %d", &sw_if_index))
5279         sw_if_index_set = 1;
5280       else if (unformat (i, "sw_if"))
5281         {
5282           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5283             {
5284               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5285                 sw_if_index_set = 1;
5286             }
5287           else
5288             break;
5289         }
5290       else if (unformat (i, "learn"))
5291         feature_bitmap |= L2INPUT_FEAT_LEARN;
5292       else if (unformat (i, "forward"))
5293         feature_bitmap |= L2INPUT_FEAT_FWD;
5294       else if (unformat (i, "flood"))
5295         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5296       else if (unformat (i, "uu-flood"))
5297         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5298       else
5299         break;
5300     }
5301
5302   if (sw_if_index_set == 0)
5303     {
5304       errmsg ("missing interface name or sw_if_index\n");
5305       return -99;
5306     }
5307
5308   M (L2_FLAGS, l2_flags);
5309
5310   mp->sw_if_index = ntohl (sw_if_index);
5311   mp->feature_bitmap = ntohl (feature_bitmap);
5312
5313   S;
5314   W;
5315   /* NOTREACHED */
5316   return 0;
5317 }
5318
5319 static int
5320 api_bridge_flags (vat_main_t * vam)
5321 {
5322   unformat_input_t *i = vam->input;
5323   vl_api_bridge_flags_t *mp;
5324   f64 timeout;
5325   u32 bd_id;
5326   u8 bd_id_set = 0;
5327   u8 is_set = 1;
5328   u32 flags = 0;
5329
5330   /* Parse args required to build the message */
5331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5332     {
5333       if (unformat (i, "bd_id %d", &bd_id))
5334         bd_id_set = 1;
5335       else if (unformat (i, "learn"))
5336         flags |= L2_LEARN;
5337       else if (unformat (i, "forward"))
5338         flags |= L2_FWD;
5339       else if (unformat (i, "flood"))
5340         flags |= L2_FLOOD;
5341       else if (unformat (i, "uu-flood"))
5342         flags |= L2_UU_FLOOD;
5343       else if (unformat (i, "arp-term"))
5344         flags |= L2_ARP_TERM;
5345       else if (unformat (i, "off"))
5346         is_set = 0;
5347       else if (unformat (i, "disable"))
5348         is_set = 0;
5349       else
5350         break;
5351     }
5352
5353   if (bd_id_set == 0)
5354     {
5355       errmsg ("missing bridge domain\n");
5356       return -99;
5357     }
5358
5359   M (BRIDGE_FLAGS, bridge_flags);
5360
5361   mp->bd_id = ntohl (bd_id);
5362   mp->feature_bitmap = ntohl (flags);
5363   mp->is_set = is_set;
5364
5365   S;
5366   W;
5367   /* NOTREACHED */
5368   return 0;
5369 }
5370
5371 static int
5372 api_bd_ip_mac_add_del (vat_main_t * vam)
5373 {
5374   unformat_input_t *i = vam->input;
5375   vl_api_bd_ip_mac_add_del_t *mp;
5376   f64 timeout;
5377   u32 bd_id;
5378   u8 is_ipv6 = 0;
5379   u8 is_add = 1;
5380   u8 bd_id_set = 0;
5381   u8 ip_set = 0;
5382   u8 mac_set = 0;
5383   ip4_address_t v4addr;
5384   ip6_address_t v6addr;
5385   u8 macaddr[6];
5386
5387
5388   /* Parse args required to build the message */
5389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5390     {
5391       if (unformat (i, "bd_id %d", &bd_id))
5392         {
5393           bd_id_set++;
5394         }
5395       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5396         {
5397           ip_set++;
5398         }
5399       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5400         {
5401           ip_set++;
5402           is_ipv6++;
5403         }
5404       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5405         {
5406           mac_set++;
5407         }
5408       else if (unformat (i, "del"))
5409         is_add = 0;
5410       else
5411         break;
5412     }
5413
5414   if (bd_id_set == 0)
5415     {
5416       errmsg ("missing bridge domain\n");
5417       return -99;
5418     }
5419   else if (ip_set == 0)
5420     {
5421       errmsg ("missing IP address\n");
5422       return -99;
5423     }
5424   else if (mac_set == 0)
5425     {
5426       errmsg ("missing MAC address\n");
5427       return -99;
5428     }
5429
5430   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5431
5432   mp->bd_id = ntohl (bd_id);
5433   mp->is_ipv6 = is_ipv6;
5434   mp->is_add = is_add;
5435   if (is_ipv6)
5436     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5437   else
5438     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5439   clib_memcpy (mp->mac_address, macaddr, 6);
5440   S;
5441   W;
5442   /* NOTREACHED */
5443   return 0;
5444 }
5445
5446 static int
5447 api_tap_connect (vat_main_t * vam)
5448 {
5449   unformat_input_t *i = vam->input;
5450   vl_api_tap_connect_t *mp;
5451   f64 timeout;
5452   u8 mac_address[6];
5453   u8 random_mac = 1;
5454   u8 name_set = 0;
5455   u8 *tap_name;
5456
5457   memset (mac_address, 0, sizeof (mac_address));
5458
5459   /* Parse args required to build the message */
5460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5461     {
5462       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5463         {
5464           random_mac = 0;
5465         }
5466       else if (unformat (i, "random-mac"))
5467         random_mac = 1;
5468       else if (unformat (i, "tapname %s", &tap_name))
5469         name_set = 1;
5470       else
5471         break;
5472     }
5473
5474   if (name_set == 0)
5475     {
5476       errmsg ("missing tap name\n");
5477       return -99;
5478     }
5479   if (vec_len (tap_name) > 63)
5480     {
5481       errmsg ("tap name too long\n");
5482     }
5483   vec_add1 (tap_name, 0);
5484
5485   /* Construct the API message */
5486   M (TAP_CONNECT, tap_connect);
5487
5488   mp->use_random_mac = random_mac;
5489   clib_memcpy (mp->mac_address, mac_address, 6);
5490   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5491   vec_free (tap_name);
5492
5493   /* send it... */
5494   S;
5495
5496   /* Wait for a reply... */
5497   W;
5498 }
5499
5500 static int
5501 api_tap_modify (vat_main_t * vam)
5502 {
5503   unformat_input_t *i = vam->input;
5504   vl_api_tap_modify_t *mp;
5505   f64 timeout;
5506   u8 mac_address[6];
5507   u8 random_mac = 1;
5508   u8 name_set = 0;
5509   u8 *tap_name;
5510   u32 sw_if_index = ~0;
5511   u8 sw_if_index_set = 0;
5512
5513   memset (mac_address, 0, sizeof (mac_address));
5514
5515   /* Parse args required to build the message */
5516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5517     {
5518       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5519         sw_if_index_set = 1;
5520       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5521         sw_if_index_set = 1;
5522       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5523         {
5524           random_mac = 0;
5525         }
5526       else if (unformat (i, "random-mac"))
5527         random_mac = 1;
5528       else if (unformat (i, "tapname %s", &tap_name))
5529         name_set = 1;
5530       else
5531         break;
5532     }
5533
5534   if (sw_if_index_set == 0)
5535     {
5536       errmsg ("missing vpp interface name");
5537       return -99;
5538     }
5539   if (name_set == 0)
5540     {
5541       errmsg ("missing tap name\n");
5542       return -99;
5543     }
5544   if (vec_len (tap_name) > 63)
5545     {
5546       errmsg ("tap name too long\n");
5547     }
5548   vec_add1 (tap_name, 0);
5549
5550   /* Construct the API message */
5551   M (TAP_MODIFY, tap_modify);
5552
5553   mp->use_random_mac = random_mac;
5554   mp->sw_if_index = ntohl (sw_if_index);
5555   clib_memcpy (mp->mac_address, mac_address, 6);
5556   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5557   vec_free (tap_name);
5558
5559   /* send it... */
5560   S;
5561
5562   /* Wait for a reply... */
5563   W;
5564 }
5565
5566 static int
5567 api_tap_delete (vat_main_t * vam)
5568 {
5569   unformat_input_t *i = vam->input;
5570   vl_api_tap_delete_t *mp;
5571   f64 timeout;
5572   u32 sw_if_index = ~0;
5573   u8 sw_if_index_set = 0;
5574
5575   /* Parse args required to build the message */
5576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5577     {
5578       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5579         sw_if_index_set = 1;
5580       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5581         sw_if_index_set = 1;
5582       else
5583         break;
5584     }
5585
5586   if (sw_if_index_set == 0)
5587     {
5588       errmsg ("missing vpp interface name");
5589       return -99;
5590     }
5591
5592   /* Construct the API message */
5593   M (TAP_DELETE, tap_delete);
5594
5595   mp->sw_if_index = ntohl (sw_if_index);
5596
5597   /* send it... */
5598   S;
5599
5600   /* Wait for a reply... */
5601   W;
5602 }
5603
5604 static int
5605 api_ip_add_del_route (vat_main_t * vam)
5606 {
5607   unformat_input_t *i = vam->input;
5608   vl_api_ip_add_del_route_t *mp;
5609   f64 timeout;
5610   u32 sw_if_index = ~0, vrf_id = 0;
5611   u8 sw_if_index_set = 0;
5612   u8 is_ipv6 = 0;
5613   u8 is_local = 0, is_drop = 0;
5614   u8 create_vrf_if_needed = 0;
5615   u8 is_add = 1;
5616   u8 next_hop_weight = 1;
5617   u8 not_last = 0;
5618   u8 is_multipath = 0;
5619   u8 address_set = 0;
5620   u8 address_length_set = 0;
5621   u32 lookup_in_vrf = 0;
5622   u32 resolve_attempts = 0;
5623   u32 dst_address_length = 0;
5624   u8 next_hop_set = 0;
5625   ip4_address_t v4_dst_address, v4_next_hop_address;
5626   ip6_address_t v6_dst_address, v6_next_hop_address;
5627   int count = 1;
5628   int j;
5629   f64 before = 0;
5630   u32 random_add_del = 0;
5631   u32 *random_vector = 0;
5632   uword *random_hash;
5633   u32 random_seed = 0xdeaddabe;
5634   u32 classify_table_index = ~0;
5635   u8 is_classify = 0;
5636   u8 resolve_host, resolve_attached;
5637
5638   /* Parse args required to build the message */
5639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5640     {
5641       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5642         sw_if_index_set = 1;
5643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5644         sw_if_index_set = 1;
5645       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5646         {
5647           address_set = 1;
5648           is_ipv6 = 0;
5649         }
5650       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5651         {
5652           address_set = 1;
5653           is_ipv6 = 1;
5654         }
5655       else if (unformat (i, "/%d", &dst_address_length))
5656         {
5657           address_length_set = 1;
5658         }
5659
5660       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5661                                          &v4_next_hop_address))
5662         {
5663           next_hop_set = 1;
5664         }
5665       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5666                                          &v6_next_hop_address))
5667         {
5668           next_hop_set = 1;
5669         }
5670       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5671         ;
5672       else if (unformat (i, "weight %d", &next_hop_weight))
5673         ;
5674       else if (unformat (i, "drop"))
5675         {
5676           is_drop = 1;
5677         }
5678       else if (unformat (i, "local"))
5679         {
5680           is_local = 1;
5681         }
5682       else if (unformat (i, "classify %d", &classify_table_index))
5683         {
5684           is_classify = 1;
5685         }
5686       else if (unformat (i, "del"))
5687         is_add = 0;
5688       else if (unformat (i, "add"))
5689         is_add = 1;
5690       else if (unformat (i, "not-last"))
5691         not_last = 1;
5692       else if (unformat (i, "resolve-via-host"))
5693         resolve_host = 1;
5694       else if (unformat (i, "resolve-via-attached"))
5695         resolve_attached = 1;
5696       else if (unformat (i, "multipath"))
5697         is_multipath = 1;
5698       else if (unformat (i, "vrf %d", &vrf_id))
5699         ;
5700       else if (unformat (i, "create-vrf"))
5701         create_vrf_if_needed = 1;
5702       else if (unformat (i, "count %d", &count))
5703         ;
5704       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5705         ;
5706       else if (unformat (i, "random"))
5707         random_add_del = 1;
5708       else if (unformat (i, "seed %d", &random_seed))
5709         ;
5710       else
5711         {
5712           clib_warning ("parse error '%U'", format_unformat_error, i);
5713           return -99;
5714         }
5715     }
5716
5717   if (resolve_attempts > 0 && sw_if_index_set == 0)
5718     {
5719       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5720       return -99;
5721     }
5722
5723   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5724     {
5725       errmsg ("next hop / local / drop / classify not set\n");
5726       return -99;
5727     }
5728
5729   if (address_set == 0)
5730     {
5731       errmsg ("missing addresses\n");
5732       return -99;
5733     }
5734
5735   if (address_length_set == 0)
5736     {
5737       errmsg ("missing address length\n");
5738       return -99;
5739     }
5740
5741   /* Generate a pile of unique, random routes */
5742   if (random_add_del)
5743     {
5744       u32 this_random_address;
5745       random_hash = hash_create (count, sizeof (uword));
5746
5747       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5748       for (j = 0; j <= count; j++)
5749         {
5750           do
5751             {
5752               this_random_address = random_u32 (&random_seed);
5753               this_random_address =
5754                 clib_host_to_net_u32 (this_random_address);
5755             }
5756           while (hash_get (random_hash, this_random_address));
5757           vec_add1 (random_vector, this_random_address);
5758           hash_set (random_hash, this_random_address, 1);
5759         }
5760       hash_free (random_hash);
5761       v4_dst_address.as_u32 = random_vector[0];
5762     }
5763
5764   if (count > 1)
5765     {
5766       /* Turn on async mode */
5767       vam->async_mode = 1;
5768       vam->async_errors = 0;
5769       before = vat_time_now (vam);
5770     }
5771
5772   for (j = 0; j < count; j++)
5773     {
5774       /* Construct the API message */
5775       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5776
5777       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5778       mp->vrf_id = ntohl (vrf_id);
5779       if (resolve_attempts > 0)
5780         {
5781           mp->resolve_attempts = ntohl (resolve_attempts);
5782           mp->resolve_if_needed = 1;
5783         }
5784       mp->create_vrf_if_needed = create_vrf_if_needed;
5785
5786       mp->is_add = is_add;
5787       mp->is_drop = is_drop;
5788       mp->is_ipv6 = is_ipv6;
5789       mp->is_local = is_local;
5790       mp->is_classify = is_classify;
5791       mp->is_multipath = is_multipath;
5792       mp->is_resolve_host = resolve_host;
5793       mp->is_resolve_attached = resolve_attached;
5794       mp->not_last = not_last;
5795       mp->next_hop_weight = next_hop_weight;
5796       mp->dst_address_length = dst_address_length;
5797       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5798       mp->classify_table_index = ntohl (classify_table_index);
5799
5800       if (is_ipv6)
5801         {
5802           clib_memcpy (mp->dst_address, &v6_dst_address,
5803                        sizeof (v6_dst_address));
5804           if (next_hop_set)
5805             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5806                          sizeof (v6_next_hop_address));
5807           increment_v6_address (&v6_dst_address);
5808         }
5809       else
5810         {
5811           clib_memcpy (mp->dst_address, &v4_dst_address,
5812                        sizeof (v4_dst_address));
5813           if (next_hop_set)
5814             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5815                          sizeof (v4_next_hop_address));
5816           if (random_add_del)
5817             v4_dst_address.as_u32 = random_vector[j + 1];
5818           else
5819             increment_v4_address (&v4_dst_address);
5820         }
5821       /* send it... */
5822       S;
5823     }
5824
5825   /* When testing multiple add/del ops, use a control-ping to sync */
5826   if (count > 1)
5827     {
5828       vl_api_control_ping_t *mp;
5829       f64 after;
5830
5831       /* Shut off async mode */
5832       vam->async_mode = 0;
5833
5834       M (CONTROL_PING, control_ping);
5835       S;
5836
5837       timeout = vat_time_now (vam) + 1.0;
5838       while (vat_time_now (vam) < timeout)
5839         if (vam->result_ready == 1)
5840           goto out;
5841       vam->retval = -99;
5842
5843     out:
5844       if (vam->retval == -99)
5845         errmsg ("timeout\n");
5846
5847       if (vam->async_errors > 0)
5848         {
5849           errmsg ("%d asynchronous errors\n", vam->async_errors);
5850           vam->retval = -98;
5851         }
5852       vam->async_errors = 0;
5853       after = vat_time_now (vam);
5854
5855       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5856                count, after - before, count / (after - before));
5857     }
5858   else
5859     {
5860       /* Wait for a reply... */
5861       W;
5862     }
5863
5864   /* Return the good/bad news */
5865   return (vam->retval);
5866 }
5867
5868 static int
5869 api_proxy_arp_add_del (vat_main_t * vam)
5870 {
5871   unformat_input_t *i = vam->input;
5872   vl_api_proxy_arp_add_del_t *mp;
5873   f64 timeout;
5874   u32 vrf_id = 0;
5875   u8 is_add = 1;
5876   ip4_address_t lo, hi;
5877   u8 range_set = 0;
5878
5879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5880     {
5881       if (unformat (i, "vrf %d", &vrf_id))
5882         ;
5883       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5884                          unformat_ip4_address, &hi))
5885         range_set = 1;
5886       else if (unformat (i, "del"))
5887         is_add = 0;
5888       else
5889         {
5890           clib_warning ("parse error '%U'", format_unformat_error, i);
5891           return -99;
5892         }
5893     }
5894
5895   if (range_set == 0)
5896     {
5897       errmsg ("address range not set\n");
5898       return -99;
5899     }
5900
5901   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5902
5903   mp->vrf_id = ntohl (vrf_id);
5904   mp->is_add = is_add;
5905   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5906   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5907
5908   S;
5909   W;
5910   /* NOTREACHED */
5911   return 0;
5912 }
5913
5914 static int
5915 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5916 {
5917   unformat_input_t *i = vam->input;
5918   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5919   f64 timeout;
5920   u32 sw_if_index;
5921   u8 enable = 1;
5922   u8 sw_if_index_set = 0;
5923
5924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5925     {
5926       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5927         sw_if_index_set = 1;
5928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5929         sw_if_index_set = 1;
5930       else if (unformat (i, "enable"))
5931         enable = 1;
5932       else if (unformat (i, "disable"))
5933         enable = 0;
5934       else
5935         {
5936           clib_warning ("parse error '%U'", format_unformat_error, i);
5937           return -99;
5938         }
5939     }
5940
5941   if (sw_if_index_set == 0)
5942     {
5943       errmsg ("missing interface name or sw_if_index\n");
5944       return -99;
5945     }
5946
5947   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5948
5949   mp->sw_if_index = ntohl (sw_if_index);
5950   mp->enable_disable = enable;
5951
5952   S;
5953   W;
5954   /* NOTREACHED */
5955   return 0;
5956 }
5957
5958 static int
5959 api_mpls_add_del_decap (vat_main_t * vam)
5960 {
5961   unformat_input_t *i = vam->input;
5962   vl_api_mpls_add_del_decap_t *mp;
5963   f64 timeout;
5964   u32 rx_vrf_id = 0;
5965   u32 tx_vrf_id = 0;
5966   u32 label = 0;
5967   u8 is_add = 1;
5968   u8 s_bit = 1;
5969   u32 next_index = 1;
5970
5971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5972     {
5973       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5974         ;
5975       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5976         ;
5977       else if (unformat (i, "label %d", &label))
5978         ;
5979       else if (unformat (i, "next-index %d", &next_index))
5980         ;
5981       else if (unformat (i, "del"))
5982         is_add = 0;
5983       else if (unformat (i, "s-bit-clear"))
5984         s_bit = 0;
5985       else
5986         {
5987           clib_warning ("parse error '%U'", format_unformat_error, i);
5988           return -99;
5989         }
5990     }
5991
5992   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5993
5994   mp->rx_vrf_id = ntohl (rx_vrf_id);
5995   mp->tx_vrf_id = ntohl (tx_vrf_id);
5996   mp->label = ntohl (label);
5997   mp->next_index = ntohl (next_index);
5998   mp->s_bit = s_bit;
5999   mp->is_add = is_add;
6000
6001   S;
6002   W;
6003   /* NOTREACHED */
6004   return 0;
6005 }
6006
6007 static int
6008 api_mpls_add_del_encap (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_mpls_add_del_encap_t *mp;
6012   f64 timeout;
6013   u32 vrf_id = 0;
6014   u32 *labels = 0;
6015   u32 label;
6016   ip4_address_t dst_address;
6017   u8 is_add = 1;
6018
6019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6020     {
6021       if (unformat (i, "vrf %d", &vrf_id))
6022         ;
6023       else if (unformat (i, "label %d", &label))
6024         vec_add1 (labels, ntohl (label));
6025       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6026         ;
6027       else if (unformat (i, "del"))
6028         is_add = 0;
6029       else
6030         {
6031           clib_warning ("parse error '%U'", format_unformat_error, i);
6032           return -99;
6033         }
6034     }
6035
6036   if (vec_len (labels) == 0)
6037     {
6038       errmsg ("missing encap label stack\n");
6039       return -99;
6040     }
6041
6042   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6043       sizeof (u32) * vec_len (labels));
6044
6045   mp->vrf_id = ntohl (vrf_id);
6046   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6047   mp->is_add = is_add;
6048   mp->nlabels = vec_len (labels);
6049   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6050
6051   vec_free (labels);
6052
6053   S;
6054   W;
6055   /* NOTREACHED */
6056   return 0;
6057 }
6058
6059 static int
6060 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6061 {
6062   unformat_input_t *i = vam->input;
6063   vl_api_mpls_gre_add_del_tunnel_t *mp;
6064   f64 timeout;
6065   u32 inner_vrf_id = 0;
6066   u32 outer_vrf_id = 0;
6067   ip4_address_t src_address;
6068   ip4_address_t dst_address;
6069   ip4_address_t intfc_address;
6070   u32 tmp;
6071   u8 intfc_address_length = 0;
6072   u8 is_add = 1;
6073   u8 l2_only = 0;
6074
6075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6076     {
6077       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6078         ;
6079       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6080         ;
6081       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6082         ;
6083       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6084         ;
6085       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6086                          &intfc_address, &tmp))
6087         intfc_address_length = tmp;
6088       else if (unformat (i, "l2-only"))
6089         l2_only = 1;
6090       else if (unformat (i, "del"))
6091         is_add = 0;
6092       else
6093         {
6094           clib_warning ("parse error '%U'", format_unformat_error, i);
6095           return -99;
6096         }
6097     }
6098
6099   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6100
6101   mp->inner_vrf_id = ntohl (inner_vrf_id);
6102   mp->outer_vrf_id = ntohl (outer_vrf_id);
6103   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6104   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6105   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6106   mp->intfc_address_length = intfc_address_length;
6107   mp->l2_only = l2_only;
6108   mp->is_add = is_add;
6109
6110   S;
6111   W;
6112   /* NOTREACHED */
6113   return 0;
6114 }
6115
6116 static int
6117 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6118 {
6119   unformat_input_t *i = vam->input;
6120   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6121   f64 timeout;
6122   u32 inner_vrf_id = 0;
6123   ip4_address_t intfc_address;
6124   u8 dst_mac_address[6];
6125   int dst_set = 1;
6126   u32 tmp;
6127   u8 intfc_address_length = 0;
6128   u8 is_add = 1;
6129   u8 l2_only = 0;
6130   u32 tx_sw_if_index;
6131   int tx_sw_if_index_set = 0;
6132
6133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6134     {
6135       if (unformat (i, "vrf %d", &inner_vrf_id))
6136         ;
6137       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6138                          &intfc_address, &tmp))
6139         intfc_address_length = tmp;
6140       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6141         tx_sw_if_index_set = 1;
6142       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6143         tx_sw_if_index_set = 1;
6144       else if (unformat (i, "dst %U", unformat_ethernet_address,
6145                          dst_mac_address))
6146         dst_set = 1;
6147       else if (unformat (i, "l2-only"))
6148         l2_only = 1;
6149       else if (unformat (i, "del"))
6150         is_add = 0;
6151       else
6152         {
6153           clib_warning ("parse error '%U'", format_unformat_error, i);
6154           return -99;
6155         }
6156     }
6157
6158   if (!dst_set)
6159     {
6160       errmsg ("dst (mac address) not set\n");
6161       return -99;
6162     }
6163   if (!tx_sw_if_index_set)
6164     {
6165       errmsg ("tx-intfc not set\n");
6166       return -99;
6167     }
6168
6169   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6170
6171   mp->vrf_id = ntohl (inner_vrf_id);
6172   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6173   mp->adj_address_length = intfc_address_length;
6174   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6175                sizeof (dst_mac_address));
6176   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6177   mp->l2_only = l2_only;
6178   mp->is_add = is_add;
6179
6180   S;
6181   W;
6182   /* NOTREACHED */
6183   return 0;
6184 }
6185
6186 static int
6187 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6188 {
6189   unformat_input_t *i = vam->input;
6190   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6191   f64 timeout;
6192   u32 inner_vrf_id = 0;
6193   u32 outer_vrf_id = 0;
6194   ip4_address_t adj_address;
6195   int adj_address_set = 0;
6196   ip4_address_t next_hop_address;
6197   int next_hop_address_set = 0;
6198   u32 tmp;
6199   u8 adj_address_length = 0;
6200   u8 l2_only = 0;
6201   u8 is_add = 1;
6202   u32 resolve_attempts = 5;
6203   u8 resolve_if_needed = 1;
6204
6205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6206     {
6207       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6208         ;
6209       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6210         ;
6211       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6212                          &adj_address, &tmp))
6213         {
6214           adj_address_length = tmp;
6215           adj_address_set = 1;
6216         }
6217       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6218                          &next_hop_address))
6219         next_hop_address_set = 1;
6220       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6221         ;
6222       else if (unformat (i, "resolve-if-needed %d", &tmp))
6223         resolve_if_needed = tmp;
6224       else if (unformat (i, "l2-only"))
6225         l2_only = 1;
6226       else if (unformat (i, "del"))
6227         is_add = 0;
6228       else
6229         {
6230           clib_warning ("parse error '%U'", format_unformat_error, i);
6231           return -99;
6232         }
6233     }
6234
6235   if (!adj_address_set)
6236     {
6237       errmsg ("adjacency address/mask not set\n");
6238       return -99;
6239     }
6240   if (!next_hop_address_set)
6241     {
6242       errmsg ("ip4 next hop address (in outer fib) not set\n");
6243       return -99;
6244     }
6245
6246   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6247
6248   mp->inner_vrf_id = ntohl (inner_vrf_id);
6249   mp->outer_vrf_id = ntohl (outer_vrf_id);
6250   mp->resolve_attempts = ntohl (resolve_attempts);
6251   mp->resolve_if_needed = resolve_if_needed;
6252   mp->is_add = is_add;
6253   mp->l2_only = l2_only;
6254   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6255   mp->adj_address_length = adj_address_length;
6256   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6257                sizeof (next_hop_address));
6258
6259   S;
6260   W;
6261   /* NOTREACHED */
6262   return 0;
6263 }
6264
6265 static int
6266 api_sw_interface_set_unnumbered (vat_main_t * vam)
6267 {
6268   unformat_input_t *i = vam->input;
6269   vl_api_sw_interface_set_unnumbered_t *mp;
6270   f64 timeout;
6271   u32 sw_if_index;
6272   u32 unnum_sw_index = ~0;
6273   u8 is_add = 1;
6274   u8 sw_if_index_set = 0;
6275
6276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6277     {
6278       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6279         sw_if_index_set = 1;
6280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6281         sw_if_index_set = 1;
6282       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6283         ;
6284       else if (unformat (i, "del"))
6285         is_add = 0;
6286       else
6287         {
6288           clib_warning ("parse error '%U'", format_unformat_error, i);
6289           return -99;
6290         }
6291     }
6292
6293   if (sw_if_index_set == 0)
6294     {
6295       errmsg ("missing interface name or sw_if_index\n");
6296       return -99;
6297     }
6298
6299   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6300
6301   mp->sw_if_index = ntohl (sw_if_index);
6302   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6303   mp->is_add = is_add;
6304
6305   S;
6306   W;
6307   /* NOTREACHED */
6308   return 0;
6309 }
6310
6311 static int
6312 api_ip_neighbor_add_del (vat_main_t * vam)
6313 {
6314   unformat_input_t *i = vam->input;
6315   vl_api_ip_neighbor_add_del_t *mp;
6316   f64 timeout;
6317   u32 sw_if_index;
6318   u8 sw_if_index_set = 0;
6319   u32 vrf_id = 0;
6320   u8 is_add = 1;
6321   u8 is_static = 0;
6322   u8 mac_address[6];
6323   u8 mac_set = 0;
6324   u8 v4_address_set = 0;
6325   u8 v6_address_set = 0;
6326   ip4_address_t v4address;
6327   ip6_address_t v6address;
6328
6329   memset (mac_address, 0, sizeof (mac_address));
6330
6331   /* Parse args required to build the message */
6332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333     {
6334       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6335         {
6336           mac_set = 1;
6337         }
6338       else if (unformat (i, "del"))
6339         is_add = 0;
6340       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6341         sw_if_index_set = 1;
6342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6343         sw_if_index_set = 1;
6344       else if (unformat (i, "is_static"))
6345         is_static = 1;
6346       else if (unformat (i, "vrf %d", &vrf_id))
6347         ;
6348       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6349         v4_address_set = 1;
6350       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6351         v6_address_set = 1;
6352       else
6353         {
6354           clib_warning ("parse error '%U'", format_unformat_error, i);
6355           return -99;
6356         }
6357     }
6358
6359   if (sw_if_index_set == 0)
6360     {
6361       errmsg ("missing interface name or sw_if_index\n");
6362       return -99;
6363     }
6364   if (v4_address_set && v6_address_set)
6365     {
6366       errmsg ("both v4 and v6 addresses set\n");
6367       return -99;
6368     }
6369   if (!v4_address_set && !v6_address_set)
6370     {
6371       errmsg ("no address set\n");
6372       return -99;
6373     }
6374
6375   /* Construct the API message */
6376   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6377
6378   mp->sw_if_index = ntohl (sw_if_index);
6379   mp->is_add = is_add;
6380   mp->vrf_id = ntohl (vrf_id);
6381   mp->is_static = is_static;
6382   if (mac_set)
6383     clib_memcpy (mp->mac_address, mac_address, 6);
6384   if (v6_address_set)
6385     {
6386       mp->is_ipv6 = 1;
6387       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6388     }
6389   else
6390     {
6391       /* mp->is_ipv6 = 0; via memset in M macro above */
6392       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6393     }
6394
6395   /* send it... */
6396   S;
6397
6398   /* Wait for a reply, return good/bad news  */
6399   W;
6400
6401   /* NOTREACHED */
6402   return 0;
6403 }
6404
6405 static int
6406 api_reset_vrf (vat_main_t * vam)
6407 {
6408   unformat_input_t *i = vam->input;
6409   vl_api_reset_vrf_t *mp;
6410   f64 timeout;
6411   u32 vrf_id = 0;
6412   u8 is_ipv6 = 0;
6413   u8 vrf_id_set = 0;
6414
6415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6416     {
6417       if (unformat (i, "vrf %d", &vrf_id))
6418         vrf_id_set = 1;
6419       else if (unformat (i, "ipv6"))
6420         is_ipv6 = 1;
6421       else
6422         {
6423           clib_warning ("parse error '%U'", format_unformat_error, i);
6424           return -99;
6425         }
6426     }
6427
6428   if (vrf_id_set == 0)
6429     {
6430       errmsg ("missing vrf id\n");
6431       return -99;
6432     }
6433
6434   M (RESET_VRF, reset_vrf);
6435
6436   mp->vrf_id = ntohl (vrf_id);
6437   mp->is_ipv6 = is_ipv6;
6438
6439   S;
6440   W;
6441   /* NOTREACHED */
6442   return 0;
6443 }
6444
6445 static int
6446 api_create_vlan_subif (vat_main_t * vam)
6447 {
6448   unformat_input_t *i = vam->input;
6449   vl_api_create_vlan_subif_t *mp;
6450   f64 timeout;
6451   u32 sw_if_index;
6452   u8 sw_if_index_set = 0;
6453   u32 vlan_id;
6454   u8 vlan_id_set = 0;
6455
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "sw_if_index %d", &sw_if_index))
6459         sw_if_index_set = 1;
6460       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6461         sw_if_index_set = 1;
6462       else if (unformat (i, "vlan %d", &vlan_id))
6463         vlan_id_set = 1;
6464       else
6465         {
6466           clib_warning ("parse error '%U'", format_unformat_error, i);
6467           return -99;
6468         }
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index\n");
6474       return -99;
6475     }
6476
6477   if (vlan_id_set == 0)
6478     {
6479       errmsg ("missing vlan_id\n");
6480       return -99;
6481     }
6482   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6483
6484   mp->sw_if_index = ntohl (sw_if_index);
6485   mp->vlan_id = ntohl (vlan_id);
6486
6487   S;
6488   W;
6489   /* NOTREACHED */
6490   return 0;
6491 }
6492
6493 #define foreach_create_subif_bit                \
6494 _(no_tags)                                      \
6495 _(one_tag)                                      \
6496 _(two_tags)                                     \
6497 _(dot1ad)                                       \
6498 _(exact_match)                                  \
6499 _(default_sub)                                  \
6500 _(outer_vlan_id_any)                            \
6501 _(inner_vlan_id_any)
6502
6503 static int
6504 api_create_subif (vat_main_t * vam)
6505 {
6506   unformat_input_t *i = vam->input;
6507   vl_api_create_subif_t *mp;
6508   f64 timeout;
6509   u32 sw_if_index;
6510   u8 sw_if_index_set = 0;
6511   u32 sub_id;
6512   u8 sub_id_set = 0;
6513   u32 no_tags = 0;
6514   u32 one_tag = 0;
6515   u32 two_tags = 0;
6516   u32 dot1ad = 0;
6517   u32 exact_match = 0;
6518   u32 default_sub = 0;
6519   u32 outer_vlan_id_any = 0;
6520   u32 inner_vlan_id_any = 0;
6521   u32 tmp;
6522   u16 outer_vlan_id = 0;
6523   u16 inner_vlan_id = 0;
6524
6525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6526     {
6527       if (unformat (i, "sw_if_index %d", &sw_if_index))
6528         sw_if_index_set = 1;
6529       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sub_id %d", &sub_id))
6532         sub_id_set = 1;
6533       else if (unformat (i, "outer_vlan_id %d", &tmp))
6534         outer_vlan_id = tmp;
6535       else if (unformat (i, "inner_vlan_id %d", &tmp))
6536         inner_vlan_id = tmp;
6537
6538 #define _(a) else if (unformat (i, #a)) a = 1 ;
6539       foreach_create_subif_bit
6540 #undef _
6541         else
6542         {
6543           clib_warning ("parse error '%U'", format_unformat_error, i);
6544           return -99;
6545         }
6546     }
6547
6548   if (sw_if_index_set == 0)
6549     {
6550       errmsg ("missing interface name or sw_if_index\n");
6551       return -99;
6552     }
6553
6554   if (sub_id_set == 0)
6555     {
6556       errmsg ("missing sub_id\n");
6557       return -99;
6558     }
6559   M (CREATE_SUBIF, create_subif);
6560
6561   mp->sw_if_index = ntohl (sw_if_index);
6562   mp->sub_id = ntohl (sub_id);
6563
6564 #define _(a) mp->a = a;
6565   foreach_create_subif_bit;
6566 #undef _
6567
6568   mp->outer_vlan_id = ntohs (outer_vlan_id);
6569   mp->inner_vlan_id = ntohs (inner_vlan_id);
6570
6571   S;
6572   W;
6573   /* NOTREACHED */
6574   return 0;
6575 }
6576
6577 static int
6578 api_oam_add_del (vat_main_t * vam)
6579 {
6580   unformat_input_t *i = vam->input;
6581   vl_api_oam_add_del_t *mp;
6582   f64 timeout;
6583   u32 vrf_id = 0;
6584   u8 is_add = 1;
6585   ip4_address_t src, dst;
6586   u8 src_set = 0;
6587   u8 dst_set = 0;
6588
6589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6590     {
6591       if (unformat (i, "vrf %d", &vrf_id))
6592         ;
6593       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6594         src_set = 1;
6595       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6596         dst_set = 1;
6597       else if (unformat (i, "del"))
6598         is_add = 0;
6599       else
6600         {
6601           clib_warning ("parse error '%U'", format_unformat_error, i);
6602           return -99;
6603         }
6604     }
6605
6606   if (src_set == 0)
6607     {
6608       errmsg ("missing src addr\n");
6609       return -99;
6610     }
6611
6612   if (dst_set == 0)
6613     {
6614       errmsg ("missing dst addr\n");
6615       return -99;
6616     }
6617
6618   M (OAM_ADD_DEL, oam_add_del);
6619
6620   mp->vrf_id = ntohl (vrf_id);
6621   mp->is_add = is_add;
6622   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6623   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6624
6625   S;
6626   W;
6627   /* NOTREACHED */
6628   return 0;
6629 }
6630
6631 static int
6632 api_reset_fib (vat_main_t * vam)
6633 {
6634   unformat_input_t *i = vam->input;
6635   vl_api_reset_fib_t *mp;
6636   f64 timeout;
6637   u32 vrf_id = 0;
6638   u8 is_ipv6 = 0;
6639   u8 vrf_id_set = 0;
6640
6641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6642     {
6643       if (unformat (i, "vrf %d", &vrf_id))
6644         vrf_id_set = 1;
6645       else if (unformat (i, "ipv6"))
6646         is_ipv6 = 1;
6647       else
6648         {
6649           clib_warning ("parse error '%U'", format_unformat_error, i);
6650           return -99;
6651         }
6652     }
6653
6654   if (vrf_id_set == 0)
6655     {
6656       errmsg ("missing vrf id\n");
6657       return -99;
6658     }
6659
6660   M (RESET_FIB, reset_fib);
6661
6662   mp->vrf_id = ntohl (vrf_id);
6663   mp->is_ipv6 = is_ipv6;
6664
6665   S;
6666   W;
6667   /* NOTREACHED */
6668   return 0;
6669 }
6670
6671 static int
6672 api_dhcp_proxy_config (vat_main_t * vam)
6673 {
6674   unformat_input_t *i = vam->input;
6675   vl_api_dhcp_proxy_config_t *mp;
6676   f64 timeout;
6677   u32 vrf_id = 0;
6678   u8 is_add = 1;
6679   u8 insert_cid = 1;
6680   u8 v4_address_set = 0;
6681   u8 v6_address_set = 0;
6682   ip4_address_t v4address;
6683   ip6_address_t v6address;
6684   u8 v4_src_address_set = 0;
6685   u8 v6_src_address_set = 0;
6686   ip4_address_t v4srcaddress;
6687   ip6_address_t v6srcaddress;
6688
6689   /* Parse args required to build the message */
6690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691     {
6692       if (unformat (i, "del"))
6693         is_add = 0;
6694       else if (unformat (i, "vrf %d", &vrf_id))
6695         ;
6696       else if (unformat (i, "insert-cid %d", &insert_cid))
6697         ;
6698       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6699         v4_address_set = 1;
6700       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6701         v6_address_set = 1;
6702       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6703         v4_src_address_set = 1;
6704       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6705         v6_src_address_set = 1;
6706       else
6707         break;
6708     }
6709
6710   if (v4_address_set && v6_address_set)
6711     {
6712       errmsg ("both v4 and v6 server addresses set\n");
6713       return -99;
6714     }
6715   if (!v4_address_set && !v6_address_set)
6716     {
6717       errmsg ("no server addresses set\n");
6718       return -99;
6719     }
6720
6721   if (v4_src_address_set && v6_src_address_set)
6722     {
6723       errmsg ("both v4 and v6  src addresses set\n");
6724       return -99;
6725     }
6726   if (!v4_src_address_set && !v6_src_address_set)
6727     {
6728       errmsg ("no src addresses set\n");
6729       return -99;
6730     }
6731
6732   if (!(v4_src_address_set && v4_address_set) &&
6733       !(v6_src_address_set && v6_address_set))
6734     {
6735       errmsg ("no matching server and src addresses set\n");
6736       return -99;
6737     }
6738
6739   /* Construct the API message */
6740   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6741
6742   mp->insert_circuit_id = insert_cid;
6743   mp->is_add = is_add;
6744   mp->vrf_id = ntohl (vrf_id);
6745   if (v6_address_set)
6746     {
6747       mp->is_ipv6 = 1;
6748       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6749       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6750     }
6751   else
6752     {
6753       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6754       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6755     }
6756
6757   /* send it... */
6758   S;
6759
6760   /* Wait for a reply, return good/bad news  */
6761   W;
6762   /* NOTREACHED */
6763   return 0;
6764 }
6765
6766 static int
6767 api_dhcp_proxy_config_2 (vat_main_t * vam)
6768 {
6769   unformat_input_t *i = vam->input;
6770   vl_api_dhcp_proxy_config_2_t *mp;
6771   f64 timeout;
6772   u32 rx_vrf_id = 0;
6773   u32 server_vrf_id = 0;
6774   u8 is_add = 1;
6775   u8 insert_cid = 1;
6776   u8 v4_address_set = 0;
6777   u8 v6_address_set = 0;
6778   ip4_address_t v4address;
6779   ip6_address_t v6address;
6780   u8 v4_src_address_set = 0;
6781   u8 v6_src_address_set = 0;
6782   ip4_address_t v4srcaddress;
6783   ip6_address_t v6srcaddress;
6784
6785   /* Parse args required to build the message */
6786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6787     {
6788       if (unformat (i, "del"))
6789         is_add = 0;
6790       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6791         ;
6792       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6793         ;
6794       else if (unformat (i, "insert-cid %d", &insert_cid))
6795         ;
6796       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6797         v4_address_set = 1;
6798       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6799         v6_address_set = 1;
6800       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6801         v4_src_address_set = 1;
6802       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6803         v6_src_address_set = 1;
6804       else
6805         break;
6806     }
6807
6808   if (v4_address_set && v6_address_set)
6809     {
6810       errmsg ("both v4 and v6 server addresses set\n");
6811       return -99;
6812     }
6813   if (!v4_address_set && !v6_address_set)
6814     {
6815       errmsg ("no server addresses set\n");
6816       return -99;
6817     }
6818
6819   if (v4_src_address_set && v6_src_address_set)
6820     {
6821       errmsg ("both v4 and v6  src addresses set\n");
6822       return -99;
6823     }
6824   if (!v4_src_address_set && !v6_src_address_set)
6825     {
6826       errmsg ("no src addresses set\n");
6827       return -99;
6828     }
6829
6830   if (!(v4_src_address_set && v4_address_set) &&
6831       !(v6_src_address_set && v6_address_set))
6832     {
6833       errmsg ("no matching server and src addresses set\n");
6834       return -99;
6835     }
6836
6837   /* Construct the API message */
6838   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6839
6840   mp->insert_circuit_id = insert_cid;
6841   mp->is_add = is_add;
6842   mp->rx_vrf_id = ntohl (rx_vrf_id);
6843   mp->server_vrf_id = ntohl (server_vrf_id);
6844   if (v6_address_set)
6845     {
6846       mp->is_ipv6 = 1;
6847       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6848       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6849     }
6850   else
6851     {
6852       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6853       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6854     }
6855
6856   /* send it... */
6857   S;
6858
6859   /* Wait for a reply, return good/bad news  */
6860   W;
6861   /* NOTREACHED */
6862   return 0;
6863 }
6864
6865 static int
6866 api_dhcp_proxy_set_vss (vat_main_t * vam)
6867 {
6868   unformat_input_t *i = vam->input;
6869   vl_api_dhcp_proxy_set_vss_t *mp;
6870   f64 timeout;
6871   u8 is_ipv6 = 0;
6872   u8 is_add = 1;
6873   u32 tbl_id;
6874   u8 tbl_id_set = 0;
6875   u32 oui;
6876   u8 oui_set = 0;
6877   u32 fib_id;
6878   u8 fib_id_set = 0;
6879
6880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881     {
6882       if (unformat (i, "tbl_id %d", &tbl_id))
6883         tbl_id_set = 1;
6884       if (unformat (i, "fib_id %d", &fib_id))
6885         fib_id_set = 1;
6886       if (unformat (i, "oui %d", &oui))
6887         oui_set = 1;
6888       else if (unformat (i, "ipv6"))
6889         is_ipv6 = 1;
6890       else if (unformat (i, "del"))
6891         is_add = 0;
6892       else
6893         {
6894           clib_warning ("parse error '%U'", format_unformat_error, i);
6895           return -99;
6896         }
6897     }
6898
6899   if (tbl_id_set == 0)
6900     {
6901       errmsg ("missing tbl id\n");
6902       return -99;
6903     }
6904
6905   if (fib_id_set == 0)
6906     {
6907       errmsg ("missing fib id\n");
6908       return -99;
6909     }
6910   if (oui_set == 0)
6911     {
6912       errmsg ("missing oui\n");
6913       return -99;
6914     }
6915
6916   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6917   mp->tbl_id = ntohl (tbl_id);
6918   mp->fib_id = ntohl (fib_id);
6919   mp->oui = ntohl (oui);
6920   mp->is_ipv6 = is_ipv6;
6921   mp->is_add = is_add;
6922
6923   S;
6924   W;
6925   /* NOTREACHED */
6926   return 0;
6927 }
6928
6929 static int
6930 api_dhcp_client_config (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_dhcp_client_config_t *mp;
6934   f64 timeout;
6935   u32 sw_if_index;
6936   u8 sw_if_index_set = 0;
6937   u8 is_add = 1;
6938   u8 *hostname = 0;
6939   u8 disable_event = 0;
6940
6941   /* Parse args required to build the message */
6942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6943     {
6944       if (unformat (i, "del"))
6945         is_add = 0;
6946       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6947         sw_if_index_set = 1;
6948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "hostname %s", &hostname))
6951         ;
6952       else if (unformat (i, "disable_event"))
6953         disable_event = 1;
6954       else
6955         break;
6956     }
6957
6958   if (sw_if_index_set == 0)
6959     {
6960       errmsg ("missing interface name or sw_if_index\n");
6961       return -99;
6962     }
6963
6964   if (vec_len (hostname) > 63)
6965     {
6966       errmsg ("hostname too long\n");
6967     }
6968   vec_add1 (hostname, 0);
6969
6970   /* Construct the API message */
6971   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6972
6973   mp->sw_if_index = ntohl (sw_if_index);
6974   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6975   vec_free (hostname);
6976   mp->is_add = is_add;
6977   mp->want_dhcp_event = disable_event ? 0 : 1;
6978   mp->pid = getpid ();
6979
6980   /* send it... */
6981   S;
6982
6983   /* Wait for a reply, return good/bad news  */
6984   W;
6985   /* NOTREACHED */
6986   return 0;
6987 }
6988
6989 static int
6990 api_set_ip_flow_hash (vat_main_t * vam)
6991 {
6992   unformat_input_t *i = vam->input;
6993   vl_api_set_ip_flow_hash_t *mp;
6994   f64 timeout;
6995   u32 vrf_id = 0;
6996   u8 is_ipv6 = 0;
6997   u8 vrf_id_set = 0;
6998   u8 src = 0;
6999   u8 dst = 0;
7000   u8 sport = 0;
7001   u8 dport = 0;
7002   u8 proto = 0;
7003   u8 reverse = 0;
7004
7005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7006     {
7007       if (unformat (i, "vrf %d", &vrf_id))
7008         vrf_id_set = 1;
7009       else if (unformat (i, "ipv6"))
7010         is_ipv6 = 1;
7011       else if (unformat (i, "src"))
7012         src = 1;
7013       else if (unformat (i, "dst"))
7014         dst = 1;
7015       else if (unformat (i, "sport"))
7016         sport = 1;
7017       else if (unformat (i, "dport"))
7018         dport = 1;
7019       else if (unformat (i, "proto"))
7020         proto = 1;
7021       else if (unformat (i, "reverse"))
7022         reverse = 1;
7023
7024       else
7025         {
7026           clib_warning ("parse error '%U'", format_unformat_error, i);
7027           return -99;
7028         }
7029     }
7030
7031   if (vrf_id_set == 0)
7032     {
7033       errmsg ("missing vrf id\n");
7034       return -99;
7035     }
7036
7037   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7038   mp->src = src;
7039   mp->dst = dst;
7040   mp->sport = sport;
7041   mp->dport = dport;
7042   mp->proto = proto;
7043   mp->reverse = reverse;
7044   mp->vrf_id = ntohl (vrf_id);
7045   mp->is_ipv6 = is_ipv6;
7046
7047   S;
7048   W;
7049   /* NOTREACHED */
7050   return 0;
7051 }
7052
7053 static int
7054 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7055 {
7056   unformat_input_t *i = vam->input;
7057   vl_api_sw_interface_ip6_enable_disable_t *mp;
7058   f64 timeout;
7059   u32 sw_if_index;
7060   u8 sw_if_index_set = 0;
7061   u8 enable = 0;
7062
7063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7064     {
7065       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7066         sw_if_index_set = 1;
7067       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7068         sw_if_index_set = 1;
7069       else if (unformat (i, "enable"))
7070         enable = 1;
7071       else if (unformat (i, "disable"))
7072         enable = 0;
7073       else
7074         {
7075           clib_warning ("parse error '%U'", format_unformat_error, i);
7076           return -99;
7077         }
7078     }
7079
7080   if (sw_if_index_set == 0)
7081     {
7082       errmsg ("missing interface name or sw_if_index\n");
7083       return -99;
7084     }
7085
7086   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7087
7088   mp->sw_if_index = ntohl (sw_if_index);
7089   mp->enable = enable;
7090
7091   S;
7092   W;
7093   /* NOTREACHED */
7094   return 0;
7095 }
7096
7097 static int
7098 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7099 {
7100   unformat_input_t *i = vam->input;
7101   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7102   f64 timeout;
7103   u32 sw_if_index;
7104   u8 sw_if_index_set = 0;
7105   u32 address_length = 0;
7106   u8 v6_address_set = 0;
7107   ip6_address_t v6address;
7108
7109   /* Parse args required to build the message */
7110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7111     {
7112       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7113         sw_if_index_set = 1;
7114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7115         sw_if_index_set = 1;
7116       else if (unformat (i, "%U/%d",
7117                          unformat_ip6_address, &v6address, &address_length))
7118         v6_address_set = 1;
7119       else
7120         break;
7121     }
7122
7123   if (sw_if_index_set == 0)
7124     {
7125       errmsg ("missing interface name or sw_if_index\n");
7126       return -99;
7127     }
7128   if (!v6_address_set)
7129     {
7130       errmsg ("no address set\n");
7131       return -99;
7132     }
7133
7134   /* Construct the API message */
7135   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7136      sw_interface_ip6_set_link_local_address);
7137
7138   mp->sw_if_index = ntohl (sw_if_index);
7139   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7140   mp->address_length = address_length;
7141
7142   /* send it... */
7143   S;
7144
7145   /* Wait for a reply, return good/bad news  */
7146   W;
7147
7148   /* NOTREACHED */
7149   return 0;
7150 }
7151
7152
7153 static int
7154 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7158   f64 timeout;
7159   u32 sw_if_index;
7160   u8 sw_if_index_set = 0;
7161   u32 address_length = 0;
7162   u8 v6_address_set = 0;
7163   ip6_address_t v6address;
7164   u8 use_default = 0;
7165   u8 no_advertise = 0;
7166   u8 off_link = 0;
7167   u8 no_autoconfig = 0;
7168   u8 no_onlink = 0;
7169   u8 is_no = 0;
7170   u32 val_lifetime = 0;
7171   u32 pref_lifetime = 0;
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7177         sw_if_index_set = 1;
7178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7179         sw_if_index_set = 1;
7180       else if (unformat (i, "%U/%d",
7181                          unformat_ip6_address, &v6address, &address_length))
7182         v6_address_set = 1;
7183       else if (unformat (i, "val_life %d", &val_lifetime))
7184         ;
7185       else if (unformat (i, "pref_life %d", &pref_lifetime))
7186         ;
7187       else if (unformat (i, "def"))
7188         use_default = 1;
7189       else if (unformat (i, "noadv"))
7190         no_advertise = 1;
7191       else if (unformat (i, "offl"))
7192         off_link = 1;
7193       else if (unformat (i, "noauto"))
7194         no_autoconfig = 1;
7195       else if (unformat (i, "nolink"))
7196         no_onlink = 1;
7197       else if (unformat (i, "isno"))
7198         is_no = 1;
7199       else
7200         {
7201           clib_warning ("parse error '%U'", format_unformat_error, i);
7202           return -99;
7203         }
7204     }
7205
7206   if (sw_if_index_set == 0)
7207     {
7208       errmsg ("missing interface name or sw_if_index\n");
7209       return -99;
7210     }
7211   if (!v6_address_set)
7212     {
7213       errmsg ("no address set\n");
7214       return -99;
7215     }
7216
7217   /* Construct the API message */
7218   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7219
7220   mp->sw_if_index = ntohl (sw_if_index);
7221   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7222   mp->address_length = address_length;
7223   mp->use_default = use_default;
7224   mp->no_advertise = no_advertise;
7225   mp->off_link = off_link;
7226   mp->no_autoconfig = no_autoconfig;
7227   mp->no_onlink = no_onlink;
7228   mp->is_no = is_no;
7229   mp->val_lifetime = ntohl (val_lifetime);
7230   mp->pref_lifetime = ntohl (pref_lifetime);
7231
7232   /* send it... */
7233   S;
7234
7235   /* Wait for a reply, return good/bad news  */
7236   W;
7237
7238   /* NOTREACHED */
7239   return 0;
7240 }
7241
7242 static int
7243 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7244 {
7245   unformat_input_t *i = vam->input;
7246   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7247   f64 timeout;
7248   u32 sw_if_index;
7249   u8 sw_if_index_set = 0;
7250   u8 suppress = 0;
7251   u8 managed = 0;
7252   u8 other = 0;
7253   u8 ll_option = 0;
7254   u8 send_unicast = 0;
7255   u8 cease = 0;
7256   u8 is_no = 0;
7257   u8 default_router = 0;
7258   u32 max_interval = 0;
7259   u32 min_interval = 0;
7260   u32 lifetime = 0;
7261   u32 initial_count = 0;
7262   u32 initial_interval = 0;
7263
7264
7265   /* Parse args required to build the message */
7266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7267     {
7268       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7269         sw_if_index_set = 1;
7270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7271         sw_if_index_set = 1;
7272       else if (unformat (i, "maxint %d", &max_interval))
7273         ;
7274       else if (unformat (i, "minint %d", &min_interval))
7275         ;
7276       else if (unformat (i, "life %d", &lifetime))
7277         ;
7278       else if (unformat (i, "count %d", &initial_count))
7279         ;
7280       else if (unformat (i, "interval %d", &initial_interval))
7281         ;
7282       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7283         suppress = 1;
7284       else if (unformat (i, "managed"))
7285         managed = 1;
7286       else if (unformat (i, "other"))
7287         other = 1;
7288       else if (unformat (i, "ll"))
7289         ll_option = 1;
7290       else if (unformat (i, "send"))
7291         send_unicast = 1;
7292       else if (unformat (i, "cease"))
7293         cease = 1;
7294       else if (unformat (i, "isno"))
7295         is_no = 1;
7296       else if (unformat (i, "def"))
7297         default_router = 1;
7298       else
7299         {
7300           clib_warning ("parse error '%U'", format_unformat_error, i);
7301           return -99;
7302         }
7303     }
7304
7305   if (sw_if_index_set == 0)
7306     {
7307       errmsg ("missing interface name or sw_if_index\n");
7308       return -99;
7309     }
7310
7311   /* Construct the API message */
7312   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7313
7314   mp->sw_if_index = ntohl (sw_if_index);
7315   mp->max_interval = ntohl (max_interval);
7316   mp->min_interval = ntohl (min_interval);
7317   mp->lifetime = ntohl (lifetime);
7318   mp->initial_count = ntohl (initial_count);
7319   mp->initial_interval = ntohl (initial_interval);
7320   mp->suppress = suppress;
7321   mp->managed = managed;
7322   mp->other = other;
7323   mp->ll_option = ll_option;
7324   mp->send_unicast = send_unicast;
7325   mp->cease = cease;
7326   mp->is_no = is_no;
7327   mp->default_router = default_router;
7328
7329   /* send it... */
7330   S;
7331
7332   /* Wait for a reply, return good/bad news  */
7333   W;
7334
7335   /* NOTREACHED */
7336   return 0;
7337 }
7338
7339 static int
7340 api_set_arp_neighbor_limit (vat_main_t * vam)
7341 {
7342   unformat_input_t *i = vam->input;
7343   vl_api_set_arp_neighbor_limit_t *mp;
7344   f64 timeout;
7345   u32 arp_nbr_limit;
7346   u8 limit_set = 0;
7347   u8 is_ipv6 = 0;
7348
7349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7350     {
7351       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7352         limit_set = 1;
7353       else if (unformat (i, "ipv6"))
7354         is_ipv6 = 1;
7355       else
7356         {
7357           clib_warning ("parse error '%U'", format_unformat_error, i);
7358           return -99;
7359         }
7360     }
7361
7362   if (limit_set == 0)
7363     {
7364       errmsg ("missing limit value\n");
7365       return -99;
7366     }
7367
7368   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7369
7370   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7371   mp->is_ipv6 = is_ipv6;
7372
7373   S;
7374   W;
7375   /* NOTREACHED */
7376   return 0;
7377 }
7378
7379 static int
7380 api_l2_patch_add_del (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_l2_patch_add_del_t *mp;
7384   f64 timeout;
7385   u32 rx_sw_if_index;
7386   u8 rx_sw_if_index_set = 0;
7387   u32 tx_sw_if_index;
7388   u8 tx_sw_if_index_set = 0;
7389   u8 is_add = 1;
7390
7391   /* Parse args required to build the message */
7392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7393     {
7394       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7395         rx_sw_if_index_set = 1;
7396       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7397         tx_sw_if_index_set = 1;
7398       else if (unformat (i, "rx"))
7399         {
7400           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7401             {
7402               if (unformat (i, "%U", unformat_sw_if_index, vam,
7403                             &rx_sw_if_index))
7404                 rx_sw_if_index_set = 1;
7405             }
7406           else
7407             break;
7408         }
7409       else if (unformat (i, "tx"))
7410         {
7411           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7412             {
7413               if (unformat (i, "%U", unformat_sw_if_index, vam,
7414                             &tx_sw_if_index))
7415                 tx_sw_if_index_set = 1;
7416             }
7417           else
7418             break;
7419         }
7420       else if (unformat (i, "del"))
7421         is_add = 0;
7422       else
7423         break;
7424     }
7425
7426   if (rx_sw_if_index_set == 0)
7427     {
7428       errmsg ("missing rx interface name or rx_sw_if_index\n");
7429       return -99;
7430     }
7431
7432   if (tx_sw_if_index_set == 0)
7433     {
7434       errmsg ("missing tx interface name or tx_sw_if_index\n");
7435       return -99;
7436     }
7437
7438   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7439
7440   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7441   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7442   mp->is_add = is_add;
7443
7444   S;
7445   W;
7446   /* NOTREACHED */
7447   return 0;
7448 }
7449
7450 static int
7451 api_ioam_enable (vat_main_t * vam)
7452 {
7453   unformat_input_t *input = vam->input;
7454   vl_api_ioam_enable_t *mp;
7455   f64 timeout;
7456   u32 id = 0;
7457   int has_trace_option = 0;
7458   int has_pow_option = 0;
7459   int has_ppc_option = 0;
7460
7461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7462     {
7463       if (unformat (input, "trace"))
7464         has_trace_option = 1;
7465       else if (unformat (input, "pow"))
7466         has_pow_option = 1;
7467       else if (unformat (input, "ppc encap"))
7468         has_ppc_option = PPC_ENCAP;
7469       else if (unformat (input, "ppc decap"))
7470         has_ppc_option = PPC_DECAP;
7471       else if (unformat (input, "ppc none"))
7472         has_ppc_option = PPC_NONE;
7473       else
7474         break;
7475     }
7476   M (IOAM_ENABLE, ioam_enable);
7477   mp->id = htons (id);
7478   mp->trace_ppc = has_ppc_option;
7479   mp->pow_enable = has_pow_option;
7480   mp->trace_enable = has_trace_option;
7481
7482   S;
7483   W;
7484
7485   return (0);
7486
7487 }
7488
7489
7490 static int
7491 api_ioam_disable (vat_main_t * vam)
7492 {
7493   vl_api_ioam_disable_t *mp;
7494   f64 timeout;
7495
7496   M (IOAM_DISABLE, ioam_disable);
7497   S;
7498   W;
7499   return 0;
7500 }
7501
7502 static int
7503 api_sr_tunnel_add_del (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_sr_tunnel_add_del_t *mp;
7507   f64 timeout;
7508   int is_del = 0;
7509   int pl_index;
7510   ip6_address_t src_address;
7511   int src_address_set = 0;
7512   ip6_address_t dst_address;
7513   u32 dst_mask_width;
7514   int dst_address_set = 0;
7515   u16 flags = 0;
7516   u32 rx_table_id = 0;
7517   u32 tx_table_id = 0;
7518   ip6_address_t *segments = 0;
7519   ip6_address_t *this_seg;
7520   ip6_address_t *tags = 0;
7521   ip6_address_t *this_tag;
7522   ip6_address_t next_address, tag;
7523   u8 *name = 0;
7524   u8 *policy_name = 0;
7525
7526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7527     {
7528       if (unformat (i, "del"))
7529         is_del = 1;
7530       else if (unformat (i, "name %s", &name))
7531         ;
7532       else if (unformat (i, "policy %s", &policy_name))
7533         ;
7534       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7535         ;
7536       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7537         ;
7538       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7539         src_address_set = 1;
7540       else if (unformat (i, "dst %U/%d",
7541                          unformat_ip6_address, &dst_address, &dst_mask_width))
7542         dst_address_set = 1;
7543       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7544         {
7545           vec_add2 (segments, this_seg, 1);
7546           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7547                        sizeof (*this_seg));
7548         }
7549       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7550         {
7551           vec_add2 (tags, this_tag, 1);
7552           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7553         }
7554       else if (unformat (i, "clean"))
7555         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7556       else if (unformat (i, "protected"))
7557         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7558       else if (unformat (i, "InPE %d", &pl_index))
7559         {
7560           if (pl_index <= 0 || pl_index > 4)
7561             {
7562             pl_index_range_error:
7563               errmsg ("pl index %d out of range\n", pl_index);
7564               return -99;
7565             }
7566           flags |=
7567             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7568         }
7569       else if (unformat (i, "EgPE %d", &pl_index))
7570         {
7571           if (pl_index <= 0 || pl_index > 4)
7572             goto pl_index_range_error;
7573           flags |=
7574             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7575         }
7576       else if (unformat (i, "OrgSrc %d", &pl_index))
7577         {
7578           if (pl_index <= 0 || pl_index > 4)
7579             goto pl_index_range_error;
7580           flags |=
7581             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7582         }
7583       else
7584         break;
7585     }
7586
7587   if (!src_address_set)
7588     {
7589       errmsg ("src address required\n");
7590       return -99;
7591     }
7592
7593   if (!dst_address_set)
7594     {
7595       errmsg ("dst address required\n");
7596       return -99;
7597     }
7598
7599   if (!segments)
7600     {
7601       errmsg ("at least one sr segment required\n");
7602       return -99;
7603     }
7604
7605   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7606       vec_len (segments) * sizeof (ip6_address_t)
7607       + vec_len (tags) * sizeof (ip6_address_t));
7608
7609   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7610   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7611   mp->dst_mask_width = dst_mask_width;
7612   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7613   mp->n_segments = vec_len (segments);
7614   mp->n_tags = vec_len (tags);
7615   mp->is_add = is_del == 0;
7616   clib_memcpy (mp->segs_and_tags, segments,
7617                vec_len (segments) * sizeof (ip6_address_t));
7618   clib_memcpy (mp->segs_and_tags +
7619                vec_len (segments) * sizeof (ip6_address_t), tags,
7620                vec_len (tags) * sizeof (ip6_address_t));
7621
7622   mp->outer_vrf_id = ntohl (rx_table_id);
7623   mp->inner_vrf_id = ntohl (tx_table_id);
7624   memcpy (mp->name, name, vec_len (name));
7625   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7626
7627   vec_free (segments);
7628   vec_free (tags);
7629
7630   S;
7631   W;
7632   /* NOTREACHED */
7633 }
7634
7635 static int
7636 api_sr_policy_add_del (vat_main_t * vam)
7637 {
7638   unformat_input_t *input = vam->input;
7639   vl_api_sr_policy_add_del_t *mp;
7640   f64 timeout;
7641   int is_del = 0;
7642   u8 *name = 0;
7643   u8 *tunnel_name = 0;
7644   u8 **tunnel_names = 0;
7645
7646   int name_set = 0;
7647   int tunnel_set = 0;
7648   int j = 0;
7649   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7650   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7651
7652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7653     {
7654       if (unformat (input, "del"))
7655         is_del = 1;
7656       else if (unformat (input, "name %s", &name))
7657         name_set = 1;
7658       else if (unformat (input, "tunnel %s", &tunnel_name))
7659         {
7660           if (tunnel_name)
7661             {
7662               vec_add1 (tunnel_names, tunnel_name);
7663               /* For serializer:
7664                  - length = #bytes to store in serial vector
7665                  - +1 = byte to store that length
7666                */
7667               tunnel_names_length += (vec_len (tunnel_name) + 1);
7668               tunnel_set = 1;
7669               tunnel_name = 0;
7670             }
7671         }
7672       else
7673         break;
7674     }
7675
7676   if (!name_set)
7677     {
7678       errmsg ("policy name required\n");
7679       return -99;
7680     }
7681
7682   if ((!tunnel_set) && (!is_del))
7683     {
7684       errmsg ("tunnel name required\n");
7685       return -99;
7686     }
7687
7688   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7689
7690
7691
7692   mp->is_add = !is_del;
7693
7694   memcpy (mp->name, name, vec_len (name));
7695   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7696   u8 *serial_orig = 0;
7697   vec_validate (serial_orig, tunnel_names_length);
7698   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7699   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7700
7701   for (j = 0; j < vec_len (tunnel_names); j++)
7702     {
7703       tun_name_len = vec_len (tunnel_names[j]);
7704       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7705       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7706       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7707       serial_orig += tun_name_len;      // Advance past the copy
7708     }
7709   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7710
7711   vec_free (tunnel_names);
7712   vec_free (tunnel_name);
7713
7714   S;
7715   W;
7716   /* NOTREACHED */
7717 }
7718
7719 static int
7720 api_sr_multicast_map_add_del (vat_main_t * vam)
7721 {
7722   unformat_input_t *input = vam->input;
7723   vl_api_sr_multicast_map_add_del_t *mp;
7724   f64 timeout;
7725   int is_del = 0;
7726   ip6_address_t multicast_address;
7727   u8 *policy_name = 0;
7728   int multicast_address_set = 0;
7729
7730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7731     {
7732       if (unformat (input, "del"))
7733         is_del = 1;
7734       else
7735         if (unformat
7736             (input, "address %U", unformat_ip6_address, &multicast_address))
7737         multicast_address_set = 1;
7738       else if (unformat (input, "sr-policy %s", &policy_name))
7739         ;
7740       else
7741         break;
7742     }
7743
7744   if (!is_del && !policy_name)
7745     {
7746       errmsg ("sr-policy name required\n");
7747       return -99;
7748     }
7749
7750
7751   if (!multicast_address_set)
7752     {
7753       errmsg ("address required\n");
7754       return -99;
7755     }
7756
7757   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7758
7759   mp->is_add = !is_del;
7760   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7761   clib_memcpy (mp->multicast_address, &multicast_address,
7762                sizeof (mp->multicast_address));
7763
7764
7765   vec_free (policy_name);
7766
7767   S;
7768   W;
7769   /* NOTREACHED */
7770 }
7771
7772
7773 #define foreach_ip4_proto_field                 \
7774 _(src_address)                                  \
7775 _(dst_address)                                  \
7776 _(tos)                                          \
7777 _(length)                                       \
7778 _(fragment_id)                                  \
7779 _(ttl)                                          \
7780 _(protocol)                                     \
7781 _(checksum)
7782
7783 uword
7784 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7785 {
7786   u8 **maskp = va_arg (*args, u8 **);
7787   u8 *mask = 0;
7788   u8 found_something = 0;
7789   ip4_header_t *ip;
7790
7791 #define _(a) u8 a=0;
7792   foreach_ip4_proto_field;
7793 #undef _
7794   u8 version = 0;
7795   u8 hdr_length = 0;
7796
7797
7798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7799     {
7800       if (unformat (input, "version"))
7801         version = 1;
7802       else if (unformat (input, "hdr_length"))
7803         hdr_length = 1;
7804       else if (unformat (input, "src"))
7805         src_address = 1;
7806       else if (unformat (input, "dst"))
7807         dst_address = 1;
7808       else if (unformat (input, "proto"))
7809         protocol = 1;
7810
7811 #define _(a) else if (unformat (input, #a)) a=1;
7812       foreach_ip4_proto_field
7813 #undef _
7814         else
7815         break;
7816     }
7817
7818 #define _(a) found_something += a;
7819   foreach_ip4_proto_field;
7820 #undef _
7821
7822   if (found_something == 0)
7823     return 0;
7824
7825   vec_validate (mask, sizeof (*ip) - 1);
7826
7827   ip = (ip4_header_t *) mask;
7828
7829 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7830   foreach_ip4_proto_field;
7831 #undef _
7832
7833   ip->ip_version_and_header_length = 0;
7834
7835   if (version)
7836     ip->ip_version_and_header_length |= 0xF0;
7837
7838   if (hdr_length)
7839     ip->ip_version_and_header_length |= 0x0F;
7840
7841   *maskp = mask;
7842   return 1;
7843 }
7844
7845 #define foreach_ip6_proto_field                 \
7846 _(src_address)                                  \
7847 _(dst_address)                                  \
7848 _(payload_length)                               \
7849 _(hop_limit)                                    \
7850 _(protocol)
7851
7852 uword
7853 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7854 {
7855   u8 **maskp = va_arg (*args, u8 **);
7856   u8 *mask = 0;
7857   u8 found_something = 0;
7858   ip6_header_t *ip;
7859   u32 ip_version_traffic_class_and_flow_label;
7860
7861 #define _(a) u8 a=0;
7862   foreach_ip6_proto_field;
7863 #undef _
7864   u8 version = 0;
7865   u8 traffic_class = 0;
7866   u8 flow_label = 0;
7867
7868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (input, "version"))
7871         version = 1;
7872       else if (unformat (input, "traffic-class"))
7873         traffic_class = 1;
7874       else if (unformat (input, "flow-label"))
7875         flow_label = 1;
7876       else if (unformat (input, "src"))
7877         src_address = 1;
7878       else if (unformat (input, "dst"))
7879         dst_address = 1;
7880       else if (unformat (input, "proto"))
7881         protocol = 1;
7882
7883 #define _(a) else if (unformat (input, #a)) a=1;
7884       foreach_ip6_proto_field
7885 #undef _
7886         else
7887         break;
7888     }
7889
7890 #define _(a) found_something += a;
7891   foreach_ip6_proto_field;
7892 #undef _
7893
7894   if (found_something == 0)
7895     return 0;
7896
7897   vec_validate (mask, sizeof (*ip) - 1);
7898
7899   ip = (ip6_header_t *) mask;
7900
7901 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7902   foreach_ip6_proto_field;
7903 #undef _
7904
7905   ip_version_traffic_class_and_flow_label = 0;
7906
7907   if (version)
7908     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7909
7910   if (traffic_class)
7911     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7912
7913   if (flow_label)
7914     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7915
7916   ip->ip_version_traffic_class_and_flow_label =
7917     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7918
7919   *maskp = mask;
7920   return 1;
7921 }
7922
7923 uword
7924 unformat_l3_mask (unformat_input_t * input, va_list * args)
7925 {
7926   u8 **maskp = va_arg (*args, u8 **);
7927
7928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7931         return 1;
7932       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7933         return 1;
7934       else
7935         break;
7936     }
7937   return 0;
7938 }
7939
7940 uword
7941 unformat_l2_mask (unformat_input_t * input, va_list * args)
7942 {
7943   u8 **maskp = va_arg (*args, u8 **);
7944   u8 *mask = 0;
7945   u8 src = 0;
7946   u8 dst = 0;
7947   u8 proto = 0;
7948   u8 tag1 = 0;
7949   u8 tag2 = 0;
7950   u8 ignore_tag1 = 0;
7951   u8 ignore_tag2 = 0;
7952   u8 cos1 = 0;
7953   u8 cos2 = 0;
7954   u8 dot1q = 0;
7955   u8 dot1ad = 0;
7956   int len = 14;
7957
7958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (input, "src"))
7961         src = 1;
7962       else if (unformat (input, "dst"))
7963         dst = 1;
7964       else if (unformat (input, "proto"))
7965         proto = 1;
7966       else if (unformat (input, "tag1"))
7967         tag1 = 1;
7968       else if (unformat (input, "tag2"))
7969         tag2 = 1;
7970       else if (unformat (input, "ignore-tag1"))
7971         ignore_tag1 = 1;
7972       else if (unformat (input, "ignore-tag2"))
7973         ignore_tag2 = 1;
7974       else if (unformat (input, "cos1"))
7975         cos1 = 1;
7976       else if (unformat (input, "cos2"))
7977         cos2 = 1;
7978       else if (unformat (input, "dot1q"))
7979         dot1q = 1;
7980       else if (unformat (input, "dot1ad"))
7981         dot1ad = 1;
7982       else
7983         break;
7984     }
7985   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7986        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7987     return 0;
7988
7989   if (tag1 || ignore_tag1 || cos1 || dot1q)
7990     len = 18;
7991   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7992     len = 22;
7993
7994   vec_validate (mask, len - 1);
7995
7996   if (dst)
7997     memset (mask, 0xff, 6);
7998
7999   if (src)
8000     memset (mask + 6, 0xff, 6);
8001
8002   if (tag2 || dot1ad)
8003     {
8004       /* inner vlan tag */
8005       if (tag2)
8006         {
8007           mask[19] = 0xff;
8008           mask[18] = 0x0f;
8009         }
8010       if (cos2)
8011         mask[18] |= 0xe0;
8012       if (proto)
8013         mask[21] = mask[20] = 0xff;
8014       if (tag1)
8015         {
8016           mask[15] = 0xff;
8017           mask[14] = 0x0f;
8018         }
8019       if (cos1)
8020         mask[14] |= 0xe0;
8021       *maskp = mask;
8022       return 1;
8023     }
8024   if (tag1 | dot1q)
8025     {
8026       if (tag1)
8027         {
8028           mask[15] = 0xff;
8029           mask[14] = 0x0f;
8030         }
8031       if (cos1)
8032         mask[14] |= 0xe0;
8033       if (proto)
8034         mask[16] = mask[17] = 0xff;
8035
8036       *maskp = mask;
8037       return 1;
8038     }
8039   if (cos2)
8040     mask[18] |= 0xe0;
8041   if (cos1)
8042     mask[14] |= 0xe0;
8043   if (proto)
8044     mask[12] = mask[13] = 0xff;
8045
8046   *maskp = mask;
8047   return 1;
8048 }
8049
8050 uword
8051 unformat_classify_mask (unformat_input_t * input, va_list * args)
8052 {
8053   u8 **maskp = va_arg (*args, u8 **);
8054   u32 *skipp = va_arg (*args, u32 *);
8055   u32 *matchp = va_arg (*args, u32 *);
8056   u32 match;
8057   u8 *mask = 0;
8058   u8 *l2 = 0;
8059   u8 *l3 = 0;
8060   int i;
8061
8062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8063     {
8064       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8065         ;
8066       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8067         ;
8068       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8069         ;
8070       else
8071         break;
8072     }
8073
8074   if (mask || l2 || l3)
8075     {
8076       if (l2 || l3)
8077         {
8078           /* "With a free Ethernet header in every package" */
8079           if (l2 == 0)
8080             vec_validate (l2, 13);
8081           mask = l2;
8082           if (vec_len (l3))
8083             {
8084               vec_append (mask, l3);
8085               vec_free (l3);
8086             }
8087         }
8088
8089       /* Scan forward looking for the first significant mask octet */
8090       for (i = 0; i < vec_len (mask); i++)
8091         if (mask[i])
8092           break;
8093
8094       /* compute (skip, match) params */
8095       *skipp = i / sizeof (u32x4);
8096       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8097
8098       /* Pad mask to an even multiple of the vector size */
8099       while (vec_len (mask) % sizeof (u32x4))
8100         vec_add1 (mask, 0);
8101
8102       match = vec_len (mask) / sizeof (u32x4);
8103
8104       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8105         {
8106           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8107           if (*tmp || *(tmp + 1))
8108             break;
8109           match--;
8110         }
8111       if (match == 0)
8112         clib_warning ("BUG: match 0");
8113
8114       _vec_len (mask) = match * sizeof (u32x4);
8115
8116       *matchp = match;
8117       *maskp = mask;
8118
8119       return 1;
8120     }
8121
8122   return 0;
8123 }
8124
8125 #define foreach_l2_next                         \
8126 _(drop, DROP)                                   \
8127 _(ethernet, ETHERNET_INPUT)                     \
8128 _(ip4, IP4_INPUT)                               \
8129 _(ip6, IP6_INPUT)
8130
8131 uword
8132 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8133 {
8134   u32 *miss_next_indexp = va_arg (*args, u32 *);
8135   u32 next_index = 0;
8136   u32 tmp;
8137
8138 #define _(n,N) \
8139   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8140   foreach_l2_next;
8141 #undef _
8142
8143   if (unformat (input, "%d", &tmp))
8144     {
8145       next_index = tmp;
8146       goto out;
8147     }
8148
8149   return 0;
8150
8151 out:
8152   *miss_next_indexp = next_index;
8153   return 1;
8154 }
8155
8156 #define foreach_ip_next                         \
8157 _(drop, DROP)                                   \
8158 _(local, LOCAL)                                 \
8159 _(rewrite, REWRITE)
8160
8161 uword
8162 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8163 {
8164   u32 *miss_next_indexp = va_arg (*args, u32 *);
8165   u32 next_index = 0;
8166   u32 tmp;
8167
8168 #define _(n,N) \
8169   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8170   foreach_ip_next;
8171 #undef _
8172
8173   if (unformat (input, "%d", &tmp))
8174     {
8175       next_index = tmp;
8176       goto out;
8177     }
8178
8179   return 0;
8180
8181 out:
8182   *miss_next_indexp = next_index;
8183   return 1;
8184 }
8185
8186 #define foreach_acl_next                        \
8187 _(deny, DENY)
8188
8189 uword
8190 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8191 {
8192   u32 *miss_next_indexp = va_arg (*args, u32 *);
8193   u32 next_index = 0;
8194   u32 tmp;
8195
8196 #define _(n,N) \
8197   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8198   foreach_acl_next;
8199 #undef _
8200
8201   if (unformat (input, "permit"))
8202     {
8203       next_index = ~0;
8204       goto out;
8205     }
8206   else if (unformat (input, "%d", &tmp))
8207     {
8208       next_index = tmp;
8209       goto out;
8210     }
8211
8212   return 0;
8213
8214 out:
8215   *miss_next_indexp = next_index;
8216   return 1;
8217 }
8218
8219 uword
8220 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8221 {
8222   u32 *r = va_arg (*args, u32 *);
8223
8224   if (unformat (input, "conform-color"))
8225     *r = POLICE_CONFORM;
8226   else if (unformat (input, "exceed-color"))
8227     *r = POLICE_EXCEED;
8228   else
8229     return 0;
8230
8231   return 1;
8232 }
8233
8234 static int
8235 api_classify_add_del_table (vat_main_t * vam)
8236 {
8237   unformat_input_t *i = vam->input;
8238   vl_api_classify_add_del_table_t *mp;
8239
8240   u32 nbuckets = 2;
8241   u32 skip = ~0;
8242   u32 match = ~0;
8243   int is_add = 1;
8244   u32 table_index = ~0;
8245   u32 next_table_index = ~0;
8246   u32 miss_next_index = ~0;
8247   u32 memory_size = 32 << 20;
8248   u8 *mask = 0;
8249   f64 timeout;
8250
8251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8252     {
8253       if (unformat (i, "del"))
8254         is_add = 0;
8255       else if (unformat (i, "buckets %d", &nbuckets))
8256         ;
8257       else if (unformat (i, "memory_size %d", &memory_size))
8258         ;
8259       else if (unformat (i, "skip %d", &skip))
8260         ;
8261       else if (unformat (i, "match %d", &match))
8262         ;
8263       else if (unformat (i, "table %d", &table_index))
8264         ;
8265       else if (unformat (i, "mask %U", unformat_classify_mask,
8266                          &mask, &skip, &match))
8267         ;
8268       else if (unformat (i, "next-table %d", &next_table_index))
8269         ;
8270       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8271                          &miss_next_index))
8272         ;
8273       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8274                          &miss_next_index))
8275         ;
8276       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8277                          &miss_next_index))
8278         ;
8279       else
8280         break;
8281     }
8282
8283   if (is_add && mask == 0)
8284     {
8285       errmsg ("Mask required\n");
8286       return -99;
8287     }
8288
8289   if (is_add && skip == ~0)
8290     {
8291       errmsg ("skip count required\n");
8292       return -99;
8293     }
8294
8295   if (is_add && match == ~0)
8296     {
8297       errmsg ("match count required\n");
8298       return -99;
8299     }
8300
8301   if (!is_add && table_index == ~0)
8302     {
8303       errmsg ("table index required for delete\n");
8304       return -99;
8305     }
8306
8307   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8308
8309   mp->is_add = is_add;
8310   mp->table_index = ntohl (table_index);
8311   mp->nbuckets = ntohl (nbuckets);
8312   mp->memory_size = ntohl (memory_size);
8313   mp->skip_n_vectors = ntohl (skip);
8314   mp->match_n_vectors = ntohl (match);
8315   mp->next_table_index = ntohl (next_table_index);
8316   mp->miss_next_index = ntohl (miss_next_index);
8317   clib_memcpy (mp->mask, mask, vec_len (mask));
8318
8319   vec_free (mask);
8320
8321   S;
8322   W;
8323   /* NOTREACHED */
8324 }
8325
8326 uword
8327 unformat_ip4_match (unformat_input_t * input, va_list * args)
8328 {
8329   u8 **matchp = va_arg (*args, u8 **);
8330   u8 *match = 0;
8331   ip4_header_t *ip;
8332   int version = 0;
8333   u32 version_val;
8334   int hdr_length = 0;
8335   u32 hdr_length_val;
8336   int src = 0, dst = 0;
8337   ip4_address_t src_val, dst_val;
8338   int proto = 0;
8339   u32 proto_val;
8340   int tos = 0;
8341   u32 tos_val;
8342   int length = 0;
8343   u32 length_val;
8344   int fragment_id = 0;
8345   u32 fragment_id_val;
8346   int ttl = 0;
8347   int ttl_val;
8348   int checksum = 0;
8349   u32 checksum_val;
8350
8351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8352     {
8353       if (unformat (input, "version %d", &version_val))
8354         version = 1;
8355       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8356         hdr_length = 1;
8357       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8358         src = 1;
8359       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8360         dst = 1;
8361       else if (unformat (input, "proto %d", &proto_val))
8362         proto = 1;
8363       else if (unformat (input, "tos %d", &tos_val))
8364         tos = 1;
8365       else if (unformat (input, "length %d", &length_val))
8366         length = 1;
8367       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8368         fragment_id = 1;
8369       else if (unformat (input, "ttl %d", &ttl_val))
8370         ttl = 1;
8371       else if (unformat (input, "checksum %d", &checksum_val))
8372         checksum = 1;
8373       else
8374         break;
8375     }
8376
8377   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8378       + ttl + checksum == 0)
8379     return 0;
8380
8381   /*
8382    * Aligned because we use the real comparison functions
8383    */
8384   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8385
8386   ip = (ip4_header_t *) match;
8387
8388   /* These are realistically matched in practice */
8389   if (src)
8390     ip->src_address.as_u32 = src_val.as_u32;
8391
8392   if (dst)
8393     ip->dst_address.as_u32 = dst_val.as_u32;
8394
8395   if (proto)
8396     ip->protocol = proto_val;
8397
8398
8399   /* These are not, but they're included for completeness */
8400   if (version)
8401     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8402
8403   if (hdr_length)
8404     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8405
8406   if (tos)
8407     ip->tos = tos_val;
8408
8409   if (length)
8410     ip->length = length_val;
8411
8412   if (ttl)
8413     ip->ttl = ttl_val;
8414
8415   if (checksum)
8416     ip->checksum = checksum_val;
8417
8418   *matchp = match;
8419   return 1;
8420 }
8421
8422 uword
8423 unformat_ip6_match (unformat_input_t * input, va_list * args)
8424 {
8425   u8 **matchp = va_arg (*args, u8 **);
8426   u8 *match = 0;
8427   ip6_header_t *ip;
8428   int version = 0;
8429   u32 version_val;
8430   u8 traffic_class = 0;
8431   u32 traffic_class_val = 0;
8432   u8 flow_label = 0;
8433   u8 flow_label_val;
8434   int src = 0, dst = 0;
8435   ip6_address_t src_val, dst_val;
8436   int proto = 0;
8437   u32 proto_val;
8438   int payload_length = 0;
8439   u32 payload_length_val;
8440   int hop_limit = 0;
8441   int hop_limit_val;
8442   u32 ip_version_traffic_class_and_flow_label;
8443
8444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8445     {
8446       if (unformat (input, "version %d", &version_val))
8447         version = 1;
8448       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8449         traffic_class = 1;
8450       else if (unformat (input, "flow_label %d", &flow_label_val))
8451         flow_label = 1;
8452       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8453         src = 1;
8454       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8455         dst = 1;
8456       else if (unformat (input, "proto %d", &proto_val))
8457         proto = 1;
8458       else if (unformat (input, "payload_length %d", &payload_length_val))
8459         payload_length = 1;
8460       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8461         hop_limit = 1;
8462       else
8463         break;
8464     }
8465
8466   if (version + traffic_class + flow_label + src + dst + proto +
8467       payload_length + hop_limit == 0)
8468     return 0;
8469
8470   /*
8471    * Aligned because we use the real comparison functions
8472    */
8473   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8474
8475   ip = (ip6_header_t *) match;
8476
8477   if (src)
8478     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8479
8480   if (dst)
8481     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8482
8483   if (proto)
8484     ip->protocol = proto_val;
8485
8486   ip_version_traffic_class_and_flow_label = 0;
8487
8488   if (version)
8489     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8490
8491   if (traffic_class)
8492     ip_version_traffic_class_and_flow_label |=
8493       (traffic_class_val & 0xFF) << 20;
8494
8495   if (flow_label)
8496     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8497
8498   ip->ip_version_traffic_class_and_flow_label =
8499     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8500
8501   if (payload_length)
8502     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8503
8504   if (hop_limit)
8505     ip->hop_limit = hop_limit_val;
8506
8507   *matchp = match;
8508   return 1;
8509 }
8510
8511 uword
8512 unformat_l3_match (unformat_input_t * input, va_list * args)
8513 {
8514   u8 **matchp = va_arg (*args, u8 **);
8515
8516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8517     {
8518       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8519         return 1;
8520       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8521         return 1;
8522       else
8523         break;
8524     }
8525   return 0;
8526 }
8527
8528 uword
8529 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8530 {
8531   u8 *tagp = va_arg (*args, u8 *);
8532   u32 tag;
8533
8534   if (unformat (input, "%d", &tag))
8535     {
8536       tagp[0] = (tag >> 8) & 0x0F;
8537       tagp[1] = tag & 0xFF;
8538       return 1;
8539     }
8540
8541   return 0;
8542 }
8543
8544 uword
8545 unformat_l2_match (unformat_input_t * input, va_list * args)
8546 {
8547   u8 **matchp = va_arg (*args, u8 **);
8548   u8 *match = 0;
8549   u8 src = 0;
8550   u8 src_val[6];
8551   u8 dst = 0;
8552   u8 dst_val[6];
8553   u8 proto = 0;
8554   u16 proto_val;
8555   u8 tag1 = 0;
8556   u8 tag1_val[2];
8557   u8 tag2 = 0;
8558   u8 tag2_val[2];
8559   int len = 14;
8560   u8 ignore_tag1 = 0;
8561   u8 ignore_tag2 = 0;
8562   u8 cos1 = 0;
8563   u8 cos2 = 0;
8564   u32 cos1_val = 0;
8565   u32 cos2_val = 0;
8566
8567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8568     {
8569       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8570         src = 1;
8571       else
8572         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8573         dst = 1;
8574       else if (unformat (input, "proto %U",
8575                          unformat_ethernet_type_host_byte_order, &proto_val))
8576         proto = 1;
8577       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8578         tag1 = 1;
8579       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8580         tag2 = 1;
8581       else if (unformat (input, "ignore-tag1"))
8582         ignore_tag1 = 1;
8583       else if (unformat (input, "ignore-tag2"))
8584         ignore_tag2 = 1;
8585       else if (unformat (input, "cos1 %d", &cos1_val))
8586         cos1 = 1;
8587       else if (unformat (input, "cos2 %d", &cos2_val))
8588         cos2 = 1;
8589       else
8590         break;
8591     }
8592   if ((src + dst + proto + tag1 + tag2 +
8593        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8594     return 0;
8595
8596   if (tag1 || ignore_tag1 || cos1)
8597     len = 18;
8598   if (tag2 || ignore_tag2 || cos2)
8599     len = 22;
8600
8601   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8602
8603   if (dst)
8604     clib_memcpy (match, dst_val, 6);
8605
8606   if (src)
8607     clib_memcpy (match + 6, src_val, 6);
8608
8609   if (tag2)
8610     {
8611       /* inner vlan tag */
8612       match[19] = tag2_val[1];
8613       match[18] = tag2_val[0];
8614       if (cos2)
8615         match[18] |= (cos2_val & 0x7) << 5;
8616       if (proto)
8617         {
8618           match[21] = proto_val & 0xff;
8619           match[20] = proto_val >> 8;
8620         }
8621       if (tag1)
8622         {
8623           match[15] = tag1_val[1];
8624           match[14] = tag1_val[0];
8625         }
8626       if (cos1)
8627         match[14] |= (cos1_val & 0x7) << 5;
8628       *matchp = match;
8629       return 1;
8630     }
8631   if (tag1)
8632     {
8633       match[15] = tag1_val[1];
8634       match[14] = tag1_val[0];
8635       if (proto)
8636         {
8637           match[17] = proto_val & 0xff;
8638           match[16] = proto_val >> 8;
8639         }
8640       if (cos1)
8641         match[14] |= (cos1_val & 0x7) << 5;
8642
8643       *matchp = match;
8644       return 1;
8645     }
8646   if (cos2)
8647     match[18] |= (cos2_val & 0x7) << 5;
8648   if (cos1)
8649     match[14] |= (cos1_val & 0x7) << 5;
8650   if (proto)
8651     {
8652       match[13] = proto_val & 0xff;
8653       match[12] = proto_val >> 8;
8654     }
8655
8656   *matchp = match;
8657   return 1;
8658 }
8659
8660
8661 uword
8662 unformat_classify_match (unformat_input_t * input, va_list * args)
8663 {
8664   u8 **matchp = va_arg (*args, u8 **);
8665   u32 skip_n_vectors = va_arg (*args, u32);
8666   u32 match_n_vectors = va_arg (*args, u32);
8667
8668   u8 *match = 0;
8669   u8 *l2 = 0;
8670   u8 *l3 = 0;
8671
8672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8673     {
8674       if (unformat (input, "hex %U", unformat_hex_string, &match))
8675         ;
8676       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8677         ;
8678       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8679         ;
8680       else
8681         break;
8682     }
8683
8684   if (match || l2 || l3)
8685     {
8686       if (l2 || l3)
8687         {
8688           /* "Win a free Ethernet header in every packet" */
8689           if (l2 == 0)
8690             vec_validate_aligned (l2, 13, sizeof (u32x4));
8691           match = l2;
8692           if (vec_len (l3))
8693             {
8694               vec_append_aligned (match, l3, sizeof (u32x4));
8695               vec_free (l3);
8696             }
8697         }
8698
8699       /* Make sure the vector is big enough even if key is all 0's */
8700       vec_validate_aligned
8701         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8702          sizeof (u32x4));
8703
8704       /* Set size, include skipped vectors */
8705       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8706
8707       *matchp = match;
8708
8709       return 1;
8710     }
8711
8712   return 0;
8713 }
8714
8715 static int
8716 api_classify_add_del_session (vat_main_t * vam)
8717 {
8718   unformat_input_t *i = vam->input;
8719   vl_api_classify_add_del_session_t *mp;
8720   int is_add = 1;
8721   u32 table_index = ~0;
8722   u32 hit_next_index = ~0;
8723   u32 opaque_index = ~0;
8724   u8 *match = 0;
8725   i32 advance = 0;
8726   f64 timeout;
8727   u32 skip_n_vectors = 0;
8728   u32 match_n_vectors = 0;
8729
8730   /*
8731    * Warning: you have to supply skip_n and match_n
8732    * because the API client cant simply look at the classify
8733    * table object.
8734    */
8735
8736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8737     {
8738       if (unformat (i, "del"))
8739         is_add = 0;
8740       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8741                          &hit_next_index))
8742         ;
8743       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8744                          &hit_next_index))
8745         ;
8746       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8747                          &hit_next_index))
8748         ;
8749       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8750         ;
8751       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8752         ;
8753       else if (unformat (i, "opaque-index %d", &opaque_index))
8754         ;
8755       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8756         ;
8757       else if (unformat (i, "match_n %d", &match_n_vectors))
8758         ;
8759       else if (unformat (i, "match %U", unformat_classify_match,
8760                          &match, skip_n_vectors, match_n_vectors))
8761         ;
8762       else if (unformat (i, "advance %d", &advance))
8763         ;
8764       else if (unformat (i, "table-index %d", &table_index))
8765         ;
8766       else
8767         break;
8768     }
8769
8770   if (table_index == ~0)
8771     {
8772       errmsg ("Table index required\n");
8773       return -99;
8774     }
8775
8776   if (is_add && match == 0)
8777     {
8778       errmsg ("Match value required\n");
8779       return -99;
8780     }
8781
8782   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8783
8784   mp->is_add = is_add;
8785   mp->table_index = ntohl (table_index);
8786   mp->hit_next_index = ntohl (hit_next_index);
8787   mp->opaque_index = ntohl (opaque_index);
8788   mp->advance = ntohl (advance);
8789   clib_memcpy (mp->match, match, vec_len (match));
8790   vec_free (match);
8791
8792   S;
8793   W;
8794   /* NOTREACHED */
8795 }
8796
8797 static int
8798 api_classify_set_interface_ip_table (vat_main_t * vam)
8799 {
8800   unformat_input_t *i = vam->input;
8801   vl_api_classify_set_interface_ip_table_t *mp;
8802   f64 timeout;
8803   u32 sw_if_index;
8804   int sw_if_index_set;
8805   u32 table_index = ~0;
8806   u8 is_ipv6 = 0;
8807
8808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8809     {
8810       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8811         sw_if_index_set = 1;
8812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8813         sw_if_index_set = 1;
8814       else if (unformat (i, "table %d", &table_index))
8815         ;
8816       else
8817         {
8818           clib_warning ("parse error '%U'", format_unformat_error, i);
8819           return -99;
8820         }
8821     }
8822
8823   if (sw_if_index_set == 0)
8824     {
8825       errmsg ("missing interface name or sw_if_index\n");
8826       return -99;
8827     }
8828
8829
8830   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8831
8832   mp->sw_if_index = ntohl (sw_if_index);
8833   mp->table_index = ntohl (table_index);
8834   mp->is_ipv6 = is_ipv6;
8835
8836   S;
8837   W;
8838   /* NOTREACHED */
8839   return 0;
8840 }
8841
8842 static int
8843 api_classify_set_interface_l2_tables (vat_main_t * vam)
8844 {
8845   unformat_input_t *i = vam->input;
8846   vl_api_classify_set_interface_l2_tables_t *mp;
8847   f64 timeout;
8848   u32 sw_if_index;
8849   int sw_if_index_set;
8850   u32 ip4_table_index = ~0;
8851   u32 ip6_table_index = ~0;
8852   u32 other_table_index = ~0;
8853   u32 is_input = 1;
8854
8855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8856     {
8857       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8858         sw_if_index_set = 1;
8859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8862         ;
8863       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8864         ;
8865       else if (unformat (i, "other-table %d", &other_table_index))
8866         ;
8867       else if (unformat (i, "is-input %d", &is_input))
8868         ;
8869       else
8870         {
8871           clib_warning ("parse error '%U'", format_unformat_error, i);
8872           return -99;
8873         }
8874     }
8875
8876   if (sw_if_index_set == 0)
8877     {
8878       errmsg ("missing interface name or sw_if_index\n");
8879       return -99;
8880     }
8881
8882
8883   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8884
8885   mp->sw_if_index = ntohl (sw_if_index);
8886   mp->ip4_table_index = ntohl (ip4_table_index);
8887   mp->ip6_table_index = ntohl (ip6_table_index);
8888   mp->other_table_index = ntohl (other_table_index);
8889   mp->is_input = (u8) is_input;
8890
8891   S;
8892   W;
8893   /* NOTREACHED */
8894   return 0;
8895 }
8896
8897 static int
8898 api_set_ipfix_exporter (vat_main_t * vam)
8899 {
8900   unformat_input_t *i = vam->input;
8901   vl_api_set_ipfix_exporter_t *mp;
8902   ip4_address_t collector_address;
8903   u8 collector_address_set = 0;
8904   u32 collector_port = ~0;
8905   ip4_address_t src_address;
8906   u8 src_address_set = 0;
8907   u32 vrf_id = ~0;
8908   u32 path_mtu = ~0;
8909   u32 template_interval = ~0;
8910   u8 udp_checksum = 0;
8911   f64 timeout;
8912
8913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8914     {
8915       if (unformat (i, "collector_address %U", unformat_ip4_address,
8916                     &collector_address))
8917         collector_address_set = 1;
8918       else if (unformat (i, "collector_port %d", &collector_port))
8919         ;
8920       else if (unformat (i, "src_address %U", unformat_ip4_address,
8921                          &src_address))
8922         src_address_set = 1;
8923       else if (unformat (i, "vrf_id %d", &vrf_id))
8924         ;
8925       else if (unformat (i, "path_mtu %d", &path_mtu))
8926         ;
8927       else if (unformat (i, "template_interval %d", &template_interval))
8928         ;
8929       else if (unformat (i, "udp_checksum"))
8930         udp_checksum = 1;
8931       else
8932         break;
8933     }
8934
8935   if (collector_address_set == 0)
8936     {
8937       errmsg ("collector_address required\n");
8938       return -99;
8939     }
8940
8941   if (src_address_set == 0)
8942     {
8943       errmsg ("src_address required\n");
8944       return -99;
8945     }
8946
8947   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8948
8949   memcpy (mp->collector_address, collector_address.data,
8950           sizeof (collector_address.data));
8951   mp->collector_port = htons ((u16) collector_port);
8952   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8953   mp->vrf_id = htonl (vrf_id);
8954   mp->path_mtu = htonl (path_mtu);
8955   mp->template_interval = htonl (template_interval);
8956   mp->udp_checksum = udp_checksum;
8957
8958   S;
8959   W;
8960   /* NOTREACHED */
8961 }
8962
8963 static int
8964 api_set_ipfix_classify_stream (vat_main_t * vam)
8965 {
8966   unformat_input_t *i = vam->input;
8967   vl_api_set_ipfix_classify_stream_t *mp;
8968   u32 domain_id = 0;
8969   u32 src_port = UDP_DST_PORT_ipfix;
8970   f64 timeout;
8971
8972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8973     {
8974       if (unformat (i, "domain %d", &domain_id))
8975         ;
8976       else if (unformat (i, "src_port %d", &src_port))
8977         ;
8978       else
8979         {
8980           errmsg ("unknown input `%U'", format_unformat_error, i);
8981           return -99;
8982         }
8983     }
8984
8985   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8986
8987   mp->domain_id = htonl (domain_id);
8988   mp->src_port = htons ((u16) src_port);
8989
8990   S;
8991   W;
8992   /* NOTREACHED */
8993 }
8994
8995 static int
8996 api_ipfix_classify_table_add_del (vat_main_t * vam)
8997 {
8998   unformat_input_t *i = vam->input;
8999   vl_api_ipfix_classify_table_add_del_t *mp;
9000   int is_add = -1;
9001   u32 classify_table_index = ~0;
9002   u8 ip_version = 0;
9003   u8 transport_protocol = 255;
9004   f64 timeout;
9005
9006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9007     {
9008       if (unformat (i, "add"))
9009         is_add = 1;
9010       else if (unformat (i, "del"))
9011         is_add = 0;
9012       else if (unformat (i, "table %d", &classify_table_index))
9013         ;
9014       else if (unformat (i, "ip4"))
9015         ip_version = 4;
9016       else if (unformat (i, "ip6"))
9017         ip_version = 6;
9018       else if (unformat (i, "tcp"))
9019         transport_protocol = 6;
9020       else if (unformat (i, "udp"))
9021         transport_protocol = 17;
9022       else
9023         {
9024           errmsg ("unknown input `%U'", format_unformat_error, i);
9025           return -99;
9026         }
9027     }
9028
9029   if (is_add == -1)
9030     {
9031       errmsg ("expecting: add|del");
9032       return -99;
9033     }
9034   if (classify_table_index == ~0)
9035     {
9036       errmsg ("classifier table not specified");
9037       return -99;
9038     }
9039   if (ip_version == 0)
9040     {
9041       errmsg ("IP version not specified");
9042       return -99;
9043     }
9044
9045   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9046
9047   mp->is_add = is_add;
9048   mp->table_id = htonl (classify_table_index);
9049   mp->ip_version = ip_version;
9050   mp->transport_protocol = transport_protocol;
9051
9052   S;
9053   W;
9054   /* NOTREACHED */
9055 }
9056
9057 static int
9058 api_get_node_index (vat_main_t * vam)
9059 {
9060   unformat_input_t *i = vam->input;
9061   vl_api_get_node_index_t *mp;
9062   f64 timeout;
9063   u8 *name = 0;
9064
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "node %s", &name))
9068         ;
9069       else
9070         break;
9071     }
9072   if (name == 0)
9073     {
9074       errmsg ("node name required\n");
9075       return -99;
9076     }
9077   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9078     {
9079       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9080       return -99;
9081     }
9082
9083   M (GET_NODE_INDEX, get_node_index);
9084   clib_memcpy (mp->node_name, name, vec_len (name));
9085   vec_free (name);
9086
9087   S;
9088   W;
9089   /* NOTREACHED */
9090   return 0;
9091 }
9092
9093 static int
9094 api_get_next_index (vat_main_t * vam)
9095 {
9096   unformat_input_t *i = vam->input;
9097   vl_api_get_next_index_t *mp;
9098   f64 timeout;
9099   u8 *node_name = 0, *next_node_name = 0;
9100
9101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (i, "node-name %s", &node_name))
9104         ;
9105       else if (unformat (i, "next-node-name %s", &next_node_name))
9106         break;
9107     }
9108
9109   if (node_name == 0)
9110     {
9111       errmsg ("node name required\n");
9112       return -99;
9113     }
9114   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9115     {
9116       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9117       return -99;
9118     }
9119
9120   if (next_node_name == 0)
9121     {
9122       errmsg ("next node name required\n");
9123       return -99;
9124     }
9125   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9126     {
9127       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9128       return -99;
9129     }
9130
9131   M (GET_NEXT_INDEX, get_next_index);
9132   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9133   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9134   vec_free (node_name);
9135   vec_free (next_node_name);
9136
9137   S;
9138   W;
9139   /* NOTREACHED */
9140   return 0;
9141 }
9142
9143 static int
9144 api_add_node_next (vat_main_t * vam)
9145 {
9146   unformat_input_t *i = vam->input;
9147   vl_api_add_node_next_t *mp;
9148   f64 timeout;
9149   u8 *name = 0;
9150   u8 *next = 0;
9151
9152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9153     {
9154       if (unformat (i, "node %s", &name))
9155         ;
9156       else if (unformat (i, "next %s", &next))
9157         ;
9158       else
9159         break;
9160     }
9161   if (name == 0)
9162     {
9163       errmsg ("node name required\n");
9164       return -99;
9165     }
9166   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9167     {
9168       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9169       return -99;
9170     }
9171   if (next == 0)
9172     {
9173       errmsg ("next node required\n");
9174       return -99;
9175     }
9176   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9177     {
9178       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9179       return -99;
9180     }
9181
9182   M (ADD_NODE_NEXT, add_node_next);
9183   clib_memcpy (mp->node_name, name, vec_len (name));
9184   clib_memcpy (mp->next_name, next, vec_len (next));
9185   vec_free (name);
9186   vec_free (next);
9187
9188   S;
9189   W;
9190   /* NOTREACHED */
9191   return 0;
9192 }
9193
9194 static int
9195 api_l2tpv3_create_tunnel (vat_main_t * vam)
9196 {
9197   unformat_input_t *i = vam->input;
9198   ip6_address_t client_address, our_address;
9199   int client_address_set = 0;
9200   int our_address_set = 0;
9201   u32 local_session_id = 0;
9202   u32 remote_session_id = 0;
9203   u64 local_cookie = 0;
9204   u64 remote_cookie = 0;
9205   u8 l2_sublayer_present = 0;
9206   vl_api_l2tpv3_create_tunnel_t *mp;
9207   f64 timeout;
9208
9209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9210     {
9211       if (unformat (i, "client_address %U", unformat_ip6_address,
9212                     &client_address))
9213         client_address_set = 1;
9214       else if (unformat (i, "our_address %U", unformat_ip6_address,
9215                          &our_address))
9216         our_address_set = 1;
9217       else if (unformat (i, "local_session_id %d", &local_session_id))
9218         ;
9219       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9220         ;
9221       else if (unformat (i, "local_cookie %lld", &local_cookie))
9222         ;
9223       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9224         ;
9225       else if (unformat (i, "l2-sublayer-present"))
9226         l2_sublayer_present = 1;
9227       else
9228         break;
9229     }
9230
9231   if (client_address_set == 0)
9232     {
9233       errmsg ("client_address required\n");
9234       return -99;
9235     }
9236
9237   if (our_address_set == 0)
9238     {
9239       errmsg ("our_address required\n");
9240       return -99;
9241     }
9242
9243   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9244
9245   clib_memcpy (mp->client_address, client_address.as_u8,
9246                sizeof (mp->client_address));
9247
9248   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9249
9250   mp->local_session_id = ntohl (local_session_id);
9251   mp->remote_session_id = ntohl (remote_session_id);
9252   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9253   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9254   mp->l2_sublayer_present = l2_sublayer_present;
9255   mp->is_ipv6 = 1;
9256
9257   S;
9258   W;
9259   /* NOTREACHED */
9260   return 0;
9261 }
9262
9263 static int
9264 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9265 {
9266   unformat_input_t *i = vam->input;
9267   u32 sw_if_index;
9268   u8 sw_if_index_set = 0;
9269   u64 new_local_cookie = 0;
9270   u64 new_remote_cookie = 0;
9271   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9272   f64 timeout;
9273
9274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9275     {
9276       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9277         sw_if_index_set = 1;
9278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9279         sw_if_index_set = 1;
9280       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9281         ;
9282       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9283         ;
9284       else
9285         break;
9286     }
9287
9288   if (sw_if_index_set == 0)
9289     {
9290       errmsg ("missing interface name or sw_if_index\n");
9291       return -99;
9292     }
9293
9294   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9295
9296   mp->sw_if_index = ntohl (sw_if_index);
9297   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9298   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9299
9300   S;
9301   W;
9302   /* NOTREACHED */
9303   return 0;
9304 }
9305
9306 static int
9307 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_l2tpv3_interface_enable_disable_t *mp;
9311   f64 timeout;
9312   u32 sw_if_index;
9313   u8 sw_if_index_set = 0;
9314   u8 enable_disable = 1;
9315
9316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9317     {
9318       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9319         sw_if_index_set = 1;
9320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9321         sw_if_index_set = 1;
9322       else if (unformat (i, "enable"))
9323         enable_disable = 1;
9324       else if (unformat (i, "disable"))
9325         enable_disable = 0;
9326       else
9327         break;
9328     }
9329
9330   if (sw_if_index_set == 0)
9331     {
9332       errmsg ("missing interface name or sw_if_index\n");
9333       return -99;
9334     }
9335
9336   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9337
9338   mp->sw_if_index = ntohl (sw_if_index);
9339   mp->enable_disable = enable_disable;
9340
9341   S;
9342   W;
9343   /* NOTREACHED */
9344   return 0;
9345 }
9346
9347 static int
9348 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9349 {
9350   unformat_input_t *i = vam->input;
9351   vl_api_l2tpv3_set_lookup_key_t *mp;
9352   f64 timeout;
9353   u8 key = ~0;
9354
9355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (i, "lookup_v6_src"))
9358         key = L2T_LOOKUP_SRC_ADDRESS;
9359       else if (unformat (i, "lookup_v6_dst"))
9360         key = L2T_LOOKUP_DST_ADDRESS;
9361       else if (unformat (i, "lookup_session_id"))
9362         key = L2T_LOOKUP_SESSION_ID;
9363       else
9364         break;
9365     }
9366
9367   if (key == (u8) ~ 0)
9368     {
9369       errmsg ("l2tp session lookup key unset\n");
9370       return -99;
9371     }
9372
9373   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9374
9375   mp->key = key;
9376
9377   S;
9378   W;
9379   /* NOTREACHED */
9380   return 0;
9381 }
9382
9383 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9384   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9385 {
9386   vat_main_t *vam = &vat_main;
9387
9388   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9389            format_ip6_address, mp->our_address,
9390            format_ip6_address, mp->client_address,
9391            clib_net_to_host_u32 (mp->sw_if_index));
9392
9393   fformat (vam->ofp,
9394            "   local cookies %016llx %016llx remote cookie %016llx\n",
9395            clib_net_to_host_u64 (mp->local_cookie[0]),
9396            clib_net_to_host_u64 (mp->local_cookie[1]),
9397            clib_net_to_host_u64 (mp->remote_cookie));
9398
9399   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9400            clib_net_to_host_u32 (mp->local_session_id),
9401            clib_net_to_host_u32 (mp->remote_session_id));
9402
9403   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9404            mp->l2_sublayer_present ? "preset" : "absent");
9405
9406 }
9407
9408 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9409   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9410 {
9411   vat_main_t *vam = &vat_main;
9412   vat_json_node_t *node = NULL;
9413   struct in6_addr addr;
9414
9415   if (VAT_JSON_ARRAY != vam->json_tree.type)
9416     {
9417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9418       vat_json_init_array (&vam->json_tree);
9419     }
9420   node = vat_json_array_add (&vam->json_tree);
9421
9422   vat_json_init_object (node);
9423
9424   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9425   vat_json_object_add_ip6 (node, "our_address", addr);
9426   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9427   vat_json_object_add_ip6 (node, "client_address", addr);
9428
9429   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9430   vat_json_init_array (lc);
9431   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9432   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9433   vat_json_object_add_uint (node, "remote_cookie",
9434                             clib_net_to_host_u64 (mp->remote_cookie));
9435
9436   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9437   vat_json_object_add_uint (node, "local_session_id",
9438                             clib_net_to_host_u32 (mp->local_session_id));
9439   vat_json_object_add_uint (node, "remote_session_id",
9440                             clib_net_to_host_u32 (mp->remote_session_id));
9441   vat_json_object_add_string_copy (node, "l2_sublayer",
9442                                    mp->l2_sublayer_present ? (u8 *) "present"
9443                                    : (u8 *) "absent");
9444 }
9445
9446 static int
9447 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9448 {
9449   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9450   f64 timeout;
9451
9452   /* Get list of l2tpv3-tunnel interfaces */
9453   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9454   S;
9455
9456   /* Use a control ping for synchronization */
9457   {
9458     vl_api_control_ping_t *mp;
9459     M (CONTROL_PING, control_ping);
9460     S;
9461   }
9462   W;
9463 }
9464
9465
9466 static void vl_api_sw_interface_tap_details_t_handler
9467   (vl_api_sw_interface_tap_details_t * mp)
9468 {
9469   vat_main_t *vam = &vat_main;
9470
9471   fformat (vam->ofp, "%-16s %d\n",
9472            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9473 }
9474
9475 static void vl_api_sw_interface_tap_details_t_handler_json
9476   (vl_api_sw_interface_tap_details_t * mp)
9477 {
9478   vat_main_t *vam = &vat_main;
9479   vat_json_node_t *node = NULL;
9480
9481   if (VAT_JSON_ARRAY != vam->json_tree.type)
9482     {
9483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9484       vat_json_init_array (&vam->json_tree);
9485     }
9486   node = vat_json_array_add (&vam->json_tree);
9487
9488   vat_json_init_object (node);
9489   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9490   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9491 }
9492
9493 static int
9494 api_sw_interface_tap_dump (vat_main_t * vam)
9495 {
9496   vl_api_sw_interface_tap_dump_t *mp;
9497   f64 timeout;
9498
9499   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9500   /* Get list of tap interfaces */
9501   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9502   S;
9503
9504   /* Use a control ping for synchronization */
9505   {
9506     vl_api_control_ping_t *mp;
9507     M (CONTROL_PING, control_ping);
9508     S;
9509   }
9510   W;
9511 }
9512
9513 static uword unformat_vxlan_decap_next
9514   (unformat_input_t * input, va_list * args)
9515 {
9516   u32 *result = va_arg (*args, u32 *);
9517   u32 tmp;
9518
9519   if (unformat (input, "drop"))
9520     *result = VXLAN_INPUT_NEXT_DROP;
9521   else if (unformat (input, "ip4"))
9522     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9523   else if (unformat (input, "ip6"))
9524     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9525   else if (unformat (input, "l2"))
9526     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9527   else if (unformat (input, "%d", &tmp))
9528     *result = tmp;
9529   else
9530     return 0;
9531   return 1;
9532 }
9533
9534 static int
9535 api_vxlan_add_del_tunnel (vat_main_t * vam)
9536 {
9537   unformat_input_t *line_input = vam->input;
9538   vl_api_vxlan_add_del_tunnel_t *mp;
9539   f64 timeout;
9540   ip4_address_t src4, dst4;
9541   ip6_address_t src6, dst6;
9542   u8 is_add = 1;
9543   u8 ipv4_set = 0, ipv6_set = 0;
9544   u8 src_set = 0;
9545   u8 dst_set = 0;
9546   u32 encap_vrf_id = 0;
9547   u32 decap_next_index = ~0;
9548   u32 vni = 0;
9549
9550   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (line_input, "del"))
9553         is_add = 0;
9554       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9555         {
9556           ipv4_set = 1;
9557           src_set = 1;
9558         }
9559       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9560         {
9561           ipv4_set = 1;
9562           dst_set = 1;
9563         }
9564       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9565         {
9566           ipv6_set = 1;
9567           src_set = 1;
9568         }
9569       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9570         {
9571           ipv6_set = 1;
9572           dst_set = 1;
9573         }
9574       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9575         ;
9576       else if (unformat (line_input, "decap-next %U",
9577                          unformat_vxlan_decap_next, &decap_next_index))
9578         ;
9579       else if (unformat (line_input, "vni %d", &vni))
9580         ;
9581       else
9582         {
9583           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9584           return -99;
9585         }
9586     }
9587
9588   if (src_set == 0)
9589     {
9590       errmsg ("tunnel src address not specified\n");
9591       return -99;
9592     }
9593   if (dst_set == 0)
9594     {
9595       errmsg ("tunnel dst address not specified\n");
9596       return -99;
9597     }
9598
9599   if (ipv4_set && ipv6_set)
9600     {
9601       errmsg ("both IPv4 and IPv6 addresses specified");
9602       return -99;
9603     }
9604
9605   if ((vni == 0) || (vni >> 24))
9606     {
9607       errmsg ("vni not specified or out of range\n");
9608       return -99;
9609     }
9610
9611   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9612
9613   if (ipv6_set)
9614     {
9615       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9616       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9617     }
9618   else
9619     {
9620       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9621       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9622     }
9623   mp->encap_vrf_id = ntohl (encap_vrf_id);
9624   mp->decap_next_index = ntohl (decap_next_index);
9625   mp->vni = ntohl (vni);
9626   mp->is_add = is_add;
9627   mp->is_ipv6 = ipv6_set;
9628
9629   S;
9630   W;
9631   /* NOTREACHED */
9632   return 0;
9633 }
9634
9635 static void vl_api_vxlan_tunnel_details_t_handler
9636   (vl_api_vxlan_tunnel_details_t * mp)
9637 {
9638   vat_main_t *vam = &vat_main;
9639
9640   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9641            ntohl (mp->sw_if_index),
9642            format_ip46_address, &(mp->src_address[0]),
9643            IP46_TYPE_ANY,
9644            format_ip46_address, &(mp->dst_address[0]),
9645            IP46_TYPE_ANY,
9646            ntohl (mp->encap_vrf_id),
9647            ntohl (mp->decap_next_index), ntohl (mp->vni));
9648 }
9649
9650 static void vl_api_vxlan_tunnel_details_t_handler_json
9651   (vl_api_vxlan_tunnel_details_t * mp)
9652 {
9653   vat_main_t *vam = &vat_main;
9654   vat_json_node_t *node = NULL;
9655   struct in_addr ip4;
9656   struct in6_addr ip6;
9657
9658   if (VAT_JSON_ARRAY != vam->json_tree.type)
9659     {
9660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9661       vat_json_init_array (&vam->json_tree);
9662     }
9663   node = vat_json_array_add (&vam->json_tree);
9664
9665   vat_json_init_object (node);
9666   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9667   if (mp->is_ipv6)
9668     {
9669       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9670       vat_json_object_add_ip6 (node, "src_address", ip6);
9671       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9672       vat_json_object_add_ip6 (node, "dst_address", ip6);
9673     }
9674   else
9675     {
9676       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9677       vat_json_object_add_ip4 (node, "src_address", ip4);
9678       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9679       vat_json_object_add_ip4 (node, "dst_address", ip4);
9680     }
9681   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9682   vat_json_object_add_uint (node, "decap_next_index",
9683                             ntohl (mp->decap_next_index));
9684   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9685   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9686 }
9687
9688 static int
9689 api_vxlan_tunnel_dump (vat_main_t * vam)
9690 {
9691   unformat_input_t *i = vam->input;
9692   vl_api_vxlan_tunnel_dump_t *mp;
9693   f64 timeout;
9694   u32 sw_if_index;
9695   u8 sw_if_index_set = 0;
9696
9697   /* Parse args required to build the message */
9698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9699     {
9700       if (unformat (i, "sw_if_index %d", &sw_if_index))
9701         sw_if_index_set = 1;
9702       else
9703         break;
9704     }
9705
9706   if (sw_if_index_set == 0)
9707     {
9708       sw_if_index = ~0;
9709     }
9710
9711   if (!vam->json_output)
9712     {
9713       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9714                "sw_if_index", "src_address", "dst_address",
9715                "encap_vrf_id", "decap_next_index", "vni");
9716     }
9717
9718   /* Get list of vxlan-tunnel interfaces */
9719   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9720
9721   mp->sw_if_index = htonl (sw_if_index);
9722
9723   S;
9724
9725   /* Use a control ping for synchronization */
9726   {
9727     vl_api_control_ping_t *mp;
9728     M (CONTROL_PING, control_ping);
9729     S;
9730   }
9731   W;
9732 }
9733
9734 static int
9735 api_gre_add_del_tunnel (vat_main_t * vam)
9736 {
9737   unformat_input_t *line_input = vam->input;
9738   vl_api_gre_add_del_tunnel_t *mp;
9739   f64 timeout;
9740   ip4_address_t src4, dst4;
9741   u8 is_add = 1;
9742   u8 teb = 0;
9743   u8 src_set = 0;
9744   u8 dst_set = 0;
9745   u32 outer_fib_id = 0;
9746
9747   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9748     {
9749       if (unformat (line_input, "del"))
9750         is_add = 0;
9751       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9752         src_set = 1;
9753       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9754         dst_set = 1;
9755       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9756         ;
9757       else if (unformat (line_input, "teb"))
9758         teb = 1;
9759       else
9760         {
9761           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9762           return -99;
9763         }
9764     }
9765
9766   if (src_set == 0)
9767     {
9768       errmsg ("tunnel src address not specified\n");
9769       return -99;
9770     }
9771   if (dst_set == 0)
9772     {
9773       errmsg ("tunnel dst address not specified\n");
9774       return -99;
9775     }
9776
9777
9778   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9779
9780   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9781   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9782   mp->outer_fib_id = ntohl (outer_fib_id);
9783   mp->is_add = is_add;
9784   mp->teb = teb;
9785
9786   S;
9787   W;
9788   /* NOTREACHED */
9789   return 0;
9790 }
9791
9792 static void vl_api_gre_tunnel_details_t_handler
9793   (vl_api_gre_tunnel_details_t * mp)
9794 {
9795   vat_main_t *vam = &vat_main;
9796
9797   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9798            ntohl (mp->sw_if_index),
9799            format_ip4_address, &mp->src_address,
9800            format_ip4_address, &mp->dst_address,
9801            mp->teb, ntohl (mp->outer_fib_id));
9802 }
9803
9804 static void vl_api_gre_tunnel_details_t_handler_json
9805   (vl_api_gre_tunnel_details_t * mp)
9806 {
9807   vat_main_t *vam = &vat_main;
9808   vat_json_node_t *node = NULL;
9809   struct in_addr ip4;
9810
9811   if (VAT_JSON_ARRAY != vam->json_tree.type)
9812     {
9813       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9814       vat_json_init_array (&vam->json_tree);
9815     }
9816   node = vat_json_array_add (&vam->json_tree);
9817
9818   vat_json_init_object (node);
9819   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9820   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9821   vat_json_object_add_ip4 (node, "src_address", ip4);
9822   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9823   vat_json_object_add_ip4 (node, "dst_address", ip4);
9824   vat_json_object_add_uint (node, "teb", mp->teb);
9825   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9826 }
9827
9828 static int
9829 api_gre_tunnel_dump (vat_main_t * vam)
9830 {
9831   unformat_input_t *i = vam->input;
9832   vl_api_gre_tunnel_dump_t *mp;
9833   f64 timeout;
9834   u32 sw_if_index;
9835   u8 sw_if_index_set = 0;
9836
9837   /* Parse args required to build the message */
9838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9839     {
9840       if (unformat (i, "sw_if_index %d", &sw_if_index))
9841         sw_if_index_set = 1;
9842       else
9843         break;
9844     }
9845
9846   if (sw_if_index_set == 0)
9847     {
9848       sw_if_index = ~0;
9849     }
9850
9851   if (!vam->json_output)
9852     {
9853       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9854                "sw_if_index", "src_address", "dst_address", "teb",
9855                "outer_fib_id");
9856     }
9857
9858   /* Get list of gre-tunnel interfaces */
9859   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9860
9861   mp->sw_if_index = htonl (sw_if_index);
9862
9863   S;
9864
9865   /* Use a control ping for synchronization */
9866   {
9867     vl_api_control_ping_t *mp;
9868     M (CONTROL_PING, control_ping);
9869     S;
9870   }
9871   W;
9872 }
9873
9874 static int
9875 api_l2_fib_clear_table (vat_main_t * vam)
9876 {
9877 //  unformat_input_t * i = vam->input;
9878   vl_api_l2_fib_clear_table_t *mp;
9879   f64 timeout;
9880
9881   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9882
9883   S;
9884   W;
9885   /* NOTREACHED */
9886   return 0;
9887 }
9888
9889 static int
9890 api_l2_interface_efp_filter (vat_main_t * vam)
9891 {
9892   unformat_input_t *i = vam->input;
9893   vl_api_l2_interface_efp_filter_t *mp;
9894   f64 timeout;
9895   u32 sw_if_index;
9896   u8 enable = 1;
9897   u8 sw_if_index_set = 0;
9898
9899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9900     {
9901       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9904         sw_if_index_set = 1;
9905       else if (unformat (i, "enable"))
9906         enable = 1;
9907       else if (unformat (i, "disable"))
9908         enable = 0;
9909       else
9910         {
9911           clib_warning ("parse error '%U'", format_unformat_error, i);
9912           return -99;
9913         }
9914     }
9915
9916   if (sw_if_index_set == 0)
9917     {
9918       errmsg ("missing sw_if_index\n");
9919       return -99;
9920     }
9921
9922   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9923
9924   mp->sw_if_index = ntohl (sw_if_index);
9925   mp->enable_disable = enable;
9926
9927   S;
9928   W;
9929   /* NOTREACHED */
9930   return 0;
9931 }
9932
9933 #define foreach_vtr_op                          \
9934 _("disable",  L2_VTR_DISABLED)                  \
9935 _("push-1",  L2_VTR_PUSH_1)                     \
9936 _("push-2",  L2_VTR_PUSH_2)                     \
9937 _("pop-1",  L2_VTR_POP_1)                       \
9938 _("pop-2",  L2_VTR_POP_2)                       \
9939 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9940 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9941 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9942 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9943
9944 static int
9945 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9946 {
9947   unformat_input_t *i = vam->input;
9948   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9949   f64 timeout;
9950   u32 sw_if_index;
9951   u8 sw_if_index_set = 0;
9952   u8 vtr_op_set = 0;
9953   u32 vtr_op = 0;
9954   u32 push_dot1q = 1;
9955   u32 tag1 = ~0;
9956   u32 tag2 = ~0;
9957
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9961         sw_if_index_set = 1;
9962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9963         sw_if_index_set = 1;
9964       else if (unformat (i, "vtr_op %d", &vtr_op))
9965         vtr_op_set = 1;
9966 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9967       foreach_vtr_op
9968 #undef _
9969         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9970         ;
9971       else if (unformat (i, "tag1 %d", &tag1))
9972         ;
9973       else if (unformat (i, "tag2 %d", &tag2))
9974         ;
9975       else
9976         {
9977           clib_warning ("parse error '%U'", format_unformat_error, i);
9978           return -99;
9979         }
9980     }
9981
9982   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9983     {
9984       errmsg ("missing vtr operation or sw_if_index\n");
9985       return -99;
9986     }
9987
9988   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9989     mp->sw_if_index = ntohl (sw_if_index);
9990   mp->vtr_op = ntohl (vtr_op);
9991   mp->push_dot1q = ntohl (push_dot1q);
9992   mp->tag1 = ntohl (tag1);
9993   mp->tag2 = ntohl (tag2);
9994
9995   S;
9996   W;
9997   /* NOTREACHED */
9998   return 0;
9999 }
10000
10001 static int
10002 api_create_vhost_user_if (vat_main_t * vam)
10003 {
10004   unformat_input_t *i = vam->input;
10005   vl_api_create_vhost_user_if_t *mp;
10006   f64 timeout;
10007   u8 *file_name;
10008   u8 is_server = 0;
10009   u8 file_name_set = 0;
10010   u32 custom_dev_instance = ~0;
10011   u8 hwaddr[6];
10012   u8 use_custom_mac = 0;
10013
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "socket %s", &file_name))
10017         {
10018           file_name_set = 1;
10019         }
10020       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10021         ;
10022       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10023         use_custom_mac = 1;
10024       else if (unformat (i, "server"))
10025         is_server = 1;
10026       else
10027         break;
10028     }
10029
10030   if (file_name_set == 0)
10031     {
10032       errmsg ("missing socket file name\n");
10033       return -99;
10034     }
10035
10036   if (vec_len (file_name) > 255)
10037     {
10038       errmsg ("socket file name too long\n");
10039       return -99;
10040     }
10041   vec_add1 (file_name, 0);
10042
10043   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10044
10045   mp->is_server = is_server;
10046   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10047   vec_free (file_name);
10048   if (custom_dev_instance != ~0)
10049     {
10050       mp->renumber = 1;
10051       mp->custom_dev_instance = ntohl (custom_dev_instance);
10052     }
10053   mp->use_custom_mac = use_custom_mac;
10054   clib_memcpy (mp->mac_address, hwaddr, 6);
10055
10056   S;
10057   W;
10058   /* NOTREACHED */
10059   return 0;
10060 }
10061
10062 static int
10063 api_modify_vhost_user_if (vat_main_t * vam)
10064 {
10065   unformat_input_t *i = vam->input;
10066   vl_api_modify_vhost_user_if_t *mp;
10067   f64 timeout;
10068   u8 *file_name;
10069   u8 is_server = 0;
10070   u8 file_name_set = 0;
10071   u32 custom_dev_instance = ~0;
10072   u8 sw_if_index_set = 0;
10073   u32 sw_if_index = (u32) ~ 0;
10074
10075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10076     {
10077       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10078         sw_if_index_set = 1;
10079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10080         sw_if_index_set = 1;
10081       else if (unformat (i, "socket %s", &file_name))
10082         {
10083           file_name_set = 1;
10084         }
10085       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10086         ;
10087       else if (unformat (i, "server"))
10088         is_server = 1;
10089       else
10090         break;
10091     }
10092
10093   if (sw_if_index_set == 0)
10094     {
10095       errmsg ("missing sw_if_index or interface name\n");
10096       return -99;
10097     }
10098
10099   if (file_name_set == 0)
10100     {
10101       errmsg ("missing socket file name\n");
10102       return -99;
10103     }
10104
10105   if (vec_len (file_name) > 255)
10106     {
10107       errmsg ("socket file name too long\n");
10108       return -99;
10109     }
10110   vec_add1 (file_name, 0);
10111
10112   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10113
10114   mp->sw_if_index = ntohl (sw_if_index);
10115   mp->is_server = is_server;
10116   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10117   vec_free (file_name);
10118   if (custom_dev_instance != ~0)
10119     {
10120       mp->renumber = 1;
10121       mp->custom_dev_instance = ntohl (custom_dev_instance);
10122     }
10123
10124   S;
10125   W;
10126   /* NOTREACHED */
10127   return 0;
10128 }
10129
10130 static int
10131 api_delete_vhost_user_if (vat_main_t * vam)
10132 {
10133   unformat_input_t *i = vam->input;
10134   vl_api_delete_vhost_user_if_t *mp;
10135   f64 timeout;
10136   u32 sw_if_index = ~0;
10137   u8 sw_if_index_set = 0;
10138
10139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10140     {
10141       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10142         sw_if_index_set = 1;
10143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10144         sw_if_index_set = 1;
10145       else
10146         break;
10147     }
10148
10149   if (sw_if_index_set == 0)
10150     {
10151       errmsg ("missing sw_if_index or interface name\n");
10152       return -99;
10153     }
10154
10155
10156   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10157
10158   mp->sw_if_index = ntohl (sw_if_index);
10159
10160   S;
10161   W;
10162   /* NOTREACHED */
10163   return 0;
10164 }
10165
10166 static void vl_api_sw_interface_vhost_user_details_t_handler
10167   (vl_api_sw_interface_vhost_user_details_t * mp)
10168 {
10169   vat_main_t *vam = &vat_main;
10170
10171   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10172            (char *) mp->interface_name,
10173            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10174            clib_net_to_host_u64 (mp->features), mp->is_server,
10175            ntohl (mp->num_regions), (char *) mp->sock_filename);
10176   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10177 }
10178
10179 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10180   (vl_api_sw_interface_vhost_user_details_t * mp)
10181 {
10182   vat_main_t *vam = &vat_main;
10183   vat_json_node_t *node = NULL;
10184
10185   if (VAT_JSON_ARRAY != vam->json_tree.type)
10186     {
10187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10188       vat_json_init_array (&vam->json_tree);
10189     }
10190   node = vat_json_array_add (&vam->json_tree);
10191
10192   vat_json_init_object (node);
10193   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10194   vat_json_object_add_string_copy (node, "interface_name",
10195                                    mp->interface_name);
10196   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10197                             ntohl (mp->virtio_net_hdr_sz));
10198   vat_json_object_add_uint (node, "features",
10199                             clib_net_to_host_u64 (mp->features));
10200   vat_json_object_add_uint (node, "is_server", mp->is_server);
10201   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10202   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10203   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10204 }
10205
10206 static int
10207 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10208 {
10209   vl_api_sw_interface_vhost_user_dump_t *mp;
10210   f64 timeout;
10211   fformat (vam->ofp,
10212            "Interface name           idx hdr_sz features server regions filename\n");
10213
10214   /* Get list of vhost-user interfaces */
10215   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10216   S;
10217
10218   /* Use a control ping for synchronization */
10219   {
10220     vl_api_control_ping_t *mp;
10221     M (CONTROL_PING, control_ping);
10222     S;
10223   }
10224   W;
10225 }
10226
10227 static int
10228 api_show_version (vat_main_t * vam)
10229 {
10230   vl_api_show_version_t *mp;
10231   f64 timeout;
10232
10233   M (SHOW_VERSION, show_version);
10234
10235   S;
10236   W;
10237   /* NOTREACHED */
10238   return 0;
10239 }
10240
10241
10242 static int
10243 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10244 {
10245   unformat_input_t *line_input = vam->input;
10246   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10247   f64 timeout;
10248   ip4_address_t local4, remote4;
10249   ip6_address_t local6, remote6;
10250   u8 is_add = 1;
10251   u8 ipv4_set = 0, ipv6_set = 0;
10252   u8 local_set = 0;
10253   u8 remote_set = 0;
10254   u32 encap_vrf_id = 0;
10255   u32 decap_vrf_id = 0;
10256   u8 protocol = ~0;
10257   u32 vni;
10258   u8 vni_set = 0;
10259
10260   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10261     {
10262       if (unformat (line_input, "del"))
10263         is_add = 0;
10264       else if (unformat (line_input, "local %U",
10265                          unformat_ip4_address, &local4))
10266         {
10267           local_set = 1;
10268           ipv4_set = 1;
10269         }
10270       else if (unformat (line_input, "remote %U",
10271                          unformat_ip4_address, &remote4))
10272         {
10273           remote_set = 1;
10274           ipv4_set = 1;
10275         }
10276       else if (unformat (line_input, "local %U",
10277                          unformat_ip6_address, &local6))
10278         {
10279           local_set = 1;
10280           ipv6_set = 1;
10281         }
10282       else if (unformat (line_input, "remote %U",
10283                          unformat_ip6_address, &remote6))
10284         {
10285           remote_set = 1;
10286           ipv6_set = 1;
10287         }
10288       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10289         ;
10290       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10291         ;
10292       else if (unformat (line_input, "vni %d", &vni))
10293         vni_set = 1;
10294       else if (unformat (line_input, "next-ip4"))
10295         protocol = 1;
10296       else if (unformat (line_input, "next-ip6"))
10297         protocol = 2;
10298       else if (unformat (line_input, "next-ethernet"))
10299         protocol = 3;
10300       else if (unformat (line_input, "next-nsh"))
10301         protocol = 4;
10302       else
10303         {
10304           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10305           return -99;
10306         }
10307     }
10308
10309   if (local_set == 0)
10310     {
10311       errmsg ("tunnel local address not specified\n");
10312       return -99;
10313     }
10314   if (remote_set == 0)
10315     {
10316       errmsg ("tunnel remote address not specified\n");
10317       return -99;
10318     }
10319   if (ipv4_set && ipv6_set)
10320     {
10321       errmsg ("both IPv4 and IPv6 addresses specified");
10322       return -99;
10323     }
10324
10325   if (vni_set == 0)
10326     {
10327       errmsg ("vni not specified\n");
10328       return -99;
10329     }
10330
10331   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10332
10333
10334   if (ipv6_set)
10335     {
10336       clib_memcpy (&mp->local, &local6, sizeof (local6));
10337       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10338     }
10339   else
10340     {
10341       clib_memcpy (&mp->local, &local4, sizeof (local4));
10342       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10343     }
10344
10345   mp->encap_vrf_id = ntohl (encap_vrf_id);
10346   mp->decap_vrf_id = ntohl (decap_vrf_id);
10347   mp->protocol = ntohl (protocol);
10348   mp->vni = ntohl (vni);
10349   mp->is_add = is_add;
10350   mp->is_ipv6 = ipv6_set;
10351
10352   S;
10353   W;
10354   /* NOTREACHED */
10355   return 0;
10356 }
10357
10358 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10359   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10360 {
10361   vat_main_t *vam = &vat_main;
10362
10363   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10364            ntohl (mp->sw_if_index),
10365            format_ip46_address, &(mp->local[0]),
10366            format_ip46_address, &(mp->remote[0]),
10367            ntohl (mp->vni),
10368            ntohl (mp->protocol),
10369            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10370 }
10371
10372 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10373   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10374 {
10375   vat_main_t *vam = &vat_main;
10376   vat_json_node_t *node = NULL;
10377   struct in_addr ip4;
10378   struct in6_addr ip6;
10379
10380   if (VAT_JSON_ARRAY != vam->json_tree.type)
10381     {
10382       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10383       vat_json_init_array (&vam->json_tree);
10384     }
10385   node = vat_json_array_add (&vam->json_tree);
10386
10387   vat_json_init_object (node);
10388   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10389   if (mp->is_ipv6)
10390     {
10391       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10392       vat_json_object_add_ip6 (node, "local", ip6);
10393       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10394       vat_json_object_add_ip6 (node, "remote", ip6);
10395     }
10396   else
10397     {
10398       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10399       vat_json_object_add_ip4 (node, "local", ip4);
10400       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10401       vat_json_object_add_ip4 (node, "remote", ip4);
10402     }
10403   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10404   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10405   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10406   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10407   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10408 }
10409
10410 static int
10411 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10412 {
10413   unformat_input_t *i = vam->input;
10414   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10415   f64 timeout;
10416   u32 sw_if_index;
10417   u8 sw_if_index_set = 0;
10418
10419   /* Parse args required to build the message */
10420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10421     {
10422       if (unformat (i, "sw_if_index %d", &sw_if_index))
10423         sw_if_index_set = 1;
10424       else
10425         break;
10426     }
10427
10428   if (sw_if_index_set == 0)
10429     {
10430       sw_if_index = ~0;
10431     }
10432
10433   if (!vam->json_output)
10434     {
10435       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10436                "sw_if_index", "local", "remote", "vni",
10437                "protocol", "encap_vrf_id", "decap_vrf_id");
10438     }
10439
10440   /* Get list of vxlan-tunnel interfaces */
10441   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10442
10443   mp->sw_if_index = htonl (sw_if_index);
10444
10445   S;
10446
10447   /* Use a control ping for synchronization */
10448   {
10449     vl_api_control_ping_t *mp;
10450     M (CONTROL_PING, control_ping);
10451     S;
10452   }
10453   W;
10454 }
10455
10456 u8 *
10457 format_l2_fib_mac_address (u8 * s, va_list * args)
10458 {
10459   u8 *a = va_arg (*args, u8 *);
10460
10461   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10462                  a[2], a[3], a[4], a[5], a[6], a[7]);
10463 }
10464
10465 static void vl_api_l2_fib_table_entry_t_handler
10466   (vl_api_l2_fib_table_entry_t * mp)
10467 {
10468   vat_main_t *vam = &vat_main;
10469
10470   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10471            "       %d       %d     %d\n",
10472            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10473            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10474            mp->bvi_mac);
10475 }
10476
10477 static void vl_api_l2_fib_table_entry_t_handler_json
10478   (vl_api_l2_fib_table_entry_t * mp)
10479 {
10480   vat_main_t *vam = &vat_main;
10481   vat_json_node_t *node = NULL;
10482
10483   if (VAT_JSON_ARRAY != vam->json_tree.type)
10484     {
10485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10486       vat_json_init_array (&vam->json_tree);
10487     }
10488   node = vat_json_array_add (&vam->json_tree);
10489
10490   vat_json_init_object (node);
10491   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10492   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10493   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10494   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10495   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10496   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10497 }
10498
10499 static int
10500 api_l2_fib_table_dump (vat_main_t * vam)
10501 {
10502   unformat_input_t *i = vam->input;
10503   vl_api_l2_fib_table_dump_t *mp;
10504   f64 timeout;
10505   u32 bd_id;
10506   u8 bd_id_set = 0;
10507
10508   /* Parse args required to build the message */
10509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10510     {
10511       if (unformat (i, "bd_id %d", &bd_id))
10512         bd_id_set = 1;
10513       else
10514         break;
10515     }
10516
10517   if (bd_id_set == 0)
10518     {
10519       errmsg ("missing bridge domain\n");
10520       return -99;
10521     }
10522
10523   fformat (vam->ofp,
10524            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10525
10526   /* Get list of l2 fib entries */
10527   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10528
10529   mp->bd_id = ntohl (bd_id);
10530   S;
10531
10532   /* Use a control ping for synchronization */
10533   {
10534     vl_api_control_ping_t *mp;
10535     M (CONTROL_PING, control_ping);
10536     S;
10537   }
10538   W;
10539 }
10540
10541
10542 static int
10543 api_interface_name_renumber (vat_main_t * vam)
10544 {
10545   unformat_input_t *line_input = vam->input;
10546   vl_api_interface_name_renumber_t *mp;
10547   u32 sw_if_index = ~0;
10548   f64 timeout;
10549   u32 new_show_dev_instance = ~0;
10550
10551   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10552     {
10553       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10554                     &sw_if_index))
10555         ;
10556       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10557         ;
10558       else if (unformat (line_input, "new_show_dev_instance %d",
10559                          &new_show_dev_instance))
10560         ;
10561       else
10562         break;
10563     }
10564
10565   if (sw_if_index == ~0)
10566     {
10567       errmsg ("missing interface name or sw_if_index\n");
10568       return -99;
10569     }
10570
10571   if (new_show_dev_instance == ~0)
10572     {
10573       errmsg ("missing new_show_dev_instance\n");
10574       return -99;
10575     }
10576
10577   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10578
10579   mp->sw_if_index = ntohl (sw_if_index);
10580   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10581
10582   S;
10583   W;
10584 }
10585
10586 static int
10587 api_want_ip4_arp_events (vat_main_t * vam)
10588 {
10589   unformat_input_t *line_input = vam->input;
10590   vl_api_want_ip4_arp_events_t *mp;
10591   f64 timeout;
10592   ip4_address_t address;
10593   int address_set = 0;
10594   u32 enable_disable = 1;
10595
10596   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10597     {
10598       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10599         address_set = 1;
10600       else if (unformat (line_input, "del"))
10601         enable_disable = 0;
10602       else
10603         break;
10604     }
10605
10606   if (address_set == 0)
10607     {
10608       errmsg ("missing addresses\n");
10609       return -99;
10610     }
10611
10612   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10613   mp->enable_disable = enable_disable;
10614   mp->pid = getpid ();
10615   mp->address = address.as_u32;
10616
10617   S;
10618   W;
10619 }
10620
10621 static int
10622 api_want_ip6_nd_events (vat_main_t * vam)
10623 {
10624   unformat_input_t *line_input = vam->input;
10625   vl_api_want_ip6_nd_events_t *mp;
10626   f64 timeout;
10627   ip6_address_t address;
10628   int address_set = 0;
10629   u32 enable_disable = 1;
10630
10631   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10634         address_set = 1;
10635       else if (unformat (line_input, "del"))
10636         enable_disable = 0;
10637       else
10638         break;
10639     }
10640
10641   if (address_set == 0)
10642     {
10643       errmsg ("missing addresses\n");
10644       return -99;
10645     }
10646
10647   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10648   mp->enable_disable = enable_disable;
10649   mp->pid = getpid ();
10650   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10651
10652   S;
10653   W;
10654 }
10655
10656 static int
10657 api_input_acl_set_interface (vat_main_t * vam)
10658 {
10659   unformat_input_t *i = vam->input;
10660   vl_api_input_acl_set_interface_t *mp;
10661   f64 timeout;
10662   u32 sw_if_index;
10663   int sw_if_index_set;
10664   u32 ip4_table_index = ~0;
10665   u32 ip6_table_index = ~0;
10666   u32 l2_table_index = ~0;
10667   u8 is_add = 1;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10672         sw_if_index_set = 1;
10673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10674         sw_if_index_set = 1;
10675       else if (unformat (i, "del"))
10676         is_add = 0;
10677       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10678         ;
10679       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10680         ;
10681       else if (unformat (i, "l2-table %d", &l2_table_index))
10682         ;
10683       else
10684         {
10685           clib_warning ("parse error '%U'", format_unformat_error, i);
10686           return -99;
10687         }
10688     }
10689
10690   if (sw_if_index_set == 0)
10691     {
10692       errmsg ("missing interface name or sw_if_index\n");
10693       return -99;
10694     }
10695
10696   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10697
10698   mp->sw_if_index = ntohl (sw_if_index);
10699   mp->ip4_table_index = ntohl (ip4_table_index);
10700   mp->ip6_table_index = ntohl (ip6_table_index);
10701   mp->l2_table_index = ntohl (l2_table_index);
10702   mp->is_add = is_add;
10703
10704   S;
10705   W;
10706   /* NOTREACHED */
10707   return 0;
10708 }
10709
10710 static int
10711 api_ip_address_dump (vat_main_t * vam)
10712 {
10713   unformat_input_t *i = vam->input;
10714   vl_api_ip_address_dump_t *mp;
10715   u32 sw_if_index = ~0;
10716   u8 sw_if_index_set = 0;
10717   u8 ipv4_set = 0;
10718   u8 ipv6_set = 0;
10719   f64 timeout;
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "sw_if_index %d", &sw_if_index))
10724         sw_if_index_set = 1;
10725       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10726         sw_if_index_set = 1;
10727       else if (unformat (i, "ipv4"))
10728         ipv4_set = 1;
10729       else if (unformat (i, "ipv6"))
10730         ipv6_set = 1;
10731       else
10732         break;
10733     }
10734
10735   if (ipv4_set && ipv6_set)
10736     {
10737       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10738       return -99;
10739     }
10740
10741   if ((!ipv4_set) && (!ipv6_set))
10742     {
10743       errmsg ("no ipv4 nor ipv6 flag set\n");
10744       return -99;
10745     }
10746
10747   if (sw_if_index_set == 0)
10748     {
10749       errmsg ("missing interface name or sw_if_index\n");
10750       return -99;
10751     }
10752
10753   vam->current_sw_if_index = sw_if_index;
10754   vam->is_ipv6 = ipv6_set;
10755
10756   M (IP_ADDRESS_DUMP, ip_address_dump);
10757   mp->sw_if_index = ntohl (sw_if_index);
10758   mp->is_ipv6 = ipv6_set;
10759   S;
10760
10761   /* Use a control ping for synchronization */
10762   {
10763     vl_api_control_ping_t *mp;
10764     M (CONTROL_PING, control_ping);
10765     S;
10766   }
10767   W;
10768 }
10769
10770 static int
10771 api_ip_dump (vat_main_t * vam)
10772 {
10773   vl_api_ip_dump_t *mp;
10774   unformat_input_t *in = vam->input;
10775   int ipv4_set = 0;
10776   int ipv6_set = 0;
10777   int is_ipv6;
10778   f64 timeout;
10779   int i;
10780
10781   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10782     {
10783       if (unformat (in, "ipv4"))
10784         ipv4_set = 1;
10785       else if (unformat (in, "ipv6"))
10786         ipv6_set = 1;
10787       else
10788         break;
10789     }
10790
10791   if (ipv4_set && ipv6_set)
10792     {
10793       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10794       return -99;
10795     }
10796
10797   if ((!ipv4_set) && (!ipv6_set))
10798     {
10799       errmsg ("no ipv4 nor ipv6 flag set\n");
10800       return -99;
10801     }
10802
10803   is_ipv6 = ipv6_set;
10804   vam->is_ipv6 = is_ipv6;
10805
10806   /* free old data */
10807   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10808     {
10809       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10810     }
10811   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10812
10813   M (IP_DUMP, ip_dump);
10814   mp->is_ipv6 = ipv6_set;
10815   S;
10816
10817   /* Use a control ping for synchronization */
10818   {
10819     vl_api_control_ping_t *mp;
10820     M (CONTROL_PING, control_ping);
10821     S;
10822   }
10823   W;
10824 }
10825
10826 static int
10827 api_ipsec_spd_add_del (vat_main_t * vam)
10828 {
10829 #if DPDK > 0
10830   unformat_input_t *i = vam->input;
10831   vl_api_ipsec_spd_add_del_t *mp;
10832   f64 timeout;
10833   u32 spd_id = ~0;
10834   u8 is_add = 1;
10835
10836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (unformat (i, "spd_id %d", &spd_id))
10839         ;
10840       else if (unformat (i, "del"))
10841         is_add = 0;
10842       else
10843         {
10844           clib_warning ("parse error '%U'", format_unformat_error, i);
10845           return -99;
10846         }
10847     }
10848   if (spd_id == ~0)
10849     {
10850       errmsg ("spd_id must be set\n");
10851       return -99;
10852     }
10853
10854   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10855
10856   mp->spd_id = ntohl (spd_id);
10857   mp->is_add = is_add;
10858
10859   S;
10860   W;
10861   /* NOTREACHED */
10862   return 0;
10863 #else
10864   clib_warning ("unsupported (no dpdk)");
10865   return -99;
10866 #endif
10867 }
10868
10869 static int
10870 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10871 {
10872 #if DPDK > 0
10873   unformat_input_t *i = vam->input;
10874   vl_api_ipsec_interface_add_del_spd_t *mp;
10875   f64 timeout;
10876   u32 sw_if_index;
10877   u8 sw_if_index_set = 0;
10878   u32 spd_id = (u32) ~ 0;
10879   u8 is_add = 1;
10880
10881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10882     {
10883       if (unformat (i, "del"))
10884         is_add = 0;
10885       else if (unformat (i, "spd_id %d", &spd_id))
10886         ;
10887       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10888         sw_if_index_set = 1;
10889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10890         sw_if_index_set = 1;
10891       else
10892         {
10893           clib_warning ("parse error '%U'", format_unformat_error, i);
10894           return -99;
10895         }
10896
10897     }
10898
10899   if (spd_id == (u32) ~ 0)
10900     {
10901       errmsg ("spd_id must be set\n");
10902       return -99;
10903     }
10904
10905   if (sw_if_index_set == 0)
10906     {
10907       errmsg ("missing interface name or sw_if_index\n");
10908       return -99;
10909     }
10910
10911   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10912
10913   mp->spd_id = ntohl (spd_id);
10914   mp->sw_if_index = ntohl (sw_if_index);
10915   mp->is_add = is_add;
10916
10917   S;
10918   W;
10919   /* NOTREACHED */
10920   return 0;
10921 #else
10922   clib_warning ("unsupported (no dpdk)");
10923   return -99;
10924 #endif
10925 }
10926
10927 static int
10928 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10929 {
10930 #if DPDK > 0
10931   unformat_input_t *i = vam->input;
10932   vl_api_ipsec_spd_add_del_entry_t *mp;
10933   f64 timeout;
10934   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10935   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10936   i32 priority = 0;
10937   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10938   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10939   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10940   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10941
10942   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10943   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10944   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10945   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10946   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10947   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10948
10949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10950     {
10951       if (unformat (i, "del"))
10952         is_add = 0;
10953       if (unformat (i, "outbound"))
10954         is_outbound = 1;
10955       if (unformat (i, "inbound"))
10956         is_outbound = 0;
10957       else if (unformat (i, "spd_id %d", &spd_id))
10958         ;
10959       else if (unformat (i, "sa_id %d", &sa_id))
10960         ;
10961       else if (unformat (i, "priority %d", &priority))
10962         ;
10963       else if (unformat (i, "protocol %d", &protocol))
10964         ;
10965       else if (unformat (i, "lport_start %d", &lport_start))
10966         ;
10967       else if (unformat (i, "lport_stop %d", &lport_stop))
10968         ;
10969       else if (unformat (i, "rport_start %d", &rport_start))
10970         ;
10971       else if (unformat (i, "rport_stop %d", &rport_stop))
10972         ;
10973       else
10974         if (unformat
10975             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10976         {
10977           is_ipv6 = 0;
10978           is_ip_any = 0;
10979         }
10980       else
10981         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10982         {
10983           is_ipv6 = 0;
10984           is_ip_any = 0;
10985         }
10986       else
10987         if (unformat
10988             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10989         {
10990           is_ipv6 = 0;
10991           is_ip_any = 0;
10992         }
10993       else
10994         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10995         {
10996           is_ipv6 = 0;
10997           is_ip_any = 0;
10998         }
10999       else
11000         if (unformat
11001             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11002         {
11003           is_ipv6 = 1;
11004           is_ip_any = 0;
11005         }
11006       else
11007         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11008         {
11009           is_ipv6 = 1;
11010           is_ip_any = 0;
11011         }
11012       else
11013         if (unformat
11014             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11015         {
11016           is_ipv6 = 1;
11017           is_ip_any = 0;
11018         }
11019       else
11020         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11021         {
11022           is_ipv6 = 1;
11023           is_ip_any = 0;
11024         }
11025       else
11026         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11027         {
11028           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11029             {
11030               clib_warning ("unsupported action: 'resolve'");
11031               return -99;
11032             }
11033         }
11034       else
11035         {
11036           clib_warning ("parse error '%U'", format_unformat_error, i);
11037           return -99;
11038         }
11039
11040     }
11041
11042   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11043
11044   mp->spd_id = ntohl (spd_id);
11045   mp->priority = ntohl (priority);
11046   mp->is_outbound = is_outbound;
11047
11048   mp->is_ipv6 = is_ipv6;
11049   if (is_ipv6 || is_ip_any)
11050     {
11051       clib_memcpy (mp->remote_address_start, &raddr6_start,
11052                    sizeof (ip6_address_t));
11053       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11054                    sizeof (ip6_address_t));
11055       clib_memcpy (mp->local_address_start, &laddr6_start,
11056                    sizeof (ip6_address_t));
11057       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11058                    sizeof (ip6_address_t));
11059     }
11060   else
11061     {
11062       clib_memcpy (mp->remote_address_start, &raddr4_start,
11063                    sizeof (ip4_address_t));
11064       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11065                    sizeof (ip4_address_t));
11066       clib_memcpy (mp->local_address_start, &laddr4_start,
11067                    sizeof (ip4_address_t));
11068       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11069                    sizeof (ip4_address_t));
11070     }
11071   mp->protocol = (u8) protocol;
11072   mp->local_port_start = ntohs ((u16) lport_start);
11073   mp->local_port_stop = ntohs ((u16) lport_stop);
11074   mp->remote_port_start = ntohs ((u16) rport_start);
11075   mp->remote_port_stop = ntohs ((u16) rport_stop);
11076   mp->policy = (u8) policy;
11077   mp->sa_id = ntohl (sa_id);
11078   mp->is_add = is_add;
11079   mp->is_ip_any = is_ip_any;
11080   S;
11081   W;
11082   /* NOTREACHED */
11083   return 0;
11084 #else
11085   clib_warning ("unsupported (no dpdk)");
11086   return -99;
11087 #endif
11088 }
11089
11090 static int
11091 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11092 {
11093 #if DPDK > 0
11094   unformat_input_t *i = vam->input;
11095   vl_api_ipsec_sad_add_del_entry_t *mp;
11096   f64 timeout;
11097   u32 sad_id = 0, spi = 0;
11098   u8 *ck = 0, *ik = 0;
11099   u8 is_add = 1;
11100
11101   u8 protocol = IPSEC_PROTOCOL_AH;
11102   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11103   u32 crypto_alg = 0, integ_alg = 0;
11104   ip4_address_t tun_src4;
11105   ip4_address_t tun_dst4;
11106   ip6_address_t tun_src6;
11107   ip6_address_t tun_dst6;
11108
11109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11110     {
11111       if (unformat (i, "del"))
11112         is_add = 0;
11113       else if (unformat (i, "sad_id %d", &sad_id))
11114         ;
11115       else if (unformat (i, "spi %d", &spi))
11116         ;
11117       else if (unformat (i, "esp"))
11118         protocol = IPSEC_PROTOCOL_ESP;
11119       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11120         {
11121           is_tunnel = 1;
11122           is_tunnel_ipv6 = 0;
11123         }
11124       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11125         {
11126           is_tunnel = 1;
11127           is_tunnel_ipv6 = 0;
11128         }
11129       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11130         {
11131           is_tunnel = 1;
11132           is_tunnel_ipv6 = 1;
11133         }
11134       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11135         {
11136           is_tunnel = 1;
11137           is_tunnel_ipv6 = 1;
11138         }
11139       else
11140         if (unformat
11141             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11142         {
11143           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11144               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11145             {
11146               clib_warning ("unsupported crypto-alg: '%U'",
11147                             format_ipsec_crypto_alg, crypto_alg);
11148               return -99;
11149             }
11150         }
11151       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11152         ;
11153       else
11154         if (unformat
11155             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11156         {
11157           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11158               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11159             {
11160               clib_warning ("unsupported integ-alg: '%U'",
11161                             format_ipsec_integ_alg, integ_alg);
11162               return -99;
11163             }
11164         }
11165       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11166         ;
11167       else
11168         {
11169           clib_warning ("parse error '%U'", format_unformat_error, i);
11170           return -99;
11171         }
11172
11173     }
11174
11175   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11176
11177   mp->sad_id = ntohl (sad_id);
11178   mp->is_add = is_add;
11179   mp->protocol = protocol;
11180   mp->spi = ntohl (spi);
11181   mp->is_tunnel = is_tunnel;
11182   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11183   mp->crypto_algorithm = crypto_alg;
11184   mp->integrity_algorithm = integ_alg;
11185   mp->crypto_key_length = vec_len (ck);
11186   mp->integrity_key_length = vec_len (ik);
11187
11188   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11189     mp->crypto_key_length = sizeof (mp->crypto_key);
11190
11191   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11192     mp->integrity_key_length = sizeof (mp->integrity_key);
11193
11194   if (ck)
11195     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11196   if (ik)
11197     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11198
11199   if (is_tunnel)
11200     {
11201       if (is_tunnel_ipv6)
11202         {
11203           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11204                        sizeof (ip6_address_t));
11205           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11206                        sizeof (ip6_address_t));
11207         }
11208       else
11209         {
11210           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11211                        sizeof (ip4_address_t));
11212           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11213                        sizeof (ip4_address_t));
11214         }
11215     }
11216
11217   S;
11218   W;
11219   /* NOTREACHED */
11220   return 0;
11221 #else
11222   clib_warning ("unsupported (no dpdk)");
11223   return -99;
11224 #endif
11225 }
11226
11227 static int
11228 api_ipsec_sa_set_key (vat_main_t * vam)
11229 {
11230 #if DPDK > 0
11231   unformat_input_t *i = vam->input;
11232   vl_api_ipsec_sa_set_key_t *mp;
11233   f64 timeout;
11234   u32 sa_id;
11235   u8 *ck = 0, *ik = 0;
11236
11237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (i, "sa_id %d", &sa_id))
11240         ;
11241       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11242         ;
11243       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11244         ;
11245       else
11246         {
11247           clib_warning ("parse error '%U'", format_unformat_error, i);
11248           return -99;
11249         }
11250     }
11251
11252   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11253
11254   mp->sa_id = ntohl (sa_id);
11255   mp->crypto_key_length = vec_len (ck);
11256   mp->integrity_key_length = vec_len (ik);
11257
11258   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11259     mp->crypto_key_length = sizeof (mp->crypto_key);
11260
11261   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11262     mp->integrity_key_length = sizeof (mp->integrity_key);
11263
11264   if (ck)
11265     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11266   if (ik)
11267     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11268
11269   S;
11270   W;
11271   /* NOTREACHED */
11272   return 0;
11273 #else
11274   clib_warning ("unsupported (no dpdk)");
11275   return -99;
11276 #endif
11277 }
11278
11279 static int
11280 api_ikev2_profile_add_del (vat_main_t * vam)
11281 {
11282 #if DPDK > 0
11283   unformat_input_t *i = vam->input;
11284   vl_api_ikev2_profile_add_del_t *mp;
11285   f64 timeout;
11286   u8 is_add = 1;
11287   u8 *name = 0;
11288
11289   const char *valid_chars = "a-zA-Z0-9_";
11290
11291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (unformat (i, "del"))
11294         is_add = 0;
11295       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11296         vec_add1 (name, 0);
11297       else
11298         {
11299           errmsg ("parse error '%U'", format_unformat_error, i);
11300           return -99;
11301         }
11302     }
11303
11304   if (!vec_len (name))
11305     {
11306       errmsg ("profile name must be specified");
11307       return -99;
11308     }
11309
11310   if (vec_len (name) > 64)
11311     {
11312       errmsg ("profile name too long");
11313       return -99;
11314     }
11315
11316   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11317
11318   clib_memcpy (mp->name, name, vec_len (name));
11319   mp->is_add = is_add;
11320   vec_free (name);
11321
11322   S;
11323   W;
11324   /* NOTREACHED */
11325   return 0;
11326 #else
11327   clib_warning ("unsupported (no dpdk)");
11328   return -99;
11329 #endif
11330 }
11331
11332 static int
11333 api_ikev2_profile_set_auth (vat_main_t * vam)
11334 {
11335 #if DPDK > 0
11336   unformat_input_t *i = vam->input;
11337   vl_api_ikev2_profile_set_auth_t *mp;
11338   f64 timeout;
11339   u8 *name = 0;
11340   u8 *data = 0;
11341   u32 auth_method = 0;
11342   u8 is_hex = 0;
11343
11344   const char *valid_chars = "a-zA-Z0-9_";
11345
11346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11347     {
11348       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11349         vec_add1 (name, 0);
11350       else if (unformat (i, "auth_method %U",
11351                          unformat_ikev2_auth_method, &auth_method))
11352         ;
11353       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11354         is_hex = 1;
11355       else if (unformat (i, "auth_data %v", &data))
11356         ;
11357       else
11358         {
11359           errmsg ("parse error '%U'", format_unformat_error, i);
11360           return -99;
11361         }
11362     }
11363
11364   if (!vec_len (name))
11365     {
11366       errmsg ("profile name must be specified");
11367       return -99;
11368     }
11369
11370   if (vec_len (name) > 64)
11371     {
11372       errmsg ("profile name too long");
11373       return -99;
11374     }
11375
11376   if (!vec_len (data))
11377     {
11378       errmsg ("auth_data must be specified");
11379       return -99;
11380     }
11381
11382   if (!auth_method)
11383     {
11384       errmsg ("auth_method must be specified");
11385       return -99;
11386     }
11387
11388   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11389
11390   mp->is_hex = is_hex;
11391   mp->auth_method = (u8) auth_method;
11392   mp->data_len = vec_len (data);
11393   clib_memcpy (mp->name, name, vec_len (name));
11394   clib_memcpy (mp->data, data, vec_len (data));
11395   vec_free (name);
11396   vec_free (data);
11397
11398   S;
11399   W;
11400   /* NOTREACHED */
11401   return 0;
11402 #else
11403   clib_warning ("unsupported (no dpdk)");
11404   return -99;
11405 #endif
11406 }
11407
11408 static int
11409 api_ikev2_profile_set_id (vat_main_t * vam)
11410 {
11411 #if DPDK > 0
11412   unformat_input_t *i = vam->input;
11413   vl_api_ikev2_profile_set_id_t *mp;
11414   f64 timeout;
11415   u8 *name = 0;
11416   u8 *data = 0;
11417   u8 is_local = 0;
11418   u32 id_type = 0;
11419   ip4_address_t ip4;
11420
11421   const char *valid_chars = "a-zA-Z0-9_";
11422
11423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11426         vec_add1 (name, 0);
11427       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11428         ;
11429       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11430         {
11431           data = vec_new (u8, 4);
11432           clib_memcpy (data, ip4.as_u8, 4);
11433         }
11434       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11435         ;
11436       else if (unformat (i, "id_data %v", &data))
11437         ;
11438       else if (unformat (i, "local"))
11439         is_local = 1;
11440       else if (unformat (i, "remote"))
11441         is_local = 0;
11442       else
11443         {
11444           errmsg ("parse error '%U'", format_unformat_error, i);
11445           return -99;
11446         }
11447     }
11448
11449   if (!vec_len (name))
11450     {
11451       errmsg ("profile name must be specified");
11452       return -99;
11453     }
11454
11455   if (vec_len (name) > 64)
11456     {
11457       errmsg ("profile name too long");
11458       return -99;
11459     }
11460
11461   if (!vec_len (data))
11462     {
11463       errmsg ("id_data must be specified");
11464       return -99;
11465     }
11466
11467   if (!id_type)
11468     {
11469       errmsg ("id_type must be specified");
11470       return -99;
11471     }
11472
11473   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11474
11475   mp->is_local = is_local;
11476   mp->id_type = (u8) id_type;
11477   mp->data_len = vec_len (data);
11478   clib_memcpy (mp->name, name, vec_len (name));
11479   clib_memcpy (mp->data, data, vec_len (data));
11480   vec_free (name);
11481   vec_free (data);
11482
11483   S;
11484   W;
11485   /* NOTREACHED */
11486   return 0;
11487 #else
11488   clib_warning ("unsupported (no dpdk)");
11489   return -99;
11490 #endif
11491 }
11492
11493 static int
11494 api_ikev2_profile_set_ts (vat_main_t * vam)
11495 {
11496 #if DPDK > 0
11497   unformat_input_t *i = vam->input;
11498   vl_api_ikev2_profile_set_ts_t *mp;
11499   f64 timeout;
11500   u8 *name = 0;
11501   u8 is_local = 0;
11502   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11503   ip4_address_t start_addr, end_addr;
11504
11505   const char *valid_chars = "a-zA-Z0-9_";
11506
11507   start_addr.as_u32 = 0;
11508   end_addr.as_u32 = (u32) ~ 0;
11509
11510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11511     {
11512       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11513         vec_add1 (name, 0);
11514       else if (unformat (i, "protocol %d", &proto))
11515         ;
11516       else if (unformat (i, "start_port %d", &start_port))
11517         ;
11518       else if (unformat (i, "end_port %d", &end_port))
11519         ;
11520       else
11521         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11522         ;
11523       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11524         ;
11525       else if (unformat (i, "local"))
11526         is_local = 1;
11527       else if (unformat (i, "remote"))
11528         is_local = 0;
11529       else
11530         {
11531           errmsg ("parse error '%U'", format_unformat_error, i);
11532           return -99;
11533         }
11534     }
11535
11536   if (!vec_len (name))
11537     {
11538       errmsg ("profile name must be specified");
11539       return -99;
11540     }
11541
11542   if (vec_len (name) > 64)
11543     {
11544       errmsg ("profile name too long");
11545       return -99;
11546     }
11547
11548   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11549
11550   mp->is_local = is_local;
11551   mp->proto = (u8) proto;
11552   mp->start_port = (u16) start_port;
11553   mp->end_port = (u16) end_port;
11554   mp->start_addr = start_addr.as_u32;
11555   mp->end_addr = end_addr.as_u32;
11556   clib_memcpy (mp->name, name, vec_len (name));
11557   vec_free (name);
11558
11559   S;
11560   W;
11561   /* NOTREACHED */
11562   return 0;
11563 #else
11564   clib_warning ("unsupported (no dpdk)");
11565   return -99;
11566 #endif
11567 }
11568
11569 static int
11570 api_ikev2_set_local_key (vat_main_t * vam)
11571 {
11572 #if DPDK > 0
11573   unformat_input_t *i = vam->input;
11574   vl_api_ikev2_set_local_key_t *mp;
11575   f64 timeout;
11576   u8 *file = 0;
11577
11578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (i, "file %v", &file))
11581         vec_add1 (file, 0);
11582       else
11583         {
11584           errmsg ("parse error '%U'", format_unformat_error, i);
11585           return -99;
11586         }
11587     }
11588
11589   if (!vec_len (file))
11590     {
11591       errmsg ("RSA key file must be specified");
11592       return -99;
11593     }
11594
11595   if (vec_len (file) > 256)
11596     {
11597       errmsg ("file name too long");
11598       return -99;
11599     }
11600
11601   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11602
11603   clib_memcpy (mp->key_file, file, vec_len (file));
11604   vec_free (file);
11605
11606   S;
11607   W;
11608   /* NOTREACHED */
11609   return 0;
11610 #else
11611   clib_warning ("unsupported (no dpdk)");
11612   return -99;
11613 #endif
11614 }
11615
11616 /*
11617  * MAP
11618  */
11619 static int
11620 api_map_add_domain (vat_main_t * vam)
11621 {
11622   unformat_input_t *i = vam->input;
11623   vl_api_map_add_domain_t *mp;
11624   f64 timeout;
11625
11626   ip4_address_t ip4_prefix;
11627   ip6_address_t ip6_prefix;
11628   ip6_address_t ip6_src;
11629   u32 num_m_args = 0;
11630   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11631     0, psid_length = 0;
11632   u8 is_translation = 0;
11633   u32 mtu = 0;
11634   u32 ip6_src_len = 128;
11635
11636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11639                     &ip4_prefix, &ip4_prefix_len))
11640         num_m_args++;
11641       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11642                          &ip6_prefix, &ip6_prefix_len))
11643         num_m_args++;
11644       else
11645         if (unformat
11646             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11647              &ip6_src_len))
11648         num_m_args++;
11649       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11650         num_m_args++;
11651       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11652         num_m_args++;
11653       else if (unformat (i, "psid-offset %d", &psid_offset))
11654         num_m_args++;
11655       else if (unformat (i, "psid-len %d", &psid_length))
11656         num_m_args++;
11657       else if (unformat (i, "mtu %d", &mtu))
11658         num_m_args++;
11659       else if (unformat (i, "map-t"))
11660         is_translation = 1;
11661       else
11662         {
11663           clib_warning ("parse error '%U'", format_unformat_error, i);
11664           return -99;
11665         }
11666     }
11667
11668   if (num_m_args < 3)
11669     {
11670       errmsg ("mandatory argument(s) missing\n");
11671       return -99;
11672     }
11673
11674   /* Construct the API message */
11675   M (MAP_ADD_DOMAIN, map_add_domain);
11676
11677   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11678   mp->ip4_prefix_len = ip4_prefix_len;
11679
11680   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11681   mp->ip6_prefix_len = ip6_prefix_len;
11682
11683   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11684   mp->ip6_src_prefix_len = ip6_src_len;
11685
11686   mp->ea_bits_len = ea_bits_len;
11687   mp->psid_offset = psid_offset;
11688   mp->psid_length = psid_length;
11689   mp->is_translation = is_translation;
11690   mp->mtu = htons (mtu);
11691
11692   /* send it... */
11693   S;
11694
11695   /* Wait for a reply, return good/bad news  */
11696   W;
11697 }
11698
11699 static int
11700 api_map_del_domain (vat_main_t * vam)
11701 {
11702   unformat_input_t *i = vam->input;
11703   vl_api_map_del_domain_t *mp;
11704   f64 timeout;
11705
11706   u32 num_m_args = 0;
11707   u32 index;
11708
11709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11710     {
11711       if (unformat (i, "index %d", &index))
11712         num_m_args++;
11713       else
11714         {
11715           clib_warning ("parse error '%U'", format_unformat_error, i);
11716           return -99;
11717         }
11718     }
11719
11720   if (num_m_args != 1)
11721     {
11722       errmsg ("mandatory argument(s) missing\n");
11723       return -99;
11724     }
11725
11726   /* Construct the API message */
11727   M (MAP_DEL_DOMAIN, map_del_domain);
11728
11729   mp->index = ntohl (index);
11730
11731   /* send it... */
11732   S;
11733
11734   /* Wait for a reply, return good/bad news  */
11735   W;
11736 }
11737
11738 static int
11739 api_map_add_del_rule (vat_main_t * vam)
11740 {
11741   unformat_input_t *i = vam->input;
11742   vl_api_map_add_del_rule_t *mp;
11743   f64 timeout;
11744   u8 is_add = 1;
11745   ip6_address_t ip6_dst;
11746   u32 num_m_args = 0, index, psid = 0;
11747
11748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11749     {
11750       if (unformat (i, "index %d", &index))
11751         num_m_args++;
11752       else if (unformat (i, "psid %d", &psid))
11753         num_m_args++;
11754       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11755         num_m_args++;
11756       else if (unformat (i, "del"))
11757         {
11758           is_add = 0;
11759         }
11760       else
11761         {
11762           clib_warning ("parse error '%U'", format_unformat_error, i);
11763           return -99;
11764         }
11765     }
11766
11767   /* Construct the API message */
11768   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11769
11770   mp->index = ntohl (index);
11771   mp->is_add = is_add;
11772   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11773   mp->psid = ntohs (psid);
11774
11775   /* send it... */
11776   S;
11777
11778   /* Wait for a reply, return good/bad news  */
11779   W;
11780 }
11781
11782 static int
11783 api_map_domain_dump (vat_main_t * vam)
11784 {
11785   vl_api_map_domain_dump_t *mp;
11786   f64 timeout;
11787
11788   /* Construct the API message */
11789   M (MAP_DOMAIN_DUMP, map_domain_dump);
11790
11791   /* send it... */
11792   S;
11793
11794   /* Use a control ping for synchronization */
11795   {
11796     vl_api_control_ping_t *mp;
11797     M (CONTROL_PING, control_ping);
11798     S;
11799   }
11800   W;
11801 }
11802
11803 static int
11804 api_map_rule_dump (vat_main_t * vam)
11805 {
11806   unformat_input_t *i = vam->input;
11807   vl_api_map_rule_dump_t *mp;
11808   f64 timeout;
11809   u32 domain_index = ~0;
11810
11811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11812     {
11813       if (unformat (i, "index %u", &domain_index))
11814         ;
11815       else
11816         break;
11817     }
11818
11819   if (domain_index == ~0)
11820     {
11821       clib_warning ("parse error: domain index expected");
11822       return -99;
11823     }
11824
11825   /* Construct the API message */
11826   M (MAP_RULE_DUMP, map_rule_dump);
11827
11828   mp->domain_index = htonl (domain_index);
11829
11830   /* send it... */
11831   S;
11832
11833   /* Use a control ping for synchronization */
11834   {
11835     vl_api_control_ping_t *mp;
11836     M (CONTROL_PING, control_ping);
11837     S;
11838   }
11839   W;
11840 }
11841
11842 static void vl_api_map_add_domain_reply_t_handler
11843   (vl_api_map_add_domain_reply_t * mp)
11844 {
11845   vat_main_t *vam = &vat_main;
11846   i32 retval = ntohl (mp->retval);
11847
11848   if (vam->async_mode)
11849     {
11850       vam->async_errors += (retval < 0);
11851     }
11852   else
11853     {
11854       vam->retval = retval;
11855       vam->result_ready = 1;
11856     }
11857 }
11858
11859 static void vl_api_map_add_domain_reply_t_handler_json
11860   (vl_api_map_add_domain_reply_t * mp)
11861 {
11862   vat_main_t *vam = &vat_main;
11863   vat_json_node_t node;
11864
11865   vat_json_init_object (&node);
11866   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11867   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11868
11869   vat_json_print (vam->ofp, &node);
11870   vat_json_free (&node);
11871
11872   vam->retval = ntohl (mp->retval);
11873   vam->result_ready = 1;
11874 }
11875
11876 static int
11877 api_get_first_msg_id (vat_main_t * vam)
11878 {
11879   vl_api_get_first_msg_id_t *mp;
11880   f64 timeout;
11881   unformat_input_t *i = vam->input;
11882   u8 *name;
11883   u8 name_set = 0;
11884
11885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11886     {
11887       if (unformat (i, "client %s", &name))
11888         name_set = 1;
11889       else
11890         break;
11891     }
11892
11893   if (name_set == 0)
11894     {
11895       errmsg ("missing client name\n");
11896       return -99;
11897     }
11898   vec_add1 (name, 0);
11899
11900   if (vec_len (name) > 63)
11901     {
11902       errmsg ("client name too long\n");
11903       return -99;
11904     }
11905
11906   M (GET_FIRST_MSG_ID, get_first_msg_id);
11907   clib_memcpy (mp->name, name, vec_len (name));
11908   S;
11909   W;
11910   /* NOTREACHED */
11911   return 0;
11912 }
11913
11914 static int
11915 api_cop_interface_enable_disable (vat_main_t * vam)
11916 {
11917   unformat_input_t *line_input = vam->input;
11918   vl_api_cop_interface_enable_disable_t *mp;
11919   f64 timeout;
11920   u32 sw_if_index = ~0;
11921   u8 enable_disable = 1;
11922
11923   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (line_input, "disable"))
11926         enable_disable = 0;
11927       if (unformat (line_input, "enable"))
11928         enable_disable = 1;
11929       else if (unformat (line_input, "%U", unformat_sw_if_index,
11930                          vam, &sw_if_index))
11931         ;
11932       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11933         ;
11934       else
11935         break;
11936     }
11937
11938   if (sw_if_index == ~0)
11939     {
11940       errmsg ("missing interface name or sw_if_index\n");
11941       return -99;
11942     }
11943
11944   /* Construct the API message */
11945   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11946   mp->sw_if_index = ntohl (sw_if_index);
11947   mp->enable_disable = enable_disable;
11948
11949   /* send it... */
11950   S;
11951   /* Wait for the reply */
11952   W;
11953 }
11954
11955 static int
11956 api_cop_whitelist_enable_disable (vat_main_t * vam)
11957 {
11958   unformat_input_t *line_input = vam->input;
11959   vl_api_cop_whitelist_enable_disable_t *mp;
11960   f64 timeout;
11961   u32 sw_if_index = ~0;
11962   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11963   u32 fib_id = 0;
11964
11965   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11966     {
11967       if (unformat (line_input, "ip4"))
11968         ip4 = 1;
11969       else if (unformat (line_input, "ip6"))
11970         ip6 = 1;
11971       else if (unformat (line_input, "default"))
11972         default_cop = 1;
11973       else if (unformat (line_input, "%U", unformat_sw_if_index,
11974                          vam, &sw_if_index))
11975         ;
11976       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11977         ;
11978       else if (unformat (line_input, "fib-id %d", &fib_id))
11979         ;
11980       else
11981         break;
11982     }
11983
11984   if (sw_if_index == ~0)
11985     {
11986       errmsg ("missing interface name or sw_if_index\n");
11987       return -99;
11988     }
11989
11990   /* Construct the API message */
11991   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11992   mp->sw_if_index = ntohl (sw_if_index);
11993   mp->fib_id = ntohl (fib_id);
11994   mp->ip4 = ip4;
11995   mp->ip6 = ip6;
11996   mp->default_cop = default_cop;
11997
11998   /* send it... */
11999   S;
12000   /* Wait for the reply */
12001   W;
12002 }
12003
12004 static int
12005 api_get_node_graph (vat_main_t * vam)
12006 {
12007   vl_api_get_node_graph_t *mp;
12008   f64 timeout;
12009
12010   M (GET_NODE_GRAPH, get_node_graph);
12011
12012   /* send it... */
12013   S;
12014   /* Wait for the reply */
12015   W;
12016 }
12017
12018 /* *INDENT-OFF* */
12019 /** Used for parsing LISP eids */
12020 typedef CLIB_PACKED(struct{
12021   u8 addr[16];   /**< eid address */
12022   u32 len;       /**< prefix length if IP */
12023   u8 type;      /**< type of eid */
12024 }) lisp_eid_vat_t;
12025 /* *INDENT-ON* */
12026
12027 static uword
12028 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12029 {
12030   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12031
12032   memset (a, 0, sizeof (a[0]));
12033
12034   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12035     {
12036       a->type = 0;              /* ipv4 type */
12037     }
12038   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12039     {
12040       a->type = 1;              /* ipv6 type */
12041     }
12042   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12043     {
12044       a->type = 2;              /* mac type */
12045     }
12046   else
12047     {
12048       return 0;
12049     }
12050
12051   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12052     {
12053       return 0;
12054     }
12055
12056   return 1;
12057 }
12058
12059 static int
12060 lisp_eid_size_vat (u8 type)
12061 {
12062   switch (type)
12063     {
12064     case 0:
12065       return 4;
12066     case 1:
12067       return 16;
12068     case 2:
12069       return 6;
12070     }
12071   return 0;
12072 }
12073
12074 static void
12075 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12076 {
12077   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12078 }
12079
12080 /* *INDENT-OFF* */
12081 /** Used for transferring locators via VPP API */
12082 typedef CLIB_PACKED(struct
12083 {
12084   u32 sw_if_index; /**< locator sw_if_index */
12085   u8 priority; /**< locator priority */
12086   u8 weight;   /**< locator weight */
12087 }) ls_locator_t;
12088 /* *INDENT-ON* */
12089
12090 static int
12091 api_lisp_add_del_locator_set (vat_main_t * vam)
12092 {
12093   unformat_input_t *input = vam->input;
12094   vl_api_lisp_add_del_locator_set_t *mp;
12095   f64 timeout = ~0;
12096   u8 is_add = 1;
12097   u8 *locator_set_name = NULL;
12098   u8 locator_set_name_set = 0;
12099   ls_locator_t locator, *locators = 0;
12100   u32 sw_if_index, priority, weight;
12101   u32 data_len = 0;
12102
12103   /* Parse args required to build the message */
12104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12105     {
12106       if (unformat (input, "del"))
12107         {
12108           is_add = 0;
12109         }
12110       else if (unformat (input, "locator-set %s", &locator_set_name))
12111         {
12112           locator_set_name_set = 1;
12113         }
12114       else if (unformat (input, "sw_if_index %u p %u w %u",
12115                          &sw_if_index, &priority, &weight))
12116         {
12117           locator.sw_if_index = htonl (sw_if_index);
12118           locator.priority = priority;
12119           locator.weight = weight;
12120           vec_add1 (locators, locator);
12121         }
12122       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12123                          vam, &sw_if_index, &priority, &weight))
12124         {
12125           locator.sw_if_index = htonl (sw_if_index);
12126           locator.priority = priority;
12127           locator.weight = weight;
12128           vec_add1 (locators, locator);
12129         }
12130       else
12131         break;
12132     }
12133
12134   if (locator_set_name_set == 0)
12135     {
12136       errmsg ("missing locator-set name");
12137       vec_free (locators);
12138       return -99;
12139     }
12140
12141   if (vec_len (locator_set_name) > 64)
12142     {
12143       errmsg ("locator-set name too long\n");
12144       vec_free (locator_set_name);
12145       vec_free (locators);
12146       return -99;
12147     }
12148   vec_add1 (locator_set_name, 0);
12149
12150   data_len = sizeof (ls_locator_t) * vec_len (locators);
12151
12152   /* Construct the API message */
12153   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12154
12155   mp->is_add = is_add;
12156   clib_memcpy (mp->locator_set_name, locator_set_name,
12157                vec_len (locator_set_name));
12158   vec_free (locator_set_name);
12159
12160   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12161   if (locators)
12162     clib_memcpy (mp->locators, locators, data_len);
12163   vec_free (locators);
12164
12165   /* send it... */
12166   S;
12167
12168   /* Wait for a reply... */
12169   W;
12170
12171   /* NOTREACHED */
12172   return 0;
12173 }
12174
12175 static int
12176 api_lisp_add_del_locator (vat_main_t * vam)
12177 {
12178   unformat_input_t *input = vam->input;
12179   vl_api_lisp_add_del_locator_t *mp;
12180   f64 timeout = ~0;
12181   u32 tmp_if_index = ~0;
12182   u32 sw_if_index = ~0;
12183   u8 sw_if_index_set = 0;
12184   u8 sw_if_index_if_name_set = 0;
12185   u32 priority = ~0;
12186   u8 priority_set = 0;
12187   u32 weight = ~0;
12188   u8 weight_set = 0;
12189   u8 is_add = 1;
12190   u8 *locator_set_name = NULL;
12191   u8 locator_set_name_set = 0;
12192
12193   /* Parse args required to build the message */
12194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12195     {
12196       if (unformat (input, "del"))
12197         {
12198           is_add = 0;
12199         }
12200       else if (unformat (input, "locator-set %s", &locator_set_name))
12201         {
12202           locator_set_name_set = 1;
12203         }
12204       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12205                          &tmp_if_index))
12206         {
12207           sw_if_index_if_name_set = 1;
12208           sw_if_index = tmp_if_index;
12209         }
12210       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12211         {
12212           sw_if_index_set = 1;
12213           sw_if_index = tmp_if_index;
12214         }
12215       else if (unformat (input, "p %d", &priority))
12216         {
12217           priority_set = 1;
12218         }
12219       else if (unformat (input, "w %d", &weight))
12220         {
12221           weight_set = 1;
12222         }
12223       else
12224         break;
12225     }
12226
12227   if (locator_set_name_set == 0)
12228     {
12229       errmsg ("missing locator-set name");
12230       return -99;
12231     }
12232
12233   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12234     {
12235       errmsg ("missing sw_if_index");
12236       vec_free (locator_set_name);
12237       return -99;
12238     }
12239
12240   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12241     {
12242       errmsg ("cannot use both params interface name and sw_if_index");
12243       vec_free (locator_set_name);
12244       return -99;
12245     }
12246
12247   if (priority_set == 0)
12248     {
12249       errmsg ("missing locator-set priority\n");
12250       vec_free (locator_set_name);
12251       return -99;
12252     }
12253
12254   if (weight_set == 0)
12255     {
12256       errmsg ("missing locator-set weight\n");
12257       vec_free (locator_set_name);
12258       return -99;
12259     }
12260
12261   if (vec_len (locator_set_name) > 64)
12262     {
12263       errmsg ("locator-set name too long\n");
12264       vec_free (locator_set_name);
12265       return -99;
12266     }
12267   vec_add1 (locator_set_name, 0);
12268
12269   /* Construct the API message */
12270   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12271
12272   mp->is_add = is_add;
12273   mp->sw_if_index = ntohl (sw_if_index);
12274   mp->priority = priority;
12275   mp->weight = weight;
12276   clib_memcpy (mp->locator_set_name, locator_set_name,
12277                vec_len (locator_set_name));
12278   vec_free (locator_set_name);
12279
12280   /* send it... */
12281   S;
12282
12283   /* Wait for a reply... */
12284   W;
12285
12286   /* NOTREACHED */
12287   return 0;
12288 }
12289
12290 static int
12291 api_lisp_add_del_local_eid (vat_main_t * vam)
12292 {
12293   unformat_input_t *input = vam->input;
12294   vl_api_lisp_add_del_local_eid_t *mp;
12295   f64 timeout = ~0;
12296   u8 is_add = 1;
12297   u8 eid_set = 0;
12298   lisp_eid_vat_t _eid, *eid = &_eid;
12299   u8 *locator_set_name = 0;
12300   u8 locator_set_name_set = 0;
12301   u32 vni = 0;
12302
12303   /* Parse args required to build the message */
12304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12305     {
12306       if (unformat (input, "del"))
12307         {
12308           is_add = 0;
12309         }
12310       else if (unformat (input, "vni %d", &vni))
12311         {
12312           ;
12313         }
12314       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12315         {
12316           eid_set = 1;
12317         }
12318       else if (unformat (input, "locator-set %s", &locator_set_name))
12319         {
12320           locator_set_name_set = 1;
12321         }
12322       else
12323         break;
12324     }
12325
12326   if (locator_set_name_set == 0)
12327     {
12328       errmsg ("missing locator-set name\n");
12329       return -99;
12330     }
12331
12332   if (0 == eid_set)
12333     {
12334       errmsg ("EID address not set!");
12335       vec_free (locator_set_name);
12336       return -99;
12337     }
12338
12339   if (vec_len (locator_set_name) > 64)
12340     {
12341       errmsg ("locator-set name too long\n");
12342       vec_free (locator_set_name);
12343       return -99;
12344     }
12345   vec_add1 (locator_set_name, 0);
12346
12347   /* Construct the API message */
12348   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12349
12350   mp->is_add = is_add;
12351   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12352   mp->eid_type = eid->type;
12353   mp->prefix_len = eid->len;
12354   mp->vni = clib_host_to_net_u32 (vni);
12355   clib_memcpy (mp->locator_set_name, locator_set_name,
12356                vec_len (locator_set_name));
12357
12358   vec_free (locator_set_name);
12359
12360   /* send it... */
12361   S;
12362
12363   /* Wait for a reply... */
12364   W;
12365
12366   /* NOTREACHED */
12367   return 0;
12368 }
12369
12370 /* *INDENT-OFF* */
12371 /** Used for transferring locators via VPP API */
12372 typedef CLIB_PACKED(struct
12373 {
12374   u8 is_ip4; /**< is locator an IPv4 address? */
12375   u8 priority; /**< locator priority */
12376   u8 weight;   /**< locator weight */
12377   u8 addr[16]; /**< IPv4/IPv6 address */
12378 }) rloc_t;
12379 /* *INDENT-ON* */
12380
12381 static int
12382 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12383 {
12384   unformat_input_t *input = vam->input;
12385   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12386   f64 timeout = ~0;
12387   u8 is_add = 1;
12388   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12389   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12390   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12391   u32 action = ~0, p, w;
12392   ip4_address_t rmt_rloc4, lcl_rloc4;
12393   ip6_address_t rmt_rloc6, lcl_rloc6;
12394   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12395
12396   memset (&rloc, 0, sizeof (rloc));
12397
12398   /* Parse args required to build the message */
12399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12400     {
12401       if (unformat (input, "del"))
12402         {
12403           is_add = 0;
12404         }
12405       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12406         {
12407           rmt_eid_set = 1;
12408         }
12409       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12410         {
12411           lcl_eid_set = 1;
12412         }
12413       else if (unformat (input, "p %d w %d", &p, &w))
12414         {
12415           if (!curr_rloc)
12416             {
12417               errmsg ("No RLOC configured for setting priority/weight!");
12418               return -99;
12419             }
12420           curr_rloc->priority = p;
12421           curr_rloc->weight = w;
12422         }
12423       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12424                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12425         {
12426           rloc.is_ip4 = 1;
12427
12428           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12429           rloc.priority = rloc.weight = 0;
12430           vec_add1 (lcl_locs, rloc);
12431
12432           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12433           vec_add1 (rmt_locs, rloc);
12434           /* priority and weight saved in rmt loc */
12435           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12436         }
12437       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12438                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12439         {
12440           rloc.is_ip4 = 0;
12441           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12442           rloc.priority = rloc.weight = 0;
12443           vec_add1 (lcl_locs, rloc);
12444
12445           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12446           vec_add1 (rmt_locs, rloc);
12447           /* priority and weight saved in rmt loc */
12448           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12449         }
12450       else if (unformat (input, "action %d", &action))
12451         {
12452           ;
12453         }
12454       else
12455         {
12456           clib_warning ("parse error '%U'", format_unformat_error, input);
12457           return -99;
12458         }
12459     }
12460
12461   if (!rmt_eid_set)
12462     {
12463       errmsg ("remote eid addresses not set\n");
12464       return -99;
12465     }
12466
12467   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12468     {
12469       errmsg ("eid types don't match\n");
12470       return -99;
12471     }
12472
12473   if (0 == rmt_locs && (u32) ~ 0 == action)
12474     {
12475       errmsg ("action not set for negative mapping\n");
12476       return -99;
12477     }
12478
12479   /* Construct the API message */
12480   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12481
12482   mp->is_add = is_add;
12483   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12484   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12485   mp->eid_type = rmt_eid->type;
12486   mp->rmt_len = rmt_eid->len;
12487   mp->lcl_len = lcl_eid->len;
12488   mp->action = action;
12489
12490   if (0 != rmt_locs && 0 != lcl_locs)
12491     {
12492       mp->loc_num = vec_len (rmt_locs);
12493       clib_memcpy (mp->lcl_locs, lcl_locs,
12494                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12495       clib_memcpy (mp->rmt_locs, rmt_locs,
12496                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12497     }
12498   vec_free (lcl_locs);
12499   vec_free (rmt_locs);
12500
12501   /* send it... */
12502   S;
12503
12504   /* Wait for a reply... */
12505   W;
12506
12507   /* NOTREACHED */
12508   return 0;
12509 }
12510
12511 static int
12512 api_lisp_add_del_map_resolver (vat_main_t * vam)
12513 {
12514   unformat_input_t *input = vam->input;
12515   vl_api_lisp_add_del_map_resolver_t *mp;
12516   f64 timeout = ~0;
12517   u8 is_add = 1;
12518   u8 ipv4_set = 0;
12519   u8 ipv6_set = 0;
12520   ip4_address_t ipv4;
12521   ip6_address_t ipv6;
12522
12523   /* Parse args required to build the message */
12524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12525     {
12526       if (unformat (input, "del"))
12527         {
12528           is_add = 0;
12529         }
12530       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12531         {
12532           ipv4_set = 1;
12533         }
12534       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12535         {
12536           ipv6_set = 1;
12537         }
12538       else
12539         break;
12540     }
12541
12542   if (ipv4_set && ipv6_set)
12543     {
12544       errmsg ("both eid v4 and v6 addresses set\n");
12545       return -99;
12546     }
12547
12548   if (!ipv4_set && !ipv6_set)
12549     {
12550       errmsg ("eid addresses not set\n");
12551       return -99;
12552     }
12553
12554   /* Construct the API message */
12555   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12556
12557   mp->is_add = is_add;
12558   if (ipv6_set)
12559     {
12560       mp->is_ipv6 = 1;
12561       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12562     }
12563   else
12564     {
12565       mp->is_ipv6 = 0;
12566       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12567     }
12568
12569   /* send it... */
12570   S;
12571
12572   /* Wait for a reply... */
12573   W;
12574
12575   /* NOTREACHED */
12576   return 0;
12577 }
12578
12579 static int
12580 api_lisp_gpe_enable_disable (vat_main_t * vam)
12581 {
12582   unformat_input_t *input = vam->input;
12583   vl_api_lisp_gpe_enable_disable_t *mp;
12584   f64 timeout = ~0;
12585   u8 is_set = 0;
12586   u8 is_en = 1;
12587
12588   /* Parse args required to build the message */
12589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12590     {
12591       if (unformat (input, "enable"))
12592         {
12593           is_set = 1;
12594           is_en = 1;
12595         }
12596       else if (unformat (input, "disable"))
12597         {
12598           is_set = 1;
12599           is_en = 0;
12600         }
12601       else
12602         break;
12603     }
12604
12605   if (is_set == 0)
12606     {
12607       errmsg ("Value not set\n");
12608       return -99;
12609     }
12610
12611   /* Construct the API message */
12612   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12613
12614   mp->is_en = is_en;
12615
12616   /* send it... */
12617   S;
12618
12619   /* Wait for a reply... */
12620   W;
12621
12622   /* NOTREACHED */
12623   return 0;
12624 }
12625
12626 static int
12627 api_lisp_enable_disable (vat_main_t * vam)
12628 {
12629   unformat_input_t *input = vam->input;
12630   vl_api_lisp_enable_disable_t *mp;
12631   f64 timeout = ~0;
12632   u8 is_set = 0;
12633   u8 is_en = 0;
12634
12635   /* Parse args required to build the message */
12636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12637     {
12638       if (unformat (input, "enable"))
12639         {
12640           is_set = 1;
12641           is_en = 1;
12642         }
12643       else if (unformat (input, "disable"))
12644         {
12645           is_set = 1;
12646         }
12647       else
12648         break;
12649     }
12650
12651   if (!is_set)
12652     {
12653       errmsg ("Value not set\n");
12654       return -99;
12655     }
12656
12657   /* Construct the API message */
12658   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12659
12660   mp->is_en = is_en;
12661
12662   /* send it... */
12663   S;
12664
12665   /* Wait for a reply... */
12666   W;
12667
12668   /* NOTREACHED */
12669   return 0;
12670 }
12671
12672 static int
12673 api_show_lisp_map_request_mode (vat_main_t * vam)
12674 {
12675   f64 timeout = ~0;
12676   vl_api_show_lisp_map_request_mode_t *mp;
12677
12678   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12679
12680   /* send */
12681   S;
12682
12683   /* wait for reply */
12684   W;
12685
12686   return 0;
12687 }
12688
12689 static int
12690 api_lisp_map_request_mode (vat_main_t * vam)
12691 {
12692   f64 timeout = ~0;
12693   unformat_input_t *input = vam->input;
12694   vl_api_lisp_map_request_mode_t *mp;
12695   u8 mode = 0;
12696
12697   /* Parse args required to build the message */
12698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12699     {
12700       if (unformat (input, "dst-only"))
12701         mode = 0;
12702       else if (unformat (input, "src-dst"))
12703         mode = 1;
12704       else
12705         {
12706           errmsg ("parse error '%U'", format_unformat_error, input);
12707           return -99;
12708         }
12709     }
12710
12711   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12712
12713   mp->mode = mode;
12714
12715   /* send */
12716   S;
12717
12718   /* wait for reply */
12719   W;
12720
12721   /* notreached */
12722   return 0;
12723 }
12724
12725 /**
12726  * Enable/disable LISP proxy ITR.
12727  *
12728  * @param vam vpp API test context
12729  * @return return code
12730  */
12731 static int
12732 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12733 {
12734   f64 timeout = ~0;
12735   u8 ls_name_set = 0;
12736   unformat_input_t *input = vam->input;
12737   vl_api_lisp_pitr_set_locator_set_t *mp;
12738   u8 is_add = 1;
12739   u8 *ls_name = 0;
12740
12741   /* Parse args required to build the message */
12742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12743     {
12744       if (unformat (input, "del"))
12745         is_add = 0;
12746       else if (unformat (input, "locator-set %s", &ls_name))
12747         ls_name_set = 1;
12748       else
12749         {
12750           errmsg ("parse error '%U'", format_unformat_error, input);
12751           return -99;
12752         }
12753     }
12754
12755   if (!ls_name_set)
12756     {
12757       errmsg ("locator-set name not set!");
12758       return -99;
12759     }
12760
12761   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12762
12763   mp->is_add = is_add;
12764   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12765   vec_free (ls_name);
12766
12767   /* send */
12768   S;
12769
12770   /* wait for reply */
12771   W;
12772
12773   /* notreached */
12774   return 0;
12775 }
12776
12777 static int
12778 api_show_lisp_pitr (vat_main_t * vam)
12779 {
12780   vl_api_show_lisp_pitr_t *mp;
12781   f64 timeout = ~0;
12782
12783   if (!vam->json_output)
12784     {
12785       fformat (vam->ofp, "%=20s\n", "lisp status:");
12786     }
12787
12788   M (SHOW_LISP_PITR, show_lisp_pitr);
12789   /* send it... */
12790   S;
12791
12792   /* Wait for a reply... */
12793   W;
12794
12795   /* NOTREACHED */
12796   return 0;
12797 }
12798
12799 /**
12800  * Add/delete mapping between vni and vrf
12801  */
12802 static int
12803 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12804 {
12805   f64 timeout = ~0;
12806   unformat_input_t *input = vam->input;
12807   vl_api_lisp_eid_table_add_del_map_t *mp;
12808   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12809   u32 vni, vrf, bd_index;
12810
12811   /* Parse args required to build the message */
12812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12813     {
12814       if (unformat (input, "del"))
12815         is_add = 0;
12816       else if (unformat (input, "vrf %d", &vrf))
12817         vrf_set = 1;
12818       else if (unformat (input, "bd_index %d", &bd_index))
12819         bd_index_set = 1;
12820       else if (unformat (input, "vni %d", &vni))
12821         vni_set = 1;
12822       else
12823         break;
12824     }
12825
12826   if (!vni_set || (!vrf_set && !bd_index_set))
12827     {
12828       errmsg ("missing arguments!");
12829       return -99;
12830     }
12831
12832   if (vrf_set && bd_index_set)
12833     {
12834       errmsg ("error: both vrf and bd entered!");
12835       return -99;
12836     }
12837
12838   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12839
12840   mp->is_add = is_add;
12841   mp->vni = htonl (vni);
12842   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12843   mp->is_l2 = bd_index_set;
12844
12845   /* send */
12846   S;
12847
12848   /* wait for reply */
12849   W;
12850
12851   /* notreached */
12852   return 0;
12853 }
12854
12855 uword
12856 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12857 {
12858   u32 *action = va_arg (*args, u32 *);
12859   u8 *s = 0;
12860
12861   if (unformat (input, "%s", &s))
12862     {
12863       if (!strcmp ((char *) s, "no-action"))
12864         action[0] = 0;
12865       else if (!strcmp ((char *) s, "natively-forward"))
12866         action[0] = 1;
12867       else if (!strcmp ((char *) s, "send-map-request"))
12868         action[0] = 2;
12869       else if (!strcmp ((char *) s, "drop"))
12870         action[0] = 3;
12871       else
12872         {
12873           clib_warning ("invalid action: '%s'", s);
12874           action[0] = 3;
12875         }
12876     }
12877   else
12878     return 0;
12879
12880   vec_free (s);
12881   return 1;
12882 }
12883
12884 /**
12885  * Add/del remote mapping to/from LISP control plane
12886  *
12887  * @param vam vpp API test context
12888  * @return return code
12889  */
12890 static int
12891 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12892 {
12893   unformat_input_t *input = vam->input;
12894   vl_api_lisp_add_del_remote_mapping_t *mp;
12895   f64 timeout = ~0;
12896   u32 vni = 0;
12897   lisp_eid_vat_t _eid, *eid = &_eid;
12898   lisp_eid_vat_t _seid, *seid = &_seid;
12899   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12900   u32 action = ~0, p, w, data_len;
12901   ip4_address_t rloc4;
12902   ip6_address_t rloc6;
12903   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12904
12905   memset (&rloc, 0, sizeof (rloc));
12906
12907   /* Parse args required to build the message */
12908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12909     {
12910       if (unformat (input, "del-all"))
12911         {
12912           del_all = 1;
12913         }
12914       else if (unformat (input, "del"))
12915         {
12916           is_add = 0;
12917         }
12918       else if (unformat (input, "add"))
12919         {
12920           is_add = 1;
12921         }
12922       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12923         {
12924           eid_set = 1;
12925         }
12926       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12927         {
12928           seid_set = 1;
12929         }
12930       else if (unformat (input, "vni %d", &vni))
12931         {
12932           ;
12933         }
12934       else if (unformat (input, "p %d w %d", &p, &w))
12935         {
12936           if (!curr_rloc)
12937             {
12938               errmsg ("No RLOC configured for setting priority/weight!");
12939               return -99;
12940             }
12941           curr_rloc->priority = p;
12942           curr_rloc->weight = w;
12943         }
12944       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12945         {
12946           rloc.is_ip4 = 1;
12947           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12948           vec_add1 (rlocs, rloc);
12949           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12950         }
12951       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12952         {
12953           rloc.is_ip4 = 0;
12954           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12955           vec_add1 (rlocs, rloc);
12956           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12957         }
12958       else if (unformat (input, "action %U",
12959                          unformat_negative_mapping_action, &action))
12960         {
12961           ;
12962         }
12963       else
12964         {
12965           clib_warning ("parse error '%U'", format_unformat_error, input);
12966           return -99;
12967         }
12968     }
12969
12970   if (0 == eid_set)
12971     {
12972       errmsg ("missing params!");
12973       return -99;
12974     }
12975
12976   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12977     {
12978       errmsg ("no action set for negative map-reply!");
12979       return -99;
12980     }
12981
12982   data_len = vec_len (rlocs) * sizeof (rloc_t);
12983
12984   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
12985   mp->is_add = is_add;
12986   mp->vni = htonl (vni);
12987   mp->action = (u8) action;
12988   mp->is_src_dst = seid_set;
12989   mp->eid_len = eid->len;
12990   mp->seid_len = seid->len;
12991   mp->del_all = del_all;
12992   mp->eid_type = eid->type;
12993   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12994   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
12995
12996   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12997   clib_memcpy (mp->rlocs, rlocs, data_len);
12998   vec_free (rlocs);
12999
13000   /* send it... */
13001   S;
13002
13003   /* Wait for a reply... */
13004   W;
13005
13006   /* NOTREACHED */
13007   return 0;
13008 }
13009
13010 /**
13011  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13012  * forwarding entries in data-plane accordingly.
13013  *
13014  * @param vam vpp API test context
13015  * @return return code
13016  */
13017 static int
13018 api_lisp_add_del_adjacency (vat_main_t * vam)
13019 {
13020   unformat_input_t *input = vam->input;
13021   vl_api_lisp_add_del_adjacency_t *mp;
13022   f64 timeout = ~0;
13023   u32 vni = 0;
13024   ip4_address_t seid4, deid4;
13025   ip6_address_t seid6, deid6;
13026   u8 deid_mac[6] = { 0 };
13027   u8 seid_mac[6] = { 0 };
13028   u8 deid_type, seid_type;
13029   u32 seid_len = 0, deid_len = 0, len;
13030   u8 is_add = 1;
13031
13032   seid_type = deid_type = (u8) ~ 0;
13033
13034   /* Parse args required to build the message */
13035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13036     {
13037       if (unformat (input, "del"))
13038         {
13039           is_add = 0;
13040         }
13041       else if (unformat (input, "add"))
13042         {
13043           is_add = 1;
13044         }
13045       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
13046                          &deid4, &len))
13047         {
13048           deid_type = 0;        /* ipv4 */
13049           deid_len = len;
13050         }
13051       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
13052                          &deid6, &len))
13053         {
13054           deid_type = 1;        /* ipv6 */
13055           deid_len = len;
13056         }
13057       else if (unformat (input, "deid %U", unformat_ethernet_address,
13058                          deid_mac))
13059         {
13060           deid_type = 2;        /* mac */
13061         }
13062       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
13063                          &seid4, &len))
13064         {
13065           seid_type = 0;        /* ipv4 */
13066           seid_len = len;
13067         }
13068       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
13069                          &seid6, &len))
13070         {
13071           seid_type = 1;        /* ipv6 */
13072           seid_len = len;
13073         }
13074       else if (unformat (input, "seid %U", unformat_ethernet_address,
13075                          seid_mac))
13076         {
13077           seid_type = 2;        /* mac */
13078         }
13079       else if (unformat (input, "vni %d", &vni))
13080         {
13081           ;
13082         }
13083       else
13084         {
13085           errmsg ("parse error '%U'", format_unformat_error, input);
13086           return -99;
13087         }
13088     }
13089
13090   if ((u8) ~ 0 == deid_type)
13091     {
13092       errmsg ("missing params!");
13093       return -99;
13094     }
13095
13096   if (seid_type != deid_type)
13097     {
13098       errmsg ("source and destination EIDs are of different types!");
13099       return -99;
13100     }
13101
13102   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13103   mp->is_add = is_add;
13104   mp->vni = htonl (vni);
13105   mp->seid_len = seid_len;
13106   mp->deid_len = deid_len;
13107   mp->eid_type = deid_type;
13108
13109   switch (mp->eid_type)
13110     {
13111     case 0:
13112       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
13113       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
13114       break;
13115     case 1:
13116       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
13117       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
13118       break;
13119     case 2:
13120       clib_memcpy (mp->seid, seid_mac, 6);
13121       clib_memcpy (mp->deid, deid_mac, 6);
13122       break;
13123     default:
13124       errmsg ("unknown EID type %d!", mp->eid_type);
13125       return 0;
13126     }
13127
13128   /* send it... */
13129   S;
13130
13131   /* Wait for a reply... */
13132   W;
13133
13134   /* NOTREACHED */
13135   return 0;
13136 }
13137
13138 static int
13139 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13140 {
13141   unformat_input_t *input = vam->input;
13142   vl_api_lisp_gpe_add_del_iface_t *mp;
13143   f64 timeout = ~0;
13144   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13145   u32 dp_table = 0, vni = 0;
13146
13147   /* Parse args required to build the message */
13148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13149     {
13150       if (unformat (input, "up"))
13151         {
13152           action_set = 1;
13153           is_add = 1;
13154         }
13155       else if (unformat (input, "down"))
13156         {
13157           action_set = 1;
13158           is_add = 0;
13159         }
13160       else if (unformat (input, "table_id %d", &dp_table))
13161         {
13162           dp_table_set = 1;
13163         }
13164       else if (unformat (input, "bd_id %d", &dp_table))
13165         {
13166           dp_table_set = 1;
13167           is_l2 = 1;
13168         }
13169       else if (unformat (input, "vni %d", &vni))
13170         {
13171           vni_set = 1;
13172         }
13173       else
13174         break;
13175     }
13176
13177   if (action_set == 0)
13178     {
13179       errmsg ("Action not set\n");
13180       return -99;
13181     }
13182   if (dp_table_set == 0 || vni_set == 0)
13183     {
13184       errmsg ("vni and dp_table must be set\n");
13185       return -99;
13186     }
13187
13188   /* Construct the API message */
13189   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13190
13191   mp->is_add = is_add;
13192   mp->dp_table = dp_table;
13193   mp->is_l2 = is_l2;
13194   mp->vni = vni;
13195
13196   /* send it... */
13197   S;
13198
13199   /* Wait for a reply... */
13200   W;
13201
13202   /* NOTREACHED */
13203   return 0;
13204 }
13205
13206 /**
13207  * Add/del map request itr rlocs from LISP control plane and updates
13208  *
13209  * @param vam vpp API test context
13210  * @return return code
13211  */
13212 static int
13213 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13214 {
13215   unformat_input_t *input = vam->input;
13216   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13217   f64 timeout = ~0;
13218   u8 *locator_set_name = 0;
13219   u8 locator_set_name_set = 0;
13220   u8 is_add = 1;
13221
13222   /* Parse args required to build the message */
13223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13224     {
13225       if (unformat (input, "del"))
13226         {
13227           is_add = 0;
13228         }
13229       else if (unformat (input, "%_%v%_", &locator_set_name))
13230         {
13231           locator_set_name_set = 1;
13232         }
13233       else
13234         {
13235           clib_warning ("parse error '%U'", format_unformat_error, input);
13236           return -99;
13237         }
13238     }
13239
13240   if (is_add && !locator_set_name_set)
13241     {
13242       errmsg ("itr-rloc is not set!");
13243       return -99;
13244     }
13245
13246   if (is_add && vec_len (locator_set_name) > 64)
13247     {
13248       errmsg ("itr-rloc locator-set name too long\n");
13249       vec_free (locator_set_name);
13250       return -99;
13251     }
13252
13253   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13254   mp->is_add = is_add;
13255   if (is_add)
13256     {
13257       clib_memcpy (mp->locator_set_name, locator_set_name,
13258                    vec_len (locator_set_name));
13259     }
13260   else
13261     {
13262       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13263     }
13264   vec_free (locator_set_name);
13265
13266   /* send it... */
13267   S;
13268
13269   /* Wait for a reply... */
13270   W;
13271
13272   /* NOTREACHED */
13273   return 0;
13274 }
13275
13276 static int
13277 api_lisp_locator_dump (vat_main_t * vam)
13278 {
13279   unformat_input_t *input = vam->input;
13280   vl_api_lisp_locator_dump_t *mp;
13281   f64 timeout = ~0;
13282   u8 is_index_set = 0, is_name_set = 0;
13283   u8 *ls_name = 0;
13284   u32 ls_index = ~0;
13285
13286   /* Parse args required to build the message */
13287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13288     {
13289       if (unformat (input, "ls_name %_%v%_", &ls_name))
13290         {
13291           is_name_set = 1;
13292         }
13293       else if (unformat (input, "ls_index %d", &ls_index))
13294         {
13295           is_index_set = 1;
13296         }
13297       else
13298         {
13299           errmsg ("parse error '%U'", format_unformat_error, input);
13300           return -99;
13301         }
13302     }
13303
13304   if (!is_index_set && !is_name_set)
13305     {
13306       errmsg ("error: expected one of index or name!\n");
13307       return -99;
13308     }
13309
13310   if (is_index_set && is_name_set)
13311     {
13312       errmsg ("error: only one param expected!\n");
13313       return -99;
13314     }
13315
13316   if (vec_len (ls_name) > 62)
13317     {
13318       errmsg ("error: locator set name too long!");
13319       return -99;
13320     }
13321
13322   if (!vam->json_output)
13323     {
13324       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13325                "weight");
13326     }
13327
13328   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13329   mp->is_index_set = is_index_set;
13330
13331   if (is_index_set)
13332     mp->ls_index = clib_host_to_net_u32 (ls_index);
13333   else
13334     {
13335       vec_add1 (ls_name, 0);
13336       strncpy ((char *) mp->ls_name, (char *) ls_name,
13337                sizeof (mp->ls_name) - 1);
13338     }
13339
13340   /* send it... */
13341   S;
13342
13343   /* Use a control ping for synchronization */
13344   {
13345     vl_api_control_ping_t *mp;
13346     M (CONTROL_PING, control_ping);
13347     S;
13348   }
13349   /* Wait for a reply... */
13350   W;
13351
13352   /* NOTREACHED */
13353   return 0;
13354 }
13355
13356 static int
13357 api_lisp_locator_set_dump (vat_main_t * vam)
13358 {
13359   vl_api_lisp_locator_set_dump_t *mp;
13360   unformat_input_t *input = vam->input;
13361   f64 timeout = ~0;
13362   u8 filter = 0;
13363
13364   /* Parse args required to build the message */
13365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (input, "local"))
13368         {
13369           filter = 1;
13370         }
13371       else if (unformat (input, "remote"))
13372         {
13373           filter = 2;
13374         }
13375       else
13376         {
13377           errmsg ("parse error '%U'", format_unformat_error, input);
13378           return -99;
13379         }
13380     }
13381
13382   if (!vam->json_output)
13383     {
13384       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13385     }
13386
13387   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13388
13389   mp->filter = filter;
13390
13391   /* send it... */
13392   S;
13393
13394   /* Use a control ping for synchronization */
13395   {
13396     vl_api_control_ping_t *mp;
13397     M (CONTROL_PING, control_ping);
13398     S;
13399   }
13400   /* Wait for a reply... */
13401   W;
13402
13403   /* NOTREACHED */
13404   return 0;
13405 }
13406
13407 static int
13408 api_lisp_eid_table_map_dump (vat_main_t * vam)
13409 {
13410   u8 is_l2 = 0;
13411   u8 mode_set = 0;
13412   unformat_input_t *input = vam->input;
13413   vl_api_lisp_eid_table_map_dump_t *mp;
13414   f64 timeout = ~0;
13415
13416   /* Parse args required to build the message */
13417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13418     {
13419       if (unformat (input, "l2"))
13420         {
13421           is_l2 = 1;
13422           mode_set = 1;
13423         }
13424       else if (unformat (input, "l3"))
13425         {
13426           is_l2 = 0;
13427           mode_set = 1;
13428         }
13429       else
13430         {
13431           errmsg ("parse error '%U'", format_unformat_error, input);
13432           return -99;
13433         }
13434     }
13435
13436   if (!mode_set)
13437     {
13438       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13439       return -99;
13440     }
13441
13442   if (!vam->json_output)
13443     {
13444       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13445     }
13446
13447   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13448   mp->is_l2 = is_l2;
13449
13450   /* send it... */
13451   S;
13452
13453   /* Use a control ping for synchronization */
13454   {
13455     vl_api_control_ping_t *mp;
13456     M (CONTROL_PING, control_ping);
13457     S;
13458   }
13459   /* Wait for a reply... */
13460   W;
13461
13462   /* NOTREACHED */
13463   return 0;
13464 }
13465
13466 static int
13467 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13468 {
13469   vl_api_lisp_eid_table_vni_dump_t *mp;
13470   f64 timeout = ~0;
13471
13472   if (!vam->json_output)
13473     {
13474       fformat (vam->ofp, "VNI\n");
13475     }
13476
13477   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13478
13479   /* send it... */
13480   S;
13481
13482   /* Use a control ping for synchronization */
13483   {
13484     vl_api_control_ping_t *mp;
13485     M (CONTROL_PING, control_ping);
13486     S;
13487   }
13488   /* Wait for a reply... */
13489   W;
13490
13491   /* NOTREACHED */
13492   return 0;
13493 }
13494
13495 static int
13496 api_lisp_eid_table_dump (vat_main_t * vam)
13497 {
13498   unformat_input_t *i = vam->input;
13499   vl_api_lisp_eid_table_dump_t *mp;
13500   f64 timeout = ~0;
13501   struct in_addr ip4;
13502   struct in6_addr ip6;
13503   u8 mac[6];
13504   u8 eid_type = ~0, eid_set = 0;
13505   u32 prefix_length = ~0, t, vni = 0;
13506   u8 filter = 0;
13507
13508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509     {
13510       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13511         {
13512           eid_set = 1;
13513           eid_type = 0;
13514           prefix_length = t;
13515         }
13516       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13517         {
13518           eid_set = 1;
13519           eid_type = 1;
13520           prefix_length = t;
13521         }
13522       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13523         {
13524           eid_set = 1;
13525           eid_type = 2;
13526         }
13527       else if (unformat (i, "vni %d", &t))
13528         {
13529           vni = t;
13530         }
13531       else if (unformat (i, "local"))
13532         {
13533           filter = 1;
13534         }
13535       else if (unformat (i, "remote"))
13536         {
13537           filter = 2;
13538         }
13539       else
13540         {
13541           errmsg ("parse error '%U'", format_unformat_error, i);
13542           return -99;
13543         }
13544     }
13545
13546   if (!vam->json_output)
13547     {
13548       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13549                "ls_index", "ttl", "authoritative");
13550     }
13551
13552   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13553
13554   mp->filter = filter;
13555   if (eid_set)
13556     {
13557       mp->eid_set = 1;
13558       mp->vni = htonl (vni);
13559       mp->eid_type = eid_type;
13560       switch (eid_type)
13561         {
13562         case 0:
13563           mp->prefix_length = prefix_length;
13564           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13565           break;
13566         case 1:
13567           mp->prefix_length = prefix_length;
13568           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13569           break;
13570         case 2:
13571           clib_memcpy (mp->eid, mac, sizeof (mac));
13572           break;
13573         default:
13574           errmsg ("unknown EID type %d!", eid_type);
13575           return -99;
13576         }
13577     }
13578
13579   /* send it... */
13580   S;
13581
13582   /* Use a control ping for synchronization */
13583   {
13584     vl_api_control_ping_t *mp;
13585     M (CONTROL_PING, control_ping);
13586     S;
13587   }
13588
13589   /* Wait for a reply... */
13590   W;
13591
13592   /* NOTREACHED */
13593   return 0;
13594 }
13595
13596 static int
13597 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13598 {
13599   vl_api_lisp_gpe_tunnel_dump_t *mp;
13600   f64 timeout = ~0;
13601
13602   if (!vam->json_output)
13603     {
13604       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13605                "%=16s%=16s%=16s%=16s%=16s\n",
13606                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13607                "Decap next", "Lisp version", "Flags", "Next protocol",
13608                "ver_res", "res", "iid");
13609     }
13610
13611   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13612   /* send it... */
13613   S;
13614
13615   /* Use a control ping for synchronization */
13616   {
13617     vl_api_control_ping_t *mp;
13618     M (CONTROL_PING, control_ping);
13619     S;
13620   }
13621   /* Wait for a reply... */
13622   W;
13623
13624   /* NOTREACHED */
13625   return 0;
13626 }
13627
13628 static int
13629 api_lisp_map_resolver_dump (vat_main_t * vam)
13630 {
13631   vl_api_lisp_map_resolver_dump_t *mp;
13632   f64 timeout = ~0;
13633
13634   if (!vam->json_output)
13635     {
13636       fformat (vam->ofp, "%=20s\n", "Map resolver");
13637     }
13638
13639   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13640   /* send it... */
13641   S;
13642
13643   /* Use a control ping for synchronization */
13644   {
13645     vl_api_control_ping_t *mp;
13646     M (CONTROL_PING, control_ping);
13647     S;
13648   }
13649   /* Wait for a reply... */
13650   W;
13651
13652   /* NOTREACHED */
13653   return 0;
13654 }
13655
13656 static int
13657 api_show_lisp_status (vat_main_t * vam)
13658 {
13659   vl_api_show_lisp_status_t *mp;
13660   f64 timeout = ~0;
13661
13662   if (!vam->json_output)
13663     {
13664       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13665     }
13666
13667   M (SHOW_LISP_STATUS, show_lisp_status);
13668   /* send it... */
13669   S;
13670   /* Wait for a reply... */
13671   W;
13672
13673   /* NOTREACHED */
13674   return 0;
13675 }
13676
13677 static int
13678 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13679 {
13680   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13681   f64 timeout = ~0;
13682
13683   if (!vam->json_output)
13684     {
13685       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13686     }
13687
13688   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13689   /* send it... */
13690   S;
13691   /* Wait for a reply... */
13692   W;
13693
13694   /* NOTREACHED */
13695   return 0;
13696 }
13697
13698 static int
13699 api_af_packet_create (vat_main_t * vam)
13700 {
13701   unformat_input_t *i = vam->input;
13702   vl_api_af_packet_create_t *mp;
13703   f64 timeout;
13704   u8 *host_if_name = 0;
13705   u8 hw_addr[6];
13706   u8 random_hw_addr = 1;
13707
13708   memset (hw_addr, 0, sizeof (hw_addr));
13709
13710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (i, "name %s", &host_if_name))
13713         vec_add1 (host_if_name, 0);
13714       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13715         random_hw_addr = 0;
13716       else
13717         break;
13718     }
13719
13720   if (!vec_len (host_if_name))
13721     {
13722       errmsg ("host-interface name must be specified");
13723       return -99;
13724     }
13725
13726   if (vec_len (host_if_name) > 64)
13727     {
13728       errmsg ("host-interface name too long");
13729       return -99;
13730     }
13731
13732   M (AF_PACKET_CREATE, af_packet_create);
13733
13734   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13735   clib_memcpy (mp->hw_addr, hw_addr, 6);
13736   mp->use_random_hw_addr = random_hw_addr;
13737   vec_free (host_if_name);
13738
13739   S;
13740   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13741   /* NOTREACHED */
13742   return 0;
13743 }
13744
13745 static int
13746 api_af_packet_delete (vat_main_t * vam)
13747 {
13748   unformat_input_t *i = vam->input;
13749   vl_api_af_packet_delete_t *mp;
13750   f64 timeout;
13751   u8 *host_if_name = 0;
13752
13753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13754     {
13755       if (unformat (i, "name %s", &host_if_name))
13756         vec_add1 (host_if_name, 0);
13757       else
13758         break;
13759     }
13760
13761   if (!vec_len (host_if_name))
13762     {
13763       errmsg ("host-interface name must be specified");
13764       return -99;
13765     }
13766
13767   if (vec_len (host_if_name) > 64)
13768     {
13769       errmsg ("host-interface name too long");
13770       return -99;
13771     }
13772
13773   M (AF_PACKET_DELETE, af_packet_delete);
13774
13775   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13776   vec_free (host_if_name);
13777
13778   S;
13779   W;
13780   /* NOTREACHED */
13781   return 0;
13782 }
13783
13784 static int
13785 api_policer_add_del (vat_main_t * vam)
13786 {
13787   unformat_input_t *i = vam->input;
13788   vl_api_policer_add_del_t *mp;
13789   f64 timeout;
13790   u8 is_add = 1;
13791   u8 *name = 0;
13792   u32 cir = 0;
13793   u32 eir = 0;
13794   u64 cb = 0;
13795   u64 eb = 0;
13796   u8 rate_type = 0;
13797   u8 round_type = 0;
13798   u8 type = 0;
13799   u8 color_aware = 0;
13800   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13801
13802   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13803   conform_action.dscp = 0;
13804   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13805   exceed_action.dscp = 0;
13806   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13807   violate_action.dscp = 0;
13808
13809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (i, "del"))
13812         is_add = 0;
13813       else if (unformat (i, "name %s", &name))
13814         vec_add1 (name, 0);
13815       else if (unformat (i, "cir %u", &cir))
13816         ;
13817       else if (unformat (i, "eir %u", &eir))
13818         ;
13819       else if (unformat (i, "cb %u", &cb))
13820         ;
13821       else if (unformat (i, "eb %u", &eb))
13822         ;
13823       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13824                          &rate_type))
13825         ;
13826       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13827                          &round_type))
13828         ;
13829       else if (unformat (i, "type %U", unformat_policer_type, &type))
13830         ;
13831       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13832                          &conform_action))
13833         ;
13834       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13835                          &exceed_action))
13836         ;
13837       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13838                          &violate_action))
13839         ;
13840       else if (unformat (i, "color-aware"))
13841         color_aware = 1;
13842       else
13843         break;
13844     }
13845
13846   if (!vec_len (name))
13847     {
13848       errmsg ("policer name must be specified");
13849       return -99;
13850     }
13851
13852   if (vec_len (name) > 64)
13853     {
13854       errmsg ("policer name too long");
13855       return -99;
13856     }
13857
13858   M (POLICER_ADD_DEL, policer_add_del);
13859
13860   clib_memcpy (mp->name, name, vec_len (name));
13861   vec_free (name);
13862   mp->is_add = is_add;
13863   mp->cir = cir;
13864   mp->eir = eir;
13865   mp->cb = cb;
13866   mp->eb = eb;
13867   mp->rate_type = rate_type;
13868   mp->round_type = round_type;
13869   mp->type = type;
13870   mp->conform_action_type = conform_action.action_type;
13871   mp->conform_dscp = conform_action.dscp;
13872   mp->exceed_action_type = exceed_action.action_type;
13873   mp->exceed_dscp = exceed_action.dscp;
13874   mp->violate_action_type = violate_action.action_type;
13875   mp->violate_dscp = violate_action.dscp;
13876   mp->color_aware = color_aware;
13877
13878   S;
13879   W;
13880   /* NOTREACHED */
13881   return 0;
13882 }
13883
13884 static int
13885 api_policer_dump (vat_main_t * vam)
13886 {
13887   unformat_input_t *i = vam->input;
13888   vl_api_policer_dump_t *mp;
13889   f64 timeout = ~0;
13890   u8 *match_name = 0;
13891   u8 match_name_valid = 0;
13892
13893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13894     {
13895       if (unformat (i, "name %s", &match_name))
13896         {
13897           vec_add1 (match_name, 0);
13898           match_name_valid = 1;
13899         }
13900       else
13901         break;
13902     }
13903
13904   M (POLICER_DUMP, policer_dump);
13905   mp->match_name_valid = match_name_valid;
13906   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13907   vec_free (match_name);
13908   /* send it... */
13909   S;
13910
13911   /* Use a control ping for synchronization */
13912   {
13913     vl_api_control_ping_t *mp;
13914     M (CONTROL_PING, control_ping);
13915     S;
13916   }
13917   /* Wait for a reply... */
13918   W;
13919
13920   /* NOTREACHED */
13921   return 0;
13922 }
13923
13924 static int
13925 api_policer_classify_set_interface (vat_main_t * vam)
13926 {
13927   unformat_input_t *i = vam->input;
13928   vl_api_policer_classify_set_interface_t *mp;
13929   f64 timeout;
13930   u32 sw_if_index;
13931   int sw_if_index_set;
13932   u32 ip4_table_index = ~0;
13933   u32 ip6_table_index = ~0;
13934   u32 l2_table_index = ~0;
13935   u8 is_add = 1;
13936
13937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13938     {
13939       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13940         sw_if_index_set = 1;
13941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13942         sw_if_index_set = 1;
13943       else if (unformat (i, "del"))
13944         is_add = 0;
13945       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13946         ;
13947       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13948         ;
13949       else if (unformat (i, "l2-table %d", &l2_table_index))
13950         ;
13951       else
13952         {
13953           clib_warning ("parse error '%U'", format_unformat_error, i);
13954           return -99;
13955         }
13956     }
13957
13958   if (sw_if_index_set == 0)
13959     {
13960       errmsg ("missing interface name or sw_if_index\n");
13961       return -99;
13962     }
13963
13964   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13965
13966   mp->sw_if_index = ntohl (sw_if_index);
13967   mp->ip4_table_index = ntohl (ip4_table_index);
13968   mp->ip6_table_index = ntohl (ip6_table_index);
13969   mp->l2_table_index = ntohl (l2_table_index);
13970   mp->is_add = is_add;
13971
13972   S;
13973   W;
13974   /* NOTREACHED */
13975   return 0;
13976 }
13977
13978 static int
13979 api_policer_classify_dump (vat_main_t * vam)
13980 {
13981   unformat_input_t *i = vam->input;
13982   vl_api_policer_classify_dump_t *mp;
13983   f64 timeout = ~0;
13984   u8 type = POLICER_CLASSIFY_N_TABLES;
13985
13986   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13987     ;
13988   else
13989     {
13990       errmsg ("classify table type must be specified\n");
13991       return -99;
13992     }
13993
13994   if (!vam->json_output)
13995     {
13996       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13997     }
13998
13999   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14000   mp->type = type;
14001   /* send it... */
14002   S;
14003
14004   /* Use a control ping for synchronization */
14005   {
14006     vl_api_control_ping_t *mp;
14007     M (CONTROL_PING, control_ping);
14008     S;
14009   }
14010   /* Wait for a reply... */
14011   W;
14012
14013   /* NOTREACHED */
14014   return 0;
14015 }
14016
14017 static int
14018 api_netmap_create (vat_main_t * vam)
14019 {
14020   unformat_input_t *i = vam->input;
14021   vl_api_netmap_create_t *mp;
14022   f64 timeout;
14023   u8 *if_name = 0;
14024   u8 hw_addr[6];
14025   u8 random_hw_addr = 1;
14026   u8 is_pipe = 0;
14027   u8 is_master = 0;
14028
14029   memset (hw_addr, 0, sizeof (hw_addr));
14030
14031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14032     {
14033       if (unformat (i, "name %s", &if_name))
14034         vec_add1 (if_name, 0);
14035       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14036         random_hw_addr = 0;
14037       else if (unformat (i, "pipe"))
14038         is_pipe = 1;
14039       else if (unformat (i, "master"))
14040         is_master = 1;
14041       else if (unformat (i, "slave"))
14042         is_master = 0;
14043       else
14044         break;
14045     }
14046
14047   if (!vec_len (if_name))
14048     {
14049       errmsg ("interface name must be specified");
14050       return -99;
14051     }
14052
14053   if (vec_len (if_name) > 64)
14054     {
14055       errmsg ("interface name too long");
14056       return -99;
14057     }
14058
14059   M (NETMAP_CREATE, netmap_create);
14060
14061   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14062   clib_memcpy (mp->hw_addr, hw_addr, 6);
14063   mp->use_random_hw_addr = random_hw_addr;
14064   mp->is_pipe = is_pipe;
14065   mp->is_master = is_master;
14066   vec_free (if_name);
14067
14068   S;
14069   W;
14070   /* NOTREACHED */
14071   return 0;
14072 }
14073
14074 static int
14075 api_netmap_delete (vat_main_t * vam)
14076 {
14077   unformat_input_t *i = vam->input;
14078   vl_api_netmap_delete_t *mp;
14079   f64 timeout;
14080   u8 *if_name = 0;
14081
14082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14083     {
14084       if (unformat (i, "name %s", &if_name))
14085         vec_add1 (if_name, 0);
14086       else
14087         break;
14088     }
14089
14090   if (!vec_len (if_name))
14091     {
14092       errmsg ("interface name must be specified");
14093       return -99;
14094     }
14095
14096   if (vec_len (if_name) > 64)
14097     {
14098       errmsg ("interface name too long");
14099       return -99;
14100     }
14101
14102   M (NETMAP_DELETE, netmap_delete);
14103
14104   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14105   vec_free (if_name);
14106
14107   S;
14108   W;
14109   /* NOTREACHED */
14110   return 0;
14111 }
14112
14113 static void vl_api_mpls_gre_tunnel_details_t_handler
14114   (vl_api_mpls_gre_tunnel_details_t * mp)
14115 {
14116   vat_main_t *vam = &vat_main;
14117   i32 i;
14118   i32 len = ntohl (mp->nlabels);
14119
14120   if (mp->l2_only == 0)
14121     {
14122       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14123                ntohl (mp->tunnel_index),
14124                format_ip4_address, &mp->tunnel_src,
14125                format_ip4_address, &mp->tunnel_dst,
14126                format_ip4_address, &mp->intfc_address,
14127                ntohl (mp->mask_width));
14128       for (i = 0; i < len; i++)
14129         {
14130           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14131         }
14132       fformat (vam->ofp, "\n");
14133       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14134                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14135     }
14136   else
14137     {
14138       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14139                ntohl (mp->tunnel_index),
14140                format_ip4_address, &mp->tunnel_src,
14141                format_ip4_address, &mp->tunnel_dst,
14142                format_ip4_address, &mp->intfc_address);
14143       for (i = 0; i < len; i++)
14144         {
14145           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14146         }
14147       fformat (vam->ofp, "\n");
14148       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14149                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14150     }
14151 }
14152
14153 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14154   (vl_api_mpls_gre_tunnel_details_t * mp)
14155 {
14156   vat_main_t *vam = &vat_main;
14157   vat_json_node_t *node = NULL;
14158   struct in_addr ip4;
14159   i32 i;
14160   i32 len = ntohl (mp->nlabels);
14161
14162   if (VAT_JSON_ARRAY != vam->json_tree.type)
14163     {
14164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14165       vat_json_init_array (&vam->json_tree);
14166     }
14167   node = vat_json_array_add (&vam->json_tree);
14168
14169   vat_json_init_object (node);
14170   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14171   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14172   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14173   vat_json_object_add_uint (node, "inner_fib_index",
14174                             ntohl (mp->inner_fib_index));
14175   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14176   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14177   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14178   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14179   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14180   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14181   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14182   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14183   vat_json_object_add_uint (node, "outer_fib_index",
14184                             ntohl (mp->outer_fib_index));
14185   vat_json_object_add_uint (node, "label_count", len);
14186   for (i = 0; i < len; i++)
14187     {
14188       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14189     }
14190 }
14191
14192 static int
14193 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14194 {
14195   vl_api_mpls_gre_tunnel_dump_t *mp;
14196   f64 timeout;
14197   i32 index = -1;
14198
14199   /* Parse args required to build the message */
14200   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14201     {
14202       if (!unformat (vam->input, "tunnel_index %d", &index))
14203         {
14204           index = -1;
14205           break;
14206         }
14207     }
14208
14209   fformat (vam->ofp, "  tunnel_index %d\n", index);
14210
14211   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14212   mp->tunnel_index = htonl (index);
14213   S;
14214
14215   /* Use a control ping for synchronization */
14216   {
14217     vl_api_control_ping_t *mp;
14218     M (CONTROL_PING, control_ping);
14219     S;
14220   }
14221   W;
14222 }
14223
14224 static void vl_api_mpls_eth_tunnel_details_t_handler
14225   (vl_api_mpls_eth_tunnel_details_t * mp)
14226 {
14227   vat_main_t *vam = &vat_main;
14228   i32 i;
14229   i32 len = ntohl (mp->nlabels);
14230
14231   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14232            ntohl (mp->tunnel_index),
14233            format_ethernet_address, &mp->tunnel_dst_mac,
14234            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14235   for (i = 0; i < len; i++)
14236     {
14237       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14238     }
14239   fformat (vam->ofp, "\n");
14240   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14241            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14242 }
14243
14244 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14245   (vl_api_mpls_eth_tunnel_details_t * mp)
14246 {
14247   vat_main_t *vam = &vat_main;
14248   vat_json_node_t *node = NULL;
14249   struct in_addr ip4;
14250   i32 i;
14251   i32 len = ntohl (mp->nlabels);
14252
14253   if (VAT_JSON_ARRAY != vam->json_tree.type)
14254     {
14255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14256       vat_json_init_array (&vam->json_tree);
14257     }
14258   node = vat_json_array_add (&vam->json_tree);
14259
14260   vat_json_init_object (node);
14261   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14262   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14263   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14264   vat_json_object_add_uint (node, "inner_fib_index",
14265                             ntohl (mp->inner_fib_index));
14266   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14267   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14268   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14269   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14270   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14271                                    format (0, "%U", format_ethernet_address,
14272                                            &mp->tunnel_dst_mac));
14273   vat_json_object_add_uint (node, "tx_sw_if_index",
14274                             ntohl (mp->tx_sw_if_index));
14275   vat_json_object_add_uint (node, "label_count", len);
14276   for (i = 0; i < len; i++)
14277     {
14278       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14279     }
14280 }
14281
14282 static int
14283 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14284 {
14285   vl_api_mpls_eth_tunnel_dump_t *mp;
14286   f64 timeout;
14287   i32 index = -1;
14288
14289   /* Parse args required to build the message */
14290   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (!unformat (vam->input, "tunnel_index %d", &index))
14293         {
14294           index = -1;
14295           break;
14296         }
14297     }
14298
14299   fformat (vam->ofp, "  tunnel_index %d\n", index);
14300
14301   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14302   mp->tunnel_index = htonl (index);
14303   S;
14304
14305   /* Use a control ping for synchronization */
14306   {
14307     vl_api_control_ping_t *mp;
14308     M (CONTROL_PING, control_ping);
14309     S;
14310   }
14311   W;
14312 }
14313
14314 static void vl_api_mpls_fib_encap_details_t_handler
14315   (vl_api_mpls_fib_encap_details_t * mp)
14316 {
14317   vat_main_t *vam = &vat_main;
14318   i32 i;
14319   i32 len = ntohl (mp->nlabels);
14320
14321   fformat (vam->ofp, "table %d, dest %U, label ",
14322            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14323   for (i = 0; i < len; i++)
14324     {
14325       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14326     }
14327   fformat (vam->ofp, "\n");
14328 }
14329
14330 static void vl_api_mpls_fib_encap_details_t_handler_json
14331   (vl_api_mpls_fib_encap_details_t * mp)
14332 {
14333   vat_main_t *vam = &vat_main;
14334   vat_json_node_t *node = NULL;
14335   i32 i;
14336   i32 len = ntohl (mp->nlabels);
14337   struct in_addr ip4;
14338
14339   if (VAT_JSON_ARRAY != vam->json_tree.type)
14340     {
14341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14342       vat_json_init_array (&vam->json_tree);
14343     }
14344   node = vat_json_array_add (&vam->json_tree);
14345
14346   vat_json_init_object (node);
14347   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14348   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14349   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14350   vat_json_object_add_ip4 (node, "dest", ip4);
14351   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14352   vat_json_object_add_uint (node, "label_count", len);
14353   for (i = 0; i < len; i++)
14354     {
14355       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14356     }
14357 }
14358
14359 static int
14360 api_mpls_fib_encap_dump (vat_main_t * vam)
14361 {
14362   vl_api_mpls_fib_encap_dump_t *mp;
14363   f64 timeout;
14364
14365   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14366   S;
14367
14368   /* Use a control ping for synchronization */
14369   {
14370     vl_api_control_ping_t *mp;
14371     M (CONTROL_PING, control_ping);
14372     S;
14373   }
14374   W;
14375 }
14376
14377 static void vl_api_mpls_fib_decap_details_t_handler
14378   (vl_api_mpls_fib_decap_details_t * mp)
14379 {
14380   vat_main_t *vam = &vat_main;
14381
14382   fformat (vam->ofp,
14383            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14384            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14385            ntohl (mp->label), ntohl (mp->s_bit));
14386 }
14387
14388 static void vl_api_mpls_fib_decap_details_t_handler_json
14389   (vl_api_mpls_fib_decap_details_t * mp)
14390 {
14391   vat_main_t *vam = &vat_main;
14392   vat_json_node_t *node = NULL;
14393   struct in_addr ip4;
14394
14395   if (VAT_JSON_ARRAY != vam->json_tree.type)
14396     {
14397       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14398       vat_json_init_array (&vam->json_tree);
14399     }
14400   node = vat_json_array_add (&vam->json_tree);
14401
14402   vat_json_init_object (node);
14403   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14404   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14405   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14406   vat_json_object_add_ip4 (node, "dest", ip4);
14407   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14408   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14409   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14410   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14411   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14412 }
14413
14414 static int
14415 api_mpls_fib_decap_dump (vat_main_t * vam)
14416 {
14417   vl_api_mpls_fib_decap_dump_t *mp;
14418   f64 timeout;
14419
14420   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14421   S;
14422
14423   /* Use a control ping for synchronization */
14424   {
14425     vl_api_control_ping_t *mp;
14426     M (CONTROL_PING, control_ping);
14427     S;
14428   }
14429   W;
14430 }
14431
14432 int
14433 api_classify_table_ids (vat_main_t * vam)
14434 {
14435   vl_api_classify_table_ids_t *mp;
14436   f64 timeout;
14437
14438   /* Construct the API message */
14439   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14440   mp->context = 0;
14441
14442   S;
14443   W;
14444   /* NOTREACHED */
14445   return 0;
14446 }
14447
14448 int
14449 api_classify_table_by_interface (vat_main_t * vam)
14450 {
14451   unformat_input_t *input = vam->input;
14452   vl_api_classify_table_by_interface_t *mp;
14453   f64 timeout;
14454
14455   u32 sw_if_index = ~0;
14456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14457     {
14458       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14459         ;
14460       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14461         ;
14462       else
14463         break;
14464     }
14465   if (sw_if_index == ~0)
14466     {
14467       errmsg ("missing interface name or sw_if_index\n");
14468       return -99;
14469     }
14470
14471   /* Construct the API message */
14472   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14473   mp->context = 0;
14474   mp->sw_if_index = ntohl (sw_if_index);
14475
14476   S;
14477   W;
14478   /* NOTREACHED */
14479   return 0;
14480 }
14481
14482 int
14483 api_classify_table_info (vat_main_t * vam)
14484 {
14485   unformat_input_t *input = vam->input;
14486   vl_api_classify_table_info_t *mp;
14487   f64 timeout;
14488
14489   u32 table_id = ~0;
14490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14491     {
14492       if (unformat (input, "table_id %d", &table_id))
14493         ;
14494       else
14495         break;
14496     }
14497   if (table_id == ~0)
14498     {
14499       errmsg ("missing table id\n");
14500       return -99;
14501     }
14502
14503   /* Construct the API message */
14504   M (CLASSIFY_TABLE_INFO, classify_table_info);
14505   mp->context = 0;
14506   mp->table_id = ntohl (table_id);
14507
14508   S;
14509   W;
14510   /* NOTREACHED */
14511   return 0;
14512 }
14513
14514 int
14515 api_classify_session_dump (vat_main_t * vam)
14516 {
14517   unformat_input_t *input = vam->input;
14518   vl_api_classify_session_dump_t *mp;
14519   f64 timeout;
14520
14521   u32 table_id = ~0;
14522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (input, "table_id %d", &table_id))
14525         ;
14526       else
14527         break;
14528     }
14529   if (table_id == ~0)
14530     {
14531       errmsg ("missing table id\n");
14532       return -99;
14533     }
14534
14535   /* Construct the API message */
14536   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14537   mp->context = 0;
14538   mp->table_id = ntohl (table_id);
14539   S;
14540
14541   /* Use a control ping for synchronization */
14542   {
14543     vl_api_control_ping_t *mp;
14544     M (CONTROL_PING, control_ping);
14545     S;
14546   }
14547   W;
14548   /* NOTREACHED */
14549   return 0;
14550 }
14551
14552 static void
14553 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14554 {
14555   vat_main_t *vam = &vat_main;
14556
14557   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14558            "src_address %U, vrf_id %d, path_mtu %u, "
14559            "template_interval %u, udp_checksum %d\n",
14560            format_ip4_address, mp->collector_address,
14561            ntohs (mp->collector_port),
14562            format_ip4_address, mp->src_address,
14563            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14564            ntohl (mp->template_interval), mp->udp_checksum);
14565
14566   vam->retval = 0;
14567   vam->result_ready = 1;
14568 }
14569
14570 static void
14571   vl_api_ipfix_exporter_details_t_handler_json
14572   (vl_api_ipfix_exporter_details_t * mp)
14573 {
14574   vat_main_t *vam = &vat_main;
14575   vat_json_node_t node;
14576   struct in_addr collector_address;
14577   struct in_addr src_address;
14578
14579   vat_json_init_object (&node);
14580   clib_memcpy (&collector_address, &mp->collector_address,
14581                sizeof (collector_address));
14582   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14583   vat_json_object_add_uint (&node, "collector_port",
14584                             ntohs (mp->collector_port));
14585   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14586   vat_json_object_add_ip4 (&node, "src_address", src_address);
14587   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14588   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14589   vat_json_object_add_uint (&node, "template_interval",
14590                             ntohl (mp->template_interval));
14591   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14592
14593   vat_json_print (vam->ofp, &node);
14594   vat_json_free (&node);
14595   vam->retval = 0;
14596   vam->result_ready = 1;
14597 }
14598
14599 int
14600 api_ipfix_exporter_dump (vat_main_t * vam)
14601 {
14602   vl_api_ipfix_exporter_dump_t *mp;
14603   f64 timeout;
14604
14605   /* Construct the API message */
14606   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14607   mp->context = 0;
14608
14609   S;
14610   W;
14611   /* NOTREACHED */
14612   return 0;
14613 }
14614
14615 static int
14616 api_ipfix_classify_stream_dump (vat_main_t * vam)
14617 {
14618   vl_api_ipfix_classify_stream_dump_t *mp;
14619   f64 timeout;
14620
14621   /* Construct the API message */
14622   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14623   mp->context = 0;
14624
14625   S;
14626   W;
14627   /* NOTREACHED */
14628   return 0;
14629 }
14630
14631 static void
14632   vl_api_ipfix_classify_stream_details_t_handler
14633   (vl_api_ipfix_classify_stream_details_t * mp)
14634 {
14635   vat_main_t *vam = &vat_main;
14636   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14637            ntohl (mp->domain_id), ntohs (mp->src_port));
14638   vam->retval = 0;
14639   vam->result_ready = 1;
14640 }
14641
14642 static void
14643   vl_api_ipfix_classify_stream_details_t_handler_json
14644   (vl_api_ipfix_classify_stream_details_t * mp)
14645 {
14646   vat_main_t *vam = &vat_main;
14647   vat_json_node_t node;
14648
14649   vat_json_init_object (&node);
14650   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14651   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14652
14653   vat_json_print (vam->ofp, &node);
14654   vat_json_free (&node);
14655   vam->retval = 0;
14656   vam->result_ready = 1;
14657 }
14658
14659 static int
14660 api_ipfix_classify_table_dump (vat_main_t * vam)
14661 {
14662   vl_api_ipfix_classify_table_dump_t *mp;
14663   f64 timeout;
14664
14665   if (!vam->json_output)
14666     {
14667       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14668                "transport_protocol");
14669     }
14670
14671   /* Construct the API message */
14672   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14673
14674   /* send it... */
14675   S;
14676
14677   /* Use a control ping for synchronization */
14678   {
14679     vl_api_control_ping_t *mp;
14680     M (CONTROL_PING, control_ping);
14681     S;
14682   }
14683   W;
14684 }
14685
14686 static void
14687   vl_api_ipfix_classify_table_details_t_handler
14688   (vl_api_ipfix_classify_table_details_t * mp)
14689 {
14690   vat_main_t *vam = &vat_main;
14691   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14692            mp->transport_protocol);
14693 }
14694
14695 static void
14696   vl_api_ipfix_classify_table_details_t_handler_json
14697   (vl_api_ipfix_classify_table_details_t * mp)
14698 {
14699   vat_json_node_t *node = NULL;
14700   vat_main_t *vam = &vat_main;
14701
14702   if (VAT_JSON_ARRAY != vam->json_tree.type)
14703     {
14704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14705       vat_json_init_array (&vam->json_tree);
14706     }
14707
14708   node = vat_json_array_add (&vam->json_tree);
14709   vat_json_init_object (node);
14710
14711   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14712   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14713   vat_json_object_add_uint (node, "transport_protocol",
14714                             mp->transport_protocol);
14715 }
14716
14717 int
14718 api_pg_create_interface (vat_main_t * vam)
14719 {
14720   unformat_input_t *input = vam->input;
14721   vl_api_pg_create_interface_t *mp;
14722   f64 timeout;
14723
14724   u32 if_id = ~0;
14725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14726     {
14727       if (unformat (input, "if_id %d", &if_id))
14728         ;
14729       else
14730         break;
14731     }
14732   if (if_id == ~0)
14733     {
14734       errmsg ("missing pg interface index\n");
14735       return -99;
14736     }
14737
14738   /* Construct the API message */
14739   M (PG_CREATE_INTERFACE, pg_create_interface);
14740   mp->context = 0;
14741   mp->interface_id = ntohl (if_id);
14742
14743   S;
14744   W;
14745   /* NOTREACHED */
14746   return 0;
14747 }
14748
14749 int
14750 api_pg_capture (vat_main_t * vam)
14751 {
14752   unformat_input_t *input = vam->input;
14753   vl_api_pg_capture_t *mp;
14754   f64 timeout;
14755
14756   u32 if_id = ~0;
14757   u8 enable = 1;
14758   u32 count = 1;
14759   u8 pcap_file_set = 0;
14760   u8 *pcap_file = 0;
14761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14762     {
14763       if (unformat (input, "if_id %d", &if_id))
14764         ;
14765       else if (unformat (input, "pcap %s", &pcap_file))
14766         pcap_file_set = 1;
14767       else if (unformat (input, "count %d", &count))
14768         ;
14769       else if (unformat (input, "disable"))
14770         enable = 0;
14771       else
14772         break;
14773     }
14774   if (if_id == ~0)
14775     {
14776       errmsg ("missing pg interface index\n");
14777       return -99;
14778     }
14779   if (pcap_file_set > 0)
14780     {
14781       if (vec_len (pcap_file) > 255)
14782         {
14783           errmsg ("pcap file name is too long\n");
14784           return -99;
14785         }
14786     }
14787
14788   u32 name_len = vec_len (pcap_file);
14789   /* Construct the API message */
14790   M (PG_CAPTURE, pg_capture);
14791   mp->context = 0;
14792   mp->interface_id = ntohl (if_id);
14793   mp->is_enabled = enable;
14794   mp->count = ntohl (count);
14795   mp->pcap_name_length = ntohl (name_len);
14796   if (pcap_file_set != 0)
14797     {
14798       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14799     }
14800   vec_free (pcap_file);
14801
14802   S;
14803   W;
14804   /* NOTREACHED */
14805   return 0;
14806 }
14807
14808 int
14809 api_pg_enable_disable (vat_main_t * vam)
14810 {
14811   unformat_input_t *input = vam->input;
14812   vl_api_pg_enable_disable_t *mp;
14813   f64 timeout;
14814
14815   u8 enable = 1;
14816   u8 stream_name_set = 0;
14817   u8 *stream_name = 0;
14818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14819     {
14820       if (unformat (input, "stream %s", &stream_name))
14821         stream_name_set = 1;
14822       else if (unformat (input, "disable"))
14823         enable = 0;
14824       else
14825         break;
14826     }
14827
14828   if (stream_name_set > 0)
14829     {
14830       if (vec_len (stream_name) > 255)
14831         {
14832           errmsg ("stream name too long\n");
14833           return -99;
14834         }
14835     }
14836
14837   u32 name_len = vec_len (stream_name);
14838   /* Construct the API message */
14839   M (PG_ENABLE_DISABLE, pg_enable_disable);
14840   mp->context = 0;
14841   mp->is_enabled = enable;
14842   if (stream_name_set != 0)
14843     {
14844       mp->stream_name_length = ntohl (name_len);
14845       clib_memcpy (mp->stream_name, stream_name, name_len);
14846     }
14847   vec_free (stream_name);
14848
14849   S;
14850   W;
14851   /* NOTREACHED */
14852   return 0;
14853 }
14854
14855 int
14856 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14857 {
14858   unformat_input_t *input = vam->input;
14859   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14860   f64 timeout;
14861
14862   u16 *low_ports = 0;
14863   u16 *high_ports = 0;
14864   u16 this_low;
14865   u16 this_hi;
14866   ip4_address_t ip4_addr;
14867   ip6_address_t ip6_addr;
14868   u32 length;
14869   u32 tmp, tmp2;
14870   u8 prefix_set = 0;
14871   u32 vrf_id = ~0;
14872   u8 is_add = 1;
14873   u8 is_ipv6 = 0;
14874
14875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14876     {
14877       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14878         {
14879           prefix_set = 1;
14880         }
14881       else
14882         if (unformat
14883             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14884         {
14885           prefix_set = 1;
14886           is_ipv6 = 1;
14887         }
14888       else if (unformat (input, "vrf %d", &vrf_id))
14889         ;
14890       else if (unformat (input, "del"))
14891         is_add = 0;
14892       else if (unformat (input, "port %d", &tmp))
14893         {
14894           if (tmp == 0 || tmp > 65535)
14895             {
14896               errmsg ("port %d out of range", tmp);
14897               return -99;
14898             }
14899           this_low = tmp;
14900           this_hi = this_low + 1;
14901           vec_add1 (low_ports, this_low);
14902           vec_add1 (high_ports, this_hi);
14903         }
14904       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14905         {
14906           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14907             {
14908               errmsg ("incorrect range parameters\n");
14909               return -99;
14910             }
14911           this_low = tmp;
14912           /* Note: in debug CLI +1 is added to high before
14913              passing to real fn that does "the work"
14914              (ip_source_and_port_range_check_add_del).
14915              This fn is a wrapper around the binary API fn a
14916              control plane will call, which expects this increment
14917              to have occurred. Hence letting the binary API control
14918              plane fn do the increment for consistency between VAT
14919              and other control planes.
14920            */
14921           this_hi = tmp2;
14922           vec_add1 (low_ports, this_low);
14923           vec_add1 (high_ports, this_hi);
14924         }
14925       else
14926         break;
14927     }
14928
14929   if (prefix_set == 0)
14930     {
14931       errmsg ("<address>/<mask> not specified\n");
14932       return -99;
14933     }
14934
14935   if (vrf_id == ~0)
14936     {
14937       errmsg ("VRF ID required, not specified\n");
14938       return -99;
14939     }
14940
14941   if (vrf_id == 0)
14942     {
14943       errmsg
14944         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14945       return -99;
14946     }
14947
14948   if (vec_len (low_ports) == 0)
14949     {
14950       errmsg ("At least one port or port range required\n");
14951       return -99;
14952     }
14953
14954   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14955      ip_source_and_port_range_check_add_del);
14956
14957   mp->is_add = is_add;
14958
14959   if (is_ipv6)
14960     {
14961       mp->is_ipv6 = 1;
14962       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14963     }
14964   else
14965     {
14966       mp->is_ipv6 = 0;
14967       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14968     }
14969
14970   mp->mask_length = length;
14971   mp->number_of_ranges = vec_len (low_ports);
14972
14973   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14974   vec_free (low_ports);
14975
14976   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14977   vec_free (high_ports);
14978
14979   mp->vrf_id = ntohl (vrf_id);
14980
14981   S;
14982   W;
14983   /* NOTREACHED */
14984   return 0;
14985 }
14986
14987 int
14988 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14989 {
14990   unformat_input_t *input = vam->input;
14991   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14992   f64 timeout;
14993   u32 sw_if_index = ~0;
14994   int vrf_set = 0;
14995   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14996   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14997   u8 is_add = 1;
14998
14999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15000     {
15001       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15002         ;
15003       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15004         ;
15005       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15006         vrf_set = 1;
15007       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15008         vrf_set = 1;
15009       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15010         vrf_set = 1;
15011       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15012         vrf_set = 1;
15013       else if (unformat (input, "del"))
15014         is_add = 0;
15015       else
15016         break;
15017     }
15018
15019   if (sw_if_index == ~0)
15020     {
15021       errmsg ("Interface required but not specified\n");
15022       return -99;
15023     }
15024
15025   if (vrf_set == 0)
15026     {
15027       errmsg ("VRF ID required but not specified\n");
15028       return -99;
15029     }
15030
15031   if (tcp_out_vrf_id == 0
15032       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15033     {
15034       errmsg
15035         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15036       return -99;
15037     }
15038
15039   /* Construct the API message */
15040   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15041      ip_source_and_port_range_check_interface_add_del);
15042
15043   mp->sw_if_index = ntohl (sw_if_index);
15044   mp->is_add = is_add;
15045   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15046   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15047   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15048   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15049
15050   /* send it... */
15051   S;
15052
15053   /* Wait for a reply... */
15054   W;
15055 }
15056
15057 static int
15058 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15059 {
15060   unformat_input_t *i = vam->input;
15061   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15062   f64 timeout;
15063   u32 local_sa_id = 0;
15064   u32 remote_sa_id = 0;
15065   ip4_address_t src_address;
15066   ip4_address_t dst_address;
15067   u8 is_add = 1;
15068
15069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15070     {
15071       if (unformat (i, "local_sa %d", &local_sa_id))
15072         ;
15073       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15074         ;
15075       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15076         ;
15077       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15078         ;
15079       else if (unformat (i, "del"))
15080         is_add = 0;
15081       else
15082         {
15083           clib_warning ("parse error '%U'", format_unformat_error, i);
15084           return -99;
15085         }
15086     }
15087
15088   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15089
15090   mp->local_sa_id = ntohl (local_sa_id);
15091   mp->remote_sa_id = ntohl (remote_sa_id);
15092   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15093   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15094   mp->is_add = is_add;
15095
15096   S;
15097   W;
15098   /* NOTREACHED */
15099   return 0;
15100 }
15101
15102 static void vl_api_ipsec_gre_tunnel_details_t_handler
15103   (vl_api_ipsec_gre_tunnel_details_t * mp)
15104 {
15105   vat_main_t *vam = &vat_main;
15106
15107   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15108            ntohl (mp->sw_if_index),
15109            format_ip4_address, &mp->src_address,
15110            format_ip4_address, &mp->dst_address,
15111            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15112 }
15113
15114 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15115   (vl_api_ipsec_gre_tunnel_details_t * mp)
15116 {
15117   vat_main_t *vam = &vat_main;
15118   vat_json_node_t *node = NULL;
15119   struct in_addr ip4;
15120
15121   if (VAT_JSON_ARRAY != vam->json_tree.type)
15122     {
15123       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15124       vat_json_init_array (&vam->json_tree);
15125     }
15126   node = vat_json_array_add (&vam->json_tree);
15127
15128   vat_json_init_object (node);
15129   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15130   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15131   vat_json_object_add_ip4 (node, "src_address", ip4);
15132   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15133   vat_json_object_add_ip4 (node, "dst_address", ip4);
15134   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15135   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15136 }
15137
15138 static int
15139 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15140 {
15141   unformat_input_t *i = vam->input;
15142   vl_api_ipsec_gre_tunnel_dump_t *mp;
15143   f64 timeout;
15144   u32 sw_if_index;
15145   u8 sw_if_index_set = 0;
15146
15147   /* Parse args required to build the message */
15148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15149     {
15150       if (unformat (i, "sw_if_index %d", &sw_if_index))
15151         sw_if_index_set = 1;
15152       else
15153         break;
15154     }
15155
15156   if (sw_if_index_set == 0)
15157     {
15158       sw_if_index = ~0;
15159     }
15160
15161   if (!vam->json_output)
15162     {
15163       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15164                "sw_if_index", "src_address", "dst_address",
15165                "local_sa_id", "remote_sa_id");
15166     }
15167
15168   /* Get list of gre-tunnel interfaces */
15169   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15170
15171   mp->sw_if_index = htonl (sw_if_index);
15172
15173   S;
15174
15175   /* Use a control ping for synchronization */
15176   {
15177     vl_api_control_ping_t *mp;
15178     M (CONTROL_PING, control_ping);
15179     S;
15180   }
15181   W;
15182 }
15183
15184 static int
15185 api_delete_subif (vat_main_t * vam)
15186 {
15187   unformat_input_t *i = vam->input;
15188   vl_api_delete_subif_t *mp;
15189   f64 timeout;
15190   u32 sw_if_index = ~0;
15191
15192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15193     {
15194       if (unformat (i, "sw_if_index %d", &sw_if_index))
15195         ;
15196       else
15197         break;
15198     }
15199
15200   if (sw_if_index == ~0)
15201     {
15202       errmsg ("missing sw_if_index\n");
15203       return -99;
15204     }
15205
15206   /* Construct the API message */
15207   M (DELETE_SUBIF, delete_subif);
15208   mp->sw_if_index = ntohl (sw_if_index);
15209
15210   S;
15211   W;
15212 }
15213
15214 static int
15215 q_or_quit (vat_main_t * vam)
15216 {
15217   longjmp (vam->jump_buf, 1);
15218   return 0;                     /* not so much */
15219 }
15220
15221 static int
15222 q (vat_main_t * vam)
15223 {
15224   return q_or_quit (vam);
15225 }
15226
15227 static int
15228 quit (vat_main_t * vam)
15229 {
15230   return q_or_quit (vam);
15231 }
15232
15233 static int
15234 comment (vat_main_t * vam)
15235 {
15236   return 0;
15237 }
15238
15239 static int
15240 cmd_cmp (void *a1, void *a2)
15241 {
15242   u8 **c1 = a1;
15243   u8 **c2 = a2;
15244
15245   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15246 }
15247
15248 static int
15249 help (vat_main_t * vam)
15250 {
15251   u8 **cmds = 0;
15252   u8 *name = 0;
15253   hash_pair_t *p;
15254   unformat_input_t *i = vam->input;
15255   int j;
15256
15257   if (unformat (i, "%s", &name))
15258     {
15259       uword *hs;
15260
15261       vec_add1 (name, 0);
15262
15263       hs = hash_get_mem (vam->help_by_name, name);
15264       if (hs)
15265         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15266       else
15267         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15268       vec_free (name);
15269       return 0;
15270     }
15271
15272   fformat (vam->ofp, "Help is available for the following:\n");
15273
15274     /* *INDENT-OFF* */
15275     hash_foreach_pair (p, vam->function_by_name,
15276     ({
15277       vec_add1 (cmds, (u8 *)(p->key));
15278     }));
15279     /* *INDENT-ON* */
15280
15281   vec_sort_with_function (cmds, cmd_cmp);
15282
15283   for (j = 0; j < vec_len (cmds); j++)
15284     fformat (vam->ofp, "%s\n", cmds[j]);
15285
15286   vec_free (cmds);
15287   return 0;
15288 }
15289
15290 static int
15291 set (vat_main_t * vam)
15292 {
15293   u8 *name = 0, *value = 0;
15294   unformat_input_t *i = vam->input;
15295
15296   if (unformat (i, "%s", &name))
15297     {
15298       /* The input buffer is a vector, not a string. */
15299       value = vec_dup (i->buffer);
15300       vec_delete (value, i->index, 0);
15301       /* Almost certainly has a trailing newline */
15302       if (value[vec_len (value) - 1] == '\n')
15303         value[vec_len (value) - 1] = 0;
15304       /* Make sure it's a proper string, one way or the other */
15305       vec_add1 (value, 0);
15306       (void) clib_macro_set_value (&vam->macro_main,
15307                                    (char *) name, (char *) value);
15308     }
15309   else
15310     errmsg ("usage: set <name> <value>\n");
15311
15312   vec_free (name);
15313   vec_free (value);
15314   return 0;
15315 }
15316
15317 static int
15318 unset (vat_main_t * vam)
15319 {
15320   u8 *name = 0;
15321
15322   if (unformat (vam->input, "%s", &name))
15323     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15324       errmsg ("unset: %s wasn't set\n", name);
15325   vec_free (name);
15326   return 0;
15327 }
15328
15329 typedef struct
15330 {
15331   u8 *name;
15332   u8 *value;
15333 } macro_sort_t;
15334
15335
15336 static int
15337 macro_sort_cmp (void *a1, void *a2)
15338 {
15339   macro_sort_t *s1 = a1;
15340   macro_sort_t *s2 = a2;
15341
15342   return strcmp ((char *) (s1->name), (char *) (s2->name));
15343 }
15344
15345 static int
15346 dump_macro_table (vat_main_t * vam)
15347 {
15348   macro_sort_t *sort_me = 0, *sm;
15349   int i;
15350   hash_pair_t *p;
15351
15352     /* *INDENT-OFF* */
15353     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15354     ({
15355       vec_add2 (sort_me, sm, 1);
15356       sm->name = (u8 *)(p->key);
15357       sm->value = (u8 *) (p->value[0]);
15358     }));
15359     /* *INDENT-ON* */
15360
15361   vec_sort_with_function (sort_me, macro_sort_cmp);
15362
15363   if (vec_len (sort_me))
15364     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15365   else
15366     fformat (vam->ofp, "The macro table is empty...\n");
15367
15368   for (i = 0; i < vec_len (sort_me); i++)
15369     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15370   return 0;
15371 }
15372
15373 static int
15374 dump_node_table (vat_main_t * vam)
15375 {
15376   int i, j;
15377   vlib_node_t *node, *next_node;
15378
15379   if (vec_len (vam->graph_nodes) == 0)
15380     {
15381       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15382       return 0;
15383     }
15384
15385   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15386     {
15387       node = vam->graph_nodes[i];
15388       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15389       for (j = 0; j < vec_len (node->next_nodes); j++)
15390         {
15391           if (node->next_nodes[j] != ~0)
15392             {
15393               next_node = vam->graph_nodes[node->next_nodes[j]];
15394               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15395             }
15396         }
15397     }
15398   return 0;
15399 }
15400
15401 static int
15402 search_node_table (vat_main_t * vam)
15403 {
15404   unformat_input_t *line_input = vam->input;
15405   u8 *node_to_find;
15406   int j;
15407   vlib_node_t *node, *next_node;
15408   uword *p;
15409
15410   if (vam->graph_node_index_by_name == 0)
15411     {
15412       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15413       return 0;
15414     }
15415
15416   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15417     {
15418       if (unformat (line_input, "%s", &node_to_find))
15419         {
15420           vec_add1 (node_to_find, 0);
15421           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15422           if (p == 0)
15423             {
15424               fformat (vam->ofp, "%s not found...\n", node_to_find);
15425               goto out;
15426             }
15427           node = vam->graph_nodes[p[0]];
15428           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15429           for (j = 0; j < vec_len (node->next_nodes); j++)
15430             {
15431               if (node->next_nodes[j] != ~0)
15432                 {
15433                   next_node = vam->graph_nodes[node->next_nodes[j]];
15434                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15435                 }
15436             }
15437         }
15438
15439       else
15440         {
15441           clib_warning ("parse error '%U'", format_unformat_error,
15442                         line_input);
15443           return -99;
15444         }
15445
15446     out:
15447       vec_free (node_to_find);
15448
15449     }
15450
15451   return 0;
15452 }
15453
15454
15455 static int
15456 script (vat_main_t * vam)
15457 {
15458   u8 *s = 0;
15459   char *save_current_file;
15460   unformat_input_t save_input;
15461   jmp_buf save_jump_buf;
15462   u32 save_line_number;
15463
15464   FILE *new_fp, *save_ifp;
15465
15466   if (unformat (vam->input, "%s", &s))
15467     {
15468       new_fp = fopen ((char *) s, "r");
15469       if (new_fp == 0)
15470         {
15471           errmsg ("Couldn't open script file %s\n", s);
15472           vec_free (s);
15473           return -99;
15474         }
15475     }
15476   else
15477     {
15478       errmsg ("Missing script name\n");
15479       return -99;
15480     }
15481
15482   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15483   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15484   save_ifp = vam->ifp;
15485   save_line_number = vam->input_line_number;
15486   save_current_file = (char *) vam->current_file;
15487
15488   vam->input_line_number = 0;
15489   vam->ifp = new_fp;
15490   vam->current_file = s;
15491   do_one_file (vam);
15492
15493   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15494   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15495   vam->ifp = save_ifp;
15496   vam->input_line_number = save_line_number;
15497   vam->current_file = (u8 *) save_current_file;
15498   vec_free (s);
15499
15500   return 0;
15501 }
15502
15503 static int
15504 echo (vat_main_t * vam)
15505 {
15506   fformat (vam->ofp, "%v", vam->input->buffer);
15507   return 0;
15508 }
15509
15510 /* List of API message constructors, CLI names map to api_xxx */
15511 #define foreach_vpe_api_msg                                             \
15512 _(create_loopback,"[mac <mac-addr>]")                                   \
15513 _(sw_interface_dump,"")                                                 \
15514 _(sw_interface_set_flags,                                               \
15515   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15516 _(sw_interface_add_del_address,                                         \
15517   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15518 _(sw_interface_set_table,                                               \
15519   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15520 _(sw_interface_set_vpath,                                               \
15521   "<intfc> | sw_if_index <id> enable | disable")                        \
15522 _(sw_interface_set_l2_xconnect,                                         \
15523   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15524   "enable | disable")                                                   \
15525 _(sw_interface_set_l2_bridge,                                           \
15526   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15527   "[shg <split-horizon-group>] [bvi]\n"                                 \
15528   "enable | disable")                                                   \
15529 _(sw_interface_set_dpdk_hqos_pipe,                                      \
15530   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
15531   "profile <profile-id>\n")                                             \
15532 _(sw_interface_set_dpdk_hqos_subport,                                   \
15533   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
15534   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
15535 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
15536   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
15537 _(bridge_domain_add_del,                                                \
15538   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15539 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15540 _(l2fib_add_del,                                                        \
15541   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15542 _(l2_flags,                                                             \
15543   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15544 _(bridge_flags,                                                         \
15545   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15546 _(tap_connect,                                                          \
15547   "tapname <name> mac <mac-addr> | random-mac")                         \
15548 _(tap_modify,                                                           \
15549   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15550 _(tap_delete,                                                           \
15551   "<vpp-if-name> | sw_if_index <id>")                                   \
15552 _(sw_interface_tap_dump, "")                                            \
15553 _(ip_add_del_route,                                                     \
15554   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15555   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15556   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15557   "[multipath] [count <n>]")                                            \
15558 _(proxy_arp_add_del,                                                    \
15559   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15560 _(proxy_arp_intfc_enable_disable,                                       \
15561   "<intfc> | sw_if_index <id> enable | disable")                        \
15562 _(mpls_add_del_encap,                                                   \
15563   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15564 _(mpls_add_del_decap,                                                   \
15565   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15566 _(mpls_gre_add_del_tunnel,                                              \
15567   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15568   "adj <ip4-address>/<mask-width> [del]")                               \
15569 _(sw_interface_set_unnumbered,                                          \
15570   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15571 _(ip_neighbor_add_del,                                                  \
15572   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15573   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15574 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15575 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15576 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15577   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15578   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15579   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15580 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15581 _(reset_fib, "vrf <n> [ipv6]")                                          \
15582 _(dhcp_proxy_config,                                                    \
15583   "svr <v46-address> src <v46-address>\n"                               \
15584    "insert-cid <n> [del]")                                              \
15585 _(dhcp_proxy_config_2,                                                  \
15586   "svr <v46-address> src <v46-address>\n"                               \
15587    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15588 _(dhcp_proxy_set_vss,                                                   \
15589   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15590 _(dhcp_client_config,                                                   \
15591   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15592 _(set_ip_flow_hash,                                                     \
15593   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15594 _(sw_interface_ip6_enable_disable,                                      \
15595   "<intfc> | sw_if_index <id> enable | disable")                        \
15596 _(sw_interface_ip6_set_link_local_address,                              \
15597   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15598 _(sw_interface_ip6nd_ra_prefix,                                         \
15599   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15600   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15601   "[nolink] [isno]")                                                    \
15602 _(sw_interface_ip6nd_ra_config,                                         \
15603   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15604   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15605   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15606 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15607 _(l2_patch_add_del,                                                     \
15608   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15609   "enable | disable")                                                   \
15610 _(mpls_ethernet_add_del_tunnel,                                         \
15611   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15612   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15613 _(mpls_ethernet_add_del_tunnel_2,                                       \
15614   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15615   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15616 _(sr_tunnel_add_del,                                                    \
15617   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15618   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15619   "[policy <policy_name>]")                                             \
15620 _(sr_policy_add_del,                                                    \
15621   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15622 _(sr_multicast_map_add_del,                                             \
15623   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15624 _(classify_add_del_table,                                               \
15625   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15626   "[del] mask <mask-value>\n"                                           \
15627   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15628 _(classify_add_del_session,                                             \
15629   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15630   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15631   "  [l3 [ip4|ip6]]")                                                   \
15632 _(classify_set_interface_ip_table,                                      \
15633   "<intfc> | sw_if_index <nn> table <nn>")                              \
15634 _(classify_set_interface_l2_tables,                                     \
15635   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15636   "  [other-table <nn>]")                                               \
15637 _(get_node_index, "node <node-name")                                    \
15638 _(add_node_next, "node <node-name> next <next-node-name>")              \
15639 _(l2tpv3_create_tunnel,                                                 \
15640   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15641   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15642   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15643 _(l2tpv3_set_tunnel_cookies,                                            \
15644   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15645   "[new_remote_cookie <nn>]\n")                                         \
15646 _(l2tpv3_interface_enable_disable,                                      \
15647   "<intfc> | sw_if_index <nn> enable | disable")                        \
15648 _(l2tpv3_set_lookup_key,                                                \
15649   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15650 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15651 _(vxlan_add_del_tunnel,                                                 \
15652   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15653   " [decap-next l2|ip4|ip6] [del]")                                     \
15654 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15655 _(gre_add_del_tunnel,                                                   \
15656   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15657 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15658 _(l2_fib_clear_table, "")                                               \
15659 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15660 _(l2_interface_vlan_tag_rewrite,                                        \
15661   "<intfc> | sw_if_index <nn> \n"                                       \
15662   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15663   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15664 _(create_vhost_user_if,                                                 \
15665         "socket <filename> [server] [renumber <dev_instance>] "         \
15666         "[mac <mac_address>]")                                          \
15667 _(modify_vhost_user_if,                                                 \
15668         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15669         "[server] [renumber <dev_instance>]")                           \
15670 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15671 _(sw_interface_vhost_user_dump, "")                                     \
15672 _(show_version, "")                                                     \
15673 _(vxlan_gpe_add_del_tunnel,                                             \
15674   "local <addr> remote <addr> vni <nn>\n"                               \
15675     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15676   "[next-ethernet] [next-nsh]\n")                                       \
15677 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15678 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15679 _(interface_name_renumber,                                              \
15680   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15681 _(input_acl_set_interface,                                              \
15682   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15683   "  [l2-table <nn>] [del]")                                            \
15684 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15685 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15686 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15687 _(ip_dump, "ipv4 | ipv6")                                               \
15688 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15689 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15690   "  spid_id <n> ")                                                     \
15691 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15692   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15693   "  integ_alg <alg> integ_key <hex>")                                  \
15694 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15695   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15696   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15697   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15698 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15699 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15700 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15701   "(auth_data 0x<data> | auth_data <data>)")                            \
15702 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15703   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15704 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15705   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15706   "(local|remote)")                                                     \
15707 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15708 _(delete_loopback,"sw_if_index <nn>")                                   \
15709 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15710 _(map_add_domain,                                                       \
15711   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15712   "ip6-src <ip6addr> "                                                  \
15713   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15714 _(map_del_domain, "index <n>")                                          \
15715 _(map_add_del_rule,                                                     \
15716   "index <n> psid <n> dst <ip6addr> [del]")                             \
15717 _(map_domain_dump, "")                                                  \
15718 _(map_rule_dump, "index <map-domain>")                                  \
15719 _(want_interface_events,  "enable|disable")                             \
15720 _(want_stats,"enable|disable")                                          \
15721 _(get_first_msg_id, "client <name>")                                    \
15722 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15723 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15724   "fib-id <nn> [ip4][ip6][default]")                                    \
15725 _(get_node_graph, " ")                                                  \
15726 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15727 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15728 _(ioam_disable, "")                                                \
15729 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15730                             " sw_if_index <sw_if_index> p <priority> "  \
15731                             "w <weight>] [del]")                        \
15732 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15733                         "iface <intf> | sw_if_index <sw_if_index> "     \
15734                         "p <priority> w <weight> [del]")                \
15735 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15736                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15737                           "locator-set <locator_name> [del]")           \
15738 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15739   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15740 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15741 _(lisp_gpe_enable_disable, "enable|disable")                            \
15742 _(lisp_enable_disable, "enable|disable")                                \
15743 _(lisp_gpe_add_del_iface, "up|down")                                    \
15744 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15745                                "[seid <seid>] "                         \
15746                                "rloc <locator> p <prio> "               \
15747                                "w <weight> [rloc <loc> ... ] "          \
15748                                "action <action> [del-all]")             \
15749 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15750                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15751                           "[rloc <loc> ... ] action <action>")          \
15752 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15753 _(lisp_map_request_mode, "src-dst|dst-only")                            \
15754 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15755 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15756 _(lisp_locator_set_dump, "[local | remote]")                            \
15757 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15758 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15759                        "[local] | [remote]")                            \
15760 _(lisp_eid_table_vni_dump, "")                                          \
15761 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15762 _(lisp_gpe_tunnel_dump, "")                                             \
15763 _(lisp_map_resolver_dump, "")                                           \
15764 _(show_lisp_status, "")                                                 \
15765 _(lisp_get_map_request_itr_rlocs, "")                                   \
15766 _(show_lisp_pitr, "")                                                   \
15767 _(show_lisp_map_request_mode, "")                                       \
15768 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15769 _(af_packet_delete, "name <host interface name>")                       \
15770 _(policer_add_del, "name <policer name> <params> [del]")                \
15771 _(policer_dump, "[name <policer name>]")                                \
15772 _(policer_classify_set_interface,                                       \
15773   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15774   "  [l2-table <nn>] [del]")                                            \
15775 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15776 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15777     "[master|slave]")                                                   \
15778 _(netmap_delete, "name <interface name>")                               \
15779 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15780 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15781 _(mpls_fib_encap_dump, "")                                              \
15782 _(mpls_fib_decap_dump, "")                                              \
15783 _(classify_table_ids, "")                                               \
15784 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15785 _(classify_table_info, "table_id <nn>")                                 \
15786 _(classify_session_dump, "table_id <nn>")                               \
15787 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15788     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15789     "[template_interval <nn>] [udp_checksum]")                          \
15790 _(ipfix_exporter_dump, "")                                              \
15791 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15792 _(ipfix_classify_stream_dump, "")                                       \
15793 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15794 _(ipfix_classify_table_dump, "")                                        \
15795 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15796 _(pg_create_interface, "if_id <nn>")                                    \
15797 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15798 _(pg_enable_disable, "[stream <id>] disable")                           \
15799 _(ip_source_and_port_range_check_add_del,                               \
15800   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15801 _(ip_source_and_port_range_check_interface_add_del,                     \
15802   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15803   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15804 _(ipsec_gre_add_del_tunnel,                                             \
15805   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15806 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15807 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15808
15809 /* List of command functions, CLI names map directly to functions */
15810 #define foreach_cli_function                                    \
15811 _(comment, "usage: comment <ignore-rest-of-line>")              \
15812 _(dump_interface_table, "usage: dump_interface_table")          \
15813 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15814 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15815 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15816 _(dump_stats_table, "usage: dump_stats_table")                  \
15817 _(dump_macro_table, "usage: dump_macro_table ")                 \
15818 _(dump_node_table, "usage: dump_node_table")                    \
15819 _(echo, "usage: echo <message>")                                \
15820 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15821 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15822 _(help, "usage: help")                                          \
15823 _(q, "usage: quit")                                             \
15824 _(quit, "usage: quit")                                          \
15825 _(search_node_table, "usage: search_node_table <name>...")      \
15826 _(set, "usage: set <variable-name> <value>")                    \
15827 _(script, "usage: script <file-name>")                          \
15828 _(unset, "usage: unset <variable-name>")
15829
15830 #define _(N,n)                                  \
15831     static void vl_api_##n##_t_handler_uni      \
15832     (vl_api_##n##_t * mp)                       \
15833     {                                           \
15834         vat_main_t * vam = &vat_main;           \
15835         if (vam->json_output) {                 \
15836             vl_api_##n##_t_handler_json(mp);    \
15837         } else {                                \
15838             vl_api_##n##_t_handler(mp);         \
15839         }                                       \
15840     }
15841 foreach_vpe_api_reply_msg;
15842 #undef _
15843
15844 void
15845 vat_api_hookup (vat_main_t * vam)
15846 {
15847 #define _(N,n)                                                  \
15848     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15849                            vl_api_##n##_t_handler_uni,          \
15850                            vl_noop_handler,                     \
15851                            vl_api_##n##_t_endian,               \
15852                            vl_api_##n##_t_print,                \
15853                            sizeof(vl_api_##n##_t), 1);
15854   foreach_vpe_api_reply_msg;
15855 #undef _
15856
15857   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15858
15859   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15860
15861   vam->function_by_name = hash_create_string (0, sizeof (uword));
15862
15863   vam->help_by_name = hash_create_string (0, sizeof (uword));
15864
15865   /* API messages we can send */
15866 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15867   foreach_vpe_api_msg;
15868 #undef _
15869
15870   /* Help strings */
15871 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15872   foreach_vpe_api_msg;
15873 #undef _
15874
15875   /* CLI functions */
15876 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15877   foreach_cli_function;
15878 #undef _
15879
15880   /* Help strings */
15881 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15882   foreach_cli_function;
15883 #undef _
15884 }
15885
15886 #undef vl_api_version
15887 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15888 #include <vpp-api/vpe.api.h>
15889 #undef vl_api_version
15890
15891 void
15892 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15893 {
15894   /*
15895    * Send the main API signature in slot 0. This bit of code must
15896    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15897    */
15898   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15899 }
15900
15901 /*
15902  * fd.io coding-style-patch-verification: ON
15903  *
15904  * Local Variables:
15905  * eval: (c-set-style "gnu")
15906  * End:
15907  */