VPP-323: Add LISP locator set index to reply API message
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558
1559 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1560   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1610   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1644   (vl_api_gre_add_del_tunnel_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->sw_if_index = ntohl (mp->sw_if_index);
1673       vam->result_ready = 1;
1674     }
1675 }
1676
1677 static void vl_api_create_vhost_user_if_reply_t_handler_json
1678   (vl_api_create_vhost_user_if_reply_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   vat_json_node_t node;
1682
1683   vat_json_init_object (&node);
1684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1685   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_ip_address_details_t_handler
1695   (vl_api_ip_address_details_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   static ip_address_details_t empty_ip_address_details = { {0} };
1699   ip_address_details_t *address = NULL;
1700   ip_details_t *current_ip_details = NULL;
1701   ip_details_t *details = NULL;
1702
1703   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1704
1705   if (!details || vam->current_sw_if_index >= vec_len (details)
1706       || !details[vam->current_sw_if_index].present)
1707     {
1708       errmsg ("ip address details arrived but not stored\n");
1709       errmsg ("ip_dump should be called first\n");
1710       return;
1711     }
1712
1713   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1714
1715 #define addresses (current_ip_details->addr)
1716
1717   vec_validate_init_empty (addresses, vec_len (addresses),
1718                            empty_ip_address_details);
1719
1720   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1721
1722   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1723   address->prefix_length = mp->prefix_length;
1724 #undef addresses
1725 }
1726
1727 static void vl_api_ip_address_details_t_handler_json
1728   (vl_api_ip_address_details_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   vat_json_node_t *node = NULL;
1732   struct in6_addr ip6;
1733   struct in_addr ip4;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   node = vat_json_array_add (&vam->json_tree);
1741
1742   vat_json_init_object (node);
1743   if (vam->is_ipv6)
1744     {
1745       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1746       vat_json_object_add_ip6 (node, "ip", ip6);
1747     }
1748   else
1749     {
1750       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1751       vat_json_object_add_ip4 (node, "ip", ip4);
1752     }
1753   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1754 }
1755
1756 static void
1757 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   static ip_details_t empty_ip_details = { 0 };
1761   ip_details_t *ip = NULL;
1762   u32 sw_if_index = ~0;
1763
1764   sw_if_index = ntohl (mp->sw_if_index);
1765
1766   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1767                            sw_if_index, empty_ip_details);
1768
1769   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1770                          sw_if_index);
1771
1772   ip->present = 1;
1773 }
1774
1775 static void
1776 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   vat_json_array_add_uint (&vam->json_tree,
1786                            clib_net_to_host_u32 (mp->sw_if_index));
1787 }
1788
1789 static void vl_api_map_domain_details_t_handler_json
1790   (vl_api_map_domain_details_t * mp)
1791 {
1792   vat_json_node_t *node = NULL;
1793   vat_main_t *vam = &vat_main;
1794   struct in6_addr ip6;
1795   struct in_addr ip4;
1796
1797   if (VAT_JSON_ARRAY != vam->json_tree.type)
1798     {
1799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1800       vat_json_init_array (&vam->json_tree);
1801     }
1802
1803   node = vat_json_array_add (&vam->json_tree);
1804   vat_json_init_object (node);
1805
1806   vat_json_object_add_uint (node, "domain_index",
1807                             clib_net_to_host_u32 (mp->domain_index));
1808   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1809   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1810   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1811   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1812   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1813   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1814   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1815   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1816   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1817   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1818   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1819   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1820   vat_json_object_add_uint (node, "flags", mp->flags);
1821   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1822   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1823 }
1824
1825 static void vl_api_map_domain_details_t_handler
1826   (vl_api_map_domain_details_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829
1830   if (mp->is_translation)
1831     {
1832       fformat (vam->ofp,
1833                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1834                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1835                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1836                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1837                clib_net_to_host_u32 (mp->domain_index));
1838     }
1839   else
1840     {
1841       fformat (vam->ofp,
1842                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1843                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1844                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1845                format_ip6_address, mp->ip6_src,
1846                clib_net_to_host_u32 (mp->domain_index));
1847     }
1848   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1849            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1850            mp->is_translation ? "map-t" : "");
1851 }
1852
1853 static void vl_api_map_rule_details_t_handler_json
1854   (vl_api_map_rule_details_t * mp)
1855 {
1856   struct in6_addr ip6;
1857   vat_json_node_t *node = NULL;
1858   vat_main_t *vam = &vat_main;
1859
1860   if (VAT_JSON_ARRAY != vam->json_tree.type)
1861     {
1862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1863       vat_json_init_array (&vam->json_tree);
1864     }
1865
1866   node = vat_json_array_add (&vam->json_tree);
1867   vat_json_init_object (node);
1868
1869   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1870   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1871   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1872 }
1873
1874 static void
1875 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1879            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1880 }
1881
1882 static void
1883 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1887           "router_addr %U host_mac %U\n",
1888           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1889           format_ip4_address, &mp->host_address,
1890           format_ip4_address, &mp->router_address,
1891           format_ethernet_address, mp->host_mac);
1892 }
1893
1894 static void vl_api_dhcp_compl_event_t_handler_json
1895   (vl_api_dhcp_compl_event_t * mp)
1896 {
1897   /* JSON output not supported */
1898 }
1899
1900 static void
1901 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1902                               u32 counter)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   static u64 default_counter = 0;
1906
1907   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1908                            NULL);
1909   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1910                            sw_if_index, default_counter);
1911   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1912 }
1913
1914 static void
1915 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1916                                 interface_counter_t counter)
1917 {
1918   vat_main_t *vam = &vat_main;
1919   static interface_counter_t default_counter = { 0, };
1920
1921   vec_validate_init_empty (vam->combined_interface_counters,
1922                            vnet_counter_type, NULL);
1923   vec_validate_init_empty (vam->combined_interface_counters
1924                            [vnet_counter_type], sw_if_index, default_counter);
1925   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1926 }
1927
1928 static void vl_api_vnet_interface_counters_t_handler
1929   (vl_api_vnet_interface_counters_t * mp)
1930 {
1931   /* not supported */
1932 }
1933
1934 static void vl_api_vnet_interface_counters_t_handler_json
1935   (vl_api_vnet_interface_counters_t * mp)
1936 {
1937   interface_counter_t counter;
1938   vlib_counter_t *v;
1939   u64 *v_packets;
1940   u64 packets;
1941   u32 count;
1942   u32 first_sw_if_index;
1943   int i;
1944
1945   count = ntohl (mp->count);
1946   first_sw_if_index = ntohl (mp->first_sw_if_index);
1947
1948   if (!mp->is_combined)
1949     {
1950       v_packets = (u64 *) & mp->data;
1951       for (i = 0; i < count; i++)
1952         {
1953           packets =
1954             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1955           set_simple_interface_counter (mp->vnet_counter_type,
1956                                         first_sw_if_index + i, packets);
1957           v_packets++;
1958         }
1959     }
1960   else
1961     {
1962       v = (vlib_counter_t *) & mp->data;
1963       for (i = 0; i < count; i++)
1964         {
1965           counter.packets =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1967           counter.bytes =
1968             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1969           set_combined_interface_counter (mp->vnet_counter_type,
1970                                           first_sw_if_index + i, counter);
1971           v++;
1972         }
1973     }
1974 }
1975
1976 static u32
1977 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   u32 i;
1981
1982   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1983     {
1984       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1985         {
1986           return i;
1987         }
1988     }
1989   return ~0;
1990 }
1991
1992 static u32
1993 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static void vl_api_vnet_ip4_fib_counters_t_handler
2009   (vl_api_vnet_ip4_fib_counters_t * mp)
2010 {
2011   /* not supported */
2012 }
2013
2014 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2015   (vl_api_vnet_ip4_fib_counters_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vl_api_ip4_fib_counter_t *v;
2019   ip4_fib_counter_t *counter;
2020   struct in_addr ip4;
2021   u32 vrf_id;
2022   u32 vrf_index;
2023   u32 count;
2024   int i;
2025
2026   vrf_id = ntohl (mp->vrf_id);
2027   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2028   if (~0 == vrf_index)
2029     {
2030       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2031       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2032       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2033       vec_validate (vam->ip4_fib_counters, vrf_index);
2034       vam->ip4_fib_counters[vrf_index] = NULL;
2035     }
2036
2037   vec_free (vam->ip4_fib_counters[vrf_index]);
2038   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2039   count = ntohl (mp->count);
2040   for (i = 0; i < count; i++)
2041     {
2042       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2043       counter = &vam->ip4_fib_counters[vrf_index][i];
2044       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2045       counter->address = ip4;
2046       counter->address_length = v->address_length;
2047       counter->packets = clib_net_to_host_u64 (v->packets);
2048       counter->bytes = clib_net_to_host_u64 (v->bytes);
2049       v++;
2050     }
2051 }
2052
2053 static void vl_api_vnet_ip6_fib_counters_t_handler
2054   (vl_api_vnet_ip6_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2060   (vl_api_vnet_ip6_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip6_fib_counter_t *v;
2064   ip6_fib_counter_t *counter;
2065   struct in6_addr ip6;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip6_fib_counters, vrf_index);
2079       vam->ip6_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip6_fib_counters[vrf_index]);
2083   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2088       counter = &vam->ip6_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2090       counter->address = ip6;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_get_first_msg_id_reply_t_handler
2099   (vl_api_get_first_msg_id_reply_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102   i32 retval = ntohl (mp->retval);
2103
2104   if (vam->async_mode)
2105     {
2106       vam->async_errors += (retval < 0);
2107     }
2108   else
2109     {
2110       vam->retval = retval;
2111       vam->result_ready = 1;
2112     }
2113   if (retval >= 0)
2114     {
2115       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2116     }
2117 }
2118
2119 static void vl_api_get_first_msg_id_reply_t_handler_json
2120   (vl_api_get_first_msg_id_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t node;
2124
2125   vat_json_init_object (&node);
2126   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2127   vat_json_object_add_uint (&node, "first_msg_id",
2128                             (uint) ntohs (mp->first_msg_id));
2129
2130   vat_json_print (vam->ofp, &node);
2131   vat_json_free (&node);
2132
2133   vam->retval = ntohl (mp->retval);
2134   vam->result_ready = 1;
2135 }
2136
2137 static void vl_api_get_node_graph_reply_t_handler
2138   (vl_api_get_node_graph_reply_t * mp)
2139 {
2140   vat_main_t *vam = &vat_main;
2141   api_main_t *am = &api_main;
2142   i32 retval = ntohl (mp->retval);
2143   u8 *pvt_copy, *reply;
2144   void *oldheap;
2145   vlib_node_t *node;
2146   int i;
2147
2148   if (vam->async_mode)
2149     {
2150       vam->async_errors += (retval < 0);
2151     }
2152   else
2153     {
2154       vam->retval = retval;
2155       vam->result_ready = 1;
2156     }
2157
2158   /* "Should never happen..." */
2159   if (retval != 0)
2160     return;
2161
2162   reply = (u8 *) (mp->reply_in_shmem);
2163   pvt_copy = vec_dup (reply);
2164
2165   /* Toss the shared-memory original... */
2166   pthread_mutex_lock (&am->vlib_rp->mutex);
2167   oldheap = svm_push_data_heap (am->vlib_rp);
2168
2169   vec_free (reply);
2170
2171   svm_pop_heap (oldheap);
2172   pthread_mutex_unlock (&am->vlib_rp->mutex);
2173
2174   if (vam->graph_nodes)
2175     {
2176       hash_free (vam->graph_node_index_by_name);
2177
2178       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2179         {
2180           node = vam->graph_nodes[i];
2181           vec_free (node->name);
2182           vec_free (node->next_nodes);
2183           vec_free (node);
2184         }
2185       vec_free (vam->graph_nodes);
2186     }
2187
2188   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2189   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2190   vec_free (pvt_copy);
2191
2192   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2193     {
2194       node = vam->graph_nodes[i];
2195       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2196     }
2197 }
2198
2199 static void vl_api_get_node_graph_reply_t_handler_json
2200   (vl_api_get_node_graph_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   api_main_t *am = &api_main;
2204   void *oldheap;
2205   vat_json_node_t node;
2206   u8 *reply;
2207
2208   /* $$$$ make this real? */
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2212
2213   reply = (u8 *) (mp->reply_in_shmem);
2214
2215   /* Toss the shared-memory original... */
2216   pthread_mutex_lock (&am->vlib_rp->mutex);
2217   oldheap = svm_push_data_heap (am->vlib_rp);
2218
2219   vec_free (reply);
2220
2221   svm_pop_heap (oldheap);
2222   pthread_mutex_unlock (&am->vlib_rp->mutex);
2223
2224   vat_json_print (vam->ofp, &node);
2225   vat_json_free (&node);
2226
2227   vam->retval = ntohl (mp->retval);
2228   vam->result_ready = 1;
2229 }
2230
2231 static void
2232 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   locator_msg_t loc;
2236   u8 *tmp_str = 0;
2237
2238   memset (&loc, 0, sizeof (loc));
2239   if (vam->noprint_msg)
2240     {
2241       loc.local = mp->local;
2242       loc.priority = mp->priority;
2243       loc.weight = mp->weight;
2244       if (loc.local)
2245         {
2246           loc.sw_if_index = ntohl (mp->sw_if_index);
2247         }
2248       else
2249         {
2250           loc.is_ipv6 = mp->is_ipv6;
2251           clib_memcpy (loc.ip_address, mp->ip_address,
2252                        sizeof (loc.ip_address));
2253         }
2254       vec_add1 (vam->locator_msg, loc);
2255     }
2256   else
2257     {
2258       if (mp->local)
2259         {
2260           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2261                             ntohl (mp->sw_if_index),
2262                             mp->priority, mp->weight);
2263         }
2264       else
2265         {
2266           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2267                             mp->is_ipv6 ? format_ip6_address :
2268                             format_ip4_address,
2269                             mp->ip_address, mp->priority, mp->weight);
2270         }
2271
2272       fformat (vam->ofp, "%s", tmp_str);
2273
2274       vec_free (tmp_str);
2275     }
2276 }
2277
2278 static void
2279 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2280                                             mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t *node = NULL;
2284   locator_msg_t loc;
2285   struct in6_addr ip6;
2286   struct in_addr ip4;
2287
2288   memset (&loc, 0, sizeof (loc));
2289   if (vam->noprint_msg)
2290     {
2291       loc.local = mp->local;
2292       loc.priority = mp->priority;
2293       loc.weight = mp->weight;
2294       if (loc.local)
2295         {
2296           loc.sw_if_index = ntohl (mp->sw_if_index);
2297         }
2298       else
2299         {
2300           loc.is_ipv6 = mp->is_ipv6;
2301           clib_memcpy (loc.ip_address, mp->ip_address,
2302                        sizeof (loc.ip_address));
2303         }
2304       vec_add1 (vam->locator_msg, loc);
2305       return;
2306     }
2307
2308   if (VAT_JSON_ARRAY != vam->json_tree.type)
2309     {
2310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2311       vat_json_init_array (&vam->json_tree);
2312     }
2313   node = vat_json_array_add (&vam->json_tree);
2314
2315   vat_json_init_object (node);
2316
2317   if (mp->local)
2318     {
2319       vat_json_object_add_uint (node, "locator_index",
2320                                 ntohl (mp->sw_if_index));
2321     }
2322   else
2323     {
2324       if (mp->is_ipv6)
2325         {
2326           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2327           vat_json_object_add_ip6 (node, "locator", ip6);
2328         }
2329       else
2330         {
2331           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2332           vat_json_object_add_ip4 (node, "locator", ip4);
2333         }
2334     }
2335   vat_json_object_add_uint (node, "priority", mp->priority);
2336   vat_json_object_add_uint (node, "weight", mp->weight);
2337 }
2338
2339 static void
2340 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2341                                            mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   locator_set_msg_t ls;
2345
2346   ls.locator_set_index = ntohl (mp->locator_set_index);
2347   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2348   vec_add1 (vam->locator_set_msg, ls);
2349 }
2350
2351 static void
2352   vl_api_lisp_locator_set_details_t_handler_json
2353   (vl_api_lisp_locator_set_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   locator_set_msg_t ls;
2357
2358   ls.locator_set_index = ntohl (mp->locator_set_index);
2359   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2360   vec_add1 (vam->locator_set_msg, ls);
2361 }
2362
2363 static void
2364 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   eid_table_t eid_table;
2368
2369   memset (&eid_table, 0, sizeof (eid_table));
2370   eid_table.is_local = mp->is_local;
2371   eid_table.locator_set_index = mp->locator_set_index;
2372   eid_table.eid_type = mp->eid_type;
2373   eid_table.vni = mp->vni;
2374   eid_table.eid_prefix_len = mp->eid_prefix_len;
2375   eid_table.ttl = mp->ttl;
2376   eid_table.authoritative = mp->authoritative;
2377   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2378   vec_add1 (vam->eid_tables, eid_table);
2379 }
2380
2381 static void
2382 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2383                                               * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   eid_table_t eid_table;
2387
2388   memset (&eid_table, 0, sizeof (eid_table));
2389   eid_table.is_local = mp->is_local;
2390   eid_table.locator_set_index = mp->locator_set_index;
2391   eid_table.eid_type = mp->eid_type;
2392   eid_table.vni = mp->vni;
2393   eid_table.eid_prefix_len = mp->eid_prefix_len;
2394   eid_table.ttl = mp->ttl;
2395   eid_table.authoritative = mp->authoritative;
2396   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2397   vec_add1 (vam->eid_tables, eid_table);
2398 }
2399
2400 static void
2401   vl_api_lisp_eid_table_map_details_t_handler
2402   (vl_api_lisp_eid_table_map_details_t * mp)
2403 {
2404   vat_main_t *vam = &vat_main;
2405
2406   u8 *line = format (0, "%=10d%=10d",
2407                      clib_net_to_host_u32 (mp->vni),
2408                      clib_net_to_host_u32 (mp->vrf));
2409   fformat (vam->ofp, "%v\n", line);
2410   vec_free (line);
2411 }
2412
2413 static void
2414   vl_api_lisp_eid_table_map_details_t_handler_json
2415   (vl_api_lisp_eid_table_map_details_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t *node = NULL;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426   vat_json_init_object (node);
2427   vat_json_object_add_uint (node, "vrf", clib_net_to_host_u32 (mp->vrf));
2428   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2429 }
2430
2431
2432
2433 static u8 *
2434 format_decap_next (u8 * s, va_list * args)
2435 {
2436   u32 next_index = va_arg (*args, u32);
2437
2438   switch (next_index)
2439     {
2440     case LISP_GPE_INPUT_NEXT_DROP:
2441       return format (s, "drop");
2442     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2443       return format (s, "ip4");
2444     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2445       return format (s, "ip6");
2446     default:
2447       return format (s, "unknown %d", next_index);
2448     }
2449   return s;
2450 }
2451
2452 static void
2453 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2454                                           mp)
2455 {
2456   vat_main_t *vam = &vat_main;
2457   u8 *iid_str;
2458   u8 *flag_str = NULL;
2459
2460   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2461
2462 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2463   foreach_lisp_gpe_flag_bit;
2464 #undef _
2465
2466   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2467            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2468            mp->tunnels,
2469            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2470            mp->source_ip,
2471            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2472            mp->destination_ip,
2473            ntohl (mp->encap_fib_id),
2474            ntohl (mp->decap_fib_id),
2475            format_decap_next, ntohl (mp->dcap_next),
2476            mp->ver_res >> 6,
2477            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2478
2479   vec_free (iid_str);
2480 }
2481
2482 static void
2483   vl_api_lisp_gpe_tunnel_details_t_handler_json
2484   (vl_api_lisp_gpe_tunnel_details_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   vat_json_node_t *node = NULL;
2488   struct in6_addr ip6;
2489   struct in_addr ip4;
2490   u8 *next_decap_str;
2491
2492   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2493
2494   if (VAT_JSON_ARRAY != vam->json_tree.type)
2495     {
2496       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2497       vat_json_init_array (&vam->json_tree);
2498     }
2499   node = vat_json_array_add (&vam->json_tree);
2500
2501   vat_json_init_object (node);
2502   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2503   if (mp->is_ipv6)
2504     {
2505       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2506       vat_json_object_add_ip6 (node, "source address", ip6);
2507       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2508       vat_json_object_add_ip6 (node, "destination address", ip6);
2509     }
2510   else
2511     {
2512       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2513       vat_json_object_add_ip4 (node, "source address", ip4);
2514       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2515       vat_json_object_add_ip4 (node, "destination address", ip4);
2516     }
2517   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2518   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2519   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2520   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2521   vat_json_object_add_uint (node, "flags", mp->flags);
2522   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2523   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2524   vat_json_object_add_uint (node, "res", mp->res);
2525   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2526
2527   vec_free (next_decap_str);
2528 }
2529
2530 static void
2531 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2532                                             * mp)
2533 {
2534   vat_main_t *vam = &vat_main;
2535
2536   fformat (vam->ofp, "%=20U\n",
2537            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2538            mp->ip_address);
2539 }
2540
2541 static void
2542   vl_api_lisp_map_resolver_details_t_handler_json
2543   (vl_api_lisp_map_resolver_details_t * mp)
2544 {
2545   vat_main_t *vam = &vat_main;
2546   vat_json_node_t *node = NULL;
2547   struct in6_addr ip6;
2548   struct in_addr ip4;
2549
2550   if (VAT_JSON_ARRAY != vam->json_tree.type)
2551     {
2552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2553       vat_json_init_array (&vam->json_tree);
2554     }
2555   node = vat_json_array_add (&vam->json_tree);
2556
2557   vat_json_init_object (node);
2558   if (mp->is_ipv6)
2559     {
2560       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2561       vat_json_object_add_ip6 (node, "map resolver", ip6);
2562     }
2563   else
2564     {
2565       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2566       vat_json_object_add_ip4 (node, "map resolver", ip4);
2567     }
2568 }
2569
2570 static void
2571   vl_api_show_lisp_status_reply_t_handler
2572   (vl_api_show_lisp_status_reply_t * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   i32 retval = ntohl (mp->retval);
2576
2577   if (0 <= retval)
2578     {
2579       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2580                mp->feature_status ? "enabled" : "disabled",
2581                mp->gpe_status ? "enabled" : "disabled");
2582     }
2583
2584   vam->retval = retval;
2585   vam->result_ready = 1;
2586 }
2587
2588 static void
2589   vl_api_show_lisp_status_reply_t_handler_json
2590   (vl_api_show_lisp_status_reply_t * mp)
2591 {
2592   vat_main_t *vam = &vat_main;
2593   vat_json_node_t node;
2594   u8 *gpe_status = NULL;
2595   u8 *feature_status = NULL;
2596
2597   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2598   feature_status = format (0, "%s",
2599                            mp->feature_status ? "enabled" : "disabled");
2600   vec_add1 (gpe_status, 0);
2601   vec_add1 (feature_status, 0);
2602
2603   vat_json_init_object (&node);
2604   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2605   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2606
2607   vec_free (gpe_status);
2608   vec_free (feature_status);
2609
2610   vat_json_print (vam->ofp, &node);
2611   vat_json_free (&node);
2612
2613   vam->retval = ntohl (mp->retval);
2614   vam->result_ready = 1;
2615 }
2616
2617 static void
2618   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2619   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2620 {
2621   vat_main_t *vam = &vat_main;
2622   i32 retval = ntohl (mp->retval);
2623
2624   if (retval >= 0)
2625     {
2626       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2627     }
2628
2629   vam->retval = retval;
2630   vam->result_ready = 1;
2631 }
2632
2633 static void
2634   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2635   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2636 {
2637   vat_main_t *vam = &vat_main;
2638   vat_json_node_t *node = NULL;
2639
2640   if (VAT_JSON_ARRAY != vam->json_tree.type)
2641     {
2642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2643       vat_json_init_array (&vam->json_tree);
2644     }
2645   node = vat_json_array_add (&vam->json_tree);
2646
2647   vat_json_init_object (node);
2648   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2649
2650   vat_json_print (vam->ofp, node);
2651   vat_json_free (node);
2652
2653   vam->retval = ntohl (mp->retval);
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   i32 retval = ntohl (mp->retval);
2662
2663   if (0 <= retval)
2664     {
2665       fformat (vam->ofp, "%-20s%-16s\n",
2666                mp->status ? "enabled" : "disabled",
2667                mp->status ? (char *) mp->locator_set_name : "");
2668     }
2669
2670   vam->retval = retval;
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2676                                             mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   vat_json_node_t node;
2680   u8 *status = 0;
2681
2682   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2683   vec_add1 (status, 0);
2684
2685   vat_json_init_object (&node);
2686   vat_json_object_add_string_copy (&node, "status", status);
2687   if (mp->status)
2688     {
2689       vat_json_object_add_string_copy (&node, "locator_set",
2690                                        mp->locator_set_name);
2691     }
2692
2693   vec_free (status);
2694
2695   vat_json_print (vam->ofp, &node);
2696   vat_json_free (&node);
2697
2698   vam->retval = ntohl (mp->retval);
2699   vam->result_ready = 1;
2700 }
2701
2702 static u8 *
2703 format_policer_type (u8 * s, va_list * va)
2704 {
2705   u32 i = va_arg (*va, u32);
2706
2707   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2708     s = format (s, "1r2c");
2709   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2710     s = format (s, "1r3c");
2711   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2712     s = format (s, "2r3c-2698");
2713   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2714     s = format (s, "2r3c-4115");
2715   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2716     s = format (s, "2r3c-mef5cf1");
2717   else
2718     s = format (s, "ILLEGAL");
2719   return s;
2720 }
2721
2722 static u8 *
2723 format_policer_rate_type (u8 * s, va_list * va)
2724 {
2725   u32 i = va_arg (*va, u32);
2726
2727   if (i == SSE2_QOS_RATE_KBPS)
2728     s = format (s, "kbps");
2729   else if (i == SSE2_QOS_RATE_PPS)
2730     s = format (s, "pps");
2731   else
2732     s = format (s, "ILLEGAL");
2733   return s;
2734 }
2735
2736 static u8 *
2737 format_policer_round_type (u8 * s, va_list * va)
2738 {
2739   u32 i = va_arg (*va, u32);
2740
2741   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2742     s = format (s, "closest");
2743   else if (i == SSE2_QOS_ROUND_TO_UP)
2744     s = format (s, "up");
2745   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2746     s = format (s, "down");
2747   else
2748     s = format (s, "ILLEGAL");
2749   return s;
2750 }
2751
2752 static u8 *
2753 format_policer_action_type (u8 * s, va_list * va)
2754 {
2755   u32 i = va_arg (*va, u32);
2756
2757   if (i == SSE2_QOS_ACTION_DROP)
2758     s = format (s, "drop");
2759   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2760     s = format (s, "transmit");
2761   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2762     s = format (s, "mark-and-transmit");
2763   else
2764     s = format (s, "ILLEGAL");
2765   return s;
2766 }
2767
2768 static u8 *
2769 format_dscp (u8 * s, va_list * va)
2770 {
2771   u32 i = va_arg (*va, u32);
2772   char *t = 0;
2773
2774   switch (i)
2775     {
2776 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2777       foreach_vnet_dscp
2778 #undef _
2779     default:
2780       return format (s, "ILLEGAL");
2781     }
2782   s = format (s, "%s", t);
2783   return s;
2784 }
2785
2786 static void
2787 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2791
2792   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2793     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2794   else
2795     conform_dscp_str = format (0, "");
2796
2797   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2798     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2799   else
2800     exceed_dscp_str = format (0, "");
2801
2802   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2803     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2804   else
2805     violate_dscp_str = format (0, "");
2806
2807   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2808            "rate type %U, round type %U, %s rate, %s color-aware, "
2809            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2810            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2811            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2812            mp->name,
2813            format_policer_type, mp->type,
2814            ntohl (mp->cir),
2815            ntohl (mp->eir),
2816            clib_net_to_host_u64 (mp->cb),
2817            clib_net_to_host_u64 (mp->eb),
2818            format_policer_rate_type, mp->rate_type,
2819            format_policer_round_type, mp->round_type,
2820            mp->single_rate ? "single" : "dual",
2821            mp->color_aware ? "is" : "not",
2822            ntohl (mp->cir_tokens_per_period),
2823            ntohl (mp->pir_tokens_per_period),
2824            ntohl (mp->scale),
2825            ntohl (mp->current_limit),
2826            ntohl (mp->current_bucket),
2827            ntohl (mp->extended_limit),
2828            ntohl (mp->extended_bucket),
2829            clib_net_to_host_u64 (mp->last_update_time),
2830            format_policer_action_type, mp->conform_action_type,
2831            conform_dscp_str,
2832            format_policer_action_type, mp->exceed_action_type,
2833            exceed_dscp_str,
2834            format_policer_action_type, mp->violate_action_type,
2835            violate_dscp_str);
2836
2837   vec_free (conform_dscp_str);
2838   vec_free (exceed_dscp_str);
2839   vec_free (violate_dscp_str);
2840 }
2841
2842 static void vl_api_policer_details_t_handler_json
2843   (vl_api_policer_details_t * mp)
2844 {
2845   vat_main_t *vam = &vat_main;
2846   vat_json_node_t *node;
2847   u8 *rate_type_str, *round_type_str, *type_str;
2848   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2849
2850   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2851   round_type_str =
2852     format (0, "%U", format_policer_round_type, mp->round_type);
2853   type_str = format (0, "%U", format_policer_type, mp->type);
2854   conform_action_str = format (0, "%U", format_policer_action_type,
2855                                mp->conform_action_type);
2856   exceed_action_str = format (0, "%U", format_policer_action_type,
2857                               mp->exceed_action_type);
2858   violate_action_str = format (0, "%U", format_policer_action_type,
2859                                mp->violate_action_type);
2860
2861   if (VAT_JSON_ARRAY != vam->json_tree.type)
2862     {
2863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2864       vat_json_init_array (&vam->json_tree);
2865     }
2866   node = vat_json_array_add (&vam->json_tree);
2867
2868   vat_json_init_object (node);
2869   vat_json_object_add_string_copy (node, "name", mp->name);
2870   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2871   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2872   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2873   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2874   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2875   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2876   vat_json_object_add_string_copy (node, "type", type_str);
2877   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2878   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2879   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2880   vat_json_object_add_uint (node, "cir_tokens_per_period",
2881                             ntohl (mp->cir_tokens_per_period));
2882   vat_json_object_add_uint (node, "eir_tokens_per_period",
2883                             ntohl (mp->pir_tokens_per_period));
2884   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2885   vat_json_object_add_uint (node, "current_bucket",
2886                             ntohl (mp->current_bucket));
2887   vat_json_object_add_uint (node, "extended_limit",
2888                             ntohl (mp->extended_limit));
2889   vat_json_object_add_uint (node, "extended_bucket",
2890                             ntohl (mp->extended_bucket));
2891   vat_json_object_add_uint (node, "last_update_time",
2892                             ntohl (mp->last_update_time));
2893   vat_json_object_add_string_copy (node, "conform_action",
2894                                    conform_action_str);
2895   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2896     {
2897       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2898       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2899       vec_free (dscp_str);
2900     }
2901   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2902   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2903     {
2904       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2905       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2906       vec_free (dscp_str);
2907     }
2908   vat_json_object_add_string_copy (node, "violate_action",
2909                                    violate_action_str);
2910   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2911     {
2912       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2913       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2914       vec_free (dscp_str);
2915     }
2916
2917   vec_free (rate_type_str);
2918   vec_free (round_type_str);
2919   vec_free (type_str);
2920   vec_free (conform_action_str);
2921   vec_free (exceed_action_str);
2922   vec_free (violate_action_str);
2923 }
2924
2925 static void
2926 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2927                                            mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   int i, count = ntohl (mp->count);
2931
2932   if (count > 0)
2933     fformat (vam->ofp, "classify table ids (%d) : ", count);
2934   for (i = 0; i < count; i++)
2935     {
2936       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2937       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2938     }
2939   vam->retval = ntohl (mp->retval);
2940   vam->result_ready = 1;
2941 }
2942
2943 static void
2944   vl_api_classify_table_ids_reply_t_handler_json
2945   (vl_api_classify_table_ids_reply_t * mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   int i, count = ntohl (mp->count);
2949
2950   if (count > 0)
2951     {
2952       vat_json_node_t node;
2953
2954       vat_json_init_object (&node);
2955       for (i = 0; i < count; i++)
2956         {
2957           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2958         }
2959       vat_json_print (vam->ofp, &node);
2960       vat_json_free (&node);
2961     }
2962   vam->retval = ntohl (mp->retval);
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_classify_table_by_interface_reply_t_handler
2968   (vl_api_classify_table_by_interface_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   u32 table_id;
2972
2973   table_id = ntohl (mp->l2_table_id);
2974   if (table_id != ~0)
2975     fformat (vam->ofp, "l2 table id : %d\n", table_id);
2976   else
2977     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2978   table_id = ntohl (mp->ip4_table_id);
2979   if (table_id != ~0)
2980     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2981   else
2982     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2983   table_id = ntohl (mp->ip6_table_id);
2984   if (table_id != ~0)
2985     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2986   else
2987     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2988   vam->retval = ntohl (mp->retval);
2989   vam->result_ready = 1;
2990 }
2991
2992 static void
2993   vl_api_classify_table_by_interface_reply_t_handler_json
2994   (vl_api_classify_table_by_interface_reply_t * mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   vat_json_node_t node;
2998
2999   vat_json_init_object (&node);
3000
3001   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3002   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3003   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3004
3005   vat_json_print (vam->ofp, &node);
3006   vat_json_free (&node);
3007
3008   vam->retval = ntohl (mp->retval);
3009   vam->result_ready = 1;
3010 }
3011
3012 static void vl_api_policer_add_del_reply_t_handler
3013   (vl_api_policer_add_del_reply_t * mp)
3014 {
3015   vat_main_t *vam = &vat_main;
3016   i32 retval = ntohl (mp->retval);
3017   if (vam->async_mode)
3018     {
3019       vam->async_errors += (retval < 0);
3020     }
3021   else
3022     {
3023       vam->retval = retval;
3024       vam->result_ready = 1;
3025       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3026         /*
3027          * Note: this is just barely thread-safe, depends on
3028          * the main thread spinning waiting for an answer...
3029          */
3030         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3031     }
3032 }
3033
3034 static void vl_api_policer_add_del_reply_t_handler_json
3035   (vl_api_policer_add_del_reply_t * mp)
3036 {
3037   vat_main_t *vam = &vat_main;
3038   vat_json_node_t node;
3039
3040   vat_json_init_object (&node);
3041   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3042   vat_json_object_add_uint (&node, "policer_index",
3043                             ntohl (mp->policer_index));
3044
3045   vat_json_print (vam->ofp, &node);
3046   vat_json_free (&node);
3047
3048   vam->retval = ntohl (mp->retval);
3049   vam->result_ready = 1;
3050 }
3051
3052 /* Format hex dump. */
3053 u8 *
3054 format_hex_bytes (u8 * s, va_list * va)
3055 {
3056   u8 *bytes = va_arg (*va, u8 *);
3057   int n_bytes = va_arg (*va, int);
3058   uword i;
3059
3060   /* Print short or long form depending on byte count. */
3061   uword short_form = n_bytes <= 32;
3062   uword indent = format_get_indent (s);
3063
3064   if (n_bytes == 0)
3065     return s;
3066
3067   for (i = 0; i < n_bytes; i++)
3068     {
3069       if (!short_form && (i % 32) == 0)
3070         s = format (s, "%08x: ", i);
3071       s = format (s, "%02x", bytes[i]);
3072       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3073         s = format (s, "\n%U", format_white_space, indent);
3074     }
3075
3076   return s;
3077 }
3078
3079 static void
3080 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3081                                             * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   i32 retval = ntohl (mp->retval);
3085   if (retval == 0)
3086     {
3087       fformat (vam->ofp, "classify table info :\n");
3088       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3089                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3090                ntohl (mp->miss_next_index));
3091       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3092                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3093                ntohl (mp->match_n_vectors));
3094       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3095                ntohl (mp->mask_length));
3096     }
3097   vam->retval = retval;
3098   vam->result_ready = 1;
3099 }
3100
3101 static void
3102   vl_api_classify_table_info_reply_t_handler_json
3103   (vl_api_classify_table_info_reply_t * mp)
3104 {
3105   vat_main_t *vam = &vat_main;
3106   vat_json_node_t node;
3107
3108   i32 retval = ntohl (mp->retval);
3109   if (retval == 0)
3110     {
3111       vat_json_init_object (&node);
3112
3113       vat_json_object_add_int (&node, "sessions",
3114                                ntohl (mp->active_sessions));
3115       vat_json_object_add_int (&node, "nexttbl",
3116                                ntohl (mp->next_table_index));
3117       vat_json_object_add_int (&node, "nextnode",
3118                                ntohl (mp->miss_next_index));
3119       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3120       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3121       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3122       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3123                       ntohl (mp->mask_length), 0);
3124       vat_json_object_add_string_copy (&node, "mask", s);
3125
3126       vat_json_print (vam->ofp, &node);
3127       vat_json_free (&node);
3128     }
3129   vam->retval = ntohl (mp->retval);
3130   vam->result_ready = 1;
3131 }
3132
3133 static void
3134 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3135                                            mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138
3139   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3140            ntohl (mp->hit_next_index), ntohl (mp->advance),
3141            ntohl (mp->opaque_index));
3142   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3143            ntohl (mp->match_length));
3144 }
3145
3146 static void
3147   vl_api_classify_session_details_t_handler_json
3148   (vl_api_classify_session_details_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t *node = NULL;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159
3160   vat_json_init_object (node);
3161   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3162   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3163   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3164   u8 *s =
3165     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3166             0);
3167   vat_json_object_add_string_copy (node, "match", s);
3168 }
3169
3170 static void vl_api_pg_create_interface_reply_t_handler
3171   (vl_api_pg_create_interface_reply_t * mp)
3172 {
3173   vat_main_t *vam = &vat_main;
3174
3175   vam->retval = ntohl (mp->retval);
3176   vam->result_ready = 1;
3177 }
3178
3179 static void vl_api_pg_create_interface_reply_t_handler_json
3180   (vl_api_pg_create_interface_reply_t * mp)
3181 {
3182   vat_main_t *vam = &vat_main;
3183   vat_json_node_t node;
3184
3185   i32 retval = ntohl (mp->retval);
3186   if (retval == 0)
3187     {
3188       vat_json_init_object (&node);
3189
3190       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3191
3192       vat_json_print (vam->ofp, &node);
3193       vat_json_free (&node);
3194     }
3195   vam->retval = ntohl (mp->retval);
3196   vam->result_ready = 1;
3197 }
3198
3199 static void vl_api_policer_classify_details_t_handler
3200   (vl_api_policer_classify_details_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203
3204   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3205            ntohl (mp->table_index));
3206 }
3207
3208 static void vl_api_policer_classify_details_t_handler_json
3209   (vl_api_policer_classify_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220
3221   vat_json_init_object (node);
3222   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3223   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3224 }
3225
3226 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3227   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   i32 retval = ntohl (mp->retval);
3231   if (vam->async_mode)
3232     {
3233       vam->async_errors += (retval < 0);
3234     }
3235   else
3236     {
3237       vam->retval = retval;
3238       vam->sw_if_index = ntohl (mp->sw_if_index);
3239       vam->result_ready = 1;
3240     }
3241 }
3242
3243 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3244   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3245 {
3246   vat_main_t *vam = &vat_main;
3247   vat_json_node_t node;
3248
3249   vat_json_init_object (&node);
3250   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3251   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3252
3253   vat_json_print (vam->ofp, &node);
3254   vat_json_free (&node);
3255
3256   vam->retval = ntohl (mp->retval);
3257   vam->result_ready = 1;
3258 }
3259
3260 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3261 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3262 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3263 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3264
3265 /*
3266  * Generate boilerplate reply handlers, which
3267  * dig the return value out of the xxx_reply_t API message,
3268  * stick it into vam->retval, and set vam->result_ready
3269  *
3270  * Could also do this by pointing N message decode slots at
3271  * a single function, but that could break in subtle ways.
3272  */
3273
3274 #define foreach_standard_reply_retval_handler           \
3275 _(sw_interface_set_flags_reply)                         \
3276 _(sw_interface_add_del_address_reply)                   \
3277 _(sw_interface_set_table_reply)                         \
3278 _(sw_interface_set_vpath_reply)                         \
3279 _(sw_interface_set_l2_bridge_reply)                     \
3280 _(bridge_domain_add_del_reply)                          \
3281 _(sw_interface_set_l2_xconnect_reply)                   \
3282 _(l2fib_add_del_reply)                                  \
3283 _(ip_add_del_route_reply)                               \
3284 _(proxy_arp_add_del_reply)                              \
3285 _(proxy_arp_intfc_enable_disable_reply)                 \
3286 _(mpls_add_del_encap_reply)                             \
3287 _(mpls_add_del_decap_reply)                             \
3288 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3289 _(sw_interface_set_unnumbered_reply)                    \
3290 _(ip_neighbor_add_del_reply)                            \
3291 _(reset_vrf_reply)                                      \
3292 _(oam_add_del_reply)                                    \
3293 _(reset_fib_reply)                                      \
3294 _(dhcp_proxy_config_reply)                              \
3295 _(dhcp_proxy_config_2_reply)                            \
3296 _(dhcp_proxy_set_vss_reply)                             \
3297 _(dhcp_client_config_reply)                             \
3298 _(set_ip_flow_hash_reply)                               \
3299 _(sw_interface_ip6_enable_disable_reply)                \
3300 _(sw_interface_ip6_set_link_local_address_reply)        \
3301 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3302 _(sw_interface_ip6nd_ra_config_reply)                   \
3303 _(set_arp_neighbor_limit_reply)                         \
3304 _(l2_patch_add_del_reply)                               \
3305 _(sr_tunnel_add_del_reply)                              \
3306 _(sr_policy_add_del_reply)                              \
3307 _(sr_multicast_map_add_del_reply)                       \
3308 _(classify_add_del_session_reply)                       \
3309 _(classify_set_interface_ip_table_reply)                \
3310 _(classify_set_interface_l2_tables_reply)               \
3311 _(l2tpv3_set_tunnel_cookies_reply)                      \
3312 _(l2tpv3_interface_enable_disable_reply)                \
3313 _(l2tpv3_set_lookup_key_reply)                          \
3314 _(l2_fib_clear_table_reply)                             \
3315 _(l2_interface_efp_filter_reply)                        \
3316 _(l2_interface_vlan_tag_rewrite_reply)                  \
3317 _(modify_vhost_user_if_reply)                           \
3318 _(delete_vhost_user_if_reply)                           \
3319 _(want_ip4_arp_events_reply)                            \
3320 _(input_acl_set_interface_reply)                        \
3321 _(ipsec_spd_add_del_reply)                              \
3322 _(ipsec_interface_add_del_spd_reply)                    \
3323 _(ipsec_spd_add_del_entry_reply)                        \
3324 _(ipsec_sad_add_del_entry_reply)                        \
3325 _(ipsec_sa_set_key_reply)                               \
3326 _(ikev2_profile_add_del_reply)                          \
3327 _(ikev2_profile_set_auth_reply)                         \
3328 _(ikev2_profile_set_id_reply)                           \
3329 _(ikev2_profile_set_ts_reply)                           \
3330 _(ikev2_set_local_key_reply)                            \
3331 _(delete_loopback_reply)                                \
3332 _(bd_ip_mac_add_del_reply)                              \
3333 _(map_del_domain_reply)                                 \
3334 _(map_add_del_rule_reply)                               \
3335 _(want_interface_events_reply)                          \
3336 _(want_stats_reply)                                     \
3337 _(cop_interface_enable_disable_reply)                   \
3338 _(cop_whitelist_enable_disable_reply)                   \
3339 _(sw_interface_clear_stats_reply)                       \
3340 _(trace_profile_add_reply)                              \
3341 _(trace_profile_apply_reply)                            \
3342 _(trace_profile_del_reply)                              \
3343 _(lisp_add_del_locator_reply)                           \
3344 _(lisp_add_del_local_eid_reply)                         \
3345 _(lisp_add_del_remote_mapping_reply)                    \
3346 _(lisp_add_del_adjacency_reply)                         \
3347 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3348 _(lisp_add_del_map_resolver_reply)                      \
3349 _(lisp_gpe_enable_disable_reply)                        \
3350 _(lisp_gpe_add_del_iface_reply)                         \
3351 _(lisp_enable_disable_reply)                            \
3352 _(lisp_pitr_set_locator_set_reply)                      \
3353 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3354 _(lisp_eid_table_add_del_map_reply)                     \
3355 _(vxlan_gpe_add_del_tunnel_reply)                       \
3356 _(af_packet_delete_reply)                               \
3357 _(policer_classify_set_interface_reply)                 \
3358 _(netmap_create_reply)                                  \
3359 _(netmap_delete_reply)                                  \
3360 _(ipfix_enable_reply)                                   \
3361 _(pg_capture_reply)                                     \
3362 _(pg_enable_disable_reply)                              \
3363 _(ip_source_and_port_range_check_add_del_reply)         \
3364 _(ip_source_and_port_range_check_interface_add_del_reply)
3365
3366 #define _(n)                                    \
3367     static void vl_api_##n##_t_handler          \
3368     (vl_api_##n##_t * mp)                       \
3369     {                                           \
3370         vat_main_t * vam = &vat_main;           \
3371         i32 retval = ntohl(mp->retval);         \
3372         if (vam->async_mode) {                  \
3373             vam->async_errors += (retval < 0);  \
3374         } else {                                \
3375             vam->retval = retval;               \
3376             vam->result_ready = 1;              \
3377         }                                       \
3378     }
3379 foreach_standard_reply_retval_handler;
3380 #undef _
3381
3382 #define _(n)                                    \
3383     static void vl_api_##n##_t_handler_json     \
3384     (vl_api_##n##_t * mp)                       \
3385     {                                           \
3386         vat_main_t * vam = &vat_main;           \
3387         vat_json_node_t node;                   \
3388         vat_json_init_object(&node);            \
3389         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3390         vat_json_print(vam->ofp, &node);        \
3391         vam->retval = ntohl(mp->retval);        \
3392         vam->result_ready = 1;                  \
3393     }
3394 foreach_standard_reply_retval_handler;
3395 #undef _
3396
3397 /*
3398  * Table of message reply handlers, must include boilerplate handlers
3399  * we just generated
3400  */
3401
3402 #define foreach_vpe_api_reply_msg                                       \
3403 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3404 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3405 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3406 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3407 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3408 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3409 _(CLI_REPLY, cli_reply)                                                 \
3410 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3411   sw_interface_add_del_address_reply)                                   \
3412 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3413 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3414 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3415   sw_interface_set_l2_xconnect_reply)                                   \
3416 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3417   sw_interface_set_l2_bridge_reply)                                     \
3418 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3419 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3420 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3421 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3422 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3423 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3424 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3425 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3426 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3427 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3428 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3429 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3430 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3431   proxy_arp_intfc_enable_disable_reply)                                 \
3432 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3433 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3434 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3435 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3436   mpls_ethernet_add_del_tunnel_reply)                                   \
3437 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3438   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3439 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3440   sw_interface_set_unnumbered_reply)                                    \
3441 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3442 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3443 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3444 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3445 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3446 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3447 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3448 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3449 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3450 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3451 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3452 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3453   sw_interface_ip6_enable_disable_reply)                                \
3454 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3455   sw_interface_ip6_set_link_local_address_reply)                        \
3456 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3457   sw_interface_ip6nd_ra_prefix_reply)                                   \
3458 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3459   sw_interface_ip6nd_ra_config_reply)                                   \
3460 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3461 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3462 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3463 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3464 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3465 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3466 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3467 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3468 classify_set_interface_ip_table_reply)                                  \
3469 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3470   classify_set_interface_l2_tables_reply)                               \
3471 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3472 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3473 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3474 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3475 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3476   l2tpv3_interface_enable_disable_reply)                                \
3477 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3478 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3479 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3480 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3481 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3482 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3483 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3484 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3485 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3486 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3487 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3488 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3489 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3490 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3491 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3492 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3493 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3494 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3495 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3496 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3497 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3498 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3499 _(IP_DETAILS, ip_details)                                               \
3500 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3501 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3502 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3503 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3504 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3505 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3506 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3507 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3508 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3509 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3510 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3511 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3512 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3513 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3514 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3515 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3516 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3517 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3518 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3519 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3520 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3521 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3522 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3523 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3524 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3525 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3526 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3527 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3528 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3529 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3530 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3531 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3532 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3533 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3534 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3535 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3536 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3537 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3538 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3539 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3540 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3541 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3542 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3543 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3544 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3545 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3546 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3547 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3548 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3549 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3550 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3551   lisp_add_del_map_request_itr_rlocs_reply)                             \
3552 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3553   lisp_get_map_request_itr_rlocs_reply)                                 \
3554 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3555 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3556 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3557 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3558 _(POLICER_DETAILS, policer_details)                                     \
3559 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3560 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3561 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3562 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3563 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3564 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3565 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3566 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3567 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3568 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3569 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3570 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3571 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3572 _(IPFIX_DETAILS, ipfix_details)                                         \
3573 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3574 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3575 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3576 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3577 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3578  ip_source_and_port_range_check_add_del_reply)                          \
3579 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3580  ip_source_and_port_range_check_interface_add_del_reply)                \
3581 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3582 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)
3583
3584 /* M: construct, but don't yet send a message */
3585
3586 #define M(T,t)                                  \
3587 do {                                            \
3588     vam->result_ready = 0;                      \
3589     mp = vl_msg_api_alloc(sizeof(*mp));         \
3590     memset (mp, 0, sizeof (*mp));               \
3591     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3592     mp->client_index = vam->my_client_index;    \
3593 } while(0);
3594
3595 #define M2(T,t,n)                               \
3596 do {                                            \
3597     vam->result_ready = 0;                      \
3598     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3599     memset (mp, 0, sizeof (*mp));               \
3600     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3601     mp->client_index = vam->my_client_index;    \
3602 } while(0);
3603
3604
3605 /* S: send a message */
3606 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3607
3608 /* W: wait for results, with timeout */
3609 #define W                                       \
3610 do {                                            \
3611     timeout = vat_time_now (vam) + 1.0;         \
3612                                                 \
3613     while (vat_time_now (vam) < timeout) {      \
3614         if (vam->result_ready == 1) {           \
3615             return (vam->retval);               \
3616         }                                       \
3617     }                                           \
3618     return -99;                                 \
3619 } while(0);
3620
3621 /* W2: wait for results, with timeout */
3622 #define W2(body)                                \
3623 do {                                            \
3624     timeout = vat_time_now (vam) + 1.0;         \
3625                                                 \
3626     while (vat_time_now (vam) < timeout) {      \
3627         if (vam->result_ready == 1) {           \
3628           (body);                               \
3629           return (vam->retval);                 \
3630         }                                       \
3631     }                                           \
3632     return -99;                                 \
3633 } while(0);
3634
3635 /* W_L: wait for results, with timeout */
3636 #define W_L(body)                               \
3637 do {                                            \
3638     timeout = vat_time_now (vam) + 1.0;         \
3639                                                 \
3640     while (vat_time_now (vam) < timeout) {      \
3641         if (vam->result_ready == 1) {           \
3642           (body);                               \
3643           return (vam->retval);                 \
3644         }                                       \
3645     }                                           \
3646     vam->noprint_msg = 0;     \
3647     return -99;                                 \
3648 } while(0);
3649
3650 typedef struct
3651 {
3652   u8 *name;
3653   u32 value;
3654 } name_sort_t;
3655
3656
3657 #define STR_VTR_OP_CASE(op)     \
3658     case L2_VTR_ ## op:         \
3659         return "" # op;
3660
3661 static const char *
3662 str_vtr_op (u32 vtr_op)
3663 {
3664   switch (vtr_op)
3665     {
3666       STR_VTR_OP_CASE (DISABLED);
3667       STR_VTR_OP_CASE (PUSH_1);
3668       STR_VTR_OP_CASE (PUSH_2);
3669       STR_VTR_OP_CASE (POP_1);
3670       STR_VTR_OP_CASE (POP_2);
3671       STR_VTR_OP_CASE (TRANSLATE_1_1);
3672       STR_VTR_OP_CASE (TRANSLATE_1_2);
3673       STR_VTR_OP_CASE (TRANSLATE_2_1);
3674       STR_VTR_OP_CASE (TRANSLATE_2_2);
3675     }
3676
3677   return "UNKNOWN";
3678 }
3679
3680 static int
3681 dump_sub_interface_table (vat_main_t * vam)
3682 {
3683   const sw_interface_subif_t *sub = NULL;
3684
3685   if (vam->json_output)
3686     {
3687       clib_warning
3688         ("JSON output supported only for VPE API calls and dump_stats_table");
3689       return -99;
3690     }
3691
3692   fformat (vam->ofp,
3693            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3694            "Interface", "sw_if_index",
3695            "sub id", "dot1ad", "tags", "outer id",
3696            "inner id", "exact", "default", "outer any", "inner any");
3697
3698   vec_foreach (sub, vam->sw_if_subif_table)
3699   {
3700     fformat (vam->ofp,
3701              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3702              sub->interface_name,
3703              sub->sw_if_index,
3704              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3705              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3706              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3707              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3708     if (sub->vtr_op != L2_VTR_DISABLED)
3709       {
3710         fformat (vam->ofp,
3711                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3712                  "tag1: %d tag2: %d ]\n",
3713                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3714                  sub->vtr_tag1, sub->vtr_tag2);
3715       }
3716   }
3717
3718   return 0;
3719 }
3720
3721 static int
3722 name_sort_cmp (void *a1, void *a2)
3723 {
3724   name_sort_t *n1 = a1;
3725   name_sort_t *n2 = a2;
3726
3727   return strcmp ((char *) n1->name, (char *) n2->name);
3728 }
3729
3730 static int
3731 dump_interface_table (vat_main_t * vam)
3732 {
3733   hash_pair_t *p;
3734   name_sort_t *nses = 0, *ns;
3735
3736   if (vam->json_output)
3737     {
3738       clib_warning
3739         ("JSON output supported only for VPE API calls and dump_stats_table");
3740       return -99;
3741     }
3742
3743   /* *INDENT-OFF* */
3744   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3745   ({
3746     vec_add2 (nses, ns, 1);
3747     ns->name = (u8 *)(p->key);
3748     ns->value = (u32) p->value[0];
3749   }));
3750   /* *INDENT-ON* */
3751
3752   vec_sort_with_function (nses, name_sort_cmp);
3753
3754   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3755   vec_foreach (ns, nses)
3756   {
3757     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3758   }
3759   vec_free (nses);
3760   return 0;
3761 }
3762
3763 static int
3764 dump_ip_table (vat_main_t * vam, int is_ipv6)
3765 {
3766   const ip_details_t *det = NULL;
3767   const ip_address_details_t *address = NULL;
3768   u32 i = ~0;
3769
3770   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3771
3772   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3773   {
3774     i++;
3775     if (!det->present)
3776       {
3777         continue;
3778       }
3779     fformat (vam->ofp, "%-12d\n", i);
3780     fformat (vam->ofp,
3781              "            %-30s%-13s\n", "Address", "Prefix length");
3782     if (!det->addr)
3783       {
3784         continue;
3785       }
3786     vec_foreach (address, det->addr)
3787     {
3788       fformat (vam->ofp,
3789                "            %-30U%-13d\n",
3790                is_ipv6 ? format_ip6_address : format_ip4_address,
3791                address->ip, address->prefix_length);
3792     }
3793   }
3794
3795   return 0;
3796 }
3797
3798 static int
3799 dump_ipv4_table (vat_main_t * vam)
3800 {
3801   if (vam->json_output)
3802     {
3803       clib_warning
3804         ("JSON output supported only for VPE API calls and dump_stats_table");
3805       return -99;
3806     }
3807
3808   return dump_ip_table (vam, 0);
3809 }
3810
3811 static int
3812 dump_ipv6_table (vat_main_t * vam)
3813 {
3814   if (vam->json_output)
3815     {
3816       clib_warning
3817         ("JSON output supported only for VPE API calls and dump_stats_table");
3818       return -99;
3819     }
3820
3821   return dump_ip_table (vam, 1);
3822 }
3823
3824 static char *
3825 counter_type_to_str (u8 counter_type, u8 is_combined)
3826 {
3827   if (!is_combined)
3828     {
3829       switch (counter_type)
3830         {
3831         case VNET_INTERFACE_COUNTER_DROP:
3832           return "drop";
3833         case VNET_INTERFACE_COUNTER_PUNT:
3834           return "punt";
3835         case VNET_INTERFACE_COUNTER_IP4:
3836           return "ip4";
3837         case VNET_INTERFACE_COUNTER_IP6:
3838           return "ip6";
3839         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3840           return "rx-no-buf";
3841         case VNET_INTERFACE_COUNTER_RX_MISS:
3842           return "rx-miss";
3843         case VNET_INTERFACE_COUNTER_RX_ERROR:
3844           return "rx-error";
3845         case VNET_INTERFACE_COUNTER_TX_ERROR:
3846           return "tx-error";
3847         default:
3848           return "INVALID-COUNTER-TYPE";
3849         }
3850     }
3851   else
3852     {
3853       switch (counter_type)
3854         {
3855         case VNET_INTERFACE_COUNTER_RX:
3856           return "rx";
3857         case VNET_INTERFACE_COUNTER_TX:
3858           return "tx";
3859         default:
3860           return "INVALID-COUNTER-TYPE";
3861         }
3862     }
3863 }
3864
3865 static int
3866 dump_stats_table (vat_main_t * vam)
3867 {
3868   vat_json_node_t node;
3869   vat_json_node_t *msg_array;
3870   vat_json_node_t *msg;
3871   vat_json_node_t *counter_array;
3872   vat_json_node_t *counter;
3873   interface_counter_t c;
3874   u64 packets;
3875   ip4_fib_counter_t *c4;
3876   ip6_fib_counter_t *c6;
3877   int i, j;
3878
3879   if (!vam->json_output)
3880     {
3881       clib_warning ("dump_stats_table supported only in JSON format");
3882       return -99;
3883     }
3884
3885   vat_json_init_object (&node);
3886
3887   /* interface counters */
3888   msg_array = vat_json_object_add (&node, "interface_counters");
3889   vat_json_init_array (msg_array);
3890   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3891     {
3892       msg = vat_json_array_add (msg_array);
3893       vat_json_init_object (msg);
3894       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3895                                        (u8 *) counter_type_to_str (i, 0));
3896       vat_json_object_add_int (msg, "is_combined", 0);
3897       counter_array = vat_json_object_add (msg, "data");
3898       vat_json_init_array (counter_array);
3899       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3900         {
3901           packets = vam->simple_interface_counters[i][j];
3902           vat_json_array_add_uint (counter_array, packets);
3903         }
3904     }
3905   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3906     {
3907       msg = vat_json_array_add (msg_array);
3908       vat_json_init_object (msg);
3909       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3910                                        (u8 *) counter_type_to_str (i, 1));
3911       vat_json_object_add_int (msg, "is_combined", 1);
3912       counter_array = vat_json_object_add (msg, "data");
3913       vat_json_init_array (counter_array);
3914       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3915         {
3916           c = vam->combined_interface_counters[i][j];
3917           counter = vat_json_array_add (counter_array);
3918           vat_json_init_object (counter);
3919           vat_json_object_add_uint (counter, "packets", c.packets);
3920           vat_json_object_add_uint (counter, "bytes", c.bytes);
3921         }
3922     }
3923
3924   /* ip4 fib counters */
3925   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3926   vat_json_init_array (msg_array);
3927   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3928     {
3929       msg = vat_json_array_add (msg_array);
3930       vat_json_init_object (msg);
3931       vat_json_object_add_uint (msg, "vrf_id",
3932                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3933       counter_array = vat_json_object_add (msg, "c");
3934       vat_json_init_array (counter_array);
3935       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3936         {
3937           counter = vat_json_array_add (counter_array);
3938           vat_json_init_object (counter);
3939           c4 = &vam->ip4_fib_counters[i][j];
3940           vat_json_object_add_ip4 (counter, "address", c4->address);
3941           vat_json_object_add_uint (counter, "address_length",
3942                                     c4->address_length);
3943           vat_json_object_add_uint (counter, "packets", c4->packets);
3944           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3945         }
3946     }
3947
3948   /* ip6 fib counters */
3949   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3950   vat_json_init_array (msg_array);
3951   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3952     {
3953       msg = vat_json_array_add (msg_array);
3954       vat_json_init_object (msg);
3955       vat_json_object_add_uint (msg, "vrf_id",
3956                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3957       counter_array = vat_json_object_add (msg, "c");
3958       vat_json_init_array (counter_array);
3959       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3960         {
3961           counter = vat_json_array_add (counter_array);
3962           vat_json_init_object (counter);
3963           c6 = &vam->ip6_fib_counters[i][j];
3964           vat_json_object_add_ip6 (counter, "address", c6->address);
3965           vat_json_object_add_uint (counter, "address_length",
3966                                     c6->address_length);
3967           vat_json_object_add_uint (counter, "packets", c6->packets);
3968           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3969         }
3970     }
3971
3972   vat_json_print (vam->ofp, &node);
3973   vat_json_free (&node);
3974
3975   return 0;
3976 }
3977
3978 int
3979 exec (vat_main_t * vam)
3980 {
3981   api_main_t *am = &api_main;
3982   vl_api_cli_request_t *mp;
3983   f64 timeout;
3984   void *oldheap;
3985   u8 *cmd = 0;
3986   unformat_input_t *i = vam->input;
3987
3988   if (vec_len (i->buffer) == 0)
3989     return -1;
3990
3991   if (vam->exec_mode == 0 && unformat (i, "mode"))
3992     {
3993       vam->exec_mode = 1;
3994       return 0;
3995     }
3996   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3997     {
3998       vam->exec_mode = 0;
3999       return 0;
4000     }
4001
4002
4003   M (CLI_REQUEST, cli_request);
4004
4005   /*
4006    * Copy cmd into shared memory.
4007    * In order for the CLI command to work, it
4008    * must be a vector ending in \n, not a C-string ending
4009    * in \n\0.
4010    */
4011   pthread_mutex_lock (&am->vlib_rp->mutex);
4012   oldheap = svm_push_data_heap (am->vlib_rp);
4013
4014   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4015   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4016
4017   svm_pop_heap (oldheap);
4018   pthread_mutex_unlock (&am->vlib_rp->mutex);
4019
4020   mp->cmd_in_shmem = (u64) cmd;
4021   S;
4022   timeout = vat_time_now (vam) + 10.0;
4023
4024   while (vat_time_now (vam) < timeout)
4025     {
4026       if (vam->result_ready == 1)
4027         {
4028           u8 *free_me;
4029           if (vam->shmem_result != NULL)
4030             fformat (vam->ofp, "%s", vam->shmem_result);
4031           pthread_mutex_lock (&am->vlib_rp->mutex);
4032           oldheap = svm_push_data_heap (am->vlib_rp);
4033
4034           free_me = (u8 *) vam->shmem_result;
4035           vec_free (free_me);
4036
4037           svm_pop_heap (oldheap);
4038           pthread_mutex_unlock (&am->vlib_rp->mutex);
4039           return 0;
4040         }
4041     }
4042   return -99;
4043 }
4044
4045 static int
4046 api_create_loopback (vat_main_t * vam)
4047 {
4048   unformat_input_t *i = vam->input;
4049   vl_api_create_loopback_t *mp;
4050   f64 timeout;
4051   u8 mac_address[6];
4052   u8 mac_set = 0;
4053
4054   memset (mac_address, 0, sizeof (mac_address));
4055
4056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4057     {
4058       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4059         mac_set = 1;
4060       else
4061         break;
4062     }
4063
4064   /* Construct the API message */
4065   M (CREATE_LOOPBACK, create_loopback);
4066   if (mac_set)
4067     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4068
4069   S;
4070   W;
4071 }
4072
4073 static int
4074 api_delete_loopback (vat_main_t * vam)
4075 {
4076   unformat_input_t *i = vam->input;
4077   vl_api_delete_loopback_t *mp;
4078   f64 timeout;
4079   u32 sw_if_index = ~0;
4080
4081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4082     {
4083       if (unformat (i, "sw_if_index %d", &sw_if_index))
4084         ;
4085       else
4086         break;
4087     }
4088
4089   if (sw_if_index == ~0)
4090     {
4091       errmsg ("missing sw_if_index\n");
4092       return -99;
4093     }
4094
4095   /* Construct the API message */
4096   M (DELETE_LOOPBACK, delete_loopback);
4097   mp->sw_if_index = ntohl (sw_if_index);
4098
4099   S;
4100   W;
4101 }
4102
4103 static int
4104 api_want_stats (vat_main_t * vam)
4105 {
4106   unformat_input_t *i = vam->input;
4107   vl_api_want_stats_t *mp;
4108   f64 timeout;
4109   int enable = -1;
4110
4111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4112     {
4113       if (unformat (i, "enable"))
4114         enable = 1;
4115       else if (unformat (i, "disable"))
4116         enable = 0;
4117       else
4118         break;
4119     }
4120
4121   if (enable == -1)
4122     {
4123       errmsg ("missing enable|disable\n");
4124       return -99;
4125     }
4126
4127   M (WANT_STATS, want_stats);
4128   mp->enable_disable = enable;
4129
4130   S;
4131   W;
4132 }
4133
4134 static int
4135 api_want_interface_events (vat_main_t * vam)
4136 {
4137   unformat_input_t *i = vam->input;
4138   vl_api_want_interface_events_t *mp;
4139   f64 timeout;
4140   int enable = -1;
4141
4142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4143     {
4144       if (unformat (i, "enable"))
4145         enable = 1;
4146       else if (unformat (i, "disable"))
4147         enable = 0;
4148       else
4149         break;
4150     }
4151
4152   if (enable == -1)
4153     {
4154       errmsg ("missing enable|disable\n");
4155       return -99;
4156     }
4157
4158   M (WANT_INTERFACE_EVENTS, want_interface_events);
4159   mp->enable_disable = enable;
4160
4161   vam->interface_event_display = enable;
4162
4163   S;
4164   W;
4165 }
4166
4167
4168 /* Note: non-static, called once to set up the initial intfc table */
4169 int
4170 api_sw_interface_dump (vat_main_t * vam)
4171 {
4172   vl_api_sw_interface_dump_t *mp;
4173   f64 timeout;
4174   hash_pair_t *p;
4175   name_sort_t *nses = 0, *ns;
4176   sw_interface_subif_t *sub = NULL;
4177
4178   /* Toss the old name table */
4179   /* *INDENT-OFF* */
4180   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4181   ({
4182     vec_add2 (nses, ns, 1);
4183     ns->name = (u8 *)(p->key);
4184     ns->value = (u32) p->value[0];
4185   }));
4186   /* *INDENT-ON* */
4187
4188   hash_free (vam->sw_if_index_by_interface_name);
4189
4190   vec_foreach (ns, nses) vec_free (ns->name);
4191
4192   vec_free (nses);
4193
4194   vec_foreach (sub, vam->sw_if_subif_table)
4195   {
4196     vec_free (sub->interface_name);
4197   }
4198   vec_free (vam->sw_if_subif_table);
4199
4200   /* recreate the interface name hash table */
4201   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4202
4203   /* Get list of ethernets */
4204   M (SW_INTERFACE_DUMP, sw_interface_dump);
4205   mp->name_filter_valid = 1;
4206   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4207   S;
4208
4209   /* and local / loopback interfaces */
4210   M (SW_INTERFACE_DUMP, sw_interface_dump);
4211   mp->name_filter_valid = 1;
4212   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4213   S;
4214
4215
4216   /* and vxlan-gpe tunnel interfaces */
4217   M (SW_INTERFACE_DUMP, sw_interface_dump);
4218   mp->name_filter_valid = 1;
4219   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4220            sizeof (mp->name_filter) - 1);
4221   S;
4222
4223   /* and vxlan tunnel interfaces */
4224   M (SW_INTERFACE_DUMP, sw_interface_dump);
4225   mp->name_filter_valid = 1;
4226   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4227   S;
4228
4229   /* and host (af_packet) interfaces */
4230   M (SW_INTERFACE_DUMP, sw_interface_dump);
4231   mp->name_filter_valid = 1;
4232   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4233   S;
4234
4235   /* and l2tpv3 tunnel interfaces */
4236   M (SW_INTERFACE_DUMP, sw_interface_dump);
4237   mp->name_filter_valid = 1;
4238   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4239            sizeof (mp->name_filter) - 1);
4240   S;
4241
4242   /* and GRE tunnel interfaces */
4243   M (SW_INTERFACE_DUMP, sw_interface_dump);
4244   mp->name_filter_valid = 1;
4245   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4246   S;
4247
4248   /* Use a control ping for synchronization */
4249   {
4250     vl_api_control_ping_t *mp;
4251     M (CONTROL_PING, control_ping);
4252     S;
4253   }
4254   W;
4255 }
4256
4257 static int
4258 api_sw_interface_set_flags (vat_main_t * vam)
4259 {
4260   unformat_input_t *i = vam->input;
4261   vl_api_sw_interface_set_flags_t *mp;
4262   f64 timeout;
4263   u32 sw_if_index;
4264   u8 sw_if_index_set = 0;
4265   u8 admin_up = 0, link_up = 0;
4266
4267   /* Parse args required to build the message */
4268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4269     {
4270       if (unformat (i, "admin-up"))
4271         admin_up = 1;
4272       else if (unformat (i, "admin-down"))
4273         admin_up = 0;
4274       else if (unformat (i, "link-up"))
4275         link_up = 1;
4276       else if (unformat (i, "link-down"))
4277         link_up = 0;
4278       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4279         sw_if_index_set = 1;
4280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4281         sw_if_index_set = 1;
4282       else
4283         break;
4284     }
4285
4286   if (sw_if_index_set == 0)
4287     {
4288       errmsg ("missing interface name or sw_if_index\n");
4289       return -99;
4290     }
4291
4292   /* Construct the API message */
4293   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4294   mp->sw_if_index = ntohl (sw_if_index);
4295   mp->admin_up_down = admin_up;
4296   mp->link_up_down = link_up;
4297
4298   /* send it... */
4299   S;
4300
4301   /* Wait for a reply, return the good/bad news... */
4302   W;
4303 }
4304
4305 static int
4306 api_sw_interface_clear_stats (vat_main_t * vam)
4307 {
4308   unformat_input_t *i = vam->input;
4309   vl_api_sw_interface_clear_stats_t *mp;
4310   f64 timeout;
4311   u32 sw_if_index;
4312   u8 sw_if_index_set = 0;
4313
4314   /* Parse args required to build the message */
4315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4316     {
4317       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4318         sw_if_index_set = 1;
4319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4320         sw_if_index_set = 1;
4321       else
4322         break;
4323     }
4324
4325   /* Construct the API message */
4326   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4327
4328   if (sw_if_index_set == 1)
4329     mp->sw_if_index = ntohl (sw_if_index);
4330   else
4331     mp->sw_if_index = ~0;
4332
4333   /* send it... */
4334   S;
4335
4336   /* Wait for a reply, return the good/bad news... */
4337   W;
4338 }
4339
4340 static int
4341 api_sw_interface_add_del_address (vat_main_t * vam)
4342 {
4343   unformat_input_t *i = vam->input;
4344   vl_api_sw_interface_add_del_address_t *mp;
4345   f64 timeout;
4346   u32 sw_if_index;
4347   u8 sw_if_index_set = 0;
4348   u8 is_add = 1, del_all = 0;
4349   u32 address_length = 0;
4350   u8 v4_address_set = 0;
4351   u8 v6_address_set = 0;
4352   ip4_address_t v4address;
4353   ip6_address_t v6address;
4354
4355   /* Parse args required to build the message */
4356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4357     {
4358       if (unformat (i, "del-all"))
4359         del_all = 1;
4360       else if (unformat (i, "del"))
4361         is_add = 0;
4362       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4363         sw_if_index_set = 1;
4364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4365         sw_if_index_set = 1;
4366       else if (unformat (i, "%U/%d",
4367                          unformat_ip4_address, &v4address, &address_length))
4368         v4_address_set = 1;
4369       else if (unformat (i, "%U/%d",
4370                          unformat_ip6_address, &v6address, &address_length))
4371         v6_address_set = 1;
4372       else
4373         break;
4374     }
4375
4376   if (sw_if_index_set == 0)
4377     {
4378       errmsg ("missing interface name or sw_if_index\n");
4379       return -99;
4380     }
4381   if (v4_address_set && v6_address_set)
4382     {
4383       errmsg ("both v4 and v6 addresses set\n");
4384       return -99;
4385     }
4386   if (!v4_address_set && !v6_address_set && !del_all)
4387     {
4388       errmsg ("no addresses set\n");
4389       return -99;
4390     }
4391
4392   /* Construct the API message */
4393   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4394
4395   mp->sw_if_index = ntohl (sw_if_index);
4396   mp->is_add = is_add;
4397   mp->del_all = del_all;
4398   if (v6_address_set)
4399     {
4400       mp->is_ipv6 = 1;
4401       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4402     }
4403   else
4404     {
4405       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4406     }
4407   mp->address_length = address_length;
4408
4409   /* send it... */
4410   S;
4411
4412   /* Wait for a reply, return good/bad news  */
4413   W;
4414 }
4415
4416 static int
4417 api_sw_interface_set_table (vat_main_t * vam)
4418 {
4419   unformat_input_t *i = vam->input;
4420   vl_api_sw_interface_set_table_t *mp;
4421   f64 timeout;
4422   u32 sw_if_index, vrf_id = 0;
4423   u8 sw_if_index_set = 0;
4424   u8 is_ipv6 = 0;
4425
4426   /* Parse args required to build the message */
4427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4428     {
4429       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4430         sw_if_index_set = 1;
4431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4432         sw_if_index_set = 1;
4433       else if (unformat (i, "vrf %d", &vrf_id))
4434         ;
4435       else if (unformat (i, "ipv6"))
4436         is_ipv6 = 1;
4437       else
4438         break;
4439     }
4440
4441   if (sw_if_index_set == 0)
4442     {
4443       errmsg ("missing interface name or sw_if_index\n");
4444       return -99;
4445     }
4446
4447   /* Construct the API message */
4448   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4449
4450   mp->sw_if_index = ntohl (sw_if_index);
4451   mp->is_ipv6 = is_ipv6;
4452   mp->vrf_id = ntohl (vrf_id);
4453
4454   /* send it... */
4455   S;
4456
4457   /* Wait for a reply... */
4458   W;
4459 }
4460
4461 static int
4462 api_sw_interface_set_vpath (vat_main_t * vam)
4463 {
4464   unformat_input_t *i = vam->input;
4465   vl_api_sw_interface_set_vpath_t *mp;
4466   f64 timeout;
4467   u32 sw_if_index = 0;
4468   u8 sw_if_index_set = 0;
4469   u8 is_enable = 0;
4470
4471   /* Parse args required to build the message */
4472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4473     {
4474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4475         sw_if_index_set = 1;
4476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4477         sw_if_index_set = 1;
4478       else if (unformat (i, "enable"))
4479         is_enable = 1;
4480       else if (unformat (i, "disable"))
4481         is_enable = 0;
4482       else
4483         break;
4484     }
4485
4486   if (sw_if_index_set == 0)
4487     {
4488       errmsg ("missing interface name or sw_if_index\n");
4489       return -99;
4490     }
4491
4492   /* Construct the API message */
4493   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4494
4495   mp->sw_if_index = ntohl (sw_if_index);
4496   mp->enable = is_enable;
4497
4498   /* send it... */
4499   S;
4500
4501   /* Wait for a reply... */
4502   W;
4503 }
4504
4505 static int
4506 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4507 {
4508   unformat_input_t *i = vam->input;
4509   vl_api_sw_interface_set_l2_xconnect_t *mp;
4510   f64 timeout;
4511   u32 rx_sw_if_index;
4512   u8 rx_sw_if_index_set = 0;
4513   u32 tx_sw_if_index;
4514   u8 tx_sw_if_index_set = 0;
4515   u8 enable = 1;
4516
4517   /* Parse args required to build the message */
4518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4519     {
4520       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4521         rx_sw_if_index_set = 1;
4522       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4523         tx_sw_if_index_set = 1;
4524       else if (unformat (i, "rx"))
4525         {
4526           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4527             {
4528               if (unformat (i, "%U", unformat_sw_if_index, vam,
4529                             &rx_sw_if_index))
4530                 rx_sw_if_index_set = 1;
4531             }
4532           else
4533             break;
4534         }
4535       else if (unformat (i, "tx"))
4536         {
4537           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4538             {
4539               if (unformat (i, "%U", unformat_sw_if_index, vam,
4540                             &tx_sw_if_index))
4541                 tx_sw_if_index_set = 1;
4542             }
4543           else
4544             break;
4545         }
4546       else if (unformat (i, "enable"))
4547         enable = 1;
4548       else if (unformat (i, "disable"))
4549         enable = 0;
4550       else
4551         break;
4552     }
4553
4554   if (rx_sw_if_index_set == 0)
4555     {
4556       errmsg ("missing rx interface name or rx_sw_if_index\n");
4557       return -99;
4558     }
4559
4560   if (enable && (tx_sw_if_index_set == 0))
4561     {
4562       errmsg ("missing tx interface name or tx_sw_if_index\n");
4563       return -99;
4564     }
4565
4566   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4567
4568   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4569   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4570   mp->enable = enable;
4571
4572   S;
4573   W;
4574   /* NOTREACHED */
4575   return 0;
4576 }
4577
4578 static int
4579 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4580 {
4581   unformat_input_t *i = vam->input;
4582   vl_api_sw_interface_set_l2_bridge_t *mp;
4583   f64 timeout;
4584   u32 rx_sw_if_index;
4585   u8 rx_sw_if_index_set = 0;
4586   u32 bd_id;
4587   u8 bd_id_set = 0;
4588   u8 bvi = 0;
4589   u32 shg = 0;
4590   u8 enable = 1;
4591
4592   /* Parse args required to build the message */
4593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4594     {
4595       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4596         rx_sw_if_index_set = 1;
4597       else if (unformat (i, "bd_id %d", &bd_id))
4598         bd_id_set = 1;
4599       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4600         rx_sw_if_index_set = 1;
4601       else if (unformat (i, "shg %d", &shg))
4602         ;
4603       else if (unformat (i, "bvi"))
4604         bvi = 1;
4605       else if (unformat (i, "enable"))
4606         enable = 1;
4607       else if (unformat (i, "disable"))
4608         enable = 0;
4609       else
4610         break;
4611     }
4612
4613   if (rx_sw_if_index_set == 0)
4614     {
4615       errmsg ("missing rx interface name or sw_if_index\n");
4616       return -99;
4617     }
4618
4619   if (enable && (bd_id_set == 0))
4620     {
4621       errmsg ("missing bridge domain\n");
4622       return -99;
4623     }
4624
4625   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4626
4627   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4628   mp->bd_id = ntohl (bd_id);
4629   mp->shg = (u8) shg;
4630   mp->bvi = bvi;
4631   mp->enable = enable;
4632
4633   S;
4634   W;
4635   /* NOTREACHED */
4636   return 0;
4637 }
4638
4639 static int
4640 api_bridge_domain_dump (vat_main_t * vam)
4641 {
4642   unformat_input_t *i = vam->input;
4643   vl_api_bridge_domain_dump_t *mp;
4644   f64 timeout;
4645   u32 bd_id = ~0;
4646
4647   /* Parse args required to build the message */
4648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4649     {
4650       if (unformat (i, "bd_id %d", &bd_id))
4651         ;
4652       else
4653         break;
4654     }
4655
4656   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4657   mp->bd_id = ntohl (bd_id);
4658   S;
4659
4660   /* Use a control ping for synchronization */
4661   {
4662     vl_api_control_ping_t *mp;
4663     M (CONTROL_PING, control_ping);
4664     S;
4665   }
4666
4667   W;
4668   /* NOTREACHED */
4669   return 0;
4670 }
4671
4672 static int
4673 api_bridge_domain_add_del (vat_main_t * vam)
4674 {
4675   unformat_input_t *i = vam->input;
4676   vl_api_bridge_domain_add_del_t *mp;
4677   f64 timeout;
4678   u32 bd_id = ~0;
4679   u8 is_add = 1;
4680   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4681
4682   /* Parse args required to build the message */
4683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4684     {
4685       if (unformat (i, "bd_id %d", &bd_id))
4686         ;
4687       else if (unformat (i, "flood %d", &flood))
4688         ;
4689       else if (unformat (i, "uu-flood %d", &uu_flood))
4690         ;
4691       else if (unformat (i, "forward %d", &forward))
4692         ;
4693       else if (unformat (i, "learn %d", &learn))
4694         ;
4695       else if (unformat (i, "arp-term %d", &arp_term))
4696         ;
4697       else if (unformat (i, "del"))
4698         {
4699           is_add = 0;
4700           flood = uu_flood = forward = learn = 0;
4701         }
4702       else
4703         break;
4704     }
4705
4706   if (bd_id == ~0)
4707     {
4708       errmsg ("missing bridge domain\n");
4709       return -99;
4710     }
4711
4712   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4713
4714   mp->bd_id = ntohl (bd_id);
4715   mp->flood = flood;
4716   mp->uu_flood = uu_flood;
4717   mp->forward = forward;
4718   mp->learn = learn;
4719   mp->arp_term = arp_term;
4720   mp->is_add = is_add;
4721
4722   S;
4723   W;
4724   /* NOTREACHED */
4725   return 0;
4726 }
4727
4728 static int
4729 api_l2fib_add_del (vat_main_t * vam)
4730 {
4731   unformat_input_t *i = vam->input;
4732   vl_api_l2fib_add_del_t *mp;
4733   f64 timeout;
4734   u64 mac = 0;
4735   u8 mac_set = 0;
4736   u32 bd_id;
4737   u8 bd_id_set = 0;
4738   u32 sw_if_index;
4739   u8 sw_if_index_set = 0;
4740   u8 is_add = 1;
4741   u8 static_mac = 0;
4742   u8 filter_mac = 0;
4743   u8 bvi_mac = 0;
4744   int count = 1;
4745   f64 before = 0;
4746   int j;
4747
4748   /* Parse args required to build the message */
4749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4750     {
4751       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4752         mac_set = 1;
4753       else if (unformat (i, "bd_id %d", &bd_id))
4754         bd_id_set = 1;
4755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4756         sw_if_index_set = 1;
4757       else if (unformat (i, "sw_if"))
4758         {
4759           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4760             {
4761               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4762                 sw_if_index_set = 1;
4763             }
4764           else
4765             break;
4766         }
4767       else if (unformat (i, "static"))
4768         static_mac = 1;
4769       else if (unformat (i, "filter"))
4770         {
4771           filter_mac = 1;
4772           static_mac = 1;
4773         }
4774       else if (unformat (i, "bvi"))
4775         {
4776           bvi_mac = 1;
4777           static_mac = 1;
4778         }
4779       else if (unformat (i, "del"))
4780         is_add = 0;
4781       else if (unformat (i, "count %d", &count))
4782         ;
4783       else
4784         break;
4785     }
4786
4787   if (mac_set == 0)
4788     {
4789       errmsg ("missing mac address\n");
4790       return -99;
4791     }
4792
4793   if (bd_id_set == 0)
4794     {
4795       errmsg ("missing bridge domain\n");
4796       return -99;
4797     }
4798
4799   if (is_add && (sw_if_index_set == 0))
4800     {
4801       errmsg ("missing interface name or sw_if_index\n");
4802       return -99;
4803     }
4804
4805   if (count > 1)
4806     {
4807       /* Turn on async mode */
4808       vam->async_mode = 1;
4809       vam->async_errors = 0;
4810       before = vat_time_now (vam);
4811     }
4812
4813   for (j = 0; j < count; j++)
4814     {
4815       M (L2FIB_ADD_DEL, l2fib_add_del);
4816
4817       mp->mac = mac;
4818       mp->bd_id = ntohl (bd_id);
4819       mp->is_add = is_add;
4820
4821       if (is_add)
4822         {
4823           mp->sw_if_index = ntohl (sw_if_index);
4824           mp->static_mac = static_mac;
4825           mp->filter_mac = filter_mac;
4826           mp->bvi_mac = bvi_mac;
4827         }
4828       increment_mac_address (&mac);
4829       /* send it... */
4830       S;
4831     }
4832
4833   if (count > 1)
4834     {
4835       vl_api_control_ping_t *mp;
4836       f64 after;
4837
4838       /* Shut off async mode */
4839       vam->async_mode = 0;
4840
4841       M (CONTROL_PING, control_ping);
4842       S;
4843
4844       timeout = vat_time_now (vam) + 1.0;
4845       while (vat_time_now (vam) < timeout)
4846         if (vam->result_ready == 1)
4847           goto out;
4848       vam->retval = -99;
4849
4850     out:
4851       if (vam->retval == -99)
4852         errmsg ("timeout\n");
4853
4854       if (vam->async_errors > 0)
4855         {
4856           errmsg ("%d asynchronous errors\n", vam->async_errors);
4857           vam->retval = -98;
4858         }
4859       vam->async_errors = 0;
4860       after = vat_time_now (vam);
4861
4862       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4863                count, after - before, count / (after - before));
4864     }
4865   else
4866     {
4867       /* Wait for a reply... */
4868       W;
4869     }
4870   /* Return the good/bad news */
4871   return (vam->retval);
4872 }
4873
4874 static int
4875 api_l2_flags (vat_main_t * vam)
4876 {
4877   unformat_input_t *i = vam->input;
4878   vl_api_l2_flags_t *mp;
4879   f64 timeout;
4880   u32 sw_if_index;
4881   u32 feature_bitmap = 0;
4882   u8 sw_if_index_set = 0;
4883
4884   /* Parse args required to build the message */
4885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4886     {
4887       if (unformat (i, "sw_if_index %d", &sw_if_index))
4888         sw_if_index_set = 1;
4889       else if (unformat (i, "sw_if"))
4890         {
4891           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4892             {
4893               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4894                 sw_if_index_set = 1;
4895             }
4896           else
4897             break;
4898         }
4899       else if (unformat (i, "learn"))
4900         feature_bitmap |= L2INPUT_FEAT_LEARN;
4901       else if (unformat (i, "forward"))
4902         feature_bitmap |= L2INPUT_FEAT_FWD;
4903       else if (unformat (i, "flood"))
4904         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4905       else if (unformat (i, "uu-flood"))
4906         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4907       else
4908         break;
4909     }
4910
4911   if (sw_if_index_set == 0)
4912     {
4913       errmsg ("missing interface name or sw_if_index\n");
4914       return -99;
4915     }
4916
4917   M (L2_FLAGS, l2_flags);
4918
4919   mp->sw_if_index = ntohl (sw_if_index);
4920   mp->feature_bitmap = ntohl (feature_bitmap);
4921
4922   S;
4923   W;
4924   /* NOTREACHED */
4925   return 0;
4926 }
4927
4928 static int
4929 api_bridge_flags (vat_main_t * vam)
4930 {
4931   unformat_input_t *i = vam->input;
4932   vl_api_bridge_flags_t *mp;
4933   f64 timeout;
4934   u32 bd_id;
4935   u8 bd_id_set = 0;
4936   u8 is_set = 1;
4937   u32 flags = 0;
4938
4939   /* Parse args required to build the message */
4940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4941     {
4942       if (unformat (i, "bd_id %d", &bd_id))
4943         bd_id_set = 1;
4944       else if (unformat (i, "learn"))
4945         flags |= L2_LEARN;
4946       else if (unformat (i, "forward"))
4947         flags |= L2_FWD;
4948       else if (unformat (i, "flood"))
4949         flags |= L2_FLOOD;
4950       else if (unformat (i, "uu-flood"))
4951         flags |= L2_UU_FLOOD;
4952       else if (unformat (i, "arp-term"))
4953         flags |= L2_ARP_TERM;
4954       else if (unformat (i, "off"))
4955         is_set = 0;
4956       else if (unformat (i, "disable"))
4957         is_set = 0;
4958       else
4959         break;
4960     }
4961
4962   if (bd_id_set == 0)
4963     {
4964       errmsg ("missing bridge domain\n");
4965       return -99;
4966     }
4967
4968   M (BRIDGE_FLAGS, bridge_flags);
4969
4970   mp->bd_id = ntohl (bd_id);
4971   mp->feature_bitmap = ntohl (flags);
4972   mp->is_set = is_set;
4973
4974   S;
4975   W;
4976   /* NOTREACHED */
4977   return 0;
4978 }
4979
4980 static int
4981 api_bd_ip_mac_add_del (vat_main_t * vam)
4982 {
4983   unformat_input_t *i = vam->input;
4984   vl_api_bd_ip_mac_add_del_t *mp;
4985   f64 timeout;
4986   u32 bd_id;
4987   u8 is_ipv6 = 0;
4988   u8 is_add = 1;
4989   u8 bd_id_set = 0;
4990   u8 ip_set = 0;
4991   u8 mac_set = 0;
4992   ip4_address_t v4addr;
4993   ip6_address_t v6addr;
4994   u8 macaddr[6];
4995
4996
4997   /* Parse args required to build the message */
4998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4999     {
5000       if (unformat (i, "bd_id %d", &bd_id))
5001         {
5002           bd_id_set++;
5003         }
5004       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5005         {
5006           ip_set++;
5007         }
5008       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5009         {
5010           ip_set++;
5011           is_ipv6++;
5012         }
5013       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5014         {
5015           mac_set++;
5016         }
5017       else if (unformat (i, "del"))
5018         is_add = 0;
5019       else
5020         break;
5021     }
5022
5023   if (bd_id_set == 0)
5024     {
5025       errmsg ("missing bridge domain\n");
5026       return -99;
5027     }
5028   else if (ip_set == 0)
5029     {
5030       errmsg ("missing IP address\n");
5031       return -99;
5032     }
5033   else if (mac_set == 0)
5034     {
5035       errmsg ("missing MAC address\n");
5036       return -99;
5037     }
5038
5039   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5040
5041   mp->bd_id = ntohl (bd_id);
5042   mp->is_ipv6 = is_ipv6;
5043   mp->is_add = is_add;
5044   if (is_ipv6)
5045     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5046   else
5047     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5048   clib_memcpy (mp->mac_address, macaddr, 6);
5049   S;
5050   W;
5051   /* NOTREACHED */
5052   return 0;
5053 }
5054
5055 static int
5056 api_tap_connect (vat_main_t * vam)
5057 {
5058   unformat_input_t *i = vam->input;
5059   vl_api_tap_connect_t *mp;
5060   f64 timeout;
5061   u8 mac_address[6];
5062   u8 random_mac = 1;
5063   u8 name_set = 0;
5064   u8 *tap_name;
5065
5066   memset (mac_address, 0, sizeof (mac_address));
5067
5068   /* Parse args required to build the message */
5069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5070     {
5071       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5072         {
5073           random_mac = 0;
5074         }
5075       else if (unformat (i, "random-mac"))
5076         random_mac = 1;
5077       else if (unformat (i, "tapname %s", &tap_name))
5078         name_set = 1;
5079       else
5080         break;
5081     }
5082
5083   if (name_set == 0)
5084     {
5085       errmsg ("missing tap name\n");
5086       return -99;
5087     }
5088   if (vec_len (tap_name) > 63)
5089     {
5090       errmsg ("tap name too long\n");
5091     }
5092   vec_add1 (tap_name, 0);
5093
5094   /* Construct the API message */
5095   M (TAP_CONNECT, tap_connect);
5096
5097   mp->use_random_mac = random_mac;
5098   clib_memcpy (mp->mac_address, mac_address, 6);
5099   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5100   vec_free (tap_name);
5101
5102   /* send it... */
5103   S;
5104
5105   /* Wait for a reply... */
5106   W;
5107 }
5108
5109 static int
5110 api_tap_modify (vat_main_t * vam)
5111 {
5112   unformat_input_t *i = vam->input;
5113   vl_api_tap_modify_t *mp;
5114   f64 timeout;
5115   u8 mac_address[6];
5116   u8 random_mac = 1;
5117   u8 name_set = 0;
5118   u8 *tap_name;
5119   u32 sw_if_index = ~0;
5120   u8 sw_if_index_set = 0;
5121
5122   memset (mac_address, 0, sizeof (mac_address));
5123
5124   /* Parse args required to build the message */
5125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5126     {
5127       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5130         sw_if_index_set = 1;
5131       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5132         {
5133           random_mac = 0;
5134         }
5135       else if (unformat (i, "random-mac"))
5136         random_mac = 1;
5137       else if (unformat (i, "tapname %s", &tap_name))
5138         name_set = 1;
5139       else
5140         break;
5141     }
5142
5143   if (sw_if_index_set == 0)
5144     {
5145       errmsg ("missing vpp interface name");
5146       return -99;
5147     }
5148   if (name_set == 0)
5149     {
5150       errmsg ("missing tap name\n");
5151       return -99;
5152     }
5153   if (vec_len (tap_name) > 63)
5154     {
5155       errmsg ("tap name too long\n");
5156     }
5157   vec_add1 (tap_name, 0);
5158
5159   /* Construct the API message */
5160   M (TAP_MODIFY, tap_modify);
5161
5162   mp->use_random_mac = random_mac;
5163   mp->sw_if_index = ntohl (sw_if_index);
5164   clib_memcpy (mp->mac_address, mac_address, 6);
5165   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5166   vec_free (tap_name);
5167
5168   /* send it... */
5169   S;
5170
5171   /* Wait for a reply... */
5172   W;
5173 }
5174
5175 static int
5176 api_tap_delete (vat_main_t * vam)
5177 {
5178   unformat_input_t *i = vam->input;
5179   vl_api_tap_delete_t *mp;
5180   f64 timeout;
5181   u32 sw_if_index = ~0;
5182   u8 sw_if_index_set = 0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5188         sw_if_index_set = 1;
5189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5190         sw_if_index_set = 1;
5191       else
5192         break;
5193     }
5194
5195   if (sw_if_index_set == 0)
5196     {
5197       errmsg ("missing vpp interface name");
5198       return -99;
5199     }
5200
5201   /* Construct the API message */
5202   M (TAP_DELETE, tap_delete);
5203
5204   mp->sw_if_index = ntohl (sw_if_index);
5205
5206   /* send it... */
5207   S;
5208
5209   /* Wait for a reply... */
5210   W;
5211 }
5212
5213 static int
5214 api_ip_add_del_route (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_ip_add_del_route_t *mp;
5218   f64 timeout;
5219   u32 sw_if_index = ~0, vrf_id = 0;
5220   u8 sw_if_index_set = 0;
5221   u8 is_ipv6 = 0;
5222   u8 is_local = 0, is_drop = 0;
5223   u8 create_vrf_if_needed = 0;
5224   u8 is_add = 1;
5225   u8 next_hop_weight = 1;
5226   u8 not_last = 0;
5227   u8 is_multipath = 0;
5228   u8 address_set = 0;
5229   u8 address_length_set = 0;
5230   u32 lookup_in_vrf = 0;
5231   u32 resolve_attempts = 0;
5232   u32 dst_address_length = 0;
5233   u8 next_hop_set = 0;
5234   ip4_address_t v4_dst_address, v4_next_hop_address;
5235   ip6_address_t v6_dst_address, v6_next_hop_address;
5236   int count = 1;
5237   int j;
5238   f64 before = 0;
5239   u32 random_add_del = 0;
5240   u32 *random_vector = 0;
5241   uword *random_hash;
5242   u32 random_seed = 0xdeaddabe;
5243   u32 classify_table_index = ~0;
5244   u8 is_classify = 0;
5245
5246   /* Parse args required to build the message */
5247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5248     {
5249       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5250         sw_if_index_set = 1;
5251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5252         sw_if_index_set = 1;
5253       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5254         {
5255           address_set = 1;
5256           is_ipv6 = 0;
5257         }
5258       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5259         {
5260           address_set = 1;
5261           is_ipv6 = 1;
5262         }
5263       else if (unformat (i, "/%d", &dst_address_length))
5264         {
5265           address_length_set = 1;
5266         }
5267
5268       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5269                                          &v4_next_hop_address))
5270         {
5271           next_hop_set = 1;
5272         }
5273       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5274                                          &v6_next_hop_address))
5275         {
5276           next_hop_set = 1;
5277         }
5278       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5279         ;
5280       else if (unformat (i, "weight %d", &next_hop_weight))
5281         ;
5282       else if (unformat (i, "drop"))
5283         {
5284           is_drop = 1;
5285         }
5286       else if (unformat (i, "local"))
5287         {
5288           is_local = 1;
5289         }
5290       else if (unformat (i, "classify %d", &classify_table_index))
5291         {
5292           is_classify = 1;
5293         }
5294       else if (unformat (i, "del"))
5295         is_add = 0;
5296       else if (unformat (i, "add"))
5297         is_add = 1;
5298       else if (unformat (i, "not-last"))
5299         not_last = 1;
5300       else if (unformat (i, "multipath"))
5301         is_multipath = 1;
5302       else if (unformat (i, "vrf %d", &vrf_id))
5303         ;
5304       else if (unformat (i, "create-vrf"))
5305         create_vrf_if_needed = 1;
5306       else if (unformat (i, "count %d", &count))
5307         ;
5308       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5309         ;
5310       else if (unformat (i, "random"))
5311         random_add_del = 1;
5312       else if (unformat (i, "seed %d", &random_seed))
5313         ;
5314       else
5315         {
5316           clib_warning ("parse error '%U'", format_unformat_error, i);
5317           return -99;
5318         }
5319     }
5320
5321   if (resolve_attempts > 0 && sw_if_index_set == 0)
5322     {
5323       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5324       return -99;
5325     }
5326
5327   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5328     {
5329       errmsg ("next hop / local / drop / classify not set\n");
5330       return -99;
5331     }
5332
5333   if (address_set == 0)
5334     {
5335       errmsg ("missing addresses\n");
5336       return -99;
5337     }
5338
5339   if (address_length_set == 0)
5340     {
5341       errmsg ("missing address length\n");
5342       return -99;
5343     }
5344
5345   /* Generate a pile of unique, random routes */
5346   if (random_add_del)
5347     {
5348       u32 this_random_address;
5349       random_hash = hash_create (count, sizeof (uword));
5350
5351       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5352       for (j = 0; j <= count; j++)
5353         {
5354           do
5355             {
5356               this_random_address = random_u32 (&random_seed);
5357               this_random_address =
5358                 clib_host_to_net_u32 (this_random_address);
5359             }
5360           while (hash_get (random_hash, this_random_address));
5361           vec_add1 (random_vector, this_random_address);
5362           hash_set (random_hash, this_random_address, 1);
5363         }
5364       hash_free (random_hash);
5365       v4_dst_address.as_u32 = random_vector[0];
5366     }
5367
5368   if (count > 1)
5369     {
5370       /* Turn on async mode */
5371       vam->async_mode = 1;
5372       vam->async_errors = 0;
5373       before = vat_time_now (vam);
5374     }
5375
5376   for (j = 0; j < count; j++)
5377     {
5378       /* Construct the API message */
5379       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5380
5381       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5382       mp->vrf_id = ntohl (vrf_id);
5383       if (resolve_attempts > 0)
5384         {
5385           mp->resolve_attempts = ntohl (resolve_attempts);
5386           mp->resolve_if_needed = 1;
5387         }
5388       mp->create_vrf_if_needed = create_vrf_if_needed;
5389
5390       mp->is_add = is_add;
5391       mp->is_drop = is_drop;
5392       mp->is_ipv6 = is_ipv6;
5393       mp->is_local = is_local;
5394       mp->is_classify = is_classify;
5395       mp->is_multipath = is_multipath;
5396       mp->not_last = not_last;
5397       mp->next_hop_weight = next_hop_weight;
5398       mp->dst_address_length = dst_address_length;
5399       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5400       mp->classify_table_index = ntohl (classify_table_index);
5401
5402       if (is_ipv6)
5403         {
5404           clib_memcpy (mp->dst_address, &v6_dst_address,
5405                        sizeof (v6_dst_address));
5406           if (next_hop_set)
5407             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5408                          sizeof (v6_next_hop_address));
5409           increment_v6_address (&v6_dst_address);
5410         }
5411       else
5412         {
5413           clib_memcpy (mp->dst_address, &v4_dst_address,
5414                        sizeof (v4_dst_address));
5415           if (next_hop_set)
5416             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5417                          sizeof (v4_next_hop_address));
5418           if (random_add_del)
5419             v4_dst_address.as_u32 = random_vector[j + 1];
5420           else
5421             increment_v4_address (&v4_dst_address);
5422         }
5423       /* send it... */
5424       S;
5425     }
5426
5427   /* When testing multiple add/del ops, use a control-ping to sync */
5428   if (count > 1)
5429     {
5430       vl_api_control_ping_t *mp;
5431       f64 after;
5432
5433       /* Shut off async mode */
5434       vam->async_mode = 0;
5435
5436       M (CONTROL_PING, control_ping);
5437       S;
5438
5439       timeout = vat_time_now (vam) + 1.0;
5440       while (vat_time_now (vam) < timeout)
5441         if (vam->result_ready == 1)
5442           goto out;
5443       vam->retval = -99;
5444
5445     out:
5446       if (vam->retval == -99)
5447         errmsg ("timeout\n");
5448
5449       if (vam->async_errors > 0)
5450         {
5451           errmsg ("%d asynchronous errors\n", vam->async_errors);
5452           vam->retval = -98;
5453         }
5454       vam->async_errors = 0;
5455       after = vat_time_now (vam);
5456
5457       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5458                count, after - before, count / (after - before));
5459     }
5460   else
5461     {
5462       /* Wait for a reply... */
5463       W;
5464     }
5465
5466   /* Return the good/bad news */
5467   return (vam->retval);
5468 }
5469
5470 static int
5471 api_proxy_arp_add_del (vat_main_t * vam)
5472 {
5473   unformat_input_t *i = vam->input;
5474   vl_api_proxy_arp_add_del_t *mp;
5475   f64 timeout;
5476   u32 vrf_id = 0;
5477   u8 is_add = 1;
5478   ip4_address_t lo, hi;
5479   u8 range_set = 0;
5480
5481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5482     {
5483       if (unformat (i, "vrf %d", &vrf_id))
5484         ;
5485       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5486                          unformat_ip4_address, &hi))
5487         range_set = 1;
5488       else if (unformat (i, "del"))
5489         is_add = 0;
5490       else
5491         {
5492           clib_warning ("parse error '%U'", format_unformat_error, i);
5493           return -99;
5494         }
5495     }
5496
5497   if (range_set == 0)
5498     {
5499       errmsg ("address range not set\n");
5500       return -99;
5501     }
5502
5503   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5504
5505   mp->vrf_id = ntohl (vrf_id);
5506   mp->is_add = is_add;
5507   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5508   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5509
5510   S;
5511   W;
5512   /* NOTREACHED */
5513   return 0;
5514 }
5515
5516 static int
5517 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5518 {
5519   unformat_input_t *i = vam->input;
5520   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5521   f64 timeout;
5522   u32 sw_if_index;
5523   u8 enable = 1;
5524   u8 sw_if_index_set = 0;
5525
5526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5527     {
5528       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5529         sw_if_index_set = 1;
5530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5531         sw_if_index_set = 1;
5532       else if (unformat (i, "enable"))
5533         enable = 1;
5534       else if (unformat (i, "disable"))
5535         enable = 0;
5536       else
5537         {
5538           clib_warning ("parse error '%U'", format_unformat_error, i);
5539           return -99;
5540         }
5541     }
5542
5543   if (sw_if_index_set == 0)
5544     {
5545       errmsg ("missing interface name or sw_if_index\n");
5546       return -99;
5547     }
5548
5549   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5550
5551   mp->sw_if_index = ntohl (sw_if_index);
5552   mp->enable_disable = enable;
5553
5554   S;
5555   W;
5556   /* NOTREACHED */
5557   return 0;
5558 }
5559
5560 static int
5561 api_mpls_add_del_decap (vat_main_t * vam)
5562 {
5563   unformat_input_t *i = vam->input;
5564   vl_api_mpls_add_del_decap_t *mp;
5565   f64 timeout;
5566   u32 rx_vrf_id = 0;
5567   u32 tx_vrf_id = 0;
5568   u32 label = 0;
5569   u8 is_add = 1;
5570   u8 s_bit = 1;
5571   u32 next_index = 1;
5572
5573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5574     {
5575       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5576         ;
5577       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5578         ;
5579       else if (unformat (i, "label %d", &label))
5580         ;
5581       else if (unformat (i, "next-index %d", &next_index))
5582         ;
5583       else if (unformat (i, "del"))
5584         is_add = 0;
5585       else if (unformat (i, "s-bit-clear"))
5586         s_bit = 0;
5587       else
5588         {
5589           clib_warning ("parse error '%U'", format_unformat_error, i);
5590           return -99;
5591         }
5592     }
5593
5594   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5595
5596   mp->rx_vrf_id = ntohl (rx_vrf_id);
5597   mp->tx_vrf_id = ntohl (tx_vrf_id);
5598   mp->label = ntohl (label);
5599   mp->next_index = ntohl (next_index);
5600   mp->s_bit = s_bit;
5601   mp->is_add = is_add;
5602
5603   S;
5604   W;
5605   /* NOTREACHED */
5606   return 0;
5607 }
5608
5609 static int
5610 api_mpls_add_del_encap (vat_main_t * vam)
5611 {
5612   unformat_input_t *i = vam->input;
5613   vl_api_mpls_add_del_encap_t *mp;
5614   f64 timeout;
5615   u32 vrf_id = 0;
5616   u32 *labels = 0;
5617   u32 label;
5618   ip4_address_t dst_address;
5619   u8 is_add = 1;
5620
5621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5622     {
5623       if (unformat (i, "vrf %d", &vrf_id))
5624         ;
5625       else if (unformat (i, "label %d", &label))
5626         vec_add1 (labels, ntohl (label));
5627       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5628         ;
5629       else if (unformat (i, "del"))
5630         is_add = 0;
5631       else
5632         {
5633           clib_warning ("parse error '%U'", format_unformat_error, i);
5634           return -99;
5635         }
5636     }
5637
5638   if (vec_len (labels) == 0)
5639     {
5640       errmsg ("missing encap label stack\n");
5641       return -99;
5642     }
5643
5644   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5645       sizeof (u32) * vec_len (labels));
5646
5647   mp->vrf_id = ntohl (vrf_id);
5648   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5649   mp->is_add = is_add;
5650   mp->nlabels = vec_len (labels);
5651   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5652
5653   vec_free (labels);
5654
5655   S;
5656   W;
5657   /* NOTREACHED */
5658   return 0;
5659 }
5660
5661 static int
5662 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5663 {
5664   unformat_input_t *i = vam->input;
5665   vl_api_mpls_gre_add_del_tunnel_t *mp;
5666   f64 timeout;
5667   u32 inner_vrf_id = 0;
5668   u32 outer_vrf_id = 0;
5669   ip4_address_t src_address;
5670   ip4_address_t dst_address;
5671   ip4_address_t intfc_address;
5672   u32 tmp;
5673   u8 intfc_address_length = 0;
5674   u8 is_add = 1;
5675   u8 l2_only = 0;
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5680         ;
5681       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5682         ;
5683       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5684         ;
5685       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5686         ;
5687       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5688                          &intfc_address, &tmp))
5689         intfc_address_length = tmp;
5690       else if (unformat (i, "l2-only"))
5691         l2_only = 1;
5692       else if (unformat (i, "del"))
5693         is_add = 0;
5694       else
5695         {
5696           clib_warning ("parse error '%U'", format_unformat_error, i);
5697           return -99;
5698         }
5699     }
5700
5701   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5702
5703   mp->inner_vrf_id = ntohl (inner_vrf_id);
5704   mp->outer_vrf_id = ntohl (outer_vrf_id);
5705   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5706   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5707   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5708   mp->intfc_address_length = intfc_address_length;
5709   mp->l2_only = l2_only;
5710   mp->is_add = is_add;
5711
5712   S;
5713   W;
5714   /* NOTREACHED */
5715   return 0;
5716 }
5717
5718 static int
5719 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5720 {
5721   unformat_input_t *i = vam->input;
5722   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5723   f64 timeout;
5724   u32 inner_vrf_id = 0;
5725   ip4_address_t intfc_address;
5726   u8 dst_mac_address[6];
5727   int dst_set = 1;
5728   u32 tmp;
5729   u8 intfc_address_length = 0;
5730   u8 is_add = 1;
5731   u8 l2_only = 0;
5732   u32 tx_sw_if_index;
5733   int tx_sw_if_index_set = 0;
5734
5735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5736     {
5737       if (unformat (i, "vrf %d", &inner_vrf_id))
5738         ;
5739       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5740                          &intfc_address, &tmp))
5741         intfc_address_length = tmp;
5742       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5743         tx_sw_if_index_set = 1;
5744       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5745         tx_sw_if_index_set = 1;
5746       else if (unformat (i, "dst %U", unformat_ethernet_address,
5747                          dst_mac_address))
5748         dst_set = 1;
5749       else if (unformat (i, "l2-only"))
5750         l2_only = 1;
5751       else if (unformat (i, "del"))
5752         is_add = 0;
5753       else
5754         {
5755           clib_warning ("parse error '%U'", format_unformat_error, i);
5756           return -99;
5757         }
5758     }
5759
5760   if (!dst_set)
5761     {
5762       errmsg ("dst (mac address) not set\n");
5763       return -99;
5764     }
5765   if (!tx_sw_if_index_set)
5766     {
5767       errmsg ("tx-intfc not set\n");
5768       return -99;
5769     }
5770
5771   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5772
5773   mp->vrf_id = ntohl (inner_vrf_id);
5774   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5775   mp->adj_address_length = intfc_address_length;
5776   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5777                sizeof (dst_mac_address));
5778   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5779   mp->l2_only = l2_only;
5780   mp->is_add = is_add;
5781
5782   S;
5783   W;
5784   /* NOTREACHED */
5785   return 0;
5786 }
5787
5788 static int
5789 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5790 {
5791   unformat_input_t *i = vam->input;
5792   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5793   f64 timeout;
5794   u32 inner_vrf_id = 0;
5795   u32 outer_vrf_id = 0;
5796   ip4_address_t adj_address;
5797   int adj_address_set = 0;
5798   ip4_address_t next_hop_address;
5799   int next_hop_address_set = 0;
5800   u32 tmp;
5801   u8 adj_address_length = 0;
5802   u8 l2_only = 0;
5803   u8 is_add = 1;
5804   u32 resolve_attempts = 5;
5805   u8 resolve_if_needed = 1;
5806
5807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5808     {
5809       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5810         ;
5811       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5812         ;
5813       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5814                          &adj_address, &tmp))
5815         {
5816           adj_address_length = tmp;
5817           adj_address_set = 1;
5818         }
5819       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5820                          &next_hop_address))
5821         next_hop_address_set = 1;
5822       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5823         ;
5824       else if (unformat (i, "resolve-if-needed %d", &tmp))
5825         resolve_if_needed = tmp;
5826       else if (unformat (i, "l2-only"))
5827         l2_only = 1;
5828       else if (unformat (i, "del"))
5829         is_add = 0;
5830       else
5831         {
5832           clib_warning ("parse error '%U'", format_unformat_error, i);
5833           return -99;
5834         }
5835     }
5836
5837   if (!adj_address_set)
5838     {
5839       errmsg ("adjacency address/mask not set\n");
5840       return -99;
5841     }
5842   if (!next_hop_address_set)
5843     {
5844       errmsg ("ip4 next hop address (in outer fib) not set\n");
5845       return -99;
5846     }
5847
5848   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5849
5850   mp->inner_vrf_id = ntohl (inner_vrf_id);
5851   mp->outer_vrf_id = ntohl (outer_vrf_id);
5852   mp->resolve_attempts = ntohl (resolve_attempts);
5853   mp->resolve_if_needed = resolve_if_needed;
5854   mp->is_add = is_add;
5855   mp->l2_only = l2_only;
5856   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5857   mp->adj_address_length = adj_address_length;
5858   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5859                sizeof (next_hop_address));
5860
5861   S;
5862   W;
5863   /* NOTREACHED */
5864   return 0;
5865 }
5866
5867 static int
5868 api_sw_interface_set_unnumbered (vat_main_t * vam)
5869 {
5870   unformat_input_t *i = vam->input;
5871   vl_api_sw_interface_set_unnumbered_t *mp;
5872   f64 timeout;
5873   u32 sw_if_index;
5874   u32 unnum_sw_index = ~0;
5875   u8 is_add = 1;
5876   u8 sw_if_index_set = 0;
5877
5878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5879     {
5880       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5881         sw_if_index_set = 1;
5882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5883         sw_if_index_set = 1;
5884       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5885         ;
5886       else if (unformat (i, "del"))
5887         is_add = 0;
5888       else
5889         {
5890           clib_warning ("parse error '%U'", format_unformat_error, i);
5891           return -99;
5892         }
5893     }
5894
5895   if (sw_if_index_set == 0)
5896     {
5897       errmsg ("missing interface name or sw_if_index\n");
5898       return -99;
5899     }
5900
5901   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5902
5903   mp->sw_if_index = ntohl (sw_if_index);
5904   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5905   mp->is_add = is_add;
5906
5907   S;
5908   W;
5909   /* NOTREACHED */
5910   return 0;
5911 }
5912
5913 static int
5914 api_ip_neighbor_add_del (vat_main_t * vam)
5915 {
5916   unformat_input_t *i = vam->input;
5917   vl_api_ip_neighbor_add_del_t *mp;
5918   f64 timeout;
5919   u32 sw_if_index;
5920   u8 sw_if_index_set = 0;
5921   u32 vrf_id = 0;
5922   u8 is_add = 1;
5923   u8 is_static = 0;
5924   u8 mac_address[6];
5925   u8 mac_set = 0;
5926   u8 v4_address_set = 0;
5927   u8 v6_address_set = 0;
5928   ip4_address_t v4address;
5929   ip6_address_t v6address;
5930
5931   memset (mac_address, 0, sizeof (mac_address));
5932
5933   /* Parse args required to build the message */
5934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5935     {
5936       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5937         {
5938           mac_set = 1;
5939         }
5940       else if (unformat (i, "del"))
5941         is_add = 0;
5942       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5943         sw_if_index_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else if (unformat (i, "is_static"))
5947         is_static = 1;
5948       else if (unformat (i, "vrf %d", &vrf_id))
5949         ;
5950       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5951         v4_address_set = 1;
5952       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5953         v6_address_set = 1;
5954       else
5955         {
5956           clib_warning ("parse error '%U'", format_unformat_error, i);
5957           return -99;
5958         }
5959     }
5960
5961   if (sw_if_index_set == 0)
5962     {
5963       errmsg ("missing interface name or sw_if_index\n");
5964       return -99;
5965     }
5966   if (v4_address_set && v6_address_set)
5967     {
5968       errmsg ("both v4 and v6 addresses set\n");
5969       return -99;
5970     }
5971   if (!v4_address_set && !v6_address_set)
5972     {
5973       errmsg ("no address set\n");
5974       return -99;
5975     }
5976
5977   /* Construct the API message */
5978   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5979
5980   mp->sw_if_index = ntohl (sw_if_index);
5981   mp->is_add = is_add;
5982   mp->vrf_id = ntohl (vrf_id);
5983   mp->is_static = is_static;
5984   if (mac_set)
5985     clib_memcpy (mp->mac_address, mac_address, 6);
5986   if (v6_address_set)
5987     {
5988       mp->is_ipv6 = 1;
5989       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
5990     }
5991   else
5992     {
5993       /* mp->is_ipv6 = 0; via memset in M macro above */
5994       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
5995     }
5996
5997   /* send it... */
5998   S;
5999
6000   /* Wait for a reply, return good/bad news  */
6001   W;
6002
6003   /* NOTREACHED */
6004   return 0;
6005 }
6006
6007 static int
6008 api_reset_vrf (vat_main_t * vam)
6009 {
6010   unformat_input_t *i = vam->input;
6011   vl_api_reset_vrf_t *mp;
6012   f64 timeout;
6013   u32 vrf_id = 0;
6014   u8 is_ipv6 = 0;
6015   u8 vrf_id_set = 0;
6016
6017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6018     {
6019       if (unformat (i, "vrf %d", &vrf_id))
6020         vrf_id_set = 1;
6021       else if (unformat (i, "ipv6"))
6022         is_ipv6 = 1;
6023       else
6024         {
6025           clib_warning ("parse error '%U'", format_unformat_error, i);
6026           return -99;
6027         }
6028     }
6029
6030   if (vrf_id_set == 0)
6031     {
6032       errmsg ("missing vrf id\n");
6033       return -99;
6034     }
6035
6036   M (RESET_VRF, reset_vrf);
6037
6038   mp->vrf_id = ntohl (vrf_id);
6039   mp->is_ipv6 = is_ipv6;
6040
6041   S;
6042   W;
6043   /* NOTREACHED */
6044   return 0;
6045 }
6046
6047 static int
6048 api_create_vlan_subif (vat_main_t * vam)
6049 {
6050   unformat_input_t *i = vam->input;
6051   vl_api_create_vlan_subif_t *mp;
6052   f64 timeout;
6053   u32 sw_if_index;
6054   u8 sw_if_index_set = 0;
6055   u32 vlan_id;
6056   u8 vlan_id_set = 0;
6057
6058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6059     {
6060       if (unformat (i, "sw_if_index %d", &sw_if_index))
6061         sw_if_index_set = 1;
6062       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6063         sw_if_index_set = 1;
6064       else if (unformat (i, "vlan %d", &vlan_id))
6065         vlan_id_set = 1;
6066       else
6067         {
6068           clib_warning ("parse error '%U'", format_unformat_error, i);
6069           return -99;
6070         }
6071     }
6072
6073   if (sw_if_index_set == 0)
6074     {
6075       errmsg ("missing interface name or sw_if_index\n");
6076       return -99;
6077     }
6078
6079   if (vlan_id_set == 0)
6080     {
6081       errmsg ("missing vlan_id\n");
6082       return -99;
6083     }
6084   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6085
6086   mp->sw_if_index = ntohl (sw_if_index);
6087   mp->vlan_id = ntohl (vlan_id);
6088
6089   S;
6090   W;
6091   /* NOTREACHED */
6092   return 0;
6093 }
6094
6095 #define foreach_create_subif_bit                \
6096 _(no_tags)                                      \
6097 _(one_tag)                                      \
6098 _(two_tags)                                     \
6099 _(dot1ad)                                       \
6100 _(exact_match)                                  \
6101 _(default_sub)                                  \
6102 _(outer_vlan_id_any)                            \
6103 _(inner_vlan_id_any)
6104
6105 static int
6106 api_create_subif (vat_main_t * vam)
6107 {
6108   unformat_input_t *i = vam->input;
6109   vl_api_create_subif_t *mp;
6110   f64 timeout;
6111   u32 sw_if_index;
6112   u8 sw_if_index_set = 0;
6113   u32 sub_id;
6114   u8 sub_id_set = 0;
6115   u32 no_tags = 0;
6116   u32 one_tag = 0;
6117   u32 two_tags = 0;
6118   u32 dot1ad = 0;
6119   u32 exact_match = 0;
6120   u32 default_sub = 0;
6121   u32 outer_vlan_id_any = 0;
6122   u32 inner_vlan_id_any = 0;
6123   u32 tmp;
6124   u16 outer_vlan_id = 0;
6125   u16 inner_vlan_id = 0;
6126
6127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6128     {
6129       if (unformat (i, "sw_if_index %d", &sw_if_index))
6130         sw_if_index_set = 1;
6131       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6132         sw_if_index_set = 1;
6133       else if (unformat (i, "sub_id %d", &sub_id))
6134         sub_id_set = 1;
6135       else if (unformat (i, "outer_vlan_id %d", &tmp))
6136         outer_vlan_id = tmp;
6137       else if (unformat (i, "inner_vlan_id %d", &tmp))
6138         inner_vlan_id = tmp;
6139
6140 #define _(a) else if (unformat (i, #a)) a = 1 ;
6141       foreach_create_subif_bit
6142 #undef _
6143         else
6144         {
6145           clib_warning ("parse error '%U'", format_unformat_error, i);
6146           return -99;
6147         }
6148     }
6149
6150   if (sw_if_index_set == 0)
6151     {
6152       errmsg ("missing interface name or sw_if_index\n");
6153       return -99;
6154     }
6155
6156   if (sub_id_set == 0)
6157     {
6158       errmsg ("missing sub_id\n");
6159       return -99;
6160     }
6161   M (CREATE_SUBIF, create_subif);
6162
6163   mp->sw_if_index = ntohl (sw_if_index);
6164   mp->sub_id = ntohl (sub_id);
6165
6166 #define _(a) mp->a = a;
6167   foreach_create_subif_bit;
6168 #undef _
6169
6170   mp->outer_vlan_id = ntohs (outer_vlan_id);
6171   mp->inner_vlan_id = ntohs (inner_vlan_id);
6172
6173   S;
6174   W;
6175   /* NOTREACHED */
6176   return 0;
6177 }
6178
6179 static int
6180 api_oam_add_del (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_oam_add_del_t *mp;
6184   f64 timeout;
6185   u32 vrf_id = 0;
6186   u8 is_add = 1;
6187   ip4_address_t src, dst;
6188   u8 src_set = 0;
6189   u8 dst_set = 0;
6190
6191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6192     {
6193       if (unformat (i, "vrf %d", &vrf_id))
6194         ;
6195       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6196         src_set = 1;
6197       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6198         dst_set = 1;
6199       else if (unformat (i, "del"))
6200         is_add = 0;
6201       else
6202         {
6203           clib_warning ("parse error '%U'", format_unformat_error, i);
6204           return -99;
6205         }
6206     }
6207
6208   if (src_set == 0)
6209     {
6210       errmsg ("missing src addr\n");
6211       return -99;
6212     }
6213
6214   if (dst_set == 0)
6215     {
6216       errmsg ("missing dst addr\n");
6217       return -99;
6218     }
6219
6220   M (OAM_ADD_DEL, oam_add_del);
6221
6222   mp->vrf_id = ntohl (vrf_id);
6223   mp->is_add = is_add;
6224   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6225   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6226
6227   S;
6228   W;
6229   /* NOTREACHED */
6230   return 0;
6231 }
6232
6233 static int
6234 api_reset_fib (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_reset_fib_t *mp;
6238   f64 timeout;
6239   u32 vrf_id = 0;
6240   u8 is_ipv6 = 0;
6241   u8 vrf_id_set = 0;
6242
6243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6244     {
6245       if (unformat (i, "vrf %d", &vrf_id))
6246         vrf_id_set = 1;
6247       else if (unformat (i, "ipv6"))
6248         is_ipv6 = 1;
6249       else
6250         {
6251           clib_warning ("parse error '%U'", format_unformat_error, i);
6252           return -99;
6253         }
6254     }
6255
6256   if (vrf_id_set == 0)
6257     {
6258       errmsg ("missing vrf id\n");
6259       return -99;
6260     }
6261
6262   M (RESET_FIB, reset_fib);
6263
6264   mp->vrf_id = ntohl (vrf_id);
6265   mp->is_ipv6 = is_ipv6;
6266
6267   S;
6268   W;
6269   /* NOTREACHED */
6270   return 0;
6271 }
6272
6273 static int
6274 api_dhcp_proxy_config (vat_main_t * vam)
6275 {
6276   unformat_input_t *i = vam->input;
6277   vl_api_dhcp_proxy_config_t *mp;
6278   f64 timeout;
6279   u32 vrf_id = 0;
6280   u8 is_add = 1;
6281   u8 insert_cid = 1;
6282   u8 v4_address_set = 0;
6283   u8 v6_address_set = 0;
6284   ip4_address_t v4address;
6285   ip6_address_t v6address;
6286   u8 v4_src_address_set = 0;
6287   u8 v6_src_address_set = 0;
6288   ip4_address_t v4srcaddress;
6289   ip6_address_t v6srcaddress;
6290
6291   /* Parse args required to build the message */
6292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6293     {
6294       if (unformat (i, "del"))
6295         is_add = 0;
6296       else if (unformat (i, "vrf %d", &vrf_id))
6297         ;
6298       else if (unformat (i, "insert-cid %d", &insert_cid))
6299         ;
6300       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6301         v4_address_set = 1;
6302       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6303         v6_address_set = 1;
6304       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6305         v4_src_address_set = 1;
6306       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6307         v6_src_address_set = 1;
6308       else
6309         break;
6310     }
6311
6312   if (v4_address_set && v6_address_set)
6313     {
6314       errmsg ("both v4 and v6 server addresses set\n");
6315       return -99;
6316     }
6317   if (!v4_address_set && !v6_address_set)
6318     {
6319       errmsg ("no server addresses set\n");
6320       return -99;
6321     }
6322
6323   if (v4_src_address_set && v6_src_address_set)
6324     {
6325       errmsg ("both v4 and v6  src addresses set\n");
6326       return -99;
6327     }
6328   if (!v4_src_address_set && !v6_src_address_set)
6329     {
6330       errmsg ("no src addresses set\n");
6331       return -99;
6332     }
6333
6334   if (!(v4_src_address_set && v4_address_set) &&
6335       !(v6_src_address_set && v6_address_set))
6336     {
6337       errmsg ("no matching server and src addresses set\n");
6338       return -99;
6339     }
6340
6341   /* Construct the API message */
6342   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6343
6344   mp->insert_circuit_id = insert_cid;
6345   mp->is_add = is_add;
6346   mp->vrf_id = ntohl (vrf_id);
6347   if (v6_address_set)
6348     {
6349       mp->is_ipv6 = 1;
6350       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6351       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6352     }
6353   else
6354     {
6355       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6356       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6357     }
6358
6359   /* send it... */
6360   S;
6361
6362   /* Wait for a reply, return good/bad news  */
6363   W;
6364   /* NOTREACHED */
6365   return 0;
6366 }
6367
6368 static int
6369 api_dhcp_proxy_config_2 (vat_main_t * vam)
6370 {
6371   unformat_input_t *i = vam->input;
6372   vl_api_dhcp_proxy_config_2_t *mp;
6373   f64 timeout;
6374   u32 rx_vrf_id = 0;
6375   u32 server_vrf_id = 0;
6376   u8 is_add = 1;
6377   u8 insert_cid = 1;
6378   u8 v4_address_set = 0;
6379   u8 v6_address_set = 0;
6380   ip4_address_t v4address;
6381   ip6_address_t v6address;
6382   u8 v4_src_address_set = 0;
6383   u8 v6_src_address_set = 0;
6384   ip4_address_t v4srcaddress;
6385   ip6_address_t v6srcaddress;
6386
6387   /* Parse args required to build the message */
6388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6389     {
6390       if (unformat (i, "del"))
6391         is_add = 0;
6392       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6393         ;
6394       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6395         ;
6396       else if (unformat (i, "insert-cid %d", &insert_cid))
6397         ;
6398       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6399         v4_address_set = 1;
6400       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6401         v6_address_set = 1;
6402       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6403         v4_src_address_set = 1;
6404       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6405         v6_src_address_set = 1;
6406       else
6407         break;
6408     }
6409
6410   if (v4_address_set && v6_address_set)
6411     {
6412       errmsg ("both v4 and v6 server addresses set\n");
6413       return -99;
6414     }
6415   if (!v4_address_set && !v6_address_set)
6416     {
6417       errmsg ("no server addresses set\n");
6418       return -99;
6419     }
6420
6421   if (v4_src_address_set && v6_src_address_set)
6422     {
6423       errmsg ("both v4 and v6  src addresses set\n");
6424       return -99;
6425     }
6426   if (!v4_src_address_set && !v6_src_address_set)
6427     {
6428       errmsg ("no src addresses set\n");
6429       return -99;
6430     }
6431
6432   if (!(v4_src_address_set && v4_address_set) &&
6433       !(v6_src_address_set && v6_address_set))
6434     {
6435       errmsg ("no matching server and src addresses set\n");
6436       return -99;
6437     }
6438
6439   /* Construct the API message */
6440   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6441
6442   mp->insert_circuit_id = insert_cid;
6443   mp->is_add = is_add;
6444   mp->rx_vrf_id = ntohl (rx_vrf_id);
6445   mp->server_vrf_id = ntohl (server_vrf_id);
6446   if (v6_address_set)
6447     {
6448       mp->is_ipv6 = 1;
6449       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6450       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6451     }
6452   else
6453     {
6454       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6455       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6456     }
6457
6458   /* send it... */
6459   S;
6460
6461   /* Wait for a reply, return good/bad news  */
6462   W;
6463   /* NOTREACHED */
6464   return 0;
6465 }
6466
6467 static int
6468 api_dhcp_proxy_set_vss (vat_main_t * vam)
6469 {
6470   unformat_input_t *i = vam->input;
6471   vl_api_dhcp_proxy_set_vss_t *mp;
6472   f64 timeout;
6473   u8 is_ipv6 = 0;
6474   u8 is_add = 1;
6475   u32 tbl_id;
6476   u8 tbl_id_set = 0;
6477   u32 oui;
6478   u8 oui_set = 0;
6479   u32 fib_id;
6480   u8 fib_id_set = 0;
6481
6482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6483     {
6484       if (unformat (i, "tbl_id %d", &tbl_id))
6485         tbl_id_set = 1;
6486       if (unformat (i, "fib_id %d", &fib_id))
6487         fib_id_set = 1;
6488       if (unformat (i, "oui %d", &oui))
6489         oui_set = 1;
6490       else if (unformat (i, "ipv6"))
6491         is_ipv6 = 1;
6492       else if (unformat (i, "del"))
6493         is_add = 0;
6494       else
6495         {
6496           clib_warning ("parse error '%U'", format_unformat_error, i);
6497           return -99;
6498         }
6499     }
6500
6501   if (tbl_id_set == 0)
6502     {
6503       errmsg ("missing tbl id\n");
6504       return -99;
6505     }
6506
6507   if (fib_id_set == 0)
6508     {
6509       errmsg ("missing fib id\n");
6510       return -99;
6511     }
6512   if (oui_set == 0)
6513     {
6514       errmsg ("missing oui\n");
6515       return -99;
6516     }
6517
6518   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6519   mp->tbl_id = ntohl (tbl_id);
6520   mp->fib_id = ntohl (fib_id);
6521   mp->oui = ntohl (oui);
6522   mp->is_ipv6 = is_ipv6;
6523   mp->is_add = is_add;
6524
6525   S;
6526   W;
6527   /* NOTREACHED */
6528   return 0;
6529 }
6530
6531 static int
6532 api_dhcp_client_config (vat_main_t * vam)
6533 {
6534   unformat_input_t *i = vam->input;
6535   vl_api_dhcp_client_config_t *mp;
6536   f64 timeout;
6537   u32 sw_if_index;
6538   u8 sw_if_index_set = 0;
6539   u8 is_add = 1;
6540   u8 *hostname = 0;
6541   u8 disable_event = 0;
6542
6543   /* Parse args required to build the message */
6544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6545     {
6546       if (unformat (i, "del"))
6547         is_add = 0;
6548       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6549         sw_if_index_set = 1;
6550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6551         sw_if_index_set = 1;
6552       else if (unformat (i, "hostname %s", &hostname))
6553         ;
6554       else if (unformat (i, "disable_event"))
6555         disable_event = 1;
6556       else
6557         break;
6558     }
6559
6560   if (sw_if_index_set == 0)
6561     {
6562       errmsg ("missing interface name or sw_if_index\n");
6563       return -99;
6564     }
6565
6566   if (vec_len (hostname) > 63)
6567     {
6568       errmsg ("hostname too long\n");
6569     }
6570   vec_add1 (hostname, 0);
6571
6572   /* Construct the API message */
6573   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6574
6575   mp->sw_if_index = ntohl (sw_if_index);
6576   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6577   vec_free (hostname);
6578   mp->is_add = is_add;
6579   mp->want_dhcp_event = disable_event ? 0 : 1;
6580   mp->pid = getpid ();
6581
6582   /* send it... */
6583   S;
6584
6585   /* Wait for a reply, return good/bad news  */
6586   W;
6587   /* NOTREACHED */
6588   return 0;
6589 }
6590
6591 static int
6592 api_set_ip_flow_hash (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_set_ip_flow_hash_t *mp;
6596   f64 timeout;
6597   u32 vrf_id = 0;
6598   u8 is_ipv6 = 0;
6599   u8 vrf_id_set = 0;
6600   u8 src = 0;
6601   u8 dst = 0;
6602   u8 sport = 0;
6603   u8 dport = 0;
6604   u8 proto = 0;
6605   u8 reverse = 0;
6606
6607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6608     {
6609       if (unformat (i, "vrf %d", &vrf_id))
6610         vrf_id_set = 1;
6611       else if (unformat (i, "ipv6"))
6612         is_ipv6 = 1;
6613       else if (unformat (i, "src"))
6614         src = 1;
6615       else if (unformat (i, "dst"))
6616         dst = 1;
6617       else if (unformat (i, "sport"))
6618         sport = 1;
6619       else if (unformat (i, "dport"))
6620         dport = 1;
6621       else if (unformat (i, "proto"))
6622         proto = 1;
6623       else if (unformat (i, "reverse"))
6624         reverse = 1;
6625
6626       else
6627         {
6628           clib_warning ("parse error '%U'", format_unformat_error, i);
6629           return -99;
6630         }
6631     }
6632
6633   if (vrf_id_set == 0)
6634     {
6635       errmsg ("missing vrf id\n");
6636       return -99;
6637     }
6638
6639   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6640   mp->src = src;
6641   mp->dst = dst;
6642   mp->sport = sport;
6643   mp->dport = dport;
6644   mp->proto = proto;
6645   mp->reverse = reverse;
6646   mp->vrf_id = ntohl (vrf_id);
6647   mp->is_ipv6 = is_ipv6;
6648
6649   S;
6650   W;
6651   /* NOTREACHED */
6652   return 0;
6653 }
6654
6655 static int
6656 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6657 {
6658   unformat_input_t *i = vam->input;
6659   vl_api_sw_interface_ip6_enable_disable_t *mp;
6660   f64 timeout;
6661   u32 sw_if_index;
6662   u8 sw_if_index_set = 0;
6663   u8 enable = 0;
6664
6665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6666     {
6667       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6668         sw_if_index_set = 1;
6669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6670         sw_if_index_set = 1;
6671       else if (unformat (i, "enable"))
6672         enable = 1;
6673       else if (unformat (i, "disable"))
6674         enable = 0;
6675       else
6676         {
6677           clib_warning ("parse error '%U'", format_unformat_error, i);
6678           return -99;
6679         }
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index\n");
6685       return -99;
6686     }
6687
6688   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6689
6690   mp->sw_if_index = ntohl (sw_if_index);
6691   mp->enable = enable;
6692
6693   S;
6694   W;
6695   /* NOTREACHED */
6696   return 0;
6697 }
6698
6699 static int
6700 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6701 {
6702   unformat_input_t *i = vam->input;
6703   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6704   f64 timeout;
6705   u32 sw_if_index;
6706   u8 sw_if_index_set = 0;
6707   u32 address_length = 0;
6708   u8 v6_address_set = 0;
6709   ip6_address_t v6address;
6710
6711   /* Parse args required to build the message */
6712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6713     {
6714       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6717         sw_if_index_set = 1;
6718       else if (unformat (i, "%U/%d",
6719                          unformat_ip6_address, &v6address, &address_length))
6720         v6_address_set = 1;
6721       else
6722         break;
6723     }
6724
6725   if (sw_if_index_set == 0)
6726     {
6727       errmsg ("missing interface name or sw_if_index\n");
6728       return -99;
6729     }
6730   if (!v6_address_set)
6731     {
6732       errmsg ("no address set\n");
6733       return -99;
6734     }
6735
6736   /* Construct the API message */
6737   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6738      sw_interface_ip6_set_link_local_address);
6739
6740   mp->sw_if_index = ntohl (sw_if_index);
6741   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6742   mp->address_length = address_length;
6743
6744   /* send it... */
6745   S;
6746
6747   /* Wait for a reply, return good/bad news  */
6748   W;
6749
6750   /* NOTREACHED */
6751   return 0;
6752 }
6753
6754
6755 static int
6756 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6757 {
6758   unformat_input_t *i = vam->input;
6759   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6760   f64 timeout;
6761   u32 sw_if_index;
6762   u8 sw_if_index_set = 0;
6763   u32 address_length = 0;
6764   u8 v6_address_set = 0;
6765   ip6_address_t v6address;
6766   u8 use_default = 0;
6767   u8 no_advertise = 0;
6768   u8 off_link = 0;
6769   u8 no_autoconfig = 0;
6770   u8 no_onlink = 0;
6771   u8 is_no = 0;
6772   u32 val_lifetime = 0;
6773   u32 pref_lifetime = 0;
6774
6775   /* Parse args required to build the message */
6776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6777     {
6778       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6779         sw_if_index_set = 1;
6780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6781         sw_if_index_set = 1;
6782       else if (unformat (i, "%U/%d",
6783                          unformat_ip6_address, &v6address, &address_length))
6784         v6_address_set = 1;
6785       else if (unformat (i, "val_life %d", &val_lifetime))
6786         ;
6787       else if (unformat (i, "pref_life %d", &pref_lifetime))
6788         ;
6789       else if (unformat (i, "def"))
6790         use_default = 1;
6791       else if (unformat (i, "noadv"))
6792         no_advertise = 1;
6793       else if (unformat (i, "offl"))
6794         off_link = 1;
6795       else if (unformat (i, "noauto"))
6796         no_autoconfig = 1;
6797       else if (unformat (i, "nolink"))
6798         no_onlink = 1;
6799       else if (unformat (i, "isno"))
6800         is_no = 1;
6801       else
6802         {
6803           clib_warning ("parse error '%U'", format_unformat_error, i);
6804           return -99;
6805         }
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index\n");
6811       return -99;
6812     }
6813   if (!v6_address_set)
6814     {
6815       errmsg ("no address set\n");
6816       return -99;
6817     }
6818
6819   /* Construct the API message */
6820   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6821
6822   mp->sw_if_index = ntohl (sw_if_index);
6823   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6824   mp->address_length = address_length;
6825   mp->use_default = use_default;
6826   mp->no_advertise = no_advertise;
6827   mp->off_link = off_link;
6828   mp->no_autoconfig = no_autoconfig;
6829   mp->no_onlink = no_onlink;
6830   mp->is_no = is_no;
6831   mp->val_lifetime = ntohl (val_lifetime);
6832   mp->pref_lifetime = ntohl (pref_lifetime);
6833
6834   /* send it... */
6835   S;
6836
6837   /* Wait for a reply, return good/bad news  */
6838   W;
6839
6840   /* NOTREACHED */
6841   return 0;
6842 }
6843
6844 static int
6845 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6846 {
6847   unformat_input_t *i = vam->input;
6848   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6849   f64 timeout;
6850   u32 sw_if_index;
6851   u8 sw_if_index_set = 0;
6852   u8 suppress = 0;
6853   u8 managed = 0;
6854   u8 other = 0;
6855   u8 ll_option = 0;
6856   u8 send_unicast = 0;
6857   u8 cease = 0;
6858   u8 is_no = 0;
6859   u8 default_router = 0;
6860   u32 max_interval = 0;
6861   u32 min_interval = 0;
6862   u32 lifetime = 0;
6863   u32 initial_count = 0;
6864   u32 initial_interval = 0;
6865
6866
6867   /* Parse args required to build the message */
6868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6869     {
6870       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6871         sw_if_index_set = 1;
6872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6873         sw_if_index_set = 1;
6874       else if (unformat (i, "maxint %d", &max_interval))
6875         ;
6876       else if (unformat (i, "minint %d", &min_interval))
6877         ;
6878       else if (unformat (i, "life %d", &lifetime))
6879         ;
6880       else if (unformat (i, "count %d", &initial_count))
6881         ;
6882       else if (unformat (i, "interval %d", &initial_interval))
6883         ;
6884       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6885         suppress = 1;
6886       else if (unformat (i, "managed"))
6887         managed = 1;
6888       else if (unformat (i, "other"))
6889         other = 1;
6890       else if (unformat (i, "ll"))
6891         ll_option = 1;
6892       else if (unformat (i, "send"))
6893         send_unicast = 1;
6894       else if (unformat (i, "cease"))
6895         cease = 1;
6896       else if (unformat (i, "isno"))
6897         is_no = 1;
6898       else if (unformat (i, "def"))
6899         default_router = 1;
6900       else
6901         {
6902           clib_warning ("parse error '%U'", format_unformat_error, i);
6903           return -99;
6904         }
6905     }
6906
6907   if (sw_if_index_set == 0)
6908     {
6909       errmsg ("missing interface name or sw_if_index\n");
6910       return -99;
6911     }
6912
6913   /* Construct the API message */
6914   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6915
6916   mp->sw_if_index = ntohl (sw_if_index);
6917   mp->max_interval = ntohl (max_interval);
6918   mp->min_interval = ntohl (min_interval);
6919   mp->lifetime = ntohl (lifetime);
6920   mp->initial_count = ntohl (initial_count);
6921   mp->initial_interval = ntohl (initial_interval);
6922   mp->suppress = suppress;
6923   mp->managed = managed;
6924   mp->other = other;
6925   mp->ll_option = ll_option;
6926   mp->send_unicast = send_unicast;
6927   mp->cease = cease;
6928   mp->is_no = is_no;
6929   mp->default_router = default_router;
6930
6931   /* send it... */
6932   S;
6933
6934   /* Wait for a reply, return good/bad news  */
6935   W;
6936
6937   /* NOTREACHED */
6938   return 0;
6939 }
6940
6941 static int
6942 api_set_arp_neighbor_limit (vat_main_t * vam)
6943 {
6944   unformat_input_t *i = vam->input;
6945   vl_api_set_arp_neighbor_limit_t *mp;
6946   f64 timeout;
6947   u32 arp_nbr_limit;
6948   u8 limit_set = 0;
6949   u8 is_ipv6 = 0;
6950
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6954         limit_set = 1;
6955       else if (unformat (i, "ipv6"))
6956         is_ipv6 = 1;
6957       else
6958         {
6959           clib_warning ("parse error '%U'", format_unformat_error, i);
6960           return -99;
6961         }
6962     }
6963
6964   if (limit_set == 0)
6965     {
6966       errmsg ("missing limit value\n");
6967       return -99;
6968     }
6969
6970   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6971
6972   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
6973   mp->is_ipv6 = is_ipv6;
6974
6975   S;
6976   W;
6977   /* NOTREACHED */
6978   return 0;
6979 }
6980
6981 static int
6982 api_l2_patch_add_del (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_l2_patch_add_del_t *mp;
6986   f64 timeout;
6987   u32 rx_sw_if_index;
6988   u8 rx_sw_if_index_set = 0;
6989   u32 tx_sw_if_index;
6990   u8 tx_sw_if_index_set = 0;
6991   u8 is_add = 1;
6992
6993   /* Parse args required to build the message */
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6997         rx_sw_if_index_set = 1;
6998       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6999         tx_sw_if_index_set = 1;
7000       else if (unformat (i, "rx"))
7001         {
7002           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7003             {
7004               if (unformat (i, "%U", unformat_sw_if_index, vam,
7005                             &rx_sw_if_index))
7006                 rx_sw_if_index_set = 1;
7007             }
7008           else
7009             break;
7010         }
7011       else if (unformat (i, "tx"))
7012         {
7013           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014             {
7015               if (unformat (i, "%U", unformat_sw_if_index, vam,
7016                             &tx_sw_if_index))
7017                 tx_sw_if_index_set = 1;
7018             }
7019           else
7020             break;
7021         }
7022       else if (unformat (i, "del"))
7023         is_add = 0;
7024       else
7025         break;
7026     }
7027
7028   if (rx_sw_if_index_set == 0)
7029     {
7030       errmsg ("missing rx interface name or rx_sw_if_index\n");
7031       return -99;
7032     }
7033
7034   if (tx_sw_if_index_set == 0)
7035     {
7036       errmsg ("missing tx interface name or tx_sw_if_index\n");
7037       return -99;
7038     }
7039
7040   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7041
7042   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7043   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7044   mp->is_add = is_add;
7045
7046   S;
7047   W;
7048   /* NOTREACHED */
7049   return 0;
7050 }
7051
7052 static int
7053 api_trace_profile_add (vat_main_t * vam)
7054 {
7055   unformat_input_t *input = vam->input;
7056   vl_api_trace_profile_add_t *mp;
7057   f64 timeout;
7058   u32 id = 0;
7059   u32 trace_option_elts = 0;
7060   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7061   int has_pow_option = 0;
7062   int has_ppc_option = 0;
7063
7064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7065     {
7066       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7067                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7068                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7069                     &node_id, &app_data))
7070         ;
7071       else if (unformat (input, "pow"))
7072         has_pow_option = 1;
7073       else if (unformat (input, "ppc encap"))
7074         has_ppc_option = PPC_ENCAP;
7075       else if (unformat (input, "ppc decap"))
7076         has_ppc_option = PPC_DECAP;
7077       else if (unformat (input, "ppc none"))
7078         has_ppc_option = PPC_NONE;
7079       else
7080         break;
7081     }
7082   M (TRACE_PROFILE_ADD, trace_profile_add);
7083   mp->id = htons (id);
7084   mp->trace_type = trace_type;
7085   mp->trace_num_elt = trace_option_elts;
7086   mp->trace_ppc = has_ppc_option;
7087   mp->trace_app_data = htonl (app_data);
7088   mp->pow_enable = has_pow_option;
7089   mp->trace_tsp = trace_tsp;
7090   mp->node_id = htonl (node_id);
7091
7092   S;
7093   W;
7094
7095   return (0);
7096
7097 }
7098
7099 static int
7100 api_trace_profile_apply (vat_main_t * vam)
7101 {
7102   unformat_input_t *input = vam->input;
7103   vl_api_trace_profile_apply_t *mp;
7104   f64 timeout;
7105   ip6_address_t addr;
7106   u32 mask_width = ~0;
7107   int is_add = 0;
7108   int is_pop = 0;
7109   int is_none = 0;
7110   u32 vrf_id = 0;
7111   u32 id = 0;
7112
7113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7114     {
7115       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7116         ;
7117       else if (unformat (input, "id %d", &id))
7118         ;
7119       else if (unformat (input, "vrf-id %d", &vrf_id))
7120         ;
7121       else if (unformat (input, "add"))
7122         is_add = 1;
7123       else if (unformat (input, "pop"))
7124         is_pop = 1;
7125       else if (unformat (input, "none"))
7126         is_none = 1;
7127       else
7128         break;
7129     }
7130
7131   if ((is_add + is_pop + is_none) != 1)
7132     {
7133       errmsg ("One of (add, pop, none) required");
7134       return -99;
7135     }
7136   if (mask_width == ~0)
7137     {
7138       errmsg ("<address>/<mask-width> required");
7139       return -99;
7140     }
7141   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7142   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7143   mp->id = htons (id);
7144   mp->prefix_length = htonl (mask_width);
7145   mp->vrf_id = htonl (vrf_id);
7146   if (is_add)
7147     mp->trace_op = IOAM_HBYH_ADD;
7148   else if (is_pop)
7149     mp->trace_op = IOAM_HBYH_POP;
7150   else
7151     mp->trace_op = IOAM_HBYH_MOD;
7152
7153   if (is_none)
7154     mp->enable = 0;
7155   else
7156     mp->enable = 1;
7157
7158   S;
7159   W;
7160
7161   return 0;
7162 }
7163
7164 static int
7165 api_trace_profile_del (vat_main_t * vam)
7166 {
7167   vl_api_trace_profile_del_t *mp;
7168   f64 timeout;
7169
7170   M (TRACE_PROFILE_DEL, trace_profile_del);
7171   S;
7172   W;
7173   return 0;
7174 }
7175
7176 static int
7177 api_sr_tunnel_add_del (vat_main_t * vam)
7178 {
7179   unformat_input_t *i = vam->input;
7180   vl_api_sr_tunnel_add_del_t *mp;
7181   f64 timeout;
7182   int is_del = 0;
7183   int pl_index;
7184   ip6_address_t src_address;
7185   int src_address_set = 0;
7186   ip6_address_t dst_address;
7187   u32 dst_mask_width;
7188   int dst_address_set = 0;
7189   u16 flags = 0;
7190   u32 rx_table_id = 0;
7191   u32 tx_table_id = 0;
7192   ip6_address_t *segments = 0;
7193   ip6_address_t *this_seg;
7194   ip6_address_t *tags = 0;
7195   ip6_address_t *this_tag;
7196   ip6_address_t next_address, tag;
7197   u8 *name = 0;
7198   u8 *policy_name = 0;
7199
7200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7201     {
7202       if (unformat (i, "del"))
7203         is_del = 1;
7204       else if (unformat (i, "name %s", &name))
7205         ;
7206       else if (unformat (i, "policy %s", &policy_name))
7207         ;
7208       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7209         ;
7210       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7211         ;
7212       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7213         src_address_set = 1;
7214       else if (unformat (i, "dst %U/%d",
7215                          unformat_ip6_address, &dst_address, &dst_mask_width))
7216         dst_address_set = 1;
7217       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7218         {
7219           vec_add2 (segments, this_seg, 1);
7220           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7221                        sizeof (*this_seg));
7222         }
7223       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7224         {
7225           vec_add2 (tags, this_tag, 1);
7226           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7227         }
7228       else if (unformat (i, "clean"))
7229         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7230       else if (unformat (i, "protected"))
7231         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7232       else if (unformat (i, "InPE %d", &pl_index))
7233         {
7234           if (pl_index <= 0 || pl_index > 4)
7235             {
7236             pl_index_range_error:
7237               errmsg ("pl index %d out of range\n", pl_index);
7238               return -99;
7239             }
7240           flags |=
7241             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7242         }
7243       else if (unformat (i, "EgPE %d", &pl_index))
7244         {
7245           if (pl_index <= 0 || pl_index > 4)
7246             goto pl_index_range_error;
7247           flags |=
7248             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7249         }
7250       else if (unformat (i, "OrgSrc %d", &pl_index))
7251         {
7252           if (pl_index <= 0 || pl_index > 4)
7253             goto pl_index_range_error;
7254           flags |=
7255             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7256         }
7257       else
7258         break;
7259     }
7260
7261   if (!src_address_set)
7262     {
7263       errmsg ("src address required\n");
7264       return -99;
7265     }
7266
7267   if (!dst_address_set)
7268     {
7269       errmsg ("dst address required\n");
7270       return -99;
7271     }
7272
7273   if (!segments)
7274     {
7275       errmsg ("at least one sr segment required\n");
7276       return -99;
7277     }
7278
7279   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7280       vec_len (segments) * sizeof (ip6_address_t)
7281       + vec_len (tags) * sizeof (ip6_address_t));
7282
7283   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7284   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7285   mp->dst_mask_width = dst_mask_width;
7286   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7287   mp->n_segments = vec_len (segments);
7288   mp->n_tags = vec_len (tags);
7289   mp->is_add = is_del == 0;
7290   clib_memcpy (mp->segs_and_tags, segments,
7291                vec_len (segments) * sizeof (ip6_address_t));
7292   clib_memcpy (mp->segs_and_tags +
7293                vec_len (segments) * sizeof (ip6_address_t), tags,
7294                vec_len (tags) * sizeof (ip6_address_t));
7295
7296   mp->outer_vrf_id = ntohl (rx_table_id);
7297   mp->inner_vrf_id = ntohl (tx_table_id);
7298   memcpy (mp->name, name, vec_len (name));
7299   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7300
7301   vec_free (segments);
7302   vec_free (tags);
7303
7304   S;
7305   W;
7306   /* NOTREACHED */
7307 }
7308
7309 static int
7310 api_sr_policy_add_del (vat_main_t * vam)
7311 {
7312   unformat_input_t *input = vam->input;
7313   vl_api_sr_policy_add_del_t *mp;
7314   f64 timeout;
7315   int is_del = 0;
7316   u8 *name = 0;
7317   u8 *tunnel_name = 0;
7318   u8 **tunnel_names = 0;
7319
7320   int name_set = 0;
7321   int tunnel_set = 0;
7322   int j = 0;
7323   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7324   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7325
7326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7327     {
7328       if (unformat (input, "del"))
7329         is_del = 1;
7330       else if (unformat (input, "name %s", &name))
7331         name_set = 1;
7332       else if (unformat (input, "tunnel %s", &tunnel_name))
7333         {
7334           if (tunnel_name)
7335             {
7336               vec_add1 (tunnel_names, tunnel_name);
7337               /* For serializer:
7338                  - length = #bytes to store in serial vector
7339                  - +1 = byte to store that length
7340                */
7341               tunnel_names_length += (vec_len (tunnel_name) + 1);
7342               tunnel_set = 1;
7343               tunnel_name = 0;
7344             }
7345         }
7346       else
7347         break;
7348     }
7349
7350   if (!name_set)
7351     {
7352       errmsg ("policy name required\n");
7353       return -99;
7354     }
7355
7356   if ((!tunnel_set) && (!is_del))
7357     {
7358       errmsg ("tunnel name required\n");
7359       return -99;
7360     }
7361
7362   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7363
7364
7365
7366   mp->is_add = !is_del;
7367
7368   memcpy (mp->name, name, vec_len (name));
7369   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7370   u8 *serial_orig = 0;
7371   vec_validate (serial_orig, tunnel_names_length);
7372   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7373   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7374
7375   for (j = 0; j < vec_len (tunnel_names); j++)
7376     {
7377       tun_name_len = vec_len (tunnel_names[j]);
7378       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7379       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7380       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7381       serial_orig += tun_name_len;      // Advance past the copy
7382     }
7383   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7384
7385   vec_free (tunnel_names);
7386   vec_free (tunnel_name);
7387
7388   S;
7389   W;
7390   /* NOTREACHED */
7391 }
7392
7393 static int
7394 api_sr_multicast_map_add_del (vat_main_t * vam)
7395 {
7396   unformat_input_t *input = vam->input;
7397   vl_api_sr_multicast_map_add_del_t *mp;
7398   f64 timeout;
7399   int is_del = 0;
7400   ip6_address_t multicast_address;
7401   u8 *policy_name = 0;
7402   int multicast_address_set = 0;
7403
7404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7405     {
7406       if (unformat (input, "del"))
7407         is_del = 1;
7408       else
7409         if (unformat
7410             (input, "address %U", unformat_ip6_address, &multicast_address))
7411         multicast_address_set = 1;
7412       else if (unformat (input, "sr-policy %s", &policy_name))
7413         ;
7414       else
7415         break;
7416     }
7417
7418   if (!is_del && !policy_name)
7419     {
7420       errmsg ("sr-policy name required\n");
7421       return -99;
7422     }
7423
7424
7425   if (!multicast_address_set)
7426     {
7427       errmsg ("address required\n");
7428       return -99;
7429     }
7430
7431   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7432
7433   mp->is_add = !is_del;
7434   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7435   clib_memcpy (mp->multicast_address, &multicast_address,
7436                sizeof (mp->multicast_address));
7437
7438
7439   vec_free (policy_name);
7440
7441   S;
7442   W;
7443   /* NOTREACHED */
7444 }
7445
7446
7447 #define foreach_ip4_proto_field                 \
7448 _(src_address)                                  \
7449 _(dst_address)                                  \
7450 _(tos)                                          \
7451 _(length)                                       \
7452 _(fragment_id)                                  \
7453 _(ttl)                                          \
7454 _(protocol)                                     \
7455 _(checksum)
7456
7457 uword
7458 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7459 {
7460   u8 **maskp = va_arg (*args, u8 **);
7461   u8 *mask = 0;
7462   u8 found_something = 0;
7463   ip4_header_t *ip;
7464
7465 #define _(a) u8 a=0;
7466   foreach_ip4_proto_field;
7467 #undef _
7468   u8 version = 0;
7469   u8 hdr_length = 0;
7470
7471
7472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7473     {
7474       if (unformat (input, "version"))
7475         version = 1;
7476       else if (unformat (input, "hdr_length"))
7477         hdr_length = 1;
7478       else if (unformat (input, "src"))
7479         src_address = 1;
7480       else if (unformat (input, "dst"))
7481         dst_address = 1;
7482       else if (unformat (input, "proto"))
7483         protocol = 1;
7484
7485 #define _(a) else if (unformat (input, #a)) a=1;
7486       foreach_ip4_proto_field
7487 #undef _
7488         else
7489         break;
7490     }
7491
7492 #define _(a) found_something += a;
7493   foreach_ip4_proto_field;
7494 #undef _
7495
7496   if (found_something == 0)
7497     return 0;
7498
7499   vec_validate (mask, sizeof (*ip) - 1);
7500
7501   ip = (ip4_header_t *) mask;
7502
7503 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7504   foreach_ip4_proto_field;
7505 #undef _
7506
7507   ip->ip_version_and_header_length = 0;
7508
7509   if (version)
7510     ip->ip_version_and_header_length |= 0xF0;
7511
7512   if (hdr_length)
7513     ip->ip_version_and_header_length |= 0x0F;
7514
7515   *maskp = mask;
7516   return 1;
7517 }
7518
7519 #define foreach_ip6_proto_field                 \
7520 _(src_address)                                  \
7521 _(dst_address)                                  \
7522 _(payload_length)                               \
7523 _(hop_limit)                                    \
7524 _(protocol)
7525
7526 uword
7527 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7528 {
7529   u8 **maskp = va_arg (*args, u8 **);
7530   u8 *mask = 0;
7531   u8 found_something = 0;
7532   ip6_header_t *ip;
7533   u32 ip_version_traffic_class_and_flow_label;
7534
7535 #define _(a) u8 a=0;
7536   foreach_ip6_proto_field;
7537 #undef _
7538   u8 version = 0;
7539   u8 traffic_class = 0;
7540   u8 flow_label = 0;
7541
7542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7543     {
7544       if (unformat (input, "version"))
7545         version = 1;
7546       else if (unformat (input, "traffic-class"))
7547         traffic_class = 1;
7548       else if (unformat (input, "flow-label"))
7549         flow_label = 1;
7550       else if (unformat (input, "src"))
7551         src_address = 1;
7552       else if (unformat (input, "dst"))
7553         dst_address = 1;
7554       else if (unformat (input, "proto"))
7555         protocol = 1;
7556
7557 #define _(a) else if (unformat (input, #a)) a=1;
7558       foreach_ip6_proto_field
7559 #undef _
7560         else
7561         break;
7562     }
7563
7564 #define _(a) found_something += a;
7565   foreach_ip6_proto_field;
7566 #undef _
7567
7568   if (found_something == 0)
7569     return 0;
7570
7571   vec_validate (mask, sizeof (*ip) - 1);
7572
7573   ip = (ip6_header_t *) mask;
7574
7575 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7576   foreach_ip6_proto_field;
7577 #undef _
7578
7579   ip_version_traffic_class_and_flow_label = 0;
7580
7581   if (version)
7582     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7583
7584   if (traffic_class)
7585     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7586
7587   if (flow_label)
7588     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7589
7590   ip->ip_version_traffic_class_and_flow_label =
7591     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7592
7593   *maskp = mask;
7594   return 1;
7595 }
7596
7597 uword
7598 unformat_l3_mask (unformat_input_t * input, va_list * args)
7599 {
7600   u8 **maskp = va_arg (*args, u8 **);
7601
7602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7603     {
7604       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7605         return 1;
7606       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7607         return 1;
7608       else
7609         break;
7610     }
7611   return 0;
7612 }
7613
7614 uword
7615 unformat_l2_mask (unformat_input_t * input, va_list * args)
7616 {
7617   u8 **maskp = va_arg (*args, u8 **);
7618   u8 *mask = 0;
7619   u8 src = 0;
7620   u8 dst = 0;
7621   u8 proto = 0;
7622   u8 tag1 = 0;
7623   u8 tag2 = 0;
7624   u8 ignore_tag1 = 0;
7625   u8 ignore_tag2 = 0;
7626   u8 cos1 = 0;
7627   u8 cos2 = 0;
7628   u8 dot1q = 0;
7629   u8 dot1ad = 0;
7630   int len = 14;
7631
7632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7633     {
7634       if (unformat (input, "src"))
7635         src = 1;
7636       else if (unformat (input, "dst"))
7637         dst = 1;
7638       else if (unformat (input, "proto"))
7639         proto = 1;
7640       else if (unformat (input, "tag1"))
7641         tag1 = 1;
7642       else if (unformat (input, "tag2"))
7643         tag2 = 1;
7644       else if (unformat (input, "ignore-tag1"))
7645         ignore_tag1 = 1;
7646       else if (unformat (input, "ignore-tag2"))
7647         ignore_tag2 = 1;
7648       else if (unformat (input, "cos1"))
7649         cos1 = 1;
7650       else if (unformat (input, "cos2"))
7651         cos2 = 1;
7652       else if (unformat (input, "dot1q"))
7653         dot1q = 1;
7654       else if (unformat (input, "dot1ad"))
7655         dot1ad = 1;
7656       else
7657         break;
7658     }
7659   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7660        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7661     return 0;
7662
7663   if (tag1 || ignore_tag1 || cos1 || dot1q)
7664     len = 18;
7665   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7666     len = 22;
7667
7668   vec_validate (mask, len - 1);
7669
7670   if (dst)
7671     memset (mask, 0xff, 6);
7672
7673   if (src)
7674     memset (mask + 6, 0xff, 6);
7675
7676   if (tag2 || dot1ad)
7677     {
7678       /* inner vlan tag */
7679       if (tag2)
7680         {
7681           mask[19] = 0xff;
7682           mask[18] = 0x0f;
7683         }
7684       if (cos2)
7685         mask[18] |= 0xe0;
7686       if (proto)
7687         mask[21] = mask[20] = 0xff;
7688       if (tag1)
7689         {
7690           mask[15] = 0xff;
7691           mask[14] = 0x0f;
7692         }
7693       if (cos1)
7694         mask[14] |= 0xe0;
7695       *maskp = mask;
7696       return 1;
7697     }
7698   if (tag1 | dot1q)
7699     {
7700       if (tag1)
7701         {
7702           mask[15] = 0xff;
7703           mask[14] = 0x0f;
7704         }
7705       if (cos1)
7706         mask[14] |= 0xe0;
7707       if (proto)
7708         mask[16] = mask[17] = 0xff;
7709
7710       *maskp = mask;
7711       return 1;
7712     }
7713   if (cos2)
7714     mask[18] |= 0xe0;
7715   if (cos1)
7716     mask[14] |= 0xe0;
7717   if (proto)
7718     mask[12] = mask[13] = 0xff;
7719
7720   *maskp = mask;
7721   return 1;
7722 }
7723
7724 uword
7725 unformat_classify_mask (unformat_input_t * input, va_list * args)
7726 {
7727   u8 **maskp = va_arg (*args, u8 **);
7728   u32 *skipp = va_arg (*args, u32 *);
7729   u32 *matchp = va_arg (*args, u32 *);
7730   u32 match;
7731   u8 *mask = 0;
7732   u8 *l2 = 0;
7733   u8 *l3 = 0;
7734   int i;
7735
7736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7737     {
7738       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7739         ;
7740       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7741         ;
7742       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7743         ;
7744       else
7745         break;
7746     }
7747
7748   if (mask || l2 || l3)
7749     {
7750       if (l2 || l3)
7751         {
7752           /* "With a free Ethernet header in every package" */
7753           if (l2 == 0)
7754             vec_validate (l2, 13);
7755           mask = l2;
7756           if (vec_len (l3))
7757             {
7758               vec_append (mask, l3);
7759               vec_free (l3);
7760             }
7761         }
7762
7763       /* Scan forward looking for the first significant mask octet */
7764       for (i = 0; i < vec_len (mask); i++)
7765         if (mask[i])
7766           break;
7767
7768       /* compute (skip, match) params */
7769       *skipp = i / sizeof (u32x4);
7770       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7771
7772       /* Pad mask to an even multiple of the vector size */
7773       while (vec_len (mask) % sizeof (u32x4))
7774         vec_add1 (mask, 0);
7775
7776       match = vec_len (mask) / sizeof (u32x4);
7777
7778       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7779         {
7780           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7781           if (*tmp || *(tmp + 1))
7782             break;
7783           match--;
7784         }
7785       if (match == 0)
7786         clib_warning ("BUG: match 0");
7787
7788       _vec_len (mask) = match * sizeof (u32x4);
7789
7790       *matchp = match;
7791       *maskp = mask;
7792
7793       return 1;
7794     }
7795
7796   return 0;
7797 }
7798
7799 #define foreach_l2_next                         \
7800 _(drop, DROP)                                   \
7801 _(ethernet, ETHERNET_INPUT)                     \
7802 _(ip4, IP4_INPUT)                               \
7803 _(ip6, IP6_INPUT)
7804
7805 uword
7806 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7807 {
7808   u32 *miss_next_indexp = va_arg (*args, u32 *);
7809   u32 next_index = 0;
7810   u32 tmp;
7811
7812 #define _(n,N) \
7813   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7814   foreach_l2_next;
7815 #undef _
7816
7817   if (unformat (input, "%d", &tmp))
7818     {
7819       next_index = tmp;
7820       goto out;
7821     }
7822
7823   return 0;
7824
7825 out:
7826   *miss_next_indexp = next_index;
7827   return 1;
7828 }
7829
7830 #define foreach_ip_next                         \
7831 _(miss, MISS)                                   \
7832 _(drop, DROP)                                   \
7833 _(local, LOCAL)                                 \
7834 _(rewrite, REWRITE)
7835
7836 uword
7837 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7838 {
7839   u32 *miss_next_indexp = va_arg (*args, u32 *);
7840   u32 next_index = 0;
7841   u32 tmp;
7842
7843 #define _(n,N) \
7844   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7845   foreach_ip_next;
7846 #undef _
7847
7848   if (unformat (input, "%d", &tmp))
7849     {
7850       next_index = tmp;
7851       goto out;
7852     }
7853
7854   return 0;
7855
7856 out:
7857   *miss_next_indexp = next_index;
7858   return 1;
7859 }
7860
7861 #define foreach_acl_next                        \
7862 _(deny, DENY)
7863
7864 uword
7865 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7866 {
7867   u32 *miss_next_indexp = va_arg (*args, u32 *);
7868   u32 next_index = 0;
7869   u32 tmp;
7870
7871 #define _(n,N) \
7872   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7873   foreach_acl_next;
7874 #undef _
7875
7876   if (unformat (input, "permit"))
7877     {
7878       next_index = ~0;
7879       goto out;
7880     }
7881   else if (unformat (input, "%d", &tmp))
7882     {
7883       next_index = tmp;
7884       goto out;
7885     }
7886
7887   return 0;
7888
7889 out:
7890   *miss_next_indexp = next_index;
7891   return 1;
7892 }
7893
7894 uword
7895 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7896 {
7897   u32 *r = va_arg (*args, u32 *);
7898
7899   if (unformat (input, "conform-color"))
7900     *r = POLICE_CONFORM;
7901   else if (unformat (input, "exceed-color"))
7902     *r = POLICE_EXCEED;
7903   else
7904     return 0;
7905
7906   return 1;
7907 }
7908
7909 static int
7910 api_classify_add_del_table (vat_main_t * vam)
7911 {
7912   unformat_input_t *i = vam->input;
7913   vl_api_classify_add_del_table_t *mp;
7914
7915   u32 nbuckets = 2;
7916   u32 skip = ~0;
7917   u32 match = ~0;
7918   int is_add = 1;
7919   u32 table_index = ~0;
7920   u32 next_table_index = ~0;
7921   u32 miss_next_index = ~0;
7922   u32 memory_size = 32 << 20;
7923   u8 *mask = 0;
7924   f64 timeout;
7925
7926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7927     {
7928       if (unformat (i, "del"))
7929         is_add = 0;
7930       else if (unformat (i, "buckets %d", &nbuckets))
7931         ;
7932       else if (unformat (i, "memory_size %d", &memory_size))
7933         ;
7934       else if (unformat (i, "skip %d", &skip))
7935         ;
7936       else if (unformat (i, "match %d", &match))
7937         ;
7938       else if (unformat (i, "table %d", &table_index))
7939         ;
7940       else if (unformat (i, "mask %U", unformat_classify_mask,
7941                          &mask, &skip, &match))
7942         ;
7943       else if (unformat (i, "next-table %d", &next_table_index))
7944         ;
7945       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7946                          &miss_next_index))
7947         ;
7948       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7949                          &miss_next_index))
7950         ;
7951       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7952                          &miss_next_index))
7953         ;
7954       else
7955         break;
7956     }
7957
7958   if (is_add && mask == 0)
7959     {
7960       errmsg ("Mask required\n");
7961       return -99;
7962     }
7963
7964   if (is_add && skip == ~0)
7965     {
7966       errmsg ("skip count required\n");
7967       return -99;
7968     }
7969
7970   if (is_add && match == ~0)
7971     {
7972       errmsg ("match count required\n");
7973       return -99;
7974     }
7975
7976   if (!is_add && table_index == ~0)
7977     {
7978       errmsg ("table index required for delete\n");
7979       return -99;
7980     }
7981
7982   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
7983
7984   mp->is_add = is_add;
7985   mp->table_index = ntohl (table_index);
7986   mp->nbuckets = ntohl (nbuckets);
7987   mp->memory_size = ntohl (memory_size);
7988   mp->skip_n_vectors = ntohl (skip);
7989   mp->match_n_vectors = ntohl (match);
7990   mp->next_table_index = ntohl (next_table_index);
7991   mp->miss_next_index = ntohl (miss_next_index);
7992   clib_memcpy (mp->mask, mask, vec_len (mask));
7993
7994   vec_free (mask);
7995
7996   S;
7997   W;
7998   /* NOTREACHED */
7999 }
8000
8001 uword
8002 unformat_ip4_match (unformat_input_t * input, va_list * args)
8003 {
8004   u8 **matchp = va_arg (*args, u8 **);
8005   u8 *match = 0;
8006   ip4_header_t *ip;
8007   int version = 0;
8008   u32 version_val;
8009   int hdr_length = 0;
8010   u32 hdr_length_val;
8011   int src = 0, dst = 0;
8012   ip4_address_t src_val, dst_val;
8013   int proto = 0;
8014   u32 proto_val;
8015   int tos = 0;
8016   u32 tos_val;
8017   int length = 0;
8018   u32 length_val;
8019   int fragment_id = 0;
8020   u32 fragment_id_val;
8021   int ttl = 0;
8022   int ttl_val;
8023   int checksum = 0;
8024   u32 checksum_val;
8025
8026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8027     {
8028       if (unformat (input, "version %d", &version_val))
8029         version = 1;
8030       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8031         hdr_length = 1;
8032       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8033         src = 1;
8034       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8035         dst = 1;
8036       else if (unformat (input, "proto %d", &proto_val))
8037         proto = 1;
8038       else if (unformat (input, "tos %d", &tos_val))
8039         tos = 1;
8040       else if (unformat (input, "length %d", &length_val))
8041         length = 1;
8042       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8043         fragment_id = 1;
8044       else if (unformat (input, "ttl %d", &ttl_val))
8045         ttl = 1;
8046       else if (unformat (input, "checksum %d", &checksum_val))
8047         checksum = 1;
8048       else
8049         break;
8050     }
8051
8052   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8053       + ttl + checksum == 0)
8054     return 0;
8055
8056   /*
8057    * Aligned because we use the real comparison functions
8058    */
8059   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8060
8061   ip = (ip4_header_t *) match;
8062
8063   /* These are realistically matched in practice */
8064   if (src)
8065     ip->src_address.as_u32 = src_val.as_u32;
8066
8067   if (dst)
8068     ip->dst_address.as_u32 = dst_val.as_u32;
8069
8070   if (proto)
8071     ip->protocol = proto_val;
8072
8073
8074   /* These are not, but they're included for completeness */
8075   if (version)
8076     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8077
8078   if (hdr_length)
8079     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8080
8081   if (tos)
8082     ip->tos = tos_val;
8083
8084   if (length)
8085     ip->length = length_val;
8086
8087   if (ttl)
8088     ip->ttl = ttl_val;
8089
8090   if (checksum)
8091     ip->checksum = checksum_val;
8092
8093   *matchp = match;
8094   return 1;
8095 }
8096
8097 uword
8098 unformat_ip6_match (unformat_input_t * input, va_list * args)
8099 {
8100   u8 **matchp = va_arg (*args, u8 **);
8101   u8 *match = 0;
8102   ip6_header_t *ip;
8103   int version = 0;
8104   u32 version_val;
8105   u8 traffic_class = 0;
8106   u32 traffic_class_val = 0;
8107   u8 flow_label = 0;
8108   u8 flow_label_val;
8109   int src = 0, dst = 0;
8110   ip6_address_t src_val, dst_val;
8111   int proto = 0;
8112   u32 proto_val;
8113   int payload_length = 0;
8114   u32 payload_length_val;
8115   int hop_limit = 0;
8116   int hop_limit_val;
8117   u32 ip_version_traffic_class_and_flow_label;
8118
8119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8120     {
8121       if (unformat (input, "version %d", &version_val))
8122         version = 1;
8123       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8124         traffic_class = 1;
8125       else if (unformat (input, "flow_label %d", &flow_label_val))
8126         flow_label = 1;
8127       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8128         src = 1;
8129       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8130         dst = 1;
8131       else if (unformat (input, "proto %d", &proto_val))
8132         proto = 1;
8133       else if (unformat (input, "payload_length %d", &payload_length_val))
8134         payload_length = 1;
8135       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8136         hop_limit = 1;
8137       else
8138         break;
8139     }
8140
8141   if (version + traffic_class + flow_label + src + dst + proto +
8142       payload_length + hop_limit == 0)
8143     return 0;
8144
8145   /*
8146    * Aligned because we use the real comparison functions
8147    */
8148   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8149
8150   ip = (ip6_header_t *) match;
8151
8152   if (src)
8153     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8154
8155   if (dst)
8156     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8157
8158   if (proto)
8159     ip->protocol = proto_val;
8160
8161   ip_version_traffic_class_and_flow_label = 0;
8162
8163   if (version)
8164     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8165
8166   if (traffic_class)
8167     ip_version_traffic_class_and_flow_label |=
8168       (traffic_class_val & 0xFF) << 20;
8169
8170   if (flow_label)
8171     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8172
8173   ip->ip_version_traffic_class_and_flow_label =
8174     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8175
8176   if (payload_length)
8177     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8178
8179   if (hop_limit)
8180     ip->hop_limit = hop_limit_val;
8181
8182   *matchp = match;
8183   return 1;
8184 }
8185
8186 uword
8187 unformat_l3_match (unformat_input_t * input, va_list * args)
8188 {
8189   u8 **matchp = va_arg (*args, u8 **);
8190
8191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8192     {
8193       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8194         return 1;
8195       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8196         return 1;
8197       else
8198         break;
8199     }
8200   return 0;
8201 }
8202
8203 uword
8204 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8205 {
8206   u8 *tagp = va_arg (*args, u8 *);
8207   u32 tag;
8208
8209   if (unformat (input, "%d", &tag))
8210     {
8211       tagp[0] = (tag >> 8) & 0x0F;
8212       tagp[1] = tag & 0xFF;
8213       return 1;
8214     }
8215
8216   return 0;
8217 }
8218
8219 uword
8220 unformat_l2_match (unformat_input_t * input, va_list * args)
8221 {
8222   u8 **matchp = va_arg (*args, u8 **);
8223   u8 *match = 0;
8224   u8 src = 0;
8225   u8 src_val[6];
8226   u8 dst = 0;
8227   u8 dst_val[6];
8228   u8 proto = 0;
8229   u16 proto_val;
8230   u8 tag1 = 0;
8231   u8 tag1_val[2];
8232   u8 tag2 = 0;
8233   u8 tag2_val[2];
8234   int len = 14;
8235   u8 ignore_tag1 = 0;
8236   u8 ignore_tag2 = 0;
8237   u8 cos1 = 0;
8238   u8 cos2 = 0;
8239   u32 cos1_val = 0;
8240   u32 cos2_val = 0;
8241
8242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8243     {
8244       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8245         src = 1;
8246       else
8247         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8248         dst = 1;
8249       else if (unformat (input, "proto %U",
8250                          unformat_ethernet_type_host_byte_order, &proto_val))
8251         proto = 1;
8252       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8253         tag1 = 1;
8254       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8255         tag2 = 1;
8256       else if (unformat (input, "ignore-tag1"))
8257         ignore_tag1 = 1;
8258       else if (unformat (input, "ignore-tag2"))
8259         ignore_tag2 = 1;
8260       else if (unformat (input, "cos1 %d", &cos1_val))
8261         cos1 = 1;
8262       else if (unformat (input, "cos2 %d", &cos2_val))
8263         cos2 = 1;
8264       else
8265         break;
8266     }
8267   if ((src + dst + proto + tag1 + tag2 +
8268        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8269     return 0;
8270
8271   if (tag1 || ignore_tag1 || cos1)
8272     len = 18;
8273   if (tag2 || ignore_tag2 || cos2)
8274     len = 22;
8275
8276   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8277
8278   if (dst)
8279     clib_memcpy (match, dst_val, 6);
8280
8281   if (src)
8282     clib_memcpy (match + 6, src_val, 6);
8283
8284   if (tag2)
8285     {
8286       /* inner vlan tag */
8287       match[19] = tag2_val[1];
8288       match[18] = tag2_val[0];
8289       if (cos2)
8290         match[18] |= (cos2_val & 0x7) << 5;
8291       if (proto)
8292         {
8293           match[21] = proto_val & 0xff;
8294           match[20] = proto_val >> 8;
8295         }
8296       if (tag1)
8297         {
8298           match[15] = tag1_val[1];
8299           match[14] = tag1_val[0];
8300         }
8301       if (cos1)
8302         match[14] |= (cos1_val & 0x7) << 5;
8303       *matchp = match;
8304       return 1;
8305     }
8306   if (tag1)
8307     {
8308       match[15] = tag1_val[1];
8309       match[14] = tag1_val[0];
8310       if (proto)
8311         {
8312           match[17] = proto_val & 0xff;
8313           match[16] = proto_val >> 8;
8314         }
8315       if (cos1)
8316         match[14] |= (cos1_val & 0x7) << 5;
8317
8318       *matchp = match;
8319       return 1;
8320     }
8321   if (cos2)
8322     match[18] |= (cos2_val & 0x7) << 5;
8323   if (cos1)
8324     match[14] |= (cos1_val & 0x7) << 5;
8325   if (proto)
8326     {
8327       match[13] = proto_val & 0xff;
8328       match[12] = proto_val >> 8;
8329     }
8330
8331   *matchp = match;
8332   return 1;
8333 }
8334
8335
8336 uword
8337 unformat_classify_match (unformat_input_t * input, va_list * args)
8338 {
8339   u8 **matchp = va_arg (*args, u8 **);
8340   u32 skip_n_vectors = va_arg (*args, u32);
8341   u32 match_n_vectors = va_arg (*args, u32);
8342
8343   u8 *match = 0;
8344   u8 *l2 = 0;
8345   u8 *l3 = 0;
8346
8347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8348     {
8349       if (unformat (input, "hex %U", unformat_hex_string, &match))
8350         ;
8351       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8352         ;
8353       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8354         ;
8355       else
8356         break;
8357     }
8358
8359   if (match || l2 || l3)
8360     {
8361       if (l2 || l3)
8362         {
8363           /* "Win a free Ethernet header in every packet" */
8364           if (l2 == 0)
8365             vec_validate_aligned (l2, 13, sizeof (u32x4));
8366           match = l2;
8367           if (vec_len (l3))
8368             {
8369               vec_append_aligned (match, l3, sizeof (u32x4));
8370               vec_free (l3);
8371             }
8372         }
8373
8374       /* Make sure the vector is big enough even if key is all 0's */
8375       vec_validate_aligned
8376         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8377          sizeof (u32x4));
8378
8379       /* Set size, include skipped vectors */
8380       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8381
8382       *matchp = match;
8383
8384       return 1;
8385     }
8386
8387   return 0;
8388 }
8389
8390 static int
8391 api_classify_add_del_session (vat_main_t * vam)
8392 {
8393   unformat_input_t *i = vam->input;
8394   vl_api_classify_add_del_session_t *mp;
8395   int is_add = 1;
8396   u32 table_index = ~0;
8397   u32 hit_next_index = ~0;
8398   u32 opaque_index = ~0;
8399   u8 *match = 0;
8400   i32 advance = 0;
8401   f64 timeout;
8402   u32 skip_n_vectors = 0;
8403   u32 match_n_vectors = 0;
8404
8405   /*
8406    * Warning: you have to supply skip_n and match_n
8407    * because the API client cant simply look at the classify
8408    * table object.
8409    */
8410
8411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8412     {
8413       if (unformat (i, "del"))
8414         is_add = 0;
8415       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8416                          &hit_next_index))
8417         ;
8418       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8419                          &hit_next_index))
8420         ;
8421       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8422                          &hit_next_index))
8423         ;
8424       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8425         ;
8426       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8427         ;
8428       else if (unformat (i, "opaque-index %d", &opaque_index))
8429         ;
8430       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8431         ;
8432       else if (unformat (i, "match_n %d", &match_n_vectors))
8433         ;
8434       else if (unformat (i, "match %U", unformat_classify_match,
8435                          &match, skip_n_vectors, match_n_vectors))
8436         ;
8437       else if (unformat (i, "advance %d", &advance))
8438         ;
8439       else if (unformat (i, "table-index %d", &table_index))
8440         ;
8441       else
8442         break;
8443     }
8444
8445   if (table_index == ~0)
8446     {
8447       errmsg ("Table index required\n");
8448       return -99;
8449     }
8450
8451   if (is_add && match == 0)
8452     {
8453       errmsg ("Match value required\n");
8454       return -99;
8455     }
8456
8457   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8458
8459   mp->is_add = is_add;
8460   mp->table_index = ntohl (table_index);
8461   mp->hit_next_index = ntohl (hit_next_index);
8462   mp->opaque_index = ntohl (opaque_index);
8463   mp->advance = ntohl (advance);
8464   clib_memcpy (mp->match, match, vec_len (match));
8465   vec_free (match);
8466
8467   S;
8468   W;
8469   /* NOTREACHED */
8470 }
8471
8472 static int
8473 api_classify_set_interface_ip_table (vat_main_t * vam)
8474 {
8475   unformat_input_t *i = vam->input;
8476   vl_api_classify_set_interface_ip_table_t *mp;
8477   f64 timeout;
8478   u32 sw_if_index;
8479   int sw_if_index_set;
8480   u32 table_index = ~0;
8481   u8 is_ipv6 = 0;
8482
8483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8484     {
8485       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8486         sw_if_index_set = 1;
8487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8488         sw_if_index_set = 1;
8489       else if (unformat (i, "table %d", &table_index))
8490         ;
8491       else
8492         {
8493           clib_warning ("parse error '%U'", format_unformat_error, i);
8494           return -99;
8495         }
8496     }
8497
8498   if (sw_if_index_set == 0)
8499     {
8500       errmsg ("missing interface name or sw_if_index\n");
8501       return -99;
8502     }
8503
8504
8505   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8506
8507   mp->sw_if_index = ntohl (sw_if_index);
8508   mp->table_index = ntohl (table_index);
8509   mp->is_ipv6 = is_ipv6;
8510
8511   S;
8512   W;
8513   /* NOTREACHED */
8514   return 0;
8515 }
8516
8517 static int
8518 api_classify_set_interface_l2_tables (vat_main_t * vam)
8519 {
8520   unformat_input_t *i = vam->input;
8521   vl_api_classify_set_interface_l2_tables_t *mp;
8522   f64 timeout;
8523   u32 sw_if_index;
8524   int sw_if_index_set;
8525   u32 ip4_table_index = ~0;
8526   u32 ip6_table_index = ~0;
8527   u32 other_table_index = ~0;
8528
8529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8530     {
8531       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8532         sw_if_index_set = 1;
8533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8534         sw_if_index_set = 1;
8535       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8536         ;
8537       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8538         ;
8539       else if (unformat (i, "other-table %d", &other_table_index))
8540         ;
8541       else
8542         {
8543           clib_warning ("parse error '%U'", format_unformat_error, i);
8544           return -99;
8545         }
8546     }
8547
8548   if (sw_if_index_set == 0)
8549     {
8550       errmsg ("missing interface name or sw_if_index\n");
8551       return -99;
8552     }
8553
8554
8555   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8556
8557   mp->sw_if_index = ntohl (sw_if_index);
8558   mp->ip4_table_index = ntohl (ip4_table_index);
8559   mp->ip6_table_index = ntohl (ip6_table_index);
8560   mp->other_table_index = ntohl (other_table_index);
8561
8562
8563   S;
8564   W;
8565   /* NOTREACHED */
8566   return 0;
8567 }
8568
8569 static int
8570 api_ipfix_enable (vat_main_t * vam)
8571 {
8572   unformat_input_t *i = vam->input;
8573   vl_api_ipfix_enable_t *mp;
8574   ip4_address_t collector_address;
8575   u8 collector_address_set = 0;
8576   u32 collector_port = ~0;
8577   ip4_address_t src_address;
8578   u8 src_address_set = 0;
8579   u32 vrf_id = ~0;
8580   u32 path_mtu = ~0;
8581   u32 template_interval = ~0;
8582   f64 timeout;
8583
8584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8585     {
8586       if (unformat (i, "collector_address %U", unformat_ip4_address,
8587                     &collector_address))
8588         collector_address_set = 1;
8589       else if (unformat (i, "collector_port %d", &collector_port))
8590         ;
8591       else if (unformat (i, "src_address %U", unformat_ip4_address,
8592                          &src_address))
8593         src_address_set = 1;
8594       else if (unformat (i, "vrf_id %d", &vrf_id))
8595         ;
8596       else if (unformat (i, "path_mtu %d", &path_mtu))
8597         ;
8598       else if (unformat (i, "template_interval %d", &template_interval))
8599         ;
8600       else
8601         break;
8602     }
8603
8604   if (collector_address_set == 0)
8605     {
8606       errmsg ("collector_address required\n");
8607       return -99;
8608     }
8609
8610   if (src_address_set == 0)
8611     {
8612       errmsg ("src_address required\n");
8613       return -99;
8614     }
8615
8616   M (IPFIX_ENABLE, ipfix_enable);
8617
8618   memcpy (mp->collector_address, collector_address.data,
8619           sizeof (collector_address.data));
8620   mp->collector_port = htons ((u16) collector_port);
8621   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8622   mp->vrf_id = htonl (vrf_id);
8623   mp->path_mtu = htonl (path_mtu);
8624   mp->template_interval = htonl (template_interval);
8625
8626   S;
8627   W;
8628   /* NOTREACHED */
8629 }
8630
8631 static int
8632 api_get_node_index (vat_main_t * vam)
8633 {
8634   unformat_input_t *i = vam->input;
8635   vl_api_get_node_index_t *mp;
8636   f64 timeout;
8637   u8 *name = 0;
8638
8639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8640     {
8641       if (unformat (i, "node %s", &name))
8642         ;
8643       else
8644         break;
8645     }
8646   if (name == 0)
8647     {
8648       errmsg ("node name required\n");
8649       return -99;
8650     }
8651   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8652     {
8653       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8654       return -99;
8655     }
8656
8657   M (GET_NODE_INDEX, get_node_index);
8658   clib_memcpy (mp->node_name, name, vec_len (name));
8659   vec_free (name);
8660
8661   S;
8662   W;
8663   /* NOTREACHED */
8664   return 0;
8665 }
8666
8667 static int
8668 api_get_next_index (vat_main_t * vam)
8669 {
8670   unformat_input_t *i = vam->input;
8671   vl_api_get_next_index_t *mp;
8672   f64 timeout;
8673   u8 *node_name = 0, *next_node_name = 0;
8674
8675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8676     {
8677       if (unformat (i, "node-name %s", &node_name))
8678         ;
8679       else if (unformat (i, "next-node-name %s", &next_node_name))
8680         break;
8681     }
8682
8683   if (node_name == 0)
8684     {
8685       errmsg ("node name required\n");
8686       return -99;
8687     }
8688   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8689     {
8690       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8691       return -99;
8692     }
8693
8694   if (next_node_name == 0)
8695     {
8696       errmsg ("next node name required\n");
8697       return -99;
8698     }
8699   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8700     {
8701       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8702       return -99;
8703     }
8704
8705   M (GET_NEXT_INDEX, get_next_index);
8706   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8707   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8708   vec_free (node_name);
8709   vec_free (next_node_name);
8710
8711   S;
8712   W;
8713   /* NOTREACHED */
8714   return 0;
8715 }
8716
8717 static int
8718 api_add_node_next (vat_main_t * vam)
8719 {
8720   unformat_input_t *i = vam->input;
8721   vl_api_add_node_next_t *mp;
8722   f64 timeout;
8723   u8 *name = 0;
8724   u8 *next = 0;
8725
8726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8727     {
8728       if (unformat (i, "node %s", &name))
8729         ;
8730       else if (unformat (i, "next %s", &next))
8731         ;
8732       else
8733         break;
8734     }
8735   if (name == 0)
8736     {
8737       errmsg ("node name required\n");
8738       return -99;
8739     }
8740   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8741     {
8742       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8743       return -99;
8744     }
8745   if (next == 0)
8746     {
8747       errmsg ("next node required\n");
8748       return -99;
8749     }
8750   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8751     {
8752       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8753       return -99;
8754     }
8755
8756   M (ADD_NODE_NEXT, add_node_next);
8757   clib_memcpy (mp->node_name, name, vec_len (name));
8758   clib_memcpy (mp->next_name, next, vec_len (next));
8759   vec_free (name);
8760   vec_free (next);
8761
8762   S;
8763   W;
8764   /* NOTREACHED */
8765   return 0;
8766 }
8767
8768 static int
8769 api_l2tpv3_create_tunnel (vat_main_t * vam)
8770 {
8771   unformat_input_t *i = vam->input;
8772   ip6_address_t client_address, our_address;
8773   int client_address_set = 0;
8774   int our_address_set = 0;
8775   u32 local_session_id = 0;
8776   u32 remote_session_id = 0;
8777   u64 local_cookie = 0;
8778   u64 remote_cookie = 0;
8779   u8 l2_sublayer_present = 0;
8780   vl_api_l2tpv3_create_tunnel_t *mp;
8781   f64 timeout;
8782
8783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8784     {
8785       if (unformat (i, "client_address %U", unformat_ip6_address,
8786                     &client_address))
8787         client_address_set = 1;
8788       else if (unformat (i, "our_address %U", unformat_ip6_address,
8789                          &our_address))
8790         our_address_set = 1;
8791       else if (unformat (i, "local_session_id %d", &local_session_id))
8792         ;
8793       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8794         ;
8795       else if (unformat (i, "local_cookie %lld", &local_cookie))
8796         ;
8797       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8798         ;
8799       else if (unformat (i, "l2-sublayer-present"))
8800         l2_sublayer_present = 1;
8801       else
8802         break;
8803     }
8804
8805   if (client_address_set == 0)
8806     {
8807       errmsg ("client_address required\n");
8808       return -99;
8809     }
8810
8811   if (our_address_set == 0)
8812     {
8813       errmsg ("our_address required\n");
8814       return -99;
8815     }
8816
8817   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8818
8819   clib_memcpy (mp->client_address, client_address.as_u8,
8820                sizeof (mp->client_address));
8821
8822   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8823
8824   mp->local_session_id = ntohl (local_session_id);
8825   mp->remote_session_id = ntohl (remote_session_id);
8826   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8827   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8828   mp->l2_sublayer_present = l2_sublayer_present;
8829   mp->is_ipv6 = 1;
8830
8831   S;
8832   W;
8833   /* NOTREACHED */
8834   return 0;
8835 }
8836
8837 static int
8838 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8839 {
8840   unformat_input_t *i = vam->input;
8841   u32 sw_if_index;
8842   u8 sw_if_index_set = 0;
8843   u64 new_local_cookie = 0;
8844   u64 new_remote_cookie = 0;
8845   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8846   f64 timeout;
8847
8848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8849     {
8850       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8851         sw_if_index_set = 1;
8852       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8853         sw_if_index_set = 1;
8854       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8855         ;
8856       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8857         ;
8858       else
8859         break;
8860     }
8861
8862   if (sw_if_index_set == 0)
8863     {
8864       errmsg ("missing interface name or sw_if_index\n");
8865       return -99;
8866     }
8867
8868   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8869
8870   mp->sw_if_index = ntohl (sw_if_index);
8871   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8872   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8873
8874   S;
8875   W;
8876   /* NOTREACHED */
8877   return 0;
8878 }
8879
8880 static int
8881 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8882 {
8883   unformat_input_t *i = vam->input;
8884   vl_api_l2tpv3_interface_enable_disable_t *mp;
8885   f64 timeout;
8886   u32 sw_if_index;
8887   u8 sw_if_index_set = 0;
8888   u8 enable_disable = 1;
8889
8890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8891     {
8892       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8893         sw_if_index_set = 1;
8894       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8895         sw_if_index_set = 1;
8896       else if (unformat (i, "enable"))
8897         enable_disable = 1;
8898       else if (unformat (i, "disable"))
8899         enable_disable = 0;
8900       else
8901         break;
8902     }
8903
8904   if (sw_if_index_set == 0)
8905     {
8906       errmsg ("missing interface name or sw_if_index\n");
8907       return -99;
8908     }
8909
8910   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8911
8912   mp->sw_if_index = ntohl (sw_if_index);
8913   mp->enable_disable = enable_disable;
8914
8915   S;
8916   W;
8917   /* NOTREACHED */
8918   return 0;
8919 }
8920
8921 static int
8922 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8923 {
8924   unformat_input_t *i = vam->input;
8925   vl_api_l2tpv3_set_lookup_key_t *mp;
8926   f64 timeout;
8927   u8 key = ~0;
8928
8929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8930     {
8931       if (unformat (i, "lookup_v6_src"))
8932         key = L2T_LOOKUP_SRC_ADDRESS;
8933       else if (unformat (i, "lookup_v6_dst"))
8934         key = L2T_LOOKUP_DST_ADDRESS;
8935       else if (unformat (i, "lookup_session_id"))
8936         key = L2T_LOOKUP_SESSION_ID;
8937       else
8938         break;
8939     }
8940
8941   if (key == (u8) ~ 0)
8942     {
8943       errmsg ("l2tp session lookup key unset\n");
8944       return -99;
8945     }
8946
8947   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8948
8949   mp->key = key;
8950
8951   S;
8952   W;
8953   /* NOTREACHED */
8954   return 0;
8955 }
8956
8957 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8958   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8959 {
8960   vat_main_t *vam = &vat_main;
8961
8962   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8963            format_ip6_address, mp->our_address,
8964            format_ip6_address, mp->client_address,
8965            clib_net_to_host_u32 (mp->sw_if_index));
8966
8967   fformat (vam->ofp,
8968            "   local cookies %016llx %016llx remote cookie %016llx\n",
8969            clib_net_to_host_u64 (mp->local_cookie[0]),
8970            clib_net_to_host_u64 (mp->local_cookie[1]),
8971            clib_net_to_host_u64 (mp->remote_cookie));
8972
8973   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
8974            clib_net_to_host_u32 (mp->local_session_id),
8975            clib_net_to_host_u32 (mp->remote_session_id));
8976
8977   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
8978            mp->l2_sublayer_present ? "preset" : "absent");
8979
8980 }
8981
8982 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8983   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8984 {
8985   vat_main_t *vam = &vat_main;
8986   vat_json_node_t *node = NULL;
8987   struct in6_addr addr;
8988
8989   if (VAT_JSON_ARRAY != vam->json_tree.type)
8990     {
8991       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8992       vat_json_init_array (&vam->json_tree);
8993     }
8994   node = vat_json_array_add (&vam->json_tree);
8995
8996   vat_json_init_object (node);
8997
8998   clib_memcpy (&addr, mp->our_address, sizeof (addr));
8999   vat_json_object_add_ip6 (node, "our_address", addr);
9000   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9001   vat_json_object_add_ip6 (node, "client_address", addr);
9002
9003   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9004   vat_json_init_array (lc);
9005   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9006   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9007   vat_json_object_add_uint (node, "remote_cookie",
9008                             clib_net_to_host_u64 (mp->remote_cookie));
9009
9010   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9011   vat_json_object_add_uint (node, "local_session_id",
9012                             clib_net_to_host_u32 (mp->local_session_id));
9013   vat_json_object_add_uint (node, "remote_session_id",
9014                             clib_net_to_host_u32 (mp->remote_session_id));
9015   vat_json_object_add_string_copy (node, "l2_sublayer",
9016                                    mp->l2_sublayer_present ? (u8 *) "present"
9017                                    : (u8 *) "absent");
9018 }
9019
9020 static int
9021 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9022 {
9023   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9024   f64 timeout;
9025
9026   /* Get list of l2tpv3-tunnel interfaces */
9027   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9028   S;
9029
9030   /* Use a control ping for synchronization */
9031   {
9032     vl_api_control_ping_t *mp;
9033     M (CONTROL_PING, control_ping);
9034     S;
9035   }
9036   W;
9037 }
9038
9039
9040 static void vl_api_sw_interface_tap_details_t_handler
9041   (vl_api_sw_interface_tap_details_t * mp)
9042 {
9043   vat_main_t *vam = &vat_main;
9044
9045   fformat (vam->ofp, "%-16s %d\n",
9046            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9047 }
9048
9049 static void vl_api_sw_interface_tap_details_t_handler_json
9050   (vl_api_sw_interface_tap_details_t * mp)
9051 {
9052   vat_main_t *vam = &vat_main;
9053   vat_json_node_t *node = NULL;
9054
9055   if (VAT_JSON_ARRAY != vam->json_tree.type)
9056     {
9057       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9058       vat_json_init_array (&vam->json_tree);
9059     }
9060   node = vat_json_array_add (&vam->json_tree);
9061
9062   vat_json_init_object (node);
9063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9064   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9065 }
9066
9067 static int
9068 api_sw_interface_tap_dump (vat_main_t * vam)
9069 {
9070   vl_api_sw_interface_tap_dump_t *mp;
9071   f64 timeout;
9072
9073   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9074   /* Get list of tap interfaces */
9075   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9076   S;
9077
9078   /* Use a control ping for synchronization */
9079   {
9080     vl_api_control_ping_t *mp;
9081     M (CONTROL_PING, control_ping);
9082     S;
9083   }
9084   W;
9085 }
9086
9087 static uword unformat_vxlan_decap_next
9088   (unformat_input_t * input, va_list * args)
9089 {
9090   u32 *result = va_arg (*args, u32 *);
9091   u32 tmp;
9092
9093   if (unformat (input, "drop"))
9094     *result = VXLAN_INPUT_NEXT_DROP;
9095   else if (unformat (input, "ip4"))
9096     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9097   else if (unformat (input, "ip6"))
9098     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9099   else if (unformat (input, "l2"))
9100     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9101   else if (unformat (input, "%d", &tmp))
9102     *result = tmp;
9103   else
9104     return 0;
9105   return 1;
9106 }
9107
9108 static int
9109 api_vxlan_add_del_tunnel (vat_main_t * vam)
9110 {
9111   unformat_input_t *line_input = vam->input;
9112   vl_api_vxlan_add_del_tunnel_t *mp;
9113   f64 timeout;
9114   ip4_address_t src4, dst4;
9115   ip6_address_t src6, dst6;
9116   u8 is_add = 1;
9117   u8 ipv4_set = 0, ipv6_set = 0;
9118   u8 src_set = 0;
9119   u8 dst_set = 0;
9120   u32 encap_vrf_id = 0;
9121   u32 decap_next_index = ~0;
9122   u32 vni = 0;
9123
9124   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9125     {
9126       if (unformat (line_input, "del"))
9127         is_add = 0;
9128       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9129         {
9130           ipv4_set = 1;
9131           src_set = 1;
9132         }
9133       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9134         {
9135           ipv4_set = 1;
9136           dst_set = 1;
9137         }
9138       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9139         {
9140           ipv6_set = 1;
9141           src_set = 1;
9142         }
9143       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9144         {
9145           ipv6_set = 1;
9146           dst_set = 1;
9147         }
9148       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9149         ;
9150       else if (unformat (line_input, "decap-next %U",
9151                          unformat_vxlan_decap_next, &decap_next_index))
9152         ;
9153       else if (unformat (line_input, "vni %d", &vni))
9154         ;
9155       else
9156         {
9157           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9158           return -99;
9159         }
9160     }
9161
9162   if (src_set == 0)
9163     {
9164       errmsg ("tunnel src address not specified\n");
9165       return -99;
9166     }
9167   if (dst_set == 0)
9168     {
9169       errmsg ("tunnel dst address not specified\n");
9170       return -99;
9171     }
9172
9173   if (ipv4_set && ipv6_set)
9174     {
9175       errmsg ("both IPv4 and IPv6 addresses specified");
9176       return -99;
9177     }
9178
9179   if ((vni == 0) || (vni >> 24))
9180     {
9181       errmsg ("vni not specified or out of range\n");
9182       return -99;
9183     }
9184
9185   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9186
9187   if (ipv6_set)
9188     {
9189       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9190       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9191     }
9192   else
9193     {
9194       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9195       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9196     }
9197   mp->encap_vrf_id = ntohl (encap_vrf_id);
9198   mp->decap_next_index = ntohl (decap_next_index);
9199   mp->vni = ntohl (vni);
9200   mp->is_add = is_add;
9201   mp->is_ipv6 = ipv6_set;
9202
9203   S;
9204   W;
9205   /* NOTREACHED */
9206   return 0;
9207 }
9208
9209 static void vl_api_vxlan_tunnel_details_t_handler
9210   (vl_api_vxlan_tunnel_details_t * mp)
9211 {
9212   vat_main_t *vam = &vat_main;
9213
9214   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9215            ntohl (mp->sw_if_index),
9216            format_ip46_address, &(mp->src_address[0]),
9217            IP46_TYPE_ANY,
9218            format_ip46_address, &(mp->dst_address[0]),
9219            IP46_TYPE_ANY,
9220            ntohl (mp->encap_vrf_id),
9221            ntohl (mp->decap_next_index), ntohl (mp->vni));
9222 }
9223
9224 static void vl_api_vxlan_tunnel_details_t_handler_json
9225   (vl_api_vxlan_tunnel_details_t * mp)
9226 {
9227   vat_main_t *vam = &vat_main;
9228   vat_json_node_t *node = NULL;
9229   struct in_addr ip4;
9230   struct in6_addr ip6;
9231
9232   if (VAT_JSON_ARRAY != vam->json_tree.type)
9233     {
9234       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9235       vat_json_init_array (&vam->json_tree);
9236     }
9237   node = vat_json_array_add (&vam->json_tree);
9238
9239   vat_json_init_object (node);
9240   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9241   if (mp->is_ipv6)
9242     {
9243       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9244       vat_json_object_add_ip6 (node, "src_address", ip6);
9245       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9246       vat_json_object_add_ip6 (node, "dst_address", ip6);
9247     }
9248   else
9249     {
9250       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9251       vat_json_object_add_ip4 (node, "src_address", ip4);
9252       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9253       vat_json_object_add_ip4 (node, "dst_address", ip4);
9254     }
9255   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9256   vat_json_object_add_uint (node, "decap_next_index",
9257                             ntohl (mp->decap_next_index));
9258   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9259   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9260 }
9261
9262 static int
9263 api_vxlan_tunnel_dump (vat_main_t * vam)
9264 {
9265   unformat_input_t *i = vam->input;
9266   vl_api_vxlan_tunnel_dump_t *mp;
9267   f64 timeout;
9268   u32 sw_if_index;
9269   u8 sw_if_index_set = 0;
9270
9271   /* Parse args required to build the message */
9272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9273     {
9274       if (unformat (i, "sw_if_index %d", &sw_if_index))
9275         sw_if_index_set = 1;
9276       else
9277         break;
9278     }
9279
9280   if (sw_if_index_set == 0)
9281     {
9282       sw_if_index = ~0;
9283     }
9284
9285   if (!vam->json_output)
9286     {
9287       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9288                "sw_if_index", "src_address", "dst_address",
9289                "encap_vrf_id", "decap_next_index", "vni");
9290     }
9291
9292   /* Get list of vxlan-tunnel interfaces */
9293   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9294
9295   mp->sw_if_index = htonl (sw_if_index);
9296
9297   S;
9298
9299   /* Use a control ping for synchronization */
9300   {
9301     vl_api_control_ping_t *mp;
9302     M (CONTROL_PING, control_ping);
9303     S;
9304   }
9305   W;
9306 }
9307
9308 static int
9309 api_gre_add_del_tunnel (vat_main_t * vam)
9310 {
9311   unformat_input_t *line_input = vam->input;
9312   vl_api_gre_add_del_tunnel_t *mp;
9313   f64 timeout;
9314   ip4_address_t src4, dst4;
9315   u8 is_add = 1;
9316   u8 src_set = 0;
9317   u8 dst_set = 0;
9318   u32 outer_fib_id = 0;
9319
9320   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9321     {
9322       if (unformat (line_input, "del"))
9323         is_add = 0;
9324       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9325         src_set = 1;
9326       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9327         dst_set = 1;
9328       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9329         ;
9330       else
9331         {
9332           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9333           return -99;
9334         }
9335     }
9336
9337   if (src_set == 0)
9338     {
9339       errmsg ("tunnel src address not specified\n");
9340       return -99;
9341     }
9342   if (dst_set == 0)
9343     {
9344       errmsg ("tunnel dst address not specified\n");
9345       return -99;
9346     }
9347
9348
9349   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9350
9351   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9352   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9353   mp->outer_fib_id = ntohl (outer_fib_id);
9354   mp->is_add = is_add;
9355
9356   S;
9357   W;
9358   /* NOTREACHED */
9359   return 0;
9360 }
9361
9362 static void vl_api_gre_tunnel_details_t_handler
9363   (vl_api_gre_tunnel_details_t * mp)
9364 {
9365   vat_main_t *vam = &vat_main;
9366
9367   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9368            ntohl (mp->sw_if_index),
9369            format_ip4_address, &mp->src_address,
9370            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9371 }
9372
9373 static void vl_api_gre_tunnel_details_t_handler_json
9374   (vl_api_gre_tunnel_details_t * mp)
9375 {
9376   vat_main_t *vam = &vat_main;
9377   vat_json_node_t *node = NULL;
9378   struct in_addr ip4;
9379
9380   if (VAT_JSON_ARRAY != vam->json_tree.type)
9381     {
9382       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9383       vat_json_init_array (&vam->json_tree);
9384     }
9385   node = vat_json_array_add (&vam->json_tree);
9386
9387   vat_json_init_object (node);
9388   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9389   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9390   vat_json_object_add_ip4 (node, "src_address", ip4);
9391   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9392   vat_json_object_add_ip4 (node, "dst_address", ip4);
9393   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9394 }
9395
9396 static int
9397 api_gre_tunnel_dump (vat_main_t * vam)
9398 {
9399   unformat_input_t *i = vam->input;
9400   vl_api_gre_tunnel_dump_t *mp;
9401   f64 timeout;
9402   u32 sw_if_index;
9403   u8 sw_if_index_set = 0;
9404
9405   /* Parse args required to build the message */
9406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9407     {
9408       if (unformat (i, "sw_if_index %d", &sw_if_index))
9409         sw_if_index_set = 1;
9410       else
9411         break;
9412     }
9413
9414   if (sw_if_index_set == 0)
9415     {
9416       sw_if_index = ~0;
9417     }
9418
9419   if (!vam->json_output)
9420     {
9421       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9422                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9423     }
9424
9425   /* Get list of gre-tunnel interfaces */
9426   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9427
9428   mp->sw_if_index = htonl (sw_if_index);
9429
9430   S;
9431
9432   /* Use a control ping for synchronization */
9433   {
9434     vl_api_control_ping_t *mp;
9435     M (CONTROL_PING, control_ping);
9436     S;
9437   }
9438   W;
9439 }
9440
9441 static int
9442 api_l2_fib_clear_table (vat_main_t * vam)
9443 {
9444 //  unformat_input_t * i = vam->input;
9445   vl_api_l2_fib_clear_table_t *mp;
9446   f64 timeout;
9447
9448   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9449
9450   S;
9451   W;
9452   /* NOTREACHED */
9453   return 0;
9454 }
9455
9456 static int
9457 api_l2_interface_efp_filter (vat_main_t * vam)
9458 {
9459   unformat_input_t *i = vam->input;
9460   vl_api_l2_interface_efp_filter_t *mp;
9461   f64 timeout;
9462   u32 sw_if_index;
9463   u8 enable = 1;
9464   u8 sw_if_index_set = 0;
9465
9466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9467     {
9468       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9469         sw_if_index_set = 1;
9470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9471         sw_if_index_set = 1;
9472       else if (unformat (i, "enable"))
9473         enable = 1;
9474       else if (unformat (i, "disable"))
9475         enable = 0;
9476       else
9477         {
9478           clib_warning ("parse error '%U'", format_unformat_error, i);
9479           return -99;
9480         }
9481     }
9482
9483   if (sw_if_index_set == 0)
9484     {
9485       errmsg ("missing sw_if_index\n");
9486       return -99;
9487     }
9488
9489   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9490
9491   mp->sw_if_index = ntohl (sw_if_index);
9492   mp->enable_disable = enable;
9493
9494   S;
9495   W;
9496   /* NOTREACHED */
9497   return 0;
9498 }
9499
9500 #define foreach_vtr_op                          \
9501 _("disable",  L2_VTR_DISABLED)                  \
9502 _("push-1",  L2_VTR_PUSH_1)                     \
9503 _("push-2",  L2_VTR_PUSH_2)                     \
9504 _("pop-1",  L2_VTR_POP_1)                       \
9505 _("pop-2",  L2_VTR_POP_2)                       \
9506 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9507 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9508 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9509 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9510
9511 static int
9512 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9513 {
9514   unformat_input_t *i = vam->input;
9515   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9516   f64 timeout;
9517   u32 sw_if_index;
9518   u8 sw_if_index_set = 0;
9519   u8 vtr_op_set = 0;
9520   u32 vtr_op = 0;
9521   u32 push_dot1q = 1;
9522   u32 tag1 = ~0;
9523   u32 tag2 = ~0;
9524
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9528         sw_if_index_set = 1;
9529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9530         sw_if_index_set = 1;
9531       else if (unformat (i, "vtr_op %d", &vtr_op))
9532         vtr_op_set = 1;
9533 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9534       foreach_vtr_op
9535 #undef _
9536         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9537         ;
9538       else if (unformat (i, "tag1 %d", &tag1))
9539         ;
9540       else if (unformat (i, "tag2 %d", &tag2))
9541         ;
9542       else
9543         {
9544           clib_warning ("parse error '%U'", format_unformat_error, i);
9545           return -99;
9546         }
9547     }
9548
9549   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9550     {
9551       errmsg ("missing vtr operation or sw_if_index\n");
9552       return -99;
9553     }
9554
9555   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9556     mp->sw_if_index = ntohl (sw_if_index);
9557   mp->vtr_op = ntohl (vtr_op);
9558   mp->push_dot1q = ntohl (push_dot1q);
9559   mp->tag1 = ntohl (tag1);
9560   mp->tag2 = ntohl (tag2);
9561
9562   S;
9563   W;
9564   /* NOTREACHED */
9565   return 0;
9566 }
9567
9568 static int
9569 api_create_vhost_user_if (vat_main_t * vam)
9570 {
9571   unformat_input_t *i = vam->input;
9572   vl_api_create_vhost_user_if_t *mp;
9573   f64 timeout;
9574   u8 *file_name;
9575   u8 is_server = 0;
9576   u8 file_name_set = 0;
9577   u32 custom_dev_instance = ~0;
9578   u8 hwaddr[6];
9579   u8 use_custom_mac = 0;
9580
9581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9582     {
9583       if (unformat (i, "socket %s", &file_name))
9584         {
9585           file_name_set = 1;
9586         }
9587       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9588         ;
9589       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9590         use_custom_mac = 1;
9591       else if (unformat (i, "server"))
9592         is_server = 1;
9593       else
9594         break;
9595     }
9596
9597   if (file_name_set == 0)
9598     {
9599       errmsg ("missing socket file name\n");
9600       return -99;
9601     }
9602
9603   if (vec_len (file_name) > 255)
9604     {
9605       errmsg ("socket file name too long\n");
9606       return -99;
9607     }
9608   vec_add1 (file_name, 0);
9609
9610   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9611
9612   mp->is_server = is_server;
9613   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9614   vec_free (file_name);
9615   if (custom_dev_instance != ~0)
9616     {
9617       mp->renumber = 1;
9618       mp->custom_dev_instance = ntohl (custom_dev_instance);
9619     }
9620   mp->use_custom_mac = use_custom_mac;
9621   clib_memcpy (mp->mac_address, hwaddr, 6);
9622
9623   S;
9624   W;
9625   /* NOTREACHED */
9626   return 0;
9627 }
9628
9629 static int
9630 api_modify_vhost_user_if (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_modify_vhost_user_if_t *mp;
9634   f64 timeout;
9635   u8 *file_name;
9636   u8 is_server = 0;
9637   u8 file_name_set = 0;
9638   u32 custom_dev_instance = ~0;
9639   u8 sw_if_index_set = 0;
9640   u32 sw_if_index = (u32) ~ 0;
9641
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9645         sw_if_index_set = 1;
9646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9647         sw_if_index_set = 1;
9648       else if (unformat (i, "socket %s", &file_name))
9649         {
9650           file_name_set = 1;
9651         }
9652       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9653         ;
9654       else if (unformat (i, "server"))
9655         is_server = 1;
9656       else
9657         break;
9658     }
9659
9660   if (sw_if_index_set == 0)
9661     {
9662       errmsg ("missing sw_if_index or interface name\n");
9663       return -99;
9664     }
9665
9666   if (file_name_set == 0)
9667     {
9668       errmsg ("missing socket file name\n");
9669       return -99;
9670     }
9671
9672   if (vec_len (file_name) > 255)
9673     {
9674       errmsg ("socket file name too long\n");
9675       return -99;
9676     }
9677   vec_add1 (file_name, 0);
9678
9679   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9680
9681   mp->sw_if_index = ntohl (sw_if_index);
9682   mp->is_server = is_server;
9683   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9684   vec_free (file_name);
9685   if (custom_dev_instance != ~0)
9686     {
9687       mp->renumber = 1;
9688       mp->custom_dev_instance = ntohl (custom_dev_instance);
9689     }
9690
9691   S;
9692   W;
9693   /* NOTREACHED */
9694   return 0;
9695 }
9696
9697 static int
9698 api_delete_vhost_user_if (vat_main_t * vam)
9699 {
9700   unformat_input_t *i = vam->input;
9701   vl_api_delete_vhost_user_if_t *mp;
9702   f64 timeout;
9703   u32 sw_if_index = ~0;
9704   u8 sw_if_index_set = 0;
9705
9706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9707     {
9708       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9709         sw_if_index_set = 1;
9710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9711         sw_if_index_set = 1;
9712       else
9713         break;
9714     }
9715
9716   if (sw_if_index_set == 0)
9717     {
9718       errmsg ("missing sw_if_index or interface name\n");
9719       return -99;
9720     }
9721
9722
9723   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9724
9725   mp->sw_if_index = ntohl (sw_if_index);
9726
9727   S;
9728   W;
9729   /* NOTREACHED */
9730   return 0;
9731 }
9732
9733 static void vl_api_sw_interface_vhost_user_details_t_handler
9734   (vl_api_sw_interface_vhost_user_details_t * mp)
9735 {
9736   vat_main_t *vam = &vat_main;
9737
9738   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9739            (char *) mp->interface_name,
9740            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9741            clib_net_to_host_u64 (mp->features), mp->is_server,
9742            ntohl (mp->num_regions), (char *) mp->sock_filename);
9743   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9744 }
9745
9746 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9747   (vl_api_sw_interface_vhost_user_details_t * mp)
9748 {
9749   vat_main_t *vam = &vat_main;
9750   vat_json_node_t *node = NULL;
9751
9752   if (VAT_JSON_ARRAY != vam->json_tree.type)
9753     {
9754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9755       vat_json_init_array (&vam->json_tree);
9756     }
9757   node = vat_json_array_add (&vam->json_tree);
9758
9759   vat_json_init_object (node);
9760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9761   vat_json_object_add_string_copy (node, "interface_name",
9762                                    mp->interface_name);
9763   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9764                             ntohl (mp->virtio_net_hdr_sz));
9765   vat_json_object_add_uint (node, "features",
9766                             clib_net_to_host_u64 (mp->features));
9767   vat_json_object_add_uint (node, "is_server", mp->is_server);
9768   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9769   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9770   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9771 }
9772
9773 static int
9774 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9775 {
9776   vl_api_sw_interface_vhost_user_dump_t *mp;
9777   f64 timeout;
9778   fformat (vam->ofp,
9779            "Interface name           idx hdr_sz features server regions filename\n");
9780
9781   /* Get list of vhost-user interfaces */
9782   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9783   S;
9784
9785   /* Use a control ping for synchronization */
9786   {
9787     vl_api_control_ping_t *mp;
9788     M (CONTROL_PING, control_ping);
9789     S;
9790   }
9791   W;
9792 }
9793
9794 static int
9795 api_show_version (vat_main_t * vam)
9796 {
9797   vl_api_show_version_t *mp;
9798   f64 timeout;
9799
9800   M (SHOW_VERSION, show_version);
9801
9802   S;
9803   W;
9804   /* NOTREACHED */
9805   return 0;
9806 }
9807
9808
9809 static int
9810 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9811 {
9812   unformat_input_t *line_input = vam->input;
9813   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9814   f64 timeout;
9815   ip4_address_t local4, remote4;
9816   ip6_address_t local6, remote6;
9817   u8 is_add = 1;
9818   u8 ipv4_set = 0, ipv6_set = 0;
9819   u8 local_set = 0;
9820   u8 remote_set = 0;
9821   u32 encap_vrf_id = 0;
9822   u32 decap_vrf_id = 0;
9823   u8 protocol = ~0;
9824   u32 vni;
9825   u8 vni_set = 0;
9826
9827   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (line_input, "del"))
9830         is_add = 0;
9831       else if (unformat (line_input, "local %U",
9832                          unformat_ip4_address, &local4))
9833         {
9834           local_set = 1;
9835           ipv4_set = 1;
9836         }
9837       else if (unformat (line_input, "remote %U",
9838                          unformat_ip4_address, &remote4))
9839         {
9840           remote_set = 1;
9841           ipv4_set = 1;
9842         }
9843       else if (unformat (line_input, "local %U",
9844                          unformat_ip6_address, &local6))
9845         {
9846           local_set = 1;
9847           ipv6_set = 1;
9848         }
9849       else if (unformat (line_input, "remote %U",
9850                          unformat_ip6_address, &remote6))
9851         {
9852           remote_set = 1;
9853           ipv6_set = 1;
9854         }
9855       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9856         ;
9857       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9858         ;
9859       else if (unformat (line_input, "vni %d", &vni))
9860         vni_set = 1;
9861       else if (unformat (line_input, "next-ip4"))
9862         protocol = 1;
9863       else if (unformat (line_input, "next-ip6"))
9864         protocol = 2;
9865       else if (unformat (line_input, "next-ethernet"))
9866         protocol = 3;
9867       else if (unformat (line_input, "next-nsh"))
9868         protocol = 4;
9869       else
9870         {
9871           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9872           return -99;
9873         }
9874     }
9875
9876   if (local_set == 0)
9877     {
9878       errmsg ("tunnel local address not specified\n");
9879       return -99;
9880     }
9881   if (remote_set == 0)
9882     {
9883       errmsg ("tunnel remote address not specified\n");
9884       return -99;
9885     }
9886   if (ipv4_set && ipv6_set)
9887     {
9888       errmsg ("both IPv4 and IPv6 addresses specified");
9889       return -99;
9890     }
9891
9892   if (vni_set == 0)
9893     {
9894       errmsg ("vni not specified\n");
9895       return -99;
9896     }
9897
9898   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9899
9900
9901   if (ipv6_set)
9902     {
9903       clib_memcpy (&mp->local, &local6, sizeof (local6));
9904       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9905     }
9906   else
9907     {
9908       clib_memcpy (&mp->local, &local4, sizeof (local4));
9909       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9910     }
9911
9912   mp->encap_vrf_id = ntohl (encap_vrf_id);
9913   mp->decap_vrf_id = ntohl (decap_vrf_id);
9914   mp->protocol = ntohl (protocol);
9915   mp->vni = ntohl (vni);
9916   mp->is_add = is_add;
9917   mp->is_ipv6 = ipv6_set;
9918
9919   S;
9920   W;
9921   /* NOTREACHED */
9922   return 0;
9923 }
9924
9925 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9926   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9927 {
9928   vat_main_t *vam = &vat_main;
9929
9930   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9931            ntohl (mp->sw_if_index),
9932            format_ip46_address, &(mp->local[0]),
9933            format_ip46_address, &(mp->remote[0]),
9934            ntohl (mp->vni),
9935            ntohl (mp->protocol),
9936            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9937 }
9938
9939 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9940   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9941 {
9942   vat_main_t *vam = &vat_main;
9943   vat_json_node_t *node = NULL;
9944   struct in_addr ip4;
9945   struct in6_addr ip6;
9946
9947   if (VAT_JSON_ARRAY != vam->json_tree.type)
9948     {
9949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9950       vat_json_init_array (&vam->json_tree);
9951     }
9952   node = vat_json_array_add (&vam->json_tree);
9953
9954   vat_json_init_object (node);
9955   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9956   if (mp->is_ipv6)
9957     {
9958       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9959       vat_json_object_add_ip6 (node, "local", ip6);
9960       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9961       vat_json_object_add_ip6 (node, "remote", ip6);
9962     }
9963   else
9964     {
9965       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9966       vat_json_object_add_ip4 (node, "local", ip4);
9967       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9968       vat_json_object_add_ip4 (node, "remote", ip4);
9969     }
9970   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9971   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9972   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9973   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
9974   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9975 }
9976
9977 static int
9978 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9979 {
9980   unformat_input_t *i = vam->input;
9981   vl_api_vxlan_gpe_tunnel_dump_t *mp;
9982   f64 timeout;
9983   u32 sw_if_index;
9984   u8 sw_if_index_set = 0;
9985
9986   /* Parse args required to build the message */
9987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9988     {
9989       if (unformat (i, "sw_if_index %d", &sw_if_index))
9990         sw_if_index_set = 1;
9991       else
9992         break;
9993     }
9994
9995   if (sw_if_index_set == 0)
9996     {
9997       sw_if_index = ~0;
9998     }
9999
10000   if (!vam->json_output)
10001     {
10002       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10003                "sw_if_index", "local", "remote", "vni",
10004                "protocol", "encap_vrf_id", "decap_vrf_id");
10005     }
10006
10007   /* Get list of vxlan-tunnel interfaces */
10008   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10009
10010   mp->sw_if_index = htonl (sw_if_index);
10011
10012   S;
10013
10014   /* Use a control ping for synchronization */
10015   {
10016     vl_api_control_ping_t *mp;
10017     M (CONTROL_PING, control_ping);
10018     S;
10019   }
10020   W;
10021 }
10022
10023 u8 *
10024 format_l2_fib_mac_address (u8 * s, va_list * args)
10025 {
10026   u8 *a = va_arg (*args, u8 *);
10027
10028   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10029                  a[2], a[3], a[4], a[5], a[6], a[7]);
10030 }
10031
10032 static void vl_api_l2_fib_table_entry_t_handler
10033   (vl_api_l2_fib_table_entry_t * mp)
10034 {
10035   vat_main_t *vam = &vat_main;
10036
10037   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10038            "       %d       %d     %d\n",
10039            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10040            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10041            mp->bvi_mac);
10042 }
10043
10044 static void vl_api_l2_fib_table_entry_t_handler_json
10045   (vl_api_l2_fib_table_entry_t * mp)
10046 {
10047   vat_main_t *vam = &vat_main;
10048   vat_json_node_t *node = NULL;
10049
10050   if (VAT_JSON_ARRAY != vam->json_tree.type)
10051     {
10052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10053       vat_json_init_array (&vam->json_tree);
10054     }
10055   node = vat_json_array_add (&vam->json_tree);
10056
10057   vat_json_init_object (node);
10058   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10059   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10061   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10062   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10063   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10064 }
10065
10066 static int
10067 api_l2_fib_table_dump (vat_main_t * vam)
10068 {
10069   unformat_input_t *i = vam->input;
10070   vl_api_l2_fib_table_dump_t *mp;
10071   f64 timeout;
10072   u32 bd_id;
10073   u8 bd_id_set = 0;
10074
10075   /* Parse args required to build the message */
10076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10077     {
10078       if (unformat (i, "bd_id %d", &bd_id))
10079         bd_id_set = 1;
10080       else
10081         break;
10082     }
10083
10084   if (bd_id_set == 0)
10085     {
10086       errmsg ("missing bridge domain\n");
10087       return -99;
10088     }
10089
10090   fformat (vam->ofp,
10091            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10092
10093   /* Get list of l2 fib entries */
10094   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10095
10096   mp->bd_id = ntohl (bd_id);
10097   S;
10098
10099   /* Use a control ping for synchronization */
10100   {
10101     vl_api_control_ping_t *mp;
10102     M (CONTROL_PING, control_ping);
10103     S;
10104   }
10105   W;
10106 }
10107
10108
10109 static int
10110 api_interface_name_renumber (vat_main_t * vam)
10111 {
10112   unformat_input_t *line_input = vam->input;
10113   vl_api_interface_name_renumber_t *mp;
10114   u32 sw_if_index = ~0;
10115   f64 timeout;
10116   u32 new_show_dev_instance = ~0;
10117
10118   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10119     {
10120       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10121                     &sw_if_index))
10122         ;
10123       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10124         ;
10125       else if (unformat (line_input, "new_show_dev_instance %d",
10126                          &new_show_dev_instance))
10127         ;
10128       else
10129         break;
10130     }
10131
10132   if (sw_if_index == ~0)
10133     {
10134       errmsg ("missing interface name or sw_if_index\n");
10135       return -99;
10136     }
10137
10138   if (new_show_dev_instance == ~0)
10139     {
10140       errmsg ("missing new_show_dev_instance\n");
10141       return -99;
10142     }
10143
10144   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10145
10146   mp->sw_if_index = ntohl (sw_if_index);
10147   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10148
10149   S;
10150   W;
10151 }
10152
10153 static int
10154 api_want_ip4_arp_events (vat_main_t * vam)
10155 {
10156   unformat_input_t *line_input = vam->input;
10157   vl_api_want_ip4_arp_events_t *mp;
10158   f64 timeout;
10159   ip4_address_t address;
10160   int address_set = 0;
10161   u32 enable_disable = 1;
10162
10163   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10164     {
10165       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10166         address_set = 1;
10167       else if (unformat (line_input, "del"))
10168         enable_disable = 0;
10169       else
10170         break;
10171     }
10172
10173   if (address_set == 0)
10174     {
10175       errmsg ("missing addresses\n");
10176       return -99;
10177     }
10178
10179   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10180   mp->enable_disable = enable_disable;
10181   mp->pid = getpid ();
10182   mp->address = address.as_u32;
10183
10184   S;
10185   W;
10186 }
10187
10188 static int
10189 api_input_acl_set_interface (vat_main_t * vam)
10190 {
10191   unformat_input_t *i = vam->input;
10192   vl_api_input_acl_set_interface_t *mp;
10193   f64 timeout;
10194   u32 sw_if_index;
10195   int sw_if_index_set;
10196   u32 ip4_table_index = ~0;
10197   u32 ip6_table_index = ~0;
10198   u32 l2_table_index = ~0;
10199   u8 is_add = 1;
10200
10201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10202     {
10203       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10204         sw_if_index_set = 1;
10205       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10206         sw_if_index_set = 1;
10207       else if (unformat (i, "del"))
10208         is_add = 0;
10209       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10210         ;
10211       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10212         ;
10213       else if (unformat (i, "l2-table %d", &l2_table_index))
10214         ;
10215       else
10216         {
10217           clib_warning ("parse error '%U'", format_unformat_error, i);
10218           return -99;
10219         }
10220     }
10221
10222   if (sw_if_index_set == 0)
10223     {
10224       errmsg ("missing interface name or sw_if_index\n");
10225       return -99;
10226     }
10227
10228   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10229
10230   mp->sw_if_index = ntohl (sw_if_index);
10231   mp->ip4_table_index = ntohl (ip4_table_index);
10232   mp->ip6_table_index = ntohl (ip6_table_index);
10233   mp->l2_table_index = ntohl (l2_table_index);
10234   mp->is_add = is_add;
10235
10236   S;
10237   W;
10238   /* NOTREACHED */
10239   return 0;
10240 }
10241
10242 static int
10243 api_ip_address_dump (vat_main_t * vam)
10244 {
10245   unformat_input_t *i = vam->input;
10246   vl_api_ip_address_dump_t *mp;
10247   u32 sw_if_index = ~0;
10248   u8 sw_if_index_set = 0;
10249   u8 ipv4_set = 0;
10250   u8 ipv6_set = 0;
10251   f64 timeout;
10252
10253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10254     {
10255       if (unformat (i, "sw_if_index %d", &sw_if_index))
10256         sw_if_index_set = 1;
10257       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10258         sw_if_index_set = 1;
10259       else if (unformat (i, "ipv4"))
10260         ipv4_set = 1;
10261       else if (unformat (i, "ipv6"))
10262         ipv6_set = 1;
10263       else
10264         break;
10265     }
10266
10267   if (ipv4_set && ipv6_set)
10268     {
10269       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10270       return -99;
10271     }
10272
10273   if ((!ipv4_set) && (!ipv6_set))
10274     {
10275       errmsg ("no ipv4 nor ipv6 flag set\n");
10276       return -99;
10277     }
10278
10279   if (sw_if_index_set == 0)
10280     {
10281       errmsg ("missing interface name or sw_if_index\n");
10282       return -99;
10283     }
10284
10285   vam->current_sw_if_index = sw_if_index;
10286   vam->is_ipv6 = ipv6_set;
10287
10288   M (IP_ADDRESS_DUMP, ip_address_dump);
10289   mp->sw_if_index = ntohl (sw_if_index);
10290   mp->is_ipv6 = ipv6_set;
10291   S;
10292
10293   /* Use a control ping for synchronization */
10294   {
10295     vl_api_control_ping_t *mp;
10296     M (CONTROL_PING, control_ping);
10297     S;
10298   }
10299   W;
10300 }
10301
10302 static int
10303 api_ip_dump (vat_main_t * vam)
10304 {
10305   vl_api_ip_dump_t *mp;
10306   unformat_input_t *in = vam->input;
10307   int ipv4_set = 0;
10308   int ipv6_set = 0;
10309   int is_ipv6;
10310   f64 timeout;
10311   int i;
10312
10313   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10314     {
10315       if (unformat (in, "ipv4"))
10316         ipv4_set = 1;
10317       else if (unformat (in, "ipv6"))
10318         ipv6_set = 1;
10319       else
10320         break;
10321     }
10322
10323   if (ipv4_set && ipv6_set)
10324     {
10325       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10326       return -99;
10327     }
10328
10329   if ((!ipv4_set) && (!ipv6_set))
10330     {
10331       errmsg ("no ipv4 nor ipv6 flag set\n");
10332       return -99;
10333     }
10334
10335   is_ipv6 = ipv6_set;
10336   vam->is_ipv6 = is_ipv6;
10337
10338   /* free old data */
10339   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10340     {
10341       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10342     }
10343   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10344
10345   M (IP_DUMP, ip_dump);
10346   mp->is_ipv6 = ipv6_set;
10347   S;
10348
10349   /* Use a control ping for synchronization */
10350   {
10351     vl_api_control_ping_t *mp;
10352     M (CONTROL_PING, control_ping);
10353     S;
10354   }
10355   W;
10356 }
10357
10358 static int
10359 api_ipsec_spd_add_del (vat_main_t * vam)
10360 {
10361 #if DPDK > 0
10362   unformat_input_t *i = vam->input;
10363   vl_api_ipsec_spd_add_del_t *mp;
10364   f64 timeout;
10365   u32 spd_id = ~0;
10366   u8 is_add = 1;
10367
10368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10369     {
10370       if (unformat (i, "spd_id %d", &spd_id))
10371         ;
10372       else if (unformat (i, "del"))
10373         is_add = 0;
10374       else
10375         {
10376           clib_warning ("parse error '%U'", format_unformat_error, i);
10377           return -99;
10378         }
10379     }
10380   if (spd_id == ~0)
10381     {
10382       errmsg ("spd_id must be set\n");
10383       return -99;
10384     }
10385
10386   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10387
10388   mp->spd_id = ntohl (spd_id);
10389   mp->is_add = is_add;
10390
10391   S;
10392   W;
10393   /* NOTREACHED */
10394   return 0;
10395 #else
10396   clib_warning ("unsupported (no dpdk)");
10397   return -99;
10398 #endif
10399 }
10400
10401 static int
10402 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10403 {
10404 #if DPDK > 0
10405   unformat_input_t *i = vam->input;
10406   vl_api_ipsec_interface_add_del_spd_t *mp;
10407   f64 timeout;
10408   u32 sw_if_index;
10409   u8 sw_if_index_set = 0;
10410   u32 spd_id = (u32) ~ 0;
10411   u8 is_add = 1;
10412
10413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (i, "del"))
10416         is_add = 0;
10417       else if (unformat (i, "spd_id %d", &spd_id))
10418         ;
10419       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10420         sw_if_index_set = 1;
10421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10422         sw_if_index_set = 1;
10423       else
10424         {
10425           clib_warning ("parse error '%U'", format_unformat_error, i);
10426           return -99;
10427         }
10428
10429     }
10430
10431   if (spd_id == (u32) ~ 0)
10432     {
10433       errmsg ("spd_id must be set\n");
10434       return -99;
10435     }
10436
10437   if (sw_if_index_set == 0)
10438     {
10439       errmsg ("missing interface name or sw_if_index\n");
10440       return -99;
10441     }
10442
10443   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10444
10445   mp->spd_id = ntohl (spd_id);
10446   mp->sw_if_index = ntohl (sw_if_index);
10447   mp->is_add = is_add;
10448
10449   S;
10450   W;
10451   /* NOTREACHED */
10452   return 0;
10453 #else
10454   clib_warning ("unsupported (no dpdk)");
10455   return -99;
10456 #endif
10457 }
10458
10459 static int
10460 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10461 {
10462 #if DPDK > 0
10463   unformat_input_t *i = vam->input;
10464   vl_api_ipsec_spd_add_del_entry_t *mp;
10465   f64 timeout;
10466   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10467   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10468   i32 priority = 0;
10469   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10470   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10471   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10472   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10473
10474   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10475   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10476   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10477   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10478   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10479   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10480
10481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10482     {
10483       if (unformat (i, "del"))
10484         is_add = 0;
10485       if (unformat (i, "outbound"))
10486         is_outbound = 1;
10487       if (unformat (i, "inbound"))
10488         is_outbound = 0;
10489       else if (unformat (i, "spd_id %d", &spd_id))
10490         ;
10491       else if (unformat (i, "sa_id %d", &sa_id))
10492         ;
10493       else if (unformat (i, "priority %d", &priority))
10494         ;
10495       else if (unformat (i, "protocol %d", &protocol))
10496         ;
10497       else if (unformat (i, "lport_start %d", &lport_start))
10498         ;
10499       else if (unformat (i, "lport_stop %d", &lport_stop))
10500         ;
10501       else if (unformat (i, "rport_start %d", &rport_start))
10502         ;
10503       else if (unformat (i, "rport_stop %d", &rport_stop))
10504         ;
10505       else
10506         if (unformat
10507             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10508         {
10509           is_ipv6 = 0;
10510           is_ip_any = 0;
10511         }
10512       else
10513         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10514         {
10515           is_ipv6 = 0;
10516           is_ip_any = 0;
10517         }
10518       else
10519         if (unformat
10520             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10521         {
10522           is_ipv6 = 0;
10523           is_ip_any = 0;
10524         }
10525       else
10526         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10527         {
10528           is_ipv6 = 0;
10529           is_ip_any = 0;
10530         }
10531       else
10532         if (unformat
10533             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10534         {
10535           is_ipv6 = 1;
10536           is_ip_any = 0;
10537         }
10538       else
10539         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10540         {
10541           is_ipv6 = 1;
10542           is_ip_any = 0;
10543         }
10544       else
10545         if (unformat
10546             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10547         {
10548           is_ipv6 = 1;
10549           is_ip_any = 0;
10550         }
10551       else
10552         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10553         {
10554           is_ipv6 = 1;
10555           is_ip_any = 0;
10556         }
10557       else
10558         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10559         {
10560           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10561             {
10562               clib_warning ("unsupported action: 'resolve'");
10563               return -99;
10564             }
10565         }
10566       else
10567         {
10568           clib_warning ("parse error '%U'", format_unformat_error, i);
10569           return -99;
10570         }
10571
10572     }
10573
10574   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10575
10576   mp->spd_id = ntohl (spd_id);
10577   mp->priority = ntohl (priority);
10578   mp->is_outbound = is_outbound;
10579
10580   mp->is_ipv6 = is_ipv6;
10581   if (is_ipv6 || is_ip_any)
10582     {
10583       clib_memcpy (mp->remote_address_start, &raddr6_start,
10584                    sizeof (ip6_address_t));
10585       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10586                    sizeof (ip6_address_t));
10587       clib_memcpy (mp->local_address_start, &laddr6_start,
10588                    sizeof (ip6_address_t));
10589       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10590                    sizeof (ip6_address_t));
10591     }
10592   else
10593     {
10594       clib_memcpy (mp->remote_address_start, &raddr4_start,
10595                    sizeof (ip4_address_t));
10596       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10597                    sizeof (ip4_address_t));
10598       clib_memcpy (mp->local_address_start, &laddr4_start,
10599                    sizeof (ip4_address_t));
10600       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10601                    sizeof (ip4_address_t));
10602     }
10603   mp->protocol = (u8) protocol;
10604   mp->local_port_start = ntohs ((u16) lport_start);
10605   mp->local_port_stop = ntohs ((u16) lport_stop);
10606   mp->remote_port_start = ntohs ((u16) rport_start);
10607   mp->remote_port_stop = ntohs ((u16) rport_stop);
10608   mp->policy = (u8) policy;
10609   mp->sa_id = ntohl (sa_id);
10610   mp->is_add = is_add;
10611   mp->is_ip_any = is_ip_any;
10612   S;
10613   W;
10614   /* NOTREACHED */
10615   return 0;
10616 #else
10617   clib_warning ("unsupported (no dpdk)");
10618   return -99;
10619 #endif
10620 }
10621
10622 static int
10623 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10624 {
10625 #if DPDK > 0
10626   unformat_input_t *i = vam->input;
10627   vl_api_ipsec_sad_add_del_entry_t *mp;
10628   f64 timeout;
10629   u32 sad_id = 0, spi = 0;
10630   u8 *ck = 0, *ik = 0;
10631   u8 is_add = 1;
10632
10633   u8 protocol = IPSEC_PROTOCOL_AH;
10634   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10635   u32 crypto_alg = 0, integ_alg = 0;
10636   ip4_address_t tun_src4;
10637   ip4_address_t tun_dst4;
10638   ip6_address_t tun_src6;
10639   ip6_address_t tun_dst6;
10640
10641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10642     {
10643       if (unformat (i, "del"))
10644         is_add = 0;
10645       else if (unformat (i, "sad_id %d", &sad_id))
10646         ;
10647       else if (unformat (i, "spi %d", &spi))
10648         ;
10649       else if (unformat (i, "esp"))
10650         protocol = IPSEC_PROTOCOL_ESP;
10651       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10652         {
10653           is_tunnel = 1;
10654           is_tunnel_ipv6 = 0;
10655         }
10656       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10657         {
10658           is_tunnel = 1;
10659           is_tunnel_ipv6 = 0;
10660         }
10661       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10662         {
10663           is_tunnel = 1;
10664           is_tunnel_ipv6 = 1;
10665         }
10666       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10667         {
10668           is_tunnel = 1;
10669           is_tunnel_ipv6 = 1;
10670         }
10671       else
10672         if (unformat
10673             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10674         {
10675           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10676               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10677             {
10678               clib_warning ("unsupported crypto-alg: '%U'",
10679                             format_ipsec_crypto_alg, crypto_alg);
10680               return -99;
10681             }
10682         }
10683       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10684         ;
10685       else
10686         if (unformat
10687             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10688         {
10689           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10690               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10691             {
10692               clib_warning ("unsupported integ-alg: '%U'",
10693                             format_ipsec_integ_alg, integ_alg);
10694               return -99;
10695             }
10696         }
10697       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10698         ;
10699       else
10700         {
10701           clib_warning ("parse error '%U'", format_unformat_error, i);
10702           return -99;
10703         }
10704
10705     }
10706
10707   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10708
10709   mp->sad_id = ntohl (sad_id);
10710   mp->is_add = is_add;
10711   mp->protocol = protocol;
10712   mp->spi = ntohl (spi);
10713   mp->is_tunnel = is_tunnel;
10714   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10715   mp->crypto_algorithm = crypto_alg;
10716   mp->integrity_algorithm = integ_alg;
10717   mp->crypto_key_length = vec_len (ck);
10718   mp->integrity_key_length = vec_len (ik);
10719
10720   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10721     mp->crypto_key_length = sizeof (mp->crypto_key);
10722
10723   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10724     mp->integrity_key_length = sizeof (mp->integrity_key);
10725
10726   if (ck)
10727     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10728   if (ik)
10729     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10730
10731   if (is_tunnel)
10732     {
10733       if (is_tunnel_ipv6)
10734         {
10735           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10736                        sizeof (ip6_address_t));
10737           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10738                        sizeof (ip6_address_t));
10739         }
10740       else
10741         {
10742           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10743                        sizeof (ip4_address_t));
10744           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10745                        sizeof (ip4_address_t));
10746         }
10747     }
10748
10749   S;
10750   W;
10751   /* NOTREACHED */
10752   return 0;
10753 #else
10754   clib_warning ("unsupported (no dpdk)");
10755   return -99;
10756 #endif
10757 }
10758
10759 static int
10760 api_ipsec_sa_set_key (vat_main_t * vam)
10761 {
10762 #if DPDK > 0
10763   unformat_input_t *i = vam->input;
10764   vl_api_ipsec_sa_set_key_t *mp;
10765   f64 timeout;
10766   u32 sa_id;
10767   u8 *ck = 0, *ik = 0;
10768
10769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (i, "sa_id %d", &sa_id))
10772         ;
10773       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10774         ;
10775       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10776         ;
10777       else
10778         {
10779           clib_warning ("parse error '%U'", format_unformat_error, i);
10780           return -99;
10781         }
10782     }
10783
10784   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10785
10786   mp->sa_id = ntohl (sa_id);
10787   mp->crypto_key_length = vec_len (ck);
10788   mp->integrity_key_length = vec_len (ik);
10789
10790   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10791     mp->crypto_key_length = sizeof (mp->crypto_key);
10792
10793   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10794     mp->integrity_key_length = sizeof (mp->integrity_key);
10795
10796   if (ck)
10797     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10798   if (ik)
10799     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10800
10801   S;
10802   W;
10803   /* NOTREACHED */
10804   return 0;
10805 #else
10806   clib_warning ("unsupported (no dpdk)");
10807   return -99;
10808 #endif
10809 }
10810
10811 static int
10812 api_ikev2_profile_add_del (vat_main_t * vam)
10813 {
10814 #if DPDK > 0
10815   unformat_input_t *i = vam->input;
10816   vl_api_ikev2_profile_add_del_t *mp;
10817   f64 timeout;
10818   u8 is_add = 1;
10819   u8 *name = 0;
10820
10821   const char *valid_chars = "a-zA-Z0-9_";
10822
10823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10824     {
10825       if (unformat (i, "del"))
10826         is_add = 0;
10827       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10828         vec_add1 (name, 0);
10829       else
10830         {
10831           errmsg ("parse error '%U'", format_unformat_error, i);
10832           return -99;
10833         }
10834     }
10835
10836   if (!vec_len (name))
10837     {
10838       errmsg ("profile name must be specified");
10839       return -99;
10840     }
10841
10842   if (vec_len (name) > 64)
10843     {
10844       errmsg ("profile name too long");
10845       return -99;
10846     }
10847
10848   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10849
10850   clib_memcpy (mp->name, name, vec_len (name));
10851   mp->is_add = is_add;
10852   vec_free (name);
10853
10854   S;
10855   W;
10856   /* NOTREACHED */
10857   return 0;
10858 #else
10859   clib_warning ("unsupported (no dpdk)");
10860   return -99;
10861 #endif
10862 }
10863
10864 static int
10865 api_ikev2_profile_set_auth (vat_main_t * vam)
10866 {
10867 #if DPDK > 0
10868   unformat_input_t *i = vam->input;
10869   vl_api_ikev2_profile_set_auth_t *mp;
10870   f64 timeout;
10871   u8 *name = 0;
10872   u8 *data = 0;
10873   u32 auth_method = 0;
10874   u8 is_hex = 0;
10875
10876   const char *valid_chars = "a-zA-Z0-9_";
10877
10878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10879     {
10880       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10881         vec_add1 (name, 0);
10882       else if (unformat (i, "auth_method %U",
10883                          unformat_ikev2_auth_method, &auth_method))
10884         ;
10885       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10886         is_hex = 1;
10887       else if (unformat (i, "auth_data %v", &data))
10888         ;
10889       else
10890         {
10891           errmsg ("parse error '%U'", format_unformat_error, i);
10892           return -99;
10893         }
10894     }
10895
10896   if (!vec_len (name))
10897     {
10898       errmsg ("profile name must be specified");
10899       return -99;
10900     }
10901
10902   if (vec_len (name) > 64)
10903     {
10904       errmsg ("profile name too long");
10905       return -99;
10906     }
10907
10908   if (!vec_len (data))
10909     {
10910       errmsg ("auth_data must be specified");
10911       return -99;
10912     }
10913
10914   if (!auth_method)
10915     {
10916       errmsg ("auth_method must be specified");
10917       return -99;
10918     }
10919
10920   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10921
10922   mp->is_hex = is_hex;
10923   mp->auth_method = (u8) auth_method;
10924   mp->data_len = vec_len (data);
10925   clib_memcpy (mp->name, name, vec_len (name));
10926   clib_memcpy (mp->data, data, vec_len (data));
10927   vec_free (name);
10928   vec_free (data);
10929
10930   S;
10931   W;
10932   /* NOTREACHED */
10933   return 0;
10934 #else
10935   clib_warning ("unsupported (no dpdk)");
10936   return -99;
10937 #endif
10938 }
10939
10940 static int
10941 api_ikev2_profile_set_id (vat_main_t * vam)
10942 {
10943 #if DPDK > 0
10944   unformat_input_t *i = vam->input;
10945   vl_api_ikev2_profile_set_id_t *mp;
10946   f64 timeout;
10947   u8 *name = 0;
10948   u8 *data = 0;
10949   u8 is_local = 0;
10950   u32 id_type = 0;
10951   ip4_address_t ip4;
10952
10953   const char *valid_chars = "a-zA-Z0-9_";
10954
10955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10956     {
10957       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10958         vec_add1 (name, 0);
10959       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10960         ;
10961       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10962         {
10963           data = vec_new (u8, 4);
10964           clib_memcpy (data, ip4.as_u8, 4);
10965         }
10966       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10967         ;
10968       else if (unformat (i, "id_data %v", &data))
10969         ;
10970       else if (unformat (i, "local"))
10971         is_local = 1;
10972       else if (unformat (i, "remote"))
10973         is_local = 0;
10974       else
10975         {
10976           errmsg ("parse error '%U'", format_unformat_error, i);
10977           return -99;
10978         }
10979     }
10980
10981   if (!vec_len (name))
10982     {
10983       errmsg ("profile name must be specified");
10984       return -99;
10985     }
10986
10987   if (vec_len (name) > 64)
10988     {
10989       errmsg ("profile name too long");
10990       return -99;
10991     }
10992
10993   if (!vec_len (data))
10994     {
10995       errmsg ("id_data must be specified");
10996       return -99;
10997     }
10998
10999   if (!id_type)
11000     {
11001       errmsg ("id_type must be specified");
11002       return -99;
11003     }
11004
11005   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11006
11007   mp->is_local = is_local;
11008   mp->id_type = (u8) id_type;
11009   mp->data_len = vec_len (data);
11010   clib_memcpy (mp->name, name, vec_len (name));
11011   clib_memcpy (mp->data, data, vec_len (data));
11012   vec_free (name);
11013   vec_free (data);
11014
11015   S;
11016   W;
11017   /* NOTREACHED */
11018   return 0;
11019 #else
11020   clib_warning ("unsupported (no dpdk)");
11021   return -99;
11022 #endif
11023 }
11024
11025 static int
11026 api_ikev2_profile_set_ts (vat_main_t * vam)
11027 {
11028 #if DPDK > 0
11029   unformat_input_t *i = vam->input;
11030   vl_api_ikev2_profile_set_ts_t *mp;
11031   f64 timeout;
11032   u8 *name = 0;
11033   u8 is_local = 0;
11034   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11035   ip4_address_t start_addr, end_addr;
11036
11037   const char *valid_chars = "a-zA-Z0-9_";
11038
11039   start_addr.as_u32 = 0;
11040   end_addr.as_u32 = (u32) ~ 0;
11041
11042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11045         vec_add1 (name, 0);
11046       else if (unformat (i, "protocol %d", &proto))
11047         ;
11048       else if (unformat (i, "start_port %d", &start_port))
11049         ;
11050       else if (unformat (i, "end_port %d", &end_port))
11051         ;
11052       else
11053         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11054         ;
11055       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11056         ;
11057       else if (unformat (i, "local"))
11058         is_local = 1;
11059       else if (unformat (i, "remote"))
11060         is_local = 0;
11061       else
11062         {
11063           errmsg ("parse error '%U'", format_unformat_error, i);
11064           return -99;
11065         }
11066     }
11067
11068   if (!vec_len (name))
11069     {
11070       errmsg ("profile name must be specified");
11071       return -99;
11072     }
11073
11074   if (vec_len (name) > 64)
11075     {
11076       errmsg ("profile name too long");
11077       return -99;
11078     }
11079
11080   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11081
11082   mp->is_local = is_local;
11083   mp->proto = (u8) proto;
11084   mp->start_port = (u16) start_port;
11085   mp->end_port = (u16) end_port;
11086   mp->start_addr = start_addr.as_u32;
11087   mp->end_addr = end_addr.as_u32;
11088   clib_memcpy (mp->name, name, vec_len (name));
11089   vec_free (name);
11090
11091   S;
11092   W;
11093   /* NOTREACHED */
11094   return 0;
11095 #else
11096   clib_warning ("unsupported (no dpdk)");
11097   return -99;
11098 #endif
11099 }
11100
11101 static int
11102 api_ikev2_set_local_key (vat_main_t * vam)
11103 {
11104 #if DPDK > 0
11105   unformat_input_t *i = vam->input;
11106   vl_api_ikev2_set_local_key_t *mp;
11107   f64 timeout;
11108   u8 *file = 0;
11109
11110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11111     {
11112       if (unformat (i, "file %v", &file))
11113         vec_add1 (file, 0);
11114       else
11115         {
11116           errmsg ("parse error '%U'", format_unformat_error, i);
11117           return -99;
11118         }
11119     }
11120
11121   if (!vec_len (file))
11122     {
11123       errmsg ("RSA key file must be specified");
11124       return -99;
11125     }
11126
11127   if (vec_len (file) > 256)
11128     {
11129       errmsg ("file name too long");
11130       return -99;
11131     }
11132
11133   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11134
11135   clib_memcpy (mp->key_file, file, vec_len (file));
11136   vec_free (file);
11137
11138   S;
11139   W;
11140   /* NOTREACHED */
11141   return 0;
11142 #else
11143   clib_warning ("unsupported (no dpdk)");
11144   return -99;
11145 #endif
11146 }
11147
11148 /*
11149  * MAP
11150  */
11151 static int
11152 api_map_add_domain (vat_main_t * vam)
11153 {
11154   unformat_input_t *i = vam->input;
11155   vl_api_map_add_domain_t *mp;
11156   f64 timeout;
11157
11158   ip4_address_t ip4_prefix;
11159   ip6_address_t ip6_prefix;
11160   ip6_address_t ip6_src;
11161   u32 num_m_args = 0;
11162   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11163     0, psid_length = 0;
11164   u8 is_translation = 0;
11165   u32 mtu = 0;
11166   u8 ip6_src_len = 128;
11167
11168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11169     {
11170       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11171                     &ip4_prefix, &ip4_prefix_len))
11172         num_m_args++;
11173       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11174                          &ip6_prefix, &ip6_prefix_len))
11175         num_m_args++;
11176       else
11177         if (unformat
11178             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11179              &ip6_src_len))
11180         num_m_args++;
11181       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11182         num_m_args++;
11183       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11184         num_m_args++;
11185       else if (unformat (i, "psid-offset %d", &psid_offset))
11186         num_m_args++;
11187       else if (unformat (i, "psid-len %d", &psid_length))
11188         num_m_args++;
11189       else if (unformat (i, "mtu %d", &mtu))
11190         num_m_args++;
11191       else if (unformat (i, "map-t"))
11192         is_translation = 1;
11193       else
11194         {
11195           clib_warning ("parse error '%U'", format_unformat_error, i);
11196           return -99;
11197         }
11198     }
11199
11200   if (num_m_args != 6)
11201     {
11202       errmsg ("mandatory argument(s) missing\n");
11203       return -99;
11204     }
11205
11206   /* Construct the API message */
11207   M (MAP_ADD_DOMAIN, map_add_domain);
11208
11209   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11210   mp->ip4_prefix_len = ip4_prefix_len;
11211
11212   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11213   mp->ip6_prefix_len = ip6_prefix_len;
11214
11215   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11216   mp->ip6_src_prefix_len = ip6_src_len;
11217
11218   mp->ea_bits_len = ea_bits_len;
11219   mp->psid_offset = psid_offset;
11220   mp->psid_length = psid_length;
11221   mp->is_translation = is_translation;
11222   mp->mtu = htons (mtu);
11223
11224   /* send it... */
11225   S;
11226
11227   /* Wait for a reply, return good/bad news  */
11228   W;
11229 }
11230
11231 static int
11232 api_map_del_domain (vat_main_t * vam)
11233 {
11234   unformat_input_t *i = vam->input;
11235   vl_api_map_del_domain_t *mp;
11236   f64 timeout;
11237
11238   u32 num_m_args = 0;
11239   u32 index;
11240
11241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11242     {
11243       if (unformat (i, "index %d", &index))
11244         num_m_args++;
11245       else
11246         {
11247           clib_warning ("parse error '%U'", format_unformat_error, i);
11248           return -99;
11249         }
11250     }
11251
11252   if (num_m_args != 1)
11253     {
11254       errmsg ("mandatory argument(s) missing\n");
11255       return -99;
11256     }
11257
11258   /* Construct the API message */
11259   M (MAP_DEL_DOMAIN, map_del_domain);
11260
11261   mp->index = ntohl (index);
11262
11263   /* send it... */
11264   S;
11265
11266   /* Wait for a reply, return good/bad news  */
11267   W;
11268 }
11269
11270 static int
11271 api_map_add_del_rule (vat_main_t * vam)
11272 {
11273   unformat_input_t *i = vam->input;
11274   vl_api_map_add_del_rule_t *mp;
11275   f64 timeout;
11276   u8 is_add = 1;
11277   ip6_address_t ip6_dst;
11278   u32 num_m_args = 0, index, psid = 0;
11279
11280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11281     {
11282       if (unformat (i, "index %d", &index))
11283         num_m_args++;
11284       else if (unformat (i, "psid %d", &psid))
11285         num_m_args++;
11286       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11287         num_m_args++;
11288       else if (unformat (i, "del"))
11289         {
11290           is_add = 0;
11291         }
11292       else
11293         {
11294           clib_warning ("parse error '%U'", format_unformat_error, i);
11295           return -99;
11296         }
11297     }
11298
11299   /* Construct the API message */
11300   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11301
11302   mp->index = ntohl (index);
11303   mp->is_add = is_add;
11304   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11305   mp->psid = ntohs (psid);
11306
11307   /* send it... */
11308   S;
11309
11310   /* Wait for a reply, return good/bad news  */
11311   W;
11312 }
11313
11314 static int
11315 api_map_domain_dump (vat_main_t * vam)
11316 {
11317   vl_api_map_domain_dump_t *mp;
11318   f64 timeout;
11319
11320   /* Construct the API message */
11321   M (MAP_DOMAIN_DUMP, map_domain_dump);
11322
11323   /* send it... */
11324   S;
11325
11326   /* Use a control ping for synchronization */
11327   {
11328     vl_api_control_ping_t *mp;
11329     M (CONTROL_PING, control_ping);
11330     S;
11331   }
11332   W;
11333 }
11334
11335 static int
11336 api_map_rule_dump (vat_main_t * vam)
11337 {
11338   unformat_input_t *i = vam->input;
11339   vl_api_map_rule_dump_t *mp;
11340   f64 timeout;
11341   u32 domain_index = ~0;
11342
11343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11344     {
11345       if (unformat (i, "index %u", &domain_index))
11346         ;
11347       else
11348         break;
11349     }
11350
11351   if (domain_index == ~0)
11352     {
11353       clib_warning ("parse error: domain index expected");
11354       return -99;
11355     }
11356
11357   /* Construct the API message */
11358   M (MAP_RULE_DUMP, map_rule_dump);
11359
11360   mp->domain_index = htonl (domain_index);
11361
11362   /* send it... */
11363   S;
11364
11365   /* Use a control ping for synchronization */
11366   {
11367     vl_api_control_ping_t *mp;
11368     M (CONTROL_PING, control_ping);
11369     S;
11370   }
11371   W;
11372 }
11373
11374 static void vl_api_map_add_domain_reply_t_handler
11375   (vl_api_map_add_domain_reply_t * mp)
11376 {
11377   vat_main_t *vam = &vat_main;
11378   i32 retval = ntohl (mp->retval);
11379
11380   if (vam->async_mode)
11381     {
11382       vam->async_errors += (retval < 0);
11383     }
11384   else
11385     {
11386       vam->retval = retval;
11387       vam->result_ready = 1;
11388     }
11389 }
11390
11391 static void vl_api_map_add_domain_reply_t_handler_json
11392   (vl_api_map_add_domain_reply_t * mp)
11393 {
11394   vat_main_t *vam = &vat_main;
11395   vat_json_node_t node;
11396
11397   vat_json_init_object (&node);
11398   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11399   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11400
11401   vat_json_print (vam->ofp, &node);
11402   vat_json_free (&node);
11403
11404   vam->retval = ntohl (mp->retval);
11405   vam->result_ready = 1;
11406 }
11407
11408 static int
11409 api_get_first_msg_id (vat_main_t * vam)
11410 {
11411   vl_api_get_first_msg_id_t *mp;
11412   f64 timeout;
11413   unformat_input_t *i = vam->input;
11414   u8 *name;
11415   u8 name_set = 0;
11416
11417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11418     {
11419       if (unformat (i, "client %s", &name))
11420         name_set = 1;
11421       else
11422         break;
11423     }
11424
11425   if (name_set == 0)
11426     {
11427       errmsg ("missing client name\n");
11428       return -99;
11429     }
11430   vec_add1 (name, 0);
11431
11432   if (vec_len (name) > 63)
11433     {
11434       errmsg ("client name too long\n");
11435       return -99;
11436     }
11437
11438   M (GET_FIRST_MSG_ID, get_first_msg_id);
11439   clib_memcpy (mp->name, name, vec_len (name));
11440   S;
11441   W;
11442   /* NOTREACHED */
11443   return 0;
11444 }
11445
11446 static int
11447 api_cop_interface_enable_disable (vat_main_t * vam)
11448 {
11449   unformat_input_t *line_input = vam->input;
11450   vl_api_cop_interface_enable_disable_t *mp;
11451   f64 timeout;
11452   u32 sw_if_index = ~0;
11453   u8 enable_disable = 1;
11454
11455   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11456     {
11457       if (unformat (line_input, "disable"))
11458         enable_disable = 0;
11459       if (unformat (line_input, "enable"))
11460         enable_disable = 1;
11461       else if (unformat (line_input, "%U", unformat_sw_if_index,
11462                          vam, &sw_if_index))
11463         ;
11464       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11465         ;
11466       else
11467         break;
11468     }
11469
11470   if (sw_if_index == ~0)
11471     {
11472       errmsg ("missing interface name or sw_if_index\n");
11473       return -99;
11474     }
11475
11476   /* Construct the API message */
11477   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11478   mp->sw_if_index = ntohl (sw_if_index);
11479   mp->enable_disable = enable_disable;
11480
11481   /* send it... */
11482   S;
11483   /* Wait for the reply */
11484   W;
11485 }
11486
11487 static int
11488 api_cop_whitelist_enable_disable (vat_main_t * vam)
11489 {
11490   unformat_input_t *line_input = vam->input;
11491   vl_api_cop_whitelist_enable_disable_t *mp;
11492   f64 timeout;
11493   u32 sw_if_index = ~0;
11494   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11495   u32 fib_id = 0;
11496
11497   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11498     {
11499       if (unformat (line_input, "ip4"))
11500         ip4 = 1;
11501       else if (unformat (line_input, "ip6"))
11502         ip6 = 1;
11503       else if (unformat (line_input, "default"))
11504         default_cop = 1;
11505       else if (unformat (line_input, "%U", unformat_sw_if_index,
11506                          vam, &sw_if_index))
11507         ;
11508       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11509         ;
11510       else if (unformat (line_input, "fib-id %d", &fib_id))
11511         ;
11512       else
11513         break;
11514     }
11515
11516   if (sw_if_index == ~0)
11517     {
11518       errmsg ("missing interface name or sw_if_index\n");
11519       return -99;
11520     }
11521
11522   /* Construct the API message */
11523   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11524   mp->sw_if_index = ntohl (sw_if_index);
11525   mp->fib_id = ntohl (fib_id);
11526   mp->ip4 = ip4;
11527   mp->ip6 = ip6;
11528   mp->default_cop = default_cop;
11529
11530   /* send it... */
11531   S;
11532   /* Wait for the reply */
11533   W;
11534 }
11535
11536 static int
11537 api_get_node_graph (vat_main_t * vam)
11538 {
11539   vl_api_get_node_graph_t *mp;
11540   f64 timeout;
11541
11542   M (GET_NODE_GRAPH, get_node_graph);
11543
11544   /* send it... */
11545   S;
11546   /* Wait for the reply */
11547   W;
11548 }
11549
11550 /* *INDENT-OFF* */
11551 /** Used for parsing LISP eids */
11552 typedef CLIB_PACKED(struct{
11553   u8 addr[16];   /**< eid address */
11554   u32 len;       /**< prefix length if IP */
11555   u8 type;      /**< type of eid */
11556 }) lisp_eid_vat_t;
11557 /* *INDENT-ON* */
11558
11559 static uword
11560 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11561 {
11562   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11563
11564   memset (a, 0, sizeof (a[0]));
11565
11566   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11567     {
11568       a->type = 0;              /* ipv4 type */
11569     }
11570   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11571     {
11572       a->type = 1;              /* ipv6 type */
11573     }
11574   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11575     {
11576       a->type = 2;              /* mac type */
11577     }
11578   else
11579     {
11580       return 0;
11581     }
11582
11583   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11584     {
11585       return 0;
11586     }
11587
11588   return 1;
11589 }
11590
11591 static int
11592 lisp_eid_size_vat (u8 type)
11593 {
11594   switch (type)
11595     {
11596     case 0:
11597       return 4;
11598     case 1:
11599       return 16;
11600     case 2:
11601       return 6;
11602     }
11603   return 0;
11604 }
11605
11606 static void
11607 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11608 {
11609   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11610 }
11611
11612 /* *INDENT-OFF* */
11613 /** Used for transferring locators via VPP API */
11614 typedef CLIB_PACKED(struct
11615 {
11616   u32 sw_if_index; /**< locator sw_if_index */
11617   u8 priority; /**< locator priority */
11618   u8 weight;   /**< locator weight */
11619 }) ls_locator_t;
11620 /* *INDENT-ON* */
11621
11622 static int
11623 api_lisp_add_del_locator_set (vat_main_t * vam)
11624 {
11625   unformat_input_t *input = vam->input;
11626   vl_api_lisp_add_del_locator_set_t *mp;
11627   f64 timeout = ~0;
11628   u8 is_add = 1;
11629   u8 *locator_set_name = NULL;
11630   u8 locator_set_name_set = 0;
11631   ls_locator_t locator, *locators = 0;
11632   u32 sw_if_index, priority, weight;
11633
11634   /* Parse args required to build the message */
11635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11636     {
11637       if (unformat (input, "del"))
11638         {
11639           is_add = 0;
11640         }
11641       else if (unformat (input, "locator-set %s", &locator_set_name))
11642         {
11643           locator_set_name_set = 1;
11644         }
11645       else if (unformat (input, "sw_if_index %u p %u w %u",
11646                          &sw_if_index, &priority, &weight))
11647         {
11648           locator.sw_if_index = htonl (sw_if_index);
11649           locator.priority = priority;
11650           locator.weight = weight;
11651           vec_add1 (locators, locator);
11652         }
11653       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11654                          vam, &sw_if_index, &priority, &weight))
11655         {
11656           locator.sw_if_index = htonl (sw_if_index);
11657           locator.priority = priority;
11658           locator.weight = weight;
11659           vec_add1 (locators, locator);
11660         }
11661       else
11662         break;
11663     }
11664
11665   if (locator_set_name_set == 0)
11666     {
11667       errmsg ("missing locator-set name");
11668       vec_free (locators);
11669       return -99;
11670     }
11671
11672   if (vec_len (locator_set_name) > 64)
11673     {
11674       errmsg ("locator-set name too long\n");
11675       vec_free (locator_set_name);
11676       vec_free (locators);
11677       return -99;
11678     }
11679   vec_add1 (locator_set_name, 0);
11680
11681   /* Construct the API message */
11682   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11683
11684   mp->is_add = is_add;
11685   clib_memcpy (mp->locator_set_name, locator_set_name,
11686                vec_len (locator_set_name));
11687   vec_free (locator_set_name);
11688
11689   mp->locator_num = vec_len (locators);
11690   if (locators)
11691     clib_memcpy (mp->locators, locators,
11692                  (sizeof (ls_locator_t) * vec_len (locators)));
11693   vec_free (locators);
11694
11695   /* send it... */
11696   S;
11697
11698   /* Wait for a reply... */
11699   W;
11700
11701   /* NOTREACHED */
11702   return 0;
11703 }
11704
11705 static int
11706 api_lisp_add_del_locator (vat_main_t * vam)
11707 {
11708   unformat_input_t *input = vam->input;
11709   vl_api_lisp_add_del_locator_t *mp;
11710   f64 timeout = ~0;
11711   u32 tmp_if_index = ~0;
11712   u32 sw_if_index = ~0;
11713   u8 sw_if_index_set = 0;
11714   u8 sw_if_index_if_name_set = 0;
11715   u32 priority = ~0;
11716   u8 priority_set = 0;
11717   u32 weight = ~0;
11718   u8 weight_set = 0;
11719   u8 is_add = 1;
11720   u8 *locator_set_name = NULL;
11721   u8 locator_set_name_set = 0;
11722
11723   /* Parse args required to build the message */
11724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11725     {
11726       if (unformat (input, "del"))
11727         {
11728           is_add = 0;
11729         }
11730       else if (unformat (input, "locator-set %s", &locator_set_name))
11731         {
11732           locator_set_name_set = 1;
11733         }
11734       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11735                          &tmp_if_index))
11736         {
11737           sw_if_index_if_name_set = 1;
11738           sw_if_index = tmp_if_index;
11739         }
11740       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11741         {
11742           sw_if_index_set = 1;
11743           sw_if_index = tmp_if_index;
11744         }
11745       else if (unformat (input, "p %d", &priority))
11746         {
11747           priority_set = 1;
11748         }
11749       else if (unformat (input, "w %d", &weight))
11750         {
11751           weight_set = 1;
11752         }
11753       else
11754         break;
11755     }
11756
11757   if (locator_set_name_set == 0)
11758     {
11759       errmsg ("missing locator-set name");
11760       return -99;
11761     }
11762
11763   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11764     {
11765       errmsg ("missing sw_if_index");
11766       vec_free (locator_set_name);
11767       return -99;
11768     }
11769
11770   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11771     {
11772       errmsg ("cannot use both params interface name and sw_if_index");
11773       vec_free (locator_set_name);
11774       return -99;
11775     }
11776
11777   if (priority_set == 0)
11778     {
11779       errmsg ("missing locator-set priority\n");
11780       vec_free (locator_set_name);
11781       return -99;
11782     }
11783
11784   if (weight_set == 0)
11785     {
11786       errmsg ("missing locator-set weight\n");
11787       vec_free (locator_set_name);
11788       return -99;
11789     }
11790
11791   if (vec_len (locator_set_name) > 64)
11792     {
11793       errmsg ("locator-set name too long\n");
11794       vec_free (locator_set_name);
11795       return -99;
11796     }
11797   vec_add1 (locator_set_name, 0);
11798
11799   /* Construct the API message */
11800   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11801
11802   mp->is_add = is_add;
11803   mp->sw_if_index = ntohl (sw_if_index);
11804   mp->priority = priority;
11805   mp->weight = weight;
11806   clib_memcpy (mp->locator_set_name, locator_set_name,
11807                vec_len (locator_set_name));
11808   vec_free (locator_set_name);
11809
11810   /* send it... */
11811   S;
11812
11813   /* Wait for a reply... */
11814   W;
11815
11816   /* NOTREACHED */
11817   return 0;
11818 }
11819
11820 static int
11821 api_lisp_add_del_local_eid (vat_main_t * vam)
11822 {
11823   unformat_input_t *input = vam->input;
11824   vl_api_lisp_add_del_local_eid_t *mp;
11825   f64 timeout = ~0;
11826   u8 is_add = 1;
11827   u8 eid_set = 0;
11828   lisp_eid_vat_t _eid, *eid = &_eid;
11829   u8 *locator_set_name = 0;
11830   u8 locator_set_name_set = 0;
11831   u32 vni = 0;
11832
11833   /* Parse args required to build the message */
11834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11835     {
11836       if (unformat (input, "del"))
11837         {
11838           is_add = 0;
11839         }
11840       else if (unformat (input, "vni %d", &vni))
11841         {
11842           ;
11843         }
11844       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11845         {
11846           eid_set = 1;
11847         }
11848       else if (unformat (input, "locator-set %s", &locator_set_name))
11849         {
11850           locator_set_name_set = 1;
11851         }
11852       else
11853         break;
11854     }
11855
11856   if (locator_set_name_set == 0)
11857     {
11858       errmsg ("missing locator-set name\n");
11859       return -99;
11860     }
11861
11862   if (0 == eid_set)
11863     {
11864       errmsg ("EID address not set!");
11865       vec_free (locator_set_name);
11866       return -99;
11867     }
11868
11869   if (vec_len (locator_set_name) > 64)
11870     {
11871       errmsg ("locator-set name too long\n");
11872       vec_free (locator_set_name);
11873       return -99;
11874     }
11875   vec_add1 (locator_set_name, 0);
11876
11877   /* Construct the API message */
11878   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11879
11880   mp->is_add = is_add;
11881   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11882   mp->eid_type = eid->type;
11883   mp->prefix_len = eid->len;
11884   mp->vni = clib_host_to_net_u32 (vni);
11885   clib_memcpy (mp->locator_set_name, locator_set_name,
11886                vec_len (locator_set_name));
11887
11888   vec_free (locator_set_name);
11889
11890   /* send it... */
11891   S;
11892
11893   /* Wait for a reply... */
11894   W;
11895
11896   /* NOTREACHED */
11897   return 0;
11898 }
11899
11900 /* *INDENT-OFF* */
11901 /** Used for transferring locators via VPP API */
11902 typedef CLIB_PACKED(struct
11903 {
11904   u8 is_ip4; /**< is locator an IPv4 address? */
11905   u8 priority; /**< locator priority */
11906   u8 weight;   /**< locator weight */
11907   u8 addr[16]; /**< IPv4/IPv6 address */
11908 }) rloc_t;
11909 /* *INDENT-ON* */
11910
11911 static int
11912 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11913 {
11914   unformat_input_t *input = vam->input;
11915   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11916   f64 timeout = ~0;
11917   u8 is_add = 1;
11918   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11919   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11920   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11921   u32 action = ~0, p, w;
11922   ip4_address_t rmt_rloc4, lcl_rloc4;
11923   ip6_address_t rmt_rloc6, lcl_rloc6;
11924   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11925
11926   memset (&rloc, 0, sizeof (rloc));
11927
11928   /* Parse args required to build the message */
11929   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11930     {
11931       if (unformat (input, "del"))
11932         {
11933           is_add = 0;
11934         }
11935       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11936         {
11937           rmt_eid_set = 1;
11938         }
11939       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11940         {
11941           lcl_eid_set = 1;
11942         }
11943       else if (unformat (input, "p %d w %d", &p, &w))
11944         {
11945           if (!curr_rloc)
11946             {
11947               errmsg ("No RLOC configured for setting priority/weight!");
11948               return -99;
11949             }
11950           curr_rloc->priority = p;
11951           curr_rloc->weight = w;
11952         }
11953       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11954                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11955         {
11956           rloc.is_ip4 = 1;
11957
11958           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11959           rloc.priority = rloc.weight = 0;
11960           vec_add1 (lcl_locs, rloc);
11961
11962           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11963           vec_add1 (rmt_locs, rloc);
11964           /* priority and weight saved in rmt loc */
11965           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11966         }
11967       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11968                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11969         {
11970           rloc.is_ip4 = 0;
11971           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11972           rloc.priority = rloc.weight = 0;
11973           vec_add1 (lcl_locs, rloc);
11974
11975           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
11976           vec_add1 (rmt_locs, rloc);
11977           /* priority and weight saved in rmt loc */
11978           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11979         }
11980       else if (unformat (input, "action %d", &action))
11981         {
11982           ;
11983         }
11984       else
11985         {
11986           clib_warning ("parse error '%U'", format_unformat_error, input);
11987           return -99;
11988         }
11989     }
11990
11991   if (!rmt_eid_set)
11992     {
11993       errmsg ("remote eid addresses not set\n");
11994       return -99;
11995     }
11996
11997   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
11998     {
11999       errmsg ("eid types don't match\n");
12000       return -99;
12001     }
12002
12003   if (0 == rmt_locs && (u32) ~ 0 == action)
12004     {
12005       errmsg ("action not set for negative mapping\n");
12006       return -99;
12007     }
12008
12009   /* Construct the API message */
12010   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12011
12012   mp->is_add = is_add;
12013   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12014   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12015   mp->eid_type = rmt_eid->type;
12016   mp->rmt_len = rmt_eid->len;
12017   mp->lcl_len = lcl_eid->len;
12018   mp->action = action;
12019
12020   if (0 != rmt_locs && 0 != lcl_locs)
12021     {
12022       mp->loc_num = vec_len (rmt_locs);
12023       clib_memcpy (mp->lcl_locs, lcl_locs,
12024                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12025       clib_memcpy (mp->rmt_locs, rmt_locs,
12026                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12027     }
12028   vec_free (lcl_locs);
12029   vec_free (rmt_locs);
12030
12031   /* send it... */
12032   S;
12033
12034   /* Wait for a reply... */
12035   W;
12036
12037   /* NOTREACHED */
12038   return 0;
12039 }
12040
12041 static int
12042 api_lisp_add_del_map_resolver (vat_main_t * vam)
12043 {
12044   unformat_input_t *input = vam->input;
12045   vl_api_lisp_add_del_map_resolver_t *mp;
12046   f64 timeout = ~0;
12047   u8 is_add = 1;
12048   u8 ipv4_set = 0;
12049   u8 ipv6_set = 0;
12050   ip4_address_t ipv4;
12051   ip6_address_t ipv6;
12052
12053   /* Parse args required to build the message */
12054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12055     {
12056       if (unformat (input, "del"))
12057         {
12058           is_add = 0;
12059         }
12060       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12061         {
12062           ipv4_set = 1;
12063         }
12064       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12065         {
12066           ipv6_set = 1;
12067         }
12068       else
12069         break;
12070     }
12071
12072   if (ipv4_set && ipv6_set)
12073     {
12074       errmsg ("both eid v4 and v6 addresses set\n");
12075       return -99;
12076     }
12077
12078   if (!ipv4_set && !ipv6_set)
12079     {
12080       errmsg ("eid addresses not set\n");
12081       return -99;
12082     }
12083
12084   /* Construct the API message */
12085   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12086
12087   mp->is_add = is_add;
12088   if (ipv6_set)
12089     {
12090       mp->is_ipv6 = 1;
12091       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12092     }
12093   else
12094     {
12095       mp->is_ipv6 = 0;
12096       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12097     }
12098
12099   /* send it... */
12100   S;
12101
12102   /* Wait for a reply... */
12103   W;
12104
12105   /* NOTREACHED */
12106   return 0;
12107 }
12108
12109 static int
12110 api_lisp_gpe_enable_disable (vat_main_t * vam)
12111 {
12112   unformat_input_t *input = vam->input;
12113   vl_api_lisp_gpe_enable_disable_t *mp;
12114   f64 timeout = ~0;
12115   u8 is_set = 0;
12116   u8 is_en = 1;
12117
12118   /* Parse args required to build the message */
12119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12120     {
12121       if (unformat (input, "enable"))
12122         {
12123           is_set = 1;
12124           is_en = 1;
12125         }
12126       else if (unformat (input, "disable"))
12127         {
12128           is_set = 1;
12129           is_en = 0;
12130         }
12131       else
12132         break;
12133     }
12134
12135   if (is_set == 0)
12136     {
12137       errmsg ("Value not set\n");
12138       return -99;
12139     }
12140
12141   /* Construct the API message */
12142   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12143
12144   mp->is_en = is_en;
12145
12146   /* send it... */
12147   S;
12148
12149   /* Wait for a reply... */
12150   W;
12151
12152   /* NOTREACHED */
12153   return 0;
12154 }
12155
12156 static int
12157 api_lisp_enable_disable (vat_main_t * vam)
12158 {
12159   unformat_input_t *input = vam->input;
12160   vl_api_lisp_enable_disable_t *mp;
12161   f64 timeout = ~0;
12162   u8 is_set = 0;
12163   u8 is_en = 0;
12164
12165   /* Parse args required to build the message */
12166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12167     {
12168       if (unformat (input, "enable"))
12169         {
12170           is_set = 1;
12171           is_en = 1;
12172         }
12173       else if (unformat (input, "disable"))
12174         {
12175           is_set = 1;
12176         }
12177       else
12178         break;
12179     }
12180
12181   if (!is_set)
12182     {
12183       errmsg ("Value not set\n");
12184       return -99;
12185     }
12186
12187   /* Construct the API message */
12188   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12189
12190   mp->is_en = is_en;
12191
12192   /* send it... */
12193   S;
12194
12195   /* Wait for a reply... */
12196   W;
12197
12198   /* NOTREACHED */
12199   return 0;
12200 }
12201
12202 /**
12203  * Enable/disable LISP proxy ITR.
12204  *
12205  * @param vam vpp API test context
12206  * @return return code
12207  */
12208 static int
12209 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12210 {
12211   f64 timeout = ~0;
12212   u8 ls_name_set = 0;
12213   unformat_input_t *input = vam->input;
12214   vl_api_lisp_pitr_set_locator_set_t *mp;
12215   u8 is_add = 1;
12216   u8 *ls_name = 0;
12217
12218   /* Parse args required to build the message */
12219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12220     {
12221       if (unformat (input, "del"))
12222         is_add = 0;
12223       else if (unformat (input, "locator-set %s", &ls_name))
12224         ls_name_set = 1;
12225       else
12226         {
12227           errmsg ("parse error '%U'", format_unformat_error, input);
12228           return -99;
12229         }
12230     }
12231
12232   if (!ls_name_set)
12233     {
12234       errmsg ("locator-set name not set!");
12235       return -99;
12236     }
12237
12238   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12239
12240   mp->is_add = is_add;
12241   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12242   vec_free (ls_name);
12243
12244   /* send */
12245   S;
12246
12247   /* wait for reply */
12248   W;
12249
12250   /* notreached */
12251   return 0;
12252 }
12253
12254 static int
12255 api_show_lisp_pitr (vat_main_t * vam)
12256 {
12257   vl_api_show_lisp_pitr_t *mp;
12258   f64 timeout = ~0;
12259
12260   if (!vam->json_output)
12261     {
12262       fformat (vam->ofp, "%=20s\n", "lisp status:");
12263     }
12264
12265   M (SHOW_LISP_PITR, show_lisp_pitr);
12266   /* send it... */
12267   S;
12268
12269   /* Wait for a reply... */
12270   W;
12271
12272   /* NOTREACHED */
12273   return 0;
12274 }
12275
12276 /**
12277  * Add/delete mapping between vni and vrf
12278  */
12279 static int
12280 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12281 {
12282   f64 timeout = ~0;
12283   unformat_input_t *input = vam->input;
12284   vl_api_lisp_eid_table_add_del_map_t *mp;
12285   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12286   u32 vni, vrf, bd_index;
12287
12288   /* Parse args required to build the message */
12289   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12290     {
12291       if (unformat (input, "del"))
12292         is_add = 0;
12293       else if (unformat (input, "vrf %d", &vrf))
12294         vrf_set = 1;
12295       else if (unformat (input, "bd_index %d", &bd_index))
12296         bd_index_set = 1;
12297       else if (unformat (input, "vni %d", &vni))
12298         vni_set = 1;
12299       else
12300         break;
12301     }
12302
12303   if (!vni_set || (!vrf_set && !bd_index_set))
12304     {
12305       errmsg ("missing arguments!");
12306       return -99;
12307     }
12308
12309   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12310
12311   mp->is_add = is_add;
12312   mp->vni = htonl (vni);
12313   mp->dp_table = htonl (vrf);
12314   mp->is_l2 = bd_index_set;
12315
12316   /* send */
12317   S;
12318
12319   /* wait for reply */
12320   W;
12321
12322   /* notreached */
12323   return 0;
12324 }
12325
12326 /**
12327  * Add/del remote mapping to/from LISP control plane
12328  *
12329  * @param vam vpp API test context
12330  * @return return code
12331  */
12332 static int
12333 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12334 {
12335   unformat_input_t *input = vam->input;
12336   vl_api_lisp_add_del_remote_mapping_t *mp;
12337   f64 timeout = ~0;
12338   u32 vni = 0;
12339   //TODO: seid need remove
12340   lisp_eid_vat_t _eid, *eid = &_eid;
12341   lisp_eid_vat_t _seid, *seid = &_seid;
12342   u8 is_add = 1, del_all = 0, eid_set = 0;
12343   u32 action = ~0, p, w;
12344   ip4_address_t rloc4;
12345   ip6_address_t rloc6;
12346   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12347
12348   memset (&rloc, 0, sizeof (rloc));
12349
12350   /* Parse args required to build the message */
12351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12352     {
12353       if (unformat (input, "del-all"))
12354         {
12355           del_all = 1;
12356         }
12357       else if (unformat (input, "del"))
12358         {
12359           is_add = 0;
12360         }
12361       else if (unformat (input, "add"))
12362         {
12363           is_add = 1;
12364         }
12365       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12366         {
12367           eid_set = 1;
12368         }
12369       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12370         {
12371           //TODO: Need remove, but first must be remove from CSIT test
12372         }
12373       else if (unformat (input, "vni %d", &vni))
12374         {
12375           ;
12376         }
12377       else if (unformat (input, "p %d w %d", &p, &w))
12378         {
12379           if (!curr_rloc)
12380             {
12381               errmsg ("No RLOC configured for setting priority/weight!");
12382               return -99;
12383             }
12384           curr_rloc->priority = p;
12385           curr_rloc->weight = w;
12386         }
12387       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12388         {
12389           rloc.is_ip4 = 1;
12390           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12391           vec_add1 (rlocs, rloc);
12392           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12393         }
12394       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12395         {
12396           rloc.is_ip4 = 0;
12397           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12398           vec_add1 (rlocs, rloc);
12399           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12400         }
12401       else if (unformat (input, "action %d", &action))
12402         {
12403           ;
12404         }
12405       else
12406         {
12407           clib_warning ("parse error '%U'", format_unformat_error, input);
12408           return -99;
12409         }
12410     }
12411
12412   if (0 == eid_set)
12413     {
12414       errmsg ("missing params!");
12415       return -99;
12416     }
12417
12418   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12419     {
12420       errmsg ("no action set for negative map-reply!");
12421       return -99;
12422     }
12423
12424   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12425   mp->is_add = is_add;
12426   mp->vni = htonl (vni);
12427   mp->action = (u8) action;
12428   mp->eid_len = eid->len;
12429   mp->del_all = del_all;
12430   mp->eid_type = eid->type;
12431   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12432
12433   mp->rloc_num = vec_len (rlocs);
12434   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12435   vec_free (rlocs);
12436
12437   /* send it... */
12438   S;
12439
12440   /* Wait for a reply... */
12441   W;
12442
12443   /* NOTREACHED */
12444   return 0;
12445 }
12446
12447 /**
12448  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12449  * forwarding entries in data-plane accordingly.
12450  *
12451  * @param vam vpp API test context
12452  * @return return code
12453  */
12454 static int
12455 api_lisp_add_del_adjacency (vat_main_t * vam)
12456 {
12457   unformat_input_t *input = vam->input;
12458   vl_api_lisp_add_del_adjacency_t *mp;
12459   f64 timeout = ~0;
12460   u32 vni = 0;
12461   ip4_address_t seid4, deid4;
12462   ip6_address_t seid6, deid6;
12463   u8 deid_mac[6] = { 0 };
12464   u8 seid_mac[6] = { 0 };
12465   u8 deid_type, seid_type;
12466   u32 seid_len = 0, deid_len = 0, len;
12467   u8 is_add = 1;
12468
12469   seid_type = deid_type = (u8) ~ 0;
12470
12471   /* Parse args required to build the message */
12472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12473     {
12474       if (unformat (input, "del"))
12475         {
12476           is_add = 0;
12477         }
12478       else if (unformat (input, "add"))
12479         {
12480           is_add = 1;
12481         }
12482       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12483                          &deid4, &len))
12484         {
12485           deid_type = 0;        /* ipv4 */
12486           deid_len = len;
12487         }
12488       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12489                          &deid6, &len))
12490         {
12491           deid_type = 1;        /* ipv6 */
12492           deid_len = len;
12493         }
12494       else if (unformat (input, "deid %U", unformat_ethernet_address,
12495                          deid_mac))
12496         {
12497           deid_type = 2;        /* mac */
12498         }
12499       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12500                          &seid4, &len))
12501         {
12502           seid_type = 0;        /* ipv4 */
12503           seid_len = len;
12504         }
12505       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12506                          &seid6, &len))
12507         {
12508           seid_type = 1;        /* ipv6 */
12509           seid_len = len;
12510         }
12511       else if (unformat (input, "seid %U", unformat_ethernet_address,
12512                          seid_mac))
12513         {
12514           seid_type = 2;        /* mac */
12515         }
12516       else if (unformat (input, "vni %d", &vni))
12517         {
12518           ;
12519         }
12520       else
12521         {
12522           errmsg ("parse error '%U'", format_unformat_error, input);
12523           return -99;
12524         }
12525     }
12526
12527   if ((u8) ~ 0 == deid_type)
12528     {
12529       errmsg ("missing params!");
12530       return -99;
12531     }
12532
12533   if (seid_type != deid_type)
12534     {
12535       errmsg ("source and destination EIDs are of different types!");
12536       return -99;
12537     }
12538
12539   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12540   mp->is_add = is_add;
12541   mp->vni = htonl (vni);
12542   mp->seid_len = seid_len;
12543   mp->deid_len = deid_len;
12544   mp->eid_type = deid_type;
12545
12546   switch (mp->eid_type)
12547     {
12548     case 0:
12549       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12550       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12551       break;
12552     case 1:
12553       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12554       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12555       break;
12556     case 2:
12557       clib_memcpy (mp->seid, seid_mac, 6);
12558       clib_memcpy (mp->deid, deid_mac, 6);
12559       break;
12560     default:
12561       errmsg ("unknown EID type %d!", mp->eid_type);
12562       return 0;
12563     }
12564
12565   /* send it... */
12566   S;
12567
12568   /* Wait for a reply... */
12569   W;
12570
12571   /* NOTREACHED */
12572   return 0;
12573 }
12574
12575 static int
12576 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12577 {
12578   unformat_input_t *input = vam->input;
12579   vl_api_lisp_gpe_add_del_iface_t *mp;
12580   f64 timeout = ~0;
12581   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12582   u32 dp_table = 0, vni = 0;
12583
12584   /* Parse args required to build the message */
12585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12586     {
12587       if (unformat (input, "up"))
12588         {
12589           action_set = 1;
12590           is_add = 1;
12591         }
12592       else if (unformat (input, "down"))
12593         {
12594           action_set = 1;
12595           is_add = 0;
12596         }
12597       else if (unformat (input, "table_id %d", &dp_table))
12598         {
12599           dp_table_set = 1;
12600         }
12601       else if (unformat (input, "bd_id %d", &dp_table))
12602         {
12603           dp_table_set = 1;
12604           is_l2 = 1;
12605         }
12606       else if (unformat (input, "vni %d", &vni))
12607         {
12608           vni_set = 1;
12609         }
12610       else
12611         break;
12612     }
12613
12614   if (action_set == 0)
12615     {
12616       errmsg ("Action not set\n");
12617       return -99;
12618     }
12619   if (dp_table_set == 0 || vni_set == 0)
12620     {
12621       errmsg ("vni and dp_table must be set\n");
12622       return -99;
12623     }
12624
12625   /* Construct the API message */
12626   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12627
12628   mp->is_add = is_add;
12629   mp->dp_table = dp_table;
12630   mp->is_l2 = is_l2;
12631   mp->vni = vni;
12632
12633   /* send it... */
12634   S;
12635
12636   /* Wait for a reply... */
12637   W;
12638
12639   /* NOTREACHED */
12640   return 0;
12641 }
12642
12643 /**
12644  * Add/del map request itr rlocs from LISP control plane and updates
12645  *
12646  * @param vam vpp API test context
12647  * @return return code
12648  */
12649 static int
12650 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12651 {
12652   unformat_input_t *input = vam->input;
12653   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12654   f64 timeout = ~0;
12655   u8 *locator_set_name = 0;
12656   u8 locator_set_name_set = 0;
12657   u8 is_add = 1;
12658
12659   /* Parse args required to build the message */
12660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (input, "del"))
12663         {
12664           is_add = 0;
12665         }
12666       else if (unformat (input, "%_%v%_", &locator_set_name))
12667         {
12668           locator_set_name_set = 1;
12669         }
12670       else
12671         {
12672           clib_warning ("parse error '%U'", format_unformat_error, input);
12673           return -99;
12674         }
12675     }
12676
12677   if (is_add && !locator_set_name_set)
12678     {
12679       errmsg ("itr-rloc is not set!");
12680       return -99;
12681     }
12682
12683   if (is_add && vec_len (locator_set_name) > 64)
12684     {
12685       errmsg ("itr-rloc locator-set name too long\n");
12686       vec_free (locator_set_name);
12687       return -99;
12688     }
12689
12690   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12691   mp->is_add = is_add;
12692   if (is_add)
12693     {
12694       clib_memcpy (mp->locator_set_name, locator_set_name,
12695                    vec_len (locator_set_name));
12696     }
12697   else
12698     {
12699       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12700     }
12701   vec_free (locator_set_name);
12702
12703   /* send it... */
12704   S;
12705
12706   /* Wait for a reply... */
12707   W;
12708
12709   /* NOTREACHED */
12710   return 0;
12711 }
12712
12713 static int
12714 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12715                             u8 filter)
12716 {
12717   vl_api_lisp_locator_dump_t *mp;
12718   f64 timeout = ~0;
12719
12720   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12721
12722   mp->locator_set_index = htonl (locator_set_index);
12723   mp->filter = filter;
12724
12725   /* send it... */
12726   S;
12727
12728   /* Use a control ping for synchronization */
12729   {
12730     vl_api_noprint_control_ping_t *mp;
12731     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12732     S;
12733   }
12734   /* Wait for a reply... */
12735   W;
12736 }
12737
12738 static inline void
12739 clean_locator_set_message (vat_main_t * vam)
12740 {
12741   locator_set_msg_t *ls = 0;
12742
12743   vec_foreach (ls, vam->locator_set_msg)
12744   {
12745     vec_free (ls->locator_set_name);
12746   }
12747
12748   vec_free (vam->locator_set_msg);
12749 }
12750
12751 static int
12752 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12753 {
12754   locator_set_msg_t *ls;
12755   locator_msg_t *loc;
12756   u8 *tmp_str = 0;
12757   int i = 0, ret = 0;
12758
12759   vec_foreach (ls, vam->locator_set_msg)
12760   {
12761     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12762     if (ret)
12763       {
12764         vec_free (vam->locator_msg);
12765         clean_locator_set_message (vam);
12766         return ret;
12767       }
12768
12769     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12770                       ls->locator_set_index,
12771                       vec_len (vam->locator_msg) ? "" : "\n");
12772     i = 0;
12773     vec_foreach (loc, vam->locator_msg)
12774     {
12775       if (i)
12776         {
12777           tmp_str = format (tmp_str, "%=37s", " ");
12778         }
12779       if (loc->local)
12780         {
12781           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12782                             loc->sw_if_index, loc->priority, loc->weight);
12783         }
12784       else
12785         {
12786           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12787                             loc->is_ipv6 ? format_ip6_address :
12788                             format_ip4_address,
12789                             loc->ip_address, loc->priority, loc->weight);
12790         }
12791       i++;
12792     }
12793
12794     fformat (vam->ofp, "%s", tmp_str);
12795     vec_free (tmp_str);
12796     vec_free (vam->locator_msg);
12797   }
12798
12799   clean_locator_set_message (vam);
12800
12801   return ret;
12802 }
12803
12804 static int
12805 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12806 {
12807   locator_set_msg_t *ls;
12808   locator_msg_t *loc;
12809   vat_json_node_t *node = NULL;
12810   vat_json_node_t *locator_array;
12811   vat_json_node_t *locator;
12812   struct in6_addr ip6;
12813   struct in_addr ip4;
12814   int ret = 0;
12815
12816   if (!vec_len (vam->locator_set_msg))
12817     {
12818       /* just print [] */
12819       vat_json_init_array (&vam->json_tree);
12820       vat_json_print (vam->ofp, &vam->json_tree);
12821       vam->json_tree.type = VAT_JSON_NONE;
12822       return ret;
12823     }
12824
12825   if (VAT_JSON_ARRAY != vam->json_tree.type)
12826     {
12827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12828       vat_json_init_array (&vam->json_tree);
12829     }
12830
12831   vec_foreach (ls, vam->locator_set_msg)
12832   {
12833     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12834     if (ret)
12835       {
12836         vec_free (ls->locator_set_name);
12837         vec_free (vam->locator_msg);
12838         vec_free (vam->locator_set_msg);
12839         vat_json_free (&vam->json_tree);
12840         vam->json_tree.type = VAT_JSON_NONE;
12841         return ret;
12842       }
12843
12844     node = vat_json_array_add (&vam->json_tree);
12845     vat_json_init_object (node);
12846
12847     vat_json_object_add_uint (node, "locator-set-index",
12848                               ls->locator_set_index);
12849     vat_json_object_add_string_copy (node, "locator-set",
12850                                      ls->locator_set_name);
12851     locator_array = vat_json_object_add_list (node, "locator");
12852     vec_foreach (loc, vam->locator_msg)
12853     {
12854       locator = vat_json_array_add (locator_array);
12855       vat_json_init_object (locator);
12856       if (loc->local)
12857         {
12858           vat_json_object_add_uint (locator, "locator-index",
12859                                     loc->sw_if_index);
12860         }
12861       else
12862         {
12863           if (loc->is_ipv6)
12864             {
12865               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12866               vat_json_object_add_ip6 (locator, "locator", ip6);
12867             }
12868           else
12869             {
12870               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12871               vat_json_object_add_ip4 (locator, "locator", ip4);
12872             }
12873         }
12874       vat_json_object_add_uint (locator, "priority", loc->priority);
12875       vat_json_object_add_uint (locator, "weight", loc->weight);
12876     }
12877
12878     vec_free (ls->locator_set_name);
12879     vec_free (vam->locator_msg);
12880   }
12881
12882   vat_json_print (vam->ofp, &vam->json_tree);
12883   vat_json_free (&vam->json_tree);
12884   vam->json_tree.type = VAT_JSON_NONE;
12885
12886   vec_free (vam->locator_set_msg);
12887
12888   return ret;
12889 }
12890
12891 static int
12892 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12893                                 u32 * locator_set_index)
12894 {
12895   locator_set_msg_t *ls;
12896   int ret = 0;
12897
12898   *locator_set_index = ~0;
12899
12900   if (!vec_len (vam->locator_set_msg))
12901     {
12902       return ret;
12903     }
12904
12905   vec_foreach (ls, vam->locator_set_msg)
12906   {
12907     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12908       {
12909         *locator_set_index = ls->locator_set_index;
12910         vec_free (vam->locator_set_msg);
12911         return ret;
12912       }
12913   }
12914
12915   vec_free (vam->locator_set_msg);
12916
12917   return ret;
12918 }
12919
12920 static int
12921 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12922                        u32 * locator_set_index)
12923 {
12924   vl_api_lisp_locator_set_dump_t *mp;
12925   f64 timeout = ~0;
12926
12927   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12928   /* send it... */
12929   S;
12930
12931   /* Use a control ping for synchronization */
12932   {
12933     vl_api_noprint_control_ping_t *mp;
12934     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12935     S;
12936   }
12937
12938   vam->noprint_msg = 1;
12939   /* Wait for a reply... */
12940   /* *INDENT-OFF* */
12941   W_L
12942   ({
12943     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12944     vam->noprint_msg = 0;
12945   });
12946   /* *INDENT-ON* */
12947
12948   /* NOTREACHED */
12949   return 0;
12950 }
12951
12952 static inline int
12953 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12954                    u8 filter)
12955 {
12956   int ret = 0;
12957
12958   ASSERT (vam);
12959
12960   if (!vam->json_output)
12961     {
12962       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12963                "locator", "priority", "weight");
12964     }
12965
12966   if (locator_set)
12967     {
12968       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
12969     }
12970
12971   if (!ret && ~0 == locator_set_index)
12972     {
12973       return -99;
12974     }
12975
12976   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
12977
12978   return ret;
12979 }
12980
12981 static int
12982 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
12983 {
12984   vl_api_lisp_locator_set_dump_t *mp;
12985   f64 timeout = ~0;
12986
12987   if (!vam->json_output)
12988     {
12989       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
12990                "locator-set", "locator-set-index", "locator", "priority",
12991                "weight");
12992     }
12993
12994   vam->noprint_msg = 1;
12995
12996   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12997
12998   mp->filter = filter;
12999
13000   /* send it... */
13001   S;
13002
13003   /* Use a control ping for synchronization */
13004   {
13005     vl_api_noprint_control_ping_t *mp;
13006     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13007     S;
13008   }
13009
13010   /* Wait for a reply... */
13011   /* *INDENT-OFF* */
13012   W_L
13013   ({
13014     if (vam->noprint_msg)
13015       {
13016         if (!vam->json_output)
13017           {
13018             print_locator_in_locator_set(vam, filter);
13019           }
13020         else
13021           {
13022             json_locator_in_locator_set(vam, filter);
13023           }
13024       }
13025     vam->noprint_msg = 0;
13026   });
13027   /* *INDENT-ON* */
13028
13029   /* NOTREACHED */
13030   return 0;
13031 }
13032
13033 static int
13034 api_lisp_locator_set_dump (vat_main_t * vam)
13035 {
13036   unformat_input_t *input = vam->input;
13037   vam->noprint_msg = 0;
13038   u32 locator_set_index = ~0;
13039   u8 locator_set_index_set = 0;
13040   u8 *locator_set = 0;
13041   u8 locator_set_set = 0;
13042   u8 filter = 0;
13043   int ret = 0;
13044
13045   /* Parse args required to build the message */
13046   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13047     {
13048       if (unformat (input, "locator-set-index %u", &locator_set_index))
13049         {
13050           locator_set_index_set = 1;
13051         }
13052       else if (unformat (input, "locator-set %s", &locator_set))
13053         {
13054           locator_set_set = 1;
13055         }
13056       else if (unformat (input, "local"))
13057         {
13058           filter = 1;
13059         }
13060       else if (unformat (input, "remote"))
13061         {
13062           filter = 2;
13063         }
13064       else
13065         {
13066           break;
13067         }
13068     }
13069
13070   if (locator_set_index_set && locator_set_set)
13071     {
13072       errmsg ("use only input parameter!\n");
13073       return -99;
13074     }
13075
13076   if (locator_set_index_set || locator_set_set)
13077     {
13078       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13079     }
13080   else
13081     {
13082       ret = lisp_locator_set_dump (vam, filter);
13083     }
13084
13085   vec_free (locator_set);
13086
13087   return ret;
13088 }
13089
13090 static int
13091 api_lisp_eid_table_map_dump (vat_main_t * vam)
13092 {
13093   vl_api_lisp_eid_table_map_dump_t *mp;
13094   f64 timeout = ~0;
13095
13096   if (!vam->json_output)
13097     {
13098       fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
13099     }
13100
13101   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13102
13103   /* send it... */
13104   S;
13105
13106   /* Use a control ping for synchronization */
13107   {
13108     vl_api_control_ping_t *mp;
13109     M (CONTROL_PING, control_ping);
13110     S;
13111   }
13112   /* Wait for a reply... */
13113   W;
13114
13115   /* NOTREACHED */
13116   return 0;
13117 }
13118
13119 static int
13120 get_locator_set (vat_main_t * vam)
13121 {
13122   vl_api_lisp_locator_set_dump_t *mp;
13123   f64 timeout = ~0;
13124
13125   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13126   /* send it... */
13127   S;
13128
13129   /* Use a control ping for synchronization */
13130   {
13131     vl_api_noprint_control_ping_t *mp;
13132     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13133     S;
13134   }
13135
13136   /* Wait for a reply... */
13137   W;
13138
13139   /* NOTREACHED */
13140   return 0;
13141 }
13142
13143 static inline u8 *
13144 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13145                           int *ret)
13146 {
13147   u8 *(*format_eid) (u8 *, va_list *) = 0;
13148
13149   ASSERT (vam != NULL);
13150   ASSERT (eid_table != NULL);
13151
13152   if (ret)
13153     {
13154       *ret = 0;
13155     }
13156
13157   switch (eid_table->eid_type)
13158     {
13159     case 0:
13160     case 1:
13161       format_eid = (eid_table->eid_type ? format_ip6_address :
13162                     format_ip4_address);
13163       str = format (0, "[%d] %U/%d",
13164                     clib_net_to_host_u32 (eid_table->vni),
13165                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13166       break;
13167     case 2:
13168       str = format (0, "[%d] %U",
13169                     clib_net_to_host_u32 (eid_table->vni),
13170                     format_ethernet_address, eid_table->eid);
13171       break;
13172     default:
13173       errmsg ("unknown EID type %d!", eid_table->eid_type);
13174       if (ret)
13175         {
13176           *ret = -99;
13177         }
13178       return 0;
13179     }
13180
13181   return str;
13182 }
13183
13184 static inline u8 *
13185 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13186                                   eid_table_t * eid_table)
13187 {
13188   locator_set_msg_t *ls = 0;
13189
13190   ASSERT (vam != NULL);
13191   ASSERT (eid_table != NULL);
13192
13193   if (eid_table->is_local)
13194     {
13195       vec_foreach (ls, vam->locator_set_msg)
13196       {
13197         if (ls->locator_set_index == eid_table->locator_set_index)
13198           {
13199             str = format (0, "local(%s)", ls->locator_set_name);
13200             return str;
13201           }
13202       }
13203
13204       str = format (0, "local(N/A)");
13205     }
13206   else
13207     {
13208       str = format (0, "remote");
13209     }
13210
13211   return str;
13212 }
13213
13214 static inline u8 *
13215 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13216                               eid_table_t * eid_table)
13217 {
13218   locator_msg_t *loc = 0;
13219   int first_line = 1;
13220
13221   ASSERT (vam != NULL);
13222   ASSERT (eid_table != NULL);
13223
13224   vec_foreach (loc, vam->locator_msg)
13225   {
13226     if (!first_line)
13227       {
13228         if (loc->local)
13229           {
13230             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13231           }
13232         else
13233           {
13234             str = format (str, "%=55s%-U\n", " ",
13235                           loc->is_ipv6 ? format_ip6_address :
13236                           format_ip4_address, loc->ip_address);
13237           }
13238
13239         continue;
13240       }
13241
13242     if (loc->local)
13243       {
13244         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13245                       eid_table->ttl, eid_table->authoritative);
13246       }
13247     else
13248       {
13249         str = format (str, "%-30U%-20u%-u\n",
13250                       loc->is_ipv6 ? format_ip6_address :
13251                       format_ip4_address,
13252                       loc->ip_address, eid_table->ttl,
13253                       eid_table->authoritative);
13254       }
13255     first_line = 0;
13256   }
13257
13258   return str;
13259 }
13260
13261 static int
13262 print_lisp_eid_table_dump (vat_main_t * vam)
13263 {
13264   eid_table_t *eid_table = 0;
13265   u8 *tmp_str = 0, *tmp_str2 = 0;
13266   int ret = 0;
13267
13268   ASSERT (vam != NULL);
13269
13270   ret = get_locator_set (vam);
13271   if (ret)
13272     {
13273       vec_free (vam->eid_tables);
13274       return ret;
13275     }
13276
13277   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13278            "ttl", "authoritative");
13279
13280   vec_foreach (eid_table, vam->eid_tables)
13281   {
13282     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13283     if (ret)
13284       {
13285         vec_free (vam->locator_msg);
13286         clean_locator_set_message (vam);
13287         vec_free (vam->eid_tables);
13288         return ret;
13289       }
13290
13291     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13292     if (ret)
13293       {
13294         vec_free (vam->locator_msg);
13295         clean_locator_set_message (vam);
13296         vec_free (vam->eid_tables);
13297         return ret;
13298       }
13299
13300     tmp_str = format (0, "%-35s", tmp_str2);
13301     vec_free (tmp_str2);
13302
13303     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13304     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13305     vec_free (tmp_str2);
13306
13307     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13308     tmp_str = format (tmp_str, "%-s", tmp_str2);
13309     vec_free (tmp_str2);
13310
13311     fformat (vam->ofp, "%s", tmp_str);
13312     vec_free (tmp_str);
13313     vec_free (vam->locator_msg);
13314   }
13315
13316   clean_locator_set_message (vam);
13317   vec_free (vam->eid_tables);
13318
13319   return ret;
13320 }
13321
13322 static inline void
13323 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13324                                 eid_table_t * eid_table)
13325 {
13326   locator_set_msg_t *ls = 0;
13327   u8 *s = 0;
13328
13329   ASSERT (vam != NULL);
13330   ASSERT (node != NULL);
13331   ASSERT (eid_table != NULL);
13332
13333   if (eid_table->is_local)
13334     {
13335       vec_foreach (ls, vam->locator_set_msg)
13336       {
13337         if (ls->locator_set_index == eid_table->locator_set_index)
13338           {
13339             vat_json_object_add_string_copy (node, "locator-set",
13340                                              ls->locator_set_name);
13341             return;
13342           }
13343       }
13344
13345       s = format (0, "N/A");
13346       vec_add1 (s, 0);
13347       vat_json_object_add_string_copy (node, "locator-set", s);
13348       vec_free (s);
13349     }
13350   else
13351     {
13352       s = format (0, "remote");
13353       vec_add1 (s, 0);
13354       vat_json_object_add_string_copy (node, "locator-set", s);
13355       vec_free (s);
13356     }
13357 }
13358
13359 static inline int
13360 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13361                         eid_table_t * eid_table)
13362 {
13363   u8 *s = 0;
13364   struct in6_addr ip6;
13365   struct in_addr ip4;
13366
13367   ASSERT (vam != NULL);
13368   ASSERT (node != NULL);
13369   ASSERT (eid_table != NULL);
13370
13371   switch (eid_table->eid_type)
13372     {
13373     case 0:
13374       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13375       vat_json_object_add_ip4 (node, "eid", ip4);
13376       vat_json_object_add_uint (node, "eid-prefix-len",
13377                                 eid_table->eid_prefix_len);
13378       break;
13379     case 1:
13380       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13381       vat_json_object_add_ip6 (node, "eid", ip6);
13382       vat_json_object_add_uint (node, "eid-prefix-len",
13383                                 eid_table->eid_prefix_len);
13384       break;
13385     case 2:
13386       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13387       vec_add1 (s, 0);
13388       vat_json_object_add_string_copy (node, "eid", s);
13389       vec_free (s);
13390       break;
13391     default:
13392       errmsg ("unknown EID type %d!", eid_table->eid_type);
13393       return -99;
13394     }
13395
13396   return 0;
13397 }
13398
13399 static inline void
13400 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13401                             eid_table_t * eid_table)
13402 {
13403   locator_msg_t *loc = 0;
13404   vat_json_node_t *locator_array = 0;
13405   vat_json_node_t *locator = 0;
13406   struct in6_addr ip6;
13407   struct in_addr ip4;
13408
13409   ASSERT (vam != NULL);
13410   ASSERT (node != NULL);
13411   ASSERT (eid_table != NULL);
13412
13413   locator_array = vat_json_object_add_list (node, "locator");
13414   vec_foreach (loc, vam->locator_msg)
13415   {
13416     locator = vat_json_array_add (locator_array);
13417     vat_json_init_object (locator);
13418     if (loc->local)
13419       {
13420         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13421       }
13422     else
13423       {
13424         if (loc->is_ipv6)
13425           {
13426             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13427             vat_json_object_add_ip6 (locator, "locator", ip6);
13428           }
13429         else
13430           {
13431             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13432             vat_json_object_add_ip4 (locator, "locator", ip4);
13433           }
13434       }
13435   }
13436 }
13437
13438 static int
13439 json_lisp_eid_table_dump (vat_main_t * vam)
13440 {
13441   eid_table_t *eid_table;
13442   vat_json_node_t *node = 0;
13443   int ret = 0;
13444
13445   ASSERT (vam != NULL);
13446
13447   ret = get_locator_set (vam);
13448   if (ret)
13449     {
13450       vec_free (vam->eid_tables);
13451       return ret;
13452     }
13453
13454   if (!vec_len (vam->eid_tables))
13455     {
13456       /* just print [] */
13457       vat_json_init_array (&vam->json_tree);
13458       vat_json_print (vam->ofp, &vam->json_tree);
13459       vam->json_tree.type = VAT_JSON_NONE;
13460       return ret;
13461     }
13462
13463   if (VAT_JSON_ARRAY != vam->json_tree.type)
13464     {
13465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13466       vat_json_init_array (&vam->json_tree);
13467     }
13468
13469   vec_foreach (eid_table, vam->eid_tables)
13470   {
13471     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13472     if (ret)
13473       {
13474         vec_free (vam->locator_msg);
13475         vec_free (vam->eid_tables);
13476         clean_locator_set_message (vam);
13477         vat_json_free (&vam->json_tree);
13478         vam->json_tree.type = VAT_JSON_NONE;
13479         return ret;
13480       }
13481
13482     node = vat_json_array_add (&vam->json_tree);
13483     vat_json_init_object (node);
13484
13485     vat_json_object_add_uint (node, "vni", eid_table->vni);
13486
13487     json_locator_set_for_eid_table (vam, node, eid_table);
13488     ret = json_eid_for_eid_table (vam, node, eid_table);
13489     if (ret)
13490       {
13491         vec_free (vam->locator_msg);
13492         vec_free (vam->eid_tables);
13493         clean_locator_set_message (vam);
13494         vat_json_free (&vam->json_tree);
13495         vam->json_tree.type = VAT_JSON_NONE;
13496         return ret;
13497       }
13498
13499     json_locator_for_eid_table (vam, node, eid_table);
13500
13501     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13502     vat_json_object_add_uint (node, "authoritative",
13503                               eid_table->authoritative);
13504
13505     vec_free (vam->locator_msg);
13506   }
13507
13508   vat_json_print (vam->ofp, &vam->json_tree);
13509   vat_json_free (&vam->json_tree);
13510   vam->json_tree.type = VAT_JSON_NONE;
13511
13512   clean_locator_set_message (vam);
13513   vec_free (vam->eid_tables);
13514
13515   return ret;
13516 }
13517
13518 static int
13519 api_lisp_eid_table_dump (vat_main_t * vam)
13520 {
13521   unformat_input_t *i = vam->input;
13522   vl_api_lisp_eid_table_dump_t *mp;
13523   f64 timeout = ~0;
13524   struct in_addr ip4;
13525   struct in6_addr ip6;
13526   u8 mac[6];
13527   u8 eid_type = ~0, eid_set = 0;
13528   u32 prefix_length = ~0, t, vni = 0;
13529   u8 filter = 0;
13530
13531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13532     {
13533       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13534         {
13535           eid_set = 1;
13536           eid_type = 0;
13537           prefix_length = t;
13538         }
13539       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13540         {
13541           eid_set = 1;
13542           eid_type = 1;
13543           prefix_length = t;
13544         }
13545       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13546         {
13547           eid_set = 1;
13548           eid_type = 2;
13549         }
13550       else if (unformat (i, "vni %d", &t))
13551         {
13552           vni = t;
13553         }
13554       else if (unformat (i, "local"))
13555         {
13556           filter = 1;
13557         }
13558       else if (unformat (i, "remote"))
13559         {
13560           filter = 2;
13561         }
13562       else
13563         {
13564           errmsg ("parse error '%U'", format_unformat_error, i);
13565           return -99;
13566         }
13567     }
13568
13569   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13570
13571   mp->filter = filter;
13572   if (eid_set)
13573     {
13574       mp->eid_set = 1;
13575       mp->vni = htonl (vni);
13576       mp->eid_type = eid_type;
13577       switch (eid_type)
13578         {
13579         case 0:
13580           mp->prefix_length = prefix_length;
13581           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13582           break;
13583         case 1:
13584           mp->prefix_length = prefix_length;
13585           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13586           break;
13587         case 2:
13588           clib_memcpy (mp->eid, mac, sizeof (mac));
13589           break;
13590         default:
13591           errmsg ("unknown EID type %d!", eid_type);
13592           return -99;
13593         }
13594     }
13595
13596   vam->noprint_msg = 1;
13597
13598   /* send it... */
13599   S;
13600
13601   /* Use a control ping for synchronization */
13602   {
13603     vl_api_noprint_control_ping_t *mp;
13604     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13605     S;
13606   }
13607
13608   /* Wait for a reply... */
13609   /* *INDENT-OFF* */
13610   W_L
13611   ({
13612     if (vam->noprint_msg)
13613       {
13614         if (!vam->json_output)
13615           {
13616             vam->retval = print_lisp_eid_table_dump(vam);
13617           }
13618         else
13619           {
13620             vam->retval = json_lisp_eid_table_dump(vam);
13621           }
13622       }
13623     vam->noprint_msg = 0;
13624   });
13625   /* *INDENT-ON* */
13626
13627   /* NOTREACHED */
13628   return 0;
13629 }
13630
13631 static int
13632 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13633 {
13634   vl_api_lisp_gpe_tunnel_dump_t *mp;
13635   f64 timeout = ~0;
13636
13637   if (!vam->json_output)
13638     {
13639       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13640                "%=16s%=16s%=16s%=16s%=16s\n",
13641                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13642                "Decap next", "Lisp version", "Flags", "Next protocol",
13643                "ver_res", "res", "iid");
13644     }
13645
13646   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13647   /* send it... */
13648   S;
13649
13650   /* Use a control ping for synchronization */
13651   {
13652     vl_api_control_ping_t *mp;
13653     M (CONTROL_PING, control_ping);
13654     S;
13655   }
13656   /* Wait for a reply... */
13657   W;
13658
13659   /* NOTREACHED */
13660   return 0;
13661 }
13662
13663 static int
13664 api_lisp_map_resolver_dump (vat_main_t * vam)
13665 {
13666   vl_api_lisp_map_resolver_dump_t *mp;
13667   f64 timeout = ~0;
13668
13669   if (!vam->json_output)
13670     {
13671       fformat (vam->ofp, "%=20s\n", "Map resolver");
13672     }
13673
13674   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13675   /* send it... */
13676   S;
13677
13678   /* Use a control ping for synchronization */
13679   {
13680     vl_api_control_ping_t *mp;
13681     M (CONTROL_PING, control_ping);
13682     S;
13683   }
13684   /* Wait for a reply... */
13685   W;
13686
13687   /* NOTREACHED */
13688   return 0;
13689 }
13690
13691 static int
13692 api_show_lisp_status (vat_main_t * vam)
13693 {
13694   vl_api_show_lisp_status_t *mp;
13695   f64 timeout = ~0;
13696
13697   if (!vam->json_output)
13698     {
13699       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13700     }
13701
13702   M (SHOW_LISP_STATUS, show_lisp_status);
13703   /* send it... */
13704   S;
13705   /* Wait for a reply... */
13706   W;
13707
13708   /* NOTREACHED */
13709   return 0;
13710 }
13711
13712 static int
13713 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13714 {
13715   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13716   f64 timeout = ~0;
13717
13718   if (!vam->json_output)
13719     {
13720       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13721     }
13722
13723   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13724   /* send it... */
13725   S;
13726   /* Wait for a reply... */
13727   W;
13728
13729   /* NOTREACHED */
13730   return 0;
13731 }
13732
13733 static int
13734 api_af_packet_create (vat_main_t * vam)
13735 {
13736   unformat_input_t *i = vam->input;
13737   vl_api_af_packet_create_t *mp;
13738   f64 timeout;
13739   u8 *host_if_name = 0;
13740   u8 hw_addr[6];
13741   u8 random_hw_addr = 1;
13742
13743   memset (hw_addr, 0, sizeof (hw_addr));
13744
13745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13746     {
13747       if (unformat (i, "name %s", &host_if_name))
13748         vec_add1 (host_if_name, 0);
13749       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13750         random_hw_addr = 0;
13751       else
13752         break;
13753     }
13754
13755   if (!vec_len (host_if_name))
13756     {
13757       errmsg ("host-interface name must be specified");
13758       return -99;
13759     }
13760
13761   if (vec_len (host_if_name) > 64)
13762     {
13763       errmsg ("host-interface name too long");
13764       return -99;
13765     }
13766
13767   M (AF_PACKET_CREATE, af_packet_create);
13768
13769   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13770   clib_memcpy (mp->hw_addr, hw_addr, 6);
13771   mp->use_random_hw_addr = random_hw_addr;
13772   vec_free (host_if_name);
13773
13774   S;
13775   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13776   /* NOTREACHED */
13777   return 0;
13778 }
13779
13780 static int
13781 api_af_packet_delete (vat_main_t * vam)
13782 {
13783   unformat_input_t *i = vam->input;
13784   vl_api_af_packet_delete_t *mp;
13785   f64 timeout;
13786   u8 *host_if_name = 0;
13787
13788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13789     {
13790       if (unformat (i, "name %s", &host_if_name))
13791         vec_add1 (host_if_name, 0);
13792       else
13793         break;
13794     }
13795
13796   if (!vec_len (host_if_name))
13797     {
13798       errmsg ("host-interface name must be specified");
13799       return -99;
13800     }
13801
13802   if (vec_len (host_if_name) > 64)
13803     {
13804       errmsg ("host-interface name too long");
13805       return -99;
13806     }
13807
13808   M (AF_PACKET_DELETE, af_packet_delete);
13809
13810   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13811   vec_free (host_if_name);
13812
13813   S;
13814   W;
13815   /* NOTREACHED */
13816   return 0;
13817 }
13818
13819 static int
13820 api_policer_add_del (vat_main_t * vam)
13821 {
13822   unformat_input_t *i = vam->input;
13823   vl_api_policer_add_del_t *mp;
13824   f64 timeout;
13825   u8 is_add = 1;
13826   u8 *name = 0;
13827   u32 cir = 0;
13828   u32 eir = 0;
13829   u64 cb = 0;
13830   u64 eb = 0;
13831   u8 rate_type = 0;
13832   u8 round_type = 0;
13833   u8 type = 0;
13834   u8 color_aware = 0;
13835   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13836
13837   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13838   conform_action.dscp = 0;
13839   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13840   exceed_action.dscp = 0;
13841   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13842   violate_action.dscp = 0;
13843
13844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (i, "del"))
13847         is_add = 0;
13848       else if (unformat (i, "name %s", &name))
13849         vec_add1 (name, 0);
13850       else if (unformat (i, "cir %u", &cir))
13851         ;
13852       else if (unformat (i, "eir %u", &eir))
13853         ;
13854       else if (unformat (i, "cb %u", &cb))
13855         ;
13856       else if (unformat (i, "eb %u", &eb))
13857         ;
13858       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13859                          &rate_type))
13860         ;
13861       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13862                          &round_type))
13863         ;
13864       else if (unformat (i, "type %U", unformat_policer_type, &type))
13865         ;
13866       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13867                          &conform_action))
13868         ;
13869       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13870                          &exceed_action))
13871         ;
13872       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13873                          &violate_action))
13874         ;
13875       else if (unformat (i, "color-aware"))
13876         color_aware = 1;
13877       else
13878         break;
13879     }
13880
13881   if (!vec_len (name))
13882     {
13883       errmsg ("policer name must be specified");
13884       return -99;
13885     }
13886
13887   if (vec_len (name) > 64)
13888     {
13889       errmsg ("policer name too long");
13890       return -99;
13891     }
13892
13893   M (POLICER_ADD_DEL, policer_add_del);
13894
13895   clib_memcpy (mp->name, name, vec_len (name));
13896   vec_free (name);
13897   mp->is_add = is_add;
13898   mp->cir = cir;
13899   mp->eir = eir;
13900   mp->cb = cb;
13901   mp->eb = eb;
13902   mp->rate_type = rate_type;
13903   mp->round_type = round_type;
13904   mp->type = type;
13905   mp->conform_action_type = conform_action.action_type;
13906   mp->conform_dscp = conform_action.dscp;
13907   mp->exceed_action_type = exceed_action.action_type;
13908   mp->exceed_dscp = exceed_action.dscp;
13909   mp->violate_action_type = violate_action.action_type;
13910   mp->violate_dscp = violate_action.dscp;
13911   mp->color_aware = color_aware;
13912
13913   S;
13914   W;
13915   /* NOTREACHED */
13916   return 0;
13917 }
13918
13919 static int
13920 api_policer_dump (vat_main_t * vam)
13921 {
13922   unformat_input_t *i = vam->input;
13923   vl_api_policer_dump_t *mp;
13924   f64 timeout = ~0;
13925   u8 *match_name = 0;
13926   u8 match_name_valid = 0;
13927
13928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (i, "name %s", &match_name))
13931         {
13932           vec_add1 (match_name, 0);
13933           match_name_valid = 1;
13934         }
13935       else
13936         break;
13937     }
13938
13939   M (POLICER_DUMP, policer_dump);
13940   mp->match_name_valid = match_name_valid;
13941   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13942   vec_free (match_name);
13943   /* send it... */
13944   S;
13945
13946   /* Use a control ping for synchronization */
13947   {
13948     vl_api_control_ping_t *mp;
13949     M (CONTROL_PING, control_ping);
13950     S;
13951   }
13952   /* Wait for a reply... */
13953   W;
13954
13955   /* NOTREACHED */
13956   return 0;
13957 }
13958
13959 static int
13960 api_policer_classify_set_interface (vat_main_t * vam)
13961 {
13962   unformat_input_t *i = vam->input;
13963   vl_api_policer_classify_set_interface_t *mp;
13964   f64 timeout;
13965   u32 sw_if_index;
13966   int sw_if_index_set;
13967   u32 ip4_table_index = ~0;
13968   u32 ip6_table_index = ~0;
13969   u32 l2_table_index = ~0;
13970   u8 is_add = 1;
13971
13972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13973     {
13974       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13975         sw_if_index_set = 1;
13976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13977         sw_if_index_set = 1;
13978       else if (unformat (i, "del"))
13979         is_add = 0;
13980       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13981         ;
13982       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13983         ;
13984       else if (unformat (i, "l2-table %d", &l2_table_index))
13985         ;
13986       else
13987         {
13988           clib_warning ("parse error '%U'", format_unformat_error, i);
13989           return -99;
13990         }
13991     }
13992
13993   if (sw_if_index_set == 0)
13994     {
13995       errmsg ("missing interface name or sw_if_index\n");
13996       return -99;
13997     }
13998
13999   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14000
14001   mp->sw_if_index = ntohl (sw_if_index);
14002   mp->ip4_table_index = ntohl (ip4_table_index);
14003   mp->ip6_table_index = ntohl (ip6_table_index);
14004   mp->l2_table_index = ntohl (l2_table_index);
14005   mp->is_add = is_add;
14006
14007   S;
14008   W;
14009   /* NOTREACHED */
14010   return 0;
14011 }
14012
14013 static int
14014 api_policer_classify_dump (vat_main_t * vam)
14015 {
14016   unformat_input_t *i = vam->input;
14017   vl_api_policer_classify_dump_t *mp;
14018   f64 timeout = ~0;
14019   u8 type = POLICER_CLASSIFY_N_TABLES;
14020
14021   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14022     ;
14023   else
14024     {
14025       errmsg ("classify table type must be specified\n");
14026       return -99;
14027     }
14028
14029   if (!vam->json_output)
14030     {
14031       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14032     }
14033
14034   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14035   mp->type = type;
14036   /* send it... */
14037   S;
14038
14039   /* Use a control ping for synchronization */
14040   {
14041     vl_api_control_ping_t *mp;
14042     M (CONTROL_PING, control_ping);
14043     S;
14044   }
14045   /* Wait for a reply... */
14046   W;
14047
14048   /* NOTREACHED */
14049   return 0;
14050 }
14051
14052 static int
14053 api_netmap_create (vat_main_t * vam)
14054 {
14055   unformat_input_t *i = vam->input;
14056   vl_api_netmap_create_t *mp;
14057   f64 timeout;
14058   u8 *if_name = 0;
14059   u8 hw_addr[6];
14060   u8 random_hw_addr = 1;
14061   u8 is_pipe = 0;
14062   u8 is_master = 0;
14063
14064   memset (hw_addr, 0, sizeof (hw_addr));
14065
14066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14067     {
14068       if (unformat (i, "name %s", &if_name))
14069         vec_add1 (if_name, 0);
14070       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14071         random_hw_addr = 0;
14072       else if (unformat (i, "pipe"))
14073         is_pipe = 1;
14074       else if (unformat (i, "master"))
14075         is_master = 1;
14076       else if (unformat (i, "slave"))
14077         is_master = 0;
14078       else
14079         break;
14080     }
14081
14082   if (!vec_len (if_name))
14083     {
14084       errmsg ("interface name must be specified");
14085       return -99;
14086     }
14087
14088   if (vec_len (if_name) > 64)
14089     {
14090       errmsg ("interface name too long");
14091       return -99;
14092     }
14093
14094   M (NETMAP_CREATE, netmap_create);
14095
14096   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14097   clib_memcpy (mp->hw_addr, hw_addr, 6);
14098   mp->use_random_hw_addr = random_hw_addr;
14099   mp->is_pipe = is_pipe;
14100   mp->is_master = is_master;
14101   vec_free (if_name);
14102
14103   S;
14104   W;
14105   /* NOTREACHED */
14106   return 0;
14107 }
14108
14109 static int
14110 api_netmap_delete (vat_main_t * vam)
14111 {
14112   unformat_input_t *i = vam->input;
14113   vl_api_netmap_delete_t *mp;
14114   f64 timeout;
14115   u8 *if_name = 0;
14116
14117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14118     {
14119       if (unformat (i, "name %s", &if_name))
14120         vec_add1 (if_name, 0);
14121       else
14122         break;
14123     }
14124
14125   if (!vec_len (if_name))
14126     {
14127       errmsg ("interface name must be specified");
14128       return -99;
14129     }
14130
14131   if (vec_len (if_name) > 64)
14132     {
14133       errmsg ("interface name too long");
14134       return -99;
14135     }
14136
14137   M (NETMAP_DELETE, netmap_delete);
14138
14139   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14140   vec_free (if_name);
14141
14142   S;
14143   W;
14144   /* NOTREACHED */
14145   return 0;
14146 }
14147
14148 static void vl_api_mpls_gre_tunnel_details_t_handler
14149   (vl_api_mpls_gre_tunnel_details_t * mp)
14150 {
14151   vat_main_t *vam = &vat_main;
14152   i32 i;
14153   i32 len = ntohl (mp->nlabels);
14154
14155   if (mp->l2_only == 0)
14156     {
14157       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14158                ntohl (mp->tunnel_index),
14159                format_ip4_address, &mp->tunnel_src,
14160                format_ip4_address, &mp->tunnel_dst,
14161                format_ip4_address, &mp->intfc_address,
14162                ntohl (mp->mask_width));
14163       for (i = 0; i < len; i++)
14164         {
14165           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14166         }
14167       fformat (vam->ofp, "\n");
14168       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14169                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14170     }
14171   else
14172     {
14173       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14174                ntohl (mp->tunnel_index),
14175                format_ip4_address, &mp->tunnel_src,
14176                format_ip4_address, &mp->tunnel_dst,
14177                format_ip4_address, &mp->intfc_address);
14178       for (i = 0; i < len; i++)
14179         {
14180           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14181         }
14182       fformat (vam->ofp, "\n");
14183       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14184                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14185     }
14186 }
14187
14188 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14189   (vl_api_mpls_gre_tunnel_details_t * mp)
14190 {
14191   vat_main_t *vam = &vat_main;
14192   vat_json_node_t *node = NULL;
14193   struct in_addr ip4;
14194   i32 i;
14195   i32 len = ntohl (mp->nlabels);
14196
14197   if (VAT_JSON_ARRAY != vam->json_tree.type)
14198     {
14199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14200       vat_json_init_array (&vam->json_tree);
14201     }
14202   node = vat_json_array_add (&vam->json_tree);
14203
14204   vat_json_init_object (node);
14205   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14206   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14207   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14208   vat_json_object_add_uint (node, "inner_fib_index",
14209                             ntohl (mp->inner_fib_index));
14210   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14211   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14212   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14213   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14214   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14215   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14216   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14217   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14218   vat_json_object_add_uint (node, "outer_fib_index",
14219                             ntohl (mp->outer_fib_index));
14220   vat_json_object_add_uint (node, "label_count", len);
14221   for (i = 0; i < len; i++)
14222     {
14223       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14224     }
14225 }
14226
14227 static int
14228 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14229 {
14230   vl_api_mpls_gre_tunnel_dump_t *mp;
14231   f64 timeout;
14232   i32 index = -1;
14233
14234   /* Parse args required to build the message */
14235   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14236     {
14237       if (!unformat (vam->input, "tunnel_index %d", &index))
14238         {
14239           index = -1;
14240           break;
14241         }
14242     }
14243
14244   fformat (vam->ofp, "  tunnel_index %d\n", index);
14245
14246   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14247   mp->tunnel_index = htonl (index);
14248   S;
14249
14250   /* Use a control ping for synchronization */
14251   {
14252     vl_api_control_ping_t *mp;
14253     M (CONTROL_PING, control_ping);
14254     S;
14255   }
14256   W;
14257 }
14258
14259 static void vl_api_mpls_eth_tunnel_details_t_handler
14260   (vl_api_mpls_eth_tunnel_details_t * mp)
14261 {
14262   vat_main_t *vam = &vat_main;
14263   i32 i;
14264   i32 len = ntohl (mp->nlabels);
14265
14266   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14267            ntohl (mp->tunnel_index),
14268            format_ethernet_address, &mp->tunnel_dst_mac,
14269            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14270   for (i = 0; i < len; i++)
14271     {
14272       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14273     }
14274   fformat (vam->ofp, "\n");
14275   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14276            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14277 }
14278
14279 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14280   (vl_api_mpls_eth_tunnel_details_t * mp)
14281 {
14282   vat_main_t *vam = &vat_main;
14283   vat_json_node_t *node = NULL;
14284   struct in_addr ip4;
14285   i32 i;
14286   i32 len = ntohl (mp->nlabels);
14287
14288   if (VAT_JSON_ARRAY != vam->json_tree.type)
14289     {
14290       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14291       vat_json_init_array (&vam->json_tree);
14292     }
14293   node = vat_json_array_add (&vam->json_tree);
14294
14295   vat_json_init_object (node);
14296   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14297   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14298   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14299   vat_json_object_add_uint (node, "inner_fib_index",
14300                             ntohl (mp->inner_fib_index));
14301   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14302   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14303   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14304   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14305   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14306                                    format (0, "%U", format_ethernet_address,
14307                                            &mp->tunnel_dst_mac));
14308   vat_json_object_add_uint (node, "tx_sw_if_index",
14309                             ntohl (mp->tx_sw_if_index));
14310   vat_json_object_add_uint (node, "label_count", len);
14311   for (i = 0; i < len; i++)
14312     {
14313       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14314     }
14315 }
14316
14317 static int
14318 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14319 {
14320   vl_api_mpls_eth_tunnel_dump_t *mp;
14321   f64 timeout;
14322   i32 index = -1;
14323
14324   /* Parse args required to build the message */
14325   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14326     {
14327       if (!unformat (vam->input, "tunnel_index %d", &index))
14328         {
14329           index = -1;
14330           break;
14331         }
14332     }
14333
14334   fformat (vam->ofp, "  tunnel_index %d\n", index);
14335
14336   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14337   mp->tunnel_index = htonl (index);
14338   S;
14339
14340   /* Use a control ping for synchronization */
14341   {
14342     vl_api_control_ping_t *mp;
14343     M (CONTROL_PING, control_ping);
14344     S;
14345   }
14346   W;
14347 }
14348
14349 static void vl_api_mpls_fib_encap_details_t_handler
14350   (vl_api_mpls_fib_encap_details_t * mp)
14351 {
14352   vat_main_t *vam = &vat_main;
14353   i32 i;
14354   i32 len = ntohl (mp->nlabels);
14355
14356   fformat (vam->ofp, "table %d, dest %U, label ",
14357            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14358   for (i = 0; i < len; i++)
14359     {
14360       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14361     }
14362   fformat (vam->ofp, "\n");
14363 }
14364
14365 static void vl_api_mpls_fib_encap_details_t_handler_json
14366   (vl_api_mpls_fib_encap_details_t * mp)
14367 {
14368   vat_main_t *vam = &vat_main;
14369   vat_json_node_t *node = NULL;
14370   i32 i;
14371   i32 len = ntohl (mp->nlabels);
14372   struct in_addr ip4;
14373
14374   if (VAT_JSON_ARRAY != vam->json_tree.type)
14375     {
14376       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14377       vat_json_init_array (&vam->json_tree);
14378     }
14379   node = vat_json_array_add (&vam->json_tree);
14380
14381   vat_json_init_object (node);
14382   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14383   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14384   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14385   vat_json_object_add_ip4 (node, "dest", ip4);
14386   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14387   vat_json_object_add_uint (node, "label_count", len);
14388   for (i = 0; i < len; i++)
14389     {
14390       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14391     }
14392 }
14393
14394 static int
14395 api_mpls_fib_encap_dump (vat_main_t * vam)
14396 {
14397   vl_api_mpls_fib_encap_dump_t *mp;
14398   f64 timeout;
14399
14400   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14401   S;
14402
14403   /* Use a control ping for synchronization */
14404   {
14405     vl_api_control_ping_t *mp;
14406     M (CONTROL_PING, control_ping);
14407     S;
14408   }
14409   W;
14410 }
14411
14412 static void vl_api_mpls_fib_decap_details_t_handler
14413   (vl_api_mpls_fib_decap_details_t * mp)
14414 {
14415   vat_main_t *vam = &vat_main;
14416
14417   fformat (vam->ofp,
14418            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14419            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14420            ntohl (mp->label), ntohl (mp->s_bit));
14421 }
14422
14423 static void vl_api_mpls_fib_decap_details_t_handler_json
14424   (vl_api_mpls_fib_decap_details_t * mp)
14425 {
14426   vat_main_t *vam = &vat_main;
14427   vat_json_node_t *node = NULL;
14428   struct in_addr ip4;
14429
14430   if (VAT_JSON_ARRAY != vam->json_tree.type)
14431     {
14432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14433       vat_json_init_array (&vam->json_tree);
14434     }
14435   node = vat_json_array_add (&vam->json_tree);
14436
14437   vat_json_init_object (node);
14438   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14439   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14440   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14441   vat_json_object_add_ip4 (node, "dest", ip4);
14442   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14443   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14444   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14445   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14446   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14447 }
14448
14449 static int
14450 api_mpls_fib_decap_dump (vat_main_t * vam)
14451 {
14452   vl_api_mpls_fib_decap_dump_t *mp;
14453   f64 timeout;
14454
14455   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14456   S;
14457
14458   /* Use a control ping for synchronization */
14459   {
14460     vl_api_control_ping_t *mp;
14461     M (CONTROL_PING, control_ping);
14462     S;
14463   }
14464   W;
14465 }
14466
14467 int
14468 api_classify_table_ids (vat_main_t * vam)
14469 {
14470   vl_api_classify_table_ids_t *mp;
14471   f64 timeout;
14472
14473   /* Construct the API message */
14474   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14475   mp->context = 0;
14476
14477   S;
14478   W;
14479   /* NOTREACHED */
14480   return 0;
14481 }
14482
14483 int
14484 api_classify_table_by_interface (vat_main_t * vam)
14485 {
14486   unformat_input_t *input = vam->input;
14487   vl_api_classify_table_by_interface_t *mp;
14488   f64 timeout;
14489
14490   u32 sw_if_index = ~0;
14491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14492     {
14493       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14494         ;
14495       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14496         ;
14497       else
14498         break;
14499     }
14500   if (sw_if_index == ~0)
14501     {
14502       errmsg ("missing interface name or sw_if_index\n");
14503       return -99;
14504     }
14505
14506   /* Construct the API message */
14507   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14508   mp->context = 0;
14509   mp->sw_if_index = ntohl (sw_if_index);
14510
14511   S;
14512   W;
14513   /* NOTREACHED */
14514   return 0;
14515 }
14516
14517 int
14518 api_classify_table_info (vat_main_t * vam)
14519 {
14520   unformat_input_t *input = vam->input;
14521   vl_api_classify_table_info_t *mp;
14522   f64 timeout;
14523
14524   u32 table_id = ~0;
14525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14526     {
14527       if (unformat (input, "table_id %d", &table_id))
14528         ;
14529       else
14530         break;
14531     }
14532   if (table_id == ~0)
14533     {
14534       errmsg ("missing table id\n");
14535       return -99;
14536     }
14537
14538   /* Construct the API message */
14539   M (CLASSIFY_TABLE_INFO, classify_table_info);
14540   mp->context = 0;
14541   mp->table_id = ntohl (table_id);
14542
14543   S;
14544   W;
14545   /* NOTREACHED */
14546   return 0;
14547 }
14548
14549 int
14550 api_classify_session_dump (vat_main_t * vam)
14551 {
14552   unformat_input_t *input = vam->input;
14553   vl_api_classify_session_dump_t *mp;
14554   f64 timeout;
14555
14556   u32 table_id = ~0;
14557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14558     {
14559       if (unformat (input, "table_id %d", &table_id))
14560         ;
14561       else
14562         break;
14563     }
14564   if (table_id == ~0)
14565     {
14566       errmsg ("missing table id\n");
14567       return -99;
14568     }
14569
14570   /* Construct the API message */
14571   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14572   mp->context = 0;
14573   mp->table_id = ntohl (table_id);
14574   S;
14575
14576   /* Use a control ping for synchronization */
14577   {
14578     vl_api_control_ping_t *mp;
14579     M (CONTROL_PING, control_ping);
14580     S;
14581   }
14582   W;
14583   /* NOTREACHED */
14584   return 0;
14585 }
14586
14587 static void
14588 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14589 {
14590   vat_main_t *vam = &vat_main;
14591
14592   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14593            "src_address %U, fib_index %u, path_mtu %u, "
14594            "template_interval %u\n",
14595            format_ip4_address, mp->collector_address,
14596            ntohs (mp->collector_port),
14597            format_ip4_address, mp->src_address,
14598            ntohl (mp->fib_index),
14599            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14600
14601   vam->retval = 0;
14602   vam->result_ready = 1;
14603 }
14604
14605 static void
14606 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14607 {
14608   vat_main_t *vam = &vat_main;
14609   vat_json_node_t node;
14610   struct in_addr collector_address;
14611   struct in_addr src_address;
14612
14613   vat_json_init_object (&node);
14614   clib_memcpy (&collector_address, &mp->collector_address,
14615                sizeof (collector_address));
14616   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14617   vat_json_object_add_uint (&node, "collector_port",
14618                             ntohs (mp->collector_port));
14619   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14620   vat_json_object_add_ip4 (&node, "src_address", src_address);
14621   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14622   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14623   vat_json_object_add_uint (&node, "template_interval",
14624                             ntohl (mp->template_interval));
14625
14626   vat_json_print (vam->ofp, &node);
14627   vat_json_free (&node);
14628   vam->retval = 0;
14629   vam->result_ready = 1;
14630 }
14631
14632 int
14633 api_ipfix_dump (vat_main_t * vam)
14634 {
14635   vl_api_ipfix_dump_t *mp;
14636   f64 timeout;
14637
14638   /* Construct the API message */
14639   M (IPFIX_DUMP, ipfix_dump);
14640   mp->context = 0;
14641
14642   S;
14643   W;
14644   /* NOTREACHED */
14645   return 0;
14646 }
14647
14648 int
14649 api_pg_create_interface (vat_main_t * vam)
14650 {
14651   unformat_input_t *input = vam->input;
14652   vl_api_pg_create_interface_t *mp;
14653   f64 timeout;
14654
14655   u32 if_id = ~0;
14656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (input, "if_id %d", &if_id))
14659         ;
14660       else
14661         break;
14662     }
14663   if (if_id == ~0)
14664     {
14665       errmsg ("missing pg interface index\n");
14666       return -99;
14667     }
14668
14669   /* Construct the API message */
14670   M (PG_CREATE_INTERFACE, pg_create_interface);
14671   mp->context = 0;
14672   mp->interface_id = ntohl (if_id);
14673
14674   S;
14675   W;
14676   /* NOTREACHED */
14677   return 0;
14678 }
14679
14680 int
14681 api_pg_capture (vat_main_t * vam)
14682 {
14683   unformat_input_t *input = vam->input;
14684   vl_api_pg_capture_t *mp;
14685   f64 timeout;
14686
14687   u32 if_id = ~0;
14688   u8 enable = 1;
14689   u32 count = 1;
14690   u8 pcap_file_set = 0;
14691   u8 *pcap_file = 0;
14692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14693     {
14694       if (unformat (input, "if_id %d", &if_id))
14695         ;
14696       else if (unformat (input, "pcap %s", &pcap_file))
14697         pcap_file_set = 1;
14698       else if (unformat (input, "count %d", &count))
14699         ;
14700       else if (unformat (input, "disable"))
14701         enable = 0;
14702       else
14703         break;
14704     }
14705   if (if_id == ~0)
14706     {
14707       errmsg ("missing pg interface index\n");
14708       return -99;
14709     }
14710   if (pcap_file_set > 0)
14711     {
14712       if (vec_len (pcap_file) > 255)
14713         {
14714           errmsg ("pcap file name is too long\n");
14715           return -99;
14716         }
14717     }
14718
14719   u32 name_len = vec_len (pcap_file);
14720   /* Construct the API message */
14721   M (PG_CAPTURE, pg_capture);
14722   mp->context = 0;
14723   mp->interface_id = ntohl (if_id);
14724   mp->is_enabled = enable;
14725   mp->count = ntohl (count);
14726   mp->pcap_name_length = ntohl (name_len);
14727   if (pcap_file_set != 0)
14728     {
14729       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14730     }
14731   vec_free (pcap_file);
14732
14733   S;
14734   W;
14735   /* NOTREACHED */
14736   return 0;
14737 }
14738
14739 int
14740 api_pg_enable_disable (vat_main_t * vam)
14741 {
14742   unformat_input_t *input = vam->input;
14743   vl_api_pg_enable_disable_t *mp;
14744   f64 timeout;
14745
14746   u8 enable = 1;
14747   u8 stream_name_set = 0;
14748   u8 *stream_name = 0;
14749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14750     {
14751       if (unformat (input, "stream %s", &stream_name))
14752         stream_name_set = 1;
14753       else if (unformat (input, "disable"))
14754         enable = 0;
14755       else
14756         break;
14757     }
14758
14759   if (stream_name_set > 0)
14760     {
14761       if (vec_len (stream_name) > 255)
14762         {
14763           errmsg ("stream name too long\n");
14764           return -99;
14765         }
14766     }
14767
14768   u32 name_len = vec_len (stream_name);
14769   /* Construct the API message */
14770   M (PG_ENABLE_DISABLE, pg_enable_disable);
14771   mp->context = 0;
14772   mp->is_enabled = enable;
14773   if (stream_name_set != 0)
14774     {
14775       mp->stream_name_length = ntohl (name_len);
14776       clib_memcpy (mp->stream_name, stream_name, name_len);
14777     }
14778   vec_free (stream_name);
14779
14780   S;
14781   W;
14782   /* NOTREACHED */
14783   return 0;
14784 }
14785
14786 int
14787 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14788 {
14789   unformat_input_t *input = vam->input;
14790   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14791   f64 timeout;
14792
14793   u16 *low_ports = 0;
14794   u16 *high_ports = 0;
14795   u16 this_low;
14796   u16 this_hi;
14797   ip4_address_t ip4_addr;
14798   ip6_address_t ip6_addr;
14799   u32 length;
14800   u32 tmp, tmp2;
14801   u8 prefix_set = 0;
14802   u32 vrf_id = ~0;
14803   u8 is_add = 1;
14804   u8 is_ipv6 = 0;
14805
14806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14807     {
14808       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14809         {
14810           prefix_set = 1;
14811         }
14812       else
14813         if (unformat
14814             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14815         {
14816           prefix_set = 1;
14817           is_ipv6 = 1;
14818         }
14819       else if (unformat (input, "vrf %d", &vrf_id))
14820         ;
14821       else if (unformat (input, "del"))
14822         is_add = 0;
14823       else if (unformat (input, "port %d", &tmp))
14824         {
14825           if (tmp == 0 || tmp > 65535)
14826             {
14827               errmsg ("port %d out of range", tmp);
14828               return -99;
14829             }
14830           this_low = tmp;
14831           this_hi = this_low + 1;
14832           vec_add1 (low_ports, this_low);
14833           vec_add1 (high_ports, this_hi);
14834         }
14835       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14836         {
14837           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14838             {
14839               errmsg ("incorrect range parameters\n");
14840               return -99;
14841             }
14842           this_low = tmp;
14843           /* Note: in debug CLI +1 is added to high before
14844              passing to real fn that does "the work"
14845              (ip_source_and_port_range_check_add_del).
14846              This fn is a wrapper around the binary API fn a
14847              control plane will call, which expects this increment
14848              to have occurred. Hence letting the binary API control
14849              plane fn do the increment for consistency between VAT
14850              and other control planes.
14851            */
14852           this_hi = tmp2;
14853           vec_add1 (low_ports, this_low);
14854           vec_add1 (high_ports, this_hi);
14855         }
14856       else
14857         break;
14858     }
14859
14860   if (prefix_set == 0)
14861     {
14862       errmsg ("<address>/<mask> not specified\n");
14863       return -99;
14864     }
14865
14866   if (vrf_id == ~0)
14867     {
14868       errmsg ("VRF ID required, not specified\n");
14869       return -99;
14870     }
14871
14872   if (vrf_id == 0)
14873     {
14874       errmsg
14875         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14876       return -99;
14877     }
14878
14879   if (vec_len (low_ports) == 0)
14880     {
14881       errmsg ("At least one port or port range required\n");
14882       return -99;
14883     }
14884
14885   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14886      ip_source_and_port_range_check_add_del);
14887
14888   mp->is_add = is_add;
14889
14890   if (is_ipv6)
14891     {
14892       mp->is_ipv6 = 1;
14893       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14894     }
14895   else
14896     {
14897       mp->is_ipv6 = 0;
14898       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14899     }
14900
14901   mp->mask_length = length;
14902   mp->number_of_ranges = vec_len (low_ports);
14903
14904   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14905   vec_free (low_ports);
14906
14907   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14908   vec_free (high_ports);
14909
14910   mp->vrf_id = ntohl (vrf_id);
14911
14912   S;
14913   W;
14914   /* NOTREACHED */
14915   return 0;
14916 }
14917
14918 int
14919 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14920 {
14921   unformat_input_t *input = vam->input;
14922   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14923   f64 timeout;
14924   u32 sw_if_index = ~0;
14925   int vrf_set = 0;
14926   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14927   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14928   u8 is_add = 1;
14929
14930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14931     {
14932       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14933         ;
14934       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14935         ;
14936       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14937         vrf_set = 1;
14938       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14939         vrf_set = 1;
14940       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14941         vrf_set = 1;
14942       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14943         vrf_set = 1;
14944       else if (unformat (input, "del"))
14945         is_add = 0;
14946       else
14947         break;
14948     }
14949
14950   if (sw_if_index == ~0)
14951     {
14952       errmsg ("Interface required but not specified\n");
14953       return -99;
14954     }
14955
14956   if (vrf_set == 0)
14957     {
14958       errmsg ("VRF ID required but not specified\n");
14959       return -99;
14960     }
14961
14962   if (tcp_out_vrf_id == 0
14963       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14964     {
14965       errmsg
14966         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14967       return -99;
14968     }
14969
14970   /* Construct the API message */
14971   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14972      ip_source_and_port_range_check_interface_add_del);
14973
14974   mp->sw_if_index = ntohl (sw_if_index);
14975   mp->is_add = is_add;
14976   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14977   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14978   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14979   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14980
14981   /* send it... */
14982   S;
14983
14984   /* Wait for a reply... */
14985   W;
14986 }
14987
14988 static int
14989 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
14990 {
14991   unformat_input_t *i = vam->input;
14992   vl_api_ipsec_gre_add_del_tunnel_t *mp;
14993   f64 timeout;
14994   u32 local_sa_id = 0;
14995   u32 remote_sa_id = 0;
14996   ip4_address_t src_address;
14997   ip4_address_t dst_address;
14998   u8 is_add = 1;
14999
15000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15001     {
15002       if (unformat (i, "local_sa %d", &local_sa_id))
15003         ;
15004       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15005         ;
15006       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15007         ;
15008       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15009         ;
15010       else if (unformat (i, "del"))
15011         is_add = 0;
15012       else
15013         {
15014           clib_warning ("parse error '%U'", format_unformat_error, i);
15015           return -99;
15016         }
15017     }
15018
15019   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15020
15021   mp->local_sa_id = ntohl (local_sa_id);
15022   mp->remote_sa_id = ntohl (remote_sa_id);
15023   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15024   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15025   mp->is_add = is_add;
15026
15027   S;
15028   W;
15029   /* NOTREACHED */
15030   return 0;
15031 }
15032
15033 static void vl_api_ipsec_gre_tunnel_details_t_handler
15034   (vl_api_ipsec_gre_tunnel_details_t * mp)
15035 {
15036   vat_main_t *vam = &vat_main;
15037
15038   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15039            ntohl (mp->sw_if_index),
15040            format_ip4_address, &mp->src_address,
15041            format_ip4_address, &mp->dst_address,
15042            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15043 }
15044
15045 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15046   (vl_api_ipsec_gre_tunnel_details_t * mp)
15047 {
15048   vat_main_t *vam = &vat_main;
15049   vat_json_node_t *node = NULL;
15050   struct in_addr ip4;
15051
15052   if (VAT_JSON_ARRAY != vam->json_tree.type)
15053     {
15054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15055       vat_json_init_array (&vam->json_tree);
15056     }
15057   node = vat_json_array_add (&vam->json_tree);
15058
15059   vat_json_init_object (node);
15060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15061   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15062   vat_json_object_add_ip4 (node, "src_address", ip4);
15063   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15064   vat_json_object_add_ip4 (node, "dst_address", ip4);
15065   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15066   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15067 }
15068
15069 static int
15070 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15071 {
15072   unformat_input_t *i = vam->input;
15073   vl_api_ipsec_gre_tunnel_dump_t *mp;
15074   f64 timeout;
15075   u32 sw_if_index;
15076   u8 sw_if_index_set = 0;
15077
15078   /* Parse args required to build the message */
15079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15080     {
15081       if (unformat (i, "sw_if_index %d", &sw_if_index))
15082         sw_if_index_set = 1;
15083       else
15084         break;
15085     }
15086
15087   if (sw_if_index_set == 0)
15088     {
15089       sw_if_index = ~0;
15090     }
15091
15092   if (!vam->json_output)
15093     {
15094       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15095                "sw_if_index", "src_address", "dst_address",
15096                "local_sa_id", "remote_sa_id");
15097     }
15098
15099   /* Get list of gre-tunnel interfaces */
15100   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15101
15102   mp->sw_if_index = htonl (sw_if_index);
15103
15104   S;
15105
15106   /* Use a control ping for synchronization */
15107   {
15108     vl_api_control_ping_t *mp;
15109     M (CONTROL_PING, control_ping);
15110     S;
15111   }
15112   W;
15113 }
15114
15115 static int
15116 q_or_quit (vat_main_t * vam)
15117 {
15118   longjmp (vam->jump_buf, 1);
15119   return 0;                     /* not so much */
15120 }
15121
15122 static int
15123 q (vat_main_t * vam)
15124 {
15125   return q_or_quit (vam);
15126 }
15127
15128 static int
15129 quit (vat_main_t * vam)
15130 {
15131   return q_or_quit (vam);
15132 }
15133
15134 static int
15135 comment (vat_main_t * vam)
15136 {
15137   return 0;
15138 }
15139
15140 static int
15141 cmd_cmp (void *a1, void *a2)
15142 {
15143   u8 **c1 = a1;
15144   u8 **c2 = a2;
15145
15146   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15147 }
15148
15149 static int
15150 help (vat_main_t * vam)
15151 {
15152   u8 **cmds = 0;
15153   u8 *name = 0;
15154   hash_pair_t *p;
15155   unformat_input_t *i = vam->input;
15156   int j;
15157
15158   if (unformat (i, "%s", &name))
15159     {
15160       uword *hs;
15161
15162       vec_add1 (name, 0);
15163
15164       hs = hash_get_mem (vam->help_by_name, name);
15165       if (hs)
15166         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15167       else
15168         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15169       vec_free (name);
15170       return 0;
15171     }
15172
15173   fformat (vam->ofp, "Help is available for the following:\n");
15174
15175     /* *INDENT-OFF* */
15176     hash_foreach_pair (p, vam->function_by_name,
15177     ({
15178       vec_add1 (cmds, (u8 *)(p->key));
15179     }));
15180     /* *INDENT-ON* */
15181
15182   vec_sort_with_function (cmds, cmd_cmp);
15183
15184   for (j = 0; j < vec_len (cmds); j++)
15185     fformat (vam->ofp, "%s\n", cmds[j]);
15186
15187   vec_free (cmds);
15188   return 0;
15189 }
15190
15191 static int
15192 set (vat_main_t * vam)
15193 {
15194   u8 *name = 0, *value = 0;
15195   unformat_input_t *i = vam->input;
15196
15197   if (unformat (i, "%s", &name))
15198     {
15199       /* The input buffer is a vector, not a string. */
15200       value = vec_dup (i->buffer);
15201       vec_delete (value, i->index, 0);
15202       /* Almost certainly has a trailing newline */
15203       if (value[vec_len (value) - 1] == '\n')
15204         value[vec_len (value) - 1] = 0;
15205       /* Make sure it's a proper string, one way or the other */
15206       vec_add1 (value, 0);
15207       (void) clib_macro_set_value (&vam->macro_main,
15208                                    (char *) name, (char *) value);
15209     }
15210   else
15211     errmsg ("usage: set <name> <value>\n");
15212
15213   vec_free (name);
15214   vec_free (value);
15215   return 0;
15216 }
15217
15218 static int
15219 unset (vat_main_t * vam)
15220 {
15221   u8 *name = 0;
15222
15223   if (unformat (vam->input, "%s", &name))
15224     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15225       errmsg ("unset: %s wasn't set\n", name);
15226   vec_free (name);
15227   return 0;
15228 }
15229
15230 typedef struct
15231 {
15232   u8 *name;
15233   u8 *value;
15234 } macro_sort_t;
15235
15236
15237 static int
15238 macro_sort_cmp (void *a1, void *a2)
15239 {
15240   macro_sort_t *s1 = a1;
15241   macro_sort_t *s2 = a2;
15242
15243   return strcmp ((char *) (s1->name), (char *) (s2->name));
15244 }
15245
15246 static int
15247 dump_macro_table (vat_main_t * vam)
15248 {
15249   macro_sort_t *sort_me = 0, *sm;
15250   int i;
15251   hash_pair_t *p;
15252
15253     /* *INDENT-OFF* */
15254     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15255     ({
15256       vec_add2 (sort_me, sm, 1);
15257       sm->name = (u8 *)(p->key);
15258       sm->value = (u8 *) (p->value[0]);
15259     }));
15260     /* *INDENT-ON* */
15261
15262   vec_sort_with_function (sort_me, macro_sort_cmp);
15263
15264   if (vec_len (sort_me))
15265     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15266   else
15267     fformat (vam->ofp, "The macro table is empty...\n");
15268
15269   for (i = 0; i < vec_len (sort_me); i++)
15270     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15271   return 0;
15272 }
15273
15274 static int
15275 dump_node_table (vat_main_t * vam)
15276 {
15277   int i, j;
15278   vlib_node_t *node, *next_node;
15279
15280   if (vec_len (vam->graph_nodes) == 0)
15281     {
15282       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15283       return 0;
15284     }
15285
15286   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15287     {
15288       node = vam->graph_nodes[i];
15289       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15290       for (j = 0; j < vec_len (node->next_nodes); j++)
15291         {
15292           if (node->next_nodes[j] != ~0)
15293             {
15294               next_node = vam->graph_nodes[node->next_nodes[j]];
15295               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15296             }
15297         }
15298     }
15299   return 0;
15300 }
15301
15302 static int
15303 search_node_table (vat_main_t * vam)
15304 {
15305   unformat_input_t *line_input = vam->input;
15306   u8 *node_to_find;
15307   int j;
15308   vlib_node_t *node, *next_node;
15309   uword *p;
15310
15311   if (vam->graph_node_index_by_name == 0)
15312     {
15313       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15314       return 0;
15315     }
15316
15317   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15318     {
15319       if (unformat (line_input, "%s", &node_to_find))
15320         {
15321           vec_add1 (node_to_find, 0);
15322           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15323           if (p == 0)
15324             {
15325               fformat (vam->ofp, "%s not found...\n", node_to_find);
15326               goto out;
15327             }
15328           node = vam->graph_nodes[p[0]];
15329           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15330           for (j = 0; j < vec_len (node->next_nodes); j++)
15331             {
15332               if (node->next_nodes[j] != ~0)
15333                 {
15334                   next_node = vam->graph_nodes[node->next_nodes[j]];
15335                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15336                 }
15337             }
15338         }
15339
15340       else
15341         {
15342           clib_warning ("parse error '%U'", format_unformat_error,
15343                         line_input);
15344           return -99;
15345         }
15346
15347     out:
15348       vec_free (node_to_find);
15349
15350     }
15351
15352   return 0;
15353 }
15354
15355
15356 static int
15357 script (vat_main_t * vam)
15358 {
15359   u8 *s = 0;
15360   char *save_current_file;
15361   unformat_input_t save_input;
15362   jmp_buf save_jump_buf;
15363   u32 save_line_number;
15364
15365   FILE *new_fp, *save_ifp;
15366
15367   if (unformat (vam->input, "%s", &s))
15368     {
15369       new_fp = fopen ((char *) s, "r");
15370       if (new_fp == 0)
15371         {
15372           errmsg ("Couldn't open script file %s\n", s);
15373           vec_free (s);
15374           return -99;
15375         }
15376     }
15377   else
15378     {
15379       errmsg ("Missing script name\n");
15380       return -99;
15381     }
15382
15383   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15384   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15385   save_ifp = vam->ifp;
15386   save_line_number = vam->input_line_number;
15387   save_current_file = (char *) vam->current_file;
15388
15389   vam->input_line_number = 0;
15390   vam->ifp = new_fp;
15391   vam->current_file = s;
15392   do_one_file (vam);
15393
15394   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15395   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15396   vam->ifp = save_ifp;
15397   vam->input_line_number = save_line_number;
15398   vam->current_file = (u8 *) save_current_file;
15399   vec_free (s);
15400
15401   return 0;
15402 }
15403
15404 static int
15405 echo (vat_main_t * vam)
15406 {
15407   fformat (vam->ofp, "%v", vam->input->buffer);
15408   return 0;
15409 }
15410
15411 /* List of API message constructors, CLI names map to api_xxx */
15412 #define foreach_vpe_api_msg                                             \
15413 _(create_loopback,"[mac <mac-addr>]")                                   \
15414 _(sw_interface_dump,"")                                                 \
15415 _(sw_interface_set_flags,                                               \
15416   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15417 _(sw_interface_add_del_address,                                         \
15418   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15419 _(sw_interface_set_table,                                               \
15420   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15421 _(sw_interface_set_vpath,                                               \
15422   "<intfc> | sw_if_index <id> enable | disable")                        \
15423 _(sw_interface_set_l2_xconnect,                                         \
15424   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15425   "enable | disable")                                                   \
15426 _(sw_interface_set_l2_bridge,                                           \
15427   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15428   "[shg <split-horizon-group>] [bvi]\n"                                 \
15429   "enable | disable")                                                   \
15430 _(bridge_domain_add_del,                                                \
15431   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15432 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15433 _(l2fib_add_del,                                                        \
15434   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15435 _(l2_flags,                                                             \
15436   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15437 _(bridge_flags,                                                         \
15438   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15439 _(tap_connect,                                                          \
15440   "tapname <name> mac <mac-addr> | random-mac")                         \
15441 _(tap_modify,                                                           \
15442   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15443 _(tap_delete,                                                           \
15444   "<vpp-if-name> | sw_if_index <id>")                                   \
15445 _(sw_interface_tap_dump, "")                                            \
15446 _(ip_add_del_route,                                                     \
15447   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15448   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15449   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15450   "[multipath] [count <n>]")                                            \
15451 _(proxy_arp_add_del,                                                    \
15452   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15453 _(proxy_arp_intfc_enable_disable,                                       \
15454   "<intfc> | sw_if_index <id> enable | disable")                        \
15455 _(mpls_add_del_encap,                                                   \
15456   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15457 _(mpls_add_del_decap,                                                   \
15458   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15459 _(mpls_gre_add_del_tunnel,                                              \
15460   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15461   "adj <ip4-address>/<mask-width> [del]")                               \
15462 _(sw_interface_set_unnumbered,                                          \
15463   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15464 _(ip_neighbor_add_del,                                                  \
15465   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15466   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15467 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15468 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15469 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15470   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15471   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15472   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15473 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15474 _(reset_fib, "vrf <n> [ipv6]")                                          \
15475 _(dhcp_proxy_config,                                                    \
15476   "svr <v46-address> src <v46-address>\n"                               \
15477    "insert-cid <n> [del]")                                              \
15478 _(dhcp_proxy_config_2,                                                  \
15479   "svr <v46-address> src <v46-address>\n"                               \
15480    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15481 _(dhcp_proxy_set_vss,                                                   \
15482   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15483 _(dhcp_client_config,                                                   \
15484   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15485 _(set_ip_flow_hash,                                                     \
15486   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15487 _(sw_interface_ip6_enable_disable,                                      \
15488   "<intfc> | sw_if_index <id> enable | disable")                        \
15489 _(sw_interface_ip6_set_link_local_address,                              \
15490   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15491 _(sw_interface_ip6nd_ra_prefix,                                         \
15492   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15493   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15494   "[nolink] [isno]")                                                    \
15495 _(sw_interface_ip6nd_ra_config,                                         \
15496   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15497   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15498   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15499 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15500 _(l2_patch_add_del,                                                     \
15501   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15502   "enable | disable")                                                   \
15503 _(mpls_ethernet_add_del_tunnel,                                         \
15504   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15505   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15506 _(mpls_ethernet_add_del_tunnel_2,                                       \
15507   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15508   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15509 _(sr_tunnel_add_del,                                                    \
15510   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15511   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15512   "[policy <policy_name>]")                                             \
15513 _(sr_policy_add_del,                                                    \
15514   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15515 _(sr_multicast_map_add_del,                                             \
15516   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15517 _(classify_add_del_table,                                               \
15518   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15519   "[del] mask <mask-value>\n"                                           \
15520   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15521 _(classify_add_del_session,                                             \
15522   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15523   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15524   "  [l3 [ip4|ip6]]")                                                   \
15525 _(classify_set_interface_ip_table,                                      \
15526   "<intfc> | sw_if_index <nn> table <nn>")                              \
15527 _(classify_set_interface_l2_tables,                                     \
15528   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15529   "  [other-table <nn>]")                                               \
15530 _(get_node_index, "node <node-name")                                    \
15531 _(add_node_next, "node <node-name> next <next-node-name>")              \
15532 _(l2tpv3_create_tunnel,                                                 \
15533   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15534   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15535   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15536 _(l2tpv3_set_tunnel_cookies,                                            \
15537   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15538   "[new_remote_cookie <nn>]\n")                                         \
15539 _(l2tpv3_interface_enable_disable,                                      \
15540   "<intfc> | sw_if_index <nn> enable | disable")                        \
15541 _(l2tpv3_set_lookup_key,                                                \
15542   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15543 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15544 _(vxlan_add_del_tunnel,                                                 \
15545   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15546   " [decap-next l2|ip4|ip6] [del]")                                     \
15547 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15548 _(gre_add_del_tunnel,                                                   \
15549   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15550 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15551 _(l2_fib_clear_table, "")                                               \
15552 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15553 _(l2_interface_vlan_tag_rewrite,                                        \
15554   "<intfc> | sw_if_index <nn> \n"                                       \
15555   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15556   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15557 _(create_vhost_user_if,                                                 \
15558         "socket <filename> [server] [renumber <dev_instance>] "         \
15559         "[mac <mac_address>]")                                          \
15560 _(modify_vhost_user_if,                                                 \
15561         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15562         "[server] [renumber <dev_instance>]")                           \
15563 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15564 _(sw_interface_vhost_user_dump, "")                                     \
15565 _(show_version, "")                                                     \
15566 _(vxlan_gpe_add_del_tunnel,                                             \
15567   "local <addr> remote <addr> vni <nn>\n"                               \
15568     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15569   "[next-ethernet] [next-nsh]\n")                                       \
15570 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15571 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15572 _(interface_name_renumber,                                              \
15573   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15574 _(input_acl_set_interface,                                              \
15575   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15576   "  [l2-table <nn>] [del]")                                            \
15577 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15578 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15579 _(ip_dump, "ipv4 | ipv6")                                               \
15580 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15581 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15582   "  spid_id <n> ")                                                     \
15583 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15584   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15585   "  integ_alg <alg> integ_key <hex>")                                  \
15586 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15587   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15588   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15589   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15590 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15591 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15592 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15593   "(auth_data 0x<data> | auth_data <data>)")                            \
15594 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15595   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15596 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15597   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15598   "(local|remote)")                                                     \
15599 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15600 _(delete_loopback,"sw_if_index <nn>")                                   \
15601 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15602 _(map_add_domain,                                                       \
15603   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15604   "ip6-src <ip6addr> "                                                  \
15605   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15606 _(map_del_domain, "index <n>")                                          \
15607 _(map_add_del_rule,                                                     \
15608   "index <n> psid <n> dst <ip6addr> [del]")                             \
15609 _(map_domain_dump, "")                                                  \
15610 _(map_rule_dump, "index <map-domain>")                                  \
15611 _(want_interface_events,  "enable|disable")                             \
15612 _(want_stats,"enable|disable")                                          \
15613 _(get_first_msg_id, "client <name>")                                    \
15614 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15615 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15616   "fib-id <nn> [ip4][ip6][default]")                                    \
15617 _(get_node_graph, " ")                                                  \
15618 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15619 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15620   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15621   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15622 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15623   " vrf_id <nn>  add | pop | none")                                     \
15624 _(trace_profile_del, "")                                                \
15625 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15626                             " sw_if_index <sw_if_index> p <priority> "  \
15627                             "w <weight>] [del]")                        \
15628 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15629                         "iface <intf> | sw_if_index <sw_if_index> "     \
15630                         "p <priority> w <weight> [del]")                \
15631 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15632                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15633                           "locator-set <locator_name> [del]")           \
15634 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15635   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15636 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15637 _(lisp_gpe_enable_disable, "enable|disable")                            \
15638 _(lisp_enable_disable, "enable|disable")                                \
15639 _(lisp_gpe_add_del_iface, "up|down")                                    \
15640 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15641                                "rloc <locator> p <prio> "               \
15642                                "w <weight> [rloc <loc> ... ] "          \
15643                                "action <action> [del-all]")             \
15644 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15645                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15646                           "[rloc <loc> ... ] action <action>")          \
15647 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15648 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15649 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15650 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15651                          "locator-set <loc-set-name>] [local | remote]")\
15652 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15653                        "[local] | [remote]")                            \
15654 _(lisp_eid_table_map_dump, "")                                          \
15655 _(lisp_gpe_tunnel_dump, "")                                             \
15656 _(lisp_map_resolver_dump, "")                                           \
15657 _(show_lisp_status, "")                                                 \
15658 _(lisp_get_map_request_itr_rlocs, "")                                   \
15659 _(show_lisp_pitr, "")                                                   \
15660 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15661 _(af_packet_delete, "name <host interface name>")                       \
15662 _(policer_add_del, "name <policer name> <params> [del]")                \
15663 _(policer_dump, "[name <policer name>]")                                \
15664 _(policer_classify_set_interface,                                       \
15665   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15666   "  [l2-table <nn>] [del]")                                            \
15667 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15668 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15669     "[master|slave]")                                                   \
15670 _(netmap_delete, "name <interface name>")                               \
15671 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15672 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15673 _(mpls_fib_encap_dump, "")                                              \
15674 _(mpls_fib_decap_dump, "")                                              \
15675 _(classify_table_ids, "")                                               \
15676 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15677 _(classify_table_info, "table_id <nn>")                                 \
15678 _(classify_session_dump, "table_id <nn>")                               \
15679 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15680                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15681                 "[template_interval <nn>]")                             \
15682 _(ipfix_dump, "")                                                       \
15683 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15684 _(pg_create_interface, "if_id <nn>")                                    \
15685 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15686 _(pg_enable_disable, "[stream <id>] disable")                           \
15687 _(ip_source_and_port_range_check_add_del,                               \
15688   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15689 _(ip_source_and_port_range_check_interface_add_del,                     \
15690   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15691   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15692 _(ipsec_gre_add_del_tunnel,                                             \
15693   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15694 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")
15695
15696 /* List of command functions, CLI names map directly to functions */
15697 #define foreach_cli_function                                    \
15698 _(comment, "usage: comment <ignore-rest-of-line>")              \
15699 _(dump_interface_table, "usage: dump_interface_table")          \
15700 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15701 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15702 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15703 _(dump_stats_table, "usage: dump_stats_table")                  \
15704 _(dump_macro_table, "usage: dump_macro_table ")                 \
15705 _(dump_node_table, "usage: dump_node_table")                    \
15706 _(echo, "usage: echo <message>")                                \
15707 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15708 _(help, "usage: help")                                          \
15709 _(q, "usage: quit")                                             \
15710 _(quit, "usage: quit")                                          \
15711 _(search_node_table, "usage: search_node_table <name>...")      \
15712 _(set, "usage: set <variable-name> <value>")                    \
15713 _(script, "usage: script <file-name>")                          \
15714 _(unset, "usage: unset <variable-name>")
15715
15716 #define _(N,n)                                  \
15717     static void vl_api_##n##_t_handler_uni      \
15718     (vl_api_##n##_t * mp)                       \
15719     {                                           \
15720         vat_main_t * vam = &vat_main;           \
15721         if (vam->json_output) {                 \
15722             vl_api_##n##_t_handler_json(mp);    \
15723         } else {                                \
15724             vl_api_##n##_t_handler(mp);         \
15725         }                                       \
15726     }
15727 foreach_vpe_api_reply_msg;
15728 #undef _
15729
15730 void
15731 vat_api_hookup (vat_main_t * vam)
15732 {
15733 #define _(N,n)                                                  \
15734     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15735                            vl_api_##n##_t_handler_uni,          \
15736                            vl_noop_handler,                     \
15737                            vl_api_##n##_t_endian,               \
15738                            vl_api_##n##_t_print,                \
15739                            sizeof(vl_api_##n##_t), 1);
15740   foreach_vpe_api_reply_msg;
15741 #undef _
15742
15743   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15744
15745   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15746
15747   vam->function_by_name = hash_create_string (0, sizeof (uword));
15748
15749   vam->help_by_name = hash_create_string (0, sizeof (uword));
15750
15751   /* API messages we can send */
15752 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15753   foreach_vpe_api_msg;
15754 #undef _
15755
15756   /* Help strings */
15757 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15758   foreach_vpe_api_msg;
15759 #undef _
15760
15761   /* CLI functions */
15762 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15763   foreach_cli_function;
15764 #undef _
15765
15766   /* Help strings */
15767 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15768   foreach_cli_function;
15769 #undef _
15770 }
15771
15772 #undef vl_api_version
15773 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15774 #include <vpp-api/vpe.api.h>
15775 #undef vl_api_version
15776
15777 void
15778 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15779 {
15780   /*
15781    * Send the main API signature in slot 0. This bit of code must
15782    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15783    */
15784   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15785 }
15786
15787 /*
15788  * fd.io coding-style-patch-verification: ON
15789  *
15790  * Local Variables:
15791  * eval: (c-set-style "gnu")
15792  * End:
15793  */