27c80d901a159609b97f64117a9085acc238ba06
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void
1319 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_l2_flags_reply_t_handler_json
1335   (vl_api_l2_flags_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1343                             ntohl (mp->resulting_feature_bitmap));
1344
1345   vat_json_print (vam->ofp, &node);
1346   vat_json_free (&node);
1347
1348   vam->retval = ntohl (mp->retval);
1349   vam->result_ready = 1;
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_bridge_flags_reply_t_handler_json
1369   (vl_api_bridge_flags_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   vat_json_node_t node;
1373
1374   vat_json_init_object (&node);
1375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1376   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1377                             ntohl (mp->resulting_feature_bitmap));
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_tap_connect_reply_t_handler
1387   (vl_api_tap_connect_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->sw_if_index = ntohl (mp->sw_if_index);
1399       vam->result_ready = 1;
1400     }
1401
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler_json
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409
1410   vat_json_init_object (&node);
1411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = ntohl (mp->retval);
1418   vam->result_ready = 1;
1419
1420 }
1421
1422 static void
1423 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   i32 retval = ntohl (mp->retval);
1427   if (vam->async_mode)
1428     {
1429       vam->async_errors += (retval < 0);
1430     }
1431   else
1432     {
1433       vam->retval = retval;
1434       vam->sw_if_index = ntohl (mp->sw_if_index);
1435       vam->result_ready = 1;
1436     }
1437 }
1438
1439 static void vl_api_tap_modify_reply_t_handler_json
1440   (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   vat_json_node_t node;
1444
1445   vat_json_init_object (&node);
1446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1448
1449   vat_json_print (vam->ofp, &node);
1450   vat_json_free (&node);
1451
1452   vam->retval = ntohl (mp->retval);
1453   vam->result_ready = 1;
1454 }
1455
1456 static void
1457 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   i32 retval = ntohl (mp->retval);
1461   if (vam->async_mode)
1462     {
1463       vam->async_errors += (retval < 0);
1464     }
1465   else
1466     {
1467       vam->retval = retval;
1468       vam->result_ready = 1;
1469     }
1470 }
1471
1472 static void vl_api_tap_delete_reply_t_handler_json
1473   (vl_api_tap_delete_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   vat_json_node_t node;
1477
1478   vat_json_init_object (&node);
1479   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->result_ready = 1;
1501     }
1502 }
1503
1504 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1505   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t node;
1509
1510   vat_json_init_object (&node);
1511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1512   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1513                             ntohl (mp->tunnel_sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520 }
1521
1522 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1523   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->sw_if_index = ntohl (mp->sw_if_index);
1535       vam->result_ready = 1;
1536     }
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t node;
1544
1545   vat_json_init_object (&node);
1546   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1547   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1548
1549   vat_json_print (vam->ofp, &node);
1550   vat_json_free (&node);
1551
1552   vam->retval = ntohl (mp->retval);
1553   vam->result_ready = 1;
1554 }
1555
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1574   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1591   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->sw_if_index = ntohl (mp->sw_if_index);
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_gre_add_del_tunnel_reply_t_handler
1625   (vl_api_gre_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_create_vhost_user_if_reply_t_handler
1659   (vl_api_create_vhost_user_if_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler_json
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_ip_address_details_t_handler
1693   (vl_api_ip_address_details_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   static ip_address_details_t empty_ip_address_details = { {0} };
1697   ip_address_details_t *address = NULL;
1698   ip_details_t *current_ip_details = NULL;
1699   ip_details_t *details = NULL;
1700
1701   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1702
1703   if (!details || vam->current_sw_if_index >= vec_len (details)
1704       || !details[vam->current_sw_if_index].present)
1705     {
1706       errmsg ("ip address details arrived but not stored\n");
1707       errmsg ("ip_dump should be called first\n");
1708       return;
1709     }
1710
1711   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1712
1713 #define addresses (current_ip_details->addr)
1714
1715   vec_validate_init_empty (addresses, vec_len (addresses),
1716                            empty_ip_address_details);
1717
1718   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1719
1720   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1721   address->prefix_length = mp->prefix_length;
1722 #undef addresses
1723 }
1724
1725 static void vl_api_ip_address_details_t_handler_json
1726   (vl_api_ip_address_details_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t *node = NULL;
1730   struct in6_addr ip6;
1731   struct in_addr ip4;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   node = vat_json_array_add (&vam->json_tree);
1739
1740   vat_json_init_object (node);
1741   if (vam->is_ipv6)
1742     {
1743       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1744       vat_json_object_add_ip6 (node, "ip", ip6);
1745     }
1746   else
1747     {
1748       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1749       vat_json_object_add_ip4 (node, "ip", ip4);
1750     }
1751   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1752 }
1753
1754 static void
1755 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   static ip_details_t empty_ip_details = { 0 };
1759   ip_details_t *ip = NULL;
1760   u32 sw_if_index = ~0;
1761
1762   sw_if_index = ntohl (mp->sw_if_index);
1763
1764   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1765                            sw_if_index, empty_ip_details);
1766
1767   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1768                          sw_if_index);
1769
1770   ip->present = 1;
1771 }
1772
1773 static void
1774 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   vat_json_array_add_uint (&vam->json_tree,
1784                            clib_net_to_host_u32 (mp->sw_if_index));
1785 }
1786
1787 static void vl_api_map_domain_details_t_handler_json
1788   (vl_api_map_domain_details_t * mp)
1789 {
1790   vat_json_node_t *node = NULL;
1791   vat_main_t *vam = &vat_main;
1792   struct in6_addr ip6;
1793   struct in_addr ip4;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800
1801   node = vat_json_array_add (&vam->json_tree);
1802   vat_json_init_object (node);
1803
1804   vat_json_object_add_uint (node, "domain_index",
1805                             clib_net_to_host_u32 (mp->domain_index));
1806   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1808   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1809   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1810   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1811   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1812   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1813   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1814   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1815   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1816   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1817   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1818   vat_json_object_add_uint (node, "flags", mp->flags);
1819   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1820   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1821 }
1822
1823 static void vl_api_map_domain_details_t_handler
1824   (vl_api_map_domain_details_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827
1828   if (mp->is_translation)
1829     {
1830       fformat (vam->ofp,
1831                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1832                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1833                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1834                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1835                clib_net_to_host_u32 (mp->domain_index));
1836     }
1837   else
1838     {
1839       fformat (vam->ofp,
1840                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1841                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1842                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1843                format_ip6_address, mp->ip6_src,
1844                clib_net_to_host_u32 (mp->domain_index));
1845     }
1846   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1847            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1848            mp->is_translation ? "map-t" : "");
1849 }
1850
1851 static void vl_api_map_rule_details_t_handler_json
1852   (vl_api_map_rule_details_t * mp)
1853 {
1854   struct in6_addr ip6;
1855   vat_json_node_t *node = NULL;
1856   vat_main_t *vam = &vat_main;
1857
1858   if (VAT_JSON_ARRAY != vam->json_tree.type)
1859     {
1860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1861       vat_json_init_array (&vam->json_tree);
1862     }
1863
1864   node = vat_json_array_add (&vam->json_tree);
1865   vat_json_init_object (node);
1866
1867   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1868   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1869   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1870 }
1871
1872 static void
1873 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1877            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1878 }
1879
1880 static void
1881 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1885           "router_addr %U host_mac %U\n",
1886           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1887           format_ip4_address, &mp->host_address,
1888           format_ip4_address, &mp->router_address,
1889           format_ethernet_address, mp->host_mac);
1890 }
1891
1892 static void vl_api_dhcp_compl_event_t_handler_json
1893   (vl_api_dhcp_compl_event_t * mp)
1894 {
1895   /* JSON output not supported */
1896 }
1897
1898 static void
1899 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                               u32 counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static u64 default_counter = 0;
1904
1905   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1906                            NULL);
1907   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1908                            sw_if_index, default_counter);
1909   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void
1913 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1914                                 interface_counter_t counter)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   static interface_counter_t default_counter = { 0, };
1918
1919   vec_validate_init_empty (vam->combined_interface_counters,
1920                            vnet_counter_type, NULL);
1921   vec_validate_init_empty (vam->combined_interface_counters
1922                            [vnet_counter_type], sw_if_index, default_counter);
1923   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   /* not supported */
1930 }
1931
1932 static void vl_api_vnet_interface_counters_t_handler_json
1933   (vl_api_vnet_interface_counters_t * mp)
1934 {
1935   interface_counter_t counter;
1936   vlib_counter_t *v;
1937   u64 *v_packets;
1938   u64 packets;
1939   u32 count;
1940   u32 first_sw_if_index;
1941   int i;
1942
1943   count = ntohl (mp->count);
1944   first_sw_if_index = ntohl (mp->first_sw_if_index);
1945
1946   if (!mp->is_combined)
1947     {
1948       v_packets = (u64 *) & mp->data;
1949       for (i = 0; i < count; i++)
1950         {
1951           packets =
1952             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1953           set_simple_interface_counter (mp->vnet_counter_type,
1954                                         first_sw_if_index + i, packets);
1955           v_packets++;
1956         }
1957     }
1958   else
1959     {
1960       v = (vlib_counter_t *) & mp->data;
1961       for (i = 0; i < count; i++)
1962         {
1963           counter.packets =
1964             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1965           counter.bytes =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1967           set_combined_interface_counter (mp->vnet_counter_type,
1968                                           first_sw_if_index + i, counter);
1969           v++;
1970         }
1971     }
1972 }
1973
1974 static u32
1975 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static u32
1991 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   u32 i;
1995
1996   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1997     {
1998       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1999         {
2000           return i;
2001         }
2002     }
2003   return ~0;
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2013   (vl_api_vnet_ip4_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip4_fib_counter_t *v;
2017   ip4_fib_counter_t *counter;
2018   struct in_addr ip4;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip4_fib_counters, vrf_index);
2032       vam->ip4_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip4_fib_counters[vrf_index]);
2036   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2041       counter = &vam->ip4_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2043       counter->address = ip4;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2058   (vl_api_vnet_ip6_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip6_fib_counter_t *v;
2062   ip6_fib_counter_t *counter;
2063   struct in6_addr ip6;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip6_fib_counters, vrf_index);
2077       vam->ip6_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip6_fib_counters[vrf_index]);
2081   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2086       counter = &vam->ip6_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2088       counter->address = ip6;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_get_first_msg_id_reply_t_handler
2097   (vl_api_get_first_msg_id_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   i32 retval = ntohl (mp->retval);
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111   if (retval >= 0)
2112     {
2113       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2114     }
2115 }
2116
2117 static void vl_api_get_first_msg_id_reply_t_handler_json
2118   (vl_api_get_first_msg_id_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t node;
2122
2123   vat_json_init_object (&node);
2124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2125   vat_json_object_add_uint (&node, "first_msg_id",
2126                             (uint) ntohs (mp->first_msg_id));
2127
2128   vat_json_print (vam->ofp, &node);
2129   vat_json_free (&node);
2130
2131   vam->retval = ntohl (mp->retval);
2132   vam->result_ready = 1;
2133 }
2134
2135 static void vl_api_get_node_graph_reply_t_handler
2136   (vl_api_get_node_graph_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   api_main_t *am = &api_main;
2140   i32 retval = ntohl (mp->retval);
2141   u8 *pvt_copy, *reply;
2142   void *oldheap;
2143   vlib_node_t *node;
2144   int i;
2145
2146   if (vam->async_mode)
2147     {
2148       vam->async_errors += (retval < 0);
2149     }
2150   else
2151     {
2152       vam->retval = retval;
2153       vam->result_ready = 1;
2154     }
2155
2156   /* "Should never happen..." */
2157   if (retval != 0)
2158     return;
2159
2160   reply = (u8 *) (mp->reply_in_shmem);
2161   pvt_copy = vec_dup (reply);
2162
2163   /* Toss the shared-memory original... */
2164   pthread_mutex_lock (&am->vlib_rp->mutex);
2165   oldheap = svm_push_data_heap (am->vlib_rp);
2166
2167   vec_free (reply);
2168
2169   svm_pop_heap (oldheap);
2170   pthread_mutex_unlock (&am->vlib_rp->mutex);
2171
2172   if (vam->graph_nodes)
2173     {
2174       hash_free (vam->graph_node_index_by_name);
2175
2176       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177         {
2178           node = vam->graph_nodes[i];
2179           vec_free (node->name);
2180           vec_free (node->next_nodes);
2181           vec_free (node);
2182         }
2183       vec_free (vam->graph_nodes);
2184     }
2185
2186   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2187   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2188   vec_free (pvt_copy);
2189
2190   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2191     {
2192       node = vam->graph_nodes[i];
2193       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2194     }
2195 }
2196
2197 static void vl_api_get_node_graph_reply_t_handler_json
2198   (vl_api_get_node_graph_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   void *oldheap;
2203   vat_json_node_t node;
2204   u8 *reply;
2205
2206   /* $$$$ make this real? */
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2210
2211   reply = (u8 *) (mp->reply_in_shmem);
2212
2213   /* Toss the shared-memory original... */
2214   pthread_mutex_lock (&am->vlib_rp->mutex);
2215   oldheap = svm_push_data_heap (am->vlib_rp);
2216
2217   vec_free (reply);
2218
2219   svm_pop_heap (oldheap);
2220   pthread_mutex_unlock (&am->vlib_rp->mutex);
2221
2222   vat_json_print (vam->ofp, &node);
2223   vat_json_free (&node);
2224
2225   vam->retval = ntohl (mp->retval);
2226   vam->result_ready = 1;
2227 }
2228
2229 static void
2230 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   u8 *s = 0;
2234
2235   if (mp->local)
2236     {
2237       s = format (s, "%=16d%=16d%=16d\n",
2238                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2239     }
2240   else
2241     {
2242       s = format (s, "%=16U%=16d%=16d\n",
2243                   mp->is_ipv6 ? format_ip6_address :
2244                   format_ip4_address,
2245                   mp->ip_address, mp->priority, mp->weight);
2246     }
2247
2248   fformat (vam->ofp, "%v", s);
2249   vec_free (s);
2250 }
2251
2252 static void
2253 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2254                                             mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t *node = NULL;
2258   struct in6_addr ip6;
2259   struct in_addr ip4;
2260
2261   if (VAT_JSON_ARRAY != vam->json_tree.type)
2262     {
2263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2264       vat_json_init_array (&vam->json_tree);
2265     }
2266   node = vat_json_array_add (&vam->json_tree);
2267   vat_json_init_object (node);
2268
2269   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2270   vat_json_object_add_uint (node, "priority", mp->priority);
2271   vat_json_object_add_uint (node, "weight", mp->weight);
2272
2273   if (mp->local)
2274     vat_json_object_add_uint (node, "sw_if_index",
2275                               clib_net_to_host_u32 (mp->sw_if_index));
2276   else
2277     {
2278       if (mp->is_ipv6)
2279         {
2280           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2281           vat_json_object_add_ip6 (node, "address", ip6);
2282         }
2283       else
2284         {
2285           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2286           vat_json_object_add_ip4 (node, "address", ip4);
2287         }
2288     }
2289 }
2290
2291 static void
2292 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2293                                            mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299
2300   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2301            ls_name);
2302   vec_free (ls_name);
2303 }
2304
2305 static void
2306   vl_api_lisp_locator_set_details_t_handler_json
2307   (vl_api_lisp_locator_set_details_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   vat_json_node_t *node = 0;
2311   u8 *ls_name = 0;
2312
2313   ls_name = format (0, "%s", mp->ls_name);
2314   vec_add1 (ls_name, 0);
2315
2316   if (VAT_JSON_ARRAY != vam->json_tree.type)
2317     {
2318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2319       vat_json_init_array (&vam->json_tree);
2320     }
2321   node = vat_json_array_add (&vam->json_tree);
2322
2323   vat_json_init_object (node);
2324   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2325   vat_json_object_add_uint (node, "ls_index",
2326                             clib_net_to_host_u32 (mp->ls_index));
2327   vec_free (ls_name);
2328 }
2329
2330 static u8 *
2331 format_lisp_flat_eid (u8 * s, va_list * args)
2332 {
2333   u32 type = va_arg (*args, u32);
2334   u8 *eid = va_arg (*args, u8 *);
2335   u32 eid_len = va_arg (*args, u32);
2336
2337   switch (type)
2338     {
2339     case 0:
2340       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2341     case 1:
2342       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2343     case 2:
2344       return format (s, "%U", format_ethernet_address, eid);
2345     }
2346   return 0;
2347 }
2348
2349 static u8 *
2350 format_lisp_eid_vat (u8 * s, va_list * args)
2351 {
2352   u32 type = va_arg (*args, u32);
2353   u8 *eid = va_arg (*args, u8 *);
2354   u32 eid_len = va_arg (*args, u32);
2355   u8 *seid = va_arg (*args, u8 *);
2356   u32 seid_len = va_arg (*args, u32);
2357   u32 is_src_dst = va_arg (*args, u32);
2358
2359   if (is_src_dst)
2360     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2361
2362   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2363
2364   return s;
2365 }
2366
2367 static void
2368 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   u8 *s = 0, *eid = 0;
2372
2373   if (~0 == mp->locator_set_index)
2374     s = format (0, "action: %d", mp->action);
2375   else
2376     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2377
2378   eid = format (0, "%U", format_lisp_eid_vat,
2379                 mp->eid_type,
2380                 mp->eid,
2381                 mp->eid_prefix_len,
2382                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2383   vec_add1 (eid, 0);
2384
2385   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2386            clib_net_to_host_u32 (mp->vni),
2387            eid,
2388            mp->is_local ? "local" : "remote",
2389            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2390   vec_free (s);
2391   vec_free (eid);
2392 }
2393
2394 static void
2395 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2396                                               * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   vat_json_node_t *node = 0;
2400   u8 *eid = 0;
2401
2402   if (VAT_JSON_ARRAY != vam->json_tree.type)
2403     {
2404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2405       vat_json_init_array (&vam->json_tree);
2406     }
2407   node = vat_json_array_add (&vam->json_tree);
2408
2409   vat_json_init_object (node);
2410   if (~0 == mp->locator_set_index)
2411     vat_json_object_add_uint (node, "action", mp->action);
2412   else
2413     vat_json_object_add_uint (node, "locator_set_index",
2414                               clib_net_to_host_u32 (mp->locator_set_index));
2415
2416   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2417   eid = format (0, "%U", format_lisp_eid_vat,
2418                 mp->eid_type,
2419                 mp->eid,
2420                 mp->eid_prefix_len,
2421                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2422   vec_add1 (eid, 0);
2423   vat_json_object_add_string_copy (node, "eid", eid);
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2426   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2427   vec_free (eid);
2428 }
2429
2430 static void
2431   vl_api_lisp_eid_table_map_details_t_handler
2432   (vl_api_lisp_eid_table_map_details_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435
2436   u8 *line = format (0, "%=10d%=10d",
2437                      clib_net_to_host_u32 (mp->vni),
2438                      clib_net_to_host_u32 (mp->dp_table));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_map_details_t_handler_json
2445   (vl_api_lisp_eid_table_map_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "dp_table",
2458                             clib_net_to_host_u32 (mp->dp_table));
2459   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2460 }
2461
2462 static void
2463   vl_api_lisp_eid_table_vni_details_t_handler
2464   (vl_api_lisp_eid_table_vni_details_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467
2468   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2469   fformat (vam->ofp, "%v\n", line);
2470   vec_free (line);
2471 }
2472
2473 static void
2474   vl_api_lisp_eid_table_vni_details_t_handler_json
2475   (vl_api_lisp_eid_table_vni_details_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t *node = NULL;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485   node = vat_json_array_add (&vam->json_tree);
2486   vat_json_init_object (node);
2487   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2488 }
2489
2490 static u8 *
2491 format_decap_next (u8 * s, va_list * args)
2492 {
2493   u32 next_index = va_arg (*args, u32);
2494
2495   switch (next_index)
2496     {
2497     case LISP_GPE_INPUT_NEXT_DROP:
2498       return format (s, "drop");
2499     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2500       return format (s, "ip4");
2501     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2502       return format (s, "ip6");
2503     default:
2504       return format (s, "unknown %d", next_index);
2505     }
2506   return s;
2507 }
2508
2509 static void
2510 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2511                                           mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *iid_str;
2515   u8 *flag_str = NULL;
2516
2517   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2518
2519 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2520   foreach_lisp_gpe_flag_bit;
2521 #undef _
2522
2523   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2524            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2525            mp->tunnels,
2526            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2527            mp->source_ip,
2528            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2529            mp->destination_ip,
2530            ntohl (mp->encap_fib_id),
2531            ntohl (mp->decap_fib_id),
2532            format_decap_next, ntohl (mp->dcap_next),
2533            mp->ver_res >> 6,
2534            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2535
2536   vec_free (iid_str);
2537 }
2538
2539 static void
2540   vl_api_lisp_gpe_tunnel_details_t_handler_json
2541   (vl_api_lisp_gpe_tunnel_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = NULL;
2545   struct in6_addr ip6;
2546   struct in_addr ip4;
2547   u8 *next_decap_str;
2548
2549   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557
2558   vat_json_init_object (node);
2559   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2560   if (mp->is_ipv6)
2561     {
2562       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2563       vat_json_object_add_ip6 (node, "source address", ip6);
2564       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2565       vat_json_object_add_ip6 (node, "destination address", ip6);
2566     }
2567   else
2568     {
2569       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2570       vat_json_object_add_ip4 (node, "source address", ip4);
2571       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2572       vat_json_object_add_ip4 (node, "destination address", ip4);
2573     }
2574   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2575   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2576   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2577   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2578   vat_json_object_add_uint (node, "flags", mp->flags);
2579   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2580   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2581   vat_json_object_add_uint (node, "res", mp->res);
2582   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2583
2584   vec_free (next_decap_str);
2585 }
2586
2587 static void
2588 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2589                                             * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   fformat (vam->ofp, "%=20U\n",
2594            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2595            mp->ip_address);
2596 }
2597
2598 static void
2599   vl_api_lisp_map_resolver_details_t_handler_json
2600   (vl_api_lisp_map_resolver_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604   struct in6_addr ip6;
2605   struct in_addr ip4;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   if (mp->is_ipv6)
2616     {
2617       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2618       vat_json_object_add_ip6 (node, "map resolver", ip6);
2619     }
2620   else
2621     {
2622       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2623       vat_json_object_add_ip4 (node, "map resolver", ip4);
2624     }
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   i32 retval = ntohl (mp->retval);
2633
2634   if (0 <= retval)
2635     {
2636       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2637                mp->feature_status ? "enabled" : "disabled",
2638                mp->gpe_status ? "enabled" : "disabled");
2639     }
2640
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler_json
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t node;
2651   u8 *gpe_status = NULL;
2652   u8 *feature_status = NULL;
2653
2654   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2655   feature_status = format (0, "%s",
2656                            mp->feature_status ? "enabled" : "disabled");
2657   vec_add1 (gpe_status, 0);
2658   vec_add1 (feature_status, 0);
2659
2660   vat_json_init_object (&node);
2661   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2662   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2663
2664   vec_free (gpe_status);
2665   vec_free (feature_status);
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2676   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   i32 retval = ntohl (mp->retval);
2680
2681   if (retval >= 0)
2682     {
2683       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2684     }
2685
2686   vam->retval = retval;
2687   vam->result_ready = 1;
2688 }
2689
2690 static void
2691   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2692   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t *node = NULL;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2706
2707   vat_json_print (vam->ofp, node);
2708   vat_json_free (node);
2709
2710   vam->retval = ntohl (mp->retval);
2711   vam->result_ready = 1;
2712 }
2713
2714 static u8 *
2715 format_lisp_map_request_mode (u8 * s, va_list * args)
2716 {
2717   u32 mode = va_arg (*args, u32);
2718
2719   switch (mode)
2720     {
2721     case 0:
2722       return format (0, "dst-only");
2723     case 1:
2724       return format (0, "src-dst");
2725     }
2726   return 0;
2727 }
2728
2729 static void
2730   vl_api_show_lisp_map_request_mode_reply_t_handler
2731   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   i32 retval = ntohl (mp->retval);
2735
2736   if (0 <= retval)
2737     {
2738       u32 mode = mp->mode;
2739       fformat (vam->ofp, "map_request_mode: %U\n",
2740                format_lisp_map_request_mode, mode);
2741     }
2742
2743   vam->retval = retval;
2744   vam->result_ready = 1;
2745 }
2746
2747 static void
2748   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2749   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   vat_json_node_t node;
2753   u8 *s = 0;
2754   u32 mode;
2755
2756   mode = mp->mode;
2757   s = format (0, "%U", format_lisp_map_request_mode, mode);
2758   vec_add1 (s, 0);
2759
2760   vat_json_init_object (&node);
2761   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2762   vat_json_print (vam->ofp, &node);
2763   vat_json_free (&node);
2764
2765   vec_free (s);
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static void
2771 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   i32 retval = ntohl (mp->retval);
2775
2776   if (0 <= retval)
2777     {
2778       fformat (vam->ofp, "%-20s%-16s\n",
2779                mp->status ? "enabled" : "disabled",
2780                mp->status ? (char *) mp->locator_set_name : "");
2781     }
2782
2783   vam->retval = retval;
2784   vam->result_ready = 1;
2785 }
2786
2787 static void
2788 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2789                                             mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   vat_json_node_t node;
2793   u8 *status = 0;
2794
2795   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2796   vec_add1 (status, 0);
2797
2798   vat_json_init_object (&node);
2799   vat_json_object_add_string_copy (&node, "status", status);
2800   if (mp->status)
2801     {
2802       vat_json_object_add_string_copy (&node, "locator_set",
2803                                        mp->locator_set_name);
2804     }
2805
2806   vec_free (status);
2807
2808   vat_json_print (vam->ofp, &node);
2809   vat_json_free (&node);
2810
2811   vam->retval = ntohl (mp->retval);
2812   vam->result_ready = 1;
2813 }
2814
2815 static u8 *
2816 format_policer_type (u8 * s, va_list * va)
2817 {
2818   u32 i = va_arg (*va, u32);
2819
2820   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2821     s = format (s, "1r2c");
2822   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2823     s = format (s, "1r3c");
2824   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2825     s = format (s, "2r3c-2698");
2826   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2827     s = format (s, "2r3c-4115");
2828   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2829     s = format (s, "2r3c-mef5cf1");
2830   else
2831     s = format (s, "ILLEGAL");
2832   return s;
2833 }
2834
2835 static u8 *
2836 format_policer_rate_type (u8 * s, va_list * va)
2837 {
2838   u32 i = va_arg (*va, u32);
2839
2840   if (i == SSE2_QOS_RATE_KBPS)
2841     s = format (s, "kbps");
2842   else if (i == SSE2_QOS_RATE_PPS)
2843     s = format (s, "pps");
2844   else
2845     s = format (s, "ILLEGAL");
2846   return s;
2847 }
2848
2849 static u8 *
2850 format_policer_round_type (u8 * s, va_list * va)
2851 {
2852   u32 i = va_arg (*va, u32);
2853
2854   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2855     s = format (s, "closest");
2856   else if (i == SSE2_QOS_ROUND_TO_UP)
2857     s = format (s, "up");
2858   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2859     s = format (s, "down");
2860   else
2861     s = format (s, "ILLEGAL");
2862   return s;
2863 }
2864
2865 static u8 *
2866 format_policer_action_type (u8 * s, va_list * va)
2867 {
2868   u32 i = va_arg (*va, u32);
2869
2870   if (i == SSE2_QOS_ACTION_DROP)
2871     s = format (s, "drop");
2872   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2873     s = format (s, "transmit");
2874   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2875     s = format (s, "mark-and-transmit");
2876   else
2877     s = format (s, "ILLEGAL");
2878   return s;
2879 }
2880
2881 static u8 *
2882 format_dscp (u8 * s, va_list * va)
2883 {
2884   u32 i = va_arg (*va, u32);
2885   char *t = 0;
2886
2887   switch (i)
2888     {
2889 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2890       foreach_vnet_dscp
2891 #undef _
2892     default:
2893       return format (s, "ILLEGAL");
2894     }
2895   s = format (s, "%s", t);
2896   return s;
2897 }
2898
2899 static void
2900 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2904
2905   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2906     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2907   else
2908     conform_dscp_str = format (0, "");
2909
2910   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2911     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2912   else
2913     exceed_dscp_str = format (0, "");
2914
2915   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2916     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2917   else
2918     violate_dscp_str = format (0, "");
2919
2920   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2921            "rate type %U, round type %U, %s rate, %s color-aware, "
2922            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2923            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2924            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2925            mp->name,
2926            format_policer_type, mp->type,
2927            ntohl (mp->cir),
2928            ntohl (mp->eir),
2929            clib_net_to_host_u64 (mp->cb),
2930            clib_net_to_host_u64 (mp->eb),
2931            format_policer_rate_type, mp->rate_type,
2932            format_policer_round_type, mp->round_type,
2933            mp->single_rate ? "single" : "dual",
2934            mp->color_aware ? "is" : "not",
2935            ntohl (mp->cir_tokens_per_period),
2936            ntohl (mp->pir_tokens_per_period),
2937            ntohl (mp->scale),
2938            ntohl (mp->current_limit),
2939            ntohl (mp->current_bucket),
2940            ntohl (mp->extended_limit),
2941            ntohl (mp->extended_bucket),
2942            clib_net_to_host_u64 (mp->last_update_time),
2943            format_policer_action_type, mp->conform_action_type,
2944            conform_dscp_str,
2945            format_policer_action_type, mp->exceed_action_type,
2946            exceed_dscp_str,
2947            format_policer_action_type, mp->violate_action_type,
2948            violate_dscp_str);
2949
2950   vec_free (conform_dscp_str);
2951   vec_free (exceed_dscp_str);
2952   vec_free (violate_dscp_str);
2953 }
2954
2955 static void vl_api_policer_details_t_handler_json
2956   (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   vat_json_node_t *node;
2960   u8 *rate_type_str, *round_type_str, *type_str;
2961   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2962
2963   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2964   round_type_str =
2965     format (0, "%U", format_policer_round_type, mp->round_type);
2966   type_str = format (0, "%U", format_policer_type, mp->type);
2967   conform_action_str = format (0, "%U", format_policer_action_type,
2968                                mp->conform_action_type);
2969   exceed_action_str = format (0, "%U", format_policer_action_type,
2970                               mp->exceed_action_type);
2971   violate_action_str = format (0, "%U", format_policer_action_type,
2972                                mp->violate_action_type);
2973
2974   if (VAT_JSON_ARRAY != vam->json_tree.type)
2975     {
2976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2977       vat_json_init_array (&vam->json_tree);
2978     }
2979   node = vat_json_array_add (&vam->json_tree);
2980
2981   vat_json_init_object (node);
2982   vat_json_object_add_string_copy (node, "name", mp->name);
2983   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2984   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2985   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2986   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2987   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2988   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2989   vat_json_object_add_string_copy (node, "type", type_str);
2990   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2991   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2992   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2993   vat_json_object_add_uint (node, "cir_tokens_per_period",
2994                             ntohl (mp->cir_tokens_per_period));
2995   vat_json_object_add_uint (node, "eir_tokens_per_period",
2996                             ntohl (mp->pir_tokens_per_period));
2997   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2998   vat_json_object_add_uint (node, "current_bucket",
2999                             ntohl (mp->current_bucket));
3000   vat_json_object_add_uint (node, "extended_limit",
3001                             ntohl (mp->extended_limit));
3002   vat_json_object_add_uint (node, "extended_bucket",
3003                             ntohl (mp->extended_bucket));
3004   vat_json_object_add_uint (node, "last_update_time",
3005                             ntohl (mp->last_update_time));
3006   vat_json_object_add_string_copy (node, "conform_action",
3007                                    conform_action_str);
3008   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3009     {
3010       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3011       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3012       vec_free (dscp_str);
3013     }
3014   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3015   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3016     {
3017       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3018       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3019       vec_free (dscp_str);
3020     }
3021   vat_json_object_add_string_copy (node, "violate_action",
3022                                    violate_action_str);
3023   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3024     {
3025       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3026       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3027       vec_free (dscp_str);
3028     }
3029
3030   vec_free (rate_type_str);
3031   vec_free (round_type_str);
3032   vec_free (type_str);
3033   vec_free (conform_action_str);
3034   vec_free (exceed_action_str);
3035   vec_free (violate_action_str);
3036 }
3037
3038 static void
3039 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3040                                            mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   int i, count = ntohl (mp->count);
3044
3045   if (count > 0)
3046     fformat (vam->ofp, "classify table ids (%d) : ", count);
3047   for (i = 0; i < count; i++)
3048     {
3049       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3050       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3051     }
3052   vam->retval = ntohl (mp->retval);
3053   vam->result_ready = 1;
3054 }
3055
3056 static void
3057   vl_api_classify_table_ids_reply_t_handler_json
3058   (vl_api_classify_table_ids_reply_t * mp)
3059 {
3060   vat_main_t *vam = &vat_main;
3061   int i, count = ntohl (mp->count);
3062
3063   if (count > 0)
3064     {
3065       vat_json_node_t node;
3066
3067       vat_json_init_object (&node);
3068       for (i = 0; i < count; i++)
3069         {
3070           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3071         }
3072       vat_json_print (vam->ofp, &node);
3073       vat_json_free (&node);
3074     }
3075   vam->retval = ntohl (mp->retval);
3076   vam->result_ready = 1;
3077 }
3078
3079 static void
3080   vl_api_classify_table_by_interface_reply_t_handler
3081   (vl_api_classify_table_by_interface_reply_t * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   u32 table_id;
3085
3086   table_id = ntohl (mp->l2_table_id);
3087   if (table_id != ~0)
3088     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3089   else
3090     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3091   table_id = ntohl (mp->ip4_table_id);
3092   if (table_id != ~0)
3093     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3094   else
3095     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3096   table_id = ntohl (mp->ip6_table_id);
3097   if (table_id != ~0)
3098     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3099   else
3100     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3101   vam->retval = ntohl (mp->retval);
3102   vam->result_ready = 1;
3103 }
3104
3105 static void
3106   vl_api_classify_table_by_interface_reply_t_handler_json
3107   (vl_api_classify_table_by_interface_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t node;
3111
3112   vat_json_init_object (&node);
3113
3114   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3115   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3116   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3117
3118   vat_json_print (vam->ofp, &node);
3119   vat_json_free (&node);
3120
3121   vam->retval = ntohl (mp->retval);
3122   vam->result_ready = 1;
3123 }
3124
3125 static void vl_api_policer_add_del_reply_t_handler
3126   (vl_api_policer_add_del_reply_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   i32 retval = ntohl (mp->retval);
3130   if (vam->async_mode)
3131     {
3132       vam->async_errors += (retval < 0);
3133     }
3134   else
3135     {
3136       vam->retval = retval;
3137       vam->result_ready = 1;
3138       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3139         /*
3140          * Note: this is just barely thread-safe, depends on
3141          * the main thread spinning waiting for an answer...
3142          */
3143         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3144     }
3145 }
3146
3147 static void vl_api_policer_add_del_reply_t_handler_json
3148   (vl_api_policer_add_del_reply_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t node;
3152
3153   vat_json_init_object (&node);
3154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3155   vat_json_object_add_uint (&node, "policer_index",
3156                             ntohl (mp->policer_index));
3157
3158   vat_json_print (vam->ofp, &node);
3159   vat_json_free (&node);
3160
3161   vam->retval = ntohl (mp->retval);
3162   vam->result_ready = 1;
3163 }
3164
3165 /* Format hex dump. */
3166 u8 *
3167 format_hex_bytes (u8 * s, va_list * va)
3168 {
3169   u8 *bytes = va_arg (*va, u8 *);
3170   int n_bytes = va_arg (*va, int);
3171   uword i;
3172
3173   /* Print short or long form depending on byte count. */
3174   uword short_form = n_bytes <= 32;
3175   uword indent = format_get_indent (s);
3176
3177   if (n_bytes == 0)
3178     return s;
3179
3180   for (i = 0; i < n_bytes; i++)
3181     {
3182       if (!short_form && (i % 32) == 0)
3183         s = format (s, "%08x: ", i);
3184       s = format (s, "%02x", bytes[i]);
3185       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3186         s = format (s, "\n%U", format_white_space, indent);
3187     }
3188
3189   return s;
3190 }
3191
3192 static void
3193 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3194                                             * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   i32 retval = ntohl (mp->retval);
3198   if (retval == 0)
3199     {
3200       fformat (vam->ofp, "classify table info :\n");
3201       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3202                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3203                ntohl (mp->miss_next_index));
3204       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3205                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3206                ntohl (mp->match_n_vectors));
3207       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3208                ntohl (mp->mask_length));
3209     }
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_classify_table_info_reply_t_handler_json
3216   (vl_api_classify_table_info_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220
3221   i32 retval = ntohl (mp->retval);
3222   if (retval == 0)
3223     {
3224       vat_json_init_object (&node);
3225
3226       vat_json_object_add_int (&node, "sessions",
3227                                ntohl (mp->active_sessions));
3228       vat_json_object_add_int (&node, "nexttbl",
3229                                ntohl (mp->next_table_index));
3230       vat_json_object_add_int (&node, "nextnode",
3231                                ntohl (mp->miss_next_index));
3232       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3233       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3234       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3235       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3236                       ntohl (mp->mask_length), 0);
3237       vat_json_object_add_string_copy (&node, "mask", s);
3238
3239       vat_json_print (vam->ofp, &node);
3240       vat_json_free (&node);
3241     }
3242   vam->retval = ntohl (mp->retval);
3243   vam->result_ready = 1;
3244 }
3245
3246 static void
3247 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3248                                            mp)
3249 {
3250   vat_main_t *vam = &vat_main;
3251
3252   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3253            ntohl (mp->hit_next_index), ntohl (mp->advance),
3254            ntohl (mp->opaque_index));
3255   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3256            ntohl (mp->match_length));
3257 }
3258
3259 static void
3260   vl_api_classify_session_details_t_handler_json
3261   (vl_api_classify_session_details_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t *node = NULL;
3265
3266   if (VAT_JSON_ARRAY != vam->json_tree.type)
3267     {
3268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3269       vat_json_init_array (&vam->json_tree);
3270     }
3271   node = vat_json_array_add (&vam->json_tree);
3272
3273   vat_json_init_object (node);
3274   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3275   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3276   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3277   u8 *s =
3278     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3279             0);
3280   vat_json_object_add_string_copy (node, "match", s);
3281 }
3282
3283 static void vl_api_pg_create_interface_reply_t_handler
3284   (vl_api_pg_create_interface_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287
3288   vam->retval = ntohl (mp->retval);
3289   vam->result_ready = 1;
3290 }
3291
3292 static void vl_api_pg_create_interface_reply_t_handler_json
3293   (vl_api_pg_create_interface_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t node;
3297
3298   i32 retval = ntohl (mp->retval);
3299   if (retval == 0)
3300     {
3301       vat_json_init_object (&node);
3302
3303       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3304
3305       vat_json_print (vam->ofp, &node);
3306       vat_json_free (&node);
3307     }
3308   vam->retval = ntohl (mp->retval);
3309   vam->result_ready = 1;
3310 }
3311
3312 static void vl_api_policer_classify_details_t_handler
3313   (vl_api_policer_classify_details_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316
3317   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3318            ntohl (mp->table_index));
3319 }
3320
3321 static void vl_api_policer_classify_details_t_handler_json
3322   (vl_api_policer_classify_details_t * mp)
3323 {
3324   vat_main_t *vam = &vat_main;
3325   vat_json_node_t *node;
3326
3327   if (VAT_JSON_ARRAY != vam->json_tree.type)
3328     {
3329       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3330       vat_json_init_array (&vam->json_tree);
3331     }
3332   node = vat_json_array_add (&vam->json_tree);
3333
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3336   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3337 }
3338
3339 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3340   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (vam->async_mode)
3345     {
3346       vam->async_errors += (retval < 0);
3347     }
3348   else
3349     {
3350       vam->retval = retval;
3351       vam->sw_if_index = ntohl (mp->sw_if_index);
3352       vam->result_ready = 1;
3353     }
3354 }
3355
3356 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3357   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   vat_json_node_t node;
3361
3362   vat_json_init_object (&node);
3363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3364   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3365
3366   vat_json_print (vam->ofp, &node);
3367   vat_json_free (&node);
3368
3369   vam->retval = ntohl (mp->retval);
3370   vam->result_ready = 1;
3371 }
3372
3373 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3374 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3375 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3376 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3377
3378 /*
3379  * Generate boilerplate reply handlers, which
3380  * dig the return value out of the xxx_reply_t API message,
3381  * stick it into vam->retval, and set vam->result_ready
3382  *
3383  * Could also do this by pointing N message decode slots at
3384  * a single function, but that could break in subtle ways.
3385  */
3386
3387 #define foreach_standard_reply_retval_handler           \
3388 _(sw_interface_set_flags_reply)                         \
3389 _(sw_interface_add_del_address_reply)                   \
3390 _(sw_interface_set_table_reply)                         \
3391 _(sw_interface_set_vpath_reply)                         \
3392 _(sw_interface_set_l2_bridge_reply)                     \
3393 _(bridge_domain_add_del_reply)                          \
3394 _(sw_interface_set_l2_xconnect_reply)                   \
3395 _(l2fib_add_del_reply)                                  \
3396 _(ip_add_del_route_reply)                               \
3397 _(proxy_arp_add_del_reply)                              \
3398 _(proxy_arp_intfc_enable_disable_reply)                 \
3399 _(mpls_add_del_encap_reply)                             \
3400 _(mpls_add_del_decap_reply)                             \
3401 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3402 _(sw_interface_set_unnumbered_reply)                    \
3403 _(ip_neighbor_add_del_reply)                            \
3404 _(reset_vrf_reply)                                      \
3405 _(oam_add_del_reply)                                    \
3406 _(reset_fib_reply)                                      \
3407 _(dhcp_proxy_config_reply)                              \
3408 _(dhcp_proxy_config_2_reply)                            \
3409 _(dhcp_proxy_set_vss_reply)                             \
3410 _(dhcp_client_config_reply)                             \
3411 _(set_ip_flow_hash_reply)                               \
3412 _(sw_interface_ip6_enable_disable_reply)                \
3413 _(sw_interface_ip6_set_link_local_address_reply)        \
3414 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3415 _(sw_interface_ip6nd_ra_config_reply)                   \
3416 _(set_arp_neighbor_limit_reply)                         \
3417 _(l2_patch_add_del_reply)                               \
3418 _(sr_tunnel_add_del_reply)                              \
3419 _(sr_policy_add_del_reply)                              \
3420 _(sr_multicast_map_add_del_reply)                       \
3421 _(classify_add_del_session_reply)                       \
3422 _(classify_set_interface_ip_table_reply)                \
3423 _(classify_set_interface_l2_tables_reply)               \
3424 _(l2tpv3_set_tunnel_cookies_reply)                      \
3425 _(l2tpv3_interface_enable_disable_reply)                \
3426 _(l2tpv3_set_lookup_key_reply)                          \
3427 _(l2_fib_clear_table_reply)                             \
3428 _(l2_interface_efp_filter_reply)                        \
3429 _(l2_interface_vlan_tag_rewrite_reply)                  \
3430 _(modify_vhost_user_if_reply)                           \
3431 _(delete_vhost_user_if_reply)                           \
3432 _(want_ip4_arp_events_reply)                            \
3433 _(want_ip6_nd_events_reply)                             \
3434 _(input_acl_set_interface_reply)                        \
3435 _(ipsec_spd_add_del_reply)                              \
3436 _(ipsec_interface_add_del_spd_reply)                    \
3437 _(ipsec_spd_add_del_entry_reply)                        \
3438 _(ipsec_sad_add_del_entry_reply)                        \
3439 _(ipsec_sa_set_key_reply)                               \
3440 _(ikev2_profile_add_del_reply)                          \
3441 _(ikev2_profile_set_auth_reply)                         \
3442 _(ikev2_profile_set_id_reply)                           \
3443 _(ikev2_profile_set_ts_reply)                           \
3444 _(ikev2_set_local_key_reply)                            \
3445 _(delete_loopback_reply)                                \
3446 _(bd_ip_mac_add_del_reply)                              \
3447 _(map_del_domain_reply)                                 \
3448 _(map_add_del_rule_reply)                               \
3449 _(want_interface_events_reply)                          \
3450 _(want_stats_reply)                                     \
3451 _(cop_interface_enable_disable_reply)                   \
3452 _(cop_whitelist_enable_disable_reply)                   \
3453 _(sw_interface_clear_stats_reply)                       \
3454 _(ioam_enable_reply)                              \
3455 _(ioam_disable_reply)                              \
3456 _(lisp_add_del_locator_reply)                           \
3457 _(lisp_add_del_local_eid_reply)                         \
3458 _(lisp_add_del_remote_mapping_reply)                    \
3459 _(lisp_add_del_adjacency_reply)                         \
3460 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3461 _(lisp_add_del_map_resolver_reply)                      \
3462 _(lisp_gpe_enable_disable_reply)                        \
3463 _(lisp_gpe_add_del_iface_reply)                         \
3464 _(lisp_enable_disable_reply)                            \
3465 _(lisp_pitr_set_locator_set_reply)                      \
3466 _(lisp_map_request_mode_reply)                          \
3467 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3468 _(lisp_eid_table_add_del_map_reply)                     \
3469 _(vxlan_gpe_add_del_tunnel_reply)                       \
3470 _(af_packet_delete_reply)                               \
3471 _(policer_classify_set_interface_reply)                 \
3472 _(netmap_create_reply)                                  \
3473 _(netmap_delete_reply)                                  \
3474 _(set_ipfix_exporter_reply)                             \
3475 _(set_ipfix_classify_stream_reply)                      \
3476 _(ipfix_classify_table_add_del_reply)                   \
3477 _(pg_capture_reply)                                     \
3478 _(pg_enable_disable_reply)                              \
3479 _(ip_source_and_port_range_check_add_del_reply)         \
3480 _(ip_source_and_port_range_check_interface_add_del_reply)\
3481 _(delete_subif_reply)
3482
3483 #define _(n)                                    \
3484     static void vl_api_##n##_t_handler          \
3485     (vl_api_##n##_t * mp)                       \
3486     {                                           \
3487         vat_main_t * vam = &vat_main;           \
3488         i32 retval = ntohl(mp->retval);         \
3489         if (vam->async_mode) {                  \
3490             vam->async_errors += (retval < 0);  \
3491         } else {                                \
3492             vam->retval = retval;               \
3493             vam->result_ready = 1;              \
3494         }                                       \
3495     }
3496 foreach_standard_reply_retval_handler;
3497 #undef _
3498
3499 #define _(n)                                    \
3500     static void vl_api_##n##_t_handler_json     \
3501     (vl_api_##n##_t * mp)                       \
3502     {                                           \
3503         vat_main_t * vam = &vat_main;           \
3504         vat_json_node_t node;                   \
3505         vat_json_init_object(&node);            \
3506         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3507         vat_json_print(vam->ofp, &node);        \
3508         vam->retval = ntohl(mp->retval);        \
3509         vam->result_ready = 1;                  \
3510     }
3511 foreach_standard_reply_retval_handler;
3512 #undef _
3513
3514 /*
3515  * Table of message reply handlers, must include boilerplate handlers
3516  * we just generated
3517  */
3518
3519 #define foreach_vpe_api_reply_msg                                       \
3520 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3521 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3522 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3523 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3524 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3525 _(CLI_REPLY, cli_reply)                                                 \
3526 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3527 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3528   sw_interface_add_del_address_reply)                                   \
3529 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3530 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3531 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3532   sw_interface_set_l2_xconnect_reply)                                   \
3533 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3534   sw_interface_set_l2_bridge_reply)                                     \
3535 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3536 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3537 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3538 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3539 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3540 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3541 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3542 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3543 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3544 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3545 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3546 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3547 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3548   proxy_arp_intfc_enable_disable_reply)                                 \
3549 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3550 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3551 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3552 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3553   mpls_ethernet_add_del_tunnel_reply)                                   \
3554 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3555   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3556 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3557   sw_interface_set_unnumbered_reply)                                    \
3558 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3559 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3560 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3561 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3562 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3563 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3564 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3565 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3566 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3567 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3568 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3569 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3570   sw_interface_ip6_enable_disable_reply)                                \
3571 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3572   sw_interface_ip6_set_link_local_address_reply)                        \
3573 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3574   sw_interface_ip6nd_ra_prefix_reply)                                   \
3575 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3576   sw_interface_ip6nd_ra_config_reply)                                   \
3577 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3578 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3579 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3580 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3581 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3582 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3583 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3584 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3585 classify_set_interface_ip_table_reply)                                  \
3586 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3587   classify_set_interface_l2_tables_reply)                               \
3588 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3589 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3590 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3591 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3592 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3593   l2tpv3_interface_enable_disable_reply)                                \
3594 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3595 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3596 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3597 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3598 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3599 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3600 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3601 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3602 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3603 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3604 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3605 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3606 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3607 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3608 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3609 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3610 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3611 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3612 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3613 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3614 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3615 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3616 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3617 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3618 _(IP_DETAILS, ip_details)                                               \
3619 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3620 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3621 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3622 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3623 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3624 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3625 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3626 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3627 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3628 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3629 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3630 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3631 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3632 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3633 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3634 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3635 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3636 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3637 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3638 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3639 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3640 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3641 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3642 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3643 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3644 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3645 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3646 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3647 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3648 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3649 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3650 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3651 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3652 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3653 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3654 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3655 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3656 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3657 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3658 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3659 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3660 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3661 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3662 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3663 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3664 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3665 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3666 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3667 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3668 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3669 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3670 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3671   lisp_add_del_map_request_itr_rlocs_reply)                             \
3672 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3673   lisp_get_map_request_itr_rlocs_reply)                                 \
3674 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3675 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3676 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3677 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3678 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3679 _(POLICER_DETAILS, policer_details)                                     \
3680 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3681 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3682 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3683 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3684 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3685 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3686 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3687 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3688 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3689 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3690 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3691 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3692 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3693 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3694 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3695 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3696 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3697 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3698 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3699 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3700 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3701 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3702 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3703  ip_source_and_port_range_check_add_del_reply)                          \
3704 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3705  ip_source_and_port_range_check_interface_add_del_reply)                \
3706 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3707 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3708 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3709
3710 /* M: construct, but don't yet send a message */
3711
3712 #define M(T,t)                                  \
3713 do {                                            \
3714     vam->result_ready = 0;                      \
3715     mp = vl_msg_api_alloc(sizeof(*mp));         \
3716     memset (mp, 0, sizeof (*mp));               \
3717     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3718     mp->client_index = vam->my_client_index;    \
3719 } while(0);
3720
3721 #define M2(T,t,n)                               \
3722 do {                                            \
3723     vam->result_ready = 0;                      \
3724     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3725     memset (mp, 0, sizeof (*mp));               \
3726     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3727     mp->client_index = vam->my_client_index;    \
3728 } while(0);
3729
3730
3731 /* S: send a message */
3732 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3733
3734 /* W: wait for results, with timeout */
3735 #define W                                       \
3736 do {                                            \
3737     timeout = vat_time_now (vam) + 1.0;         \
3738                                                 \
3739     while (vat_time_now (vam) < timeout) {      \
3740         if (vam->result_ready == 1) {           \
3741             return (vam->retval);               \
3742         }                                       \
3743     }                                           \
3744     return -99;                                 \
3745 } while(0);
3746
3747 /* W2: wait for results, with timeout */
3748 #define W2(body)                                \
3749 do {                                            \
3750     timeout = vat_time_now (vam) + 1.0;         \
3751                                                 \
3752     while (vat_time_now (vam) < timeout) {      \
3753         if (vam->result_ready == 1) {           \
3754           (body);                               \
3755           return (vam->retval);                 \
3756         }                                       \
3757     }                                           \
3758     return -99;                                 \
3759 } while(0);
3760
3761 typedef struct
3762 {
3763   u8 *name;
3764   u32 value;
3765 } name_sort_t;
3766
3767
3768 #define STR_VTR_OP_CASE(op)     \
3769     case L2_VTR_ ## op:         \
3770         return "" # op;
3771
3772 static const char *
3773 str_vtr_op (u32 vtr_op)
3774 {
3775   switch (vtr_op)
3776     {
3777       STR_VTR_OP_CASE (DISABLED);
3778       STR_VTR_OP_CASE (PUSH_1);
3779       STR_VTR_OP_CASE (PUSH_2);
3780       STR_VTR_OP_CASE (POP_1);
3781       STR_VTR_OP_CASE (POP_2);
3782       STR_VTR_OP_CASE (TRANSLATE_1_1);
3783       STR_VTR_OP_CASE (TRANSLATE_1_2);
3784       STR_VTR_OP_CASE (TRANSLATE_2_1);
3785       STR_VTR_OP_CASE (TRANSLATE_2_2);
3786     }
3787
3788   return "UNKNOWN";
3789 }
3790
3791 static int
3792 dump_sub_interface_table (vat_main_t * vam)
3793 {
3794   const sw_interface_subif_t *sub = NULL;
3795
3796   if (vam->json_output)
3797     {
3798       clib_warning
3799         ("JSON output supported only for VPE API calls and dump_stats_table");
3800       return -99;
3801     }
3802
3803   fformat (vam->ofp,
3804            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3805            "Interface", "sw_if_index",
3806            "sub id", "dot1ad", "tags", "outer id",
3807            "inner id", "exact", "default", "outer any", "inner any");
3808
3809   vec_foreach (sub, vam->sw_if_subif_table)
3810   {
3811     fformat (vam->ofp,
3812              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3813              sub->interface_name,
3814              sub->sw_if_index,
3815              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3816              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3817              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3818              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3819     if (sub->vtr_op != L2_VTR_DISABLED)
3820       {
3821         fformat (vam->ofp,
3822                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3823                  "tag1: %d tag2: %d ]\n",
3824                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3825                  sub->vtr_tag1, sub->vtr_tag2);
3826       }
3827   }
3828
3829   return 0;
3830 }
3831
3832 static int
3833 name_sort_cmp (void *a1, void *a2)
3834 {
3835   name_sort_t *n1 = a1;
3836   name_sort_t *n2 = a2;
3837
3838   return strcmp ((char *) n1->name, (char *) n2->name);
3839 }
3840
3841 static int
3842 dump_interface_table (vat_main_t * vam)
3843 {
3844   hash_pair_t *p;
3845   name_sort_t *nses = 0, *ns;
3846
3847   if (vam->json_output)
3848     {
3849       clib_warning
3850         ("JSON output supported only for VPE API calls and dump_stats_table");
3851       return -99;
3852     }
3853
3854   /* *INDENT-OFF* */
3855   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3856   ({
3857     vec_add2 (nses, ns, 1);
3858     ns->name = (u8 *)(p->key);
3859     ns->value = (u32) p->value[0];
3860   }));
3861   /* *INDENT-ON* */
3862
3863   vec_sort_with_function (nses, name_sort_cmp);
3864
3865   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3866   vec_foreach (ns, nses)
3867   {
3868     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3869   }
3870   vec_free (nses);
3871   return 0;
3872 }
3873
3874 static int
3875 dump_ip_table (vat_main_t * vam, int is_ipv6)
3876 {
3877   const ip_details_t *det = NULL;
3878   const ip_address_details_t *address = NULL;
3879   u32 i = ~0;
3880
3881   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3882
3883   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3884   {
3885     i++;
3886     if (!det->present)
3887       {
3888         continue;
3889       }
3890     fformat (vam->ofp, "%-12d\n", i);
3891     fformat (vam->ofp,
3892              "            %-30s%-13s\n", "Address", "Prefix length");
3893     if (!det->addr)
3894       {
3895         continue;
3896       }
3897     vec_foreach (address, det->addr)
3898     {
3899       fformat (vam->ofp,
3900                "            %-30U%-13d\n",
3901                is_ipv6 ? format_ip6_address : format_ip4_address,
3902                address->ip, address->prefix_length);
3903     }
3904   }
3905
3906   return 0;
3907 }
3908
3909 static int
3910 dump_ipv4_table (vat_main_t * vam)
3911 {
3912   if (vam->json_output)
3913     {
3914       clib_warning
3915         ("JSON output supported only for VPE API calls and dump_stats_table");
3916       return -99;
3917     }
3918
3919   return dump_ip_table (vam, 0);
3920 }
3921
3922 static int
3923 dump_ipv6_table (vat_main_t * vam)
3924 {
3925   if (vam->json_output)
3926     {
3927       clib_warning
3928         ("JSON output supported only for VPE API calls and dump_stats_table");
3929       return -99;
3930     }
3931
3932   return dump_ip_table (vam, 1);
3933 }
3934
3935 static char *
3936 counter_type_to_str (u8 counter_type, u8 is_combined)
3937 {
3938   if (!is_combined)
3939     {
3940       switch (counter_type)
3941         {
3942         case VNET_INTERFACE_COUNTER_DROP:
3943           return "drop";
3944         case VNET_INTERFACE_COUNTER_PUNT:
3945           return "punt";
3946         case VNET_INTERFACE_COUNTER_IP4:
3947           return "ip4";
3948         case VNET_INTERFACE_COUNTER_IP6:
3949           return "ip6";
3950         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3951           return "rx-no-buf";
3952         case VNET_INTERFACE_COUNTER_RX_MISS:
3953           return "rx-miss";
3954         case VNET_INTERFACE_COUNTER_RX_ERROR:
3955           return "rx-error";
3956         case VNET_INTERFACE_COUNTER_TX_ERROR:
3957           return "tx-error";
3958         default:
3959           return "INVALID-COUNTER-TYPE";
3960         }
3961     }
3962   else
3963     {
3964       switch (counter_type)
3965         {
3966         case VNET_INTERFACE_COUNTER_RX:
3967           return "rx";
3968         case VNET_INTERFACE_COUNTER_TX:
3969           return "tx";
3970         default:
3971           return "INVALID-COUNTER-TYPE";
3972         }
3973     }
3974 }
3975
3976 static int
3977 dump_stats_table (vat_main_t * vam)
3978 {
3979   vat_json_node_t node;
3980   vat_json_node_t *msg_array;
3981   vat_json_node_t *msg;
3982   vat_json_node_t *counter_array;
3983   vat_json_node_t *counter;
3984   interface_counter_t c;
3985   u64 packets;
3986   ip4_fib_counter_t *c4;
3987   ip6_fib_counter_t *c6;
3988   int i, j;
3989
3990   if (!vam->json_output)
3991     {
3992       clib_warning ("dump_stats_table supported only in JSON format");
3993       return -99;
3994     }
3995
3996   vat_json_init_object (&node);
3997
3998   /* interface counters */
3999   msg_array = vat_json_object_add (&node, "interface_counters");
4000   vat_json_init_array (msg_array);
4001   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4002     {
4003       msg = vat_json_array_add (msg_array);
4004       vat_json_init_object (msg);
4005       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4006                                        (u8 *) counter_type_to_str (i, 0));
4007       vat_json_object_add_int (msg, "is_combined", 0);
4008       counter_array = vat_json_object_add (msg, "data");
4009       vat_json_init_array (counter_array);
4010       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4011         {
4012           packets = vam->simple_interface_counters[i][j];
4013           vat_json_array_add_uint (counter_array, packets);
4014         }
4015     }
4016   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4017     {
4018       msg = vat_json_array_add (msg_array);
4019       vat_json_init_object (msg);
4020       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4021                                        (u8 *) counter_type_to_str (i, 1));
4022       vat_json_object_add_int (msg, "is_combined", 1);
4023       counter_array = vat_json_object_add (msg, "data");
4024       vat_json_init_array (counter_array);
4025       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4026         {
4027           c = vam->combined_interface_counters[i][j];
4028           counter = vat_json_array_add (counter_array);
4029           vat_json_init_object (counter);
4030           vat_json_object_add_uint (counter, "packets", c.packets);
4031           vat_json_object_add_uint (counter, "bytes", c.bytes);
4032         }
4033     }
4034
4035   /* ip4 fib counters */
4036   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4037   vat_json_init_array (msg_array);
4038   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4039     {
4040       msg = vat_json_array_add (msg_array);
4041       vat_json_init_object (msg);
4042       vat_json_object_add_uint (msg, "vrf_id",
4043                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4044       counter_array = vat_json_object_add (msg, "c");
4045       vat_json_init_array (counter_array);
4046       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4047         {
4048           counter = vat_json_array_add (counter_array);
4049           vat_json_init_object (counter);
4050           c4 = &vam->ip4_fib_counters[i][j];
4051           vat_json_object_add_ip4 (counter, "address", c4->address);
4052           vat_json_object_add_uint (counter, "address_length",
4053                                     c4->address_length);
4054           vat_json_object_add_uint (counter, "packets", c4->packets);
4055           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4056         }
4057     }
4058
4059   /* ip6 fib counters */
4060   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4061   vat_json_init_array (msg_array);
4062   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4063     {
4064       msg = vat_json_array_add (msg_array);
4065       vat_json_init_object (msg);
4066       vat_json_object_add_uint (msg, "vrf_id",
4067                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4068       counter_array = vat_json_object_add (msg, "c");
4069       vat_json_init_array (counter_array);
4070       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4071         {
4072           counter = vat_json_array_add (counter_array);
4073           vat_json_init_object (counter);
4074           c6 = &vam->ip6_fib_counters[i][j];
4075           vat_json_object_add_ip6 (counter, "address", c6->address);
4076           vat_json_object_add_uint (counter, "address_length",
4077                                     c6->address_length);
4078           vat_json_object_add_uint (counter, "packets", c6->packets);
4079           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4080         }
4081     }
4082
4083   vat_json_print (vam->ofp, &node);
4084   vat_json_free (&node);
4085
4086   return 0;
4087 }
4088
4089 int
4090 exec (vat_main_t * vam)
4091 {
4092   api_main_t *am = &api_main;
4093   vl_api_cli_request_t *mp;
4094   f64 timeout;
4095   void *oldheap;
4096   u8 *cmd = 0;
4097   unformat_input_t *i = vam->input;
4098
4099   if (vec_len (i->buffer) == 0)
4100     return -1;
4101
4102   if (vam->exec_mode == 0 && unformat (i, "mode"))
4103     {
4104       vam->exec_mode = 1;
4105       return 0;
4106     }
4107   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4108     {
4109       vam->exec_mode = 0;
4110       return 0;
4111     }
4112
4113
4114   M (CLI_REQUEST, cli_request);
4115
4116   /*
4117    * Copy cmd into shared memory.
4118    * In order for the CLI command to work, it
4119    * must be a vector ending in \n, not a C-string ending
4120    * in \n\0.
4121    */
4122   pthread_mutex_lock (&am->vlib_rp->mutex);
4123   oldheap = svm_push_data_heap (am->vlib_rp);
4124
4125   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4126   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4127
4128   svm_pop_heap (oldheap);
4129   pthread_mutex_unlock (&am->vlib_rp->mutex);
4130
4131   mp->cmd_in_shmem = (u64) cmd;
4132   S;
4133   timeout = vat_time_now (vam) + 10.0;
4134
4135   while (vat_time_now (vam) < timeout)
4136     {
4137       if (vam->result_ready == 1)
4138         {
4139           u8 *free_me;
4140           if (vam->shmem_result != NULL)
4141             fformat (vam->ofp, "%s", vam->shmem_result);
4142           pthread_mutex_lock (&am->vlib_rp->mutex);
4143           oldheap = svm_push_data_heap (am->vlib_rp);
4144
4145           free_me = (u8 *) vam->shmem_result;
4146           vec_free (free_me);
4147
4148           svm_pop_heap (oldheap);
4149           pthread_mutex_unlock (&am->vlib_rp->mutex);
4150           return 0;
4151         }
4152     }
4153   return -99;
4154 }
4155
4156 /*
4157  * Future replacement of exec() that passes CLI buffers directly in
4158  * the API messages instead of an additional shared memory area.
4159  */
4160 static int
4161 exec_inband (vat_main_t * vam)
4162 {
4163   vl_api_cli_inband_t *mp;
4164   f64 timeout;
4165   unformat_input_t *i = vam->input;
4166
4167   if (vec_len (i->buffer) == 0)
4168     return -1;
4169
4170   if (vam->exec_mode == 0 && unformat (i, "mode"))
4171     {
4172       vam->exec_mode = 1;
4173       return 0;
4174     }
4175   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4176     {
4177       vam->exec_mode = 0;
4178       return 0;
4179     }
4180
4181   /*
4182    * In order for the CLI command to work, it
4183    * must be a vector ending in \n, not a C-string ending
4184    * in \n\0.
4185    */
4186   u32 len = vec_len (vam->input->buffer);
4187   M2 (CLI_INBAND, cli_inband, len);
4188   clib_memcpy (mp->cmd, vam->input->buffer, len);
4189   mp->length = htonl (len);
4190
4191   S;
4192   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4193 }
4194
4195 static int
4196 api_create_loopback (vat_main_t * vam)
4197 {
4198   unformat_input_t *i = vam->input;
4199   vl_api_create_loopback_t *mp;
4200   f64 timeout;
4201   u8 mac_address[6];
4202   u8 mac_set = 0;
4203
4204   memset (mac_address, 0, sizeof (mac_address));
4205
4206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4207     {
4208       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4209         mac_set = 1;
4210       else
4211         break;
4212     }
4213
4214   /* Construct the API message */
4215   M (CREATE_LOOPBACK, create_loopback);
4216   if (mac_set)
4217     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4218
4219   S;
4220   W;
4221 }
4222
4223 static int
4224 api_delete_loopback (vat_main_t * vam)
4225 {
4226   unformat_input_t *i = vam->input;
4227   vl_api_delete_loopback_t *mp;
4228   f64 timeout;
4229   u32 sw_if_index = ~0;
4230
4231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4232     {
4233       if (unformat (i, "sw_if_index %d", &sw_if_index))
4234         ;
4235       else
4236         break;
4237     }
4238
4239   if (sw_if_index == ~0)
4240     {
4241       errmsg ("missing sw_if_index\n");
4242       return -99;
4243     }
4244
4245   /* Construct the API message */
4246   M (DELETE_LOOPBACK, delete_loopback);
4247   mp->sw_if_index = ntohl (sw_if_index);
4248
4249   S;
4250   W;
4251 }
4252
4253 static int
4254 api_want_stats (vat_main_t * vam)
4255 {
4256   unformat_input_t *i = vam->input;
4257   vl_api_want_stats_t *mp;
4258   f64 timeout;
4259   int enable = -1;
4260
4261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4262     {
4263       if (unformat (i, "enable"))
4264         enable = 1;
4265       else if (unformat (i, "disable"))
4266         enable = 0;
4267       else
4268         break;
4269     }
4270
4271   if (enable == -1)
4272     {
4273       errmsg ("missing enable|disable\n");
4274       return -99;
4275     }
4276
4277   M (WANT_STATS, want_stats);
4278   mp->enable_disable = enable;
4279
4280   S;
4281   W;
4282 }
4283
4284 static int
4285 api_want_interface_events (vat_main_t * vam)
4286 {
4287   unformat_input_t *i = vam->input;
4288   vl_api_want_interface_events_t *mp;
4289   f64 timeout;
4290   int enable = -1;
4291
4292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4293     {
4294       if (unformat (i, "enable"))
4295         enable = 1;
4296       else if (unformat (i, "disable"))
4297         enable = 0;
4298       else
4299         break;
4300     }
4301
4302   if (enable == -1)
4303     {
4304       errmsg ("missing enable|disable\n");
4305       return -99;
4306     }
4307
4308   M (WANT_INTERFACE_EVENTS, want_interface_events);
4309   mp->enable_disable = enable;
4310
4311   vam->interface_event_display = enable;
4312
4313   S;
4314   W;
4315 }
4316
4317
4318 /* Note: non-static, called once to set up the initial intfc table */
4319 int
4320 api_sw_interface_dump (vat_main_t * vam)
4321 {
4322   vl_api_sw_interface_dump_t *mp;
4323   f64 timeout;
4324   hash_pair_t *p;
4325   name_sort_t *nses = 0, *ns;
4326   sw_interface_subif_t *sub = NULL;
4327
4328   /* Toss the old name table */
4329   /* *INDENT-OFF* */
4330   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4331   ({
4332     vec_add2 (nses, ns, 1);
4333     ns->name = (u8 *)(p->key);
4334     ns->value = (u32) p->value[0];
4335   }));
4336   /* *INDENT-ON* */
4337
4338   hash_free (vam->sw_if_index_by_interface_name);
4339
4340   vec_foreach (ns, nses) vec_free (ns->name);
4341
4342   vec_free (nses);
4343
4344   vec_foreach (sub, vam->sw_if_subif_table)
4345   {
4346     vec_free (sub->interface_name);
4347   }
4348   vec_free (vam->sw_if_subif_table);
4349
4350   /* recreate the interface name hash table */
4351   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4352
4353   /* Get list of ethernets */
4354   M (SW_INTERFACE_DUMP, sw_interface_dump);
4355   mp->name_filter_valid = 1;
4356   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4357   S;
4358
4359   /* and local / loopback interfaces */
4360   M (SW_INTERFACE_DUMP, sw_interface_dump);
4361   mp->name_filter_valid = 1;
4362   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4363   S;
4364
4365
4366   /* and vxlan-gpe tunnel interfaces */
4367   M (SW_INTERFACE_DUMP, sw_interface_dump);
4368   mp->name_filter_valid = 1;
4369   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4370            sizeof (mp->name_filter) - 1);
4371   S;
4372
4373   /* and vxlan tunnel interfaces */
4374   M (SW_INTERFACE_DUMP, sw_interface_dump);
4375   mp->name_filter_valid = 1;
4376   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4377   S;
4378
4379   /* and host (af_packet) interfaces */
4380   M (SW_INTERFACE_DUMP, sw_interface_dump);
4381   mp->name_filter_valid = 1;
4382   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4383   S;
4384
4385   /* and l2tpv3 tunnel interfaces */
4386   M (SW_INTERFACE_DUMP, sw_interface_dump);
4387   mp->name_filter_valid = 1;
4388   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4389            sizeof (mp->name_filter) - 1);
4390   S;
4391
4392   /* and GRE tunnel interfaces */
4393   M (SW_INTERFACE_DUMP, sw_interface_dump);
4394   mp->name_filter_valid = 1;
4395   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4396   S;
4397
4398   /* and LISP-GPE interfaces */
4399   M (SW_INTERFACE_DUMP, sw_interface_dump);
4400   mp->name_filter_valid = 1;
4401   strncpy ((char *) mp->name_filter, "lisp_gpe",
4402            sizeof (mp->name_filter) - 1);
4403   S;
4404
4405   /* and IPSEC tunnel interfaces */
4406   M (SW_INTERFACE_DUMP, sw_interface_dump);
4407   mp->name_filter_valid = 1;
4408   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4409   S;
4410
4411   /* Use a control ping for synchronization */
4412   {
4413     vl_api_control_ping_t *mp;
4414     M (CONTROL_PING, control_ping);
4415     S;
4416   }
4417   W;
4418 }
4419
4420 static int
4421 api_sw_interface_set_flags (vat_main_t * vam)
4422 {
4423   unformat_input_t *i = vam->input;
4424   vl_api_sw_interface_set_flags_t *mp;
4425   f64 timeout;
4426   u32 sw_if_index;
4427   u8 sw_if_index_set = 0;
4428   u8 admin_up = 0, link_up = 0;
4429
4430   /* Parse args required to build the message */
4431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4432     {
4433       if (unformat (i, "admin-up"))
4434         admin_up = 1;
4435       else if (unformat (i, "admin-down"))
4436         admin_up = 0;
4437       else if (unformat (i, "link-up"))
4438         link_up = 1;
4439       else if (unformat (i, "link-down"))
4440         link_up = 0;
4441       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4442         sw_if_index_set = 1;
4443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4444         sw_if_index_set = 1;
4445       else
4446         break;
4447     }
4448
4449   if (sw_if_index_set == 0)
4450     {
4451       errmsg ("missing interface name or sw_if_index\n");
4452       return -99;
4453     }
4454
4455   /* Construct the API message */
4456   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4457   mp->sw_if_index = ntohl (sw_if_index);
4458   mp->admin_up_down = admin_up;
4459   mp->link_up_down = link_up;
4460
4461   /* send it... */
4462   S;
4463
4464   /* Wait for a reply, return the good/bad news... */
4465   W;
4466 }
4467
4468 static int
4469 api_sw_interface_clear_stats (vat_main_t * vam)
4470 {
4471   unformat_input_t *i = vam->input;
4472   vl_api_sw_interface_clear_stats_t *mp;
4473   f64 timeout;
4474   u32 sw_if_index;
4475   u8 sw_if_index_set = 0;
4476
4477   /* Parse args required to build the message */
4478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4479     {
4480       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4481         sw_if_index_set = 1;
4482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4483         sw_if_index_set = 1;
4484       else
4485         break;
4486     }
4487
4488   /* Construct the API message */
4489   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4490
4491   if (sw_if_index_set == 1)
4492     mp->sw_if_index = ntohl (sw_if_index);
4493   else
4494     mp->sw_if_index = ~0;
4495
4496   /* send it... */
4497   S;
4498
4499   /* Wait for a reply, return the good/bad news... */
4500   W;
4501 }
4502
4503 static int
4504 api_sw_interface_add_del_address (vat_main_t * vam)
4505 {
4506   unformat_input_t *i = vam->input;
4507   vl_api_sw_interface_add_del_address_t *mp;
4508   f64 timeout;
4509   u32 sw_if_index;
4510   u8 sw_if_index_set = 0;
4511   u8 is_add = 1, del_all = 0;
4512   u32 address_length = 0;
4513   u8 v4_address_set = 0;
4514   u8 v6_address_set = 0;
4515   ip4_address_t v4address;
4516   ip6_address_t v6address;
4517
4518   /* Parse args required to build the message */
4519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4520     {
4521       if (unformat (i, "del-all"))
4522         del_all = 1;
4523       else if (unformat (i, "del"))
4524         is_add = 0;
4525       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4526         sw_if_index_set = 1;
4527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4528         sw_if_index_set = 1;
4529       else if (unformat (i, "%U/%d",
4530                          unformat_ip4_address, &v4address, &address_length))
4531         v4_address_set = 1;
4532       else if (unformat (i, "%U/%d",
4533                          unformat_ip6_address, &v6address, &address_length))
4534         v6_address_set = 1;
4535       else
4536         break;
4537     }
4538
4539   if (sw_if_index_set == 0)
4540     {
4541       errmsg ("missing interface name or sw_if_index\n");
4542       return -99;
4543     }
4544   if (v4_address_set && v6_address_set)
4545     {
4546       errmsg ("both v4 and v6 addresses set\n");
4547       return -99;
4548     }
4549   if (!v4_address_set && !v6_address_set && !del_all)
4550     {
4551       errmsg ("no addresses set\n");
4552       return -99;
4553     }
4554
4555   /* Construct the API message */
4556   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4557
4558   mp->sw_if_index = ntohl (sw_if_index);
4559   mp->is_add = is_add;
4560   mp->del_all = del_all;
4561   if (v6_address_set)
4562     {
4563       mp->is_ipv6 = 1;
4564       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4565     }
4566   else
4567     {
4568       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4569     }
4570   mp->address_length = address_length;
4571
4572   /* send it... */
4573   S;
4574
4575   /* Wait for a reply, return good/bad news  */
4576   W;
4577 }
4578
4579 static int
4580 api_sw_interface_set_table (vat_main_t * vam)
4581 {
4582   unformat_input_t *i = vam->input;
4583   vl_api_sw_interface_set_table_t *mp;
4584   f64 timeout;
4585   u32 sw_if_index, vrf_id = 0;
4586   u8 sw_if_index_set = 0;
4587   u8 is_ipv6 = 0;
4588
4589   /* Parse args required to build the message */
4590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4591     {
4592       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4593         sw_if_index_set = 1;
4594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4595         sw_if_index_set = 1;
4596       else if (unformat (i, "vrf %d", &vrf_id))
4597         ;
4598       else if (unformat (i, "ipv6"))
4599         is_ipv6 = 1;
4600       else
4601         break;
4602     }
4603
4604   if (sw_if_index_set == 0)
4605     {
4606       errmsg ("missing interface name or sw_if_index\n");
4607       return -99;
4608     }
4609
4610   /* Construct the API message */
4611   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4612
4613   mp->sw_if_index = ntohl (sw_if_index);
4614   mp->is_ipv6 = is_ipv6;
4615   mp->vrf_id = ntohl (vrf_id);
4616
4617   /* send it... */
4618   S;
4619
4620   /* Wait for a reply... */
4621   W;
4622 }
4623
4624 static int
4625 api_sw_interface_set_vpath (vat_main_t * vam)
4626 {
4627   unformat_input_t *i = vam->input;
4628   vl_api_sw_interface_set_vpath_t *mp;
4629   f64 timeout;
4630   u32 sw_if_index = 0;
4631   u8 sw_if_index_set = 0;
4632   u8 is_enable = 0;
4633
4634   /* Parse args required to build the message */
4635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4636     {
4637       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4638         sw_if_index_set = 1;
4639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4640         sw_if_index_set = 1;
4641       else if (unformat (i, "enable"))
4642         is_enable = 1;
4643       else if (unformat (i, "disable"))
4644         is_enable = 0;
4645       else
4646         break;
4647     }
4648
4649   if (sw_if_index_set == 0)
4650     {
4651       errmsg ("missing interface name or sw_if_index\n");
4652       return -99;
4653     }
4654
4655   /* Construct the API message */
4656   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4657
4658   mp->sw_if_index = ntohl (sw_if_index);
4659   mp->enable = is_enable;
4660
4661   /* send it... */
4662   S;
4663
4664   /* Wait for a reply... */
4665   W;
4666 }
4667
4668 static int
4669 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4670 {
4671   unformat_input_t *i = vam->input;
4672   vl_api_sw_interface_set_l2_xconnect_t *mp;
4673   f64 timeout;
4674   u32 rx_sw_if_index;
4675   u8 rx_sw_if_index_set = 0;
4676   u32 tx_sw_if_index;
4677   u8 tx_sw_if_index_set = 0;
4678   u8 enable = 1;
4679
4680   /* Parse args required to build the message */
4681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4682     {
4683       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4684         rx_sw_if_index_set = 1;
4685       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4686         tx_sw_if_index_set = 1;
4687       else if (unformat (i, "rx"))
4688         {
4689           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4690             {
4691               if (unformat (i, "%U", unformat_sw_if_index, vam,
4692                             &rx_sw_if_index))
4693                 rx_sw_if_index_set = 1;
4694             }
4695           else
4696             break;
4697         }
4698       else if (unformat (i, "tx"))
4699         {
4700           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701             {
4702               if (unformat (i, "%U", unformat_sw_if_index, vam,
4703                             &tx_sw_if_index))
4704                 tx_sw_if_index_set = 1;
4705             }
4706           else
4707             break;
4708         }
4709       else if (unformat (i, "enable"))
4710         enable = 1;
4711       else if (unformat (i, "disable"))
4712         enable = 0;
4713       else
4714         break;
4715     }
4716
4717   if (rx_sw_if_index_set == 0)
4718     {
4719       errmsg ("missing rx interface name or rx_sw_if_index\n");
4720       return -99;
4721     }
4722
4723   if (enable && (tx_sw_if_index_set == 0))
4724     {
4725       errmsg ("missing tx interface name or tx_sw_if_index\n");
4726       return -99;
4727     }
4728
4729   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4730
4731   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4732   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4733   mp->enable = enable;
4734
4735   S;
4736   W;
4737   /* NOTREACHED */
4738   return 0;
4739 }
4740
4741 static int
4742 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4743 {
4744   unformat_input_t *i = vam->input;
4745   vl_api_sw_interface_set_l2_bridge_t *mp;
4746   f64 timeout;
4747   u32 rx_sw_if_index;
4748   u8 rx_sw_if_index_set = 0;
4749   u32 bd_id;
4750   u8 bd_id_set = 0;
4751   u8 bvi = 0;
4752   u32 shg = 0;
4753   u8 enable = 1;
4754
4755   /* Parse args required to build the message */
4756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4757     {
4758       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4759         rx_sw_if_index_set = 1;
4760       else if (unformat (i, "bd_id %d", &bd_id))
4761         bd_id_set = 1;
4762       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4763         rx_sw_if_index_set = 1;
4764       else if (unformat (i, "shg %d", &shg))
4765         ;
4766       else if (unformat (i, "bvi"))
4767         bvi = 1;
4768       else if (unformat (i, "enable"))
4769         enable = 1;
4770       else if (unformat (i, "disable"))
4771         enable = 0;
4772       else
4773         break;
4774     }
4775
4776   if (rx_sw_if_index_set == 0)
4777     {
4778       errmsg ("missing rx interface name or sw_if_index\n");
4779       return -99;
4780     }
4781
4782   if (enable && (bd_id_set == 0))
4783     {
4784       errmsg ("missing bridge domain\n");
4785       return -99;
4786     }
4787
4788   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4789
4790   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4791   mp->bd_id = ntohl (bd_id);
4792   mp->shg = (u8) shg;
4793   mp->bvi = bvi;
4794   mp->enable = enable;
4795
4796   S;
4797   W;
4798   /* NOTREACHED */
4799   return 0;
4800 }
4801
4802 static int
4803 api_bridge_domain_dump (vat_main_t * vam)
4804 {
4805   unformat_input_t *i = vam->input;
4806   vl_api_bridge_domain_dump_t *mp;
4807   f64 timeout;
4808   u32 bd_id = ~0;
4809
4810   /* Parse args required to build the message */
4811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4812     {
4813       if (unformat (i, "bd_id %d", &bd_id))
4814         ;
4815       else
4816         break;
4817     }
4818
4819   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4820   mp->bd_id = ntohl (bd_id);
4821   S;
4822
4823   /* Use a control ping for synchronization */
4824   {
4825     vl_api_control_ping_t *mp;
4826     M (CONTROL_PING, control_ping);
4827     S;
4828   }
4829
4830   W;
4831   /* NOTREACHED */
4832   return 0;
4833 }
4834
4835 static int
4836 api_bridge_domain_add_del (vat_main_t * vam)
4837 {
4838   unformat_input_t *i = vam->input;
4839   vl_api_bridge_domain_add_del_t *mp;
4840   f64 timeout;
4841   u32 bd_id = ~0;
4842   u8 is_add = 1;
4843   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4844
4845   /* Parse args required to build the message */
4846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4847     {
4848       if (unformat (i, "bd_id %d", &bd_id))
4849         ;
4850       else if (unformat (i, "flood %d", &flood))
4851         ;
4852       else if (unformat (i, "uu-flood %d", &uu_flood))
4853         ;
4854       else if (unformat (i, "forward %d", &forward))
4855         ;
4856       else if (unformat (i, "learn %d", &learn))
4857         ;
4858       else if (unformat (i, "arp-term %d", &arp_term))
4859         ;
4860       else if (unformat (i, "del"))
4861         {
4862           is_add = 0;
4863           flood = uu_flood = forward = learn = 0;
4864         }
4865       else
4866         break;
4867     }
4868
4869   if (bd_id == ~0)
4870     {
4871       errmsg ("missing bridge domain\n");
4872       return -99;
4873     }
4874
4875   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4876
4877   mp->bd_id = ntohl (bd_id);
4878   mp->flood = flood;
4879   mp->uu_flood = uu_flood;
4880   mp->forward = forward;
4881   mp->learn = learn;
4882   mp->arp_term = arp_term;
4883   mp->is_add = is_add;
4884
4885   S;
4886   W;
4887   /* NOTREACHED */
4888   return 0;
4889 }
4890
4891 static int
4892 api_l2fib_add_del (vat_main_t * vam)
4893 {
4894   unformat_input_t *i = vam->input;
4895   vl_api_l2fib_add_del_t *mp;
4896   f64 timeout;
4897   u64 mac = 0;
4898   u8 mac_set = 0;
4899   u32 bd_id;
4900   u8 bd_id_set = 0;
4901   u32 sw_if_index;
4902   u8 sw_if_index_set = 0;
4903   u8 is_add = 1;
4904   u8 static_mac = 0;
4905   u8 filter_mac = 0;
4906   u8 bvi_mac = 0;
4907   int count = 1;
4908   f64 before = 0;
4909   int j;
4910
4911   /* Parse args required to build the message */
4912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4913     {
4914       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4915         mac_set = 1;
4916       else if (unformat (i, "bd_id %d", &bd_id))
4917         bd_id_set = 1;
4918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4919         sw_if_index_set = 1;
4920       else if (unformat (i, "sw_if"))
4921         {
4922           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4923             {
4924               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4925                 sw_if_index_set = 1;
4926             }
4927           else
4928             break;
4929         }
4930       else if (unformat (i, "static"))
4931         static_mac = 1;
4932       else if (unformat (i, "filter"))
4933         {
4934           filter_mac = 1;
4935           static_mac = 1;
4936         }
4937       else if (unformat (i, "bvi"))
4938         {
4939           bvi_mac = 1;
4940           static_mac = 1;
4941         }
4942       else if (unformat (i, "del"))
4943         is_add = 0;
4944       else if (unformat (i, "count %d", &count))
4945         ;
4946       else
4947         break;
4948     }
4949
4950   if (mac_set == 0)
4951     {
4952       errmsg ("missing mac address\n");
4953       return -99;
4954     }
4955
4956   if (bd_id_set == 0)
4957     {
4958       errmsg ("missing bridge domain\n");
4959       return -99;
4960     }
4961
4962   if (is_add && (sw_if_index_set == 0))
4963     {
4964       errmsg ("missing interface name or sw_if_index\n");
4965       return -99;
4966     }
4967
4968   if (count > 1)
4969     {
4970       /* Turn on async mode */
4971       vam->async_mode = 1;
4972       vam->async_errors = 0;
4973       before = vat_time_now (vam);
4974     }
4975
4976   for (j = 0; j < count; j++)
4977     {
4978       M (L2FIB_ADD_DEL, l2fib_add_del);
4979
4980       mp->mac = mac;
4981       mp->bd_id = ntohl (bd_id);
4982       mp->is_add = is_add;
4983
4984       if (is_add)
4985         {
4986           mp->sw_if_index = ntohl (sw_if_index);
4987           mp->static_mac = static_mac;
4988           mp->filter_mac = filter_mac;
4989           mp->bvi_mac = bvi_mac;
4990         }
4991       increment_mac_address (&mac);
4992       /* send it... */
4993       S;
4994     }
4995
4996   if (count > 1)
4997     {
4998       vl_api_control_ping_t *mp;
4999       f64 after;
5000
5001       /* Shut off async mode */
5002       vam->async_mode = 0;
5003
5004       M (CONTROL_PING, control_ping);
5005       S;
5006
5007       timeout = vat_time_now (vam) + 1.0;
5008       while (vat_time_now (vam) < timeout)
5009         if (vam->result_ready == 1)
5010           goto out;
5011       vam->retval = -99;
5012
5013     out:
5014       if (vam->retval == -99)
5015         errmsg ("timeout\n");
5016
5017       if (vam->async_errors > 0)
5018         {
5019           errmsg ("%d asynchronous errors\n", vam->async_errors);
5020           vam->retval = -98;
5021         }
5022       vam->async_errors = 0;
5023       after = vat_time_now (vam);
5024
5025       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5026                count, after - before, count / (after - before));
5027     }
5028   else
5029     {
5030       /* Wait for a reply... */
5031       W;
5032     }
5033   /* Return the good/bad news */
5034   return (vam->retval);
5035 }
5036
5037 static int
5038 api_l2_flags (vat_main_t * vam)
5039 {
5040   unformat_input_t *i = vam->input;
5041   vl_api_l2_flags_t *mp;
5042   f64 timeout;
5043   u32 sw_if_index;
5044   u32 feature_bitmap = 0;
5045   u8 sw_if_index_set = 0;
5046
5047   /* Parse args required to build the message */
5048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5049     {
5050       if (unformat (i, "sw_if_index %d", &sw_if_index))
5051         sw_if_index_set = 1;
5052       else if (unformat (i, "sw_if"))
5053         {
5054           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5055             {
5056               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5057                 sw_if_index_set = 1;
5058             }
5059           else
5060             break;
5061         }
5062       else if (unformat (i, "learn"))
5063         feature_bitmap |= L2INPUT_FEAT_LEARN;
5064       else if (unformat (i, "forward"))
5065         feature_bitmap |= L2INPUT_FEAT_FWD;
5066       else if (unformat (i, "flood"))
5067         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5068       else if (unformat (i, "uu-flood"))
5069         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5070       else
5071         break;
5072     }
5073
5074   if (sw_if_index_set == 0)
5075     {
5076       errmsg ("missing interface name or sw_if_index\n");
5077       return -99;
5078     }
5079
5080   M (L2_FLAGS, l2_flags);
5081
5082   mp->sw_if_index = ntohl (sw_if_index);
5083   mp->feature_bitmap = ntohl (feature_bitmap);
5084
5085   S;
5086   W;
5087   /* NOTREACHED */
5088   return 0;
5089 }
5090
5091 static int
5092 api_bridge_flags (vat_main_t * vam)
5093 {
5094   unformat_input_t *i = vam->input;
5095   vl_api_bridge_flags_t *mp;
5096   f64 timeout;
5097   u32 bd_id;
5098   u8 bd_id_set = 0;
5099   u8 is_set = 1;
5100   u32 flags = 0;
5101
5102   /* Parse args required to build the message */
5103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5104     {
5105       if (unformat (i, "bd_id %d", &bd_id))
5106         bd_id_set = 1;
5107       else if (unformat (i, "learn"))
5108         flags |= L2_LEARN;
5109       else if (unformat (i, "forward"))
5110         flags |= L2_FWD;
5111       else if (unformat (i, "flood"))
5112         flags |= L2_FLOOD;
5113       else if (unformat (i, "uu-flood"))
5114         flags |= L2_UU_FLOOD;
5115       else if (unformat (i, "arp-term"))
5116         flags |= L2_ARP_TERM;
5117       else if (unformat (i, "off"))
5118         is_set = 0;
5119       else if (unformat (i, "disable"))
5120         is_set = 0;
5121       else
5122         break;
5123     }
5124
5125   if (bd_id_set == 0)
5126     {
5127       errmsg ("missing bridge domain\n");
5128       return -99;
5129     }
5130
5131   M (BRIDGE_FLAGS, bridge_flags);
5132
5133   mp->bd_id = ntohl (bd_id);
5134   mp->feature_bitmap = ntohl (flags);
5135   mp->is_set = is_set;
5136
5137   S;
5138   W;
5139   /* NOTREACHED */
5140   return 0;
5141 }
5142
5143 static int
5144 api_bd_ip_mac_add_del (vat_main_t * vam)
5145 {
5146   unformat_input_t *i = vam->input;
5147   vl_api_bd_ip_mac_add_del_t *mp;
5148   f64 timeout;
5149   u32 bd_id;
5150   u8 is_ipv6 = 0;
5151   u8 is_add = 1;
5152   u8 bd_id_set = 0;
5153   u8 ip_set = 0;
5154   u8 mac_set = 0;
5155   ip4_address_t v4addr;
5156   ip6_address_t v6addr;
5157   u8 macaddr[6];
5158
5159
5160   /* Parse args required to build the message */
5161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5162     {
5163       if (unformat (i, "bd_id %d", &bd_id))
5164         {
5165           bd_id_set++;
5166         }
5167       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5168         {
5169           ip_set++;
5170         }
5171       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5172         {
5173           ip_set++;
5174           is_ipv6++;
5175         }
5176       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5177         {
5178           mac_set++;
5179         }
5180       else if (unformat (i, "del"))
5181         is_add = 0;
5182       else
5183         break;
5184     }
5185
5186   if (bd_id_set == 0)
5187     {
5188       errmsg ("missing bridge domain\n");
5189       return -99;
5190     }
5191   else if (ip_set == 0)
5192     {
5193       errmsg ("missing IP address\n");
5194       return -99;
5195     }
5196   else if (mac_set == 0)
5197     {
5198       errmsg ("missing MAC address\n");
5199       return -99;
5200     }
5201
5202   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5203
5204   mp->bd_id = ntohl (bd_id);
5205   mp->is_ipv6 = is_ipv6;
5206   mp->is_add = is_add;
5207   if (is_ipv6)
5208     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5209   else
5210     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5211   clib_memcpy (mp->mac_address, macaddr, 6);
5212   S;
5213   W;
5214   /* NOTREACHED */
5215   return 0;
5216 }
5217
5218 static int
5219 api_tap_connect (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_tap_connect_t *mp;
5223   f64 timeout;
5224   u8 mac_address[6];
5225   u8 random_mac = 1;
5226   u8 name_set = 0;
5227   u8 *tap_name;
5228
5229   memset (mac_address, 0, sizeof (mac_address));
5230
5231   /* Parse args required to build the message */
5232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5233     {
5234       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5235         {
5236           random_mac = 0;
5237         }
5238       else if (unformat (i, "random-mac"))
5239         random_mac = 1;
5240       else if (unformat (i, "tapname %s", &tap_name))
5241         name_set = 1;
5242       else
5243         break;
5244     }
5245
5246   if (name_set == 0)
5247     {
5248       errmsg ("missing tap name\n");
5249       return -99;
5250     }
5251   if (vec_len (tap_name) > 63)
5252     {
5253       errmsg ("tap name too long\n");
5254     }
5255   vec_add1 (tap_name, 0);
5256
5257   /* Construct the API message */
5258   M (TAP_CONNECT, tap_connect);
5259
5260   mp->use_random_mac = random_mac;
5261   clib_memcpy (mp->mac_address, mac_address, 6);
5262   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5263   vec_free (tap_name);
5264
5265   /* send it... */
5266   S;
5267
5268   /* Wait for a reply... */
5269   W;
5270 }
5271
5272 static int
5273 api_tap_modify (vat_main_t * vam)
5274 {
5275   unformat_input_t *i = vam->input;
5276   vl_api_tap_modify_t *mp;
5277   f64 timeout;
5278   u8 mac_address[6];
5279   u8 random_mac = 1;
5280   u8 name_set = 0;
5281   u8 *tap_name;
5282   u32 sw_if_index = ~0;
5283   u8 sw_if_index_set = 0;
5284
5285   memset (mac_address, 0, sizeof (mac_address));
5286
5287   /* Parse args required to build the message */
5288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5289     {
5290       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5291         sw_if_index_set = 1;
5292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5295         {
5296           random_mac = 0;
5297         }
5298       else if (unformat (i, "random-mac"))
5299         random_mac = 1;
5300       else if (unformat (i, "tapname %s", &tap_name))
5301         name_set = 1;
5302       else
5303         break;
5304     }
5305
5306   if (sw_if_index_set == 0)
5307     {
5308       errmsg ("missing vpp interface name");
5309       return -99;
5310     }
5311   if (name_set == 0)
5312     {
5313       errmsg ("missing tap name\n");
5314       return -99;
5315     }
5316   if (vec_len (tap_name) > 63)
5317     {
5318       errmsg ("tap name too long\n");
5319     }
5320   vec_add1 (tap_name, 0);
5321
5322   /* Construct the API message */
5323   M (TAP_MODIFY, tap_modify);
5324
5325   mp->use_random_mac = random_mac;
5326   mp->sw_if_index = ntohl (sw_if_index);
5327   clib_memcpy (mp->mac_address, mac_address, 6);
5328   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5329   vec_free (tap_name);
5330
5331   /* send it... */
5332   S;
5333
5334   /* Wait for a reply... */
5335   W;
5336 }
5337
5338 static int
5339 api_tap_delete (vat_main_t * vam)
5340 {
5341   unformat_input_t *i = vam->input;
5342   vl_api_tap_delete_t *mp;
5343   f64 timeout;
5344   u32 sw_if_index = ~0;
5345   u8 sw_if_index_set = 0;
5346
5347   /* Parse args required to build the message */
5348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349     {
5350       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5351         sw_if_index_set = 1;
5352       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5353         sw_if_index_set = 1;
5354       else
5355         break;
5356     }
5357
5358   if (sw_if_index_set == 0)
5359     {
5360       errmsg ("missing vpp interface name");
5361       return -99;
5362     }
5363
5364   /* Construct the API message */
5365   M (TAP_DELETE, tap_delete);
5366
5367   mp->sw_if_index = ntohl (sw_if_index);
5368
5369   /* send it... */
5370   S;
5371
5372   /* Wait for a reply... */
5373   W;
5374 }
5375
5376 static int
5377 api_ip_add_del_route (vat_main_t * vam)
5378 {
5379   unformat_input_t *i = vam->input;
5380   vl_api_ip_add_del_route_t *mp;
5381   f64 timeout;
5382   u32 sw_if_index = ~0, vrf_id = 0;
5383   u8 sw_if_index_set = 0;
5384   u8 is_ipv6 = 0;
5385   u8 is_local = 0, is_drop = 0;
5386   u8 create_vrf_if_needed = 0;
5387   u8 is_add = 1;
5388   u8 next_hop_weight = 1;
5389   u8 not_last = 0;
5390   u8 is_multipath = 0;
5391   u8 address_set = 0;
5392   u8 address_length_set = 0;
5393   u32 lookup_in_vrf = 0;
5394   u32 resolve_attempts = 0;
5395   u32 dst_address_length = 0;
5396   u8 next_hop_set = 0;
5397   ip4_address_t v4_dst_address, v4_next_hop_address;
5398   ip6_address_t v6_dst_address, v6_next_hop_address;
5399   int count = 1;
5400   int j;
5401   f64 before = 0;
5402   u32 random_add_del = 0;
5403   u32 *random_vector = 0;
5404   uword *random_hash;
5405   u32 random_seed = 0xdeaddabe;
5406   u32 classify_table_index = ~0;
5407   u8 is_classify = 0;
5408   u8 resolve_host, resolve_attached;
5409
5410   /* Parse args required to build the message */
5411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5412     {
5413       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5414         sw_if_index_set = 1;
5415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5416         sw_if_index_set = 1;
5417       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5418         {
5419           address_set = 1;
5420           is_ipv6 = 0;
5421         }
5422       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5423         {
5424           address_set = 1;
5425           is_ipv6 = 1;
5426         }
5427       else if (unformat (i, "/%d", &dst_address_length))
5428         {
5429           address_length_set = 1;
5430         }
5431
5432       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5433                                          &v4_next_hop_address))
5434         {
5435           next_hop_set = 1;
5436         }
5437       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5438                                          &v6_next_hop_address))
5439         {
5440           next_hop_set = 1;
5441         }
5442       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5443         ;
5444       else if (unformat (i, "weight %d", &next_hop_weight))
5445         ;
5446       else if (unformat (i, "drop"))
5447         {
5448           is_drop = 1;
5449         }
5450       else if (unformat (i, "local"))
5451         {
5452           is_local = 1;
5453         }
5454       else if (unformat (i, "classify %d", &classify_table_index))
5455         {
5456           is_classify = 1;
5457         }
5458       else if (unformat (i, "del"))
5459         is_add = 0;
5460       else if (unformat (i, "add"))
5461         is_add = 1;
5462       else if (unformat (i, "not-last"))
5463         not_last = 1;
5464       else if (unformat (i, "resolve-via-host"))
5465         resolve_host = 1;
5466       else if (unformat (i, "resolve-via-attached"))
5467         resolve_attached = 1;
5468       else if (unformat (i, "multipath"))
5469         is_multipath = 1;
5470       else if (unformat (i, "vrf %d", &vrf_id))
5471         ;
5472       else if (unformat (i, "create-vrf"))
5473         create_vrf_if_needed = 1;
5474       else if (unformat (i, "count %d", &count))
5475         ;
5476       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5477         ;
5478       else if (unformat (i, "random"))
5479         random_add_del = 1;
5480       else if (unformat (i, "seed %d", &random_seed))
5481         ;
5482       else
5483         {
5484           clib_warning ("parse error '%U'", format_unformat_error, i);
5485           return -99;
5486         }
5487     }
5488
5489   if (resolve_attempts > 0 && sw_if_index_set == 0)
5490     {
5491       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5492       return -99;
5493     }
5494
5495   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5496     {
5497       errmsg ("next hop / local / drop / classify not set\n");
5498       return -99;
5499     }
5500
5501   if (address_set == 0)
5502     {
5503       errmsg ("missing addresses\n");
5504       return -99;
5505     }
5506
5507   if (address_length_set == 0)
5508     {
5509       errmsg ("missing address length\n");
5510       return -99;
5511     }
5512
5513   /* Generate a pile of unique, random routes */
5514   if (random_add_del)
5515     {
5516       u32 this_random_address;
5517       random_hash = hash_create (count, sizeof (uword));
5518
5519       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5520       for (j = 0; j <= count; j++)
5521         {
5522           do
5523             {
5524               this_random_address = random_u32 (&random_seed);
5525               this_random_address =
5526                 clib_host_to_net_u32 (this_random_address);
5527             }
5528           while (hash_get (random_hash, this_random_address));
5529           vec_add1 (random_vector, this_random_address);
5530           hash_set (random_hash, this_random_address, 1);
5531         }
5532       hash_free (random_hash);
5533       v4_dst_address.as_u32 = random_vector[0];
5534     }
5535
5536   if (count > 1)
5537     {
5538       /* Turn on async mode */
5539       vam->async_mode = 1;
5540       vam->async_errors = 0;
5541       before = vat_time_now (vam);
5542     }
5543
5544   for (j = 0; j < count; j++)
5545     {
5546       /* Construct the API message */
5547       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5548
5549       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5550       mp->vrf_id = ntohl (vrf_id);
5551       if (resolve_attempts > 0)
5552         {
5553           mp->resolve_attempts = ntohl (resolve_attempts);
5554           mp->resolve_if_needed = 1;
5555         }
5556       mp->create_vrf_if_needed = create_vrf_if_needed;
5557
5558       mp->is_add = is_add;
5559       mp->is_drop = is_drop;
5560       mp->is_ipv6 = is_ipv6;
5561       mp->is_local = is_local;
5562       mp->is_classify = is_classify;
5563       mp->is_multipath = is_multipath;
5564       mp->is_resolve_host = resolve_host;
5565       mp->is_resolve_attached = resolve_attached;
5566       mp->not_last = not_last;
5567       mp->next_hop_weight = next_hop_weight;
5568       mp->dst_address_length = dst_address_length;
5569       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5570       mp->classify_table_index = ntohl (classify_table_index);
5571
5572       if (is_ipv6)
5573         {
5574           clib_memcpy (mp->dst_address, &v6_dst_address,
5575                        sizeof (v6_dst_address));
5576           if (next_hop_set)
5577             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5578                          sizeof (v6_next_hop_address));
5579           increment_v6_address (&v6_dst_address);
5580         }
5581       else
5582         {
5583           clib_memcpy (mp->dst_address, &v4_dst_address,
5584                        sizeof (v4_dst_address));
5585           if (next_hop_set)
5586             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5587                          sizeof (v4_next_hop_address));
5588           if (random_add_del)
5589             v4_dst_address.as_u32 = random_vector[j + 1];
5590           else
5591             increment_v4_address (&v4_dst_address);
5592         }
5593       /* send it... */
5594       S;
5595     }
5596
5597   /* When testing multiple add/del ops, use a control-ping to sync */
5598   if (count > 1)
5599     {
5600       vl_api_control_ping_t *mp;
5601       f64 after;
5602
5603       /* Shut off async mode */
5604       vam->async_mode = 0;
5605
5606       M (CONTROL_PING, control_ping);
5607       S;
5608
5609       timeout = vat_time_now (vam) + 1.0;
5610       while (vat_time_now (vam) < timeout)
5611         if (vam->result_ready == 1)
5612           goto out;
5613       vam->retval = -99;
5614
5615     out:
5616       if (vam->retval == -99)
5617         errmsg ("timeout\n");
5618
5619       if (vam->async_errors > 0)
5620         {
5621           errmsg ("%d asynchronous errors\n", vam->async_errors);
5622           vam->retval = -98;
5623         }
5624       vam->async_errors = 0;
5625       after = vat_time_now (vam);
5626
5627       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5628                count, after - before, count / (after - before));
5629     }
5630   else
5631     {
5632       /* Wait for a reply... */
5633       W;
5634     }
5635
5636   /* Return the good/bad news */
5637   return (vam->retval);
5638 }
5639
5640 static int
5641 api_proxy_arp_add_del (vat_main_t * vam)
5642 {
5643   unformat_input_t *i = vam->input;
5644   vl_api_proxy_arp_add_del_t *mp;
5645   f64 timeout;
5646   u32 vrf_id = 0;
5647   u8 is_add = 1;
5648   ip4_address_t lo, hi;
5649   u8 range_set = 0;
5650
5651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5652     {
5653       if (unformat (i, "vrf %d", &vrf_id))
5654         ;
5655       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5656                          unformat_ip4_address, &hi))
5657         range_set = 1;
5658       else if (unformat (i, "del"))
5659         is_add = 0;
5660       else
5661         {
5662           clib_warning ("parse error '%U'", format_unformat_error, i);
5663           return -99;
5664         }
5665     }
5666
5667   if (range_set == 0)
5668     {
5669       errmsg ("address range not set\n");
5670       return -99;
5671     }
5672
5673   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5674
5675   mp->vrf_id = ntohl (vrf_id);
5676   mp->is_add = is_add;
5677   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5678   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5679
5680   S;
5681   W;
5682   /* NOTREACHED */
5683   return 0;
5684 }
5685
5686 static int
5687 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5688 {
5689   unformat_input_t *i = vam->input;
5690   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5691   f64 timeout;
5692   u32 sw_if_index;
5693   u8 enable = 1;
5694   u8 sw_if_index_set = 0;
5695
5696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5697     {
5698       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5699         sw_if_index_set = 1;
5700       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5701         sw_if_index_set = 1;
5702       else if (unformat (i, "enable"))
5703         enable = 1;
5704       else if (unformat (i, "disable"))
5705         enable = 0;
5706       else
5707         {
5708           clib_warning ("parse error '%U'", format_unformat_error, i);
5709           return -99;
5710         }
5711     }
5712
5713   if (sw_if_index_set == 0)
5714     {
5715       errmsg ("missing interface name or sw_if_index\n");
5716       return -99;
5717     }
5718
5719   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5720
5721   mp->sw_if_index = ntohl (sw_if_index);
5722   mp->enable_disable = enable;
5723
5724   S;
5725   W;
5726   /* NOTREACHED */
5727   return 0;
5728 }
5729
5730 static int
5731 api_mpls_add_del_decap (vat_main_t * vam)
5732 {
5733   unformat_input_t *i = vam->input;
5734   vl_api_mpls_add_del_decap_t *mp;
5735   f64 timeout;
5736   u32 rx_vrf_id = 0;
5737   u32 tx_vrf_id = 0;
5738   u32 label = 0;
5739   u8 is_add = 1;
5740   u8 s_bit = 1;
5741   u32 next_index = 1;
5742
5743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5744     {
5745       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5746         ;
5747       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5748         ;
5749       else if (unformat (i, "label %d", &label))
5750         ;
5751       else if (unformat (i, "next-index %d", &next_index))
5752         ;
5753       else if (unformat (i, "del"))
5754         is_add = 0;
5755       else if (unformat (i, "s-bit-clear"))
5756         s_bit = 0;
5757       else
5758         {
5759           clib_warning ("parse error '%U'", format_unformat_error, i);
5760           return -99;
5761         }
5762     }
5763
5764   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5765
5766   mp->rx_vrf_id = ntohl (rx_vrf_id);
5767   mp->tx_vrf_id = ntohl (tx_vrf_id);
5768   mp->label = ntohl (label);
5769   mp->next_index = ntohl (next_index);
5770   mp->s_bit = s_bit;
5771   mp->is_add = is_add;
5772
5773   S;
5774   W;
5775   /* NOTREACHED */
5776   return 0;
5777 }
5778
5779 static int
5780 api_mpls_add_del_encap (vat_main_t * vam)
5781 {
5782   unformat_input_t *i = vam->input;
5783   vl_api_mpls_add_del_encap_t *mp;
5784   f64 timeout;
5785   u32 vrf_id = 0;
5786   u32 *labels = 0;
5787   u32 label;
5788   ip4_address_t dst_address;
5789   u8 is_add = 1;
5790
5791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5792     {
5793       if (unformat (i, "vrf %d", &vrf_id))
5794         ;
5795       else if (unformat (i, "label %d", &label))
5796         vec_add1 (labels, ntohl (label));
5797       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5798         ;
5799       else if (unformat (i, "del"))
5800         is_add = 0;
5801       else
5802         {
5803           clib_warning ("parse error '%U'", format_unformat_error, i);
5804           return -99;
5805         }
5806     }
5807
5808   if (vec_len (labels) == 0)
5809     {
5810       errmsg ("missing encap label stack\n");
5811       return -99;
5812     }
5813
5814   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5815       sizeof (u32) * vec_len (labels));
5816
5817   mp->vrf_id = ntohl (vrf_id);
5818   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5819   mp->is_add = is_add;
5820   mp->nlabels = vec_len (labels);
5821   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5822
5823   vec_free (labels);
5824
5825   S;
5826   W;
5827   /* NOTREACHED */
5828   return 0;
5829 }
5830
5831 static int
5832 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5833 {
5834   unformat_input_t *i = vam->input;
5835   vl_api_mpls_gre_add_del_tunnel_t *mp;
5836   f64 timeout;
5837   u32 inner_vrf_id = 0;
5838   u32 outer_vrf_id = 0;
5839   ip4_address_t src_address;
5840   ip4_address_t dst_address;
5841   ip4_address_t intfc_address;
5842   u32 tmp;
5843   u8 intfc_address_length = 0;
5844   u8 is_add = 1;
5845   u8 l2_only = 0;
5846
5847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5848     {
5849       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5850         ;
5851       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5852         ;
5853       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5854         ;
5855       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5856         ;
5857       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5858                          &intfc_address, &tmp))
5859         intfc_address_length = tmp;
5860       else if (unformat (i, "l2-only"))
5861         l2_only = 1;
5862       else if (unformat (i, "del"))
5863         is_add = 0;
5864       else
5865         {
5866           clib_warning ("parse error '%U'", format_unformat_error, i);
5867           return -99;
5868         }
5869     }
5870
5871   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5872
5873   mp->inner_vrf_id = ntohl (inner_vrf_id);
5874   mp->outer_vrf_id = ntohl (outer_vrf_id);
5875   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5876   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5877   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5878   mp->intfc_address_length = intfc_address_length;
5879   mp->l2_only = l2_only;
5880   mp->is_add = is_add;
5881
5882   S;
5883   W;
5884   /* NOTREACHED */
5885   return 0;
5886 }
5887
5888 static int
5889 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5893   f64 timeout;
5894   u32 inner_vrf_id = 0;
5895   ip4_address_t intfc_address;
5896   u8 dst_mac_address[6];
5897   int dst_set = 1;
5898   u32 tmp;
5899   u8 intfc_address_length = 0;
5900   u8 is_add = 1;
5901   u8 l2_only = 0;
5902   u32 tx_sw_if_index;
5903   int tx_sw_if_index_set = 0;
5904
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "vrf %d", &inner_vrf_id))
5908         ;
5909       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5910                          &intfc_address, &tmp))
5911         intfc_address_length = tmp;
5912       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5913         tx_sw_if_index_set = 1;
5914       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5915         tx_sw_if_index_set = 1;
5916       else if (unformat (i, "dst %U", unformat_ethernet_address,
5917                          dst_mac_address))
5918         dst_set = 1;
5919       else if (unformat (i, "l2-only"))
5920         l2_only = 1;
5921       else if (unformat (i, "del"))
5922         is_add = 0;
5923       else
5924         {
5925           clib_warning ("parse error '%U'", format_unformat_error, i);
5926           return -99;
5927         }
5928     }
5929
5930   if (!dst_set)
5931     {
5932       errmsg ("dst (mac address) not set\n");
5933       return -99;
5934     }
5935   if (!tx_sw_if_index_set)
5936     {
5937       errmsg ("tx-intfc not set\n");
5938       return -99;
5939     }
5940
5941   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5942
5943   mp->vrf_id = ntohl (inner_vrf_id);
5944   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5945   mp->adj_address_length = intfc_address_length;
5946   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5947                sizeof (dst_mac_address));
5948   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5949   mp->l2_only = l2_only;
5950   mp->is_add = is_add;
5951
5952   S;
5953   W;
5954   /* NOTREACHED */
5955   return 0;
5956 }
5957
5958 static int
5959 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5960 {
5961   unformat_input_t *i = vam->input;
5962   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5963   f64 timeout;
5964   u32 inner_vrf_id = 0;
5965   u32 outer_vrf_id = 0;
5966   ip4_address_t adj_address;
5967   int adj_address_set = 0;
5968   ip4_address_t next_hop_address;
5969   int next_hop_address_set = 0;
5970   u32 tmp;
5971   u8 adj_address_length = 0;
5972   u8 l2_only = 0;
5973   u8 is_add = 1;
5974   u32 resolve_attempts = 5;
5975   u8 resolve_if_needed = 1;
5976
5977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5978     {
5979       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5980         ;
5981       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5982         ;
5983       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5984                          &adj_address, &tmp))
5985         {
5986           adj_address_length = tmp;
5987           adj_address_set = 1;
5988         }
5989       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5990                          &next_hop_address))
5991         next_hop_address_set = 1;
5992       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5993         ;
5994       else if (unformat (i, "resolve-if-needed %d", &tmp))
5995         resolve_if_needed = tmp;
5996       else if (unformat (i, "l2-only"))
5997         l2_only = 1;
5998       else if (unformat (i, "del"))
5999         is_add = 0;
6000       else
6001         {
6002           clib_warning ("parse error '%U'", format_unformat_error, i);
6003           return -99;
6004         }
6005     }
6006
6007   if (!adj_address_set)
6008     {
6009       errmsg ("adjacency address/mask not set\n");
6010       return -99;
6011     }
6012   if (!next_hop_address_set)
6013     {
6014       errmsg ("ip4 next hop address (in outer fib) not set\n");
6015       return -99;
6016     }
6017
6018   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6019
6020   mp->inner_vrf_id = ntohl (inner_vrf_id);
6021   mp->outer_vrf_id = ntohl (outer_vrf_id);
6022   mp->resolve_attempts = ntohl (resolve_attempts);
6023   mp->resolve_if_needed = resolve_if_needed;
6024   mp->is_add = is_add;
6025   mp->l2_only = l2_only;
6026   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6027   mp->adj_address_length = adj_address_length;
6028   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6029                sizeof (next_hop_address));
6030
6031   S;
6032   W;
6033   /* NOTREACHED */
6034   return 0;
6035 }
6036
6037 static int
6038 api_sw_interface_set_unnumbered (vat_main_t * vam)
6039 {
6040   unformat_input_t *i = vam->input;
6041   vl_api_sw_interface_set_unnumbered_t *mp;
6042   f64 timeout;
6043   u32 sw_if_index;
6044   u32 unnum_sw_index = ~0;
6045   u8 is_add = 1;
6046   u8 sw_if_index_set = 0;
6047
6048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6049     {
6050       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6051         sw_if_index_set = 1;
6052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6053         sw_if_index_set = 1;
6054       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6055         ;
6056       else if (unformat (i, "del"))
6057         is_add = 0;
6058       else
6059         {
6060           clib_warning ("parse error '%U'", format_unformat_error, i);
6061           return -99;
6062         }
6063     }
6064
6065   if (sw_if_index_set == 0)
6066     {
6067       errmsg ("missing interface name or sw_if_index\n");
6068       return -99;
6069     }
6070
6071   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6072
6073   mp->sw_if_index = ntohl (sw_if_index);
6074   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6075   mp->is_add = is_add;
6076
6077   S;
6078   W;
6079   /* NOTREACHED */
6080   return 0;
6081 }
6082
6083 static int
6084 api_ip_neighbor_add_del (vat_main_t * vam)
6085 {
6086   unformat_input_t *i = vam->input;
6087   vl_api_ip_neighbor_add_del_t *mp;
6088   f64 timeout;
6089   u32 sw_if_index;
6090   u8 sw_if_index_set = 0;
6091   u32 vrf_id = 0;
6092   u8 is_add = 1;
6093   u8 is_static = 0;
6094   u8 mac_address[6];
6095   u8 mac_set = 0;
6096   u8 v4_address_set = 0;
6097   u8 v6_address_set = 0;
6098   ip4_address_t v4address;
6099   ip6_address_t v6address;
6100
6101   memset (mac_address, 0, sizeof (mac_address));
6102
6103   /* Parse args required to build the message */
6104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6105     {
6106       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6107         {
6108           mac_set = 1;
6109         }
6110       else if (unformat (i, "del"))
6111         is_add = 0;
6112       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6113         sw_if_index_set = 1;
6114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6115         sw_if_index_set = 1;
6116       else if (unformat (i, "is_static"))
6117         is_static = 1;
6118       else if (unformat (i, "vrf %d", &vrf_id))
6119         ;
6120       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6121         v4_address_set = 1;
6122       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6123         v6_address_set = 1;
6124       else
6125         {
6126           clib_warning ("parse error '%U'", format_unformat_error, i);
6127           return -99;
6128         }
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index\n");
6134       return -99;
6135     }
6136   if (v4_address_set && v6_address_set)
6137     {
6138       errmsg ("both v4 and v6 addresses set\n");
6139       return -99;
6140     }
6141   if (!v4_address_set && !v6_address_set)
6142     {
6143       errmsg ("no address set\n");
6144       return -99;
6145     }
6146
6147   /* Construct the API message */
6148   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6149
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->is_add = is_add;
6152   mp->vrf_id = ntohl (vrf_id);
6153   mp->is_static = is_static;
6154   if (mac_set)
6155     clib_memcpy (mp->mac_address, mac_address, 6);
6156   if (v6_address_set)
6157     {
6158       mp->is_ipv6 = 1;
6159       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6160     }
6161   else
6162     {
6163       /* mp->is_ipv6 = 0; via memset in M macro above */
6164       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6165     }
6166
6167   /* send it... */
6168   S;
6169
6170   /* Wait for a reply, return good/bad news  */
6171   W;
6172
6173   /* NOTREACHED */
6174   return 0;
6175 }
6176
6177 static int
6178 api_reset_vrf (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_reset_vrf_t *mp;
6182   f64 timeout;
6183   u32 vrf_id = 0;
6184   u8 is_ipv6 = 0;
6185   u8 vrf_id_set = 0;
6186
6187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6188     {
6189       if (unformat (i, "vrf %d", &vrf_id))
6190         vrf_id_set = 1;
6191       else if (unformat (i, "ipv6"))
6192         is_ipv6 = 1;
6193       else
6194         {
6195           clib_warning ("parse error '%U'", format_unformat_error, i);
6196           return -99;
6197         }
6198     }
6199
6200   if (vrf_id_set == 0)
6201     {
6202       errmsg ("missing vrf id\n");
6203       return -99;
6204     }
6205
6206   M (RESET_VRF, reset_vrf);
6207
6208   mp->vrf_id = ntohl (vrf_id);
6209   mp->is_ipv6 = is_ipv6;
6210
6211   S;
6212   W;
6213   /* NOTREACHED */
6214   return 0;
6215 }
6216
6217 static int
6218 api_create_vlan_subif (vat_main_t * vam)
6219 {
6220   unformat_input_t *i = vam->input;
6221   vl_api_create_vlan_subif_t *mp;
6222   f64 timeout;
6223   u32 sw_if_index;
6224   u8 sw_if_index_set = 0;
6225   u32 vlan_id;
6226   u8 vlan_id_set = 0;
6227
6228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6229     {
6230       if (unformat (i, "sw_if_index %d", &sw_if_index))
6231         sw_if_index_set = 1;
6232       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6233         sw_if_index_set = 1;
6234       else if (unformat (i, "vlan %d", &vlan_id))
6235         vlan_id_set = 1;
6236       else
6237         {
6238           clib_warning ("parse error '%U'", format_unformat_error, i);
6239           return -99;
6240         }
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index\n");
6246       return -99;
6247     }
6248
6249   if (vlan_id_set == 0)
6250     {
6251       errmsg ("missing vlan_id\n");
6252       return -99;
6253     }
6254   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6255
6256   mp->sw_if_index = ntohl (sw_if_index);
6257   mp->vlan_id = ntohl (vlan_id);
6258
6259   S;
6260   W;
6261   /* NOTREACHED */
6262   return 0;
6263 }
6264
6265 #define foreach_create_subif_bit                \
6266 _(no_tags)                                      \
6267 _(one_tag)                                      \
6268 _(two_tags)                                     \
6269 _(dot1ad)                                       \
6270 _(exact_match)                                  \
6271 _(default_sub)                                  \
6272 _(outer_vlan_id_any)                            \
6273 _(inner_vlan_id_any)
6274
6275 static int
6276 api_create_subif (vat_main_t * vam)
6277 {
6278   unformat_input_t *i = vam->input;
6279   vl_api_create_subif_t *mp;
6280   f64 timeout;
6281   u32 sw_if_index;
6282   u8 sw_if_index_set = 0;
6283   u32 sub_id;
6284   u8 sub_id_set = 0;
6285   u32 no_tags = 0;
6286   u32 one_tag = 0;
6287   u32 two_tags = 0;
6288   u32 dot1ad = 0;
6289   u32 exact_match = 0;
6290   u32 default_sub = 0;
6291   u32 outer_vlan_id_any = 0;
6292   u32 inner_vlan_id_any = 0;
6293   u32 tmp;
6294   u16 outer_vlan_id = 0;
6295   u16 inner_vlan_id = 0;
6296
6297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6298     {
6299       if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "sub_id %d", &sub_id))
6304         sub_id_set = 1;
6305       else if (unformat (i, "outer_vlan_id %d", &tmp))
6306         outer_vlan_id = tmp;
6307       else if (unformat (i, "inner_vlan_id %d", &tmp))
6308         inner_vlan_id = tmp;
6309
6310 #define _(a) else if (unformat (i, #a)) a = 1 ;
6311       foreach_create_subif_bit
6312 #undef _
6313         else
6314         {
6315           clib_warning ("parse error '%U'", format_unformat_error, i);
6316           return -99;
6317         }
6318     }
6319
6320   if (sw_if_index_set == 0)
6321     {
6322       errmsg ("missing interface name or sw_if_index\n");
6323       return -99;
6324     }
6325
6326   if (sub_id_set == 0)
6327     {
6328       errmsg ("missing sub_id\n");
6329       return -99;
6330     }
6331   M (CREATE_SUBIF, create_subif);
6332
6333   mp->sw_if_index = ntohl (sw_if_index);
6334   mp->sub_id = ntohl (sub_id);
6335
6336 #define _(a) mp->a = a;
6337   foreach_create_subif_bit;
6338 #undef _
6339
6340   mp->outer_vlan_id = ntohs (outer_vlan_id);
6341   mp->inner_vlan_id = ntohs (inner_vlan_id);
6342
6343   S;
6344   W;
6345   /* NOTREACHED */
6346   return 0;
6347 }
6348
6349 static int
6350 api_oam_add_del (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_oam_add_del_t *mp;
6354   f64 timeout;
6355   u32 vrf_id = 0;
6356   u8 is_add = 1;
6357   ip4_address_t src, dst;
6358   u8 src_set = 0;
6359   u8 dst_set = 0;
6360
6361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6362     {
6363       if (unformat (i, "vrf %d", &vrf_id))
6364         ;
6365       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6366         src_set = 1;
6367       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6368         dst_set = 1;
6369       else if (unformat (i, "del"))
6370         is_add = 0;
6371       else
6372         {
6373           clib_warning ("parse error '%U'", format_unformat_error, i);
6374           return -99;
6375         }
6376     }
6377
6378   if (src_set == 0)
6379     {
6380       errmsg ("missing src addr\n");
6381       return -99;
6382     }
6383
6384   if (dst_set == 0)
6385     {
6386       errmsg ("missing dst addr\n");
6387       return -99;
6388     }
6389
6390   M (OAM_ADD_DEL, oam_add_del);
6391
6392   mp->vrf_id = ntohl (vrf_id);
6393   mp->is_add = is_add;
6394   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6395   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6396
6397   S;
6398   W;
6399   /* NOTREACHED */
6400   return 0;
6401 }
6402
6403 static int
6404 api_reset_fib (vat_main_t * vam)
6405 {
6406   unformat_input_t *i = vam->input;
6407   vl_api_reset_fib_t *mp;
6408   f64 timeout;
6409   u32 vrf_id = 0;
6410   u8 is_ipv6 = 0;
6411   u8 vrf_id_set = 0;
6412
6413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6414     {
6415       if (unformat (i, "vrf %d", &vrf_id))
6416         vrf_id_set = 1;
6417       else if (unformat (i, "ipv6"))
6418         is_ipv6 = 1;
6419       else
6420         {
6421           clib_warning ("parse error '%U'", format_unformat_error, i);
6422           return -99;
6423         }
6424     }
6425
6426   if (vrf_id_set == 0)
6427     {
6428       errmsg ("missing vrf id\n");
6429       return -99;
6430     }
6431
6432   M (RESET_FIB, reset_fib);
6433
6434   mp->vrf_id = ntohl (vrf_id);
6435   mp->is_ipv6 = is_ipv6;
6436
6437   S;
6438   W;
6439   /* NOTREACHED */
6440   return 0;
6441 }
6442
6443 static int
6444 api_dhcp_proxy_config (vat_main_t * vam)
6445 {
6446   unformat_input_t *i = vam->input;
6447   vl_api_dhcp_proxy_config_t *mp;
6448   f64 timeout;
6449   u32 vrf_id = 0;
6450   u8 is_add = 1;
6451   u8 insert_cid = 1;
6452   u8 v4_address_set = 0;
6453   u8 v6_address_set = 0;
6454   ip4_address_t v4address;
6455   ip6_address_t v6address;
6456   u8 v4_src_address_set = 0;
6457   u8 v6_src_address_set = 0;
6458   ip4_address_t v4srcaddress;
6459   ip6_address_t v6srcaddress;
6460
6461   /* Parse args required to build the message */
6462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6463     {
6464       if (unformat (i, "del"))
6465         is_add = 0;
6466       else if (unformat (i, "vrf %d", &vrf_id))
6467         ;
6468       else if (unformat (i, "insert-cid %d", &insert_cid))
6469         ;
6470       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6471         v4_address_set = 1;
6472       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6473         v6_address_set = 1;
6474       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6475         v4_src_address_set = 1;
6476       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6477         v6_src_address_set = 1;
6478       else
6479         break;
6480     }
6481
6482   if (v4_address_set && v6_address_set)
6483     {
6484       errmsg ("both v4 and v6 server addresses set\n");
6485       return -99;
6486     }
6487   if (!v4_address_set && !v6_address_set)
6488     {
6489       errmsg ("no server addresses set\n");
6490       return -99;
6491     }
6492
6493   if (v4_src_address_set && v6_src_address_set)
6494     {
6495       errmsg ("both v4 and v6  src addresses set\n");
6496       return -99;
6497     }
6498   if (!v4_src_address_set && !v6_src_address_set)
6499     {
6500       errmsg ("no src addresses set\n");
6501       return -99;
6502     }
6503
6504   if (!(v4_src_address_set && v4_address_set) &&
6505       !(v6_src_address_set && v6_address_set))
6506     {
6507       errmsg ("no matching server and src addresses set\n");
6508       return -99;
6509     }
6510
6511   /* Construct the API message */
6512   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6513
6514   mp->insert_circuit_id = insert_cid;
6515   mp->is_add = is_add;
6516   mp->vrf_id = ntohl (vrf_id);
6517   if (v6_address_set)
6518     {
6519       mp->is_ipv6 = 1;
6520       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6521       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6522     }
6523   else
6524     {
6525       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6526       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6527     }
6528
6529   /* send it... */
6530   S;
6531
6532   /* Wait for a reply, return good/bad news  */
6533   W;
6534   /* NOTREACHED */
6535   return 0;
6536 }
6537
6538 static int
6539 api_dhcp_proxy_config_2 (vat_main_t * vam)
6540 {
6541   unformat_input_t *i = vam->input;
6542   vl_api_dhcp_proxy_config_2_t *mp;
6543   f64 timeout;
6544   u32 rx_vrf_id = 0;
6545   u32 server_vrf_id = 0;
6546   u8 is_add = 1;
6547   u8 insert_cid = 1;
6548   u8 v4_address_set = 0;
6549   u8 v6_address_set = 0;
6550   ip4_address_t v4address;
6551   ip6_address_t v6address;
6552   u8 v4_src_address_set = 0;
6553   u8 v6_src_address_set = 0;
6554   ip4_address_t v4srcaddress;
6555   ip6_address_t v6srcaddress;
6556
6557   /* Parse args required to build the message */
6558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559     {
6560       if (unformat (i, "del"))
6561         is_add = 0;
6562       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6563         ;
6564       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6565         ;
6566       else if (unformat (i, "insert-cid %d", &insert_cid))
6567         ;
6568       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6569         v4_address_set = 1;
6570       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6571         v6_address_set = 1;
6572       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6573         v4_src_address_set = 1;
6574       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6575         v6_src_address_set = 1;
6576       else
6577         break;
6578     }
6579
6580   if (v4_address_set && v6_address_set)
6581     {
6582       errmsg ("both v4 and v6 server addresses set\n");
6583       return -99;
6584     }
6585   if (!v4_address_set && !v6_address_set)
6586     {
6587       errmsg ("no server addresses set\n");
6588       return -99;
6589     }
6590
6591   if (v4_src_address_set && v6_src_address_set)
6592     {
6593       errmsg ("both v4 and v6  src addresses set\n");
6594       return -99;
6595     }
6596   if (!v4_src_address_set && !v6_src_address_set)
6597     {
6598       errmsg ("no src addresses set\n");
6599       return -99;
6600     }
6601
6602   if (!(v4_src_address_set && v4_address_set) &&
6603       !(v6_src_address_set && v6_address_set))
6604     {
6605       errmsg ("no matching server and src addresses set\n");
6606       return -99;
6607     }
6608
6609   /* Construct the API message */
6610   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6611
6612   mp->insert_circuit_id = insert_cid;
6613   mp->is_add = is_add;
6614   mp->rx_vrf_id = ntohl (rx_vrf_id);
6615   mp->server_vrf_id = ntohl (server_vrf_id);
6616   if (v6_address_set)
6617     {
6618       mp->is_ipv6 = 1;
6619       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6620       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6621     }
6622   else
6623     {
6624       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6625       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6626     }
6627
6628   /* send it... */
6629   S;
6630
6631   /* Wait for a reply, return good/bad news  */
6632   W;
6633   /* NOTREACHED */
6634   return 0;
6635 }
6636
6637 static int
6638 api_dhcp_proxy_set_vss (vat_main_t * vam)
6639 {
6640   unformat_input_t *i = vam->input;
6641   vl_api_dhcp_proxy_set_vss_t *mp;
6642   f64 timeout;
6643   u8 is_ipv6 = 0;
6644   u8 is_add = 1;
6645   u32 tbl_id;
6646   u8 tbl_id_set = 0;
6647   u32 oui;
6648   u8 oui_set = 0;
6649   u32 fib_id;
6650   u8 fib_id_set = 0;
6651
6652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6653     {
6654       if (unformat (i, "tbl_id %d", &tbl_id))
6655         tbl_id_set = 1;
6656       if (unformat (i, "fib_id %d", &fib_id))
6657         fib_id_set = 1;
6658       if (unformat (i, "oui %d", &oui))
6659         oui_set = 1;
6660       else if (unformat (i, "ipv6"))
6661         is_ipv6 = 1;
6662       else if (unformat (i, "del"))
6663         is_add = 0;
6664       else
6665         {
6666           clib_warning ("parse error '%U'", format_unformat_error, i);
6667           return -99;
6668         }
6669     }
6670
6671   if (tbl_id_set == 0)
6672     {
6673       errmsg ("missing tbl id\n");
6674       return -99;
6675     }
6676
6677   if (fib_id_set == 0)
6678     {
6679       errmsg ("missing fib id\n");
6680       return -99;
6681     }
6682   if (oui_set == 0)
6683     {
6684       errmsg ("missing oui\n");
6685       return -99;
6686     }
6687
6688   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6689   mp->tbl_id = ntohl (tbl_id);
6690   mp->fib_id = ntohl (fib_id);
6691   mp->oui = ntohl (oui);
6692   mp->is_ipv6 = is_ipv6;
6693   mp->is_add = is_add;
6694
6695   S;
6696   W;
6697   /* NOTREACHED */
6698   return 0;
6699 }
6700
6701 static int
6702 api_dhcp_client_config (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_dhcp_client_config_t *mp;
6706   f64 timeout;
6707   u32 sw_if_index;
6708   u8 sw_if_index_set = 0;
6709   u8 is_add = 1;
6710   u8 *hostname = 0;
6711   u8 disable_event = 0;
6712
6713   /* Parse args required to build the message */
6714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6715     {
6716       if (unformat (i, "del"))
6717         is_add = 0;
6718       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6719         sw_if_index_set = 1;
6720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6721         sw_if_index_set = 1;
6722       else if (unformat (i, "hostname %s", &hostname))
6723         ;
6724       else if (unformat (i, "disable_event"))
6725         disable_event = 1;
6726       else
6727         break;
6728     }
6729
6730   if (sw_if_index_set == 0)
6731     {
6732       errmsg ("missing interface name or sw_if_index\n");
6733       return -99;
6734     }
6735
6736   if (vec_len (hostname) > 63)
6737     {
6738       errmsg ("hostname too long\n");
6739     }
6740   vec_add1 (hostname, 0);
6741
6742   /* Construct the API message */
6743   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6744
6745   mp->sw_if_index = ntohl (sw_if_index);
6746   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6747   vec_free (hostname);
6748   mp->is_add = is_add;
6749   mp->want_dhcp_event = disable_event ? 0 : 1;
6750   mp->pid = getpid ();
6751
6752   /* send it... */
6753   S;
6754
6755   /* Wait for a reply, return good/bad news  */
6756   W;
6757   /* NOTREACHED */
6758   return 0;
6759 }
6760
6761 static int
6762 api_set_ip_flow_hash (vat_main_t * vam)
6763 {
6764   unformat_input_t *i = vam->input;
6765   vl_api_set_ip_flow_hash_t *mp;
6766   f64 timeout;
6767   u32 vrf_id = 0;
6768   u8 is_ipv6 = 0;
6769   u8 vrf_id_set = 0;
6770   u8 src = 0;
6771   u8 dst = 0;
6772   u8 sport = 0;
6773   u8 dport = 0;
6774   u8 proto = 0;
6775   u8 reverse = 0;
6776
6777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6778     {
6779       if (unformat (i, "vrf %d", &vrf_id))
6780         vrf_id_set = 1;
6781       else if (unformat (i, "ipv6"))
6782         is_ipv6 = 1;
6783       else if (unformat (i, "src"))
6784         src = 1;
6785       else if (unformat (i, "dst"))
6786         dst = 1;
6787       else if (unformat (i, "sport"))
6788         sport = 1;
6789       else if (unformat (i, "dport"))
6790         dport = 1;
6791       else if (unformat (i, "proto"))
6792         proto = 1;
6793       else if (unformat (i, "reverse"))
6794         reverse = 1;
6795
6796       else
6797         {
6798           clib_warning ("parse error '%U'", format_unformat_error, i);
6799           return -99;
6800         }
6801     }
6802
6803   if (vrf_id_set == 0)
6804     {
6805       errmsg ("missing vrf id\n");
6806       return -99;
6807     }
6808
6809   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6810   mp->src = src;
6811   mp->dst = dst;
6812   mp->sport = sport;
6813   mp->dport = dport;
6814   mp->proto = proto;
6815   mp->reverse = reverse;
6816   mp->vrf_id = ntohl (vrf_id);
6817   mp->is_ipv6 = is_ipv6;
6818
6819   S;
6820   W;
6821   /* NOTREACHED */
6822   return 0;
6823 }
6824
6825 static int
6826 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_sw_interface_ip6_enable_disable_t *mp;
6830   f64 timeout;
6831   u32 sw_if_index;
6832   u8 sw_if_index_set = 0;
6833   u8 enable = 0;
6834
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "enable"))
6842         enable = 1;
6843       else if (unformat (i, "disable"))
6844         enable = 0;
6845       else
6846         {
6847           clib_warning ("parse error '%U'", format_unformat_error, i);
6848           return -99;
6849         }
6850     }
6851
6852   if (sw_if_index_set == 0)
6853     {
6854       errmsg ("missing interface name or sw_if_index\n");
6855       return -99;
6856     }
6857
6858   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6859
6860   mp->sw_if_index = ntohl (sw_if_index);
6861   mp->enable = enable;
6862
6863   S;
6864   W;
6865   /* NOTREACHED */
6866   return 0;
6867 }
6868
6869 static int
6870 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6871 {
6872   unformat_input_t *i = vam->input;
6873   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6874   f64 timeout;
6875   u32 sw_if_index;
6876   u8 sw_if_index_set = 0;
6877   u32 address_length = 0;
6878   u8 v6_address_set = 0;
6879   ip6_address_t v6address;
6880
6881   /* Parse args required to build the message */
6882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6883     {
6884       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6885         sw_if_index_set = 1;
6886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6887         sw_if_index_set = 1;
6888       else if (unformat (i, "%U/%d",
6889                          unformat_ip6_address, &v6address, &address_length))
6890         v6_address_set = 1;
6891       else
6892         break;
6893     }
6894
6895   if (sw_if_index_set == 0)
6896     {
6897       errmsg ("missing interface name or sw_if_index\n");
6898       return -99;
6899     }
6900   if (!v6_address_set)
6901     {
6902       errmsg ("no address set\n");
6903       return -99;
6904     }
6905
6906   /* Construct the API message */
6907   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6908      sw_interface_ip6_set_link_local_address);
6909
6910   mp->sw_if_index = ntohl (sw_if_index);
6911   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6912   mp->address_length = address_length;
6913
6914   /* send it... */
6915   S;
6916
6917   /* Wait for a reply, return good/bad news  */
6918   W;
6919
6920   /* NOTREACHED */
6921   return 0;
6922 }
6923
6924
6925 static int
6926 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6927 {
6928   unformat_input_t *i = vam->input;
6929   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6930   f64 timeout;
6931   u32 sw_if_index;
6932   u8 sw_if_index_set = 0;
6933   u32 address_length = 0;
6934   u8 v6_address_set = 0;
6935   ip6_address_t v6address;
6936   u8 use_default = 0;
6937   u8 no_advertise = 0;
6938   u8 off_link = 0;
6939   u8 no_autoconfig = 0;
6940   u8 no_onlink = 0;
6941   u8 is_no = 0;
6942   u32 val_lifetime = 0;
6943   u32 pref_lifetime = 0;
6944
6945   /* Parse args required to build the message */
6946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6947     {
6948       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6949         sw_if_index_set = 1;
6950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6951         sw_if_index_set = 1;
6952       else if (unformat (i, "%U/%d",
6953                          unformat_ip6_address, &v6address, &address_length))
6954         v6_address_set = 1;
6955       else if (unformat (i, "val_life %d", &val_lifetime))
6956         ;
6957       else if (unformat (i, "pref_life %d", &pref_lifetime))
6958         ;
6959       else if (unformat (i, "def"))
6960         use_default = 1;
6961       else if (unformat (i, "noadv"))
6962         no_advertise = 1;
6963       else if (unformat (i, "offl"))
6964         off_link = 1;
6965       else if (unformat (i, "noauto"))
6966         no_autoconfig = 1;
6967       else if (unformat (i, "nolink"))
6968         no_onlink = 1;
6969       else if (unformat (i, "isno"))
6970         is_no = 1;
6971       else
6972         {
6973           clib_warning ("parse error '%U'", format_unformat_error, i);
6974           return -99;
6975         }
6976     }
6977
6978   if (sw_if_index_set == 0)
6979     {
6980       errmsg ("missing interface name or sw_if_index\n");
6981       return -99;
6982     }
6983   if (!v6_address_set)
6984     {
6985       errmsg ("no address set\n");
6986       return -99;
6987     }
6988
6989   /* Construct the API message */
6990   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6991
6992   mp->sw_if_index = ntohl (sw_if_index);
6993   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6994   mp->address_length = address_length;
6995   mp->use_default = use_default;
6996   mp->no_advertise = no_advertise;
6997   mp->off_link = off_link;
6998   mp->no_autoconfig = no_autoconfig;
6999   mp->no_onlink = no_onlink;
7000   mp->is_no = is_no;
7001   mp->val_lifetime = ntohl (val_lifetime);
7002   mp->pref_lifetime = ntohl (pref_lifetime);
7003
7004   /* send it... */
7005   S;
7006
7007   /* Wait for a reply, return good/bad news  */
7008   W;
7009
7010   /* NOTREACHED */
7011   return 0;
7012 }
7013
7014 static int
7015 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7016 {
7017   unformat_input_t *i = vam->input;
7018   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7019   f64 timeout;
7020   u32 sw_if_index;
7021   u8 sw_if_index_set = 0;
7022   u8 suppress = 0;
7023   u8 managed = 0;
7024   u8 other = 0;
7025   u8 ll_option = 0;
7026   u8 send_unicast = 0;
7027   u8 cease = 0;
7028   u8 is_no = 0;
7029   u8 default_router = 0;
7030   u32 max_interval = 0;
7031   u32 min_interval = 0;
7032   u32 lifetime = 0;
7033   u32 initial_count = 0;
7034   u32 initial_interval = 0;
7035
7036
7037   /* Parse args required to build the message */
7038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7039     {
7040       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7041         sw_if_index_set = 1;
7042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7043         sw_if_index_set = 1;
7044       else if (unformat (i, "maxint %d", &max_interval))
7045         ;
7046       else if (unformat (i, "minint %d", &min_interval))
7047         ;
7048       else if (unformat (i, "life %d", &lifetime))
7049         ;
7050       else if (unformat (i, "count %d", &initial_count))
7051         ;
7052       else if (unformat (i, "interval %d", &initial_interval))
7053         ;
7054       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7055         suppress = 1;
7056       else if (unformat (i, "managed"))
7057         managed = 1;
7058       else if (unformat (i, "other"))
7059         other = 1;
7060       else if (unformat (i, "ll"))
7061         ll_option = 1;
7062       else if (unformat (i, "send"))
7063         send_unicast = 1;
7064       else if (unformat (i, "cease"))
7065         cease = 1;
7066       else if (unformat (i, "isno"))
7067         is_no = 1;
7068       else if (unformat (i, "def"))
7069         default_router = 1;
7070       else
7071         {
7072           clib_warning ("parse error '%U'", format_unformat_error, i);
7073           return -99;
7074         }
7075     }
7076
7077   if (sw_if_index_set == 0)
7078     {
7079       errmsg ("missing interface name or sw_if_index\n");
7080       return -99;
7081     }
7082
7083   /* Construct the API message */
7084   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7085
7086   mp->sw_if_index = ntohl (sw_if_index);
7087   mp->max_interval = ntohl (max_interval);
7088   mp->min_interval = ntohl (min_interval);
7089   mp->lifetime = ntohl (lifetime);
7090   mp->initial_count = ntohl (initial_count);
7091   mp->initial_interval = ntohl (initial_interval);
7092   mp->suppress = suppress;
7093   mp->managed = managed;
7094   mp->other = other;
7095   mp->ll_option = ll_option;
7096   mp->send_unicast = send_unicast;
7097   mp->cease = cease;
7098   mp->is_no = is_no;
7099   mp->default_router = default_router;
7100
7101   /* send it... */
7102   S;
7103
7104   /* Wait for a reply, return good/bad news  */
7105   W;
7106
7107   /* NOTREACHED */
7108   return 0;
7109 }
7110
7111 static int
7112 api_set_arp_neighbor_limit (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_set_arp_neighbor_limit_t *mp;
7116   f64 timeout;
7117   u32 arp_nbr_limit;
7118   u8 limit_set = 0;
7119   u8 is_ipv6 = 0;
7120
7121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7122     {
7123       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7124         limit_set = 1;
7125       else if (unformat (i, "ipv6"))
7126         is_ipv6 = 1;
7127       else
7128         {
7129           clib_warning ("parse error '%U'", format_unformat_error, i);
7130           return -99;
7131         }
7132     }
7133
7134   if (limit_set == 0)
7135     {
7136       errmsg ("missing limit value\n");
7137       return -99;
7138     }
7139
7140   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7141
7142   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7143   mp->is_ipv6 = is_ipv6;
7144
7145   S;
7146   W;
7147   /* NOTREACHED */
7148   return 0;
7149 }
7150
7151 static int
7152 api_l2_patch_add_del (vat_main_t * vam)
7153 {
7154   unformat_input_t *i = vam->input;
7155   vl_api_l2_patch_add_del_t *mp;
7156   f64 timeout;
7157   u32 rx_sw_if_index;
7158   u8 rx_sw_if_index_set = 0;
7159   u32 tx_sw_if_index;
7160   u8 tx_sw_if_index_set = 0;
7161   u8 is_add = 1;
7162
7163   /* Parse args required to build the message */
7164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7165     {
7166       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7167         rx_sw_if_index_set = 1;
7168       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7169         tx_sw_if_index_set = 1;
7170       else if (unformat (i, "rx"))
7171         {
7172           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7173             {
7174               if (unformat (i, "%U", unformat_sw_if_index, vam,
7175                             &rx_sw_if_index))
7176                 rx_sw_if_index_set = 1;
7177             }
7178           else
7179             break;
7180         }
7181       else if (unformat (i, "tx"))
7182         {
7183           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184             {
7185               if (unformat (i, "%U", unformat_sw_if_index, vam,
7186                             &tx_sw_if_index))
7187                 tx_sw_if_index_set = 1;
7188             }
7189           else
7190             break;
7191         }
7192       else if (unformat (i, "del"))
7193         is_add = 0;
7194       else
7195         break;
7196     }
7197
7198   if (rx_sw_if_index_set == 0)
7199     {
7200       errmsg ("missing rx interface name or rx_sw_if_index\n");
7201       return -99;
7202     }
7203
7204   if (tx_sw_if_index_set == 0)
7205     {
7206       errmsg ("missing tx interface name or tx_sw_if_index\n");
7207       return -99;
7208     }
7209
7210   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7211
7212   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7213   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7214   mp->is_add = is_add;
7215
7216   S;
7217   W;
7218   /* NOTREACHED */
7219   return 0;
7220 }
7221
7222 static int
7223 api_ioam_enable (vat_main_t * vam)
7224 {
7225   unformat_input_t *input = vam->input;
7226   vl_api_ioam_enable_t *mp;
7227   f64 timeout;
7228   u32 id = 0;
7229   int has_trace_option = 0;
7230   int has_pow_option = 0;
7231   int has_ppc_option = 0;
7232
7233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7234     {
7235       if (unformat (input, "trace"))
7236         has_trace_option = 1;
7237       else if (unformat (input, "pow"))
7238         has_pow_option = 1;
7239       else if (unformat (input, "ppc encap"))
7240         has_ppc_option = PPC_ENCAP;
7241       else if (unformat (input, "ppc decap"))
7242         has_ppc_option = PPC_DECAP;
7243       else if (unformat (input, "ppc none"))
7244         has_ppc_option = PPC_NONE;
7245       else
7246         break;
7247     }
7248   M (IOAM_ENABLE, ioam_enable);
7249   mp->id = htons (id);
7250   mp->trace_ppc = has_ppc_option;
7251   mp->pow_enable = has_pow_option;
7252   mp->trace_enable = has_trace_option;
7253
7254   S;
7255   W;
7256
7257   return (0);
7258
7259 }
7260
7261
7262 static int
7263 api_ioam_disable (vat_main_t * vam)
7264 {
7265   vl_api_ioam_disable_t *mp;
7266   f64 timeout;
7267
7268   M (IOAM_DISABLE, ioam_disable);
7269   S;
7270   W;
7271   return 0;
7272 }
7273
7274 static int
7275 api_sr_tunnel_add_del (vat_main_t * vam)
7276 {
7277   unformat_input_t *i = vam->input;
7278   vl_api_sr_tunnel_add_del_t *mp;
7279   f64 timeout;
7280   int is_del = 0;
7281   int pl_index;
7282   ip6_address_t src_address;
7283   int src_address_set = 0;
7284   ip6_address_t dst_address;
7285   u32 dst_mask_width;
7286   int dst_address_set = 0;
7287   u16 flags = 0;
7288   u32 rx_table_id = 0;
7289   u32 tx_table_id = 0;
7290   ip6_address_t *segments = 0;
7291   ip6_address_t *this_seg;
7292   ip6_address_t *tags = 0;
7293   ip6_address_t *this_tag;
7294   ip6_address_t next_address, tag;
7295   u8 *name = 0;
7296   u8 *policy_name = 0;
7297
7298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7299     {
7300       if (unformat (i, "del"))
7301         is_del = 1;
7302       else if (unformat (i, "name %s", &name))
7303         ;
7304       else if (unformat (i, "policy %s", &policy_name))
7305         ;
7306       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7307         ;
7308       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7309         ;
7310       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7311         src_address_set = 1;
7312       else if (unformat (i, "dst %U/%d",
7313                          unformat_ip6_address, &dst_address, &dst_mask_width))
7314         dst_address_set = 1;
7315       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7316         {
7317           vec_add2 (segments, this_seg, 1);
7318           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7319                        sizeof (*this_seg));
7320         }
7321       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7322         {
7323           vec_add2 (tags, this_tag, 1);
7324           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7325         }
7326       else if (unformat (i, "clean"))
7327         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7328       else if (unformat (i, "protected"))
7329         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7330       else if (unformat (i, "InPE %d", &pl_index))
7331         {
7332           if (pl_index <= 0 || pl_index > 4)
7333             {
7334             pl_index_range_error:
7335               errmsg ("pl index %d out of range\n", pl_index);
7336               return -99;
7337             }
7338           flags |=
7339             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7340         }
7341       else if (unformat (i, "EgPE %d", &pl_index))
7342         {
7343           if (pl_index <= 0 || pl_index > 4)
7344             goto pl_index_range_error;
7345           flags |=
7346             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7347         }
7348       else if (unformat (i, "OrgSrc %d", &pl_index))
7349         {
7350           if (pl_index <= 0 || pl_index > 4)
7351             goto pl_index_range_error;
7352           flags |=
7353             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7354         }
7355       else
7356         break;
7357     }
7358
7359   if (!src_address_set)
7360     {
7361       errmsg ("src address required\n");
7362       return -99;
7363     }
7364
7365   if (!dst_address_set)
7366     {
7367       errmsg ("dst address required\n");
7368       return -99;
7369     }
7370
7371   if (!segments)
7372     {
7373       errmsg ("at least one sr segment required\n");
7374       return -99;
7375     }
7376
7377   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7378       vec_len (segments) * sizeof (ip6_address_t)
7379       + vec_len (tags) * sizeof (ip6_address_t));
7380
7381   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7382   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7383   mp->dst_mask_width = dst_mask_width;
7384   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7385   mp->n_segments = vec_len (segments);
7386   mp->n_tags = vec_len (tags);
7387   mp->is_add = is_del == 0;
7388   clib_memcpy (mp->segs_and_tags, segments,
7389                vec_len (segments) * sizeof (ip6_address_t));
7390   clib_memcpy (mp->segs_and_tags +
7391                vec_len (segments) * sizeof (ip6_address_t), tags,
7392                vec_len (tags) * sizeof (ip6_address_t));
7393
7394   mp->outer_vrf_id = ntohl (rx_table_id);
7395   mp->inner_vrf_id = ntohl (tx_table_id);
7396   memcpy (mp->name, name, vec_len (name));
7397   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7398
7399   vec_free (segments);
7400   vec_free (tags);
7401
7402   S;
7403   W;
7404   /* NOTREACHED */
7405 }
7406
7407 static int
7408 api_sr_policy_add_del (vat_main_t * vam)
7409 {
7410   unformat_input_t *input = vam->input;
7411   vl_api_sr_policy_add_del_t *mp;
7412   f64 timeout;
7413   int is_del = 0;
7414   u8 *name = 0;
7415   u8 *tunnel_name = 0;
7416   u8 **tunnel_names = 0;
7417
7418   int name_set = 0;
7419   int tunnel_set = 0;
7420   int j = 0;
7421   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7422   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7423
7424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7425     {
7426       if (unformat (input, "del"))
7427         is_del = 1;
7428       else if (unformat (input, "name %s", &name))
7429         name_set = 1;
7430       else if (unformat (input, "tunnel %s", &tunnel_name))
7431         {
7432           if (tunnel_name)
7433             {
7434               vec_add1 (tunnel_names, tunnel_name);
7435               /* For serializer:
7436                  - length = #bytes to store in serial vector
7437                  - +1 = byte to store that length
7438                */
7439               tunnel_names_length += (vec_len (tunnel_name) + 1);
7440               tunnel_set = 1;
7441               tunnel_name = 0;
7442             }
7443         }
7444       else
7445         break;
7446     }
7447
7448   if (!name_set)
7449     {
7450       errmsg ("policy name required\n");
7451       return -99;
7452     }
7453
7454   if ((!tunnel_set) && (!is_del))
7455     {
7456       errmsg ("tunnel name required\n");
7457       return -99;
7458     }
7459
7460   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7461
7462
7463
7464   mp->is_add = !is_del;
7465
7466   memcpy (mp->name, name, vec_len (name));
7467   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7468   u8 *serial_orig = 0;
7469   vec_validate (serial_orig, tunnel_names_length);
7470   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7471   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7472
7473   for (j = 0; j < vec_len (tunnel_names); j++)
7474     {
7475       tun_name_len = vec_len (tunnel_names[j]);
7476       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7477       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7478       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7479       serial_orig += tun_name_len;      // Advance past the copy
7480     }
7481   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7482
7483   vec_free (tunnel_names);
7484   vec_free (tunnel_name);
7485
7486   S;
7487   W;
7488   /* NOTREACHED */
7489 }
7490
7491 static int
7492 api_sr_multicast_map_add_del (vat_main_t * vam)
7493 {
7494   unformat_input_t *input = vam->input;
7495   vl_api_sr_multicast_map_add_del_t *mp;
7496   f64 timeout;
7497   int is_del = 0;
7498   ip6_address_t multicast_address;
7499   u8 *policy_name = 0;
7500   int multicast_address_set = 0;
7501
7502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7503     {
7504       if (unformat (input, "del"))
7505         is_del = 1;
7506       else
7507         if (unformat
7508             (input, "address %U", unformat_ip6_address, &multicast_address))
7509         multicast_address_set = 1;
7510       else if (unformat (input, "sr-policy %s", &policy_name))
7511         ;
7512       else
7513         break;
7514     }
7515
7516   if (!is_del && !policy_name)
7517     {
7518       errmsg ("sr-policy name required\n");
7519       return -99;
7520     }
7521
7522
7523   if (!multicast_address_set)
7524     {
7525       errmsg ("address required\n");
7526       return -99;
7527     }
7528
7529   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7530
7531   mp->is_add = !is_del;
7532   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7533   clib_memcpy (mp->multicast_address, &multicast_address,
7534                sizeof (mp->multicast_address));
7535
7536
7537   vec_free (policy_name);
7538
7539   S;
7540   W;
7541   /* NOTREACHED */
7542 }
7543
7544
7545 #define foreach_ip4_proto_field                 \
7546 _(src_address)                                  \
7547 _(dst_address)                                  \
7548 _(tos)                                          \
7549 _(length)                                       \
7550 _(fragment_id)                                  \
7551 _(ttl)                                          \
7552 _(protocol)                                     \
7553 _(checksum)
7554
7555 uword
7556 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7557 {
7558   u8 **maskp = va_arg (*args, u8 **);
7559   u8 *mask = 0;
7560   u8 found_something = 0;
7561   ip4_header_t *ip;
7562
7563 #define _(a) u8 a=0;
7564   foreach_ip4_proto_field;
7565 #undef _
7566   u8 version = 0;
7567   u8 hdr_length = 0;
7568
7569
7570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7571     {
7572       if (unformat (input, "version"))
7573         version = 1;
7574       else if (unformat (input, "hdr_length"))
7575         hdr_length = 1;
7576       else if (unformat (input, "src"))
7577         src_address = 1;
7578       else if (unformat (input, "dst"))
7579         dst_address = 1;
7580       else if (unformat (input, "proto"))
7581         protocol = 1;
7582
7583 #define _(a) else if (unformat (input, #a)) a=1;
7584       foreach_ip4_proto_field
7585 #undef _
7586         else
7587         break;
7588     }
7589
7590 #define _(a) found_something += a;
7591   foreach_ip4_proto_field;
7592 #undef _
7593
7594   if (found_something == 0)
7595     return 0;
7596
7597   vec_validate (mask, sizeof (*ip) - 1);
7598
7599   ip = (ip4_header_t *) mask;
7600
7601 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7602   foreach_ip4_proto_field;
7603 #undef _
7604
7605   ip->ip_version_and_header_length = 0;
7606
7607   if (version)
7608     ip->ip_version_and_header_length |= 0xF0;
7609
7610   if (hdr_length)
7611     ip->ip_version_and_header_length |= 0x0F;
7612
7613   *maskp = mask;
7614   return 1;
7615 }
7616
7617 #define foreach_ip6_proto_field                 \
7618 _(src_address)                                  \
7619 _(dst_address)                                  \
7620 _(payload_length)                               \
7621 _(hop_limit)                                    \
7622 _(protocol)
7623
7624 uword
7625 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7626 {
7627   u8 **maskp = va_arg (*args, u8 **);
7628   u8 *mask = 0;
7629   u8 found_something = 0;
7630   ip6_header_t *ip;
7631   u32 ip_version_traffic_class_and_flow_label;
7632
7633 #define _(a) u8 a=0;
7634   foreach_ip6_proto_field;
7635 #undef _
7636   u8 version = 0;
7637   u8 traffic_class = 0;
7638   u8 flow_label = 0;
7639
7640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7641     {
7642       if (unformat (input, "version"))
7643         version = 1;
7644       else if (unformat (input, "traffic-class"))
7645         traffic_class = 1;
7646       else if (unformat (input, "flow-label"))
7647         flow_label = 1;
7648       else if (unformat (input, "src"))
7649         src_address = 1;
7650       else if (unformat (input, "dst"))
7651         dst_address = 1;
7652       else if (unformat (input, "proto"))
7653         protocol = 1;
7654
7655 #define _(a) else if (unformat (input, #a)) a=1;
7656       foreach_ip6_proto_field
7657 #undef _
7658         else
7659         break;
7660     }
7661
7662 #define _(a) found_something += a;
7663   foreach_ip6_proto_field;
7664 #undef _
7665
7666   if (found_something == 0)
7667     return 0;
7668
7669   vec_validate (mask, sizeof (*ip) - 1);
7670
7671   ip = (ip6_header_t *) mask;
7672
7673 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7674   foreach_ip6_proto_field;
7675 #undef _
7676
7677   ip_version_traffic_class_and_flow_label = 0;
7678
7679   if (version)
7680     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7681
7682   if (traffic_class)
7683     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7684
7685   if (flow_label)
7686     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7687
7688   ip->ip_version_traffic_class_and_flow_label =
7689     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7690
7691   *maskp = mask;
7692   return 1;
7693 }
7694
7695 uword
7696 unformat_l3_mask (unformat_input_t * input, va_list * args)
7697 {
7698   u8 **maskp = va_arg (*args, u8 **);
7699
7700   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7701     {
7702       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7703         return 1;
7704       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7705         return 1;
7706       else
7707         break;
7708     }
7709   return 0;
7710 }
7711
7712 uword
7713 unformat_l2_mask (unformat_input_t * input, va_list * args)
7714 {
7715   u8 **maskp = va_arg (*args, u8 **);
7716   u8 *mask = 0;
7717   u8 src = 0;
7718   u8 dst = 0;
7719   u8 proto = 0;
7720   u8 tag1 = 0;
7721   u8 tag2 = 0;
7722   u8 ignore_tag1 = 0;
7723   u8 ignore_tag2 = 0;
7724   u8 cos1 = 0;
7725   u8 cos2 = 0;
7726   u8 dot1q = 0;
7727   u8 dot1ad = 0;
7728   int len = 14;
7729
7730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7731     {
7732       if (unformat (input, "src"))
7733         src = 1;
7734       else if (unformat (input, "dst"))
7735         dst = 1;
7736       else if (unformat (input, "proto"))
7737         proto = 1;
7738       else if (unformat (input, "tag1"))
7739         tag1 = 1;
7740       else if (unformat (input, "tag2"))
7741         tag2 = 1;
7742       else if (unformat (input, "ignore-tag1"))
7743         ignore_tag1 = 1;
7744       else if (unformat (input, "ignore-tag2"))
7745         ignore_tag2 = 1;
7746       else if (unformat (input, "cos1"))
7747         cos1 = 1;
7748       else if (unformat (input, "cos2"))
7749         cos2 = 1;
7750       else if (unformat (input, "dot1q"))
7751         dot1q = 1;
7752       else if (unformat (input, "dot1ad"))
7753         dot1ad = 1;
7754       else
7755         break;
7756     }
7757   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7758        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7759     return 0;
7760
7761   if (tag1 || ignore_tag1 || cos1 || dot1q)
7762     len = 18;
7763   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7764     len = 22;
7765
7766   vec_validate (mask, len - 1);
7767
7768   if (dst)
7769     memset (mask, 0xff, 6);
7770
7771   if (src)
7772     memset (mask + 6, 0xff, 6);
7773
7774   if (tag2 || dot1ad)
7775     {
7776       /* inner vlan tag */
7777       if (tag2)
7778         {
7779           mask[19] = 0xff;
7780           mask[18] = 0x0f;
7781         }
7782       if (cos2)
7783         mask[18] |= 0xe0;
7784       if (proto)
7785         mask[21] = mask[20] = 0xff;
7786       if (tag1)
7787         {
7788           mask[15] = 0xff;
7789           mask[14] = 0x0f;
7790         }
7791       if (cos1)
7792         mask[14] |= 0xe0;
7793       *maskp = mask;
7794       return 1;
7795     }
7796   if (tag1 | dot1q)
7797     {
7798       if (tag1)
7799         {
7800           mask[15] = 0xff;
7801           mask[14] = 0x0f;
7802         }
7803       if (cos1)
7804         mask[14] |= 0xe0;
7805       if (proto)
7806         mask[16] = mask[17] = 0xff;
7807
7808       *maskp = mask;
7809       return 1;
7810     }
7811   if (cos2)
7812     mask[18] |= 0xe0;
7813   if (cos1)
7814     mask[14] |= 0xe0;
7815   if (proto)
7816     mask[12] = mask[13] = 0xff;
7817
7818   *maskp = mask;
7819   return 1;
7820 }
7821
7822 uword
7823 unformat_classify_mask (unformat_input_t * input, va_list * args)
7824 {
7825   u8 **maskp = va_arg (*args, u8 **);
7826   u32 *skipp = va_arg (*args, u32 *);
7827   u32 *matchp = va_arg (*args, u32 *);
7828   u32 match;
7829   u8 *mask = 0;
7830   u8 *l2 = 0;
7831   u8 *l3 = 0;
7832   int i;
7833
7834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7835     {
7836       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7837         ;
7838       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7839         ;
7840       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7841         ;
7842       else
7843         break;
7844     }
7845
7846   if (mask || l2 || l3)
7847     {
7848       if (l2 || l3)
7849         {
7850           /* "With a free Ethernet header in every package" */
7851           if (l2 == 0)
7852             vec_validate (l2, 13);
7853           mask = l2;
7854           if (vec_len (l3))
7855             {
7856               vec_append (mask, l3);
7857               vec_free (l3);
7858             }
7859         }
7860
7861       /* Scan forward looking for the first significant mask octet */
7862       for (i = 0; i < vec_len (mask); i++)
7863         if (mask[i])
7864           break;
7865
7866       /* compute (skip, match) params */
7867       *skipp = i / sizeof (u32x4);
7868       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7869
7870       /* Pad mask to an even multiple of the vector size */
7871       while (vec_len (mask) % sizeof (u32x4))
7872         vec_add1 (mask, 0);
7873
7874       match = vec_len (mask) / sizeof (u32x4);
7875
7876       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7877         {
7878           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7879           if (*tmp || *(tmp + 1))
7880             break;
7881           match--;
7882         }
7883       if (match == 0)
7884         clib_warning ("BUG: match 0");
7885
7886       _vec_len (mask) = match * sizeof (u32x4);
7887
7888       *matchp = match;
7889       *maskp = mask;
7890
7891       return 1;
7892     }
7893
7894   return 0;
7895 }
7896
7897 #define foreach_l2_next                         \
7898 _(drop, DROP)                                   \
7899 _(ethernet, ETHERNET_INPUT)                     \
7900 _(ip4, IP4_INPUT)                               \
7901 _(ip6, IP6_INPUT)
7902
7903 uword
7904 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7905 {
7906   u32 *miss_next_indexp = va_arg (*args, u32 *);
7907   u32 next_index = 0;
7908   u32 tmp;
7909
7910 #define _(n,N) \
7911   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7912   foreach_l2_next;
7913 #undef _
7914
7915   if (unformat (input, "%d", &tmp))
7916     {
7917       next_index = tmp;
7918       goto out;
7919     }
7920
7921   return 0;
7922
7923 out:
7924   *miss_next_indexp = next_index;
7925   return 1;
7926 }
7927
7928 #define foreach_ip_next                         \
7929 _(drop, DROP)                                   \
7930 _(local, LOCAL)                                 \
7931 _(rewrite, REWRITE)
7932
7933 uword
7934 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7935 {
7936   u32 *miss_next_indexp = va_arg (*args, u32 *);
7937   u32 next_index = 0;
7938   u32 tmp;
7939
7940 #define _(n,N) \
7941   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7942   foreach_ip_next;
7943 #undef _
7944
7945   if (unformat (input, "%d", &tmp))
7946     {
7947       next_index = tmp;
7948       goto out;
7949     }
7950
7951   return 0;
7952
7953 out:
7954   *miss_next_indexp = next_index;
7955   return 1;
7956 }
7957
7958 #define foreach_acl_next                        \
7959 _(deny, DENY)
7960
7961 uword
7962 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7963 {
7964   u32 *miss_next_indexp = va_arg (*args, u32 *);
7965   u32 next_index = 0;
7966   u32 tmp;
7967
7968 #define _(n,N) \
7969   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7970   foreach_acl_next;
7971 #undef _
7972
7973   if (unformat (input, "permit"))
7974     {
7975       next_index = ~0;
7976       goto out;
7977     }
7978   else if (unformat (input, "%d", &tmp))
7979     {
7980       next_index = tmp;
7981       goto out;
7982     }
7983
7984   return 0;
7985
7986 out:
7987   *miss_next_indexp = next_index;
7988   return 1;
7989 }
7990
7991 uword
7992 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7993 {
7994   u32 *r = va_arg (*args, u32 *);
7995
7996   if (unformat (input, "conform-color"))
7997     *r = POLICE_CONFORM;
7998   else if (unformat (input, "exceed-color"))
7999     *r = POLICE_EXCEED;
8000   else
8001     return 0;
8002
8003   return 1;
8004 }
8005
8006 static int
8007 api_classify_add_del_table (vat_main_t * vam)
8008 {
8009   unformat_input_t *i = vam->input;
8010   vl_api_classify_add_del_table_t *mp;
8011
8012   u32 nbuckets = 2;
8013   u32 skip = ~0;
8014   u32 match = ~0;
8015   int is_add = 1;
8016   u32 table_index = ~0;
8017   u32 next_table_index = ~0;
8018   u32 miss_next_index = ~0;
8019   u32 memory_size = 32 << 20;
8020   u8 *mask = 0;
8021   f64 timeout;
8022
8023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8024     {
8025       if (unformat (i, "del"))
8026         is_add = 0;
8027       else if (unformat (i, "buckets %d", &nbuckets))
8028         ;
8029       else if (unformat (i, "memory_size %d", &memory_size))
8030         ;
8031       else if (unformat (i, "skip %d", &skip))
8032         ;
8033       else if (unformat (i, "match %d", &match))
8034         ;
8035       else if (unformat (i, "table %d", &table_index))
8036         ;
8037       else if (unformat (i, "mask %U", unformat_classify_mask,
8038                          &mask, &skip, &match))
8039         ;
8040       else if (unformat (i, "next-table %d", &next_table_index))
8041         ;
8042       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8043                          &miss_next_index))
8044         ;
8045       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8046                          &miss_next_index))
8047         ;
8048       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8049                          &miss_next_index))
8050         ;
8051       else
8052         break;
8053     }
8054
8055   if (is_add && mask == 0)
8056     {
8057       errmsg ("Mask required\n");
8058       return -99;
8059     }
8060
8061   if (is_add && skip == ~0)
8062     {
8063       errmsg ("skip count required\n");
8064       return -99;
8065     }
8066
8067   if (is_add && match == ~0)
8068     {
8069       errmsg ("match count required\n");
8070       return -99;
8071     }
8072
8073   if (!is_add && table_index == ~0)
8074     {
8075       errmsg ("table index required for delete\n");
8076       return -99;
8077     }
8078
8079   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8080
8081   mp->is_add = is_add;
8082   mp->table_index = ntohl (table_index);
8083   mp->nbuckets = ntohl (nbuckets);
8084   mp->memory_size = ntohl (memory_size);
8085   mp->skip_n_vectors = ntohl (skip);
8086   mp->match_n_vectors = ntohl (match);
8087   mp->next_table_index = ntohl (next_table_index);
8088   mp->miss_next_index = ntohl (miss_next_index);
8089   clib_memcpy (mp->mask, mask, vec_len (mask));
8090
8091   vec_free (mask);
8092
8093   S;
8094   W;
8095   /* NOTREACHED */
8096 }
8097
8098 uword
8099 unformat_ip4_match (unformat_input_t * input, va_list * args)
8100 {
8101   u8 **matchp = va_arg (*args, u8 **);
8102   u8 *match = 0;
8103   ip4_header_t *ip;
8104   int version = 0;
8105   u32 version_val;
8106   int hdr_length = 0;
8107   u32 hdr_length_val;
8108   int src = 0, dst = 0;
8109   ip4_address_t src_val, dst_val;
8110   int proto = 0;
8111   u32 proto_val;
8112   int tos = 0;
8113   u32 tos_val;
8114   int length = 0;
8115   u32 length_val;
8116   int fragment_id = 0;
8117   u32 fragment_id_val;
8118   int ttl = 0;
8119   int ttl_val;
8120   int checksum = 0;
8121   u32 checksum_val;
8122
8123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8124     {
8125       if (unformat (input, "version %d", &version_val))
8126         version = 1;
8127       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8128         hdr_length = 1;
8129       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8130         src = 1;
8131       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8132         dst = 1;
8133       else if (unformat (input, "proto %d", &proto_val))
8134         proto = 1;
8135       else if (unformat (input, "tos %d", &tos_val))
8136         tos = 1;
8137       else if (unformat (input, "length %d", &length_val))
8138         length = 1;
8139       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8140         fragment_id = 1;
8141       else if (unformat (input, "ttl %d", &ttl_val))
8142         ttl = 1;
8143       else if (unformat (input, "checksum %d", &checksum_val))
8144         checksum = 1;
8145       else
8146         break;
8147     }
8148
8149   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8150       + ttl + checksum == 0)
8151     return 0;
8152
8153   /*
8154    * Aligned because we use the real comparison functions
8155    */
8156   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8157
8158   ip = (ip4_header_t *) match;
8159
8160   /* These are realistically matched in practice */
8161   if (src)
8162     ip->src_address.as_u32 = src_val.as_u32;
8163
8164   if (dst)
8165     ip->dst_address.as_u32 = dst_val.as_u32;
8166
8167   if (proto)
8168     ip->protocol = proto_val;
8169
8170
8171   /* These are not, but they're included for completeness */
8172   if (version)
8173     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8174
8175   if (hdr_length)
8176     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8177
8178   if (tos)
8179     ip->tos = tos_val;
8180
8181   if (length)
8182     ip->length = length_val;
8183
8184   if (ttl)
8185     ip->ttl = ttl_val;
8186
8187   if (checksum)
8188     ip->checksum = checksum_val;
8189
8190   *matchp = match;
8191   return 1;
8192 }
8193
8194 uword
8195 unformat_ip6_match (unformat_input_t * input, va_list * args)
8196 {
8197   u8 **matchp = va_arg (*args, u8 **);
8198   u8 *match = 0;
8199   ip6_header_t *ip;
8200   int version = 0;
8201   u32 version_val;
8202   u8 traffic_class = 0;
8203   u32 traffic_class_val = 0;
8204   u8 flow_label = 0;
8205   u8 flow_label_val;
8206   int src = 0, dst = 0;
8207   ip6_address_t src_val, dst_val;
8208   int proto = 0;
8209   u32 proto_val;
8210   int payload_length = 0;
8211   u32 payload_length_val;
8212   int hop_limit = 0;
8213   int hop_limit_val;
8214   u32 ip_version_traffic_class_and_flow_label;
8215
8216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8217     {
8218       if (unformat (input, "version %d", &version_val))
8219         version = 1;
8220       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8221         traffic_class = 1;
8222       else if (unformat (input, "flow_label %d", &flow_label_val))
8223         flow_label = 1;
8224       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8225         src = 1;
8226       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8227         dst = 1;
8228       else if (unformat (input, "proto %d", &proto_val))
8229         proto = 1;
8230       else if (unformat (input, "payload_length %d", &payload_length_val))
8231         payload_length = 1;
8232       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8233         hop_limit = 1;
8234       else
8235         break;
8236     }
8237
8238   if (version + traffic_class + flow_label + src + dst + proto +
8239       payload_length + hop_limit == 0)
8240     return 0;
8241
8242   /*
8243    * Aligned because we use the real comparison functions
8244    */
8245   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8246
8247   ip = (ip6_header_t *) match;
8248
8249   if (src)
8250     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8251
8252   if (dst)
8253     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8254
8255   if (proto)
8256     ip->protocol = proto_val;
8257
8258   ip_version_traffic_class_and_flow_label = 0;
8259
8260   if (version)
8261     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8262
8263   if (traffic_class)
8264     ip_version_traffic_class_and_flow_label |=
8265       (traffic_class_val & 0xFF) << 20;
8266
8267   if (flow_label)
8268     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8269
8270   ip->ip_version_traffic_class_and_flow_label =
8271     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8272
8273   if (payload_length)
8274     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8275
8276   if (hop_limit)
8277     ip->hop_limit = hop_limit_val;
8278
8279   *matchp = match;
8280   return 1;
8281 }
8282
8283 uword
8284 unformat_l3_match (unformat_input_t * input, va_list * args)
8285 {
8286   u8 **matchp = va_arg (*args, u8 **);
8287
8288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8289     {
8290       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8291         return 1;
8292       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8293         return 1;
8294       else
8295         break;
8296     }
8297   return 0;
8298 }
8299
8300 uword
8301 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8302 {
8303   u8 *tagp = va_arg (*args, u8 *);
8304   u32 tag;
8305
8306   if (unformat (input, "%d", &tag))
8307     {
8308       tagp[0] = (tag >> 8) & 0x0F;
8309       tagp[1] = tag & 0xFF;
8310       return 1;
8311     }
8312
8313   return 0;
8314 }
8315
8316 uword
8317 unformat_l2_match (unformat_input_t * input, va_list * args)
8318 {
8319   u8 **matchp = va_arg (*args, u8 **);
8320   u8 *match = 0;
8321   u8 src = 0;
8322   u8 src_val[6];
8323   u8 dst = 0;
8324   u8 dst_val[6];
8325   u8 proto = 0;
8326   u16 proto_val;
8327   u8 tag1 = 0;
8328   u8 tag1_val[2];
8329   u8 tag2 = 0;
8330   u8 tag2_val[2];
8331   int len = 14;
8332   u8 ignore_tag1 = 0;
8333   u8 ignore_tag2 = 0;
8334   u8 cos1 = 0;
8335   u8 cos2 = 0;
8336   u32 cos1_val = 0;
8337   u32 cos2_val = 0;
8338
8339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8340     {
8341       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8342         src = 1;
8343       else
8344         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8345         dst = 1;
8346       else if (unformat (input, "proto %U",
8347                          unformat_ethernet_type_host_byte_order, &proto_val))
8348         proto = 1;
8349       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8350         tag1 = 1;
8351       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8352         tag2 = 1;
8353       else if (unformat (input, "ignore-tag1"))
8354         ignore_tag1 = 1;
8355       else if (unformat (input, "ignore-tag2"))
8356         ignore_tag2 = 1;
8357       else if (unformat (input, "cos1 %d", &cos1_val))
8358         cos1 = 1;
8359       else if (unformat (input, "cos2 %d", &cos2_val))
8360         cos2 = 1;
8361       else
8362         break;
8363     }
8364   if ((src + dst + proto + tag1 + tag2 +
8365        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8366     return 0;
8367
8368   if (tag1 || ignore_tag1 || cos1)
8369     len = 18;
8370   if (tag2 || ignore_tag2 || cos2)
8371     len = 22;
8372
8373   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8374
8375   if (dst)
8376     clib_memcpy (match, dst_val, 6);
8377
8378   if (src)
8379     clib_memcpy (match + 6, src_val, 6);
8380
8381   if (tag2)
8382     {
8383       /* inner vlan tag */
8384       match[19] = tag2_val[1];
8385       match[18] = tag2_val[0];
8386       if (cos2)
8387         match[18] |= (cos2_val & 0x7) << 5;
8388       if (proto)
8389         {
8390           match[21] = proto_val & 0xff;
8391           match[20] = proto_val >> 8;
8392         }
8393       if (tag1)
8394         {
8395           match[15] = tag1_val[1];
8396           match[14] = tag1_val[0];
8397         }
8398       if (cos1)
8399         match[14] |= (cos1_val & 0x7) << 5;
8400       *matchp = match;
8401       return 1;
8402     }
8403   if (tag1)
8404     {
8405       match[15] = tag1_val[1];
8406       match[14] = tag1_val[0];
8407       if (proto)
8408         {
8409           match[17] = proto_val & 0xff;
8410           match[16] = proto_val >> 8;
8411         }
8412       if (cos1)
8413         match[14] |= (cos1_val & 0x7) << 5;
8414
8415       *matchp = match;
8416       return 1;
8417     }
8418   if (cos2)
8419     match[18] |= (cos2_val & 0x7) << 5;
8420   if (cos1)
8421     match[14] |= (cos1_val & 0x7) << 5;
8422   if (proto)
8423     {
8424       match[13] = proto_val & 0xff;
8425       match[12] = proto_val >> 8;
8426     }
8427
8428   *matchp = match;
8429   return 1;
8430 }
8431
8432
8433 uword
8434 unformat_classify_match (unformat_input_t * input, va_list * args)
8435 {
8436   u8 **matchp = va_arg (*args, u8 **);
8437   u32 skip_n_vectors = va_arg (*args, u32);
8438   u32 match_n_vectors = va_arg (*args, u32);
8439
8440   u8 *match = 0;
8441   u8 *l2 = 0;
8442   u8 *l3 = 0;
8443
8444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8445     {
8446       if (unformat (input, "hex %U", unformat_hex_string, &match))
8447         ;
8448       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8449         ;
8450       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8451         ;
8452       else
8453         break;
8454     }
8455
8456   if (match || l2 || l3)
8457     {
8458       if (l2 || l3)
8459         {
8460           /* "Win a free Ethernet header in every packet" */
8461           if (l2 == 0)
8462             vec_validate_aligned (l2, 13, sizeof (u32x4));
8463           match = l2;
8464           if (vec_len (l3))
8465             {
8466               vec_append_aligned (match, l3, sizeof (u32x4));
8467               vec_free (l3);
8468             }
8469         }
8470
8471       /* Make sure the vector is big enough even if key is all 0's */
8472       vec_validate_aligned
8473         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8474          sizeof (u32x4));
8475
8476       /* Set size, include skipped vectors */
8477       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8478
8479       *matchp = match;
8480
8481       return 1;
8482     }
8483
8484   return 0;
8485 }
8486
8487 static int
8488 api_classify_add_del_session (vat_main_t * vam)
8489 {
8490   unformat_input_t *i = vam->input;
8491   vl_api_classify_add_del_session_t *mp;
8492   int is_add = 1;
8493   u32 table_index = ~0;
8494   u32 hit_next_index = ~0;
8495   u32 opaque_index = ~0;
8496   u8 *match = 0;
8497   i32 advance = 0;
8498   f64 timeout;
8499   u32 skip_n_vectors = 0;
8500   u32 match_n_vectors = 0;
8501
8502   /*
8503    * Warning: you have to supply skip_n and match_n
8504    * because the API client cant simply look at the classify
8505    * table object.
8506    */
8507
8508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8509     {
8510       if (unformat (i, "del"))
8511         is_add = 0;
8512       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8513                          &hit_next_index))
8514         ;
8515       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8516                          &hit_next_index))
8517         ;
8518       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8519                          &hit_next_index))
8520         ;
8521       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8522         ;
8523       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8524         ;
8525       else if (unformat (i, "opaque-index %d", &opaque_index))
8526         ;
8527       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8528         ;
8529       else if (unformat (i, "match_n %d", &match_n_vectors))
8530         ;
8531       else if (unformat (i, "match %U", unformat_classify_match,
8532                          &match, skip_n_vectors, match_n_vectors))
8533         ;
8534       else if (unformat (i, "advance %d", &advance))
8535         ;
8536       else if (unformat (i, "table-index %d", &table_index))
8537         ;
8538       else
8539         break;
8540     }
8541
8542   if (table_index == ~0)
8543     {
8544       errmsg ("Table index required\n");
8545       return -99;
8546     }
8547
8548   if (is_add && match == 0)
8549     {
8550       errmsg ("Match value required\n");
8551       return -99;
8552     }
8553
8554   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8555
8556   mp->is_add = is_add;
8557   mp->table_index = ntohl (table_index);
8558   mp->hit_next_index = ntohl (hit_next_index);
8559   mp->opaque_index = ntohl (opaque_index);
8560   mp->advance = ntohl (advance);
8561   clib_memcpy (mp->match, match, vec_len (match));
8562   vec_free (match);
8563
8564   S;
8565   W;
8566   /* NOTREACHED */
8567 }
8568
8569 static int
8570 api_classify_set_interface_ip_table (vat_main_t * vam)
8571 {
8572   unformat_input_t *i = vam->input;
8573   vl_api_classify_set_interface_ip_table_t *mp;
8574   f64 timeout;
8575   u32 sw_if_index;
8576   int sw_if_index_set;
8577   u32 table_index = ~0;
8578   u8 is_ipv6 = 0;
8579
8580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8583         sw_if_index_set = 1;
8584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8585         sw_if_index_set = 1;
8586       else if (unformat (i, "table %d", &table_index))
8587         ;
8588       else
8589         {
8590           clib_warning ("parse error '%U'", format_unformat_error, i);
8591           return -99;
8592         }
8593     }
8594
8595   if (sw_if_index_set == 0)
8596     {
8597       errmsg ("missing interface name or sw_if_index\n");
8598       return -99;
8599     }
8600
8601
8602   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8603
8604   mp->sw_if_index = ntohl (sw_if_index);
8605   mp->table_index = ntohl (table_index);
8606   mp->is_ipv6 = is_ipv6;
8607
8608   S;
8609   W;
8610   /* NOTREACHED */
8611   return 0;
8612 }
8613
8614 static int
8615 api_classify_set_interface_l2_tables (vat_main_t * vam)
8616 {
8617   unformat_input_t *i = vam->input;
8618   vl_api_classify_set_interface_l2_tables_t *mp;
8619   f64 timeout;
8620   u32 sw_if_index;
8621   int sw_if_index_set;
8622   u32 ip4_table_index = ~0;
8623   u32 ip6_table_index = ~0;
8624   u32 other_table_index = ~0;
8625   u32 is_input = 1;
8626
8627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8628     {
8629       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8630         sw_if_index_set = 1;
8631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8632         sw_if_index_set = 1;
8633       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8634         ;
8635       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8636         ;
8637       else if (unformat (i, "other-table %d", &other_table_index))
8638         ;
8639       else if (unformat (i, "is-input %d", &is_input))
8640         ;
8641       else
8642         {
8643           clib_warning ("parse error '%U'", format_unformat_error, i);
8644           return -99;
8645         }
8646     }
8647
8648   if (sw_if_index_set == 0)
8649     {
8650       errmsg ("missing interface name or sw_if_index\n");
8651       return -99;
8652     }
8653
8654
8655   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8656
8657   mp->sw_if_index = ntohl (sw_if_index);
8658   mp->ip4_table_index = ntohl (ip4_table_index);
8659   mp->ip6_table_index = ntohl (ip6_table_index);
8660   mp->other_table_index = ntohl (other_table_index);
8661   mp->is_input = (u8) is_input;
8662
8663   S;
8664   W;
8665   /* NOTREACHED */
8666   return 0;
8667 }
8668
8669 static int
8670 api_set_ipfix_exporter (vat_main_t * vam)
8671 {
8672   unformat_input_t *i = vam->input;
8673   vl_api_set_ipfix_exporter_t *mp;
8674   ip4_address_t collector_address;
8675   u8 collector_address_set = 0;
8676   u32 collector_port = ~0;
8677   ip4_address_t src_address;
8678   u8 src_address_set = 0;
8679   u32 vrf_id = ~0;
8680   u32 path_mtu = ~0;
8681   u32 template_interval = ~0;
8682   u8 udp_checksum = 0;
8683   f64 timeout;
8684
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "collector_address %U", unformat_ip4_address,
8688                     &collector_address))
8689         collector_address_set = 1;
8690       else if (unformat (i, "collector_port %d", &collector_port))
8691         ;
8692       else if (unformat (i, "src_address %U", unformat_ip4_address,
8693                          &src_address))
8694         src_address_set = 1;
8695       else if (unformat (i, "vrf_id %d", &vrf_id))
8696         ;
8697       else if (unformat (i, "path_mtu %d", &path_mtu))
8698         ;
8699       else if (unformat (i, "template_interval %d", &template_interval))
8700         ;
8701       else if (unformat (i, "udp_checksum"))
8702         udp_checksum = 1;
8703       else
8704         break;
8705     }
8706
8707   if (collector_address_set == 0)
8708     {
8709       errmsg ("collector_address required\n");
8710       return -99;
8711     }
8712
8713   if (src_address_set == 0)
8714     {
8715       errmsg ("src_address required\n");
8716       return -99;
8717     }
8718
8719   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8720
8721   memcpy (mp->collector_address, collector_address.data,
8722           sizeof (collector_address.data));
8723   mp->collector_port = htons ((u16) collector_port);
8724   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8725   mp->vrf_id = htonl (vrf_id);
8726   mp->path_mtu = htonl (path_mtu);
8727   mp->template_interval = htonl (template_interval);
8728   mp->udp_checksum = udp_checksum;
8729
8730   S;
8731   W;
8732   /* NOTREACHED */
8733 }
8734
8735 static int
8736 api_set_ipfix_classify_stream (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   vl_api_set_ipfix_classify_stream_t *mp;
8740   u32 domain_id = 0;
8741   u32 src_port = UDP_DST_PORT_ipfix;
8742   f64 timeout;
8743
8744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8745     {
8746       if (unformat (i, "domain %d", &domain_id))
8747         ;
8748       else if (unformat (i, "src_port %d", &src_port))
8749         ;
8750       else
8751         {
8752           errmsg ("unknown input `%U'", format_unformat_error, i);
8753           return -99;
8754         }
8755     }
8756
8757   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8758
8759   mp->domain_id = htonl (domain_id);
8760   mp->src_port = htons ((u16) src_port);
8761
8762   S;
8763   W;
8764   /* NOTREACHED */
8765 }
8766
8767 static int
8768 api_ipfix_classify_table_add_del (vat_main_t * vam)
8769 {
8770   unformat_input_t *i = vam->input;
8771   vl_api_ipfix_classify_table_add_del_t *mp;
8772   int is_add = -1;
8773   u32 classify_table_index = ~0;
8774   u8 ip_version = 0;
8775   u8 transport_protocol = 255;
8776   f64 timeout;
8777
8778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8779     {
8780       if (unformat (i, "add"))
8781         is_add = 1;
8782       else if (unformat (i, "del"))
8783         is_add = 0;
8784       else if (unformat (i, "table %d", &classify_table_index))
8785         ;
8786       else if (unformat (i, "ip4"))
8787         ip_version = 4;
8788       else if (unformat (i, "ip6"))
8789         ip_version = 6;
8790       else if (unformat (i, "tcp"))
8791         transport_protocol = 6;
8792       else if (unformat (i, "udp"))
8793         transport_protocol = 17;
8794       else
8795         {
8796           errmsg ("unknown input `%U'", format_unformat_error, i);
8797           return -99;
8798         }
8799     }
8800
8801   if (is_add == -1)
8802     {
8803       errmsg ("expecting: add|del");
8804       return -99;
8805     }
8806   if (classify_table_index == ~0)
8807     {
8808       errmsg ("classifier table not specified");
8809       return -99;
8810     }
8811   if (ip_version == 0)
8812     {
8813       errmsg ("IP version not specified");
8814       return -99;
8815     }
8816
8817   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
8818
8819   mp->is_add = is_add;
8820   mp->table_id = htonl (classify_table_index);
8821   mp->ip_version = ip_version;
8822   mp->transport_protocol = transport_protocol;
8823
8824   S;
8825   W;
8826   /* NOTREACHED */
8827 }
8828
8829 static int
8830 api_get_node_index (vat_main_t * vam)
8831 {
8832   unformat_input_t *i = vam->input;
8833   vl_api_get_node_index_t *mp;
8834   f64 timeout;
8835   u8 *name = 0;
8836
8837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8838     {
8839       if (unformat (i, "node %s", &name))
8840         ;
8841       else
8842         break;
8843     }
8844   if (name == 0)
8845     {
8846       errmsg ("node name required\n");
8847       return -99;
8848     }
8849   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8850     {
8851       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8852       return -99;
8853     }
8854
8855   M (GET_NODE_INDEX, get_node_index);
8856   clib_memcpy (mp->node_name, name, vec_len (name));
8857   vec_free (name);
8858
8859   S;
8860   W;
8861   /* NOTREACHED */
8862   return 0;
8863 }
8864
8865 static int
8866 api_get_next_index (vat_main_t * vam)
8867 {
8868   unformat_input_t *i = vam->input;
8869   vl_api_get_next_index_t *mp;
8870   f64 timeout;
8871   u8 *node_name = 0, *next_node_name = 0;
8872
8873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8874     {
8875       if (unformat (i, "node-name %s", &node_name))
8876         ;
8877       else if (unformat (i, "next-node-name %s", &next_node_name))
8878         break;
8879     }
8880
8881   if (node_name == 0)
8882     {
8883       errmsg ("node name required\n");
8884       return -99;
8885     }
8886   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8887     {
8888       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8889       return -99;
8890     }
8891
8892   if (next_node_name == 0)
8893     {
8894       errmsg ("next node name required\n");
8895       return -99;
8896     }
8897   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8898     {
8899       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8900       return -99;
8901     }
8902
8903   M (GET_NEXT_INDEX, get_next_index);
8904   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8905   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8906   vec_free (node_name);
8907   vec_free (next_node_name);
8908
8909   S;
8910   W;
8911   /* NOTREACHED */
8912   return 0;
8913 }
8914
8915 static int
8916 api_add_node_next (vat_main_t * vam)
8917 {
8918   unformat_input_t *i = vam->input;
8919   vl_api_add_node_next_t *mp;
8920   f64 timeout;
8921   u8 *name = 0;
8922   u8 *next = 0;
8923
8924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8925     {
8926       if (unformat (i, "node %s", &name))
8927         ;
8928       else if (unformat (i, "next %s", &next))
8929         ;
8930       else
8931         break;
8932     }
8933   if (name == 0)
8934     {
8935       errmsg ("node name required\n");
8936       return -99;
8937     }
8938   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8939     {
8940       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8941       return -99;
8942     }
8943   if (next == 0)
8944     {
8945       errmsg ("next node required\n");
8946       return -99;
8947     }
8948   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8949     {
8950       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8951       return -99;
8952     }
8953
8954   M (ADD_NODE_NEXT, add_node_next);
8955   clib_memcpy (mp->node_name, name, vec_len (name));
8956   clib_memcpy (mp->next_name, next, vec_len (next));
8957   vec_free (name);
8958   vec_free (next);
8959
8960   S;
8961   W;
8962   /* NOTREACHED */
8963   return 0;
8964 }
8965
8966 static int
8967 api_l2tpv3_create_tunnel (vat_main_t * vam)
8968 {
8969   unformat_input_t *i = vam->input;
8970   ip6_address_t client_address, our_address;
8971   int client_address_set = 0;
8972   int our_address_set = 0;
8973   u32 local_session_id = 0;
8974   u32 remote_session_id = 0;
8975   u64 local_cookie = 0;
8976   u64 remote_cookie = 0;
8977   u8 l2_sublayer_present = 0;
8978   vl_api_l2tpv3_create_tunnel_t *mp;
8979   f64 timeout;
8980
8981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8982     {
8983       if (unformat (i, "client_address %U", unformat_ip6_address,
8984                     &client_address))
8985         client_address_set = 1;
8986       else if (unformat (i, "our_address %U", unformat_ip6_address,
8987                          &our_address))
8988         our_address_set = 1;
8989       else if (unformat (i, "local_session_id %d", &local_session_id))
8990         ;
8991       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8992         ;
8993       else if (unformat (i, "local_cookie %lld", &local_cookie))
8994         ;
8995       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8996         ;
8997       else if (unformat (i, "l2-sublayer-present"))
8998         l2_sublayer_present = 1;
8999       else
9000         break;
9001     }
9002
9003   if (client_address_set == 0)
9004     {
9005       errmsg ("client_address required\n");
9006       return -99;
9007     }
9008
9009   if (our_address_set == 0)
9010     {
9011       errmsg ("our_address required\n");
9012       return -99;
9013     }
9014
9015   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9016
9017   clib_memcpy (mp->client_address, client_address.as_u8,
9018                sizeof (mp->client_address));
9019
9020   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9021
9022   mp->local_session_id = ntohl (local_session_id);
9023   mp->remote_session_id = ntohl (remote_session_id);
9024   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9025   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9026   mp->l2_sublayer_present = l2_sublayer_present;
9027   mp->is_ipv6 = 1;
9028
9029   S;
9030   W;
9031   /* NOTREACHED */
9032   return 0;
9033 }
9034
9035 static int
9036 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9037 {
9038   unformat_input_t *i = vam->input;
9039   u32 sw_if_index;
9040   u8 sw_if_index_set = 0;
9041   u64 new_local_cookie = 0;
9042   u64 new_remote_cookie = 0;
9043   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9044   f64 timeout;
9045
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9049         sw_if_index_set = 1;
9050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9051         sw_if_index_set = 1;
9052       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9053         ;
9054       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9055         ;
9056       else
9057         break;
9058     }
9059
9060   if (sw_if_index_set == 0)
9061     {
9062       errmsg ("missing interface name or sw_if_index\n");
9063       return -99;
9064     }
9065
9066   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9067
9068   mp->sw_if_index = ntohl (sw_if_index);
9069   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9070   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9071
9072   S;
9073   W;
9074   /* NOTREACHED */
9075   return 0;
9076 }
9077
9078 static int
9079 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9080 {
9081   unformat_input_t *i = vam->input;
9082   vl_api_l2tpv3_interface_enable_disable_t *mp;
9083   f64 timeout;
9084   u32 sw_if_index;
9085   u8 sw_if_index_set = 0;
9086   u8 enable_disable = 1;
9087
9088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9089     {
9090       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9091         sw_if_index_set = 1;
9092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9093         sw_if_index_set = 1;
9094       else if (unformat (i, "enable"))
9095         enable_disable = 1;
9096       else if (unformat (i, "disable"))
9097         enable_disable = 0;
9098       else
9099         break;
9100     }
9101
9102   if (sw_if_index_set == 0)
9103     {
9104       errmsg ("missing interface name or sw_if_index\n");
9105       return -99;
9106     }
9107
9108   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9109
9110   mp->sw_if_index = ntohl (sw_if_index);
9111   mp->enable_disable = enable_disable;
9112
9113   S;
9114   W;
9115   /* NOTREACHED */
9116   return 0;
9117 }
9118
9119 static int
9120 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9121 {
9122   unformat_input_t *i = vam->input;
9123   vl_api_l2tpv3_set_lookup_key_t *mp;
9124   f64 timeout;
9125   u8 key = ~0;
9126
9127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9128     {
9129       if (unformat (i, "lookup_v6_src"))
9130         key = L2T_LOOKUP_SRC_ADDRESS;
9131       else if (unformat (i, "lookup_v6_dst"))
9132         key = L2T_LOOKUP_DST_ADDRESS;
9133       else if (unformat (i, "lookup_session_id"))
9134         key = L2T_LOOKUP_SESSION_ID;
9135       else
9136         break;
9137     }
9138
9139   if (key == (u8) ~ 0)
9140     {
9141       errmsg ("l2tp session lookup key unset\n");
9142       return -99;
9143     }
9144
9145   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9146
9147   mp->key = key;
9148
9149   S;
9150   W;
9151   /* NOTREACHED */
9152   return 0;
9153 }
9154
9155 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9156   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9157 {
9158   vat_main_t *vam = &vat_main;
9159
9160   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9161            format_ip6_address, mp->our_address,
9162            format_ip6_address, mp->client_address,
9163            clib_net_to_host_u32 (mp->sw_if_index));
9164
9165   fformat (vam->ofp,
9166            "   local cookies %016llx %016llx remote cookie %016llx\n",
9167            clib_net_to_host_u64 (mp->local_cookie[0]),
9168            clib_net_to_host_u64 (mp->local_cookie[1]),
9169            clib_net_to_host_u64 (mp->remote_cookie));
9170
9171   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9172            clib_net_to_host_u32 (mp->local_session_id),
9173            clib_net_to_host_u32 (mp->remote_session_id));
9174
9175   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9176            mp->l2_sublayer_present ? "preset" : "absent");
9177
9178 }
9179
9180 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9181   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9182 {
9183   vat_main_t *vam = &vat_main;
9184   vat_json_node_t *node = NULL;
9185   struct in6_addr addr;
9186
9187   if (VAT_JSON_ARRAY != vam->json_tree.type)
9188     {
9189       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9190       vat_json_init_array (&vam->json_tree);
9191     }
9192   node = vat_json_array_add (&vam->json_tree);
9193
9194   vat_json_init_object (node);
9195
9196   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9197   vat_json_object_add_ip6 (node, "our_address", addr);
9198   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9199   vat_json_object_add_ip6 (node, "client_address", addr);
9200
9201   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9202   vat_json_init_array (lc);
9203   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9204   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9205   vat_json_object_add_uint (node, "remote_cookie",
9206                             clib_net_to_host_u64 (mp->remote_cookie));
9207
9208   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9209   vat_json_object_add_uint (node, "local_session_id",
9210                             clib_net_to_host_u32 (mp->local_session_id));
9211   vat_json_object_add_uint (node, "remote_session_id",
9212                             clib_net_to_host_u32 (mp->remote_session_id));
9213   vat_json_object_add_string_copy (node, "l2_sublayer",
9214                                    mp->l2_sublayer_present ? (u8 *) "present"
9215                                    : (u8 *) "absent");
9216 }
9217
9218 static int
9219 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9220 {
9221   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9222   f64 timeout;
9223
9224   /* Get list of l2tpv3-tunnel interfaces */
9225   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9226   S;
9227
9228   /* Use a control ping for synchronization */
9229   {
9230     vl_api_control_ping_t *mp;
9231     M (CONTROL_PING, control_ping);
9232     S;
9233   }
9234   W;
9235 }
9236
9237
9238 static void vl_api_sw_interface_tap_details_t_handler
9239   (vl_api_sw_interface_tap_details_t * mp)
9240 {
9241   vat_main_t *vam = &vat_main;
9242
9243   fformat (vam->ofp, "%-16s %d\n",
9244            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9245 }
9246
9247 static void vl_api_sw_interface_tap_details_t_handler_json
9248   (vl_api_sw_interface_tap_details_t * mp)
9249 {
9250   vat_main_t *vam = &vat_main;
9251   vat_json_node_t *node = NULL;
9252
9253   if (VAT_JSON_ARRAY != vam->json_tree.type)
9254     {
9255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9256       vat_json_init_array (&vam->json_tree);
9257     }
9258   node = vat_json_array_add (&vam->json_tree);
9259
9260   vat_json_init_object (node);
9261   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9262   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9263 }
9264
9265 static int
9266 api_sw_interface_tap_dump (vat_main_t * vam)
9267 {
9268   vl_api_sw_interface_tap_dump_t *mp;
9269   f64 timeout;
9270
9271   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9272   /* Get list of tap interfaces */
9273   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9274   S;
9275
9276   /* Use a control ping for synchronization */
9277   {
9278     vl_api_control_ping_t *mp;
9279     M (CONTROL_PING, control_ping);
9280     S;
9281   }
9282   W;
9283 }
9284
9285 static uword unformat_vxlan_decap_next
9286   (unformat_input_t * input, va_list * args)
9287 {
9288   u32 *result = va_arg (*args, u32 *);
9289   u32 tmp;
9290
9291   if (unformat (input, "drop"))
9292     *result = VXLAN_INPUT_NEXT_DROP;
9293   else if (unformat (input, "ip4"))
9294     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9295   else if (unformat (input, "ip6"))
9296     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9297   else if (unformat (input, "l2"))
9298     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9299   else if (unformat (input, "%d", &tmp))
9300     *result = tmp;
9301   else
9302     return 0;
9303   return 1;
9304 }
9305
9306 static int
9307 api_vxlan_add_del_tunnel (vat_main_t * vam)
9308 {
9309   unformat_input_t *line_input = vam->input;
9310   vl_api_vxlan_add_del_tunnel_t *mp;
9311   f64 timeout;
9312   ip4_address_t src4, dst4;
9313   ip6_address_t src6, dst6;
9314   u8 is_add = 1;
9315   u8 ipv4_set = 0, ipv6_set = 0;
9316   u8 src_set = 0;
9317   u8 dst_set = 0;
9318   u32 encap_vrf_id = 0;
9319   u32 decap_next_index = ~0;
9320   u32 vni = 0;
9321
9322   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (line_input, "del"))
9325         is_add = 0;
9326       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9327         {
9328           ipv4_set = 1;
9329           src_set = 1;
9330         }
9331       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9332         {
9333           ipv4_set = 1;
9334           dst_set = 1;
9335         }
9336       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9337         {
9338           ipv6_set = 1;
9339           src_set = 1;
9340         }
9341       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9342         {
9343           ipv6_set = 1;
9344           dst_set = 1;
9345         }
9346       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9347         ;
9348       else if (unformat (line_input, "decap-next %U",
9349                          unformat_vxlan_decap_next, &decap_next_index))
9350         ;
9351       else if (unformat (line_input, "vni %d", &vni))
9352         ;
9353       else
9354         {
9355           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9356           return -99;
9357         }
9358     }
9359
9360   if (src_set == 0)
9361     {
9362       errmsg ("tunnel src address not specified\n");
9363       return -99;
9364     }
9365   if (dst_set == 0)
9366     {
9367       errmsg ("tunnel dst address not specified\n");
9368       return -99;
9369     }
9370
9371   if (ipv4_set && ipv6_set)
9372     {
9373       errmsg ("both IPv4 and IPv6 addresses specified");
9374       return -99;
9375     }
9376
9377   if ((vni == 0) || (vni >> 24))
9378     {
9379       errmsg ("vni not specified or out of range\n");
9380       return -99;
9381     }
9382
9383   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9384
9385   if (ipv6_set)
9386     {
9387       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9388       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9389     }
9390   else
9391     {
9392       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9393       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9394     }
9395   mp->encap_vrf_id = ntohl (encap_vrf_id);
9396   mp->decap_next_index = ntohl (decap_next_index);
9397   mp->vni = ntohl (vni);
9398   mp->is_add = is_add;
9399   mp->is_ipv6 = ipv6_set;
9400
9401   S;
9402   W;
9403   /* NOTREACHED */
9404   return 0;
9405 }
9406
9407 static void vl_api_vxlan_tunnel_details_t_handler
9408   (vl_api_vxlan_tunnel_details_t * mp)
9409 {
9410   vat_main_t *vam = &vat_main;
9411
9412   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9413            ntohl (mp->sw_if_index),
9414            format_ip46_address, &(mp->src_address[0]),
9415            IP46_TYPE_ANY,
9416            format_ip46_address, &(mp->dst_address[0]),
9417            IP46_TYPE_ANY,
9418            ntohl (mp->encap_vrf_id),
9419            ntohl (mp->decap_next_index), ntohl (mp->vni));
9420 }
9421
9422 static void vl_api_vxlan_tunnel_details_t_handler_json
9423   (vl_api_vxlan_tunnel_details_t * mp)
9424 {
9425   vat_main_t *vam = &vat_main;
9426   vat_json_node_t *node = NULL;
9427   struct in_addr ip4;
9428   struct in6_addr ip6;
9429
9430   if (VAT_JSON_ARRAY != vam->json_tree.type)
9431     {
9432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9433       vat_json_init_array (&vam->json_tree);
9434     }
9435   node = vat_json_array_add (&vam->json_tree);
9436
9437   vat_json_init_object (node);
9438   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9439   if (mp->is_ipv6)
9440     {
9441       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9442       vat_json_object_add_ip6 (node, "src_address", ip6);
9443       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9444       vat_json_object_add_ip6 (node, "dst_address", ip6);
9445     }
9446   else
9447     {
9448       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9449       vat_json_object_add_ip4 (node, "src_address", ip4);
9450       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9451       vat_json_object_add_ip4 (node, "dst_address", ip4);
9452     }
9453   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9454   vat_json_object_add_uint (node, "decap_next_index",
9455                             ntohl (mp->decap_next_index));
9456   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9457   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9458 }
9459
9460 static int
9461 api_vxlan_tunnel_dump (vat_main_t * vam)
9462 {
9463   unformat_input_t *i = vam->input;
9464   vl_api_vxlan_tunnel_dump_t *mp;
9465   f64 timeout;
9466   u32 sw_if_index;
9467   u8 sw_if_index_set = 0;
9468
9469   /* Parse args required to build the message */
9470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9471     {
9472       if (unformat (i, "sw_if_index %d", &sw_if_index))
9473         sw_if_index_set = 1;
9474       else
9475         break;
9476     }
9477
9478   if (sw_if_index_set == 0)
9479     {
9480       sw_if_index = ~0;
9481     }
9482
9483   if (!vam->json_output)
9484     {
9485       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9486                "sw_if_index", "src_address", "dst_address",
9487                "encap_vrf_id", "decap_next_index", "vni");
9488     }
9489
9490   /* Get list of vxlan-tunnel interfaces */
9491   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9492
9493   mp->sw_if_index = htonl (sw_if_index);
9494
9495   S;
9496
9497   /* Use a control ping for synchronization */
9498   {
9499     vl_api_control_ping_t *mp;
9500     M (CONTROL_PING, control_ping);
9501     S;
9502   }
9503   W;
9504 }
9505
9506 static int
9507 api_gre_add_del_tunnel (vat_main_t * vam)
9508 {
9509   unformat_input_t *line_input = vam->input;
9510   vl_api_gre_add_del_tunnel_t *mp;
9511   f64 timeout;
9512   ip4_address_t src4, dst4;
9513   u8 is_add = 1;
9514   u8 teb = 0;
9515   u8 src_set = 0;
9516   u8 dst_set = 0;
9517   u32 outer_fib_id = 0;
9518
9519   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9520     {
9521       if (unformat (line_input, "del"))
9522         is_add = 0;
9523       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9524         src_set = 1;
9525       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9526         dst_set = 1;
9527       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9528         ;
9529       else if (unformat (line_input, "teb"))
9530         teb = 1;
9531       else
9532         {
9533           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9534           return -99;
9535         }
9536     }
9537
9538   if (src_set == 0)
9539     {
9540       errmsg ("tunnel src address not specified\n");
9541       return -99;
9542     }
9543   if (dst_set == 0)
9544     {
9545       errmsg ("tunnel dst address not specified\n");
9546       return -99;
9547     }
9548
9549
9550   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9551
9552   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9553   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9554   mp->outer_fib_id = ntohl (outer_fib_id);
9555   mp->is_add = is_add;
9556   mp->teb = teb;
9557
9558   S;
9559   W;
9560   /* NOTREACHED */
9561   return 0;
9562 }
9563
9564 static void vl_api_gre_tunnel_details_t_handler
9565   (vl_api_gre_tunnel_details_t * mp)
9566 {
9567   vat_main_t *vam = &vat_main;
9568
9569   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9570            ntohl (mp->sw_if_index),
9571            format_ip4_address, &mp->src_address,
9572            format_ip4_address, &mp->dst_address,
9573            mp->teb, ntohl (mp->outer_fib_id));
9574 }
9575
9576 static void vl_api_gre_tunnel_details_t_handler_json
9577   (vl_api_gre_tunnel_details_t * mp)
9578 {
9579   vat_main_t *vam = &vat_main;
9580   vat_json_node_t *node = NULL;
9581   struct in_addr ip4;
9582
9583   if (VAT_JSON_ARRAY != vam->json_tree.type)
9584     {
9585       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9586       vat_json_init_array (&vam->json_tree);
9587     }
9588   node = vat_json_array_add (&vam->json_tree);
9589
9590   vat_json_init_object (node);
9591   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9592   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9593   vat_json_object_add_ip4 (node, "src_address", ip4);
9594   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9595   vat_json_object_add_ip4 (node, "dst_address", ip4);
9596   vat_json_object_add_uint (node, "teb", mp->teb);
9597   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9598 }
9599
9600 static int
9601 api_gre_tunnel_dump (vat_main_t * vam)
9602 {
9603   unformat_input_t *i = vam->input;
9604   vl_api_gre_tunnel_dump_t *mp;
9605   f64 timeout;
9606   u32 sw_if_index;
9607   u8 sw_if_index_set = 0;
9608
9609   /* Parse args required to build the message */
9610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9611     {
9612       if (unformat (i, "sw_if_index %d", &sw_if_index))
9613         sw_if_index_set = 1;
9614       else
9615         break;
9616     }
9617
9618   if (sw_if_index_set == 0)
9619     {
9620       sw_if_index = ~0;
9621     }
9622
9623   if (!vam->json_output)
9624     {
9625       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9626                "sw_if_index", "src_address", "dst_address", "teb",
9627                "outer_fib_id");
9628     }
9629
9630   /* Get list of gre-tunnel interfaces */
9631   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9632
9633   mp->sw_if_index = htonl (sw_if_index);
9634
9635   S;
9636
9637   /* Use a control ping for synchronization */
9638   {
9639     vl_api_control_ping_t *mp;
9640     M (CONTROL_PING, control_ping);
9641     S;
9642   }
9643   W;
9644 }
9645
9646 static int
9647 api_l2_fib_clear_table (vat_main_t * vam)
9648 {
9649 //  unformat_input_t * i = vam->input;
9650   vl_api_l2_fib_clear_table_t *mp;
9651   f64 timeout;
9652
9653   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9654
9655   S;
9656   W;
9657   /* NOTREACHED */
9658   return 0;
9659 }
9660
9661 static int
9662 api_l2_interface_efp_filter (vat_main_t * vam)
9663 {
9664   unformat_input_t *i = vam->input;
9665   vl_api_l2_interface_efp_filter_t *mp;
9666   f64 timeout;
9667   u32 sw_if_index;
9668   u8 enable = 1;
9669   u8 sw_if_index_set = 0;
9670
9671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9672     {
9673       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9674         sw_if_index_set = 1;
9675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9676         sw_if_index_set = 1;
9677       else if (unformat (i, "enable"))
9678         enable = 1;
9679       else if (unformat (i, "disable"))
9680         enable = 0;
9681       else
9682         {
9683           clib_warning ("parse error '%U'", format_unformat_error, i);
9684           return -99;
9685         }
9686     }
9687
9688   if (sw_if_index_set == 0)
9689     {
9690       errmsg ("missing sw_if_index\n");
9691       return -99;
9692     }
9693
9694   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9695
9696   mp->sw_if_index = ntohl (sw_if_index);
9697   mp->enable_disable = enable;
9698
9699   S;
9700   W;
9701   /* NOTREACHED */
9702   return 0;
9703 }
9704
9705 #define foreach_vtr_op                          \
9706 _("disable",  L2_VTR_DISABLED)                  \
9707 _("push-1",  L2_VTR_PUSH_1)                     \
9708 _("push-2",  L2_VTR_PUSH_2)                     \
9709 _("pop-1",  L2_VTR_POP_1)                       \
9710 _("pop-2",  L2_VTR_POP_2)                       \
9711 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9712 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9713 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9714 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9715
9716 static int
9717 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9718 {
9719   unformat_input_t *i = vam->input;
9720   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9721   f64 timeout;
9722   u32 sw_if_index;
9723   u8 sw_if_index_set = 0;
9724   u8 vtr_op_set = 0;
9725   u32 vtr_op = 0;
9726   u32 push_dot1q = 1;
9727   u32 tag1 = ~0;
9728   u32 tag2 = ~0;
9729
9730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9731     {
9732       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9733         sw_if_index_set = 1;
9734       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9735         sw_if_index_set = 1;
9736       else if (unformat (i, "vtr_op %d", &vtr_op))
9737         vtr_op_set = 1;
9738 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9739       foreach_vtr_op
9740 #undef _
9741         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9742         ;
9743       else if (unformat (i, "tag1 %d", &tag1))
9744         ;
9745       else if (unformat (i, "tag2 %d", &tag2))
9746         ;
9747       else
9748         {
9749           clib_warning ("parse error '%U'", format_unformat_error, i);
9750           return -99;
9751         }
9752     }
9753
9754   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9755     {
9756       errmsg ("missing vtr operation or sw_if_index\n");
9757       return -99;
9758     }
9759
9760   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9761     mp->sw_if_index = ntohl (sw_if_index);
9762   mp->vtr_op = ntohl (vtr_op);
9763   mp->push_dot1q = ntohl (push_dot1q);
9764   mp->tag1 = ntohl (tag1);
9765   mp->tag2 = ntohl (tag2);
9766
9767   S;
9768   W;
9769   /* NOTREACHED */
9770   return 0;
9771 }
9772
9773 static int
9774 api_create_vhost_user_if (vat_main_t * vam)
9775 {
9776   unformat_input_t *i = vam->input;
9777   vl_api_create_vhost_user_if_t *mp;
9778   f64 timeout;
9779   u8 *file_name;
9780   u8 is_server = 0;
9781   u8 file_name_set = 0;
9782   u32 custom_dev_instance = ~0;
9783   u8 hwaddr[6];
9784   u8 use_custom_mac = 0;
9785
9786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9787     {
9788       if (unformat (i, "socket %s", &file_name))
9789         {
9790           file_name_set = 1;
9791         }
9792       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9793         ;
9794       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9795         use_custom_mac = 1;
9796       else if (unformat (i, "server"))
9797         is_server = 1;
9798       else
9799         break;
9800     }
9801
9802   if (file_name_set == 0)
9803     {
9804       errmsg ("missing socket file name\n");
9805       return -99;
9806     }
9807
9808   if (vec_len (file_name) > 255)
9809     {
9810       errmsg ("socket file name too long\n");
9811       return -99;
9812     }
9813   vec_add1 (file_name, 0);
9814
9815   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9816
9817   mp->is_server = is_server;
9818   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9819   vec_free (file_name);
9820   if (custom_dev_instance != ~0)
9821     {
9822       mp->renumber = 1;
9823       mp->custom_dev_instance = ntohl (custom_dev_instance);
9824     }
9825   mp->use_custom_mac = use_custom_mac;
9826   clib_memcpy (mp->mac_address, hwaddr, 6);
9827
9828   S;
9829   W;
9830   /* NOTREACHED */
9831   return 0;
9832 }
9833
9834 static int
9835 api_modify_vhost_user_if (vat_main_t * vam)
9836 {
9837   unformat_input_t *i = vam->input;
9838   vl_api_modify_vhost_user_if_t *mp;
9839   f64 timeout;
9840   u8 *file_name;
9841   u8 is_server = 0;
9842   u8 file_name_set = 0;
9843   u32 custom_dev_instance = ~0;
9844   u8 sw_if_index_set = 0;
9845   u32 sw_if_index = (u32) ~ 0;
9846
9847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9848     {
9849       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9850         sw_if_index_set = 1;
9851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9852         sw_if_index_set = 1;
9853       else if (unformat (i, "socket %s", &file_name))
9854         {
9855           file_name_set = 1;
9856         }
9857       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9858         ;
9859       else if (unformat (i, "server"))
9860         is_server = 1;
9861       else
9862         break;
9863     }
9864
9865   if (sw_if_index_set == 0)
9866     {
9867       errmsg ("missing sw_if_index or interface name\n");
9868       return -99;
9869     }
9870
9871   if (file_name_set == 0)
9872     {
9873       errmsg ("missing socket file name\n");
9874       return -99;
9875     }
9876
9877   if (vec_len (file_name) > 255)
9878     {
9879       errmsg ("socket file name too long\n");
9880       return -99;
9881     }
9882   vec_add1 (file_name, 0);
9883
9884   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9885
9886   mp->sw_if_index = ntohl (sw_if_index);
9887   mp->is_server = is_server;
9888   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9889   vec_free (file_name);
9890   if (custom_dev_instance != ~0)
9891     {
9892       mp->renumber = 1;
9893       mp->custom_dev_instance = ntohl (custom_dev_instance);
9894     }
9895
9896   S;
9897   W;
9898   /* NOTREACHED */
9899   return 0;
9900 }
9901
9902 static int
9903 api_delete_vhost_user_if (vat_main_t * vam)
9904 {
9905   unformat_input_t *i = vam->input;
9906   vl_api_delete_vhost_user_if_t *mp;
9907   f64 timeout;
9908   u32 sw_if_index = ~0;
9909   u8 sw_if_index_set = 0;
9910
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9914         sw_if_index_set = 1;
9915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9916         sw_if_index_set = 1;
9917       else
9918         break;
9919     }
9920
9921   if (sw_if_index_set == 0)
9922     {
9923       errmsg ("missing sw_if_index or interface name\n");
9924       return -99;
9925     }
9926
9927
9928   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9929
9930   mp->sw_if_index = ntohl (sw_if_index);
9931
9932   S;
9933   W;
9934   /* NOTREACHED */
9935   return 0;
9936 }
9937
9938 static void vl_api_sw_interface_vhost_user_details_t_handler
9939   (vl_api_sw_interface_vhost_user_details_t * mp)
9940 {
9941   vat_main_t *vam = &vat_main;
9942
9943   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9944            (char *) mp->interface_name,
9945            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9946            clib_net_to_host_u64 (mp->features), mp->is_server,
9947            ntohl (mp->num_regions), (char *) mp->sock_filename);
9948   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9949 }
9950
9951 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9952   (vl_api_sw_interface_vhost_user_details_t * mp)
9953 {
9954   vat_main_t *vam = &vat_main;
9955   vat_json_node_t *node = NULL;
9956
9957   if (VAT_JSON_ARRAY != vam->json_tree.type)
9958     {
9959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9960       vat_json_init_array (&vam->json_tree);
9961     }
9962   node = vat_json_array_add (&vam->json_tree);
9963
9964   vat_json_init_object (node);
9965   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9966   vat_json_object_add_string_copy (node, "interface_name",
9967                                    mp->interface_name);
9968   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9969                             ntohl (mp->virtio_net_hdr_sz));
9970   vat_json_object_add_uint (node, "features",
9971                             clib_net_to_host_u64 (mp->features));
9972   vat_json_object_add_uint (node, "is_server", mp->is_server);
9973   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9974   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9975   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9976 }
9977
9978 static int
9979 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9980 {
9981   vl_api_sw_interface_vhost_user_dump_t *mp;
9982   f64 timeout;
9983   fformat (vam->ofp,
9984            "Interface name           idx hdr_sz features server regions filename\n");
9985
9986   /* Get list of vhost-user interfaces */
9987   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9988   S;
9989
9990   /* Use a control ping for synchronization */
9991   {
9992     vl_api_control_ping_t *mp;
9993     M (CONTROL_PING, control_ping);
9994     S;
9995   }
9996   W;
9997 }
9998
9999 static int
10000 api_show_version (vat_main_t * vam)
10001 {
10002   vl_api_show_version_t *mp;
10003   f64 timeout;
10004
10005   M (SHOW_VERSION, show_version);
10006
10007   S;
10008   W;
10009   /* NOTREACHED */
10010   return 0;
10011 }
10012
10013
10014 static int
10015 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10016 {
10017   unformat_input_t *line_input = vam->input;
10018   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10019   f64 timeout;
10020   ip4_address_t local4, remote4;
10021   ip6_address_t local6, remote6;
10022   u8 is_add = 1;
10023   u8 ipv4_set = 0, ipv6_set = 0;
10024   u8 local_set = 0;
10025   u8 remote_set = 0;
10026   u32 encap_vrf_id = 0;
10027   u32 decap_vrf_id = 0;
10028   u8 protocol = ~0;
10029   u32 vni;
10030   u8 vni_set = 0;
10031
10032   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (line_input, "del"))
10035         is_add = 0;
10036       else if (unformat (line_input, "local %U",
10037                          unformat_ip4_address, &local4))
10038         {
10039           local_set = 1;
10040           ipv4_set = 1;
10041         }
10042       else if (unformat (line_input, "remote %U",
10043                          unformat_ip4_address, &remote4))
10044         {
10045           remote_set = 1;
10046           ipv4_set = 1;
10047         }
10048       else if (unformat (line_input, "local %U",
10049                          unformat_ip6_address, &local6))
10050         {
10051           local_set = 1;
10052           ipv6_set = 1;
10053         }
10054       else if (unformat (line_input, "remote %U",
10055                          unformat_ip6_address, &remote6))
10056         {
10057           remote_set = 1;
10058           ipv6_set = 1;
10059         }
10060       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10061         ;
10062       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10063         ;
10064       else if (unformat (line_input, "vni %d", &vni))
10065         vni_set = 1;
10066       else if (unformat (line_input, "next-ip4"))
10067         protocol = 1;
10068       else if (unformat (line_input, "next-ip6"))
10069         protocol = 2;
10070       else if (unformat (line_input, "next-ethernet"))
10071         protocol = 3;
10072       else if (unformat (line_input, "next-nsh"))
10073         protocol = 4;
10074       else
10075         {
10076           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10077           return -99;
10078         }
10079     }
10080
10081   if (local_set == 0)
10082     {
10083       errmsg ("tunnel local address not specified\n");
10084       return -99;
10085     }
10086   if (remote_set == 0)
10087     {
10088       errmsg ("tunnel remote address not specified\n");
10089       return -99;
10090     }
10091   if (ipv4_set && ipv6_set)
10092     {
10093       errmsg ("both IPv4 and IPv6 addresses specified");
10094       return -99;
10095     }
10096
10097   if (vni_set == 0)
10098     {
10099       errmsg ("vni not specified\n");
10100       return -99;
10101     }
10102
10103   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10104
10105
10106   if (ipv6_set)
10107     {
10108       clib_memcpy (&mp->local, &local6, sizeof (local6));
10109       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10110     }
10111   else
10112     {
10113       clib_memcpy (&mp->local, &local4, sizeof (local4));
10114       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10115     }
10116
10117   mp->encap_vrf_id = ntohl (encap_vrf_id);
10118   mp->decap_vrf_id = ntohl (decap_vrf_id);
10119   mp->protocol = ntohl (protocol);
10120   mp->vni = ntohl (vni);
10121   mp->is_add = is_add;
10122   mp->is_ipv6 = ipv6_set;
10123
10124   S;
10125   W;
10126   /* NOTREACHED */
10127   return 0;
10128 }
10129
10130 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10131   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10132 {
10133   vat_main_t *vam = &vat_main;
10134
10135   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10136            ntohl (mp->sw_if_index),
10137            format_ip46_address, &(mp->local[0]),
10138            format_ip46_address, &(mp->remote[0]),
10139            ntohl (mp->vni),
10140            ntohl (mp->protocol),
10141            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10142 }
10143
10144 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10145   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10146 {
10147   vat_main_t *vam = &vat_main;
10148   vat_json_node_t *node = NULL;
10149   struct in_addr ip4;
10150   struct in6_addr ip6;
10151
10152   if (VAT_JSON_ARRAY != vam->json_tree.type)
10153     {
10154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10155       vat_json_init_array (&vam->json_tree);
10156     }
10157   node = vat_json_array_add (&vam->json_tree);
10158
10159   vat_json_init_object (node);
10160   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10161   if (mp->is_ipv6)
10162     {
10163       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10164       vat_json_object_add_ip6 (node, "local", ip6);
10165       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10166       vat_json_object_add_ip6 (node, "remote", ip6);
10167     }
10168   else
10169     {
10170       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10171       vat_json_object_add_ip4 (node, "local", ip4);
10172       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10173       vat_json_object_add_ip4 (node, "remote", ip4);
10174     }
10175   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10176   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10177   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10178   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10179   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10180 }
10181
10182 static int
10183 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10184 {
10185   unformat_input_t *i = vam->input;
10186   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10187   f64 timeout;
10188   u32 sw_if_index;
10189   u8 sw_if_index_set = 0;
10190
10191   /* Parse args required to build the message */
10192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10193     {
10194       if (unformat (i, "sw_if_index %d", &sw_if_index))
10195         sw_if_index_set = 1;
10196       else
10197         break;
10198     }
10199
10200   if (sw_if_index_set == 0)
10201     {
10202       sw_if_index = ~0;
10203     }
10204
10205   if (!vam->json_output)
10206     {
10207       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10208                "sw_if_index", "local", "remote", "vni",
10209                "protocol", "encap_vrf_id", "decap_vrf_id");
10210     }
10211
10212   /* Get list of vxlan-tunnel interfaces */
10213   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10214
10215   mp->sw_if_index = htonl (sw_if_index);
10216
10217   S;
10218
10219   /* Use a control ping for synchronization */
10220   {
10221     vl_api_control_ping_t *mp;
10222     M (CONTROL_PING, control_ping);
10223     S;
10224   }
10225   W;
10226 }
10227
10228 u8 *
10229 format_l2_fib_mac_address (u8 * s, va_list * args)
10230 {
10231   u8 *a = va_arg (*args, u8 *);
10232
10233   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10234                  a[2], a[3], a[4], a[5], a[6], a[7]);
10235 }
10236
10237 static void vl_api_l2_fib_table_entry_t_handler
10238   (vl_api_l2_fib_table_entry_t * mp)
10239 {
10240   vat_main_t *vam = &vat_main;
10241
10242   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10243            "       %d       %d     %d\n",
10244            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10245            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10246            mp->bvi_mac);
10247 }
10248
10249 static void vl_api_l2_fib_table_entry_t_handler_json
10250   (vl_api_l2_fib_table_entry_t * mp)
10251 {
10252   vat_main_t *vam = &vat_main;
10253   vat_json_node_t *node = NULL;
10254
10255   if (VAT_JSON_ARRAY != vam->json_tree.type)
10256     {
10257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10258       vat_json_init_array (&vam->json_tree);
10259     }
10260   node = vat_json_array_add (&vam->json_tree);
10261
10262   vat_json_init_object (node);
10263   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10264   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10265   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10266   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10267   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10268   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10269 }
10270
10271 static int
10272 api_l2_fib_table_dump (vat_main_t * vam)
10273 {
10274   unformat_input_t *i = vam->input;
10275   vl_api_l2_fib_table_dump_t *mp;
10276   f64 timeout;
10277   u32 bd_id;
10278   u8 bd_id_set = 0;
10279
10280   /* Parse args required to build the message */
10281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (i, "bd_id %d", &bd_id))
10284         bd_id_set = 1;
10285       else
10286         break;
10287     }
10288
10289   if (bd_id_set == 0)
10290     {
10291       errmsg ("missing bridge domain\n");
10292       return -99;
10293     }
10294
10295   fformat (vam->ofp,
10296            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10297
10298   /* Get list of l2 fib entries */
10299   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10300
10301   mp->bd_id = ntohl (bd_id);
10302   S;
10303
10304   /* Use a control ping for synchronization */
10305   {
10306     vl_api_control_ping_t *mp;
10307     M (CONTROL_PING, control_ping);
10308     S;
10309   }
10310   W;
10311 }
10312
10313
10314 static int
10315 api_interface_name_renumber (vat_main_t * vam)
10316 {
10317   unformat_input_t *line_input = vam->input;
10318   vl_api_interface_name_renumber_t *mp;
10319   u32 sw_if_index = ~0;
10320   f64 timeout;
10321   u32 new_show_dev_instance = ~0;
10322
10323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10326                     &sw_if_index))
10327         ;
10328       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10329         ;
10330       else if (unformat (line_input, "new_show_dev_instance %d",
10331                          &new_show_dev_instance))
10332         ;
10333       else
10334         break;
10335     }
10336
10337   if (sw_if_index == ~0)
10338     {
10339       errmsg ("missing interface name or sw_if_index\n");
10340       return -99;
10341     }
10342
10343   if (new_show_dev_instance == ~0)
10344     {
10345       errmsg ("missing new_show_dev_instance\n");
10346       return -99;
10347     }
10348
10349   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10350
10351   mp->sw_if_index = ntohl (sw_if_index);
10352   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10353
10354   S;
10355   W;
10356 }
10357
10358 static int
10359 api_want_ip4_arp_events (vat_main_t * vam)
10360 {
10361   unformat_input_t *line_input = vam->input;
10362   vl_api_want_ip4_arp_events_t *mp;
10363   f64 timeout;
10364   ip4_address_t address;
10365   int address_set = 0;
10366   u32 enable_disable = 1;
10367
10368   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10369     {
10370       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10371         address_set = 1;
10372       else if (unformat (line_input, "del"))
10373         enable_disable = 0;
10374       else
10375         break;
10376     }
10377
10378   if (address_set == 0)
10379     {
10380       errmsg ("missing addresses\n");
10381       return -99;
10382     }
10383
10384   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10385   mp->enable_disable = enable_disable;
10386   mp->pid = getpid ();
10387   mp->address = address.as_u32;
10388
10389   S;
10390   W;
10391 }
10392
10393 static int
10394 api_want_ip6_nd_events (vat_main_t * vam)
10395 {
10396   unformat_input_t *line_input = vam->input;
10397   vl_api_want_ip6_nd_events_t *mp;
10398   f64 timeout;
10399   ip6_address_t address;
10400   int address_set = 0;
10401   u32 enable_disable = 1;
10402
10403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10404     {
10405       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10406         address_set = 1;
10407       else if (unformat (line_input, "del"))
10408         enable_disable = 0;
10409       else
10410         break;
10411     }
10412
10413   if (address_set == 0)
10414     {
10415       errmsg ("missing addresses\n");
10416       return -99;
10417     }
10418
10419   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10420   mp->enable_disable = enable_disable;
10421   mp->pid = getpid ();
10422   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10423
10424   S;
10425   W;
10426 }
10427
10428 static int
10429 api_input_acl_set_interface (vat_main_t * vam)
10430 {
10431   unformat_input_t *i = vam->input;
10432   vl_api_input_acl_set_interface_t *mp;
10433   f64 timeout;
10434   u32 sw_if_index;
10435   int sw_if_index_set;
10436   u32 ip4_table_index = ~0;
10437   u32 ip6_table_index = ~0;
10438   u32 l2_table_index = ~0;
10439   u8 is_add = 1;
10440
10441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10442     {
10443       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10444         sw_if_index_set = 1;
10445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10446         sw_if_index_set = 1;
10447       else if (unformat (i, "del"))
10448         is_add = 0;
10449       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10450         ;
10451       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10452         ;
10453       else if (unformat (i, "l2-table %d", &l2_table_index))
10454         ;
10455       else
10456         {
10457           clib_warning ("parse error '%U'", format_unformat_error, i);
10458           return -99;
10459         }
10460     }
10461
10462   if (sw_if_index_set == 0)
10463     {
10464       errmsg ("missing interface name or sw_if_index\n");
10465       return -99;
10466     }
10467
10468   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10469
10470   mp->sw_if_index = ntohl (sw_if_index);
10471   mp->ip4_table_index = ntohl (ip4_table_index);
10472   mp->ip6_table_index = ntohl (ip6_table_index);
10473   mp->l2_table_index = ntohl (l2_table_index);
10474   mp->is_add = is_add;
10475
10476   S;
10477   W;
10478   /* NOTREACHED */
10479   return 0;
10480 }
10481
10482 static int
10483 api_ip_address_dump (vat_main_t * vam)
10484 {
10485   unformat_input_t *i = vam->input;
10486   vl_api_ip_address_dump_t *mp;
10487   u32 sw_if_index = ~0;
10488   u8 sw_if_index_set = 0;
10489   u8 ipv4_set = 0;
10490   u8 ipv6_set = 0;
10491   f64 timeout;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "sw_if_index %d", &sw_if_index))
10496         sw_if_index_set = 1;
10497       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10498         sw_if_index_set = 1;
10499       else if (unformat (i, "ipv4"))
10500         ipv4_set = 1;
10501       else if (unformat (i, "ipv6"))
10502         ipv6_set = 1;
10503       else
10504         break;
10505     }
10506
10507   if (ipv4_set && ipv6_set)
10508     {
10509       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10510       return -99;
10511     }
10512
10513   if ((!ipv4_set) && (!ipv6_set))
10514     {
10515       errmsg ("no ipv4 nor ipv6 flag set\n");
10516       return -99;
10517     }
10518
10519   if (sw_if_index_set == 0)
10520     {
10521       errmsg ("missing interface name or sw_if_index\n");
10522       return -99;
10523     }
10524
10525   vam->current_sw_if_index = sw_if_index;
10526   vam->is_ipv6 = ipv6_set;
10527
10528   M (IP_ADDRESS_DUMP, ip_address_dump);
10529   mp->sw_if_index = ntohl (sw_if_index);
10530   mp->is_ipv6 = ipv6_set;
10531   S;
10532
10533   /* Use a control ping for synchronization */
10534   {
10535     vl_api_control_ping_t *mp;
10536     M (CONTROL_PING, control_ping);
10537     S;
10538   }
10539   W;
10540 }
10541
10542 static int
10543 api_ip_dump (vat_main_t * vam)
10544 {
10545   vl_api_ip_dump_t *mp;
10546   unformat_input_t *in = vam->input;
10547   int ipv4_set = 0;
10548   int ipv6_set = 0;
10549   int is_ipv6;
10550   f64 timeout;
10551   int i;
10552
10553   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10554     {
10555       if (unformat (in, "ipv4"))
10556         ipv4_set = 1;
10557       else if (unformat (in, "ipv6"))
10558         ipv6_set = 1;
10559       else
10560         break;
10561     }
10562
10563   if (ipv4_set && ipv6_set)
10564     {
10565       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10566       return -99;
10567     }
10568
10569   if ((!ipv4_set) && (!ipv6_set))
10570     {
10571       errmsg ("no ipv4 nor ipv6 flag set\n");
10572       return -99;
10573     }
10574
10575   is_ipv6 = ipv6_set;
10576   vam->is_ipv6 = is_ipv6;
10577
10578   /* free old data */
10579   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10580     {
10581       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10582     }
10583   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10584
10585   M (IP_DUMP, ip_dump);
10586   mp->is_ipv6 = ipv6_set;
10587   S;
10588
10589   /* Use a control ping for synchronization */
10590   {
10591     vl_api_control_ping_t *mp;
10592     M (CONTROL_PING, control_ping);
10593     S;
10594   }
10595   W;
10596 }
10597
10598 static int
10599 api_ipsec_spd_add_del (vat_main_t * vam)
10600 {
10601 #if DPDK > 0
10602   unformat_input_t *i = vam->input;
10603   vl_api_ipsec_spd_add_del_t *mp;
10604   f64 timeout;
10605   u32 spd_id = ~0;
10606   u8 is_add = 1;
10607
10608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10609     {
10610       if (unformat (i, "spd_id %d", &spd_id))
10611         ;
10612       else if (unformat (i, "del"))
10613         is_add = 0;
10614       else
10615         {
10616           clib_warning ("parse error '%U'", format_unformat_error, i);
10617           return -99;
10618         }
10619     }
10620   if (spd_id == ~0)
10621     {
10622       errmsg ("spd_id must be set\n");
10623       return -99;
10624     }
10625
10626   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10627
10628   mp->spd_id = ntohl (spd_id);
10629   mp->is_add = is_add;
10630
10631   S;
10632   W;
10633   /* NOTREACHED */
10634   return 0;
10635 #else
10636   clib_warning ("unsupported (no dpdk)");
10637   return -99;
10638 #endif
10639 }
10640
10641 static int
10642 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10643 {
10644 #if DPDK > 0
10645   unformat_input_t *i = vam->input;
10646   vl_api_ipsec_interface_add_del_spd_t *mp;
10647   f64 timeout;
10648   u32 sw_if_index;
10649   u8 sw_if_index_set = 0;
10650   u32 spd_id = (u32) ~ 0;
10651   u8 is_add = 1;
10652
10653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10654     {
10655       if (unformat (i, "del"))
10656         is_add = 0;
10657       else if (unformat (i, "spd_id %d", &spd_id))
10658         ;
10659       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10660         sw_if_index_set = 1;
10661       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10662         sw_if_index_set = 1;
10663       else
10664         {
10665           clib_warning ("parse error '%U'", format_unformat_error, i);
10666           return -99;
10667         }
10668
10669     }
10670
10671   if (spd_id == (u32) ~ 0)
10672     {
10673       errmsg ("spd_id must be set\n");
10674       return -99;
10675     }
10676
10677   if (sw_if_index_set == 0)
10678     {
10679       errmsg ("missing interface name or sw_if_index\n");
10680       return -99;
10681     }
10682
10683   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10684
10685   mp->spd_id = ntohl (spd_id);
10686   mp->sw_if_index = ntohl (sw_if_index);
10687   mp->is_add = is_add;
10688
10689   S;
10690   W;
10691   /* NOTREACHED */
10692   return 0;
10693 #else
10694   clib_warning ("unsupported (no dpdk)");
10695   return -99;
10696 #endif
10697 }
10698
10699 static int
10700 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10701 {
10702 #if DPDK > 0
10703   unformat_input_t *i = vam->input;
10704   vl_api_ipsec_spd_add_del_entry_t *mp;
10705   f64 timeout;
10706   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10707   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10708   i32 priority = 0;
10709   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10710   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10711   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10712   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10713
10714   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10715   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10716   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10717   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10718   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10719   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "del"))
10724         is_add = 0;
10725       if (unformat (i, "outbound"))
10726         is_outbound = 1;
10727       if (unformat (i, "inbound"))
10728         is_outbound = 0;
10729       else if (unformat (i, "spd_id %d", &spd_id))
10730         ;
10731       else if (unformat (i, "sa_id %d", &sa_id))
10732         ;
10733       else if (unformat (i, "priority %d", &priority))
10734         ;
10735       else if (unformat (i, "protocol %d", &protocol))
10736         ;
10737       else if (unformat (i, "lport_start %d", &lport_start))
10738         ;
10739       else if (unformat (i, "lport_stop %d", &lport_stop))
10740         ;
10741       else if (unformat (i, "rport_start %d", &rport_start))
10742         ;
10743       else if (unformat (i, "rport_stop %d", &rport_stop))
10744         ;
10745       else
10746         if (unformat
10747             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10748         {
10749           is_ipv6 = 0;
10750           is_ip_any = 0;
10751         }
10752       else
10753         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10754         {
10755           is_ipv6 = 0;
10756           is_ip_any = 0;
10757         }
10758       else
10759         if (unformat
10760             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10761         {
10762           is_ipv6 = 0;
10763           is_ip_any = 0;
10764         }
10765       else
10766         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10767         {
10768           is_ipv6 = 0;
10769           is_ip_any = 0;
10770         }
10771       else
10772         if (unformat
10773             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10774         {
10775           is_ipv6 = 1;
10776           is_ip_any = 0;
10777         }
10778       else
10779         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10780         {
10781           is_ipv6 = 1;
10782           is_ip_any = 0;
10783         }
10784       else
10785         if (unformat
10786             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10787         {
10788           is_ipv6 = 1;
10789           is_ip_any = 0;
10790         }
10791       else
10792         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10793         {
10794           is_ipv6 = 1;
10795           is_ip_any = 0;
10796         }
10797       else
10798         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10799         {
10800           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10801             {
10802               clib_warning ("unsupported action: 'resolve'");
10803               return -99;
10804             }
10805         }
10806       else
10807         {
10808           clib_warning ("parse error '%U'", format_unformat_error, i);
10809           return -99;
10810         }
10811
10812     }
10813
10814   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10815
10816   mp->spd_id = ntohl (spd_id);
10817   mp->priority = ntohl (priority);
10818   mp->is_outbound = is_outbound;
10819
10820   mp->is_ipv6 = is_ipv6;
10821   if (is_ipv6 || is_ip_any)
10822     {
10823       clib_memcpy (mp->remote_address_start, &raddr6_start,
10824                    sizeof (ip6_address_t));
10825       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10826                    sizeof (ip6_address_t));
10827       clib_memcpy (mp->local_address_start, &laddr6_start,
10828                    sizeof (ip6_address_t));
10829       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10830                    sizeof (ip6_address_t));
10831     }
10832   else
10833     {
10834       clib_memcpy (mp->remote_address_start, &raddr4_start,
10835                    sizeof (ip4_address_t));
10836       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10837                    sizeof (ip4_address_t));
10838       clib_memcpy (mp->local_address_start, &laddr4_start,
10839                    sizeof (ip4_address_t));
10840       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10841                    sizeof (ip4_address_t));
10842     }
10843   mp->protocol = (u8) protocol;
10844   mp->local_port_start = ntohs ((u16) lport_start);
10845   mp->local_port_stop = ntohs ((u16) lport_stop);
10846   mp->remote_port_start = ntohs ((u16) rport_start);
10847   mp->remote_port_stop = ntohs ((u16) rport_stop);
10848   mp->policy = (u8) policy;
10849   mp->sa_id = ntohl (sa_id);
10850   mp->is_add = is_add;
10851   mp->is_ip_any = is_ip_any;
10852   S;
10853   W;
10854   /* NOTREACHED */
10855   return 0;
10856 #else
10857   clib_warning ("unsupported (no dpdk)");
10858   return -99;
10859 #endif
10860 }
10861
10862 static int
10863 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10864 {
10865 #if DPDK > 0
10866   unformat_input_t *i = vam->input;
10867   vl_api_ipsec_sad_add_del_entry_t *mp;
10868   f64 timeout;
10869   u32 sad_id = 0, spi = 0;
10870   u8 *ck = 0, *ik = 0;
10871   u8 is_add = 1;
10872
10873   u8 protocol = IPSEC_PROTOCOL_AH;
10874   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10875   u32 crypto_alg = 0, integ_alg = 0;
10876   ip4_address_t tun_src4;
10877   ip4_address_t tun_dst4;
10878   ip6_address_t tun_src6;
10879   ip6_address_t tun_dst6;
10880
10881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10882     {
10883       if (unformat (i, "del"))
10884         is_add = 0;
10885       else if (unformat (i, "sad_id %d", &sad_id))
10886         ;
10887       else if (unformat (i, "spi %d", &spi))
10888         ;
10889       else if (unformat (i, "esp"))
10890         protocol = IPSEC_PROTOCOL_ESP;
10891       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10892         {
10893           is_tunnel = 1;
10894           is_tunnel_ipv6 = 0;
10895         }
10896       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10897         {
10898           is_tunnel = 1;
10899           is_tunnel_ipv6 = 0;
10900         }
10901       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10902         {
10903           is_tunnel = 1;
10904           is_tunnel_ipv6 = 1;
10905         }
10906       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10907         {
10908           is_tunnel = 1;
10909           is_tunnel_ipv6 = 1;
10910         }
10911       else
10912         if (unformat
10913             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10914         {
10915           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10916               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10917             {
10918               clib_warning ("unsupported crypto-alg: '%U'",
10919                             format_ipsec_crypto_alg, crypto_alg);
10920               return -99;
10921             }
10922         }
10923       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10924         ;
10925       else
10926         if (unformat
10927             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10928         {
10929           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10930               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10931             {
10932               clib_warning ("unsupported integ-alg: '%U'",
10933                             format_ipsec_integ_alg, integ_alg);
10934               return -99;
10935             }
10936         }
10937       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10938         ;
10939       else
10940         {
10941           clib_warning ("parse error '%U'", format_unformat_error, i);
10942           return -99;
10943         }
10944
10945     }
10946
10947   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10948
10949   mp->sad_id = ntohl (sad_id);
10950   mp->is_add = is_add;
10951   mp->protocol = protocol;
10952   mp->spi = ntohl (spi);
10953   mp->is_tunnel = is_tunnel;
10954   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10955   mp->crypto_algorithm = crypto_alg;
10956   mp->integrity_algorithm = integ_alg;
10957   mp->crypto_key_length = vec_len (ck);
10958   mp->integrity_key_length = vec_len (ik);
10959
10960   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10961     mp->crypto_key_length = sizeof (mp->crypto_key);
10962
10963   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10964     mp->integrity_key_length = sizeof (mp->integrity_key);
10965
10966   if (ck)
10967     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10968   if (ik)
10969     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10970
10971   if (is_tunnel)
10972     {
10973       if (is_tunnel_ipv6)
10974         {
10975           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10976                        sizeof (ip6_address_t));
10977           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10978                        sizeof (ip6_address_t));
10979         }
10980       else
10981         {
10982           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10983                        sizeof (ip4_address_t));
10984           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10985                        sizeof (ip4_address_t));
10986         }
10987     }
10988
10989   S;
10990   W;
10991   /* NOTREACHED */
10992   return 0;
10993 #else
10994   clib_warning ("unsupported (no dpdk)");
10995   return -99;
10996 #endif
10997 }
10998
10999 static int
11000 api_ipsec_sa_set_key (vat_main_t * vam)
11001 {
11002 #if DPDK > 0
11003   unformat_input_t *i = vam->input;
11004   vl_api_ipsec_sa_set_key_t *mp;
11005   f64 timeout;
11006   u32 sa_id;
11007   u8 *ck = 0, *ik = 0;
11008
11009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11010     {
11011       if (unformat (i, "sa_id %d", &sa_id))
11012         ;
11013       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11014         ;
11015       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11016         ;
11017       else
11018         {
11019           clib_warning ("parse error '%U'", format_unformat_error, i);
11020           return -99;
11021         }
11022     }
11023
11024   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11025
11026   mp->sa_id = ntohl (sa_id);
11027   mp->crypto_key_length = vec_len (ck);
11028   mp->integrity_key_length = vec_len (ik);
11029
11030   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11031     mp->crypto_key_length = sizeof (mp->crypto_key);
11032
11033   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11034     mp->integrity_key_length = sizeof (mp->integrity_key);
11035
11036   if (ck)
11037     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11038   if (ik)
11039     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11040
11041   S;
11042   W;
11043   /* NOTREACHED */
11044   return 0;
11045 #else
11046   clib_warning ("unsupported (no dpdk)");
11047   return -99;
11048 #endif
11049 }
11050
11051 static int
11052 api_ikev2_profile_add_del (vat_main_t * vam)
11053 {
11054 #if DPDK > 0
11055   unformat_input_t *i = vam->input;
11056   vl_api_ikev2_profile_add_del_t *mp;
11057   f64 timeout;
11058   u8 is_add = 1;
11059   u8 *name = 0;
11060
11061   const char *valid_chars = "a-zA-Z0-9_";
11062
11063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11064     {
11065       if (unformat (i, "del"))
11066         is_add = 0;
11067       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11068         vec_add1 (name, 0);
11069       else
11070         {
11071           errmsg ("parse error '%U'", format_unformat_error, i);
11072           return -99;
11073         }
11074     }
11075
11076   if (!vec_len (name))
11077     {
11078       errmsg ("profile name must be specified");
11079       return -99;
11080     }
11081
11082   if (vec_len (name) > 64)
11083     {
11084       errmsg ("profile name too long");
11085       return -99;
11086     }
11087
11088   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11089
11090   clib_memcpy (mp->name, name, vec_len (name));
11091   mp->is_add = is_add;
11092   vec_free (name);
11093
11094   S;
11095   W;
11096   /* NOTREACHED */
11097   return 0;
11098 #else
11099   clib_warning ("unsupported (no dpdk)");
11100   return -99;
11101 #endif
11102 }
11103
11104 static int
11105 api_ikev2_profile_set_auth (vat_main_t * vam)
11106 {
11107 #if DPDK > 0
11108   unformat_input_t *i = vam->input;
11109   vl_api_ikev2_profile_set_auth_t *mp;
11110   f64 timeout;
11111   u8 *name = 0;
11112   u8 *data = 0;
11113   u32 auth_method = 0;
11114   u8 is_hex = 0;
11115
11116   const char *valid_chars = "a-zA-Z0-9_";
11117
11118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11119     {
11120       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11121         vec_add1 (name, 0);
11122       else if (unformat (i, "auth_method %U",
11123                          unformat_ikev2_auth_method, &auth_method))
11124         ;
11125       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11126         is_hex = 1;
11127       else if (unformat (i, "auth_data %v", &data))
11128         ;
11129       else
11130         {
11131           errmsg ("parse error '%U'", format_unformat_error, i);
11132           return -99;
11133         }
11134     }
11135
11136   if (!vec_len (name))
11137     {
11138       errmsg ("profile name must be specified");
11139       return -99;
11140     }
11141
11142   if (vec_len (name) > 64)
11143     {
11144       errmsg ("profile name too long");
11145       return -99;
11146     }
11147
11148   if (!vec_len (data))
11149     {
11150       errmsg ("auth_data must be specified");
11151       return -99;
11152     }
11153
11154   if (!auth_method)
11155     {
11156       errmsg ("auth_method must be specified");
11157       return -99;
11158     }
11159
11160   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11161
11162   mp->is_hex = is_hex;
11163   mp->auth_method = (u8) auth_method;
11164   mp->data_len = vec_len (data);
11165   clib_memcpy (mp->name, name, vec_len (name));
11166   clib_memcpy (mp->data, data, vec_len (data));
11167   vec_free (name);
11168   vec_free (data);
11169
11170   S;
11171   W;
11172   /* NOTREACHED */
11173   return 0;
11174 #else
11175   clib_warning ("unsupported (no dpdk)");
11176   return -99;
11177 #endif
11178 }
11179
11180 static int
11181 api_ikev2_profile_set_id (vat_main_t * vam)
11182 {
11183 #if DPDK > 0
11184   unformat_input_t *i = vam->input;
11185   vl_api_ikev2_profile_set_id_t *mp;
11186   f64 timeout;
11187   u8 *name = 0;
11188   u8 *data = 0;
11189   u8 is_local = 0;
11190   u32 id_type = 0;
11191   ip4_address_t ip4;
11192
11193   const char *valid_chars = "a-zA-Z0-9_";
11194
11195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11196     {
11197       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11198         vec_add1 (name, 0);
11199       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11200         ;
11201       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11202         {
11203           data = vec_new (u8, 4);
11204           clib_memcpy (data, ip4.as_u8, 4);
11205         }
11206       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11207         ;
11208       else if (unformat (i, "id_data %v", &data))
11209         ;
11210       else if (unformat (i, "local"))
11211         is_local = 1;
11212       else if (unformat (i, "remote"))
11213         is_local = 0;
11214       else
11215         {
11216           errmsg ("parse error '%U'", format_unformat_error, i);
11217           return -99;
11218         }
11219     }
11220
11221   if (!vec_len (name))
11222     {
11223       errmsg ("profile name must be specified");
11224       return -99;
11225     }
11226
11227   if (vec_len (name) > 64)
11228     {
11229       errmsg ("profile name too long");
11230       return -99;
11231     }
11232
11233   if (!vec_len (data))
11234     {
11235       errmsg ("id_data must be specified");
11236       return -99;
11237     }
11238
11239   if (!id_type)
11240     {
11241       errmsg ("id_type must be specified");
11242       return -99;
11243     }
11244
11245   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11246
11247   mp->is_local = is_local;
11248   mp->id_type = (u8) id_type;
11249   mp->data_len = vec_len (data);
11250   clib_memcpy (mp->name, name, vec_len (name));
11251   clib_memcpy (mp->data, data, vec_len (data));
11252   vec_free (name);
11253   vec_free (data);
11254
11255   S;
11256   W;
11257   /* NOTREACHED */
11258   return 0;
11259 #else
11260   clib_warning ("unsupported (no dpdk)");
11261   return -99;
11262 #endif
11263 }
11264
11265 static int
11266 api_ikev2_profile_set_ts (vat_main_t * vam)
11267 {
11268 #if DPDK > 0
11269   unformat_input_t *i = vam->input;
11270   vl_api_ikev2_profile_set_ts_t *mp;
11271   f64 timeout;
11272   u8 *name = 0;
11273   u8 is_local = 0;
11274   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11275   ip4_address_t start_addr, end_addr;
11276
11277   const char *valid_chars = "a-zA-Z0-9_";
11278
11279   start_addr.as_u32 = 0;
11280   end_addr.as_u32 = (u32) ~ 0;
11281
11282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11283     {
11284       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11285         vec_add1 (name, 0);
11286       else if (unformat (i, "protocol %d", &proto))
11287         ;
11288       else if (unformat (i, "start_port %d", &start_port))
11289         ;
11290       else if (unformat (i, "end_port %d", &end_port))
11291         ;
11292       else
11293         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11294         ;
11295       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11296         ;
11297       else if (unformat (i, "local"))
11298         is_local = 1;
11299       else if (unformat (i, "remote"))
11300         is_local = 0;
11301       else
11302         {
11303           errmsg ("parse error '%U'", format_unformat_error, i);
11304           return -99;
11305         }
11306     }
11307
11308   if (!vec_len (name))
11309     {
11310       errmsg ("profile name must be specified");
11311       return -99;
11312     }
11313
11314   if (vec_len (name) > 64)
11315     {
11316       errmsg ("profile name too long");
11317       return -99;
11318     }
11319
11320   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11321
11322   mp->is_local = is_local;
11323   mp->proto = (u8) proto;
11324   mp->start_port = (u16) start_port;
11325   mp->end_port = (u16) end_port;
11326   mp->start_addr = start_addr.as_u32;
11327   mp->end_addr = end_addr.as_u32;
11328   clib_memcpy (mp->name, name, vec_len (name));
11329   vec_free (name);
11330
11331   S;
11332   W;
11333   /* NOTREACHED */
11334   return 0;
11335 #else
11336   clib_warning ("unsupported (no dpdk)");
11337   return -99;
11338 #endif
11339 }
11340
11341 static int
11342 api_ikev2_set_local_key (vat_main_t * vam)
11343 {
11344 #if DPDK > 0
11345   unformat_input_t *i = vam->input;
11346   vl_api_ikev2_set_local_key_t *mp;
11347   f64 timeout;
11348   u8 *file = 0;
11349
11350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11351     {
11352       if (unformat (i, "file %v", &file))
11353         vec_add1 (file, 0);
11354       else
11355         {
11356           errmsg ("parse error '%U'", format_unformat_error, i);
11357           return -99;
11358         }
11359     }
11360
11361   if (!vec_len (file))
11362     {
11363       errmsg ("RSA key file must be specified");
11364       return -99;
11365     }
11366
11367   if (vec_len (file) > 256)
11368     {
11369       errmsg ("file name too long");
11370       return -99;
11371     }
11372
11373   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11374
11375   clib_memcpy (mp->key_file, file, vec_len (file));
11376   vec_free (file);
11377
11378   S;
11379   W;
11380   /* NOTREACHED */
11381   return 0;
11382 #else
11383   clib_warning ("unsupported (no dpdk)");
11384   return -99;
11385 #endif
11386 }
11387
11388 /*
11389  * MAP
11390  */
11391 static int
11392 api_map_add_domain (vat_main_t * vam)
11393 {
11394   unformat_input_t *i = vam->input;
11395   vl_api_map_add_domain_t *mp;
11396   f64 timeout;
11397
11398   ip4_address_t ip4_prefix;
11399   ip6_address_t ip6_prefix;
11400   ip6_address_t ip6_src;
11401   u32 num_m_args = 0;
11402   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11403     0, psid_length = 0;
11404   u8 is_translation = 0;
11405   u32 mtu = 0;
11406   u32 ip6_src_len = 128;
11407
11408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11409     {
11410       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11411                     &ip4_prefix, &ip4_prefix_len))
11412         num_m_args++;
11413       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11414                          &ip6_prefix, &ip6_prefix_len))
11415         num_m_args++;
11416       else
11417         if (unformat
11418             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11419              &ip6_src_len))
11420         num_m_args++;
11421       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11422         num_m_args++;
11423       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11424         num_m_args++;
11425       else if (unformat (i, "psid-offset %d", &psid_offset))
11426         num_m_args++;
11427       else if (unformat (i, "psid-len %d", &psid_length))
11428         num_m_args++;
11429       else if (unformat (i, "mtu %d", &mtu))
11430         num_m_args++;
11431       else if (unformat (i, "map-t"))
11432         is_translation = 1;
11433       else
11434         {
11435           clib_warning ("parse error '%U'", format_unformat_error, i);
11436           return -99;
11437         }
11438     }
11439
11440   if (num_m_args < 3)
11441     {
11442       errmsg ("mandatory argument(s) missing\n");
11443       return -99;
11444     }
11445
11446   /* Construct the API message */
11447   M (MAP_ADD_DOMAIN, map_add_domain);
11448
11449   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11450   mp->ip4_prefix_len = ip4_prefix_len;
11451
11452   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11453   mp->ip6_prefix_len = ip6_prefix_len;
11454
11455   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11456   mp->ip6_src_prefix_len = ip6_src_len;
11457
11458   mp->ea_bits_len = ea_bits_len;
11459   mp->psid_offset = psid_offset;
11460   mp->psid_length = psid_length;
11461   mp->is_translation = is_translation;
11462   mp->mtu = htons (mtu);
11463
11464   /* send it... */
11465   S;
11466
11467   /* Wait for a reply, return good/bad news  */
11468   W;
11469 }
11470
11471 static int
11472 api_map_del_domain (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_map_del_domain_t *mp;
11476   f64 timeout;
11477
11478   u32 num_m_args = 0;
11479   u32 index;
11480
11481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11482     {
11483       if (unformat (i, "index %d", &index))
11484         num_m_args++;
11485       else
11486         {
11487           clib_warning ("parse error '%U'", format_unformat_error, i);
11488           return -99;
11489         }
11490     }
11491
11492   if (num_m_args != 1)
11493     {
11494       errmsg ("mandatory argument(s) missing\n");
11495       return -99;
11496     }
11497
11498   /* Construct the API message */
11499   M (MAP_DEL_DOMAIN, map_del_domain);
11500
11501   mp->index = ntohl (index);
11502
11503   /* send it... */
11504   S;
11505
11506   /* Wait for a reply, return good/bad news  */
11507   W;
11508 }
11509
11510 static int
11511 api_map_add_del_rule (vat_main_t * vam)
11512 {
11513   unformat_input_t *i = vam->input;
11514   vl_api_map_add_del_rule_t *mp;
11515   f64 timeout;
11516   u8 is_add = 1;
11517   ip6_address_t ip6_dst;
11518   u32 num_m_args = 0, index, psid = 0;
11519
11520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11521     {
11522       if (unformat (i, "index %d", &index))
11523         num_m_args++;
11524       else if (unformat (i, "psid %d", &psid))
11525         num_m_args++;
11526       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11527         num_m_args++;
11528       else if (unformat (i, "del"))
11529         {
11530           is_add = 0;
11531         }
11532       else
11533         {
11534           clib_warning ("parse error '%U'", format_unformat_error, i);
11535           return -99;
11536         }
11537     }
11538
11539   /* Construct the API message */
11540   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11541
11542   mp->index = ntohl (index);
11543   mp->is_add = is_add;
11544   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11545   mp->psid = ntohs (psid);
11546
11547   /* send it... */
11548   S;
11549
11550   /* Wait for a reply, return good/bad news  */
11551   W;
11552 }
11553
11554 static int
11555 api_map_domain_dump (vat_main_t * vam)
11556 {
11557   vl_api_map_domain_dump_t *mp;
11558   f64 timeout;
11559
11560   /* Construct the API message */
11561   M (MAP_DOMAIN_DUMP, map_domain_dump);
11562
11563   /* send it... */
11564   S;
11565
11566   /* Use a control ping for synchronization */
11567   {
11568     vl_api_control_ping_t *mp;
11569     M (CONTROL_PING, control_ping);
11570     S;
11571   }
11572   W;
11573 }
11574
11575 static int
11576 api_map_rule_dump (vat_main_t * vam)
11577 {
11578   unformat_input_t *i = vam->input;
11579   vl_api_map_rule_dump_t *mp;
11580   f64 timeout;
11581   u32 domain_index = ~0;
11582
11583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (i, "index %u", &domain_index))
11586         ;
11587       else
11588         break;
11589     }
11590
11591   if (domain_index == ~0)
11592     {
11593       clib_warning ("parse error: domain index expected");
11594       return -99;
11595     }
11596
11597   /* Construct the API message */
11598   M (MAP_RULE_DUMP, map_rule_dump);
11599
11600   mp->domain_index = htonl (domain_index);
11601
11602   /* send it... */
11603   S;
11604
11605   /* Use a control ping for synchronization */
11606   {
11607     vl_api_control_ping_t *mp;
11608     M (CONTROL_PING, control_ping);
11609     S;
11610   }
11611   W;
11612 }
11613
11614 static void vl_api_map_add_domain_reply_t_handler
11615   (vl_api_map_add_domain_reply_t * mp)
11616 {
11617   vat_main_t *vam = &vat_main;
11618   i32 retval = ntohl (mp->retval);
11619
11620   if (vam->async_mode)
11621     {
11622       vam->async_errors += (retval < 0);
11623     }
11624   else
11625     {
11626       vam->retval = retval;
11627       vam->result_ready = 1;
11628     }
11629 }
11630
11631 static void vl_api_map_add_domain_reply_t_handler_json
11632   (vl_api_map_add_domain_reply_t * mp)
11633 {
11634   vat_main_t *vam = &vat_main;
11635   vat_json_node_t node;
11636
11637   vat_json_init_object (&node);
11638   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11639   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11640
11641   vat_json_print (vam->ofp, &node);
11642   vat_json_free (&node);
11643
11644   vam->retval = ntohl (mp->retval);
11645   vam->result_ready = 1;
11646 }
11647
11648 static int
11649 api_get_first_msg_id (vat_main_t * vam)
11650 {
11651   vl_api_get_first_msg_id_t *mp;
11652   f64 timeout;
11653   unformat_input_t *i = vam->input;
11654   u8 *name;
11655   u8 name_set = 0;
11656
11657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11658     {
11659       if (unformat (i, "client %s", &name))
11660         name_set = 1;
11661       else
11662         break;
11663     }
11664
11665   if (name_set == 0)
11666     {
11667       errmsg ("missing client name\n");
11668       return -99;
11669     }
11670   vec_add1 (name, 0);
11671
11672   if (vec_len (name) > 63)
11673     {
11674       errmsg ("client name too long\n");
11675       return -99;
11676     }
11677
11678   M (GET_FIRST_MSG_ID, get_first_msg_id);
11679   clib_memcpy (mp->name, name, vec_len (name));
11680   S;
11681   W;
11682   /* NOTREACHED */
11683   return 0;
11684 }
11685
11686 static int
11687 api_cop_interface_enable_disable (vat_main_t * vam)
11688 {
11689   unformat_input_t *line_input = vam->input;
11690   vl_api_cop_interface_enable_disable_t *mp;
11691   f64 timeout;
11692   u32 sw_if_index = ~0;
11693   u8 enable_disable = 1;
11694
11695   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (line_input, "disable"))
11698         enable_disable = 0;
11699       if (unformat (line_input, "enable"))
11700         enable_disable = 1;
11701       else if (unformat (line_input, "%U", unformat_sw_if_index,
11702                          vam, &sw_if_index))
11703         ;
11704       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11705         ;
11706       else
11707         break;
11708     }
11709
11710   if (sw_if_index == ~0)
11711     {
11712       errmsg ("missing interface name or sw_if_index\n");
11713       return -99;
11714     }
11715
11716   /* Construct the API message */
11717   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11718   mp->sw_if_index = ntohl (sw_if_index);
11719   mp->enable_disable = enable_disable;
11720
11721   /* send it... */
11722   S;
11723   /* Wait for the reply */
11724   W;
11725 }
11726
11727 static int
11728 api_cop_whitelist_enable_disable (vat_main_t * vam)
11729 {
11730   unformat_input_t *line_input = vam->input;
11731   vl_api_cop_whitelist_enable_disable_t *mp;
11732   f64 timeout;
11733   u32 sw_if_index = ~0;
11734   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11735   u32 fib_id = 0;
11736
11737   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11738     {
11739       if (unformat (line_input, "ip4"))
11740         ip4 = 1;
11741       else if (unformat (line_input, "ip6"))
11742         ip6 = 1;
11743       else if (unformat (line_input, "default"))
11744         default_cop = 1;
11745       else if (unformat (line_input, "%U", unformat_sw_if_index,
11746                          vam, &sw_if_index))
11747         ;
11748       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11749         ;
11750       else if (unformat (line_input, "fib-id %d", &fib_id))
11751         ;
11752       else
11753         break;
11754     }
11755
11756   if (sw_if_index == ~0)
11757     {
11758       errmsg ("missing interface name or sw_if_index\n");
11759       return -99;
11760     }
11761
11762   /* Construct the API message */
11763   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11764   mp->sw_if_index = ntohl (sw_if_index);
11765   mp->fib_id = ntohl (fib_id);
11766   mp->ip4 = ip4;
11767   mp->ip6 = ip6;
11768   mp->default_cop = default_cop;
11769
11770   /* send it... */
11771   S;
11772   /* Wait for the reply */
11773   W;
11774 }
11775
11776 static int
11777 api_get_node_graph (vat_main_t * vam)
11778 {
11779   vl_api_get_node_graph_t *mp;
11780   f64 timeout;
11781
11782   M (GET_NODE_GRAPH, get_node_graph);
11783
11784   /* send it... */
11785   S;
11786   /* Wait for the reply */
11787   W;
11788 }
11789
11790 /* *INDENT-OFF* */
11791 /** Used for parsing LISP eids */
11792 typedef CLIB_PACKED(struct{
11793   u8 addr[16];   /**< eid address */
11794   u32 len;       /**< prefix length if IP */
11795   u8 type;      /**< type of eid */
11796 }) lisp_eid_vat_t;
11797 /* *INDENT-ON* */
11798
11799 static uword
11800 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11801 {
11802   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11803
11804   memset (a, 0, sizeof (a[0]));
11805
11806   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11807     {
11808       a->type = 0;              /* ipv4 type */
11809     }
11810   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11811     {
11812       a->type = 1;              /* ipv6 type */
11813     }
11814   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11815     {
11816       a->type = 2;              /* mac type */
11817     }
11818   else
11819     {
11820       return 0;
11821     }
11822
11823   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11824     {
11825       return 0;
11826     }
11827
11828   return 1;
11829 }
11830
11831 static int
11832 lisp_eid_size_vat (u8 type)
11833 {
11834   switch (type)
11835     {
11836     case 0:
11837       return 4;
11838     case 1:
11839       return 16;
11840     case 2:
11841       return 6;
11842     }
11843   return 0;
11844 }
11845
11846 static void
11847 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11848 {
11849   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11850 }
11851
11852 /* *INDENT-OFF* */
11853 /** Used for transferring locators via VPP API */
11854 typedef CLIB_PACKED(struct
11855 {
11856   u32 sw_if_index; /**< locator sw_if_index */
11857   u8 priority; /**< locator priority */
11858   u8 weight;   /**< locator weight */
11859 }) ls_locator_t;
11860 /* *INDENT-ON* */
11861
11862 static int
11863 api_lisp_add_del_locator_set (vat_main_t * vam)
11864 {
11865   unformat_input_t *input = vam->input;
11866   vl_api_lisp_add_del_locator_set_t *mp;
11867   f64 timeout = ~0;
11868   u8 is_add = 1;
11869   u8 *locator_set_name = NULL;
11870   u8 locator_set_name_set = 0;
11871   ls_locator_t locator, *locators = 0;
11872   u32 sw_if_index, priority, weight;
11873
11874   /* Parse args required to build the message */
11875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (input, "del"))
11878         {
11879           is_add = 0;
11880         }
11881       else if (unformat (input, "locator-set %s", &locator_set_name))
11882         {
11883           locator_set_name_set = 1;
11884         }
11885       else if (unformat (input, "sw_if_index %u p %u w %u",
11886                          &sw_if_index, &priority, &weight))
11887         {
11888           locator.sw_if_index = htonl (sw_if_index);
11889           locator.priority = priority;
11890           locator.weight = weight;
11891           vec_add1 (locators, locator);
11892         }
11893       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11894                          vam, &sw_if_index, &priority, &weight))
11895         {
11896           locator.sw_if_index = htonl (sw_if_index);
11897           locator.priority = priority;
11898           locator.weight = weight;
11899           vec_add1 (locators, locator);
11900         }
11901       else
11902         break;
11903     }
11904
11905   if (locator_set_name_set == 0)
11906     {
11907       errmsg ("missing locator-set name");
11908       vec_free (locators);
11909       return -99;
11910     }
11911
11912   if (vec_len (locator_set_name) > 64)
11913     {
11914       errmsg ("locator-set name too long\n");
11915       vec_free (locator_set_name);
11916       vec_free (locators);
11917       return -99;
11918     }
11919   vec_add1 (locator_set_name, 0);
11920
11921   /* Construct the API message */
11922   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11923
11924   mp->is_add = is_add;
11925   clib_memcpy (mp->locator_set_name, locator_set_name,
11926                vec_len (locator_set_name));
11927   vec_free (locator_set_name);
11928
11929   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11930   if (locators)
11931     clib_memcpy (mp->locators, locators,
11932                  (sizeof (ls_locator_t) * vec_len (locators)));
11933   vec_free (locators);
11934
11935   /* send it... */
11936   S;
11937
11938   /* Wait for a reply... */
11939   W;
11940
11941   /* NOTREACHED */
11942   return 0;
11943 }
11944
11945 static int
11946 api_lisp_add_del_locator (vat_main_t * vam)
11947 {
11948   unformat_input_t *input = vam->input;
11949   vl_api_lisp_add_del_locator_t *mp;
11950   f64 timeout = ~0;
11951   u32 tmp_if_index = ~0;
11952   u32 sw_if_index = ~0;
11953   u8 sw_if_index_set = 0;
11954   u8 sw_if_index_if_name_set = 0;
11955   u32 priority = ~0;
11956   u8 priority_set = 0;
11957   u32 weight = ~0;
11958   u8 weight_set = 0;
11959   u8 is_add = 1;
11960   u8 *locator_set_name = NULL;
11961   u8 locator_set_name_set = 0;
11962
11963   /* Parse args required to build the message */
11964   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11965     {
11966       if (unformat (input, "del"))
11967         {
11968           is_add = 0;
11969         }
11970       else if (unformat (input, "locator-set %s", &locator_set_name))
11971         {
11972           locator_set_name_set = 1;
11973         }
11974       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11975                          &tmp_if_index))
11976         {
11977           sw_if_index_if_name_set = 1;
11978           sw_if_index = tmp_if_index;
11979         }
11980       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11981         {
11982           sw_if_index_set = 1;
11983           sw_if_index = tmp_if_index;
11984         }
11985       else if (unformat (input, "p %d", &priority))
11986         {
11987           priority_set = 1;
11988         }
11989       else if (unformat (input, "w %d", &weight))
11990         {
11991           weight_set = 1;
11992         }
11993       else
11994         break;
11995     }
11996
11997   if (locator_set_name_set == 0)
11998     {
11999       errmsg ("missing locator-set name");
12000       return -99;
12001     }
12002
12003   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12004     {
12005       errmsg ("missing sw_if_index");
12006       vec_free (locator_set_name);
12007       return -99;
12008     }
12009
12010   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12011     {
12012       errmsg ("cannot use both params interface name and sw_if_index");
12013       vec_free (locator_set_name);
12014       return -99;
12015     }
12016
12017   if (priority_set == 0)
12018     {
12019       errmsg ("missing locator-set priority\n");
12020       vec_free (locator_set_name);
12021       return -99;
12022     }
12023
12024   if (weight_set == 0)
12025     {
12026       errmsg ("missing locator-set weight\n");
12027       vec_free (locator_set_name);
12028       return -99;
12029     }
12030
12031   if (vec_len (locator_set_name) > 64)
12032     {
12033       errmsg ("locator-set name too long\n");
12034       vec_free (locator_set_name);
12035       return -99;
12036     }
12037   vec_add1 (locator_set_name, 0);
12038
12039   /* Construct the API message */
12040   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12041
12042   mp->is_add = is_add;
12043   mp->sw_if_index = ntohl (sw_if_index);
12044   mp->priority = priority;
12045   mp->weight = weight;
12046   clib_memcpy (mp->locator_set_name, locator_set_name,
12047                vec_len (locator_set_name));
12048   vec_free (locator_set_name);
12049
12050   /* send it... */
12051   S;
12052
12053   /* Wait for a reply... */
12054   W;
12055
12056   /* NOTREACHED */
12057   return 0;
12058 }
12059
12060 static int
12061 api_lisp_add_del_local_eid (vat_main_t * vam)
12062 {
12063   unformat_input_t *input = vam->input;
12064   vl_api_lisp_add_del_local_eid_t *mp;
12065   f64 timeout = ~0;
12066   u8 is_add = 1;
12067   u8 eid_set = 0;
12068   lisp_eid_vat_t _eid, *eid = &_eid;
12069   u8 *locator_set_name = 0;
12070   u8 locator_set_name_set = 0;
12071   u32 vni = 0;
12072
12073   /* Parse args required to build the message */
12074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12075     {
12076       if (unformat (input, "del"))
12077         {
12078           is_add = 0;
12079         }
12080       else if (unformat (input, "vni %d", &vni))
12081         {
12082           ;
12083         }
12084       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12085         {
12086           eid_set = 1;
12087         }
12088       else if (unformat (input, "locator-set %s", &locator_set_name))
12089         {
12090           locator_set_name_set = 1;
12091         }
12092       else
12093         break;
12094     }
12095
12096   if (locator_set_name_set == 0)
12097     {
12098       errmsg ("missing locator-set name\n");
12099       return -99;
12100     }
12101
12102   if (0 == eid_set)
12103     {
12104       errmsg ("EID address not set!");
12105       vec_free (locator_set_name);
12106       return -99;
12107     }
12108
12109   if (vec_len (locator_set_name) > 64)
12110     {
12111       errmsg ("locator-set name too long\n");
12112       vec_free (locator_set_name);
12113       return -99;
12114     }
12115   vec_add1 (locator_set_name, 0);
12116
12117   /* Construct the API message */
12118   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12119
12120   mp->is_add = is_add;
12121   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12122   mp->eid_type = eid->type;
12123   mp->prefix_len = eid->len;
12124   mp->vni = clib_host_to_net_u32 (vni);
12125   clib_memcpy (mp->locator_set_name, locator_set_name,
12126                vec_len (locator_set_name));
12127
12128   vec_free (locator_set_name);
12129
12130   /* send it... */
12131   S;
12132
12133   /* Wait for a reply... */
12134   W;
12135
12136   /* NOTREACHED */
12137   return 0;
12138 }
12139
12140 /* *INDENT-OFF* */
12141 /** Used for transferring locators via VPP API */
12142 typedef CLIB_PACKED(struct
12143 {
12144   u8 is_ip4; /**< is locator an IPv4 address? */
12145   u8 priority; /**< locator priority */
12146   u8 weight;   /**< locator weight */
12147   u8 addr[16]; /**< IPv4/IPv6 address */
12148 }) rloc_t;
12149 /* *INDENT-ON* */
12150
12151 static int
12152 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12153 {
12154   unformat_input_t *input = vam->input;
12155   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12156   f64 timeout = ~0;
12157   u8 is_add = 1;
12158   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12159   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12160   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12161   u32 action = ~0, p, w;
12162   ip4_address_t rmt_rloc4, lcl_rloc4;
12163   ip6_address_t rmt_rloc6, lcl_rloc6;
12164   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12165
12166   memset (&rloc, 0, sizeof (rloc));
12167
12168   /* Parse args required to build the message */
12169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12170     {
12171       if (unformat (input, "del"))
12172         {
12173           is_add = 0;
12174         }
12175       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12176         {
12177           rmt_eid_set = 1;
12178         }
12179       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12180         {
12181           lcl_eid_set = 1;
12182         }
12183       else if (unformat (input, "p %d w %d", &p, &w))
12184         {
12185           if (!curr_rloc)
12186             {
12187               errmsg ("No RLOC configured for setting priority/weight!");
12188               return -99;
12189             }
12190           curr_rloc->priority = p;
12191           curr_rloc->weight = w;
12192         }
12193       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12194                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12195         {
12196           rloc.is_ip4 = 1;
12197
12198           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12199           rloc.priority = rloc.weight = 0;
12200           vec_add1 (lcl_locs, rloc);
12201
12202           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12203           vec_add1 (rmt_locs, rloc);
12204           /* priority and weight saved in rmt loc */
12205           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12206         }
12207       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12208                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12209         {
12210           rloc.is_ip4 = 0;
12211           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12212           rloc.priority = rloc.weight = 0;
12213           vec_add1 (lcl_locs, rloc);
12214
12215           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12216           vec_add1 (rmt_locs, rloc);
12217           /* priority and weight saved in rmt loc */
12218           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12219         }
12220       else if (unformat (input, "action %d", &action))
12221         {
12222           ;
12223         }
12224       else
12225         {
12226           clib_warning ("parse error '%U'", format_unformat_error, input);
12227           return -99;
12228         }
12229     }
12230
12231   if (!rmt_eid_set)
12232     {
12233       errmsg ("remote eid addresses not set\n");
12234       return -99;
12235     }
12236
12237   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12238     {
12239       errmsg ("eid types don't match\n");
12240       return -99;
12241     }
12242
12243   if (0 == rmt_locs && (u32) ~ 0 == action)
12244     {
12245       errmsg ("action not set for negative mapping\n");
12246       return -99;
12247     }
12248
12249   /* Construct the API message */
12250   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12251
12252   mp->is_add = is_add;
12253   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12254   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12255   mp->eid_type = rmt_eid->type;
12256   mp->rmt_len = rmt_eid->len;
12257   mp->lcl_len = lcl_eid->len;
12258   mp->action = action;
12259
12260   if (0 != rmt_locs && 0 != lcl_locs)
12261     {
12262       mp->loc_num = vec_len (rmt_locs);
12263       clib_memcpy (mp->lcl_locs, lcl_locs,
12264                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12265       clib_memcpy (mp->rmt_locs, rmt_locs,
12266                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12267     }
12268   vec_free (lcl_locs);
12269   vec_free (rmt_locs);
12270
12271   /* send it... */
12272   S;
12273
12274   /* Wait for a reply... */
12275   W;
12276
12277   /* NOTREACHED */
12278   return 0;
12279 }
12280
12281 static int
12282 api_lisp_add_del_map_resolver (vat_main_t * vam)
12283 {
12284   unformat_input_t *input = vam->input;
12285   vl_api_lisp_add_del_map_resolver_t *mp;
12286   f64 timeout = ~0;
12287   u8 is_add = 1;
12288   u8 ipv4_set = 0;
12289   u8 ipv6_set = 0;
12290   ip4_address_t ipv4;
12291   ip6_address_t ipv6;
12292
12293   /* Parse args required to build the message */
12294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12295     {
12296       if (unformat (input, "del"))
12297         {
12298           is_add = 0;
12299         }
12300       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12301         {
12302           ipv4_set = 1;
12303         }
12304       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12305         {
12306           ipv6_set = 1;
12307         }
12308       else
12309         break;
12310     }
12311
12312   if (ipv4_set && ipv6_set)
12313     {
12314       errmsg ("both eid v4 and v6 addresses set\n");
12315       return -99;
12316     }
12317
12318   if (!ipv4_set && !ipv6_set)
12319     {
12320       errmsg ("eid addresses not set\n");
12321       return -99;
12322     }
12323
12324   /* Construct the API message */
12325   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12326
12327   mp->is_add = is_add;
12328   if (ipv6_set)
12329     {
12330       mp->is_ipv6 = 1;
12331       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12332     }
12333   else
12334     {
12335       mp->is_ipv6 = 0;
12336       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12337     }
12338
12339   /* send it... */
12340   S;
12341
12342   /* Wait for a reply... */
12343   W;
12344
12345   /* NOTREACHED */
12346   return 0;
12347 }
12348
12349 static int
12350 api_lisp_gpe_enable_disable (vat_main_t * vam)
12351 {
12352   unformat_input_t *input = vam->input;
12353   vl_api_lisp_gpe_enable_disable_t *mp;
12354   f64 timeout = ~0;
12355   u8 is_set = 0;
12356   u8 is_en = 1;
12357
12358   /* Parse args required to build the message */
12359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12360     {
12361       if (unformat (input, "enable"))
12362         {
12363           is_set = 1;
12364           is_en = 1;
12365         }
12366       else if (unformat (input, "disable"))
12367         {
12368           is_set = 1;
12369           is_en = 0;
12370         }
12371       else
12372         break;
12373     }
12374
12375   if (is_set == 0)
12376     {
12377       errmsg ("Value not set\n");
12378       return -99;
12379     }
12380
12381   /* Construct the API message */
12382   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12383
12384   mp->is_en = is_en;
12385
12386   /* send it... */
12387   S;
12388
12389   /* Wait for a reply... */
12390   W;
12391
12392   /* NOTREACHED */
12393   return 0;
12394 }
12395
12396 static int
12397 api_lisp_enable_disable (vat_main_t * vam)
12398 {
12399   unformat_input_t *input = vam->input;
12400   vl_api_lisp_enable_disable_t *mp;
12401   f64 timeout = ~0;
12402   u8 is_set = 0;
12403   u8 is_en = 0;
12404
12405   /* Parse args required to build the message */
12406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12407     {
12408       if (unformat (input, "enable"))
12409         {
12410           is_set = 1;
12411           is_en = 1;
12412         }
12413       else if (unformat (input, "disable"))
12414         {
12415           is_set = 1;
12416         }
12417       else
12418         break;
12419     }
12420
12421   if (!is_set)
12422     {
12423       errmsg ("Value not set\n");
12424       return -99;
12425     }
12426
12427   /* Construct the API message */
12428   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12429
12430   mp->is_en = is_en;
12431
12432   /* send it... */
12433   S;
12434
12435   /* Wait for a reply... */
12436   W;
12437
12438   /* NOTREACHED */
12439   return 0;
12440 }
12441
12442 static int
12443 api_show_lisp_map_request_mode (vat_main_t * vam)
12444 {
12445   f64 timeout = ~0;
12446   vl_api_show_lisp_map_request_mode_t *mp;
12447
12448   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12449
12450   /* send */
12451   S;
12452
12453   /* wait for reply */
12454   W;
12455
12456   return 0;
12457 }
12458
12459 static int
12460 api_lisp_map_request_mode (vat_main_t * vam)
12461 {
12462   f64 timeout = ~0;
12463   unformat_input_t *input = vam->input;
12464   vl_api_lisp_map_request_mode_t *mp;
12465   u8 mode = 0;
12466
12467   /* Parse args required to build the message */
12468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (input, "dst-only"))
12471         mode = 0;
12472       else if (unformat (input, "src-dst"))
12473         mode = 1;
12474       else
12475         {
12476           errmsg ("parse error '%U'", format_unformat_error, input);
12477           return -99;
12478         }
12479     }
12480
12481   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12482
12483   mp->mode = mode;
12484
12485   /* send */
12486   S;
12487
12488   /* wait for reply */
12489   W;
12490
12491   /* notreached */
12492   return 0;
12493 }
12494
12495 /**
12496  * Enable/disable LISP proxy ITR.
12497  *
12498  * @param vam vpp API test context
12499  * @return return code
12500  */
12501 static int
12502 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12503 {
12504   f64 timeout = ~0;
12505   u8 ls_name_set = 0;
12506   unformat_input_t *input = vam->input;
12507   vl_api_lisp_pitr_set_locator_set_t *mp;
12508   u8 is_add = 1;
12509   u8 *ls_name = 0;
12510
12511   /* Parse args required to build the message */
12512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12513     {
12514       if (unformat (input, "del"))
12515         is_add = 0;
12516       else if (unformat (input, "locator-set %s", &ls_name))
12517         ls_name_set = 1;
12518       else
12519         {
12520           errmsg ("parse error '%U'", format_unformat_error, input);
12521           return -99;
12522         }
12523     }
12524
12525   if (!ls_name_set)
12526     {
12527       errmsg ("locator-set name not set!");
12528       return -99;
12529     }
12530
12531   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12532
12533   mp->is_add = is_add;
12534   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12535   vec_free (ls_name);
12536
12537   /* send */
12538   S;
12539
12540   /* wait for reply */
12541   W;
12542
12543   /* notreached */
12544   return 0;
12545 }
12546
12547 static int
12548 api_show_lisp_pitr (vat_main_t * vam)
12549 {
12550   vl_api_show_lisp_pitr_t *mp;
12551   f64 timeout = ~0;
12552
12553   if (!vam->json_output)
12554     {
12555       fformat (vam->ofp, "%=20s\n", "lisp status:");
12556     }
12557
12558   M (SHOW_LISP_PITR, show_lisp_pitr);
12559   /* send it... */
12560   S;
12561
12562   /* Wait for a reply... */
12563   W;
12564
12565   /* NOTREACHED */
12566   return 0;
12567 }
12568
12569 /**
12570  * Add/delete mapping between vni and vrf
12571  */
12572 static int
12573 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12574 {
12575   f64 timeout = ~0;
12576   unformat_input_t *input = vam->input;
12577   vl_api_lisp_eid_table_add_del_map_t *mp;
12578   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12579   u32 vni, vrf, bd_index;
12580
12581   /* Parse args required to build the message */
12582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12583     {
12584       if (unformat (input, "del"))
12585         is_add = 0;
12586       else if (unformat (input, "vrf %d", &vrf))
12587         vrf_set = 1;
12588       else if (unformat (input, "bd_index %d", &bd_index))
12589         bd_index_set = 1;
12590       else if (unformat (input, "vni %d", &vni))
12591         vni_set = 1;
12592       else
12593         break;
12594     }
12595
12596   if (!vni_set || (!vrf_set && !bd_index_set))
12597     {
12598       errmsg ("missing arguments!");
12599       return -99;
12600     }
12601
12602   if (vrf_set && bd_index_set)
12603     {
12604       errmsg ("error: both vrf and bd entered!");
12605       return -99;
12606     }
12607
12608   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12609
12610   mp->is_add = is_add;
12611   mp->vni = htonl (vni);
12612   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12613   mp->is_l2 = bd_index_set;
12614
12615   /* send */
12616   S;
12617
12618   /* wait for reply */
12619   W;
12620
12621   /* notreached */
12622   return 0;
12623 }
12624
12625 uword
12626 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12627 {
12628   u32 *action = va_arg (*args, u32 *);
12629   u8 *s = 0;
12630
12631   if (unformat (input, "%s", &s))
12632     {
12633       if (!strcmp ((char *) s, "no-action"))
12634         action[0] = 0;
12635       else if (!strcmp ((char *) s, "natively-forward"))
12636         action[0] = 1;
12637       else if (!strcmp ((char *) s, "send-map-request"))
12638         action[0] = 2;
12639       else if (!strcmp ((char *) s, "drop"))
12640         action[0] = 3;
12641       else
12642         {
12643           clib_warning ("invalid action: '%s'", s);
12644           action[0] = 3;
12645         }
12646     }
12647   else
12648     return 0;
12649
12650   vec_free (s);
12651   return 1;
12652 }
12653
12654 /**
12655  * Add/del remote mapping to/from LISP control plane
12656  *
12657  * @param vam vpp API test context
12658  * @return return code
12659  */
12660 static int
12661 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12662 {
12663   unformat_input_t *input = vam->input;
12664   vl_api_lisp_add_del_remote_mapping_t *mp;
12665   f64 timeout = ~0;
12666   u32 vni = 0;
12667   lisp_eid_vat_t _eid, *eid = &_eid;
12668   lisp_eid_vat_t _seid, *seid = &_seid;
12669   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12670   u32 action = ~0, p, w;
12671   ip4_address_t rloc4;
12672   ip6_address_t rloc6;
12673   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12674
12675   memset (&rloc, 0, sizeof (rloc));
12676
12677   /* Parse args required to build the message */
12678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12679     {
12680       if (unformat (input, "del-all"))
12681         {
12682           del_all = 1;
12683         }
12684       else if (unformat (input, "del"))
12685         {
12686           is_add = 0;
12687         }
12688       else if (unformat (input, "add"))
12689         {
12690           is_add = 1;
12691         }
12692       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12693         {
12694           eid_set = 1;
12695         }
12696       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12697         {
12698           seid_set = 1;
12699         }
12700       else if (unformat (input, "vni %d", &vni))
12701         {
12702           ;
12703         }
12704       else if (unformat (input, "p %d w %d", &p, &w))
12705         {
12706           if (!curr_rloc)
12707             {
12708               errmsg ("No RLOC configured for setting priority/weight!");
12709               return -99;
12710             }
12711           curr_rloc->priority = p;
12712           curr_rloc->weight = w;
12713         }
12714       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12715         {
12716           rloc.is_ip4 = 1;
12717           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12718           vec_add1 (rlocs, rloc);
12719           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12720         }
12721       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12722         {
12723           rloc.is_ip4 = 0;
12724           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12725           vec_add1 (rlocs, rloc);
12726           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12727         }
12728       else if (unformat (input, "action %U",
12729                          unformat_negative_mapping_action, &action))
12730         {
12731           ;
12732         }
12733       else
12734         {
12735           clib_warning ("parse error '%U'", format_unformat_error, input);
12736           return -99;
12737         }
12738     }
12739
12740   if (0 == eid_set)
12741     {
12742       errmsg ("missing params!");
12743       return -99;
12744     }
12745
12746   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12747     {
12748       errmsg ("no action set for negative map-reply!");
12749       return -99;
12750     }
12751
12752   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12753   mp->is_add = is_add;
12754   mp->vni = htonl (vni);
12755   mp->action = (u8) action;
12756   mp->is_src_dst = seid_set;
12757   mp->eid_len = eid->len;
12758   mp->seid_len = seid->len;
12759   mp->del_all = del_all;
12760   mp->eid_type = eid->type;
12761   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12762   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
12763
12764   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12765   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12766   vec_free (rlocs);
12767
12768   /* send it... */
12769   S;
12770
12771   /* Wait for a reply... */
12772   W;
12773
12774   /* NOTREACHED */
12775   return 0;
12776 }
12777
12778 /**
12779  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12780  * forwarding entries in data-plane accordingly.
12781  *
12782  * @param vam vpp API test context
12783  * @return return code
12784  */
12785 static int
12786 api_lisp_add_del_adjacency (vat_main_t * vam)
12787 {
12788   unformat_input_t *input = vam->input;
12789   vl_api_lisp_add_del_adjacency_t *mp;
12790   f64 timeout = ~0;
12791   u32 vni = 0;
12792   ip4_address_t seid4, deid4;
12793   ip6_address_t seid6, deid6;
12794   u8 deid_mac[6] = { 0 };
12795   u8 seid_mac[6] = { 0 };
12796   u8 deid_type, seid_type;
12797   u32 seid_len = 0, deid_len = 0, len;
12798   u8 is_add = 1;
12799
12800   seid_type = deid_type = (u8) ~ 0;
12801
12802   /* Parse args required to build the message */
12803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12804     {
12805       if (unformat (input, "del"))
12806         {
12807           is_add = 0;
12808         }
12809       else if (unformat (input, "add"))
12810         {
12811           is_add = 1;
12812         }
12813       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12814                          &deid4, &len))
12815         {
12816           deid_type = 0;        /* ipv4 */
12817           deid_len = len;
12818         }
12819       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12820                          &deid6, &len))
12821         {
12822           deid_type = 1;        /* ipv6 */
12823           deid_len = len;
12824         }
12825       else if (unformat (input, "deid %U", unformat_ethernet_address,
12826                          deid_mac))
12827         {
12828           deid_type = 2;        /* mac */
12829         }
12830       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12831                          &seid4, &len))
12832         {
12833           seid_type = 0;        /* ipv4 */
12834           seid_len = len;
12835         }
12836       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12837                          &seid6, &len))
12838         {
12839           seid_type = 1;        /* ipv6 */
12840           seid_len = len;
12841         }
12842       else if (unformat (input, "seid %U", unformat_ethernet_address,
12843                          seid_mac))
12844         {
12845           seid_type = 2;        /* mac */
12846         }
12847       else if (unformat (input, "vni %d", &vni))
12848         {
12849           ;
12850         }
12851       else
12852         {
12853           errmsg ("parse error '%U'", format_unformat_error, input);
12854           return -99;
12855         }
12856     }
12857
12858   if ((u8) ~ 0 == deid_type)
12859     {
12860       errmsg ("missing params!");
12861       return -99;
12862     }
12863
12864   if (seid_type != deid_type)
12865     {
12866       errmsg ("source and destination EIDs are of different types!");
12867       return -99;
12868     }
12869
12870   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12871   mp->is_add = is_add;
12872   mp->vni = htonl (vni);
12873   mp->seid_len = seid_len;
12874   mp->deid_len = deid_len;
12875   mp->eid_type = deid_type;
12876
12877   switch (mp->eid_type)
12878     {
12879     case 0:
12880       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12881       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12882       break;
12883     case 1:
12884       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12885       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12886       break;
12887     case 2:
12888       clib_memcpy (mp->seid, seid_mac, 6);
12889       clib_memcpy (mp->deid, deid_mac, 6);
12890       break;
12891     default:
12892       errmsg ("unknown EID type %d!", mp->eid_type);
12893       return 0;
12894     }
12895
12896   /* send it... */
12897   S;
12898
12899   /* Wait for a reply... */
12900   W;
12901
12902   /* NOTREACHED */
12903   return 0;
12904 }
12905
12906 static int
12907 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12908 {
12909   unformat_input_t *input = vam->input;
12910   vl_api_lisp_gpe_add_del_iface_t *mp;
12911   f64 timeout = ~0;
12912   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12913   u32 dp_table = 0, vni = 0;
12914
12915   /* Parse args required to build the message */
12916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12917     {
12918       if (unformat (input, "up"))
12919         {
12920           action_set = 1;
12921           is_add = 1;
12922         }
12923       else if (unformat (input, "down"))
12924         {
12925           action_set = 1;
12926           is_add = 0;
12927         }
12928       else if (unformat (input, "table_id %d", &dp_table))
12929         {
12930           dp_table_set = 1;
12931         }
12932       else if (unformat (input, "bd_id %d", &dp_table))
12933         {
12934           dp_table_set = 1;
12935           is_l2 = 1;
12936         }
12937       else if (unformat (input, "vni %d", &vni))
12938         {
12939           vni_set = 1;
12940         }
12941       else
12942         break;
12943     }
12944
12945   if (action_set == 0)
12946     {
12947       errmsg ("Action not set\n");
12948       return -99;
12949     }
12950   if (dp_table_set == 0 || vni_set == 0)
12951     {
12952       errmsg ("vni and dp_table must be set\n");
12953       return -99;
12954     }
12955
12956   /* Construct the API message */
12957   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12958
12959   mp->is_add = is_add;
12960   mp->dp_table = dp_table;
12961   mp->is_l2 = is_l2;
12962   mp->vni = vni;
12963
12964   /* send it... */
12965   S;
12966
12967   /* Wait for a reply... */
12968   W;
12969
12970   /* NOTREACHED */
12971   return 0;
12972 }
12973
12974 /**
12975  * Add/del map request itr rlocs from LISP control plane and updates
12976  *
12977  * @param vam vpp API test context
12978  * @return return code
12979  */
12980 static int
12981 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12982 {
12983   unformat_input_t *input = vam->input;
12984   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12985   f64 timeout = ~0;
12986   u8 *locator_set_name = 0;
12987   u8 locator_set_name_set = 0;
12988   u8 is_add = 1;
12989
12990   /* Parse args required to build the message */
12991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12992     {
12993       if (unformat (input, "del"))
12994         {
12995           is_add = 0;
12996         }
12997       else if (unformat (input, "%_%v%_", &locator_set_name))
12998         {
12999           locator_set_name_set = 1;
13000         }
13001       else
13002         {
13003           clib_warning ("parse error '%U'", format_unformat_error, input);
13004           return -99;
13005         }
13006     }
13007
13008   if (is_add && !locator_set_name_set)
13009     {
13010       errmsg ("itr-rloc is not set!");
13011       return -99;
13012     }
13013
13014   if (is_add && vec_len (locator_set_name) > 64)
13015     {
13016       errmsg ("itr-rloc locator-set name too long\n");
13017       vec_free (locator_set_name);
13018       return -99;
13019     }
13020
13021   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13022   mp->is_add = is_add;
13023   if (is_add)
13024     {
13025       clib_memcpy (mp->locator_set_name, locator_set_name,
13026                    vec_len (locator_set_name));
13027     }
13028   else
13029     {
13030       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13031     }
13032   vec_free (locator_set_name);
13033
13034   /* send it... */
13035   S;
13036
13037   /* Wait for a reply... */
13038   W;
13039
13040   /* NOTREACHED */
13041   return 0;
13042 }
13043
13044 static int
13045 api_lisp_locator_dump (vat_main_t * vam)
13046 {
13047   unformat_input_t *input = vam->input;
13048   vl_api_lisp_locator_dump_t *mp;
13049   f64 timeout = ~0;
13050   u8 is_index_set = 0, is_name_set = 0;
13051   u8 *ls_name = 0;
13052   u32 ls_index = ~0;
13053
13054   /* Parse args required to build the message */
13055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13056     {
13057       if (unformat (input, "ls_name %_%v%_", &ls_name))
13058         {
13059           is_name_set = 1;
13060         }
13061       else if (unformat (input, "ls_index %d", &ls_index))
13062         {
13063           is_index_set = 1;
13064         }
13065       else
13066         {
13067           errmsg ("parse error '%U'", format_unformat_error, input);
13068           return -99;
13069         }
13070     }
13071
13072   if (!is_index_set && !is_name_set)
13073     {
13074       errmsg ("error: expected one of index or name!\n");
13075       return -99;
13076     }
13077
13078   if (is_index_set && is_name_set)
13079     {
13080       errmsg ("error: only one param expected!\n");
13081       return -99;
13082     }
13083
13084   if (vec_len (ls_name) > 62)
13085     {
13086       errmsg ("error: locator set name too long!");
13087       return -99;
13088     }
13089
13090   if (!vam->json_output)
13091     {
13092       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13093                "weight");
13094     }
13095
13096   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13097   mp->is_index_set = is_index_set;
13098
13099   if (is_index_set)
13100     mp->ls_index = clib_host_to_net_u32 (ls_index);
13101   else
13102     {
13103       vec_add1 (ls_name, 0);
13104       strncpy ((char *) mp->ls_name, (char *) ls_name,
13105                sizeof (mp->ls_name) - 1);
13106     }
13107
13108   /* send it... */
13109   S;
13110
13111   /* Use a control ping for synchronization */
13112   {
13113     vl_api_control_ping_t *mp;
13114     M (CONTROL_PING, control_ping);
13115     S;
13116   }
13117   /* Wait for a reply... */
13118   W;
13119
13120   /* NOTREACHED */
13121   return 0;
13122 }
13123
13124 static int
13125 api_lisp_locator_set_dump (vat_main_t * vam)
13126 {
13127   vl_api_lisp_locator_set_dump_t *mp;
13128   unformat_input_t *input = vam->input;
13129   f64 timeout = ~0;
13130   u8 filter = 0;
13131
13132   /* Parse args required to build the message */
13133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat (input, "local"))
13136         {
13137           filter = 1;
13138         }
13139       else if (unformat (input, "remote"))
13140         {
13141           filter = 2;
13142         }
13143       else
13144         {
13145           errmsg ("parse error '%U'", format_unformat_error, input);
13146           return -99;
13147         }
13148     }
13149
13150   if (!vam->json_output)
13151     {
13152       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13153     }
13154
13155   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13156
13157   mp->filter = filter;
13158
13159   /* send it... */
13160   S;
13161
13162   /* Use a control ping for synchronization */
13163   {
13164     vl_api_control_ping_t *mp;
13165     M (CONTROL_PING, control_ping);
13166     S;
13167   }
13168   /* Wait for a reply... */
13169   W;
13170
13171   /* NOTREACHED */
13172   return 0;
13173 }
13174
13175 static int
13176 api_lisp_eid_table_map_dump (vat_main_t * vam)
13177 {
13178   u8 is_l2 = 0;
13179   u8 mode_set = 0;
13180   unformat_input_t *input = vam->input;
13181   vl_api_lisp_eid_table_map_dump_t *mp;
13182   f64 timeout = ~0;
13183
13184   /* Parse args required to build the message */
13185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13186     {
13187       if (unformat (input, "l2"))
13188         {
13189           is_l2 = 1;
13190           mode_set = 1;
13191         }
13192       else if (unformat (input, "l3"))
13193         {
13194           is_l2 = 0;
13195           mode_set = 1;
13196         }
13197       else
13198         {
13199           errmsg ("parse error '%U'", format_unformat_error, input);
13200           return -99;
13201         }
13202     }
13203
13204   if (!mode_set)
13205     {
13206       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13207       return -99;
13208     }
13209
13210   if (!vam->json_output)
13211     {
13212       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13213     }
13214
13215   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13216   mp->is_l2 = is_l2;
13217
13218   /* send it... */
13219   S;
13220
13221   /* Use a control ping for synchronization */
13222   {
13223     vl_api_control_ping_t *mp;
13224     M (CONTROL_PING, control_ping);
13225     S;
13226   }
13227   /* Wait for a reply... */
13228   W;
13229
13230   /* NOTREACHED */
13231   return 0;
13232 }
13233
13234 static int
13235 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13236 {
13237   vl_api_lisp_eid_table_vni_dump_t *mp;
13238   f64 timeout = ~0;
13239
13240   if (!vam->json_output)
13241     {
13242       fformat (vam->ofp, "VNI\n");
13243     }
13244
13245   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13246
13247   /* send it... */
13248   S;
13249
13250   /* Use a control ping for synchronization */
13251   {
13252     vl_api_control_ping_t *mp;
13253     M (CONTROL_PING, control_ping);
13254     S;
13255   }
13256   /* Wait for a reply... */
13257   W;
13258
13259   /* NOTREACHED */
13260   return 0;
13261 }
13262
13263 static int
13264 api_lisp_eid_table_dump (vat_main_t * vam)
13265 {
13266   unformat_input_t *i = vam->input;
13267   vl_api_lisp_eid_table_dump_t *mp;
13268   f64 timeout = ~0;
13269   struct in_addr ip4;
13270   struct in6_addr ip6;
13271   u8 mac[6];
13272   u8 eid_type = ~0, eid_set = 0;
13273   u32 prefix_length = ~0, t, vni = 0;
13274   u8 filter = 0;
13275
13276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13279         {
13280           eid_set = 1;
13281           eid_type = 0;
13282           prefix_length = t;
13283         }
13284       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13285         {
13286           eid_set = 1;
13287           eid_type = 1;
13288           prefix_length = t;
13289         }
13290       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13291         {
13292           eid_set = 1;
13293           eid_type = 2;
13294         }
13295       else if (unformat (i, "vni %d", &t))
13296         {
13297           vni = t;
13298         }
13299       else if (unformat (i, "local"))
13300         {
13301           filter = 1;
13302         }
13303       else if (unformat (i, "remote"))
13304         {
13305           filter = 2;
13306         }
13307       else
13308         {
13309           errmsg ("parse error '%U'", format_unformat_error, i);
13310           return -99;
13311         }
13312     }
13313
13314   if (!vam->json_output)
13315     {
13316       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13317                "ls_index", "ttl", "authoritative");
13318     }
13319
13320   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13321
13322   mp->filter = filter;
13323   if (eid_set)
13324     {
13325       mp->eid_set = 1;
13326       mp->vni = htonl (vni);
13327       mp->eid_type = eid_type;
13328       switch (eid_type)
13329         {
13330         case 0:
13331           mp->prefix_length = prefix_length;
13332           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13333           break;
13334         case 1:
13335           mp->prefix_length = prefix_length;
13336           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13337           break;
13338         case 2:
13339           clib_memcpy (mp->eid, mac, sizeof (mac));
13340           break;
13341         default:
13342           errmsg ("unknown EID type %d!", eid_type);
13343           return -99;
13344         }
13345     }
13346
13347   /* send it... */
13348   S;
13349
13350   /* Use a control ping for synchronization */
13351   {
13352     vl_api_control_ping_t *mp;
13353     M (CONTROL_PING, control_ping);
13354     S;
13355   }
13356
13357   /* Wait for a reply... */
13358   W;
13359
13360   /* NOTREACHED */
13361   return 0;
13362 }
13363
13364 static int
13365 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13366 {
13367   vl_api_lisp_gpe_tunnel_dump_t *mp;
13368   f64 timeout = ~0;
13369
13370   if (!vam->json_output)
13371     {
13372       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13373                "%=16s%=16s%=16s%=16s%=16s\n",
13374                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13375                "Decap next", "Lisp version", "Flags", "Next protocol",
13376                "ver_res", "res", "iid");
13377     }
13378
13379   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13380   /* send it... */
13381   S;
13382
13383   /* Use a control ping for synchronization */
13384   {
13385     vl_api_control_ping_t *mp;
13386     M (CONTROL_PING, control_ping);
13387     S;
13388   }
13389   /* Wait for a reply... */
13390   W;
13391
13392   /* NOTREACHED */
13393   return 0;
13394 }
13395
13396 static int
13397 api_lisp_map_resolver_dump (vat_main_t * vam)
13398 {
13399   vl_api_lisp_map_resolver_dump_t *mp;
13400   f64 timeout = ~0;
13401
13402   if (!vam->json_output)
13403     {
13404       fformat (vam->ofp, "%=20s\n", "Map resolver");
13405     }
13406
13407   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13408   /* send it... */
13409   S;
13410
13411   /* Use a control ping for synchronization */
13412   {
13413     vl_api_control_ping_t *mp;
13414     M (CONTROL_PING, control_ping);
13415     S;
13416   }
13417   /* Wait for a reply... */
13418   W;
13419
13420   /* NOTREACHED */
13421   return 0;
13422 }
13423
13424 static int
13425 api_show_lisp_status (vat_main_t * vam)
13426 {
13427   vl_api_show_lisp_status_t *mp;
13428   f64 timeout = ~0;
13429
13430   if (!vam->json_output)
13431     {
13432       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13433     }
13434
13435   M (SHOW_LISP_STATUS, show_lisp_status);
13436   /* send it... */
13437   S;
13438   /* Wait for a reply... */
13439   W;
13440
13441   /* NOTREACHED */
13442   return 0;
13443 }
13444
13445 static int
13446 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13447 {
13448   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13449   f64 timeout = ~0;
13450
13451   if (!vam->json_output)
13452     {
13453       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13454     }
13455
13456   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13457   /* send it... */
13458   S;
13459   /* Wait for a reply... */
13460   W;
13461
13462   /* NOTREACHED */
13463   return 0;
13464 }
13465
13466 static int
13467 api_af_packet_create (vat_main_t * vam)
13468 {
13469   unformat_input_t *i = vam->input;
13470   vl_api_af_packet_create_t *mp;
13471   f64 timeout;
13472   u8 *host_if_name = 0;
13473   u8 hw_addr[6];
13474   u8 random_hw_addr = 1;
13475
13476   memset (hw_addr, 0, sizeof (hw_addr));
13477
13478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13479     {
13480       if (unformat (i, "name %s", &host_if_name))
13481         vec_add1 (host_if_name, 0);
13482       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13483         random_hw_addr = 0;
13484       else
13485         break;
13486     }
13487
13488   if (!vec_len (host_if_name))
13489     {
13490       errmsg ("host-interface name must be specified");
13491       return -99;
13492     }
13493
13494   if (vec_len (host_if_name) > 64)
13495     {
13496       errmsg ("host-interface name too long");
13497       return -99;
13498     }
13499
13500   M (AF_PACKET_CREATE, af_packet_create);
13501
13502   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13503   clib_memcpy (mp->hw_addr, hw_addr, 6);
13504   mp->use_random_hw_addr = random_hw_addr;
13505   vec_free (host_if_name);
13506
13507   S;
13508   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13509   /* NOTREACHED */
13510   return 0;
13511 }
13512
13513 static int
13514 api_af_packet_delete (vat_main_t * vam)
13515 {
13516   unformat_input_t *i = vam->input;
13517   vl_api_af_packet_delete_t *mp;
13518   f64 timeout;
13519   u8 *host_if_name = 0;
13520
13521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13522     {
13523       if (unformat (i, "name %s", &host_if_name))
13524         vec_add1 (host_if_name, 0);
13525       else
13526         break;
13527     }
13528
13529   if (!vec_len (host_if_name))
13530     {
13531       errmsg ("host-interface name must be specified");
13532       return -99;
13533     }
13534
13535   if (vec_len (host_if_name) > 64)
13536     {
13537       errmsg ("host-interface name too long");
13538       return -99;
13539     }
13540
13541   M (AF_PACKET_DELETE, af_packet_delete);
13542
13543   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13544   vec_free (host_if_name);
13545
13546   S;
13547   W;
13548   /* NOTREACHED */
13549   return 0;
13550 }
13551
13552 static int
13553 api_policer_add_del (vat_main_t * vam)
13554 {
13555   unformat_input_t *i = vam->input;
13556   vl_api_policer_add_del_t *mp;
13557   f64 timeout;
13558   u8 is_add = 1;
13559   u8 *name = 0;
13560   u32 cir = 0;
13561   u32 eir = 0;
13562   u64 cb = 0;
13563   u64 eb = 0;
13564   u8 rate_type = 0;
13565   u8 round_type = 0;
13566   u8 type = 0;
13567   u8 color_aware = 0;
13568   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13569
13570   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13571   conform_action.dscp = 0;
13572   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13573   exceed_action.dscp = 0;
13574   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13575   violate_action.dscp = 0;
13576
13577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13578     {
13579       if (unformat (i, "del"))
13580         is_add = 0;
13581       else if (unformat (i, "name %s", &name))
13582         vec_add1 (name, 0);
13583       else if (unformat (i, "cir %u", &cir))
13584         ;
13585       else if (unformat (i, "eir %u", &eir))
13586         ;
13587       else if (unformat (i, "cb %u", &cb))
13588         ;
13589       else if (unformat (i, "eb %u", &eb))
13590         ;
13591       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13592                          &rate_type))
13593         ;
13594       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13595                          &round_type))
13596         ;
13597       else if (unformat (i, "type %U", unformat_policer_type, &type))
13598         ;
13599       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13600                          &conform_action))
13601         ;
13602       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13603                          &exceed_action))
13604         ;
13605       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13606                          &violate_action))
13607         ;
13608       else if (unformat (i, "color-aware"))
13609         color_aware = 1;
13610       else
13611         break;
13612     }
13613
13614   if (!vec_len (name))
13615     {
13616       errmsg ("policer name must be specified");
13617       return -99;
13618     }
13619
13620   if (vec_len (name) > 64)
13621     {
13622       errmsg ("policer name too long");
13623       return -99;
13624     }
13625
13626   M (POLICER_ADD_DEL, policer_add_del);
13627
13628   clib_memcpy (mp->name, name, vec_len (name));
13629   vec_free (name);
13630   mp->is_add = is_add;
13631   mp->cir = cir;
13632   mp->eir = eir;
13633   mp->cb = cb;
13634   mp->eb = eb;
13635   mp->rate_type = rate_type;
13636   mp->round_type = round_type;
13637   mp->type = type;
13638   mp->conform_action_type = conform_action.action_type;
13639   mp->conform_dscp = conform_action.dscp;
13640   mp->exceed_action_type = exceed_action.action_type;
13641   mp->exceed_dscp = exceed_action.dscp;
13642   mp->violate_action_type = violate_action.action_type;
13643   mp->violate_dscp = violate_action.dscp;
13644   mp->color_aware = color_aware;
13645
13646   S;
13647   W;
13648   /* NOTREACHED */
13649   return 0;
13650 }
13651
13652 static int
13653 api_policer_dump (vat_main_t * vam)
13654 {
13655   unformat_input_t *i = vam->input;
13656   vl_api_policer_dump_t *mp;
13657   f64 timeout = ~0;
13658   u8 *match_name = 0;
13659   u8 match_name_valid = 0;
13660
13661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13662     {
13663       if (unformat (i, "name %s", &match_name))
13664         {
13665           vec_add1 (match_name, 0);
13666           match_name_valid = 1;
13667         }
13668       else
13669         break;
13670     }
13671
13672   M (POLICER_DUMP, policer_dump);
13673   mp->match_name_valid = match_name_valid;
13674   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13675   vec_free (match_name);
13676   /* send it... */
13677   S;
13678
13679   /* Use a control ping for synchronization */
13680   {
13681     vl_api_control_ping_t *mp;
13682     M (CONTROL_PING, control_ping);
13683     S;
13684   }
13685   /* Wait for a reply... */
13686   W;
13687
13688   /* NOTREACHED */
13689   return 0;
13690 }
13691
13692 static int
13693 api_policer_classify_set_interface (vat_main_t * vam)
13694 {
13695   unformat_input_t *i = vam->input;
13696   vl_api_policer_classify_set_interface_t *mp;
13697   f64 timeout;
13698   u32 sw_if_index;
13699   int sw_if_index_set;
13700   u32 ip4_table_index = ~0;
13701   u32 ip6_table_index = ~0;
13702   u32 l2_table_index = ~0;
13703   u8 is_add = 1;
13704
13705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13706     {
13707       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13708         sw_if_index_set = 1;
13709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13710         sw_if_index_set = 1;
13711       else if (unformat (i, "del"))
13712         is_add = 0;
13713       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13714         ;
13715       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13716         ;
13717       else if (unformat (i, "l2-table %d", &l2_table_index))
13718         ;
13719       else
13720         {
13721           clib_warning ("parse error '%U'", format_unformat_error, i);
13722           return -99;
13723         }
13724     }
13725
13726   if (sw_if_index_set == 0)
13727     {
13728       errmsg ("missing interface name or sw_if_index\n");
13729       return -99;
13730     }
13731
13732   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13733
13734   mp->sw_if_index = ntohl (sw_if_index);
13735   mp->ip4_table_index = ntohl (ip4_table_index);
13736   mp->ip6_table_index = ntohl (ip6_table_index);
13737   mp->l2_table_index = ntohl (l2_table_index);
13738   mp->is_add = is_add;
13739
13740   S;
13741   W;
13742   /* NOTREACHED */
13743   return 0;
13744 }
13745
13746 static int
13747 api_policer_classify_dump (vat_main_t * vam)
13748 {
13749   unformat_input_t *i = vam->input;
13750   vl_api_policer_classify_dump_t *mp;
13751   f64 timeout = ~0;
13752   u8 type = POLICER_CLASSIFY_N_TABLES;
13753
13754   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13755     ;
13756   else
13757     {
13758       errmsg ("classify table type must be specified\n");
13759       return -99;
13760     }
13761
13762   if (!vam->json_output)
13763     {
13764       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13765     }
13766
13767   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
13768   mp->type = type;
13769   /* send it... */
13770   S;
13771
13772   /* Use a control ping for synchronization */
13773   {
13774     vl_api_control_ping_t *mp;
13775     M (CONTROL_PING, control_ping);
13776     S;
13777   }
13778   /* Wait for a reply... */
13779   W;
13780
13781   /* NOTREACHED */
13782   return 0;
13783 }
13784
13785 static int
13786 api_netmap_create (vat_main_t * vam)
13787 {
13788   unformat_input_t *i = vam->input;
13789   vl_api_netmap_create_t *mp;
13790   f64 timeout;
13791   u8 *if_name = 0;
13792   u8 hw_addr[6];
13793   u8 random_hw_addr = 1;
13794   u8 is_pipe = 0;
13795   u8 is_master = 0;
13796
13797   memset (hw_addr, 0, sizeof (hw_addr));
13798
13799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (i, "name %s", &if_name))
13802         vec_add1 (if_name, 0);
13803       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13804         random_hw_addr = 0;
13805       else if (unformat (i, "pipe"))
13806         is_pipe = 1;
13807       else if (unformat (i, "master"))
13808         is_master = 1;
13809       else if (unformat (i, "slave"))
13810         is_master = 0;
13811       else
13812         break;
13813     }
13814
13815   if (!vec_len (if_name))
13816     {
13817       errmsg ("interface name must be specified");
13818       return -99;
13819     }
13820
13821   if (vec_len (if_name) > 64)
13822     {
13823       errmsg ("interface name too long");
13824       return -99;
13825     }
13826
13827   M (NETMAP_CREATE, netmap_create);
13828
13829   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13830   clib_memcpy (mp->hw_addr, hw_addr, 6);
13831   mp->use_random_hw_addr = random_hw_addr;
13832   mp->is_pipe = is_pipe;
13833   mp->is_master = is_master;
13834   vec_free (if_name);
13835
13836   S;
13837   W;
13838   /* NOTREACHED */
13839   return 0;
13840 }
13841
13842 static int
13843 api_netmap_delete (vat_main_t * vam)
13844 {
13845   unformat_input_t *i = vam->input;
13846   vl_api_netmap_delete_t *mp;
13847   f64 timeout;
13848   u8 *if_name = 0;
13849
13850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13851     {
13852       if (unformat (i, "name %s", &if_name))
13853         vec_add1 (if_name, 0);
13854       else
13855         break;
13856     }
13857
13858   if (!vec_len (if_name))
13859     {
13860       errmsg ("interface name must be specified");
13861       return -99;
13862     }
13863
13864   if (vec_len (if_name) > 64)
13865     {
13866       errmsg ("interface name too long");
13867       return -99;
13868     }
13869
13870   M (NETMAP_DELETE, netmap_delete);
13871
13872   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
13873   vec_free (if_name);
13874
13875   S;
13876   W;
13877   /* NOTREACHED */
13878   return 0;
13879 }
13880
13881 static void vl_api_mpls_gre_tunnel_details_t_handler
13882   (vl_api_mpls_gre_tunnel_details_t * mp)
13883 {
13884   vat_main_t *vam = &vat_main;
13885   i32 i;
13886   i32 len = ntohl (mp->nlabels);
13887
13888   if (mp->l2_only == 0)
13889     {
13890       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
13891                ntohl (mp->tunnel_index),
13892                format_ip4_address, &mp->tunnel_src,
13893                format_ip4_address, &mp->tunnel_dst,
13894                format_ip4_address, &mp->intfc_address,
13895                ntohl (mp->mask_width));
13896       for (i = 0; i < len; i++)
13897         {
13898           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13899         }
13900       fformat (vam->ofp, "\n");
13901       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
13902                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
13903     }
13904   else
13905     {
13906       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
13907                ntohl (mp->tunnel_index),
13908                format_ip4_address, &mp->tunnel_src,
13909                format_ip4_address, &mp->tunnel_dst,
13910                format_ip4_address, &mp->intfc_address);
13911       for (i = 0; i < len; i++)
13912         {
13913           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
13914         }
13915       fformat (vam->ofp, "\n");
13916       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
13917                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
13918     }
13919 }
13920
13921 static void vl_api_mpls_gre_tunnel_details_t_handler_json
13922   (vl_api_mpls_gre_tunnel_details_t * mp)
13923 {
13924   vat_main_t *vam = &vat_main;
13925   vat_json_node_t *node = NULL;
13926   struct in_addr ip4;
13927   i32 i;
13928   i32 len = ntohl (mp->nlabels);
13929
13930   if (VAT_JSON_ARRAY != vam->json_tree.type)
13931     {
13932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13933       vat_json_init_array (&vam->json_tree);
13934     }
13935   node = vat_json_array_add (&vam->json_tree);
13936
13937   vat_json_init_object (node);
13938   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
13939   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
13940   vat_json_object_add_ip4 (node, "intfc_address", ip4);
13941   vat_json_object_add_uint (node, "inner_fib_index",
13942                             ntohl (mp->inner_fib_index));
13943   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
13944   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
13945   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
13946   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
13947   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
13948   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
13949   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
13950   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
13951   vat_json_object_add_uint (node, "outer_fib_index",
13952                             ntohl (mp->outer_fib_index));
13953   vat_json_object_add_uint (node, "label_count", len);
13954   for (i = 0; i < len; i++)
13955     {
13956       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
13957     }
13958 }
13959
13960 static int
13961 api_mpls_gre_tunnel_dump (vat_main_t * vam)
13962 {
13963   vl_api_mpls_gre_tunnel_dump_t *mp;
13964   f64 timeout;
13965   i32 index = -1;
13966
13967   /* Parse args required to build the message */
13968   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (!unformat (vam->input, "tunnel_index %d", &index))
13971         {
13972           index = -1;
13973           break;
13974         }
13975     }
13976
13977   fformat (vam->ofp, "  tunnel_index %d\n", index);
13978
13979   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
13980   mp->tunnel_index = htonl (index);
13981   S;
13982
13983   /* Use a control ping for synchronization */
13984   {
13985     vl_api_control_ping_t *mp;
13986     M (CONTROL_PING, control_ping);
13987     S;
13988   }
13989   W;
13990 }
13991
13992 static void vl_api_mpls_eth_tunnel_details_t_handler
13993   (vl_api_mpls_eth_tunnel_details_t * mp)
13994 {
13995   vat_main_t *vam = &vat_main;
13996   i32 i;
13997   i32 len = ntohl (mp->nlabels);
13998
13999   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14000            ntohl (mp->tunnel_index),
14001            format_ethernet_address, &mp->tunnel_dst_mac,
14002            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14003   for (i = 0; i < len; i++)
14004     {
14005       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14006     }
14007   fformat (vam->ofp, "\n");
14008   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14009            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14010 }
14011
14012 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14013   (vl_api_mpls_eth_tunnel_details_t * mp)
14014 {
14015   vat_main_t *vam = &vat_main;
14016   vat_json_node_t *node = NULL;
14017   struct in_addr ip4;
14018   i32 i;
14019   i32 len = ntohl (mp->nlabels);
14020
14021   if (VAT_JSON_ARRAY != vam->json_tree.type)
14022     {
14023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14024       vat_json_init_array (&vam->json_tree);
14025     }
14026   node = vat_json_array_add (&vam->json_tree);
14027
14028   vat_json_init_object (node);
14029   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14030   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14031   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14032   vat_json_object_add_uint (node, "inner_fib_index",
14033                             ntohl (mp->inner_fib_index));
14034   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14035   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14036   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14037   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14038   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14039                                    format (0, "%U", format_ethernet_address,
14040                                            &mp->tunnel_dst_mac));
14041   vat_json_object_add_uint (node, "tx_sw_if_index",
14042                             ntohl (mp->tx_sw_if_index));
14043   vat_json_object_add_uint (node, "label_count", len);
14044   for (i = 0; i < len; i++)
14045     {
14046       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14047     }
14048 }
14049
14050 static int
14051 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14052 {
14053   vl_api_mpls_eth_tunnel_dump_t *mp;
14054   f64 timeout;
14055   i32 index = -1;
14056
14057   /* Parse args required to build the message */
14058   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14059     {
14060       if (!unformat (vam->input, "tunnel_index %d", &index))
14061         {
14062           index = -1;
14063           break;
14064         }
14065     }
14066
14067   fformat (vam->ofp, "  tunnel_index %d\n", index);
14068
14069   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14070   mp->tunnel_index = htonl (index);
14071   S;
14072
14073   /* Use a control ping for synchronization */
14074   {
14075     vl_api_control_ping_t *mp;
14076     M (CONTROL_PING, control_ping);
14077     S;
14078   }
14079   W;
14080 }
14081
14082 static void vl_api_mpls_fib_encap_details_t_handler
14083   (vl_api_mpls_fib_encap_details_t * mp)
14084 {
14085   vat_main_t *vam = &vat_main;
14086   i32 i;
14087   i32 len = ntohl (mp->nlabels);
14088
14089   fformat (vam->ofp, "table %d, dest %U, label ",
14090            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14091   for (i = 0; i < len; i++)
14092     {
14093       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14094     }
14095   fformat (vam->ofp, "\n");
14096 }
14097
14098 static void vl_api_mpls_fib_encap_details_t_handler_json
14099   (vl_api_mpls_fib_encap_details_t * mp)
14100 {
14101   vat_main_t *vam = &vat_main;
14102   vat_json_node_t *node = NULL;
14103   i32 i;
14104   i32 len = ntohl (mp->nlabels);
14105   struct in_addr ip4;
14106
14107   if (VAT_JSON_ARRAY != vam->json_tree.type)
14108     {
14109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14110       vat_json_init_array (&vam->json_tree);
14111     }
14112   node = vat_json_array_add (&vam->json_tree);
14113
14114   vat_json_init_object (node);
14115   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14116   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14117   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14118   vat_json_object_add_ip4 (node, "dest", ip4);
14119   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14120   vat_json_object_add_uint (node, "label_count", len);
14121   for (i = 0; i < len; i++)
14122     {
14123       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14124     }
14125 }
14126
14127 static int
14128 api_mpls_fib_encap_dump (vat_main_t * vam)
14129 {
14130   vl_api_mpls_fib_encap_dump_t *mp;
14131   f64 timeout;
14132
14133   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14134   S;
14135
14136   /* Use a control ping for synchronization */
14137   {
14138     vl_api_control_ping_t *mp;
14139     M (CONTROL_PING, control_ping);
14140     S;
14141   }
14142   W;
14143 }
14144
14145 static void vl_api_mpls_fib_decap_details_t_handler
14146   (vl_api_mpls_fib_decap_details_t * mp)
14147 {
14148   vat_main_t *vam = &vat_main;
14149
14150   fformat (vam->ofp,
14151            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14152            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14153            ntohl (mp->label), ntohl (mp->s_bit));
14154 }
14155
14156 static void vl_api_mpls_fib_decap_details_t_handler_json
14157   (vl_api_mpls_fib_decap_details_t * mp)
14158 {
14159   vat_main_t *vam = &vat_main;
14160   vat_json_node_t *node = NULL;
14161   struct in_addr ip4;
14162
14163   if (VAT_JSON_ARRAY != vam->json_tree.type)
14164     {
14165       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14166       vat_json_init_array (&vam->json_tree);
14167     }
14168   node = vat_json_array_add (&vam->json_tree);
14169
14170   vat_json_init_object (node);
14171   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14172   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14173   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14174   vat_json_object_add_ip4 (node, "dest", ip4);
14175   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14176   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14177   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14178   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14179   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14180 }
14181
14182 static int
14183 api_mpls_fib_decap_dump (vat_main_t * vam)
14184 {
14185   vl_api_mpls_fib_decap_dump_t *mp;
14186   f64 timeout;
14187
14188   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14189   S;
14190
14191   /* Use a control ping for synchronization */
14192   {
14193     vl_api_control_ping_t *mp;
14194     M (CONTROL_PING, control_ping);
14195     S;
14196   }
14197   W;
14198 }
14199
14200 int
14201 api_classify_table_ids (vat_main_t * vam)
14202 {
14203   vl_api_classify_table_ids_t *mp;
14204   f64 timeout;
14205
14206   /* Construct the API message */
14207   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14208   mp->context = 0;
14209
14210   S;
14211   W;
14212   /* NOTREACHED */
14213   return 0;
14214 }
14215
14216 int
14217 api_classify_table_by_interface (vat_main_t * vam)
14218 {
14219   unformat_input_t *input = vam->input;
14220   vl_api_classify_table_by_interface_t *mp;
14221   f64 timeout;
14222
14223   u32 sw_if_index = ~0;
14224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14225     {
14226       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14227         ;
14228       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14229         ;
14230       else
14231         break;
14232     }
14233   if (sw_if_index == ~0)
14234     {
14235       errmsg ("missing interface name or sw_if_index\n");
14236       return -99;
14237     }
14238
14239   /* Construct the API message */
14240   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14241   mp->context = 0;
14242   mp->sw_if_index = ntohl (sw_if_index);
14243
14244   S;
14245   W;
14246   /* NOTREACHED */
14247   return 0;
14248 }
14249
14250 int
14251 api_classify_table_info (vat_main_t * vam)
14252 {
14253   unformat_input_t *input = vam->input;
14254   vl_api_classify_table_info_t *mp;
14255   f64 timeout;
14256
14257   u32 table_id = ~0;
14258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14259     {
14260       if (unformat (input, "table_id %d", &table_id))
14261         ;
14262       else
14263         break;
14264     }
14265   if (table_id == ~0)
14266     {
14267       errmsg ("missing table id\n");
14268       return -99;
14269     }
14270
14271   /* Construct the API message */
14272   M (CLASSIFY_TABLE_INFO, classify_table_info);
14273   mp->context = 0;
14274   mp->table_id = ntohl (table_id);
14275
14276   S;
14277   W;
14278   /* NOTREACHED */
14279   return 0;
14280 }
14281
14282 int
14283 api_classify_session_dump (vat_main_t * vam)
14284 {
14285   unformat_input_t *input = vam->input;
14286   vl_api_classify_session_dump_t *mp;
14287   f64 timeout;
14288
14289   u32 table_id = ~0;
14290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (input, "table_id %d", &table_id))
14293         ;
14294       else
14295         break;
14296     }
14297   if (table_id == ~0)
14298     {
14299       errmsg ("missing table id\n");
14300       return -99;
14301     }
14302
14303   /* Construct the API message */
14304   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14305   mp->context = 0;
14306   mp->table_id = ntohl (table_id);
14307   S;
14308
14309   /* Use a control ping for synchronization */
14310   {
14311     vl_api_control_ping_t *mp;
14312     M (CONTROL_PING, control_ping);
14313     S;
14314   }
14315   W;
14316   /* NOTREACHED */
14317   return 0;
14318 }
14319
14320 static void
14321 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14322 {
14323   vat_main_t *vam = &vat_main;
14324
14325   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14326            "src_address %U, vrf_id %d, path_mtu %u, "
14327            "template_interval %u, udp_checksum %d\n",
14328            format_ip4_address, mp->collector_address,
14329            ntohs (mp->collector_port),
14330            format_ip4_address, mp->src_address,
14331            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14332            ntohl (mp->template_interval), mp->udp_checksum);
14333
14334   vam->retval = 0;
14335   vam->result_ready = 1;
14336 }
14337
14338 static void
14339   vl_api_ipfix_exporter_details_t_handler_json
14340   (vl_api_ipfix_exporter_details_t * mp)
14341 {
14342   vat_main_t *vam = &vat_main;
14343   vat_json_node_t node;
14344   struct in_addr collector_address;
14345   struct in_addr src_address;
14346
14347   vat_json_init_object (&node);
14348   clib_memcpy (&collector_address, &mp->collector_address,
14349                sizeof (collector_address));
14350   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14351   vat_json_object_add_uint (&node, "collector_port",
14352                             ntohs (mp->collector_port));
14353   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14354   vat_json_object_add_ip4 (&node, "src_address", src_address);
14355   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14356   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14357   vat_json_object_add_uint (&node, "template_interval",
14358                             ntohl (mp->template_interval));
14359   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14360
14361   vat_json_print (vam->ofp, &node);
14362   vat_json_free (&node);
14363   vam->retval = 0;
14364   vam->result_ready = 1;
14365 }
14366
14367 int
14368 api_ipfix_exporter_dump (vat_main_t * vam)
14369 {
14370   vl_api_ipfix_exporter_dump_t *mp;
14371   f64 timeout;
14372
14373   /* Construct the API message */
14374   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14375   mp->context = 0;
14376
14377   S;
14378   W;
14379   /* NOTREACHED */
14380   return 0;
14381 }
14382
14383 static int
14384 api_ipfix_classify_stream_dump (vat_main_t * vam)
14385 {
14386   vl_api_ipfix_classify_stream_dump_t *mp;
14387   f64 timeout;
14388
14389   /* Construct the API message */
14390   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14391   mp->context = 0;
14392
14393   S;
14394   W;
14395   /* NOTREACHED */
14396   return 0;
14397 }
14398
14399 static void
14400   vl_api_ipfix_classify_stream_details_t_handler
14401   (vl_api_ipfix_classify_stream_details_t * mp)
14402 {
14403   vat_main_t *vam = &vat_main;
14404   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14405            ntohl (mp->domain_id), ntohs (mp->src_port));
14406   vam->retval = 0;
14407   vam->result_ready = 1;
14408 }
14409
14410 static void
14411   vl_api_ipfix_classify_stream_details_t_handler_json
14412   (vl_api_ipfix_classify_stream_details_t * mp)
14413 {
14414   vat_main_t *vam = &vat_main;
14415   vat_json_node_t node;
14416
14417   vat_json_init_object (&node);
14418   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14419   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14420
14421   vat_json_print (vam->ofp, &node);
14422   vat_json_free (&node);
14423   vam->retval = 0;
14424   vam->result_ready = 1;
14425 }
14426
14427 static int
14428 api_ipfix_classify_table_dump (vat_main_t * vam)
14429 {
14430   vl_api_ipfix_classify_table_dump_t *mp;
14431   f64 timeout;
14432
14433   if (!vam->json_output)
14434     {
14435       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14436                "transport_protocol");
14437     }
14438
14439   /* Construct the API message */
14440   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14441
14442   /* send it... */
14443   S;
14444
14445   /* Use a control ping for synchronization */
14446   {
14447     vl_api_control_ping_t *mp;
14448     M (CONTROL_PING, control_ping);
14449     S;
14450   }
14451   W;
14452 }
14453
14454 static void
14455   vl_api_ipfix_classify_table_details_t_handler
14456   (vl_api_ipfix_classify_table_details_t * mp)
14457 {
14458   vat_main_t *vam = &vat_main;
14459   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14460            mp->transport_protocol);
14461 }
14462
14463 static void
14464   vl_api_ipfix_classify_table_details_t_handler_json
14465   (vl_api_ipfix_classify_table_details_t * mp)
14466 {
14467   vat_json_node_t *node = NULL;
14468   vat_main_t *vam = &vat_main;
14469
14470   if (VAT_JSON_ARRAY != vam->json_tree.type)
14471     {
14472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14473       vat_json_init_array (&vam->json_tree);
14474     }
14475
14476   node = vat_json_array_add (&vam->json_tree);
14477   vat_json_init_object (node);
14478
14479   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14480   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14481   vat_json_object_add_uint (node, "transport_protocol",
14482                             mp->transport_protocol);
14483 }
14484
14485 int
14486 api_pg_create_interface (vat_main_t * vam)
14487 {
14488   unformat_input_t *input = vam->input;
14489   vl_api_pg_create_interface_t *mp;
14490   f64 timeout;
14491
14492   u32 if_id = ~0;
14493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14494     {
14495       if (unformat (input, "if_id %d", &if_id))
14496         ;
14497       else
14498         break;
14499     }
14500   if (if_id == ~0)
14501     {
14502       errmsg ("missing pg interface index\n");
14503       return -99;
14504     }
14505
14506   /* Construct the API message */
14507   M (PG_CREATE_INTERFACE, pg_create_interface);
14508   mp->context = 0;
14509   mp->interface_id = ntohl (if_id);
14510
14511   S;
14512   W;
14513   /* NOTREACHED */
14514   return 0;
14515 }
14516
14517 int
14518 api_pg_capture (vat_main_t * vam)
14519 {
14520   unformat_input_t *input = vam->input;
14521   vl_api_pg_capture_t *mp;
14522   f64 timeout;
14523
14524   u32 if_id = ~0;
14525   u8 enable = 1;
14526   u32 count = 1;
14527   u8 pcap_file_set = 0;
14528   u8 *pcap_file = 0;
14529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14530     {
14531       if (unformat (input, "if_id %d", &if_id))
14532         ;
14533       else if (unformat (input, "pcap %s", &pcap_file))
14534         pcap_file_set = 1;
14535       else if (unformat (input, "count %d", &count))
14536         ;
14537       else if (unformat (input, "disable"))
14538         enable = 0;
14539       else
14540         break;
14541     }
14542   if (if_id == ~0)
14543     {
14544       errmsg ("missing pg interface index\n");
14545       return -99;
14546     }
14547   if (pcap_file_set > 0)
14548     {
14549       if (vec_len (pcap_file) > 255)
14550         {
14551           errmsg ("pcap file name is too long\n");
14552           return -99;
14553         }
14554     }
14555
14556   u32 name_len = vec_len (pcap_file);
14557   /* Construct the API message */
14558   M (PG_CAPTURE, pg_capture);
14559   mp->context = 0;
14560   mp->interface_id = ntohl (if_id);
14561   mp->is_enabled = enable;
14562   mp->count = ntohl (count);
14563   mp->pcap_name_length = ntohl (name_len);
14564   if (pcap_file_set != 0)
14565     {
14566       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14567     }
14568   vec_free (pcap_file);
14569
14570   S;
14571   W;
14572   /* NOTREACHED */
14573   return 0;
14574 }
14575
14576 int
14577 api_pg_enable_disable (vat_main_t * vam)
14578 {
14579   unformat_input_t *input = vam->input;
14580   vl_api_pg_enable_disable_t *mp;
14581   f64 timeout;
14582
14583   u8 enable = 1;
14584   u8 stream_name_set = 0;
14585   u8 *stream_name = 0;
14586   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14587     {
14588       if (unformat (input, "stream %s", &stream_name))
14589         stream_name_set = 1;
14590       else if (unformat (input, "disable"))
14591         enable = 0;
14592       else
14593         break;
14594     }
14595
14596   if (stream_name_set > 0)
14597     {
14598       if (vec_len (stream_name) > 255)
14599         {
14600           errmsg ("stream name too long\n");
14601           return -99;
14602         }
14603     }
14604
14605   u32 name_len = vec_len (stream_name);
14606   /* Construct the API message */
14607   M (PG_ENABLE_DISABLE, pg_enable_disable);
14608   mp->context = 0;
14609   mp->is_enabled = enable;
14610   if (stream_name_set != 0)
14611     {
14612       mp->stream_name_length = ntohl (name_len);
14613       clib_memcpy (mp->stream_name, stream_name, name_len);
14614     }
14615   vec_free (stream_name);
14616
14617   S;
14618   W;
14619   /* NOTREACHED */
14620   return 0;
14621 }
14622
14623 int
14624 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14625 {
14626   unformat_input_t *input = vam->input;
14627   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14628   f64 timeout;
14629
14630   u16 *low_ports = 0;
14631   u16 *high_ports = 0;
14632   u16 this_low;
14633   u16 this_hi;
14634   ip4_address_t ip4_addr;
14635   ip6_address_t ip6_addr;
14636   u32 length;
14637   u32 tmp, tmp2;
14638   u8 prefix_set = 0;
14639   u32 vrf_id = ~0;
14640   u8 is_add = 1;
14641   u8 is_ipv6 = 0;
14642
14643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14646         {
14647           prefix_set = 1;
14648         }
14649       else
14650         if (unformat
14651             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14652         {
14653           prefix_set = 1;
14654           is_ipv6 = 1;
14655         }
14656       else if (unformat (input, "vrf %d", &vrf_id))
14657         ;
14658       else if (unformat (input, "del"))
14659         is_add = 0;
14660       else if (unformat (input, "port %d", &tmp))
14661         {
14662           if (tmp == 0 || tmp > 65535)
14663             {
14664               errmsg ("port %d out of range", tmp);
14665               return -99;
14666             }
14667           this_low = tmp;
14668           this_hi = this_low + 1;
14669           vec_add1 (low_ports, this_low);
14670           vec_add1 (high_ports, this_hi);
14671         }
14672       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14673         {
14674           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14675             {
14676               errmsg ("incorrect range parameters\n");
14677               return -99;
14678             }
14679           this_low = tmp;
14680           /* Note: in debug CLI +1 is added to high before
14681              passing to real fn that does "the work"
14682              (ip_source_and_port_range_check_add_del).
14683              This fn is a wrapper around the binary API fn a
14684              control plane will call, which expects this increment
14685              to have occurred. Hence letting the binary API control
14686              plane fn do the increment for consistency between VAT
14687              and other control planes.
14688            */
14689           this_hi = tmp2;
14690           vec_add1 (low_ports, this_low);
14691           vec_add1 (high_ports, this_hi);
14692         }
14693       else
14694         break;
14695     }
14696
14697   if (prefix_set == 0)
14698     {
14699       errmsg ("<address>/<mask> not specified\n");
14700       return -99;
14701     }
14702
14703   if (vrf_id == ~0)
14704     {
14705       errmsg ("VRF ID required, not specified\n");
14706       return -99;
14707     }
14708
14709   if (vrf_id == 0)
14710     {
14711       errmsg
14712         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14713       return -99;
14714     }
14715
14716   if (vec_len (low_ports) == 0)
14717     {
14718       errmsg ("At least one port or port range required\n");
14719       return -99;
14720     }
14721
14722   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14723      ip_source_and_port_range_check_add_del);
14724
14725   mp->is_add = is_add;
14726
14727   if (is_ipv6)
14728     {
14729       mp->is_ipv6 = 1;
14730       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14731     }
14732   else
14733     {
14734       mp->is_ipv6 = 0;
14735       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14736     }
14737
14738   mp->mask_length = length;
14739   mp->number_of_ranges = vec_len (low_ports);
14740
14741   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14742   vec_free (low_ports);
14743
14744   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14745   vec_free (high_ports);
14746
14747   mp->vrf_id = ntohl (vrf_id);
14748
14749   S;
14750   W;
14751   /* NOTREACHED */
14752   return 0;
14753 }
14754
14755 int
14756 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14757 {
14758   unformat_input_t *input = vam->input;
14759   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14760   f64 timeout;
14761   u32 sw_if_index = ~0;
14762   int vrf_set = 0;
14763   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14764   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14765   u8 is_add = 1;
14766
14767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14768     {
14769       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14770         ;
14771       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14772         ;
14773       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14774         vrf_set = 1;
14775       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14776         vrf_set = 1;
14777       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14778         vrf_set = 1;
14779       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14780         vrf_set = 1;
14781       else if (unformat (input, "del"))
14782         is_add = 0;
14783       else
14784         break;
14785     }
14786
14787   if (sw_if_index == ~0)
14788     {
14789       errmsg ("Interface required but not specified\n");
14790       return -99;
14791     }
14792
14793   if (vrf_set == 0)
14794     {
14795       errmsg ("VRF ID required but not specified\n");
14796       return -99;
14797     }
14798
14799   if (tcp_out_vrf_id == 0
14800       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14801     {
14802       errmsg
14803         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14804       return -99;
14805     }
14806
14807   /* Construct the API message */
14808   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14809      ip_source_and_port_range_check_interface_add_del);
14810
14811   mp->sw_if_index = ntohl (sw_if_index);
14812   mp->is_add = is_add;
14813   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14814   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14815   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14816   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14817
14818   /* send it... */
14819   S;
14820
14821   /* Wait for a reply... */
14822   W;
14823 }
14824
14825 static int
14826 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
14827 {
14828   unformat_input_t *i = vam->input;
14829   vl_api_ipsec_gre_add_del_tunnel_t *mp;
14830   f64 timeout;
14831   u32 local_sa_id = 0;
14832   u32 remote_sa_id = 0;
14833   ip4_address_t src_address;
14834   ip4_address_t dst_address;
14835   u8 is_add = 1;
14836
14837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14838     {
14839       if (unformat (i, "local_sa %d", &local_sa_id))
14840         ;
14841       else if (unformat (i, "remote_sa %d", &remote_sa_id))
14842         ;
14843       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
14844         ;
14845       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
14846         ;
14847       else if (unformat (i, "del"))
14848         is_add = 0;
14849       else
14850         {
14851           clib_warning ("parse error '%U'", format_unformat_error, i);
14852           return -99;
14853         }
14854     }
14855
14856   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
14857
14858   mp->local_sa_id = ntohl (local_sa_id);
14859   mp->remote_sa_id = ntohl (remote_sa_id);
14860   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
14861   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
14862   mp->is_add = is_add;
14863
14864   S;
14865   W;
14866   /* NOTREACHED */
14867   return 0;
14868 }
14869
14870 static void vl_api_ipsec_gre_tunnel_details_t_handler
14871   (vl_api_ipsec_gre_tunnel_details_t * mp)
14872 {
14873   vat_main_t *vam = &vat_main;
14874
14875   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
14876            ntohl (mp->sw_if_index),
14877            format_ip4_address, &mp->src_address,
14878            format_ip4_address, &mp->dst_address,
14879            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
14880 }
14881
14882 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
14883   (vl_api_ipsec_gre_tunnel_details_t * mp)
14884 {
14885   vat_main_t *vam = &vat_main;
14886   vat_json_node_t *node = NULL;
14887   struct in_addr ip4;
14888
14889   if (VAT_JSON_ARRAY != vam->json_tree.type)
14890     {
14891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14892       vat_json_init_array (&vam->json_tree);
14893     }
14894   node = vat_json_array_add (&vam->json_tree);
14895
14896   vat_json_init_object (node);
14897   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14898   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
14899   vat_json_object_add_ip4 (node, "src_address", ip4);
14900   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
14901   vat_json_object_add_ip4 (node, "dst_address", ip4);
14902   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
14903   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
14904 }
14905
14906 static int
14907 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
14908 {
14909   unformat_input_t *i = vam->input;
14910   vl_api_ipsec_gre_tunnel_dump_t *mp;
14911   f64 timeout;
14912   u32 sw_if_index;
14913   u8 sw_if_index_set = 0;
14914
14915   /* Parse args required to build the message */
14916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14917     {
14918       if (unformat (i, "sw_if_index %d", &sw_if_index))
14919         sw_if_index_set = 1;
14920       else
14921         break;
14922     }
14923
14924   if (sw_if_index_set == 0)
14925     {
14926       sw_if_index = ~0;
14927     }
14928
14929   if (!vam->json_output)
14930     {
14931       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
14932                "sw_if_index", "src_address", "dst_address",
14933                "local_sa_id", "remote_sa_id");
14934     }
14935
14936   /* Get list of gre-tunnel interfaces */
14937   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
14938
14939   mp->sw_if_index = htonl (sw_if_index);
14940
14941   S;
14942
14943   /* Use a control ping for synchronization */
14944   {
14945     vl_api_control_ping_t *mp;
14946     M (CONTROL_PING, control_ping);
14947     S;
14948   }
14949   W;
14950 }
14951
14952 static int
14953 api_delete_subif (vat_main_t * vam)
14954 {
14955   unformat_input_t *i = vam->input;
14956   vl_api_delete_subif_t *mp;
14957   f64 timeout;
14958   u32 sw_if_index = ~0;
14959
14960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14961     {
14962       if (unformat (i, "sw_if_index %d", &sw_if_index))
14963         ;
14964       else
14965         break;
14966     }
14967
14968   if (sw_if_index == ~0)
14969     {
14970       errmsg ("missing sw_if_index\n");
14971       return -99;
14972     }
14973
14974   /* Construct the API message */
14975   M (DELETE_SUBIF, delete_subif);
14976   mp->sw_if_index = ntohl (sw_if_index);
14977
14978   S;
14979   W;
14980 }
14981
14982 static int
14983 q_or_quit (vat_main_t * vam)
14984 {
14985   longjmp (vam->jump_buf, 1);
14986   return 0;                     /* not so much */
14987 }
14988
14989 static int
14990 q (vat_main_t * vam)
14991 {
14992   return q_or_quit (vam);
14993 }
14994
14995 static int
14996 quit (vat_main_t * vam)
14997 {
14998   return q_or_quit (vam);
14999 }
15000
15001 static int
15002 comment (vat_main_t * vam)
15003 {
15004   return 0;
15005 }
15006
15007 static int
15008 cmd_cmp (void *a1, void *a2)
15009 {
15010   u8 **c1 = a1;
15011   u8 **c2 = a2;
15012
15013   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15014 }
15015
15016 static int
15017 help (vat_main_t * vam)
15018 {
15019   u8 **cmds = 0;
15020   u8 *name = 0;
15021   hash_pair_t *p;
15022   unformat_input_t *i = vam->input;
15023   int j;
15024
15025   if (unformat (i, "%s", &name))
15026     {
15027       uword *hs;
15028
15029       vec_add1 (name, 0);
15030
15031       hs = hash_get_mem (vam->help_by_name, name);
15032       if (hs)
15033         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15034       else
15035         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15036       vec_free (name);
15037       return 0;
15038     }
15039
15040   fformat (vam->ofp, "Help is available for the following:\n");
15041
15042     /* *INDENT-OFF* */
15043     hash_foreach_pair (p, vam->function_by_name,
15044     ({
15045       vec_add1 (cmds, (u8 *)(p->key));
15046     }));
15047     /* *INDENT-ON* */
15048
15049   vec_sort_with_function (cmds, cmd_cmp);
15050
15051   for (j = 0; j < vec_len (cmds); j++)
15052     fformat (vam->ofp, "%s\n", cmds[j]);
15053
15054   vec_free (cmds);
15055   return 0;
15056 }
15057
15058 static int
15059 set (vat_main_t * vam)
15060 {
15061   u8 *name = 0, *value = 0;
15062   unformat_input_t *i = vam->input;
15063
15064   if (unformat (i, "%s", &name))
15065     {
15066       /* The input buffer is a vector, not a string. */
15067       value = vec_dup (i->buffer);
15068       vec_delete (value, i->index, 0);
15069       /* Almost certainly has a trailing newline */
15070       if (value[vec_len (value) - 1] == '\n')
15071         value[vec_len (value) - 1] = 0;
15072       /* Make sure it's a proper string, one way or the other */
15073       vec_add1 (value, 0);
15074       (void) clib_macro_set_value (&vam->macro_main,
15075                                    (char *) name, (char *) value);
15076     }
15077   else
15078     errmsg ("usage: set <name> <value>\n");
15079
15080   vec_free (name);
15081   vec_free (value);
15082   return 0;
15083 }
15084
15085 static int
15086 unset (vat_main_t * vam)
15087 {
15088   u8 *name = 0;
15089
15090   if (unformat (vam->input, "%s", &name))
15091     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15092       errmsg ("unset: %s wasn't set\n", name);
15093   vec_free (name);
15094   return 0;
15095 }
15096
15097 typedef struct
15098 {
15099   u8 *name;
15100   u8 *value;
15101 } macro_sort_t;
15102
15103
15104 static int
15105 macro_sort_cmp (void *a1, void *a2)
15106 {
15107   macro_sort_t *s1 = a1;
15108   macro_sort_t *s2 = a2;
15109
15110   return strcmp ((char *) (s1->name), (char *) (s2->name));
15111 }
15112
15113 static int
15114 dump_macro_table (vat_main_t * vam)
15115 {
15116   macro_sort_t *sort_me = 0, *sm;
15117   int i;
15118   hash_pair_t *p;
15119
15120     /* *INDENT-OFF* */
15121     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15122     ({
15123       vec_add2 (sort_me, sm, 1);
15124       sm->name = (u8 *)(p->key);
15125       sm->value = (u8 *) (p->value[0]);
15126     }));
15127     /* *INDENT-ON* */
15128
15129   vec_sort_with_function (sort_me, macro_sort_cmp);
15130
15131   if (vec_len (sort_me))
15132     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15133   else
15134     fformat (vam->ofp, "The macro table is empty...\n");
15135
15136   for (i = 0; i < vec_len (sort_me); i++)
15137     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15138   return 0;
15139 }
15140
15141 static int
15142 dump_node_table (vat_main_t * vam)
15143 {
15144   int i, j;
15145   vlib_node_t *node, *next_node;
15146
15147   if (vec_len (vam->graph_nodes) == 0)
15148     {
15149       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15150       return 0;
15151     }
15152
15153   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15154     {
15155       node = vam->graph_nodes[i];
15156       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15157       for (j = 0; j < vec_len (node->next_nodes); j++)
15158         {
15159           if (node->next_nodes[j] != ~0)
15160             {
15161               next_node = vam->graph_nodes[node->next_nodes[j]];
15162               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15163             }
15164         }
15165     }
15166   return 0;
15167 }
15168
15169 static int
15170 search_node_table (vat_main_t * vam)
15171 {
15172   unformat_input_t *line_input = vam->input;
15173   u8 *node_to_find;
15174   int j;
15175   vlib_node_t *node, *next_node;
15176   uword *p;
15177
15178   if (vam->graph_node_index_by_name == 0)
15179     {
15180       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15181       return 0;
15182     }
15183
15184   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15185     {
15186       if (unformat (line_input, "%s", &node_to_find))
15187         {
15188           vec_add1 (node_to_find, 0);
15189           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15190           if (p == 0)
15191             {
15192               fformat (vam->ofp, "%s not found...\n", node_to_find);
15193               goto out;
15194             }
15195           node = vam->graph_nodes[p[0]];
15196           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15197           for (j = 0; j < vec_len (node->next_nodes); j++)
15198             {
15199               if (node->next_nodes[j] != ~0)
15200                 {
15201                   next_node = vam->graph_nodes[node->next_nodes[j]];
15202                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15203                 }
15204             }
15205         }
15206
15207       else
15208         {
15209           clib_warning ("parse error '%U'", format_unformat_error,
15210                         line_input);
15211           return -99;
15212         }
15213
15214     out:
15215       vec_free (node_to_find);
15216
15217     }
15218
15219   return 0;
15220 }
15221
15222
15223 static int
15224 script (vat_main_t * vam)
15225 {
15226   u8 *s = 0;
15227   char *save_current_file;
15228   unformat_input_t save_input;
15229   jmp_buf save_jump_buf;
15230   u32 save_line_number;
15231
15232   FILE *new_fp, *save_ifp;
15233
15234   if (unformat (vam->input, "%s", &s))
15235     {
15236       new_fp = fopen ((char *) s, "r");
15237       if (new_fp == 0)
15238         {
15239           errmsg ("Couldn't open script file %s\n", s);
15240           vec_free (s);
15241           return -99;
15242         }
15243     }
15244   else
15245     {
15246       errmsg ("Missing script name\n");
15247       return -99;
15248     }
15249
15250   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15251   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15252   save_ifp = vam->ifp;
15253   save_line_number = vam->input_line_number;
15254   save_current_file = (char *) vam->current_file;
15255
15256   vam->input_line_number = 0;
15257   vam->ifp = new_fp;
15258   vam->current_file = s;
15259   do_one_file (vam);
15260
15261   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15262   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15263   vam->ifp = save_ifp;
15264   vam->input_line_number = save_line_number;
15265   vam->current_file = (u8 *) save_current_file;
15266   vec_free (s);
15267
15268   return 0;
15269 }
15270
15271 static int
15272 echo (vat_main_t * vam)
15273 {
15274   fformat (vam->ofp, "%v", vam->input->buffer);
15275   return 0;
15276 }
15277
15278 /* List of API message constructors, CLI names map to api_xxx */
15279 #define foreach_vpe_api_msg                                             \
15280 _(create_loopback,"[mac <mac-addr>]")                                   \
15281 _(sw_interface_dump,"")                                                 \
15282 _(sw_interface_set_flags,                                               \
15283   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15284 _(sw_interface_add_del_address,                                         \
15285   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15286 _(sw_interface_set_table,                                               \
15287   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15288 _(sw_interface_set_vpath,                                               \
15289   "<intfc> | sw_if_index <id> enable | disable")                        \
15290 _(sw_interface_set_l2_xconnect,                                         \
15291   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15292   "enable | disable")                                                   \
15293 _(sw_interface_set_l2_bridge,                                           \
15294   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15295   "[shg <split-horizon-group>] [bvi]\n"                                 \
15296   "enable | disable")                                                   \
15297 _(bridge_domain_add_del,                                                \
15298   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15299 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15300 _(l2fib_add_del,                                                        \
15301   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15302 _(l2_flags,                                                             \
15303   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15304 _(bridge_flags,                                                         \
15305   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15306 _(tap_connect,                                                          \
15307   "tapname <name> mac <mac-addr> | random-mac")                         \
15308 _(tap_modify,                                                           \
15309   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15310 _(tap_delete,                                                           \
15311   "<vpp-if-name> | sw_if_index <id>")                                   \
15312 _(sw_interface_tap_dump, "")                                            \
15313 _(ip_add_del_route,                                                     \
15314   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15315   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15316   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15317   "[multipath] [count <n>]")                                            \
15318 _(proxy_arp_add_del,                                                    \
15319   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15320 _(proxy_arp_intfc_enable_disable,                                       \
15321   "<intfc> | sw_if_index <id> enable | disable")                        \
15322 _(mpls_add_del_encap,                                                   \
15323   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15324 _(mpls_add_del_decap,                                                   \
15325   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15326 _(mpls_gre_add_del_tunnel,                                              \
15327   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15328   "adj <ip4-address>/<mask-width> [del]")                               \
15329 _(sw_interface_set_unnumbered,                                          \
15330   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15331 _(ip_neighbor_add_del,                                                  \
15332   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15333   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15334 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15335 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15336 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15337   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15338   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15339   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15340 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15341 _(reset_fib, "vrf <n> [ipv6]")                                          \
15342 _(dhcp_proxy_config,                                                    \
15343   "svr <v46-address> src <v46-address>\n"                               \
15344    "insert-cid <n> [del]")                                              \
15345 _(dhcp_proxy_config_2,                                                  \
15346   "svr <v46-address> src <v46-address>\n"                               \
15347    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15348 _(dhcp_proxy_set_vss,                                                   \
15349   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15350 _(dhcp_client_config,                                                   \
15351   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15352 _(set_ip_flow_hash,                                                     \
15353   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15354 _(sw_interface_ip6_enable_disable,                                      \
15355   "<intfc> | sw_if_index <id> enable | disable")                        \
15356 _(sw_interface_ip6_set_link_local_address,                              \
15357   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15358 _(sw_interface_ip6nd_ra_prefix,                                         \
15359   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15360   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15361   "[nolink] [isno]")                                                    \
15362 _(sw_interface_ip6nd_ra_config,                                         \
15363   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15364   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15365   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15366 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15367 _(l2_patch_add_del,                                                     \
15368   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15369   "enable | disable")                                                   \
15370 _(mpls_ethernet_add_del_tunnel,                                         \
15371   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15372   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15373 _(mpls_ethernet_add_del_tunnel_2,                                       \
15374   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15375   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15376 _(sr_tunnel_add_del,                                                    \
15377   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15378   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15379   "[policy <policy_name>]")                                             \
15380 _(sr_policy_add_del,                                                    \
15381   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15382 _(sr_multicast_map_add_del,                                             \
15383   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15384 _(classify_add_del_table,                                               \
15385   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15386   "[del] mask <mask-value>\n"                                           \
15387   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15388 _(classify_add_del_session,                                             \
15389   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15390   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15391   "  [l3 [ip4|ip6]]")                                                   \
15392 _(classify_set_interface_ip_table,                                      \
15393   "<intfc> | sw_if_index <nn> table <nn>")                              \
15394 _(classify_set_interface_l2_tables,                                     \
15395   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15396   "  [other-table <nn>]")                                               \
15397 _(get_node_index, "node <node-name")                                    \
15398 _(add_node_next, "node <node-name> next <next-node-name>")              \
15399 _(l2tpv3_create_tunnel,                                                 \
15400   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15401   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15402   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15403 _(l2tpv3_set_tunnel_cookies,                                            \
15404   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15405   "[new_remote_cookie <nn>]\n")                                         \
15406 _(l2tpv3_interface_enable_disable,                                      \
15407   "<intfc> | sw_if_index <nn> enable | disable")                        \
15408 _(l2tpv3_set_lookup_key,                                                \
15409   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15410 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15411 _(vxlan_add_del_tunnel,                                                 \
15412   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15413   " [decap-next l2|ip4|ip6] [del]")                                     \
15414 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15415 _(gre_add_del_tunnel,                                                   \
15416   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15417 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15418 _(l2_fib_clear_table, "")                                               \
15419 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15420 _(l2_interface_vlan_tag_rewrite,                                        \
15421   "<intfc> | sw_if_index <nn> \n"                                       \
15422   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15423   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15424 _(create_vhost_user_if,                                                 \
15425         "socket <filename> [server] [renumber <dev_instance>] "         \
15426         "[mac <mac_address>]")                                          \
15427 _(modify_vhost_user_if,                                                 \
15428         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15429         "[server] [renumber <dev_instance>]")                           \
15430 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15431 _(sw_interface_vhost_user_dump, "")                                     \
15432 _(show_version, "")                                                     \
15433 _(vxlan_gpe_add_del_tunnel,                                             \
15434   "local <addr> remote <addr> vni <nn>\n"                               \
15435     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15436   "[next-ethernet] [next-nsh]\n")                                       \
15437 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15438 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15439 _(interface_name_renumber,                                              \
15440   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15441 _(input_acl_set_interface,                                              \
15442   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15443   "  [l2-table <nn>] [del]")                                            \
15444 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15445 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15446 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15447 _(ip_dump, "ipv4 | ipv6")                                               \
15448 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15449 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15450   "  spid_id <n> ")                                                     \
15451 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15452   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15453   "  integ_alg <alg> integ_key <hex>")                                  \
15454 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15455   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15456   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15457   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15458 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15459 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15460 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15461   "(auth_data 0x<data> | auth_data <data>)")                            \
15462 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15463   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15464 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15465   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15466   "(local|remote)")                                                     \
15467 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15468 _(delete_loopback,"sw_if_index <nn>")                                   \
15469 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15470 _(map_add_domain,                                                       \
15471   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15472   "ip6-src <ip6addr> "                                                  \
15473   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15474 _(map_del_domain, "index <n>")                                          \
15475 _(map_add_del_rule,                                                     \
15476   "index <n> psid <n> dst <ip6addr> [del]")                             \
15477 _(map_domain_dump, "")                                                  \
15478 _(map_rule_dump, "index <map-domain>")                                  \
15479 _(want_interface_events,  "enable|disable")                             \
15480 _(want_stats,"enable|disable")                                          \
15481 _(get_first_msg_id, "client <name>")                                    \
15482 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15483 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15484   "fib-id <nn> [ip4][ip6][default]")                                    \
15485 _(get_node_graph, " ")                                                  \
15486 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15487 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15488 _(ioam_disable, "")                                                \
15489 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15490                             " sw_if_index <sw_if_index> p <priority> "  \
15491                             "w <weight>] [del]")                        \
15492 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15493                         "iface <intf> | sw_if_index <sw_if_index> "     \
15494                         "p <priority> w <weight> [del]")                \
15495 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15496                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15497                           "locator-set <locator_name> [del]")           \
15498 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15499   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15500 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15501 _(lisp_gpe_enable_disable, "enable|disable")                            \
15502 _(lisp_enable_disable, "enable|disable")                                \
15503 _(lisp_gpe_add_del_iface, "up|down")                                    \
15504 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15505                                "[seid <seid>] "                         \
15506                                "rloc <locator> p <prio> "               \
15507                                "w <weight> [rloc <loc> ... ] "          \
15508                                "action <action> [del-all]")             \
15509 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15510                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15511                           "[rloc <loc> ... ] action <action>")          \
15512 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15513 _(lisp_map_request_mode, "src-dst|dst-only")                            \
15514 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15515 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15516 _(lisp_locator_set_dump, "[local | remote]")                            \
15517 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15518 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15519                        "[local] | [remote]")                            \
15520 _(lisp_eid_table_vni_dump, "")                                          \
15521 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15522 _(lisp_gpe_tunnel_dump, "")                                             \
15523 _(lisp_map_resolver_dump, "")                                           \
15524 _(show_lisp_status, "")                                                 \
15525 _(lisp_get_map_request_itr_rlocs, "")                                   \
15526 _(show_lisp_pitr, "")                                                   \
15527 _(show_lisp_map_request_mode, "")                                       \
15528 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15529 _(af_packet_delete, "name <host interface name>")                       \
15530 _(policer_add_del, "name <policer name> <params> [del]")                \
15531 _(policer_dump, "[name <policer name>]")                                \
15532 _(policer_classify_set_interface,                                       \
15533   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15534   "  [l2-table <nn>] [del]")                                            \
15535 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15536 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15537     "[master|slave]")                                                   \
15538 _(netmap_delete, "name <interface name>")                               \
15539 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15540 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15541 _(mpls_fib_encap_dump, "")                                              \
15542 _(mpls_fib_decap_dump, "")                                              \
15543 _(classify_table_ids, "")                                               \
15544 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15545 _(classify_table_info, "table_id <nn>")                                 \
15546 _(classify_session_dump, "table_id <nn>")                               \
15547 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15548     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15549     "[template_interval <nn>] [udp_checksum]")                          \
15550 _(ipfix_exporter_dump, "")                                              \
15551 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15552 _(ipfix_classify_stream_dump, "")                                       \
15553 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15554 _(ipfix_classify_table_dump, "")                                        \
15555 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15556 _(pg_create_interface, "if_id <nn>")                                    \
15557 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15558 _(pg_enable_disable, "[stream <id>] disable")                           \
15559 _(ip_source_and_port_range_check_add_del,                               \
15560   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15561 _(ip_source_and_port_range_check_interface_add_del,                     \
15562   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15563   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15564 _(ipsec_gre_add_del_tunnel,                                             \
15565   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15566 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15567 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15568
15569 /* List of command functions, CLI names map directly to functions */
15570 #define foreach_cli_function                                    \
15571 _(comment, "usage: comment <ignore-rest-of-line>")              \
15572 _(dump_interface_table, "usage: dump_interface_table")          \
15573 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15574 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15575 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15576 _(dump_stats_table, "usage: dump_stats_table")                  \
15577 _(dump_macro_table, "usage: dump_macro_table ")                 \
15578 _(dump_node_table, "usage: dump_node_table")                    \
15579 _(echo, "usage: echo <message>")                                \
15580 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15581 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15582 _(help, "usage: help")                                          \
15583 _(q, "usage: quit")                                             \
15584 _(quit, "usage: quit")                                          \
15585 _(search_node_table, "usage: search_node_table <name>...")      \
15586 _(set, "usage: set <variable-name> <value>")                    \
15587 _(script, "usage: script <file-name>")                          \
15588 _(unset, "usage: unset <variable-name>")
15589
15590 #define _(N,n)                                  \
15591     static void vl_api_##n##_t_handler_uni      \
15592     (vl_api_##n##_t * mp)                       \
15593     {                                           \
15594         vat_main_t * vam = &vat_main;           \
15595         if (vam->json_output) {                 \
15596             vl_api_##n##_t_handler_json(mp);    \
15597         } else {                                \
15598             vl_api_##n##_t_handler(mp);         \
15599         }                                       \
15600     }
15601 foreach_vpe_api_reply_msg;
15602 #undef _
15603
15604 void
15605 vat_api_hookup (vat_main_t * vam)
15606 {
15607 #define _(N,n)                                                  \
15608     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15609                            vl_api_##n##_t_handler_uni,          \
15610                            vl_noop_handler,                     \
15611                            vl_api_##n##_t_endian,               \
15612                            vl_api_##n##_t_print,                \
15613                            sizeof(vl_api_##n##_t), 1);
15614   foreach_vpe_api_reply_msg;
15615 #undef _
15616
15617   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15618
15619   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15620
15621   vam->function_by_name = hash_create_string (0, sizeof (uword));
15622
15623   vam->help_by_name = hash_create_string (0, sizeof (uword));
15624
15625   /* API messages we can send */
15626 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15627   foreach_vpe_api_msg;
15628 #undef _
15629
15630   /* Help strings */
15631 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15632   foreach_vpe_api_msg;
15633 #undef _
15634
15635   /* CLI functions */
15636 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15637   foreach_cli_function;
15638 #undef _
15639
15640   /* Help strings */
15641 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15642   foreach_cli_function;
15643 #undef _
15644 }
15645
15646 #undef vl_api_version
15647 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15648 #include <vpp-api/vpe.api.h>
15649 #undef vl_api_version
15650
15651 void
15652 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15653 {
15654   /*
15655    * Send the main API signature in slot 0. This bit of code must
15656    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15657    */
15658   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15659 }
15660
15661 /*
15662  * fd.io coding-style-patch-verification: ON
15663  *
15664  * Local Variables:
15665  * eval: (c-set-style "gnu")
15666  * End:
15667  */