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