0df2051e6c77aaae847b7f46360d6fc8da3e35b3
[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
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void vl_api_noprint_control_ping_reply_t_handler
1319   (vl_api_noprint_control_ping_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_noprint_control_ping_reply_t_handler_json
1335   (vl_api_noprint_control_ping_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   i32 retval = ntohl (mp->retval);
1339
1340   if (vam->noprint_msg)
1341     {
1342       vam->retval = retval;
1343       vam->result_ready = 1;
1344       return;
1345     }
1346
1347   if (VAT_JSON_NONE != vam->json_tree.type)
1348     {
1349       vat_json_print (vam->ofp, &vam->json_tree);
1350       vat_json_free (&vam->json_tree);
1351       vam->json_tree.type = VAT_JSON_NONE;
1352     }
1353   else
1354     {
1355       /* just print [] */
1356       vat_json_init_array (&vam->json_tree);
1357       vat_json_print (vam->ofp, &vam->json_tree);
1358       vam->json_tree.type = VAT_JSON_NONE;
1359     }
1360
1361   vam->retval = retval;
1362   vam->result_ready = 1;
1363 }
1364
1365 static void
1366 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   i32 retval = ntohl (mp->retval);
1370   if (vam->async_mode)
1371     {
1372       vam->async_errors += (retval < 0);
1373     }
1374   else
1375     {
1376       vam->retval = retval;
1377       vam->result_ready = 1;
1378     }
1379 }
1380
1381 static void vl_api_l2_flags_reply_t_handler_json
1382   (vl_api_l2_flags_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   vat_json_node_t node;
1386
1387   vat_json_init_object (&node);
1388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1389   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1390                             ntohl (mp->resulting_feature_bitmap));
1391
1392   vat_json_print (vam->ofp, &node);
1393   vat_json_free (&node);
1394
1395   vam->retval = ntohl (mp->retval);
1396   vam->result_ready = 1;
1397 }
1398
1399 static void vl_api_bridge_flags_reply_t_handler
1400   (vl_api_bridge_flags_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   i32 retval = ntohl (mp->retval);
1404   if (vam->async_mode)
1405     {
1406       vam->async_errors += (retval < 0);
1407     }
1408   else
1409     {
1410       vam->retval = retval;
1411       vam->result_ready = 1;
1412     }
1413 }
1414
1415 static void vl_api_bridge_flags_reply_t_handler_json
1416   (vl_api_bridge_flags_reply_t * mp)
1417 {
1418   vat_main_t *vam = &vat_main;
1419   vat_json_node_t node;
1420
1421   vat_json_init_object (&node);
1422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1423   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1424                             ntohl (mp->resulting_feature_bitmap));
1425
1426   vat_json_print (vam->ofp, &node);
1427   vat_json_free (&node);
1428
1429   vam->retval = ntohl (mp->retval);
1430   vam->result_ready = 1;
1431 }
1432
1433 static void vl_api_tap_connect_reply_t_handler
1434   (vl_api_tap_connect_reply_t * mp)
1435 {
1436   vat_main_t *vam = &vat_main;
1437   i32 retval = ntohl (mp->retval);
1438   if (vam->async_mode)
1439     {
1440       vam->async_errors += (retval < 0);
1441     }
1442   else
1443     {
1444       vam->retval = retval;
1445       vam->sw_if_index = ntohl (mp->sw_if_index);
1446       vam->result_ready = 1;
1447     }
1448
1449 }
1450
1451 static void vl_api_tap_connect_reply_t_handler_json
1452   (vl_api_tap_connect_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   vat_json_node_t node;
1456
1457   vat_json_init_object (&node);
1458   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1459   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1460
1461   vat_json_print (vam->ofp, &node);
1462   vat_json_free (&node);
1463
1464   vam->retval = ntohl (mp->retval);
1465   vam->result_ready = 1;
1466
1467 }
1468
1469 static void
1470 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474   if (vam->async_mode)
1475     {
1476       vam->async_errors += (retval < 0);
1477     }
1478   else
1479     {
1480       vam->retval = retval;
1481       vam->sw_if_index = ntohl (mp->sw_if_index);
1482       vam->result_ready = 1;
1483     }
1484 }
1485
1486 static void vl_api_tap_modify_reply_t_handler_json
1487   (vl_api_tap_modify_reply_t * mp)
1488 {
1489   vat_main_t *vam = &vat_main;
1490   vat_json_node_t node;
1491
1492   vat_json_init_object (&node);
1493   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1494   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1495
1496   vat_json_print (vam->ofp, &node);
1497   vat_json_free (&node);
1498
1499   vam->retval = ntohl (mp->retval);
1500   vam->result_ready = 1;
1501 }
1502
1503 static void
1504 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1505 {
1506   vat_main_t *vam = &vat_main;
1507   i32 retval = ntohl (mp->retval);
1508   if (vam->async_mode)
1509     {
1510       vam->async_errors += (retval < 0);
1511     }
1512   else
1513     {
1514       vam->retval = retval;
1515       vam->result_ready = 1;
1516     }
1517 }
1518
1519 static void vl_api_tap_delete_reply_t_handler_json
1520   (vl_api_tap_delete_reply_t * mp)
1521 {
1522   vat_main_t *vam = &vat_main;
1523   vat_json_node_t node;
1524
1525   vat_json_init_object (&node);
1526   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1527
1528   vat_json_print (vam->ofp, &node);
1529   vat_json_free (&node);
1530
1531   vam->retval = ntohl (mp->retval);
1532   vam->result_ready = 1;
1533 }
1534
1535 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1536   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1537 {
1538   vat_main_t *vam = &vat_main;
1539   i32 retval = ntohl (mp->retval);
1540   if (vam->async_mode)
1541     {
1542       vam->async_errors += (retval < 0);
1543     }
1544   else
1545     {
1546       vam->retval = retval;
1547       vam->result_ready = 1;
1548     }
1549 }
1550
1551 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1552   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   vat_json_node_t node;
1556
1557   vat_json_init_object (&node);
1558   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1559   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1560                             ntohl (mp->tunnel_sw_if_index));
1561
1562   vat_json_print (vam->ofp, &node);
1563   vat_json_free (&node);
1564
1565   vam->retval = ntohl (mp->retval);
1566   vam->result_ready = 1;
1567 }
1568
1569 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1570   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   i32 retval = ntohl (mp->retval);
1574   if (vam->async_mode)
1575     {
1576       vam->async_errors += (retval < 0);
1577     }
1578   else
1579     {
1580       vam->retval = retval;
1581       vam->sw_if_index = ntohl (mp->sw_if_index);
1582       vam->result_ready = 1;
1583     }
1584 }
1585
1586 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1587   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1588 {
1589   vat_main_t *vam = &vat_main;
1590   vat_json_node_t node;
1591
1592   vat_json_init_object (&node);
1593   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1594   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1595
1596   vat_json_print (vam->ofp, &node);
1597   vat_json_free (&node);
1598
1599   vam->retval = ntohl (mp->retval);
1600   vam->result_ready = 1;
1601 }
1602
1603
1604 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1605   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   i32 retval = ntohl (mp->retval);
1609   if (vam->async_mode)
1610     {
1611       vam->async_errors += (retval < 0);
1612     }
1613   else
1614     {
1615       vam->retval = retval;
1616       vam->result_ready = 1;
1617     }
1618 }
1619
1620 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1621   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   vat_json_node_t node;
1625
1626   vat_json_init_object (&node);
1627   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1628   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1629
1630   vat_json_print (vam->ofp, &node);
1631   vat_json_free (&node);
1632
1633   vam->retval = ntohl (mp->retval);
1634   vam->result_ready = 1;
1635 }
1636
1637 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1638   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   i32 retval = ntohl (mp->retval);
1642   if (vam->async_mode)
1643     {
1644       vam->async_errors += (retval < 0);
1645     }
1646   else
1647     {
1648       vam->retval = retval;
1649       vam->sw_if_index = ntohl (mp->sw_if_index);
1650       vam->result_ready = 1;
1651     }
1652 }
1653
1654 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1655   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   vat_json_node_t node;
1659
1660   vat_json_init_object (&node);
1661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1662   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1663
1664   vat_json_print (vam->ofp, &node);
1665   vat_json_free (&node);
1666
1667   vam->retval = ntohl (mp->retval);
1668   vam->result_ready = 1;
1669 }
1670
1671 static void vl_api_gre_add_del_tunnel_reply_t_handler
1672   (vl_api_gre_add_del_tunnel_reply_t * mp)
1673 {
1674   vat_main_t *vam = &vat_main;
1675   i32 retval = ntohl (mp->retval);
1676   if (vam->async_mode)
1677     {
1678       vam->async_errors += (retval < 0);
1679     }
1680   else
1681     {
1682       vam->retval = retval;
1683       vam->sw_if_index = ntohl (mp->sw_if_index);
1684       vam->result_ready = 1;
1685     }
1686 }
1687
1688 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1689   (vl_api_gre_add_del_tunnel_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   vat_json_node_t node;
1693
1694   vat_json_init_object (&node);
1695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1696   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1697
1698   vat_json_print (vam->ofp, &node);
1699   vat_json_free (&node);
1700
1701   vam->retval = ntohl (mp->retval);
1702   vam->result_ready = 1;
1703 }
1704
1705 static void vl_api_create_vhost_user_if_reply_t_handler
1706   (vl_api_create_vhost_user_if_reply_t * mp)
1707 {
1708   vat_main_t *vam = &vat_main;
1709   i32 retval = ntohl (mp->retval);
1710   if (vam->async_mode)
1711     {
1712       vam->async_errors += (retval < 0);
1713     }
1714   else
1715     {
1716       vam->retval = retval;
1717       vam->sw_if_index = ntohl (mp->sw_if_index);
1718       vam->result_ready = 1;
1719     }
1720 }
1721
1722 static void vl_api_create_vhost_user_if_reply_t_handler_json
1723   (vl_api_create_vhost_user_if_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   vat_json_node_t node;
1727
1728   vat_json_init_object (&node);
1729   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1730   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1731
1732   vat_json_print (vam->ofp, &node);
1733   vat_json_free (&node);
1734
1735   vam->retval = ntohl (mp->retval);
1736   vam->result_ready = 1;
1737 }
1738
1739 static void vl_api_ip_address_details_t_handler
1740   (vl_api_ip_address_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_address_details_t empty_ip_address_details = { {0} };
1744   ip_address_details_t *address = NULL;
1745   ip_details_t *current_ip_details = NULL;
1746   ip_details_t *details = NULL;
1747
1748   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1749
1750   if (!details || vam->current_sw_if_index >= vec_len (details)
1751       || !details[vam->current_sw_if_index].present)
1752     {
1753       errmsg ("ip address details arrived but not stored\n");
1754       errmsg ("ip_dump should be called first\n");
1755       return;
1756     }
1757
1758   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1759
1760 #define addresses (current_ip_details->addr)
1761
1762   vec_validate_init_empty (addresses, vec_len (addresses),
1763                            empty_ip_address_details);
1764
1765   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1766
1767   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1768   address->prefix_length = mp->prefix_length;
1769 #undef addresses
1770 }
1771
1772 static void vl_api_ip_address_details_t_handler_json
1773   (vl_api_ip_address_details_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   vat_json_node_t *node = NULL;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
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   node = vat_json_array_add (&vam->json_tree);
1786
1787   vat_json_init_object (node);
1788   if (vam->is_ipv6)
1789     {
1790       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1791       vat_json_object_add_ip6 (node, "ip", ip6);
1792     }
1793   else
1794     {
1795       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1796       vat_json_object_add_ip4 (node, "ip", ip4);
1797     }
1798   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1799 }
1800
1801 static void
1802 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   static ip_details_t empty_ip_details = { 0 };
1806   ip_details_t *ip = NULL;
1807   u32 sw_if_index = ~0;
1808
1809   sw_if_index = ntohl (mp->sw_if_index);
1810
1811   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1812                            sw_if_index, empty_ip_details);
1813
1814   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1815                          sw_if_index);
1816
1817   ip->present = 1;
1818 }
1819
1820 static void
1821 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824
1825   if (VAT_JSON_ARRAY != vam->json_tree.type)
1826     {
1827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1828       vat_json_init_array (&vam->json_tree);
1829     }
1830   vat_json_array_add_uint (&vam->json_tree,
1831                            clib_net_to_host_u32 (mp->sw_if_index));
1832 }
1833
1834 static void vl_api_map_domain_details_t_handler_json
1835   (vl_api_map_domain_details_t * mp)
1836 {
1837   vat_json_node_t *node = NULL;
1838   vat_main_t *vam = &vat_main;
1839   struct in6_addr ip6;
1840   struct in_addr ip4;
1841
1842   if (VAT_JSON_ARRAY != vam->json_tree.type)
1843     {
1844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1845       vat_json_init_array (&vam->json_tree);
1846     }
1847
1848   node = vat_json_array_add (&vam->json_tree);
1849   vat_json_init_object (node);
1850
1851   vat_json_object_add_uint (node, "domain_index",
1852                             clib_net_to_host_u32 (mp->domain_index));
1853   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1855   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1856   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1857   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1858   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1859   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1860   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1861   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1862   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1863   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1864   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1865   vat_json_object_add_uint (node, "flags", mp->flags);
1866   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1867   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1868 }
1869
1870 static void vl_api_map_domain_details_t_handler
1871   (vl_api_map_domain_details_t * mp)
1872 {
1873   vat_main_t *vam = &vat_main;
1874
1875   if (mp->is_translation)
1876     {
1877       fformat (vam->ofp,
1878                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1879                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1880                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1881                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1882                clib_net_to_host_u32 (mp->domain_index));
1883     }
1884   else
1885     {
1886       fformat (vam->ofp,
1887                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1888                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1889                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1890                format_ip6_address, mp->ip6_src,
1891                clib_net_to_host_u32 (mp->domain_index));
1892     }
1893   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1894            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1895            mp->is_translation ? "map-t" : "");
1896 }
1897
1898 static void vl_api_map_rule_details_t_handler_json
1899   (vl_api_map_rule_details_t * mp)
1900 {
1901   struct in6_addr ip6;
1902   vat_json_node_t *node = NULL;
1903   vat_main_t *vam = &vat_main;
1904
1905   if (VAT_JSON_ARRAY != vam->json_tree.type)
1906     {
1907       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1908       vat_json_init_array (&vam->json_tree);
1909     }
1910
1911   node = vat_json_array_add (&vam->json_tree);
1912   vat_json_init_object (node);
1913
1914   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1915   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1916   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1917 }
1918
1919 static void
1920 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1921 {
1922   vat_main_t *vam = &vat_main;
1923   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1924            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1925 }
1926
1927 static void
1928 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1932           "router_addr %U host_mac %U\n",
1933           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1934           format_ip4_address, &mp->host_address,
1935           format_ip4_address, &mp->router_address,
1936           format_ethernet_address, mp->host_mac);
1937 }
1938
1939 static void vl_api_dhcp_compl_event_t_handler_json
1940   (vl_api_dhcp_compl_event_t * mp)
1941 {
1942   /* JSON output not supported */
1943 }
1944
1945 static void
1946 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1947                               u32 counter)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   static u64 default_counter = 0;
1951
1952   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1953                            NULL);
1954   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1955                            sw_if_index, default_counter);
1956   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1957 }
1958
1959 static void
1960 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1961                                 interface_counter_t counter)
1962 {
1963   vat_main_t *vam = &vat_main;
1964   static interface_counter_t default_counter = { 0, };
1965
1966   vec_validate_init_empty (vam->combined_interface_counters,
1967                            vnet_counter_type, NULL);
1968   vec_validate_init_empty (vam->combined_interface_counters
1969                            [vnet_counter_type], sw_if_index, default_counter);
1970   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1971 }
1972
1973 static void vl_api_vnet_interface_counters_t_handler
1974   (vl_api_vnet_interface_counters_t * mp)
1975 {
1976   /* not supported */
1977 }
1978
1979 static void vl_api_vnet_interface_counters_t_handler_json
1980   (vl_api_vnet_interface_counters_t * mp)
1981 {
1982   interface_counter_t counter;
1983   vlib_counter_t *v;
1984   u64 *v_packets;
1985   u64 packets;
1986   u32 count;
1987   u32 first_sw_if_index;
1988   int i;
1989
1990   count = ntohl (mp->count);
1991   first_sw_if_index = ntohl (mp->first_sw_if_index);
1992
1993   if (!mp->is_combined)
1994     {
1995       v_packets = (u64 *) & mp->data;
1996       for (i = 0; i < count; i++)
1997         {
1998           packets =
1999             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2000           set_simple_interface_counter (mp->vnet_counter_type,
2001                                         first_sw_if_index + i, packets);
2002           v_packets++;
2003         }
2004     }
2005   else
2006     {
2007       v = (vlib_counter_t *) & mp->data;
2008       for (i = 0; i < count; i++)
2009         {
2010           counter.packets =
2011             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2012           counter.bytes =
2013             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2014           set_combined_interface_counter (mp->vnet_counter_type,
2015                                           first_sw_if_index + i, counter);
2016           v++;
2017         }
2018     }
2019 }
2020
2021 static u32
2022 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2023 {
2024   vat_main_t *vam = &vat_main;
2025   u32 i;
2026
2027   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2028     {
2029       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2030         {
2031           return i;
2032         }
2033     }
2034   return ~0;
2035 }
2036
2037 static u32
2038 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2039 {
2040   vat_main_t *vam = &vat_main;
2041   u32 i;
2042
2043   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2044     {
2045       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2046         {
2047           return i;
2048         }
2049     }
2050   return ~0;
2051 }
2052
2053 static void vl_api_vnet_ip4_fib_counters_t_handler
2054   (vl_api_vnet_ip4_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2060   (vl_api_vnet_ip4_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip4_fib_counter_t *v;
2064   ip4_fib_counter_t *counter;
2065   struct in_addr ip4;
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 = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip4_fib_counters, vrf_index);
2079       vam->ip4_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip4_fib_counters[vrf_index]);
2083   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2088       counter = &vam->ip4_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2090       counter->address = ip4;
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_vnet_ip6_fib_counters_t_handler
2099   (vl_api_vnet_ip6_fib_counters_t * mp)
2100 {
2101   /* not supported */
2102 }
2103
2104 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2105   (vl_api_vnet_ip6_fib_counters_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   vl_api_ip6_fib_counter_t *v;
2109   ip6_fib_counter_t *counter;
2110   struct in6_addr ip6;
2111   u32 vrf_id;
2112   u32 vrf_index;
2113   u32 count;
2114   int i;
2115
2116   vrf_id = ntohl (mp->vrf_id);
2117   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2118   if (~0 == vrf_index)
2119     {
2120       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2121       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2122       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2123       vec_validate (vam->ip6_fib_counters, vrf_index);
2124       vam->ip6_fib_counters[vrf_index] = NULL;
2125     }
2126
2127   vec_free (vam->ip6_fib_counters[vrf_index]);
2128   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2129   count = ntohl (mp->count);
2130   for (i = 0; i < count; i++)
2131     {
2132       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2133       counter = &vam->ip6_fib_counters[vrf_index][i];
2134       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2135       counter->address = ip6;
2136       counter->address_length = v->address_length;
2137       counter->packets = clib_net_to_host_u64 (v->packets);
2138       counter->bytes = clib_net_to_host_u64 (v->bytes);
2139       v++;
2140     }
2141 }
2142
2143 static void vl_api_get_first_msg_id_reply_t_handler
2144   (vl_api_get_first_msg_id_reply_t * mp)
2145 {
2146   vat_main_t *vam = &vat_main;
2147   i32 retval = ntohl (mp->retval);
2148
2149   if (vam->async_mode)
2150     {
2151       vam->async_errors += (retval < 0);
2152     }
2153   else
2154     {
2155       vam->retval = retval;
2156       vam->result_ready = 1;
2157     }
2158   if (retval >= 0)
2159     {
2160       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2161     }
2162 }
2163
2164 static void vl_api_get_first_msg_id_reply_t_handler_json
2165   (vl_api_get_first_msg_id_reply_t * mp)
2166 {
2167   vat_main_t *vam = &vat_main;
2168   vat_json_node_t node;
2169
2170   vat_json_init_object (&node);
2171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2172   vat_json_object_add_uint (&node, "first_msg_id",
2173                             (uint) ntohs (mp->first_msg_id));
2174
2175   vat_json_print (vam->ofp, &node);
2176   vat_json_free (&node);
2177
2178   vam->retval = ntohl (mp->retval);
2179   vam->result_ready = 1;
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   i32 retval = ntohl (mp->retval);
2188   u8 *pvt_copy, *reply;
2189   void *oldheap;
2190   vlib_node_t *node;
2191   int i;
2192
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->result_ready = 1;
2201     }
2202
2203   /* "Should never happen..." */
2204   if (retval != 0)
2205     return;
2206
2207   reply = (u8 *) (mp->reply_in_shmem);
2208   pvt_copy = vec_dup (reply);
2209
2210   /* Toss the shared-memory original... */
2211   pthread_mutex_lock (&am->vlib_rp->mutex);
2212   oldheap = svm_push_data_heap (am->vlib_rp);
2213
2214   vec_free (reply);
2215
2216   svm_pop_heap (oldheap);
2217   pthread_mutex_unlock (&am->vlib_rp->mutex);
2218
2219   if (vam->graph_nodes)
2220     {
2221       hash_free (vam->graph_node_index_by_name);
2222
2223       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2224         {
2225           node = vam->graph_nodes[i];
2226           vec_free (node->name);
2227           vec_free (node->next_nodes);
2228           vec_free (node);
2229         }
2230       vec_free (vam->graph_nodes);
2231     }
2232
2233   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2234   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2235   vec_free (pvt_copy);
2236
2237   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2238     {
2239       node = vam->graph_nodes[i];
2240       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2241     }
2242 }
2243
2244 static void vl_api_get_node_graph_reply_t_handler_json
2245   (vl_api_get_node_graph_reply_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   api_main_t *am = &api_main;
2249   void *oldheap;
2250   vat_json_node_t node;
2251   u8 *reply;
2252
2253   /* $$$$ make this real? */
2254   vat_json_init_object (&node);
2255   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2256   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2257
2258   reply = (u8 *) (mp->reply_in_shmem);
2259
2260   /* Toss the shared-memory original... */
2261   pthread_mutex_lock (&am->vlib_rp->mutex);
2262   oldheap = svm_push_data_heap (am->vlib_rp);
2263
2264   vec_free (reply);
2265
2266   svm_pop_heap (oldheap);
2267   pthread_mutex_unlock (&am->vlib_rp->mutex);
2268
2269   vat_json_print (vam->ofp, &node);
2270   vat_json_free (&node);
2271
2272   vam->retval = ntohl (mp->retval);
2273   vam->result_ready = 1;
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2278 {
2279   vat_main_t *vam = &vat_main;
2280   locator_msg_t loc;
2281   u8 *tmp_str = 0;
2282
2283   memset (&loc, 0, sizeof (loc));
2284   if (vam->noprint_msg)
2285     {
2286       loc.local = mp->local;
2287       loc.priority = mp->priority;
2288       loc.weight = mp->weight;
2289       if (loc.local)
2290         {
2291           loc.sw_if_index = ntohl (mp->sw_if_index);
2292         }
2293       else
2294         {
2295           loc.is_ipv6 = mp->is_ipv6;
2296           clib_memcpy (loc.ip_address, mp->ip_address,
2297                        sizeof (loc.ip_address));
2298         }
2299       vec_add1 (vam->locator_msg, loc);
2300     }
2301   else
2302     {
2303       if (mp->local)
2304         {
2305           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2306                             ntohl (mp->sw_if_index),
2307                             mp->priority, mp->weight);
2308         }
2309       else
2310         {
2311           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2312                             mp->is_ipv6 ? format_ip6_address :
2313                             format_ip4_address,
2314                             mp->ip_address, mp->priority, mp->weight);
2315         }
2316
2317       fformat (vam->ofp, "%s", tmp_str);
2318
2319       vec_free (tmp_str);
2320     }
2321 }
2322
2323 static void
2324 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2325                                             mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t *node = NULL;
2329   locator_msg_t loc;
2330   struct in6_addr ip6;
2331   struct in_addr ip4;
2332
2333   memset (&loc, 0, sizeof (loc));
2334   if (vam->noprint_msg)
2335     {
2336       loc.local = mp->local;
2337       loc.priority = mp->priority;
2338       loc.weight = mp->weight;
2339       if (loc.local)
2340         {
2341           loc.sw_if_index = ntohl (mp->sw_if_index);
2342         }
2343       else
2344         {
2345           loc.is_ipv6 = mp->is_ipv6;
2346           clib_memcpy (loc.ip_address, mp->ip_address,
2347                        sizeof (loc.ip_address));
2348         }
2349       vec_add1 (vam->locator_msg, loc);
2350       return;
2351     }
2352
2353   if (VAT_JSON_ARRAY != vam->json_tree.type)
2354     {
2355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2356       vat_json_init_array (&vam->json_tree);
2357     }
2358   node = vat_json_array_add (&vam->json_tree);
2359
2360   vat_json_init_object (node);
2361
2362   if (mp->local)
2363     {
2364       vat_json_object_add_uint (node, "locator_index",
2365                                 ntohl (mp->sw_if_index));
2366     }
2367   else
2368     {
2369       if (mp->is_ipv6)
2370         {
2371           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2372           vat_json_object_add_ip6 (node, "locator", ip6);
2373         }
2374       else
2375         {
2376           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2377           vat_json_object_add_ip4 (node, "locator", ip4);
2378         }
2379     }
2380   vat_json_object_add_uint (node, "priority", mp->priority);
2381   vat_json_object_add_uint (node, "weight", mp->weight);
2382 }
2383
2384 static void
2385 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2386                                            mp)
2387 {
2388   vat_main_t *vam = &vat_main;
2389   locator_set_msg_t ls;
2390
2391   ls.locator_set_index = ntohl (mp->locator_set_index);
2392   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2393   vec_add1 (vam->locator_set_msg, ls);
2394 }
2395
2396 static void
2397   vl_api_lisp_locator_set_details_t_handler_json
2398   (vl_api_lisp_locator_set_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   locator_set_msg_t ls;
2402
2403   ls.locator_set_index = ntohl (mp->locator_set_index);
2404   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2405   vec_add1 (vam->locator_set_msg, ls);
2406 }
2407
2408 static void
2409 add_lisp_eid_table_entry (vat_main_t * vam,
2410                           vl_api_lisp_eid_table_details_t * mp)
2411 {
2412   eid_table_t eid_table;
2413
2414   memset (&eid_table, 0, sizeof (eid_table));
2415   eid_table.is_local = mp->is_local;
2416   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2417   eid_table.eid_type = mp->eid_type;
2418   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2419   eid_table.eid_prefix_len = mp->eid_prefix_len;
2420   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2421   eid_table.action = mp->action;
2422   eid_table.authoritative = mp->authoritative;
2423   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2424   vec_add1 (vam->eid_tables, eid_table);
2425 }
2426
2427 static void
2428 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   add_lisp_eid_table_entry (vam, mp);
2432 }
2433
2434 static void
2435 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2436                                               * mp)
2437 {
2438   vat_main_t *vam = &vat_main;
2439   add_lisp_eid_table_entry (vam, mp);
2440 }
2441
2442 static void
2443   vl_api_lisp_eid_table_map_details_t_handler
2444   (vl_api_lisp_eid_table_map_details_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447
2448   u8 *line = format (0, "%=10d%=10d",
2449                      clib_net_to_host_u32 (mp->vni),
2450                      clib_net_to_host_u32 (mp->dp_table));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_map_details_t_handler_json
2457   (vl_api_lisp_eid_table_map_details_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t *node = NULL;
2461
2462   if (VAT_JSON_ARRAY != vam->json_tree.type)
2463     {
2464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2465       vat_json_init_array (&vam->json_tree);
2466     }
2467   node = vat_json_array_add (&vam->json_tree);
2468   vat_json_init_object (node);
2469   vat_json_object_add_uint (node, "dp_table",
2470                             clib_net_to_host_u32 (mp->dp_table));
2471   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2472 }
2473
2474 static void
2475   vl_api_lisp_eid_table_vni_details_t_handler
2476   (vl_api_lisp_eid_table_vni_details_t * mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479
2480   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2481   fformat (vam->ofp, "%v\n", line);
2482   vec_free (line);
2483 }
2484
2485 static void
2486   vl_api_lisp_eid_table_vni_details_t_handler_json
2487   (vl_api_lisp_eid_table_vni_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   vat_json_node_t *node = NULL;
2491
2492   if (VAT_JSON_ARRAY != vam->json_tree.type)
2493     {
2494       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2495       vat_json_init_array (&vam->json_tree);
2496     }
2497   node = vat_json_array_add (&vam->json_tree);
2498   vat_json_init_object (node);
2499   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2500 }
2501
2502 static u8 *
2503 format_decap_next (u8 * s, va_list * args)
2504 {
2505   u32 next_index = va_arg (*args, u32);
2506
2507   switch (next_index)
2508     {
2509     case LISP_GPE_INPUT_NEXT_DROP:
2510       return format (s, "drop");
2511     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2512       return format (s, "ip4");
2513     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2514       return format (s, "ip6");
2515     default:
2516       return format (s, "unknown %d", next_index);
2517     }
2518   return s;
2519 }
2520
2521 static void
2522 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2523                                           mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   u8 *iid_str;
2527   u8 *flag_str = NULL;
2528
2529   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2530
2531 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2532   foreach_lisp_gpe_flag_bit;
2533 #undef _
2534
2535   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2536            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2537            mp->tunnels,
2538            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2539            mp->source_ip,
2540            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2541            mp->destination_ip,
2542            ntohl (mp->encap_fib_id),
2543            ntohl (mp->decap_fib_id),
2544            format_decap_next, ntohl (mp->dcap_next),
2545            mp->ver_res >> 6,
2546            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2547
2548   vec_free (iid_str);
2549 }
2550
2551 static void
2552   vl_api_lisp_gpe_tunnel_details_t_handler_json
2553   (vl_api_lisp_gpe_tunnel_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   vat_json_node_t *node = NULL;
2557   struct in6_addr ip6;
2558   struct in_addr ip4;
2559   u8 *next_decap_str;
2560
2561   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2572   if (mp->is_ipv6)
2573     {
2574       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "source address", ip6);
2576       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2577       vat_json_object_add_ip6 (node, "destination address", ip6);
2578     }
2579   else
2580     {
2581       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2582       vat_json_object_add_ip4 (node, "source address", ip4);
2583       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2584       vat_json_object_add_ip4 (node, "destination address", ip4);
2585     }
2586   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2587   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2588   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2589   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2590   vat_json_object_add_uint (node, "flags", mp->flags);
2591   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2592   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2593   vat_json_object_add_uint (node, "res", mp->res);
2594   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2595
2596   vec_free (next_decap_str);
2597 }
2598
2599 static void
2600 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2601                                             * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604
2605   fformat (vam->ofp, "%=20U\n",
2606            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2607            mp->ip_address);
2608 }
2609
2610 static void
2611   vl_api_lisp_map_resolver_details_t_handler_json
2612   (vl_api_lisp_map_resolver_details_t * mp)
2613 {
2614   vat_main_t *vam = &vat_main;
2615   vat_json_node_t *node = NULL;
2616   struct in6_addr ip6;
2617   struct in_addr ip4;
2618
2619   if (VAT_JSON_ARRAY != vam->json_tree.type)
2620     {
2621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2622       vat_json_init_array (&vam->json_tree);
2623     }
2624   node = vat_json_array_add (&vam->json_tree);
2625
2626   vat_json_init_object (node);
2627   if (mp->is_ipv6)
2628     {
2629       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2630       vat_json_object_add_ip6 (node, "map resolver", ip6);
2631     }
2632   else
2633     {
2634       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2635       vat_json_object_add_ip4 (node, "map resolver", ip4);
2636     }
2637 }
2638
2639 static void
2640   vl_api_show_lisp_status_reply_t_handler
2641   (vl_api_show_lisp_status_reply_t * mp)
2642 {
2643   vat_main_t *vam = &vat_main;
2644   i32 retval = ntohl (mp->retval);
2645
2646   if (0 <= retval)
2647     {
2648       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2649                mp->feature_status ? "enabled" : "disabled",
2650                mp->gpe_status ? "enabled" : "disabled");
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_show_lisp_status_reply_t_handler_json
2659   (vl_api_show_lisp_status_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t node;
2663   u8 *gpe_status = NULL;
2664   u8 *feature_status = NULL;
2665
2666   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2667   feature_status = format (0, "%s",
2668                            mp->feature_status ? "enabled" : "disabled");
2669   vec_add1 (gpe_status, 0);
2670   vec_add1 (feature_status, 0);
2671
2672   vat_json_init_object (&node);
2673   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2674   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2675
2676   vec_free (gpe_status);
2677   vec_free (feature_status);
2678
2679   vat_json_print (vam->ofp, &node);
2680   vat_json_free (&node);
2681
2682   vam->retval = ntohl (mp->retval);
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2688   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   i32 retval = ntohl (mp->retval);
2692
2693   if (retval >= 0)
2694     {
2695       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2704   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t *node = NULL;
2708
2709   if (VAT_JSON_ARRAY != vam->json_tree.type)
2710     {
2711       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2712       vat_json_init_array (&vam->json_tree);
2713     }
2714   node = vat_json_array_add (&vam->json_tree);
2715
2716   vat_json_init_object (node);
2717   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2718
2719   vat_json_print (vam->ofp, node);
2720   vat_json_free (node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static void
2727 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2728 {
2729   vat_main_t *vam = &vat_main;
2730   i32 retval = ntohl (mp->retval);
2731
2732   if (0 <= retval)
2733     {
2734       fformat (vam->ofp, "%-20s%-16s\n",
2735                mp->status ? "enabled" : "disabled",
2736                mp->status ? (char *) mp->locator_set_name : "");
2737     }
2738
2739   vam->retval = retval;
2740   vam->result_ready = 1;
2741 }
2742
2743 static void
2744 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2745                                             mp)
2746 {
2747   vat_main_t *vam = &vat_main;
2748   vat_json_node_t node;
2749   u8 *status = 0;
2750
2751   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2752   vec_add1 (status, 0);
2753
2754   vat_json_init_object (&node);
2755   vat_json_object_add_string_copy (&node, "status", status);
2756   if (mp->status)
2757     {
2758       vat_json_object_add_string_copy (&node, "locator_set",
2759                                        mp->locator_set_name);
2760     }
2761
2762   vec_free (status);
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_policer_type (u8 * s, va_list * va)
2773 {
2774   u32 i = va_arg (*va, u32);
2775
2776   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2777     s = format (s, "1r2c");
2778   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2779     s = format (s, "1r3c");
2780   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2781     s = format (s, "2r3c-2698");
2782   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2783     s = format (s, "2r3c-4115");
2784   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2785     s = format (s, "2r3c-mef5cf1");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_rate_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_RATE_KBPS)
2797     s = format (s, "kbps");
2798   else if (i == SSE2_QOS_RATE_PPS)
2799     s = format (s, "pps");
2800   else
2801     s = format (s, "ILLEGAL");
2802   return s;
2803 }
2804
2805 static u8 *
2806 format_policer_round_type (u8 * s, va_list * va)
2807 {
2808   u32 i = va_arg (*va, u32);
2809
2810   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2811     s = format (s, "closest");
2812   else if (i == SSE2_QOS_ROUND_TO_UP)
2813     s = format (s, "up");
2814   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2815     s = format (s, "down");
2816   else
2817     s = format (s, "ILLEGAL");
2818   return s;
2819 }
2820
2821 static u8 *
2822 format_policer_action_type (u8 * s, va_list * va)
2823 {
2824   u32 i = va_arg (*va, u32);
2825
2826   if (i == SSE2_QOS_ACTION_DROP)
2827     s = format (s, "drop");
2828   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2829     s = format (s, "transmit");
2830   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2831     s = format (s, "mark-and-transmit");
2832   else
2833     s = format (s, "ILLEGAL");
2834   return s;
2835 }
2836
2837 static u8 *
2838 format_dscp (u8 * s, va_list * va)
2839 {
2840   u32 i = va_arg (*va, u32);
2841   char *t = 0;
2842
2843   switch (i)
2844     {
2845 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2846       foreach_vnet_dscp
2847 #undef _
2848     default:
2849       return format (s, "ILLEGAL");
2850     }
2851   s = format (s, "%s", t);
2852   return s;
2853 }
2854
2855 static void
2856 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2857 {
2858   vat_main_t *vam = &vat_main;
2859   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2860
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2863   else
2864     conform_dscp_str = format (0, "");
2865
2866   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2867     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2868   else
2869     exceed_dscp_str = format (0, "");
2870
2871   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2872     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2873   else
2874     violate_dscp_str = format (0, "");
2875
2876   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2877            "rate type %U, round type %U, %s rate, %s color-aware, "
2878            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2879            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2880            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2881            mp->name,
2882            format_policer_type, mp->type,
2883            ntohl (mp->cir),
2884            ntohl (mp->eir),
2885            clib_net_to_host_u64 (mp->cb),
2886            clib_net_to_host_u64 (mp->eb),
2887            format_policer_rate_type, mp->rate_type,
2888            format_policer_round_type, mp->round_type,
2889            mp->single_rate ? "single" : "dual",
2890            mp->color_aware ? "is" : "not",
2891            ntohl (mp->cir_tokens_per_period),
2892            ntohl (mp->pir_tokens_per_period),
2893            ntohl (mp->scale),
2894            ntohl (mp->current_limit),
2895            ntohl (mp->current_bucket),
2896            ntohl (mp->extended_limit),
2897            ntohl (mp->extended_bucket),
2898            clib_net_to_host_u64 (mp->last_update_time),
2899            format_policer_action_type, mp->conform_action_type,
2900            conform_dscp_str,
2901            format_policer_action_type, mp->exceed_action_type,
2902            exceed_dscp_str,
2903            format_policer_action_type, mp->violate_action_type,
2904            violate_dscp_str);
2905
2906   vec_free (conform_dscp_str);
2907   vec_free (exceed_dscp_str);
2908   vec_free (violate_dscp_str);
2909 }
2910
2911 static void vl_api_policer_details_t_handler_json
2912   (vl_api_policer_details_t * mp)
2913 {
2914   vat_main_t *vam = &vat_main;
2915   vat_json_node_t *node;
2916   u8 *rate_type_str, *round_type_str, *type_str;
2917   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2918
2919   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2920   round_type_str =
2921     format (0, "%U", format_policer_round_type, mp->round_type);
2922   type_str = format (0, "%U", format_policer_type, mp->type);
2923   conform_action_str = format (0, "%U", format_policer_action_type,
2924                                mp->conform_action_type);
2925   exceed_action_str = format (0, "%U", format_policer_action_type,
2926                               mp->exceed_action_type);
2927   violate_action_str = format (0, "%U", format_policer_action_type,
2928                                mp->violate_action_type);
2929
2930   if (VAT_JSON_ARRAY != vam->json_tree.type)
2931     {
2932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2933       vat_json_init_array (&vam->json_tree);
2934     }
2935   node = vat_json_array_add (&vam->json_tree);
2936
2937   vat_json_init_object (node);
2938   vat_json_object_add_string_copy (node, "name", mp->name);
2939   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2940   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2941   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2942   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2943   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2944   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2945   vat_json_object_add_string_copy (node, "type", type_str);
2946   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2947   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2948   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2949   vat_json_object_add_uint (node, "cir_tokens_per_period",
2950                             ntohl (mp->cir_tokens_per_period));
2951   vat_json_object_add_uint (node, "eir_tokens_per_period",
2952                             ntohl (mp->pir_tokens_per_period));
2953   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2954   vat_json_object_add_uint (node, "current_bucket",
2955                             ntohl (mp->current_bucket));
2956   vat_json_object_add_uint (node, "extended_limit",
2957                             ntohl (mp->extended_limit));
2958   vat_json_object_add_uint (node, "extended_bucket",
2959                             ntohl (mp->extended_bucket));
2960   vat_json_object_add_uint (node, "last_update_time",
2961                             ntohl (mp->last_update_time));
2962   vat_json_object_add_string_copy (node, "conform_action",
2963                                    conform_action_str);
2964   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     {
2966       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2967       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2968       vec_free (dscp_str);
2969     }
2970   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2971   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2972     {
2973       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2974       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2975       vec_free (dscp_str);
2976     }
2977   vat_json_object_add_string_copy (node, "violate_action",
2978                                    violate_action_str);
2979   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2980     {
2981       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2982       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2983       vec_free (dscp_str);
2984     }
2985
2986   vec_free (rate_type_str);
2987   vec_free (round_type_str);
2988   vec_free (type_str);
2989   vec_free (conform_action_str);
2990   vec_free (exceed_action_str);
2991   vec_free (violate_action_str);
2992 }
2993
2994 static void
2995 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2996                                            mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   int i, count = ntohl (mp->count);
3000
3001   if (count > 0)
3002     fformat (vam->ofp, "classify table ids (%d) : ", count);
3003   for (i = 0; i < count; i++)
3004     {
3005       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3006       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3007     }
3008   vam->retval = ntohl (mp->retval);
3009   vam->result_ready = 1;
3010 }
3011
3012 static void
3013   vl_api_classify_table_ids_reply_t_handler_json
3014   (vl_api_classify_table_ids_reply_t * mp)
3015 {
3016   vat_main_t *vam = &vat_main;
3017   int i, count = ntohl (mp->count);
3018
3019   if (count > 0)
3020     {
3021       vat_json_node_t node;
3022
3023       vat_json_init_object (&node);
3024       for (i = 0; i < count; i++)
3025         {
3026           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3027         }
3028       vat_json_print (vam->ofp, &node);
3029       vat_json_free (&node);
3030     }
3031   vam->retval = ntohl (mp->retval);
3032   vam->result_ready = 1;
3033 }
3034
3035 static void
3036   vl_api_classify_table_by_interface_reply_t_handler
3037   (vl_api_classify_table_by_interface_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   u32 table_id;
3041
3042   table_id = ntohl (mp->l2_table_id);
3043   if (table_id != ~0)
3044     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3045   else
3046     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3047   table_id = ntohl (mp->ip4_table_id);
3048   if (table_id != ~0)
3049     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3050   else
3051     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3052   table_id = ntohl (mp->ip6_table_id);
3053   if (table_id != ~0)
3054     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3055   else
3056     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3057   vam->retval = ntohl (mp->retval);
3058   vam->result_ready = 1;
3059 }
3060
3061 static void
3062   vl_api_classify_table_by_interface_reply_t_handler_json
3063   (vl_api_classify_table_by_interface_reply_t * mp)
3064 {
3065   vat_main_t *vam = &vat_main;
3066   vat_json_node_t node;
3067
3068   vat_json_init_object (&node);
3069
3070   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3071   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3072   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3073
3074   vat_json_print (vam->ofp, &node);
3075   vat_json_free (&node);
3076
3077   vam->retval = ntohl (mp->retval);
3078   vam->result_ready = 1;
3079 }
3080
3081 static void vl_api_policer_add_del_reply_t_handler
3082   (vl_api_policer_add_del_reply_t * mp)
3083 {
3084   vat_main_t *vam = &vat_main;
3085   i32 retval = ntohl (mp->retval);
3086   if (vam->async_mode)
3087     {
3088       vam->async_errors += (retval < 0);
3089     }
3090   else
3091     {
3092       vam->retval = retval;
3093       vam->result_ready = 1;
3094       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3095         /*
3096          * Note: this is just barely thread-safe, depends on
3097          * the main thread spinning waiting for an answer...
3098          */
3099         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3100     }
3101 }
3102
3103 static void vl_api_policer_add_del_reply_t_handler_json
3104   (vl_api_policer_add_del_reply_t * mp)
3105 {
3106   vat_main_t *vam = &vat_main;
3107   vat_json_node_t node;
3108
3109   vat_json_init_object (&node);
3110   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3111   vat_json_object_add_uint (&node, "policer_index",
3112                             ntohl (mp->policer_index));
3113
3114   vat_json_print (vam->ofp, &node);
3115   vat_json_free (&node);
3116
3117   vam->retval = ntohl (mp->retval);
3118   vam->result_ready = 1;
3119 }
3120
3121 /* Format hex dump. */
3122 u8 *
3123 format_hex_bytes (u8 * s, va_list * va)
3124 {
3125   u8 *bytes = va_arg (*va, u8 *);
3126   int n_bytes = va_arg (*va, int);
3127   uword i;
3128
3129   /* Print short or long form depending on byte count. */
3130   uword short_form = n_bytes <= 32;
3131   uword indent = format_get_indent (s);
3132
3133   if (n_bytes == 0)
3134     return s;
3135
3136   for (i = 0; i < n_bytes; i++)
3137     {
3138       if (!short_form && (i % 32) == 0)
3139         s = format (s, "%08x: ", i);
3140       s = format (s, "%02x", bytes[i]);
3141       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3142         s = format (s, "\n%U", format_white_space, indent);
3143     }
3144
3145   return s;
3146 }
3147
3148 static void
3149 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3150                                             * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   i32 retval = ntohl (mp->retval);
3154   if (retval == 0)
3155     {
3156       fformat (vam->ofp, "classify table info :\n");
3157       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3158                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3159                ntohl (mp->miss_next_index));
3160       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3161                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3162                ntohl (mp->match_n_vectors));
3163       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3164                ntohl (mp->mask_length));
3165     }
3166   vam->retval = retval;
3167   vam->result_ready = 1;
3168 }
3169
3170 static void
3171   vl_api_classify_table_info_reply_t_handler_json
3172   (vl_api_classify_table_info_reply_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t node;
3176
3177   i32 retval = ntohl (mp->retval);
3178   if (retval == 0)
3179     {
3180       vat_json_init_object (&node);
3181
3182       vat_json_object_add_int (&node, "sessions",
3183                                ntohl (mp->active_sessions));
3184       vat_json_object_add_int (&node, "nexttbl",
3185                                ntohl (mp->next_table_index));
3186       vat_json_object_add_int (&node, "nextnode",
3187                                ntohl (mp->miss_next_index));
3188       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3189       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3190       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3191       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3192                       ntohl (mp->mask_length), 0);
3193       vat_json_object_add_string_copy (&node, "mask", s);
3194
3195       vat_json_print (vam->ofp, &node);
3196       vat_json_free (&node);
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3204                                            mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207
3208   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3209            ntohl (mp->hit_next_index), ntohl (mp->advance),
3210            ntohl (mp->opaque_index));
3211   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3212            ntohl (mp->match_length));
3213 }
3214
3215 static void
3216   vl_api_classify_session_details_t_handler_json
3217   (vl_api_classify_session_details_t * mp)
3218 {
3219   vat_main_t *vam = &vat_main;
3220   vat_json_node_t *node = NULL;
3221
3222   if (VAT_JSON_ARRAY != vam->json_tree.type)
3223     {
3224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3225       vat_json_init_array (&vam->json_tree);
3226     }
3227   node = vat_json_array_add (&vam->json_tree);
3228
3229   vat_json_init_object (node);
3230   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3231   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3232   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3233   u8 *s =
3234     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3235             0);
3236   vat_json_object_add_string_copy (node, "match", s);
3237 }
3238
3239 static void vl_api_pg_create_interface_reply_t_handler
3240   (vl_api_pg_create_interface_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243
3244   vam->retval = ntohl (mp->retval);
3245   vam->result_ready = 1;
3246 }
3247
3248 static void vl_api_pg_create_interface_reply_t_handler_json
3249   (vl_api_pg_create_interface_reply_t * mp)
3250 {
3251   vat_main_t *vam = &vat_main;
3252   vat_json_node_t node;
3253
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       vat_json_init_object (&node);
3258
3259       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3260
3261       vat_json_print (vam->ofp, &node);
3262       vat_json_free (&node);
3263     }
3264   vam->retval = ntohl (mp->retval);
3265   vam->result_ready = 1;
3266 }
3267
3268 static void vl_api_policer_classify_details_t_handler
3269   (vl_api_policer_classify_details_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272
3273   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3274            ntohl (mp->table_index));
3275 }
3276
3277 static void vl_api_policer_classify_details_t_handler_json
3278   (vl_api_policer_classify_details_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t *node;
3282
3283   if (VAT_JSON_ARRAY != vam->json_tree.type)
3284     {
3285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3286       vat_json_init_array (&vam->json_tree);
3287     }
3288   node = vat_json_array_add (&vam->json_tree);
3289
3290   vat_json_init_object (node);
3291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3292   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3293 }
3294
3295 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3296   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   i32 retval = ntohl (mp->retval);
3300   if (vam->async_mode)
3301     {
3302       vam->async_errors += (retval < 0);
3303     }
3304   else
3305     {
3306       vam->retval = retval;
3307       vam->sw_if_index = ntohl (mp->sw_if_index);
3308       vam->result_ready = 1;
3309     }
3310 }
3311
3312 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3313   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t node;
3317
3318   vat_json_init_object (&node);
3319   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3320   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3321
3322   vat_json_print (vam->ofp, &node);
3323   vat_json_free (&node);
3324
3325   vam->retval = ntohl (mp->retval);
3326   vam->result_ready = 1;
3327 }
3328
3329 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3330 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3331 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3332 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3333
3334 /*
3335  * Generate boilerplate reply handlers, which
3336  * dig the return value out of the xxx_reply_t API message,
3337  * stick it into vam->retval, and set vam->result_ready
3338  *
3339  * Could also do this by pointing N message decode slots at
3340  * a single function, but that could break in subtle ways.
3341  */
3342
3343 #define foreach_standard_reply_retval_handler           \
3344 _(sw_interface_set_flags_reply)                         \
3345 _(sw_interface_add_del_address_reply)                   \
3346 _(sw_interface_set_table_reply)                         \
3347 _(sw_interface_set_vpath_reply)                         \
3348 _(sw_interface_set_l2_bridge_reply)                     \
3349 _(bridge_domain_add_del_reply)                          \
3350 _(sw_interface_set_l2_xconnect_reply)                   \
3351 _(l2fib_add_del_reply)                                  \
3352 _(ip_add_del_route_reply)                               \
3353 _(proxy_arp_add_del_reply)                              \
3354 _(proxy_arp_intfc_enable_disable_reply)                 \
3355 _(mpls_add_del_encap_reply)                             \
3356 _(mpls_add_del_decap_reply)                             \
3357 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3358 _(sw_interface_set_unnumbered_reply)                    \
3359 _(ip_neighbor_add_del_reply)                            \
3360 _(reset_vrf_reply)                                      \
3361 _(oam_add_del_reply)                                    \
3362 _(reset_fib_reply)                                      \
3363 _(dhcp_proxy_config_reply)                              \
3364 _(dhcp_proxy_config_2_reply)                            \
3365 _(dhcp_proxy_set_vss_reply)                             \
3366 _(dhcp_client_config_reply)                             \
3367 _(set_ip_flow_hash_reply)                               \
3368 _(sw_interface_ip6_enable_disable_reply)                \
3369 _(sw_interface_ip6_set_link_local_address_reply)        \
3370 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3371 _(sw_interface_ip6nd_ra_config_reply)                   \
3372 _(set_arp_neighbor_limit_reply)                         \
3373 _(l2_patch_add_del_reply)                               \
3374 _(sr_tunnel_add_del_reply)                              \
3375 _(sr_policy_add_del_reply)                              \
3376 _(sr_multicast_map_add_del_reply)                       \
3377 _(classify_add_del_session_reply)                       \
3378 _(classify_set_interface_ip_table_reply)                \
3379 _(classify_set_interface_l2_tables_reply)               \
3380 _(l2tpv3_set_tunnel_cookies_reply)                      \
3381 _(l2tpv3_interface_enable_disable_reply)                \
3382 _(l2tpv3_set_lookup_key_reply)                          \
3383 _(l2_fib_clear_table_reply)                             \
3384 _(l2_interface_efp_filter_reply)                        \
3385 _(l2_interface_vlan_tag_rewrite_reply)                  \
3386 _(modify_vhost_user_if_reply)                           \
3387 _(delete_vhost_user_if_reply)                           \
3388 _(want_ip4_arp_events_reply)                            \
3389 _(want_ip6_nd_events_reply)                             \
3390 _(input_acl_set_interface_reply)                        \
3391 _(ipsec_spd_add_del_reply)                              \
3392 _(ipsec_interface_add_del_spd_reply)                    \
3393 _(ipsec_spd_add_del_entry_reply)                        \
3394 _(ipsec_sad_add_del_entry_reply)                        \
3395 _(ipsec_sa_set_key_reply)                               \
3396 _(ikev2_profile_add_del_reply)                          \
3397 _(ikev2_profile_set_auth_reply)                         \
3398 _(ikev2_profile_set_id_reply)                           \
3399 _(ikev2_profile_set_ts_reply)                           \
3400 _(ikev2_set_local_key_reply)                            \
3401 _(delete_loopback_reply)                                \
3402 _(bd_ip_mac_add_del_reply)                              \
3403 _(map_del_domain_reply)                                 \
3404 _(map_add_del_rule_reply)                               \
3405 _(want_interface_events_reply)                          \
3406 _(want_stats_reply)                                     \
3407 _(cop_interface_enable_disable_reply)                   \
3408 _(cop_whitelist_enable_disable_reply)                   \
3409 _(sw_interface_clear_stats_reply)                       \
3410 _(ioam_enable_reply)                              \
3411 _(ioam_disable_reply)                              \
3412 _(lisp_add_del_locator_reply)                           \
3413 _(lisp_add_del_local_eid_reply)                         \
3414 _(lisp_add_del_remote_mapping_reply)                    \
3415 _(lisp_add_del_adjacency_reply)                         \
3416 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3417 _(lisp_add_del_map_resolver_reply)                      \
3418 _(lisp_gpe_enable_disable_reply)                        \
3419 _(lisp_gpe_add_del_iface_reply)                         \
3420 _(lisp_enable_disable_reply)                            \
3421 _(lisp_pitr_set_locator_set_reply)                      \
3422 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3423 _(lisp_eid_table_add_del_map_reply)                     \
3424 _(vxlan_gpe_add_del_tunnel_reply)                       \
3425 _(af_packet_delete_reply)                               \
3426 _(policer_classify_set_interface_reply)                 \
3427 _(netmap_create_reply)                                  \
3428 _(netmap_delete_reply)                                  \
3429 _(set_ipfix_exporter_reply)                             \
3430 _(set_ipfix_classify_stream_reply)                      \
3431 _(ipfix_classify_table_add_del_reply)                   \
3432 _(pg_capture_reply)                                     \
3433 _(pg_enable_disable_reply)                              \
3434 _(ip_source_and_port_range_check_add_del_reply)         \
3435 _(ip_source_and_port_range_check_interface_add_del_reply)\
3436 _(delete_subif_reply)
3437
3438 #define _(n)                                    \
3439     static void vl_api_##n##_t_handler          \
3440     (vl_api_##n##_t * mp)                       \
3441     {                                           \
3442         vat_main_t * vam = &vat_main;           \
3443         i32 retval = ntohl(mp->retval);         \
3444         if (vam->async_mode) {                  \
3445             vam->async_errors += (retval < 0);  \
3446         } else {                                \
3447             vam->retval = retval;               \
3448             vam->result_ready = 1;              \
3449         }                                       \
3450     }
3451 foreach_standard_reply_retval_handler;
3452 #undef _
3453
3454 #define _(n)                                    \
3455     static void vl_api_##n##_t_handler_json     \
3456     (vl_api_##n##_t * mp)                       \
3457     {                                           \
3458         vat_main_t * vam = &vat_main;           \
3459         vat_json_node_t node;                   \
3460         vat_json_init_object(&node);            \
3461         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3462         vat_json_print(vam->ofp, &node);        \
3463         vam->retval = ntohl(mp->retval);        \
3464         vam->result_ready = 1;                  \
3465     }
3466 foreach_standard_reply_retval_handler;
3467 #undef _
3468
3469 /*
3470  * Table of message reply handlers, must include boilerplate handlers
3471  * we just generated
3472  */
3473
3474 #define foreach_vpe_api_reply_msg                                       \
3475 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3476 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3477 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3478 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3479 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3480 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3481 _(CLI_REPLY, cli_reply)                                                 \
3482 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3483 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3484   sw_interface_add_del_address_reply)                                   \
3485 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3486 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3487 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3488   sw_interface_set_l2_xconnect_reply)                                   \
3489 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3490   sw_interface_set_l2_bridge_reply)                                     \
3491 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3492 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3493 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3494 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3495 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3496 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3497 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3498 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3499 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3500 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3501 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3502 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3503 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3504   proxy_arp_intfc_enable_disable_reply)                                 \
3505 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3506 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3507 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3508 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3509   mpls_ethernet_add_del_tunnel_reply)                                   \
3510 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3511   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3512 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3513   sw_interface_set_unnumbered_reply)                                    \
3514 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3515 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3516 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3517 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3518 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3519 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3520 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3521 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3522 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3523 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3524 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3525 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3526   sw_interface_ip6_enable_disable_reply)                                \
3527 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3528   sw_interface_ip6_set_link_local_address_reply)                        \
3529 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3530   sw_interface_ip6nd_ra_prefix_reply)                                   \
3531 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3532   sw_interface_ip6nd_ra_config_reply)                                   \
3533 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3534 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3535 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3536 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3537 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3538 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3539 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3540 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3541 classify_set_interface_ip_table_reply)                                  \
3542 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3543   classify_set_interface_l2_tables_reply)                               \
3544 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3545 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3546 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3547 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3548 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3549   l2tpv3_interface_enable_disable_reply)                                \
3550 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3551 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3552 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3553 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3554 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3555 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3556 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3557 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3558 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3559 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3560 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3561 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3562 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3563 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3564 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3565 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3566 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3567 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3568 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3569 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3570 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3571 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3572 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3573 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3574 _(IP_DETAILS, ip_details)                                               \
3575 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3576 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3577 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3578 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3579 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3580 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3581 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3582 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3583 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3584 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3585 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3586 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3587 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3588 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3589 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3590 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3591 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3592 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3593 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3594 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3595 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3596 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3597 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3598 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3599 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3600 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3601 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3602 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3603 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3604 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3605 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3606 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3607 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3608 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3609 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3610 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3611 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3612 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3613 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3614 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3615 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3616 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3617 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3618 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3619 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3620 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3621 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3622 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3623 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3624 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3625 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3626   lisp_add_del_map_request_itr_rlocs_reply)                             \
3627 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3628   lisp_get_map_request_itr_rlocs_reply)                                 \
3629 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3630 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3631 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3632 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3633 _(POLICER_DETAILS, policer_details)                                     \
3634 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3635 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3636 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3637 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3638 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3639 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3640 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3641 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3642 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3643 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3644 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3645 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3646 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3647 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3648 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3649 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3650 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3651 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3652 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3653 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3654 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3655 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3656 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3657  ip_source_and_port_range_check_add_del_reply)                          \
3658 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3659  ip_source_and_port_range_check_interface_add_del_reply)                \
3660 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3661 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3662 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3663
3664 /* M: construct, but don't yet send a message */
3665
3666 #define M(T,t)                                  \
3667 do {                                            \
3668     vam->result_ready = 0;                      \
3669     mp = vl_msg_api_alloc(sizeof(*mp));         \
3670     memset (mp, 0, sizeof (*mp));               \
3671     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3672     mp->client_index = vam->my_client_index;    \
3673 } while(0);
3674
3675 #define M2(T,t,n)                               \
3676 do {                                            \
3677     vam->result_ready = 0;                      \
3678     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3679     memset (mp, 0, sizeof (*mp));               \
3680     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3681     mp->client_index = vam->my_client_index;    \
3682 } while(0);
3683
3684
3685 /* S: send a message */
3686 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3687
3688 /* W: wait for results, with timeout */
3689 #define W                                       \
3690 do {                                            \
3691     timeout = vat_time_now (vam) + 1.0;         \
3692                                                 \
3693     while (vat_time_now (vam) < timeout) {      \
3694         if (vam->result_ready == 1) {           \
3695             return (vam->retval);               \
3696         }                                       \
3697     }                                           \
3698     return -99;                                 \
3699 } while(0);
3700
3701 /* W2: wait for results, with timeout */
3702 #define W2(body)                                \
3703 do {                                            \
3704     timeout = vat_time_now (vam) + 1.0;         \
3705                                                 \
3706     while (vat_time_now (vam) < timeout) {      \
3707         if (vam->result_ready == 1) {           \
3708           (body);                               \
3709           return (vam->retval);                 \
3710         }                                       \
3711     }                                           \
3712     return -99;                                 \
3713 } while(0);
3714
3715 /* W_L: wait for results, with timeout */
3716 #define W_L(body)                               \
3717 do {                                            \
3718     timeout = vat_time_now (vam) + 1.0;         \
3719                                                 \
3720     while (vat_time_now (vam) < timeout) {      \
3721         if (vam->result_ready == 1) {           \
3722           (body);                               \
3723           return (vam->retval);                 \
3724         }                                       \
3725     }                                           \
3726     vam->noprint_msg = 0;     \
3727     return -99;                                 \
3728 } while(0);
3729
3730 typedef struct
3731 {
3732   u8 *name;
3733   u32 value;
3734 } name_sort_t;
3735
3736
3737 #define STR_VTR_OP_CASE(op)     \
3738     case L2_VTR_ ## op:         \
3739         return "" # op;
3740
3741 static const char *
3742 str_vtr_op (u32 vtr_op)
3743 {
3744   switch (vtr_op)
3745     {
3746       STR_VTR_OP_CASE (DISABLED);
3747       STR_VTR_OP_CASE (PUSH_1);
3748       STR_VTR_OP_CASE (PUSH_2);
3749       STR_VTR_OP_CASE (POP_1);
3750       STR_VTR_OP_CASE (POP_2);
3751       STR_VTR_OP_CASE (TRANSLATE_1_1);
3752       STR_VTR_OP_CASE (TRANSLATE_1_2);
3753       STR_VTR_OP_CASE (TRANSLATE_2_1);
3754       STR_VTR_OP_CASE (TRANSLATE_2_2);
3755     }
3756
3757   return "UNKNOWN";
3758 }
3759
3760 static int
3761 dump_sub_interface_table (vat_main_t * vam)
3762 {
3763   const sw_interface_subif_t *sub = NULL;
3764
3765   if (vam->json_output)
3766     {
3767       clib_warning
3768         ("JSON output supported only for VPE API calls and dump_stats_table");
3769       return -99;
3770     }
3771
3772   fformat (vam->ofp,
3773            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3774            "Interface", "sw_if_index",
3775            "sub id", "dot1ad", "tags", "outer id",
3776            "inner id", "exact", "default", "outer any", "inner any");
3777
3778   vec_foreach (sub, vam->sw_if_subif_table)
3779   {
3780     fformat (vam->ofp,
3781              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3782              sub->interface_name,
3783              sub->sw_if_index,
3784              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3785              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3786              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3787              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3788     if (sub->vtr_op != L2_VTR_DISABLED)
3789       {
3790         fformat (vam->ofp,
3791                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3792                  "tag1: %d tag2: %d ]\n",
3793                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3794                  sub->vtr_tag1, sub->vtr_tag2);
3795       }
3796   }
3797
3798   return 0;
3799 }
3800
3801 static int
3802 name_sort_cmp (void *a1, void *a2)
3803 {
3804   name_sort_t *n1 = a1;
3805   name_sort_t *n2 = a2;
3806
3807   return strcmp ((char *) n1->name, (char *) n2->name);
3808 }
3809
3810 static int
3811 dump_interface_table (vat_main_t * vam)
3812 {
3813   hash_pair_t *p;
3814   name_sort_t *nses = 0, *ns;
3815
3816   if (vam->json_output)
3817     {
3818       clib_warning
3819         ("JSON output supported only for VPE API calls and dump_stats_table");
3820       return -99;
3821     }
3822
3823   /* *INDENT-OFF* */
3824   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3825   ({
3826     vec_add2 (nses, ns, 1);
3827     ns->name = (u8 *)(p->key);
3828     ns->value = (u32) p->value[0];
3829   }));
3830   /* *INDENT-ON* */
3831
3832   vec_sort_with_function (nses, name_sort_cmp);
3833
3834   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3835   vec_foreach (ns, nses)
3836   {
3837     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3838   }
3839   vec_free (nses);
3840   return 0;
3841 }
3842
3843 static int
3844 dump_ip_table (vat_main_t * vam, int is_ipv6)
3845 {
3846   const ip_details_t *det = NULL;
3847   const ip_address_details_t *address = NULL;
3848   u32 i = ~0;
3849
3850   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3851
3852   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3853   {
3854     i++;
3855     if (!det->present)
3856       {
3857         continue;
3858       }
3859     fformat (vam->ofp, "%-12d\n", i);
3860     fformat (vam->ofp,
3861              "            %-30s%-13s\n", "Address", "Prefix length");
3862     if (!det->addr)
3863       {
3864         continue;
3865       }
3866     vec_foreach (address, det->addr)
3867     {
3868       fformat (vam->ofp,
3869                "            %-30U%-13d\n",
3870                is_ipv6 ? format_ip6_address : format_ip4_address,
3871                address->ip, address->prefix_length);
3872     }
3873   }
3874
3875   return 0;
3876 }
3877
3878 static int
3879 dump_ipv4_table (vat_main_t * vam)
3880 {
3881   if (vam->json_output)
3882     {
3883       clib_warning
3884         ("JSON output supported only for VPE API calls and dump_stats_table");
3885       return -99;
3886     }
3887
3888   return dump_ip_table (vam, 0);
3889 }
3890
3891 static int
3892 dump_ipv6_table (vat_main_t * vam)
3893 {
3894   if (vam->json_output)
3895     {
3896       clib_warning
3897         ("JSON output supported only for VPE API calls and dump_stats_table");
3898       return -99;
3899     }
3900
3901   return dump_ip_table (vam, 1);
3902 }
3903
3904 static char *
3905 counter_type_to_str (u8 counter_type, u8 is_combined)
3906 {
3907   if (!is_combined)
3908     {
3909       switch (counter_type)
3910         {
3911         case VNET_INTERFACE_COUNTER_DROP:
3912           return "drop";
3913         case VNET_INTERFACE_COUNTER_PUNT:
3914           return "punt";
3915         case VNET_INTERFACE_COUNTER_IP4:
3916           return "ip4";
3917         case VNET_INTERFACE_COUNTER_IP6:
3918           return "ip6";
3919         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3920           return "rx-no-buf";
3921         case VNET_INTERFACE_COUNTER_RX_MISS:
3922           return "rx-miss";
3923         case VNET_INTERFACE_COUNTER_RX_ERROR:
3924           return "rx-error";
3925         case VNET_INTERFACE_COUNTER_TX_ERROR:
3926           return "tx-error";
3927         default:
3928           return "INVALID-COUNTER-TYPE";
3929         }
3930     }
3931   else
3932     {
3933       switch (counter_type)
3934         {
3935         case VNET_INTERFACE_COUNTER_RX:
3936           return "rx";
3937         case VNET_INTERFACE_COUNTER_TX:
3938           return "tx";
3939         default:
3940           return "INVALID-COUNTER-TYPE";
3941         }
3942     }
3943 }
3944
3945 static int
3946 dump_stats_table (vat_main_t * vam)
3947 {
3948   vat_json_node_t node;
3949   vat_json_node_t *msg_array;
3950   vat_json_node_t *msg;
3951   vat_json_node_t *counter_array;
3952   vat_json_node_t *counter;
3953   interface_counter_t c;
3954   u64 packets;
3955   ip4_fib_counter_t *c4;
3956   ip6_fib_counter_t *c6;
3957   int i, j;
3958
3959   if (!vam->json_output)
3960     {
3961       clib_warning ("dump_stats_table supported only in JSON format");
3962       return -99;
3963     }
3964
3965   vat_json_init_object (&node);
3966
3967   /* interface counters */
3968   msg_array = vat_json_object_add (&node, "interface_counters");
3969   vat_json_init_array (msg_array);
3970   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3971     {
3972       msg = vat_json_array_add (msg_array);
3973       vat_json_init_object (msg);
3974       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3975                                        (u8 *) counter_type_to_str (i, 0));
3976       vat_json_object_add_int (msg, "is_combined", 0);
3977       counter_array = vat_json_object_add (msg, "data");
3978       vat_json_init_array (counter_array);
3979       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3980         {
3981           packets = vam->simple_interface_counters[i][j];
3982           vat_json_array_add_uint (counter_array, packets);
3983         }
3984     }
3985   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3986     {
3987       msg = vat_json_array_add (msg_array);
3988       vat_json_init_object (msg);
3989       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3990                                        (u8 *) counter_type_to_str (i, 1));
3991       vat_json_object_add_int (msg, "is_combined", 1);
3992       counter_array = vat_json_object_add (msg, "data");
3993       vat_json_init_array (counter_array);
3994       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3995         {
3996           c = vam->combined_interface_counters[i][j];
3997           counter = vat_json_array_add (counter_array);
3998           vat_json_init_object (counter);
3999           vat_json_object_add_uint (counter, "packets", c.packets);
4000           vat_json_object_add_uint (counter, "bytes", c.bytes);
4001         }
4002     }
4003
4004   /* ip4 fib counters */
4005   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4006   vat_json_init_array (msg_array);
4007   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4008     {
4009       msg = vat_json_array_add (msg_array);
4010       vat_json_init_object (msg);
4011       vat_json_object_add_uint (msg, "vrf_id",
4012                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4013       counter_array = vat_json_object_add (msg, "c");
4014       vat_json_init_array (counter_array);
4015       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4016         {
4017           counter = vat_json_array_add (counter_array);
4018           vat_json_init_object (counter);
4019           c4 = &vam->ip4_fib_counters[i][j];
4020           vat_json_object_add_ip4 (counter, "address", c4->address);
4021           vat_json_object_add_uint (counter, "address_length",
4022                                     c4->address_length);
4023           vat_json_object_add_uint (counter, "packets", c4->packets);
4024           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4025         }
4026     }
4027
4028   /* ip6 fib counters */
4029   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4030   vat_json_init_array (msg_array);
4031   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4032     {
4033       msg = vat_json_array_add (msg_array);
4034       vat_json_init_object (msg);
4035       vat_json_object_add_uint (msg, "vrf_id",
4036                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4037       counter_array = vat_json_object_add (msg, "c");
4038       vat_json_init_array (counter_array);
4039       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4040         {
4041           counter = vat_json_array_add (counter_array);
4042           vat_json_init_object (counter);
4043           c6 = &vam->ip6_fib_counters[i][j];
4044           vat_json_object_add_ip6 (counter, "address", c6->address);
4045           vat_json_object_add_uint (counter, "address_length",
4046                                     c6->address_length);
4047           vat_json_object_add_uint (counter, "packets", c6->packets);
4048           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4049         }
4050     }
4051
4052   vat_json_print (vam->ofp, &node);
4053   vat_json_free (&node);
4054
4055   return 0;
4056 }
4057
4058 int
4059 exec (vat_main_t * vam)
4060 {
4061   api_main_t *am = &api_main;
4062   vl_api_cli_request_t *mp;
4063   f64 timeout;
4064   void *oldheap;
4065   u8 *cmd = 0;
4066   unformat_input_t *i = vam->input;
4067
4068   if (vec_len (i->buffer) == 0)
4069     return -1;
4070
4071   if (vam->exec_mode == 0 && unformat (i, "mode"))
4072     {
4073       vam->exec_mode = 1;
4074       return 0;
4075     }
4076   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4077     {
4078       vam->exec_mode = 0;
4079       return 0;
4080     }
4081
4082
4083   M (CLI_REQUEST, cli_request);
4084
4085   /*
4086    * Copy cmd into shared memory.
4087    * In order for the CLI command to work, it
4088    * must be a vector ending in \n, not a C-string ending
4089    * in \n\0.
4090    */
4091   pthread_mutex_lock (&am->vlib_rp->mutex);
4092   oldheap = svm_push_data_heap (am->vlib_rp);
4093
4094   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4095   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4096
4097   svm_pop_heap (oldheap);
4098   pthread_mutex_unlock (&am->vlib_rp->mutex);
4099
4100   mp->cmd_in_shmem = (u64) cmd;
4101   S;
4102   timeout = vat_time_now (vam) + 10.0;
4103
4104   while (vat_time_now (vam) < timeout)
4105     {
4106       if (vam->result_ready == 1)
4107         {
4108           u8 *free_me;
4109           if (vam->shmem_result != NULL)
4110             fformat (vam->ofp, "%s", vam->shmem_result);
4111           pthread_mutex_lock (&am->vlib_rp->mutex);
4112           oldheap = svm_push_data_heap (am->vlib_rp);
4113
4114           free_me = (u8 *) vam->shmem_result;
4115           vec_free (free_me);
4116
4117           svm_pop_heap (oldheap);
4118           pthread_mutex_unlock (&am->vlib_rp->mutex);
4119           return 0;
4120         }
4121     }
4122   return -99;
4123 }
4124
4125 /*
4126  * Future replacement of exec() that passes CLI buffers directly in
4127  * the API messages instead of an additional shared memory area.
4128  */
4129 static int
4130 exec_inband (vat_main_t * vam)
4131 {
4132   vl_api_cli_inband_t *mp;
4133   f64 timeout;
4134   unformat_input_t *i = vam->input;
4135
4136   if (vec_len (i->buffer) == 0)
4137     return -1;
4138
4139   if (vam->exec_mode == 0 && unformat (i, "mode"))
4140     {
4141       vam->exec_mode = 1;
4142       return 0;
4143     }
4144   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4145     {
4146       vam->exec_mode = 0;
4147       return 0;
4148     }
4149
4150   /*
4151    * In order for the CLI command to work, it
4152    * must be a vector ending in \n, not a C-string ending
4153    * in \n\0.
4154    */
4155   u32 len = vec_len (vam->input->buffer);
4156   M2 (CLI_INBAND, cli_inband, len);
4157   clib_memcpy (mp->cmd, vam->input->buffer, len);
4158   mp->length = htonl (len);
4159
4160   S;
4161   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4162 }
4163
4164 static int
4165 api_create_loopback (vat_main_t * vam)
4166 {
4167   unformat_input_t *i = vam->input;
4168   vl_api_create_loopback_t *mp;
4169   f64 timeout;
4170   u8 mac_address[6];
4171   u8 mac_set = 0;
4172
4173   memset (mac_address, 0, sizeof (mac_address));
4174
4175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4176     {
4177       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4178         mac_set = 1;
4179       else
4180         break;
4181     }
4182
4183   /* Construct the API message */
4184   M (CREATE_LOOPBACK, create_loopback);
4185   if (mac_set)
4186     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4187
4188   S;
4189   W;
4190 }
4191
4192 static int
4193 api_delete_loopback (vat_main_t * vam)
4194 {
4195   unformat_input_t *i = vam->input;
4196   vl_api_delete_loopback_t *mp;
4197   f64 timeout;
4198   u32 sw_if_index = ~0;
4199
4200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4201     {
4202       if (unformat (i, "sw_if_index %d", &sw_if_index))
4203         ;
4204       else
4205         break;
4206     }
4207
4208   if (sw_if_index == ~0)
4209     {
4210       errmsg ("missing sw_if_index\n");
4211       return -99;
4212     }
4213
4214   /* Construct the API message */
4215   M (DELETE_LOOPBACK, delete_loopback);
4216   mp->sw_if_index = ntohl (sw_if_index);
4217
4218   S;
4219   W;
4220 }
4221
4222 static int
4223 api_want_stats (vat_main_t * vam)
4224 {
4225   unformat_input_t *i = vam->input;
4226   vl_api_want_stats_t *mp;
4227   f64 timeout;
4228   int enable = -1;
4229
4230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4231     {
4232       if (unformat (i, "enable"))
4233         enable = 1;
4234       else if (unformat (i, "disable"))
4235         enable = 0;
4236       else
4237         break;
4238     }
4239
4240   if (enable == -1)
4241     {
4242       errmsg ("missing enable|disable\n");
4243       return -99;
4244     }
4245
4246   M (WANT_STATS, want_stats);
4247   mp->enable_disable = enable;
4248
4249   S;
4250   W;
4251 }
4252
4253 static int
4254 api_want_interface_events (vat_main_t * vam)
4255 {
4256   unformat_input_t *i = vam->input;
4257   vl_api_want_interface_events_t *mp;
4258   f64 timeout;
4259   int enable = -1;
4260
4261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4262     {
4263       if (unformat (i, "enable"))
4264         enable = 1;
4265       else if (unformat (i, "disable"))
4266         enable = 0;
4267       else
4268         break;
4269     }
4270
4271   if (enable == -1)
4272     {
4273       errmsg ("missing enable|disable\n");
4274       return -99;
4275     }
4276
4277   M (WANT_INTERFACE_EVENTS, want_interface_events);
4278   mp->enable_disable = enable;
4279
4280   vam->interface_event_display = enable;
4281
4282   S;
4283   W;
4284 }
4285
4286
4287 /* Note: non-static, called once to set up the initial intfc table */
4288 int
4289 api_sw_interface_dump (vat_main_t * vam)
4290 {
4291   vl_api_sw_interface_dump_t *mp;
4292   f64 timeout;
4293   hash_pair_t *p;
4294   name_sort_t *nses = 0, *ns;
4295   sw_interface_subif_t *sub = NULL;
4296
4297   /* Toss the old name table */
4298   /* *INDENT-OFF* */
4299   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4300   ({
4301     vec_add2 (nses, ns, 1);
4302     ns->name = (u8 *)(p->key);
4303     ns->value = (u32) p->value[0];
4304   }));
4305   /* *INDENT-ON* */
4306
4307   hash_free (vam->sw_if_index_by_interface_name);
4308
4309   vec_foreach (ns, nses) vec_free (ns->name);
4310
4311   vec_free (nses);
4312
4313   vec_foreach (sub, vam->sw_if_subif_table)
4314   {
4315     vec_free (sub->interface_name);
4316   }
4317   vec_free (vam->sw_if_subif_table);
4318
4319   /* recreate the interface name hash table */
4320   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4321
4322   /* Get list of ethernets */
4323   M (SW_INTERFACE_DUMP, sw_interface_dump);
4324   mp->name_filter_valid = 1;
4325   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4326   S;
4327
4328   /* and local / loopback interfaces */
4329   M (SW_INTERFACE_DUMP, sw_interface_dump);
4330   mp->name_filter_valid = 1;
4331   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4332   S;
4333
4334
4335   /* and vxlan-gpe tunnel interfaces */
4336   M (SW_INTERFACE_DUMP, sw_interface_dump);
4337   mp->name_filter_valid = 1;
4338   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4339            sizeof (mp->name_filter) - 1);
4340   S;
4341
4342   /* and vxlan tunnel interfaces */
4343   M (SW_INTERFACE_DUMP, sw_interface_dump);
4344   mp->name_filter_valid = 1;
4345   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4346   S;
4347
4348   /* and host (af_packet) interfaces */
4349   M (SW_INTERFACE_DUMP, sw_interface_dump);
4350   mp->name_filter_valid = 1;
4351   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4352   S;
4353
4354   /* and l2tpv3 tunnel interfaces */
4355   M (SW_INTERFACE_DUMP, sw_interface_dump);
4356   mp->name_filter_valid = 1;
4357   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4358            sizeof (mp->name_filter) - 1);
4359   S;
4360
4361   /* and GRE tunnel interfaces */
4362   M (SW_INTERFACE_DUMP, sw_interface_dump);
4363   mp->name_filter_valid = 1;
4364   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4365   S;
4366
4367   /* and LISP-GPE interfaces */
4368   M (SW_INTERFACE_DUMP, sw_interface_dump);
4369   mp->name_filter_valid = 1;
4370   strncpy ((char *) mp->name_filter, "lisp_gpe",
4371            sizeof (mp->name_filter) - 1);
4372   S;
4373
4374   /* and IPSEC tunnel interfaces */
4375   M (SW_INTERFACE_DUMP, sw_interface_dump);
4376   mp->name_filter_valid = 1;
4377   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4378   S;
4379
4380   /* Use a control ping for synchronization */
4381   {
4382     vl_api_control_ping_t *mp;
4383     M (CONTROL_PING, control_ping);
4384     S;
4385   }
4386   W;
4387 }
4388
4389 static int
4390 api_sw_interface_set_flags (vat_main_t * vam)
4391 {
4392   unformat_input_t *i = vam->input;
4393   vl_api_sw_interface_set_flags_t *mp;
4394   f64 timeout;
4395   u32 sw_if_index;
4396   u8 sw_if_index_set = 0;
4397   u8 admin_up = 0, link_up = 0;
4398
4399   /* Parse args required to build the message */
4400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4401     {
4402       if (unformat (i, "admin-up"))
4403         admin_up = 1;
4404       else if (unformat (i, "admin-down"))
4405         admin_up = 0;
4406       else if (unformat (i, "link-up"))
4407         link_up = 1;
4408       else if (unformat (i, "link-down"))
4409         link_up = 0;
4410       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4411         sw_if_index_set = 1;
4412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4413         sw_if_index_set = 1;
4414       else
4415         break;
4416     }
4417
4418   if (sw_if_index_set == 0)
4419     {
4420       errmsg ("missing interface name or sw_if_index\n");
4421       return -99;
4422     }
4423
4424   /* Construct the API message */
4425   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4426   mp->sw_if_index = ntohl (sw_if_index);
4427   mp->admin_up_down = admin_up;
4428   mp->link_up_down = link_up;
4429
4430   /* send it... */
4431   S;
4432
4433   /* Wait for a reply, return the good/bad news... */
4434   W;
4435 }
4436
4437 static int
4438 api_sw_interface_clear_stats (vat_main_t * vam)
4439 {
4440   unformat_input_t *i = vam->input;
4441   vl_api_sw_interface_clear_stats_t *mp;
4442   f64 timeout;
4443   u32 sw_if_index;
4444   u8 sw_if_index_set = 0;
4445
4446   /* Parse args required to build the message */
4447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4448     {
4449       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4450         sw_if_index_set = 1;
4451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4452         sw_if_index_set = 1;
4453       else
4454         break;
4455     }
4456
4457   /* Construct the API message */
4458   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4459
4460   if (sw_if_index_set == 1)
4461     mp->sw_if_index = ntohl (sw_if_index);
4462   else
4463     mp->sw_if_index = ~0;
4464
4465   /* send it... */
4466   S;
4467
4468   /* Wait for a reply, return the good/bad news... */
4469   W;
4470 }
4471
4472 static int
4473 api_sw_interface_add_del_address (vat_main_t * vam)
4474 {
4475   unformat_input_t *i = vam->input;
4476   vl_api_sw_interface_add_del_address_t *mp;
4477   f64 timeout;
4478   u32 sw_if_index;
4479   u8 sw_if_index_set = 0;
4480   u8 is_add = 1, del_all = 0;
4481   u32 address_length = 0;
4482   u8 v4_address_set = 0;
4483   u8 v6_address_set = 0;
4484   ip4_address_t v4address;
4485   ip6_address_t v6address;
4486
4487   /* Parse args required to build the message */
4488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4489     {
4490       if (unformat (i, "del-all"))
4491         del_all = 1;
4492       else if (unformat (i, "del"))
4493         is_add = 0;
4494       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4495         sw_if_index_set = 1;
4496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4497         sw_if_index_set = 1;
4498       else if (unformat (i, "%U/%d",
4499                          unformat_ip4_address, &v4address, &address_length))
4500         v4_address_set = 1;
4501       else if (unformat (i, "%U/%d",
4502                          unformat_ip6_address, &v6address, &address_length))
4503         v6_address_set = 1;
4504       else
4505         break;
4506     }
4507
4508   if (sw_if_index_set == 0)
4509     {
4510       errmsg ("missing interface name or sw_if_index\n");
4511       return -99;
4512     }
4513   if (v4_address_set && v6_address_set)
4514     {
4515       errmsg ("both v4 and v6 addresses set\n");
4516       return -99;
4517     }
4518   if (!v4_address_set && !v6_address_set && !del_all)
4519     {
4520       errmsg ("no addresses set\n");
4521       return -99;
4522     }
4523
4524   /* Construct the API message */
4525   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4526
4527   mp->sw_if_index = ntohl (sw_if_index);
4528   mp->is_add = is_add;
4529   mp->del_all = del_all;
4530   if (v6_address_set)
4531     {
4532       mp->is_ipv6 = 1;
4533       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4534     }
4535   else
4536     {
4537       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4538     }
4539   mp->address_length = address_length;
4540
4541   /* send it... */
4542   S;
4543
4544   /* Wait for a reply, return good/bad news  */
4545   W;
4546 }
4547
4548 static int
4549 api_sw_interface_set_table (vat_main_t * vam)
4550 {
4551   unformat_input_t *i = vam->input;
4552   vl_api_sw_interface_set_table_t *mp;
4553   f64 timeout;
4554   u32 sw_if_index, vrf_id = 0;
4555   u8 sw_if_index_set = 0;
4556   u8 is_ipv6 = 0;
4557
4558   /* Parse args required to build the message */
4559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4560     {
4561       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4562         sw_if_index_set = 1;
4563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4564         sw_if_index_set = 1;
4565       else if (unformat (i, "vrf %d", &vrf_id))
4566         ;
4567       else if (unformat (i, "ipv6"))
4568         is_ipv6 = 1;
4569       else
4570         break;
4571     }
4572
4573   if (sw_if_index_set == 0)
4574     {
4575       errmsg ("missing interface name or sw_if_index\n");
4576       return -99;
4577     }
4578
4579   /* Construct the API message */
4580   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4581
4582   mp->sw_if_index = ntohl (sw_if_index);
4583   mp->is_ipv6 = is_ipv6;
4584   mp->vrf_id = ntohl (vrf_id);
4585
4586   /* send it... */
4587   S;
4588
4589   /* Wait for a reply... */
4590   W;
4591 }
4592
4593 static int
4594 api_sw_interface_set_vpath (vat_main_t * vam)
4595 {
4596   unformat_input_t *i = vam->input;
4597   vl_api_sw_interface_set_vpath_t *mp;
4598   f64 timeout;
4599   u32 sw_if_index = 0;
4600   u8 sw_if_index_set = 0;
4601   u8 is_enable = 0;
4602
4603   /* Parse args required to build the message */
4604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4605     {
4606       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4607         sw_if_index_set = 1;
4608       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4609         sw_if_index_set = 1;
4610       else if (unformat (i, "enable"))
4611         is_enable = 1;
4612       else if (unformat (i, "disable"))
4613         is_enable = 0;
4614       else
4615         break;
4616     }
4617
4618   if (sw_if_index_set == 0)
4619     {
4620       errmsg ("missing interface name or sw_if_index\n");
4621       return -99;
4622     }
4623
4624   /* Construct the API message */
4625   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4626
4627   mp->sw_if_index = ntohl (sw_if_index);
4628   mp->enable = is_enable;
4629
4630   /* send it... */
4631   S;
4632
4633   /* Wait for a reply... */
4634   W;
4635 }
4636
4637 static int
4638 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4639 {
4640   unformat_input_t *i = vam->input;
4641   vl_api_sw_interface_set_l2_xconnect_t *mp;
4642   f64 timeout;
4643   u32 rx_sw_if_index;
4644   u8 rx_sw_if_index_set = 0;
4645   u32 tx_sw_if_index;
4646   u8 tx_sw_if_index_set = 0;
4647   u8 enable = 1;
4648
4649   /* Parse args required to build the message */
4650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4651     {
4652       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4653         rx_sw_if_index_set = 1;
4654       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4655         tx_sw_if_index_set = 1;
4656       else if (unformat (i, "rx"))
4657         {
4658           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4659             {
4660               if (unformat (i, "%U", unformat_sw_if_index, vam,
4661                             &rx_sw_if_index))
4662                 rx_sw_if_index_set = 1;
4663             }
4664           else
4665             break;
4666         }
4667       else if (unformat (i, "tx"))
4668         {
4669           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4670             {
4671               if (unformat (i, "%U", unformat_sw_if_index, vam,
4672                             &tx_sw_if_index))
4673                 tx_sw_if_index_set = 1;
4674             }
4675           else
4676             break;
4677         }
4678       else if (unformat (i, "enable"))
4679         enable = 1;
4680       else if (unformat (i, "disable"))
4681         enable = 0;
4682       else
4683         break;
4684     }
4685
4686   if (rx_sw_if_index_set == 0)
4687     {
4688       errmsg ("missing rx interface name or rx_sw_if_index\n");
4689       return -99;
4690     }
4691
4692   if (enable && (tx_sw_if_index_set == 0))
4693     {
4694       errmsg ("missing tx interface name or tx_sw_if_index\n");
4695       return -99;
4696     }
4697
4698   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4699
4700   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4701   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4702   mp->enable = enable;
4703
4704   S;
4705   W;
4706   /* NOTREACHED */
4707   return 0;
4708 }
4709
4710 static int
4711 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4712 {
4713   unformat_input_t *i = vam->input;
4714   vl_api_sw_interface_set_l2_bridge_t *mp;
4715   f64 timeout;
4716   u32 rx_sw_if_index;
4717   u8 rx_sw_if_index_set = 0;
4718   u32 bd_id;
4719   u8 bd_id_set = 0;
4720   u8 bvi = 0;
4721   u32 shg = 0;
4722   u8 enable = 1;
4723
4724   /* Parse args required to build the message */
4725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4726     {
4727       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4728         rx_sw_if_index_set = 1;
4729       else if (unformat (i, "bd_id %d", &bd_id))
4730         bd_id_set = 1;
4731       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4732         rx_sw_if_index_set = 1;
4733       else if (unformat (i, "shg %d", &shg))
4734         ;
4735       else if (unformat (i, "bvi"))
4736         bvi = 1;
4737       else if (unformat (i, "enable"))
4738         enable = 1;
4739       else if (unformat (i, "disable"))
4740         enable = 0;
4741       else
4742         break;
4743     }
4744
4745   if (rx_sw_if_index_set == 0)
4746     {
4747       errmsg ("missing rx interface name or sw_if_index\n");
4748       return -99;
4749     }
4750
4751   if (enable && (bd_id_set == 0))
4752     {
4753       errmsg ("missing bridge domain\n");
4754       return -99;
4755     }
4756
4757   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4758
4759   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4760   mp->bd_id = ntohl (bd_id);
4761   mp->shg = (u8) shg;
4762   mp->bvi = bvi;
4763   mp->enable = enable;
4764
4765   S;
4766   W;
4767   /* NOTREACHED */
4768   return 0;
4769 }
4770
4771 static int
4772 api_bridge_domain_dump (vat_main_t * vam)
4773 {
4774   unformat_input_t *i = vam->input;
4775   vl_api_bridge_domain_dump_t *mp;
4776   f64 timeout;
4777   u32 bd_id = ~0;
4778
4779   /* Parse args required to build the message */
4780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4781     {
4782       if (unformat (i, "bd_id %d", &bd_id))
4783         ;
4784       else
4785         break;
4786     }
4787
4788   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4789   mp->bd_id = ntohl (bd_id);
4790   S;
4791
4792   /* Use a control ping for synchronization */
4793   {
4794     vl_api_control_ping_t *mp;
4795     M (CONTROL_PING, control_ping);
4796     S;
4797   }
4798
4799   W;
4800   /* NOTREACHED */
4801   return 0;
4802 }
4803
4804 static int
4805 api_bridge_domain_add_del (vat_main_t * vam)
4806 {
4807   unformat_input_t *i = vam->input;
4808   vl_api_bridge_domain_add_del_t *mp;
4809   f64 timeout;
4810   u32 bd_id = ~0;
4811   u8 is_add = 1;
4812   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4813
4814   /* Parse args required to build the message */
4815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4816     {
4817       if (unformat (i, "bd_id %d", &bd_id))
4818         ;
4819       else if (unformat (i, "flood %d", &flood))
4820         ;
4821       else if (unformat (i, "uu-flood %d", &uu_flood))
4822         ;
4823       else if (unformat (i, "forward %d", &forward))
4824         ;
4825       else if (unformat (i, "learn %d", &learn))
4826         ;
4827       else if (unformat (i, "arp-term %d", &arp_term))
4828         ;
4829       else if (unformat (i, "del"))
4830         {
4831           is_add = 0;
4832           flood = uu_flood = forward = learn = 0;
4833         }
4834       else
4835         break;
4836     }
4837
4838   if (bd_id == ~0)
4839     {
4840       errmsg ("missing bridge domain\n");
4841       return -99;
4842     }
4843
4844   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4845
4846   mp->bd_id = ntohl (bd_id);
4847   mp->flood = flood;
4848   mp->uu_flood = uu_flood;
4849   mp->forward = forward;
4850   mp->learn = learn;
4851   mp->arp_term = arp_term;
4852   mp->is_add = is_add;
4853
4854   S;
4855   W;
4856   /* NOTREACHED */
4857   return 0;
4858 }
4859
4860 static int
4861 api_l2fib_add_del (vat_main_t * vam)
4862 {
4863   unformat_input_t *i = vam->input;
4864   vl_api_l2fib_add_del_t *mp;
4865   f64 timeout;
4866   u64 mac = 0;
4867   u8 mac_set = 0;
4868   u32 bd_id;
4869   u8 bd_id_set = 0;
4870   u32 sw_if_index;
4871   u8 sw_if_index_set = 0;
4872   u8 is_add = 1;
4873   u8 static_mac = 0;
4874   u8 filter_mac = 0;
4875   u8 bvi_mac = 0;
4876   int count = 1;
4877   f64 before = 0;
4878   int j;
4879
4880   /* Parse args required to build the message */
4881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4882     {
4883       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4884         mac_set = 1;
4885       else if (unformat (i, "bd_id %d", &bd_id))
4886         bd_id_set = 1;
4887       else 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, "static"))
4900         static_mac = 1;
4901       else if (unformat (i, "filter"))
4902         {
4903           filter_mac = 1;
4904           static_mac = 1;
4905         }
4906       else if (unformat (i, "bvi"))
4907         {
4908           bvi_mac = 1;
4909           static_mac = 1;
4910         }
4911       else if (unformat (i, "del"))
4912         is_add = 0;
4913       else if (unformat (i, "count %d", &count))
4914         ;
4915       else
4916         break;
4917     }
4918
4919   if (mac_set == 0)
4920     {
4921       errmsg ("missing mac address\n");
4922       return -99;
4923     }
4924
4925   if (bd_id_set == 0)
4926     {
4927       errmsg ("missing bridge domain\n");
4928       return -99;
4929     }
4930
4931   if (is_add && (sw_if_index_set == 0))
4932     {
4933       errmsg ("missing interface name or sw_if_index\n");
4934       return -99;
4935     }
4936
4937   if (count > 1)
4938     {
4939       /* Turn on async mode */
4940       vam->async_mode = 1;
4941       vam->async_errors = 0;
4942       before = vat_time_now (vam);
4943     }
4944
4945   for (j = 0; j < count; j++)
4946     {
4947       M (L2FIB_ADD_DEL, l2fib_add_del);
4948
4949       mp->mac = mac;
4950       mp->bd_id = ntohl (bd_id);
4951       mp->is_add = is_add;
4952
4953       if (is_add)
4954         {
4955           mp->sw_if_index = ntohl (sw_if_index);
4956           mp->static_mac = static_mac;
4957           mp->filter_mac = filter_mac;
4958           mp->bvi_mac = bvi_mac;
4959         }
4960       increment_mac_address (&mac);
4961       /* send it... */
4962       S;
4963     }
4964
4965   if (count > 1)
4966     {
4967       vl_api_control_ping_t *mp;
4968       f64 after;
4969
4970       /* Shut off async mode */
4971       vam->async_mode = 0;
4972
4973       M (CONTROL_PING, control_ping);
4974       S;
4975
4976       timeout = vat_time_now (vam) + 1.0;
4977       while (vat_time_now (vam) < timeout)
4978         if (vam->result_ready == 1)
4979           goto out;
4980       vam->retval = -99;
4981
4982     out:
4983       if (vam->retval == -99)
4984         errmsg ("timeout\n");
4985
4986       if (vam->async_errors > 0)
4987         {
4988           errmsg ("%d asynchronous errors\n", vam->async_errors);
4989           vam->retval = -98;
4990         }
4991       vam->async_errors = 0;
4992       after = vat_time_now (vam);
4993
4994       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4995                count, after - before, count / (after - before));
4996     }
4997   else
4998     {
4999       /* Wait for a reply... */
5000       W;
5001     }
5002   /* Return the good/bad news */
5003   return (vam->retval);
5004 }
5005
5006 static int
5007 api_l2_flags (vat_main_t * vam)
5008 {
5009   unformat_input_t *i = vam->input;
5010   vl_api_l2_flags_t *mp;
5011   f64 timeout;
5012   u32 sw_if_index;
5013   u32 feature_bitmap = 0;
5014   u8 sw_if_index_set = 0;
5015
5016   /* Parse args required to build the message */
5017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5018     {
5019       if (unformat (i, "sw_if_index %d", &sw_if_index))
5020         sw_if_index_set = 1;
5021       else if (unformat (i, "sw_if"))
5022         {
5023           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5024             {
5025               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5026                 sw_if_index_set = 1;
5027             }
5028           else
5029             break;
5030         }
5031       else if (unformat (i, "learn"))
5032         feature_bitmap |= L2INPUT_FEAT_LEARN;
5033       else if (unformat (i, "forward"))
5034         feature_bitmap |= L2INPUT_FEAT_FWD;
5035       else if (unformat (i, "flood"))
5036         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5037       else if (unformat (i, "uu-flood"))
5038         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5039       else
5040         break;
5041     }
5042
5043   if (sw_if_index_set == 0)
5044     {
5045       errmsg ("missing interface name or sw_if_index\n");
5046       return -99;
5047     }
5048
5049   M (L2_FLAGS, l2_flags);
5050
5051   mp->sw_if_index = ntohl (sw_if_index);
5052   mp->feature_bitmap = ntohl (feature_bitmap);
5053
5054   S;
5055   W;
5056   /* NOTREACHED */
5057   return 0;
5058 }
5059
5060 static int
5061 api_bridge_flags (vat_main_t * vam)
5062 {
5063   unformat_input_t *i = vam->input;
5064   vl_api_bridge_flags_t *mp;
5065   f64 timeout;
5066   u32 bd_id;
5067   u8 bd_id_set = 0;
5068   u8 is_set = 1;
5069   u32 flags = 0;
5070
5071   /* Parse args required to build the message */
5072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5073     {
5074       if (unformat (i, "bd_id %d", &bd_id))
5075         bd_id_set = 1;
5076       else if (unformat (i, "learn"))
5077         flags |= L2_LEARN;
5078       else if (unformat (i, "forward"))
5079         flags |= L2_FWD;
5080       else if (unformat (i, "flood"))
5081         flags |= L2_FLOOD;
5082       else if (unformat (i, "uu-flood"))
5083         flags |= L2_UU_FLOOD;
5084       else if (unformat (i, "arp-term"))
5085         flags |= L2_ARP_TERM;
5086       else if (unformat (i, "off"))
5087         is_set = 0;
5088       else if (unformat (i, "disable"))
5089         is_set = 0;
5090       else
5091         break;
5092     }
5093
5094   if (bd_id_set == 0)
5095     {
5096       errmsg ("missing bridge domain\n");
5097       return -99;
5098     }
5099
5100   M (BRIDGE_FLAGS, bridge_flags);
5101
5102   mp->bd_id = ntohl (bd_id);
5103   mp->feature_bitmap = ntohl (flags);
5104   mp->is_set = is_set;
5105
5106   S;
5107   W;
5108   /* NOTREACHED */
5109   return 0;
5110 }
5111
5112 static int
5113 api_bd_ip_mac_add_del (vat_main_t * vam)
5114 {
5115   unformat_input_t *i = vam->input;
5116   vl_api_bd_ip_mac_add_del_t *mp;
5117   f64 timeout;
5118   u32 bd_id;
5119   u8 is_ipv6 = 0;
5120   u8 is_add = 1;
5121   u8 bd_id_set = 0;
5122   u8 ip_set = 0;
5123   u8 mac_set = 0;
5124   ip4_address_t v4addr;
5125   ip6_address_t v6addr;
5126   u8 macaddr[6];
5127
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "bd_id %d", &bd_id))
5133         {
5134           bd_id_set++;
5135         }
5136       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5137         {
5138           ip_set++;
5139         }
5140       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5141         {
5142           ip_set++;
5143           is_ipv6++;
5144         }
5145       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5146         {
5147           mac_set++;
5148         }
5149       else if (unformat (i, "del"))
5150         is_add = 0;
5151       else
5152         break;
5153     }
5154
5155   if (bd_id_set == 0)
5156     {
5157       errmsg ("missing bridge domain\n");
5158       return -99;
5159     }
5160   else if (ip_set == 0)
5161     {
5162       errmsg ("missing IP address\n");
5163       return -99;
5164     }
5165   else if (mac_set == 0)
5166     {
5167       errmsg ("missing MAC address\n");
5168       return -99;
5169     }
5170
5171   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5172
5173   mp->bd_id = ntohl (bd_id);
5174   mp->is_ipv6 = is_ipv6;
5175   mp->is_add = is_add;
5176   if (is_ipv6)
5177     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5178   else
5179     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5180   clib_memcpy (mp->mac_address, macaddr, 6);
5181   S;
5182   W;
5183   /* NOTREACHED */
5184   return 0;
5185 }
5186
5187 static int
5188 api_tap_connect (vat_main_t * vam)
5189 {
5190   unformat_input_t *i = vam->input;
5191   vl_api_tap_connect_t *mp;
5192   f64 timeout;
5193   u8 mac_address[6];
5194   u8 random_mac = 1;
5195   u8 name_set = 0;
5196   u8 *tap_name;
5197
5198   memset (mac_address, 0, sizeof (mac_address));
5199
5200   /* Parse args required to build the message */
5201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5202     {
5203       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5204         {
5205           random_mac = 0;
5206         }
5207       else if (unformat (i, "random-mac"))
5208         random_mac = 1;
5209       else if (unformat (i, "tapname %s", &tap_name))
5210         name_set = 1;
5211       else
5212         break;
5213     }
5214
5215   if (name_set == 0)
5216     {
5217       errmsg ("missing tap name\n");
5218       return -99;
5219     }
5220   if (vec_len (tap_name) > 63)
5221     {
5222       errmsg ("tap name too long\n");
5223     }
5224   vec_add1 (tap_name, 0);
5225
5226   /* Construct the API message */
5227   M (TAP_CONNECT, tap_connect);
5228
5229   mp->use_random_mac = random_mac;
5230   clib_memcpy (mp->mac_address, mac_address, 6);
5231   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5232   vec_free (tap_name);
5233
5234   /* send it... */
5235   S;
5236
5237   /* Wait for a reply... */
5238   W;
5239 }
5240
5241 static int
5242 api_tap_modify (vat_main_t * vam)
5243 {
5244   unformat_input_t *i = vam->input;
5245   vl_api_tap_modify_t *mp;
5246   f64 timeout;
5247   u8 mac_address[6];
5248   u8 random_mac = 1;
5249   u8 name_set = 0;
5250   u8 *tap_name;
5251   u32 sw_if_index = ~0;
5252   u8 sw_if_index_set = 0;
5253
5254   memset (mac_address, 0, sizeof (mac_address));
5255
5256   /* Parse args required to build the message */
5257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5258     {
5259       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5260         sw_if_index_set = 1;
5261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5262         sw_if_index_set = 1;
5263       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5264         {
5265           random_mac = 0;
5266         }
5267       else if (unformat (i, "random-mac"))
5268         random_mac = 1;
5269       else if (unformat (i, "tapname %s", &tap_name))
5270         name_set = 1;
5271       else
5272         break;
5273     }
5274
5275   if (sw_if_index_set == 0)
5276     {
5277       errmsg ("missing vpp interface name");
5278       return -99;
5279     }
5280   if (name_set == 0)
5281     {
5282       errmsg ("missing tap name\n");
5283       return -99;
5284     }
5285   if (vec_len (tap_name) > 63)
5286     {
5287       errmsg ("tap name too long\n");
5288     }
5289   vec_add1 (tap_name, 0);
5290
5291   /* Construct the API message */
5292   M (TAP_MODIFY, tap_modify);
5293
5294   mp->use_random_mac = random_mac;
5295   mp->sw_if_index = ntohl (sw_if_index);
5296   clib_memcpy (mp->mac_address, mac_address, 6);
5297   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5298   vec_free (tap_name);
5299
5300   /* send it... */
5301   S;
5302
5303   /* Wait for a reply... */
5304   W;
5305 }
5306
5307 static int
5308 api_tap_delete (vat_main_t * vam)
5309 {
5310   unformat_input_t *i = vam->input;
5311   vl_api_tap_delete_t *mp;
5312   f64 timeout;
5313   u32 sw_if_index = ~0;
5314   u8 sw_if_index_set = 0;
5315
5316   /* Parse args required to build the message */
5317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5318     {
5319       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5320         sw_if_index_set = 1;
5321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5322         sw_if_index_set = 1;
5323       else
5324         break;
5325     }
5326
5327   if (sw_if_index_set == 0)
5328     {
5329       errmsg ("missing vpp interface name");
5330       return -99;
5331     }
5332
5333   /* Construct the API message */
5334   M (TAP_DELETE, tap_delete);
5335
5336   mp->sw_if_index = ntohl (sw_if_index);
5337
5338   /* send it... */
5339   S;
5340
5341   /* Wait for a reply... */
5342   W;
5343 }
5344
5345 static int
5346 api_ip_add_del_route (vat_main_t * vam)
5347 {
5348   unformat_input_t *i = vam->input;
5349   vl_api_ip_add_del_route_t *mp;
5350   f64 timeout;
5351   u32 sw_if_index = ~0, vrf_id = 0;
5352   u8 sw_if_index_set = 0;
5353   u8 is_ipv6 = 0;
5354   u8 is_local = 0, is_drop = 0;
5355   u8 create_vrf_if_needed = 0;
5356   u8 is_add = 1;
5357   u8 next_hop_weight = 1;
5358   u8 not_last = 0;
5359   u8 is_multipath = 0;
5360   u8 address_set = 0;
5361   u8 address_length_set = 0;
5362   u32 lookup_in_vrf = 0;
5363   u32 resolve_attempts = 0;
5364   u32 dst_address_length = 0;
5365   u8 next_hop_set = 0;
5366   ip4_address_t v4_dst_address, v4_next_hop_address;
5367   ip6_address_t v6_dst_address, v6_next_hop_address;
5368   int count = 1;
5369   int j;
5370   f64 before = 0;
5371   u32 random_add_del = 0;
5372   u32 *random_vector = 0;
5373   uword *random_hash;
5374   u32 random_seed = 0xdeaddabe;
5375   u32 classify_table_index = ~0;
5376   u8 is_classify = 0;
5377
5378   /* Parse args required to build the message */
5379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5380     {
5381       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5382         sw_if_index_set = 1;
5383       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5384         sw_if_index_set = 1;
5385       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5386         {
5387           address_set = 1;
5388           is_ipv6 = 0;
5389         }
5390       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5391         {
5392           address_set = 1;
5393           is_ipv6 = 1;
5394         }
5395       else if (unformat (i, "/%d", &dst_address_length))
5396         {
5397           address_length_set = 1;
5398         }
5399
5400       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5401                                          &v4_next_hop_address))
5402         {
5403           next_hop_set = 1;
5404         }
5405       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5406                                          &v6_next_hop_address))
5407         {
5408           next_hop_set = 1;
5409         }
5410       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5411         ;
5412       else if (unformat (i, "weight %d", &next_hop_weight))
5413         ;
5414       else if (unformat (i, "drop"))
5415         {
5416           is_drop = 1;
5417         }
5418       else if (unformat (i, "local"))
5419         {
5420           is_local = 1;
5421         }
5422       else if (unformat (i, "classify %d", &classify_table_index))
5423         {
5424           is_classify = 1;
5425         }
5426       else if (unformat (i, "del"))
5427         is_add = 0;
5428       else if (unformat (i, "add"))
5429         is_add = 1;
5430       else if (unformat (i, "not-last"))
5431         not_last = 1;
5432       else if (unformat (i, "multipath"))
5433         is_multipath = 1;
5434       else if (unformat (i, "vrf %d", &vrf_id))
5435         ;
5436       else if (unformat (i, "create-vrf"))
5437         create_vrf_if_needed = 1;
5438       else if (unformat (i, "count %d", &count))
5439         ;
5440       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5441         ;
5442       else if (unformat (i, "random"))
5443         random_add_del = 1;
5444       else if (unformat (i, "seed %d", &random_seed))
5445         ;
5446       else
5447         {
5448           clib_warning ("parse error '%U'", format_unformat_error, i);
5449           return -99;
5450         }
5451     }
5452
5453   if (resolve_attempts > 0 && sw_if_index_set == 0)
5454     {
5455       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5456       return -99;
5457     }
5458
5459   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5460     {
5461       errmsg ("next hop / local / drop / classify not set\n");
5462       return -99;
5463     }
5464
5465   if (address_set == 0)
5466     {
5467       errmsg ("missing addresses\n");
5468       return -99;
5469     }
5470
5471   if (address_length_set == 0)
5472     {
5473       errmsg ("missing address length\n");
5474       return -99;
5475     }
5476
5477   /* Generate a pile of unique, random routes */
5478   if (random_add_del)
5479     {
5480       u32 this_random_address;
5481       random_hash = hash_create (count, sizeof (uword));
5482
5483       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5484       for (j = 0; j <= count; j++)
5485         {
5486           do
5487             {
5488               this_random_address = random_u32 (&random_seed);
5489               this_random_address =
5490                 clib_host_to_net_u32 (this_random_address);
5491             }
5492           while (hash_get (random_hash, this_random_address));
5493           vec_add1 (random_vector, this_random_address);
5494           hash_set (random_hash, this_random_address, 1);
5495         }
5496       hash_free (random_hash);
5497       v4_dst_address.as_u32 = random_vector[0];
5498     }
5499
5500   if (count > 1)
5501     {
5502       /* Turn on async mode */
5503       vam->async_mode = 1;
5504       vam->async_errors = 0;
5505       before = vat_time_now (vam);
5506     }
5507
5508   for (j = 0; j < count; j++)
5509     {
5510       /* Construct the API message */
5511       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5512
5513       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5514       mp->vrf_id = ntohl (vrf_id);
5515       if (resolve_attempts > 0)
5516         {
5517           mp->resolve_attempts = ntohl (resolve_attempts);
5518           mp->resolve_if_needed = 1;
5519         }
5520       mp->create_vrf_if_needed = create_vrf_if_needed;
5521
5522       mp->is_add = is_add;
5523       mp->is_drop = is_drop;
5524       mp->is_ipv6 = is_ipv6;
5525       mp->is_local = is_local;
5526       mp->is_classify = is_classify;
5527       mp->is_multipath = is_multipath;
5528       mp->not_last = not_last;
5529       mp->next_hop_weight = next_hop_weight;
5530       mp->dst_address_length = dst_address_length;
5531       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5532       mp->classify_table_index = ntohl (classify_table_index);
5533
5534       if (is_ipv6)
5535         {
5536           clib_memcpy (mp->dst_address, &v6_dst_address,
5537                        sizeof (v6_dst_address));
5538           if (next_hop_set)
5539             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5540                          sizeof (v6_next_hop_address));
5541           increment_v6_address (&v6_dst_address);
5542         }
5543       else
5544         {
5545           clib_memcpy (mp->dst_address, &v4_dst_address,
5546                        sizeof (v4_dst_address));
5547           if (next_hop_set)
5548             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5549                          sizeof (v4_next_hop_address));
5550           if (random_add_del)
5551             v4_dst_address.as_u32 = random_vector[j + 1];
5552           else
5553             increment_v4_address (&v4_dst_address);
5554         }
5555       /* send it... */
5556       S;
5557     }
5558
5559   /* When testing multiple add/del ops, use a control-ping to sync */
5560   if (count > 1)
5561     {
5562       vl_api_control_ping_t *mp;
5563       f64 after;
5564
5565       /* Shut off async mode */
5566       vam->async_mode = 0;
5567
5568       M (CONTROL_PING, control_ping);
5569       S;
5570
5571       timeout = vat_time_now (vam) + 1.0;
5572       while (vat_time_now (vam) < timeout)
5573         if (vam->result_ready == 1)
5574           goto out;
5575       vam->retval = -99;
5576
5577     out:
5578       if (vam->retval == -99)
5579         errmsg ("timeout\n");
5580
5581       if (vam->async_errors > 0)
5582         {
5583           errmsg ("%d asynchronous errors\n", vam->async_errors);
5584           vam->retval = -98;
5585         }
5586       vam->async_errors = 0;
5587       after = vat_time_now (vam);
5588
5589       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5590                count, after - before, count / (after - before));
5591     }
5592   else
5593     {
5594       /* Wait for a reply... */
5595       W;
5596     }
5597
5598   /* Return the good/bad news */
5599   return (vam->retval);
5600 }
5601
5602 static int
5603 api_proxy_arp_add_del (vat_main_t * vam)
5604 {
5605   unformat_input_t *i = vam->input;
5606   vl_api_proxy_arp_add_del_t *mp;
5607   f64 timeout;
5608   u32 vrf_id = 0;
5609   u8 is_add = 1;
5610   ip4_address_t lo, hi;
5611   u8 range_set = 0;
5612
5613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5614     {
5615       if (unformat (i, "vrf %d", &vrf_id))
5616         ;
5617       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5618                          unformat_ip4_address, &hi))
5619         range_set = 1;
5620       else if (unformat (i, "del"))
5621         is_add = 0;
5622       else
5623         {
5624           clib_warning ("parse error '%U'", format_unformat_error, i);
5625           return -99;
5626         }
5627     }
5628
5629   if (range_set == 0)
5630     {
5631       errmsg ("address range not set\n");
5632       return -99;
5633     }
5634
5635   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5636
5637   mp->vrf_id = ntohl (vrf_id);
5638   mp->is_add = is_add;
5639   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5640   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5641
5642   S;
5643   W;
5644   /* NOTREACHED */
5645   return 0;
5646 }
5647
5648 static int
5649 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5650 {
5651   unformat_input_t *i = vam->input;
5652   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5653   f64 timeout;
5654   u32 sw_if_index;
5655   u8 enable = 1;
5656   u8 sw_if_index_set = 0;
5657
5658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5659     {
5660       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5661         sw_if_index_set = 1;
5662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5663         sw_if_index_set = 1;
5664       else if (unformat (i, "enable"))
5665         enable = 1;
5666       else if (unformat (i, "disable"))
5667         enable = 0;
5668       else
5669         {
5670           clib_warning ("parse error '%U'", format_unformat_error, i);
5671           return -99;
5672         }
5673     }
5674
5675   if (sw_if_index_set == 0)
5676     {
5677       errmsg ("missing interface name or sw_if_index\n");
5678       return -99;
5679     }
5680
5681   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5682
5683   mp->sw_if_index = ntohl (sw_if_index);
5684   mp->enable_disable = enable;
5685
5686   S;
5687   W;
5688   /* NOTREACHED */
5689   return 0;
5690 }
5691
5692 static int
5693 api_mpls_add_del_decap (vat_main_t * vam)
5694 {
5695   unformat_input_t *i = vam->input;
5696   vl_api_mpls_add_del_decap_t *mp;
5697   f64 timeout;
5698   u32 rx_vrf_id = 0;
5699   u32 tx_vrf_id = 0;
5700   u32 label = 0;
5701   u8 is_add = 1;
5702   u8 s_bit = 1;
5703   u32 next_index = 1;
5704
5705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5706     {
5707       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5708         ;
5709       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5710         ;
5711       else if (unformat (i, "label %d", &label))
5712         ;
5713       else if (unformat (i, "next-index %d", &next_index))
5714         ;
5715       else if (unformat (i, "del"))
5716         is_add = 0;
5717       else if (unformat (i, "s-bit-clear"))
5718         s_bit = 0;
5719       else
5720         {
5721           clib_warning ("parse error '%U'", format_unformat_error, i);
5722           return -99;
5723         }
5724     }
5725
5726   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5727
5728   mp->rx_vrf_id = ntohl (rx_vrf_id);
5729   mp->tx_vrf_id = ntohl (tx_vrf_id);
5730   mp->label = ntohl (label);
5731   mp->next_index = ntohl (next_index);
5732   mp->s_bit = s_bit;
5733   mp->is_add = is_add;
5734
5735   S;
5736   W;
5737   /* NOTREACHED */
5738   return 0;
5739 }
5740
5741 static int
5742 api_mpls_add_del_encap (vat_main_t * vam)
5743 {
5744   unformat_input_t *i = vam->input;
5745   vl_api_mpls_add_del_encap_t *mp;
5746   f64 timeout;
5747   u32 vrf_id = 0;
5748   u32 *labels = 0;
5749   u32 label;
5750   ip4_address_t dst_address;
5751   u8 is_add = 1;
5752
5753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5754     {
5755       if (unformat (i, "vrf %d", &vrf_id))
5756         ;
5757       else if (unformat (i, "label %d", &label))
5758         vec_add1 (labels, ntohl (label));
5759       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5760         ;
5761       else if (unformat (i, "del"))
5762         is_add = 0;
5763       else
5764         {
5765           clib_warning ("parse error '%U'", format_unformat_error, i);
5766           return -99;
5767         }
5768     }
5769
5770   if (vec_len (labels) == 0)
5771     {
5772       errmsg ("missing encap label stack\n");
5773       return -99;
5774     }
5775
5776   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5777       sizeof (u32) * vec_len (labels));
5778
5779   mp->vrf_id = ntohl (vrf_id);
5780   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5781   mp->is_add = is_add;
5782   mp->nlabels = vec_len (labels);
5783   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5784
5785   vec_free (labels);
5786
5787   S;
5788   W;
5789   /* NOTREACHED */
5790   return 0;
5791 }
5792
5793 static int
5794 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5795 {
5796   unformat_input_t *i = vam->input;
5797   vl_api_mpls_gre_add_del_tunnel_t *mp;
5798   f64 timeout;
5799   u32 inner_vrf_id = 0;
5800   u32 outer_vrf_id = 0;
5801   ip4_address_t src_address;
5802   ip4_address_t dst_address;
5803   ip4_address_t intfc_address;
5804   u32 tmp;
5805   u8 intfc_address_length = 0;
5806   u8 is_add = 1;
5807   u8 l2_only = 0;
5808
5809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5810     {
5811       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5812         ;
5813       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5814         ;
5815       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5816         ;
5817       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5818         ;
5819       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5820                          &intfc_address, &tmp))
5821         intfc_address_length = tmp;
5822       else if (unformat (i, "l2-only"))
5823         l2_only = 1;
5824       else if (unformat (i, "del"))
5825         is_add = 0;
5826       else
5827         {
5828           clib_warning ("parse error '%U'", format_unformat_error, i);
5829           return -99;
5830         }
5831     }
5832
5833   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5834
5835   mp->inner_vrf_id = ntohl (inner_vrf_id);
5836   mp->outer_vrf_id = ntohl (outer_vrf_id);
5837   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5838   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5839   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5840   mp->intfc_address_length = intfc_address_length;
5841   mp->l2_only = l2_only;
5842   mp->is_add = is_add;
5843
5844   S;
5845   W;
5846   /* NOTREACHED */
5847   return 0;
5848 }
5849
5850 static int
5851 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5852 {
5853   unformat_input_t *i = vam->input;
5854   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5855   f64 timeout;
5856   u32 inner_vrf_id = 0;
5857   ip4_address_t intfc_address;
5858   u8 dst_mac_address[6];
5859   int dst_set = 1;
5860   u32 tmp;
5861   u8 intfc_address_length = 0;
5862   u8 is_add = 1;
5863   u8 l2_only = 0;
5864   u32 tx_sw_if_index;
5865   int tx_sw_if_index_set = 0;
5866
5867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5868     {
5869       if (unformat (i, "vrf %d", &inner_vrf_id))
5870         ;
5871       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5872                          &intfc_address, &tmp))
5873         intfc_address_length = tmp;
5874       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5875         tx_sw_if_index_set = 1;
5876       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5877         tx_sw_if_index_set = 1;
5878       else if (unformat (i, "dst %U", unformat_ethernet_address,
5879                          dst_mac_address))
5880         dst_set = 1;
5881       else if (unformat (i, "l2-only"))
5882         l2_only = 1;
5883       else if (unformat (i, "del"))
5884         is_add = 0;
5885       else
5886         {
5887           clib_warning ("parse error '%U'", format_unformat_error, i);
5888           return -99;
5889         }
5890     }
5891
5892   if (!dst_set)
5893     {
5894       errmsg ("dst (mac address) not set\n");
5895       return -99;
5896     }
5897   if (!tx_sw_if_index_set)
5898     {
5899       errmsg ("tx-intfc not set\n");
5900       return -99;
5901     }
5902
5903   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5904
5905   mp->vrf_id = ntohl (inner_vrf_id);
5906   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5907   mp->adj_address_length = intfc_address_length;
5908   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5909                sizeof (dst_mac_address));
5910   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5911   mp->l2_only = l2_only;
5912   mp->is_add = is_add;
5913
5914   S;
5915   W;
5916   /* NOTREACHED */
5917   return 0;
5918 }
5919
5920 static int
5921 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5922 {
5923   unformat_input_t *i = vam->input;
5924   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5925   f64 timeout;
5926   u32 inner_vrf_id = 0;
5927   u32 outer_vrf_id = 0;
5928   ip4_address_t adj_address;
5929   int adj_address_set = 0;
5930   ip4_address_t next_hop_address;
5931   int next_hop_address_set = 0;
5932   u32 tmp;
5933   u8 adj_address_length = 0;
5934   u8 l2_only = 0;
5935   u8 is_add = 1;
5936   u32 resolve_attempts = 5;
5937   u8 resolve_if_needed = 1;
5938
5939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5940     {
5941       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5942         ;
5943       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5944         ;
5945       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5946                          &adj_address, &tmp))
5947         {
5948           adj_address_length = tmp;
5949           adj_address_set = 1;
5950         }
5951       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5952                          &next_hop_address))
5953         next_hop_address_set = 1;
5954       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5955         ;
5956       else if (unformat (i, "resolve-if-needed %d", &tmp))
5957         resolve_if_needed = tmp;
5958       else if (unformat (i, "l2-only"))
5959         l2_only = 1;
5960       else if (unformat (i, "del"))
5961         is_add = 0;
5962       else
5963         {
5964           clib_warning ("parse error '%U'", format_unformat_error, i);
5965           return -99;
5966         }
5967     }
5968
5969   if (!adj_address_set)
5970     {
5971       errmsg ("adjacency address/mask not set\n");
5972       return -99;
5973     }
5974   if (!next_hop_address_set)
5975     {
5976       errmsg ("ip4 next hop address (in outer fib) not set\n");
5977       return -99;
5978     }
5979
5980   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5981
5982   mp->inner_vrf_id = ntohl (inner_vrf_id);
5983   mp->outer_vrf_id = ntohl (outer_vrf_id);
5984   mp->resolve_attempts = ntohl (resolve_attempts);
5985   mp->resolve_if_needed = resolve_if_needed;
5986   mp->is_add = is_add;
5987   mp->l2_only = l2_only;
5988   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5989   mp->adj_address_length = adj_address_length;
5990   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5991                sizeof (next_hop_address));
5992
5993   S;
5994   W;
5995   /* NOTREACHED */
5996   return 0;
5997 }
5998
5999 static int
6000 api_sw_interface_set_unnumbered (vat_main_t * vam)
6001 {
6002   unformat_input_t *i = vam->input;
6003   vl_api_sw_interface_set_unnumbered_t *mp;
6004   f64 timeout;
6005   u32 sw_if_index;
6006   u32 unnum_sw_index = ~0;
6007   u8 is_add = 1;
6008   u8 sw_if_index_set = 0;
6009
6010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6011     {
6012       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6013         sw_if_index_set = 1;
6014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6015         sw_if_index_set = 1;
6016       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6017         ;
6018       else if (unformat (i, "del"))
6019         is_add = 0;
6020       else
6021         {
6022           clib_warning ("parse error '%U'", format_unformat_error, i);
6023           return -99;
6024         }
6025     }
6026
6027   if (sw_if_index_set == 0)
6028     {
6029       errmsg ("missing interface name or sw_if_index\n");
6030       return -99;
6031     }
6032
6033   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6034
6035   mp->sw_if_index = ntohl (sw_if_index);
6036   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6037   mp->is_add = is_add;
6038
6039   S;
6040   W;
6041   /* NOTREACHED */
6042   return 0;
6043 }
6044
6045 static int
6046 api_ip_neighbor_add_del (vat_main_t * vam)
6047 {
6048   unformat_input_t *i = vam->input;
6049   vl_api_ip_neighbor_add_del_t *mp;
6050   f64 timeout;
6051   u32 sw_if_index;
6052   u8 sw_if_index_set = 0;
6053   u32 vrf_id = 0;
6054   u8 is_add = 1;
6055   u8 is_static = 0;
6056   u8 mac_address[6];
6057   u8 mac_set = 0;
6058   u8 v4_address_set = 0;
6059   u8 v6_address_set = 0;
6060   ip4_address_t v4address;
6061   ip6_address_t v6address;
6062
6063   memset (mac_address, 0, sizeof (mac_address));
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6069         {
6070           mac_set = 1;
6071         }
6072       else if (unformat (i, "del"))
6073         is_add = 0;
6074       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6075         sw_if_index_set = 1;
6076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6077         sw_if_index_set = 1;
6078       else if (unformat (i, "is_static"))
6079         is_static = 1;
6080       else if (unformat (i, "vrf %d", &vrf_id))
6081         ;
6082       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6083         v4_address_set = 1;
6084       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6085         v6_address_set = 1;
6086       else
6087         {
6088           clib_warning ("parse error '%U'", format_unformat_error, i);
6089           return -99;
6090         }
6091     }
6092
6093   if (sw_if_index_set == 0)
6094     {
6095       errmsg ("missing interface name or sw_if_index\n");
6096       return -99;
6097     }
6098   if (v4_address_set && v6_address_set)
6099     {
6100       errmsg ("both v4 and v6 addresses set\n");
6101       return -99;
6102     }
6103   if (!v4_address_set && !v6_address_set)
6104     {
6105       errmsg ("no address set\n");
6106       return -99;
6107     }
6108
6109   /* Construct the API message */
6110   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6111
6112   mp->sw_if_index = ntohl (sw_if_index);
6113   mp->is_add = is_add;
6114   mp->vrf_id = ntohl (vrf_id);
6115   mp->is_static = is_static;
6116   if (mac_set)
6117     clib_memcpy (mp->mac_address, mac_address, 6);
6118   if (v6_address_set)
6119     {
6120       mp->is_ipv6 = 1;
6121       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6122     }
6123   else
6124     {
6125       /* mp->is_ipv6 = 0; via memset in M macro above */
6126       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6127     }
6128
6129   /* send it... */
6130   S;
6131
6132   /* Wait for a reply, return good/bad news  */
6133   W;
6134
6135   /* NOTREACHED */
6136   return 0;
6137 }
6138
6139 static int
6140 api_reset_vrf (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_reset_vrf_t *mp;
6144   f64 timeout;
6145   u32 vrf_id = 0;
6146   u8 is_ipv6 = 0;
6147   u8 vrf_id_set = 0;
6148
6149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6150     {
6151       if (unformat (i, "vrf %d", &vrf_id))
6152         vrf_id_set = 1;
6153       else if (unformat (i, "ipv6"))
6154         is_ipv6 = 1;
6155       else
6156         {
6157           clib_warning ("parse error '%U'", format_unformat_error, i);
6158           return -99;
6159         }
6160     }
6161
6162   if (vrf_id_set == 0)
6163     {
6164       errmsg ("missing vrf id\n");
6165       return -99;
6166     }
6167
6168   M (RESET_VRF, reset_vrf);
6169
6170   mp->vrf_id = ntohl (vrf_id);
6171   mp->is_ipv6 = is_ipv6;
6172
6173   S;
6174   W;
6175   /* NOTREACHED */
6176   return 0;
6177 }
6178
6179 static int
6180 api_create_vlan_subif (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_create_vlan_subif_t *mp;
6184   f64 timeout;
6185   u32 sw_if_index;
6186   u8 sw_if_index_set = 0;
6187   u32 vlan_id;
6188   u8 vlan_id_set = 0;
6189
6190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6191     {
6192       if (unformat (i, "sw_if_index %d", &sw_if_index))
6193         sw_if_index_set = 1;
6194       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6195         sw_if_index_set = 1;
6196       else if (unformat (i, "vlan %d", &vlan_id))
6197         vlan_id_set = 1;
6198       else
6199         {
6200           clib_warning ("parse error '%U'", format_unformat_error, i);
6201           return -99;
6202         }
6203     }
6204
6205   if (sw_if_index_set == 0)
6206     {
6207       errmsg ("missing interface name or sw_if_index\n");
6208       return -99;
6209     }
6210
6211   if (vlan_id_set == 0)
6212     {
6213       errmsg ("missing vlan_id\n");
6214       return -99;
6215     }
6216   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6217
6218   mp->sw_if_index = ntohl (sw_if_index);
6219   mp->vlan_id = ntohl (vlan_id);
6220
6221   S;
6222   W;
6223   /* NOTREACHED */
6224   return 0;
6225 }
6226
6227 #define foreach_create_subif_bit                \
6228 _(no_tags)                                      \
6229 _(one_tag)                                      \
6230 _(two_tags)                                     \
6231 _(dot1ad)                                       \
6232 _(exact_match)                                  \
6233 _(default_sub)                                  \
6234 _(outer_vlan_id_any)                            \
6235 _(inner_vlan_id_any)
6236
6237 static int
6238 api_create_subif (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_create_subif_t *mp;
6242   f64 timeout;
6243   u32 sw_if_index;
6244   u8 sw_if_index_set = 0;
6245   u32 sub_id;
6246   u8 sub_id_set = 0;
6247   u32 no_tags = 0;
6248   u32 one_tag = 0;
6249   u32 two_tags = 0;
6250   u32 dot1ad = 0;
6251   u32 exact_match = 0;
6252   u32 default_sub = 0;
6253   u32 outer_vlan_id_any = 0;
6254   u32 inner_vlan_id_any = 0;
6255   u32 tmp;
6256   u16 outer_vlan_id = 0;
6257   u16 inner_vlan_id = 0;
6258
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "sw_if_index %d", &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6264         sw_if_index_set = 1;
6265       else if (unformat (i, "sub_id %d", &sub_id))
6266         sub_id_set = 1;
6267       else if (unformat (i, "outer_vlan_id %d", &tmp))
6268         outer_vlan_id = tmp;
6269       else if (unformat (i, "inner_vlan_id %d", &tmp))
6270         inner_vlan_id = tmp;
6271
6272 #define _(a) else if (unformat (i, #a)) a = 1 ;
6273       foreach_create_subif_bit
6274 #undef _
6275         else
6276         {
6277           clib_warning ("parse error '%U'", format_unformat_error, i);
6278           return -99;
6279         }
6280     }
6281
6282   if (sw_if_index_set == 0)
6283     {
6284       errmsg ("missing interface name or sw_if_index\n");
6285       return -99;
6286     }
6287
6288   if (sub_id_set == 0)
6289     {
6290       errmsg ("missing sub_id\n");
6291       return -99;
6292     }
6293   M (CREATE_SUBIF, create_subif);
6294
6295   mp->sw_if_index = ntohl (sw_if_index);
6296   mp->sub_id = ntohl (sub_id);
6297
6298 #define _(a) mp->a = a;
6299   foreach_create_subif_bit;
6300 #undef _
6301
6302   mp->outer_vlan_id = ntohs (outer_vlan_id);
6303   mp->inner_vlan_id = ntohs (inner_vlan_id);
6304
6305   S;
6306   W;
6307   /* NOTREACHED */
6308   return 0;
6309 }
6310
6311 static int
6312 api_oam_add_del (vat_main_t * vam)
6313 {
6314   unformat_input_t *i = vam->input;
6315   vl_api_oam_add_del_t *mp;
6316   f64 timeout;
6317   u32 vrf_id = 0;
6318   u8 is_add = 1;
6319   ip4_address_t src, dst;
6320   u8 src_set = 0;
6321   u8 dst_set = 0;
6322
6323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6324     {
6325       if (unformat (i, "vrf %d", &vrf_id))
6326         ;
6327       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6328         src_set = 1;
6329       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6330         dst_set = 1;
6331       else if (unformat (i, "del"))
6332         is_add = 0;
6333       else
6334         {
6335           clib_warning ("parse error '%U'", format_unformat_error, i);
6336           return -99;
6337         }
6338     }
6339
6340   if (src_set == 0)
6341     {
6342       errmsg ("missing src addr\n");
6343       return -99;
6344     }
6345
6346   if (dst_set == 0)
6347     {
6348       errmsg ("missing dst addr\n");
6349       return -99;
6350     }
6351
6352   M (OAM_ADD_DEL, oam_add_del);
6353
6354   mp->vrf_id = ntohl (vrf_id);
6355   mp->is_add = is_add;
6356   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6357   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6358
6359   S;
6360   W;
6361   /* NOTREACHED */
6362   return 0;
6363 }
6364
6365 static int
6366 api_reset_fib (vat_main_t * vam)
6367 {
6368   unformat_input_t *i = vam->input;
6369   vl_api_reset_fib_t *mp;
6370   f64 timeout;
6371   u32 vrf_id = 0;
6372   u8 is_ipv6 = 0;
6373   u8 vrf_id_set = 0;
6374
6375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6376     {
6377       if (unformat (i, "vrf %d", &vrf_id))
6378         vrf_id_set = 1;
6379       else if (unformat (i, "ipv6"))
6380         is_ipv6 = 1;
6381       else
6382         {
6383           clib_warning ("parse error '%U'", format_unformat_error, i);
6384           return -99;
6385         }
6386     }
6387
6388   if (vrf_id_set == 0)
6389     {
6390       errmsg ("missing vrf id\n");
6391       return -99;
6392     }
6393
6394   M (RESET_FIB, reset_fib);
6395
6396   mp->vrf_id = ntohl (vrf_id);
6397   mp->is_ipv6 = is_ipv6;
6398
6399   S;
6400   W;
6401   /* NOTREACHED */
6402   return 0;
6403 }
6404
6405 static int
6406 api_dhcp_proxy_config (vat_main_t * vam)
6407 {
6408   unformat_input_t *i = vam->input;
6409   vl_api_dhcp_proxy_config_t *mp;
6410   f64 timeout;
6411   u32 vrf_id = 0;
6412   u8 is_add = 1;
6413   u8 insert_cid = 1;
6414   u8 v4_address_set = 0;
6415   u8 v6_address_set = 0;
6416   ip4_address_t v4address;
6417   ip6_address_t v6address;
6418   u8 v4_src_address_set = 0;
6419   u8 v6_src_address_set = 0;
6420   ip4_address_t v4srcaddress;
6421   ip6_address_t v6srcaddress;
6422
6423   /* Parse args required to build the message */
6424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6425     {
6426       if (unformat (i, "del"))
6427         is_add = 0;
6428       else if (unformat (i, "vrf %d", &vrf_id))
6429         ;
6430       else if (unformat (i, "insert-cid %d", &insert_cid))
6431         ;
6432       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6433         v4_address_set = 1;
6434       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6435         v6_address_set = 1;
6436       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6437         v4_src_address_set = 1;
6438       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6439         v6_src_address_set = 1;
6440       else
6441         break;
6442     }
6443
6444   if (v4_address_set && v6_address_set)
6445     {
6446       errmsg ("both v4 and v6 server addresses set\n");
6447       return -99;
6448     }
6449   if (!v4_address_set && !v6_address_set)
6450     {
6451       errmsg ("no server addresses set\n");
6452       return -99;
6453     }
6454
6455   if (v4_src_address_set && v6_src_address_set)
6456     {
6457       errmsg ("both v4 and v6  src addresses set\n");
6458       return -99;
6459     }
6460   if (!v4_src_address_set && !v6_src_address_set)
6461     {
6462       errmsg ("no src addresses set\n");
6463       return -99;
6464     }
6465
6466   if (!(v4_src_address_set && v4_address_set) &&
6467       !(v6_src_address_set && v6_address_set))
6468     {
6469       errmsg ("no matching server and src addresses set\n");
6470       return -99;
6471     }
6472
6473   /* Construct the API message */
6474   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6475
6476   mp->insert_circuit_id = insert_cid;
6477   mp->is_add = is_add;
6478   mp->vrf_id = ntohl (vrf_id);
6479   if (v6_address_set)
6480     {
6481       mp->is_ipv6 = 1;
6482       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6483       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6484     }
6485   else
6486     {
6487       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6488       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6489     }
6490
6491   /* send it... */
6492   S;
6493
6494   /* Wait for a reply, return good/bad news  */
6495   W;
6496   /* NOTREACHED */
6497   return 0;
6498 }
6499
6500 static int
6501 api_dhcp_proxy_config_2 (vat_main_t * vam)
6502 {
6503   unformat_input_t *i = vam->input;
6504   vl_api_dhcp_proxy_config_2_t *mp;
6505   f64 timeout;
6506   u32 rx_vrf_id = 0;
6507   u32 server_vrf_id = 0;
6508   u8 is_add = 1;
6509   u8 insert_cid = 1;
6510   u8 v4_address_set = 0;
6511   u8 v6_address_set = 0;
6512   ip4_address_t v4address;
6513   ip6_address_t v6address;
6514   u8 v4_src_address_set = 0;
6515   u8 v6_src_address_set = 0;
6516   ip4_address_t v4srcaddress;
6517   ip6_address_t v6srcaddress;
6518
6519   /* Parse args required to build the message */
6520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6521     {
6522       if (unformat (i, "del"))
6523         is_add = 0;
6524       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6525         ;
6526       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6527         ;
6528       else if (unformat (i, "insert-cid %d", &insert_cid))
6529         ;
6530       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6531         v4_address_set = 1;
6532       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6533         v6_address_set = 1;
6534       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6535         v4_src_address_set = 1;
6536       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6537         v6_src_address_set = 1;
6538       else
6539         break;
6540     }
6541
6542   if (v4_address_set && v6_address_set)
6543     {
6544       errmsg ("both v4 and v6 server addresses set\n");
6545       return -99;
6546     }
6547   if (!v4_address_set && !v6_address_set)
6548     {
6549       errmsg ("no server addresses set\n");
6550       return -99;
6551     }
6552
6553   if (v4_src_address_set && v6_src_address_set)
6554     {
6555       errmsg ("both v4 and v6  src addresses set\n");
6556       return -99;
6557     }
6558   if (!v4_src_address_set && !v6_src_address_set)
6559     {
6560       errmsg ("no src addresses set\n");
6561       return -99;
6562     }
6563
6564   if (!(v4_src_address_set && v4_address_set) &&
6565       !(v6_src_address_set && v6_address_set))
6566     {
6567       errmsg ("no matching server and src addresses set\n");
6568       return -99;
6569     }
6570
6571   /* Construct the API message */
6572   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6573
6574   mp->insert_circuit_id = insert_cid;
6575   mp->is_add = is_add;
6576   mp->rx_vrf_id = ntohl (rx_vrf_id);
6577   mp->server_vrf_id = ntohl (server_vrf_id);
6578   if (v6_address_set)
6579     {
6580       mp->is_ipv6 = 1;
6581       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6582       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6583     }
6584   else
6585     {
6586       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6587       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6588     }
6589
6590   /* send it... */
6591   S;
6592
6593   /* Wait for a reply, return good/bad news  */
6594   W;
6595   /* NOTREACHED */
6596   return 0;
6597 }
6598
6599 static int
6600 api_dhcp_proxy_set_vss (vat_main_t * vam)
6601 {
6602   unformat_input_t *i = vam->input;
6603   vl_api_dhcp_proxy_set_vss_t *mp;
6604   f64 timeout;
6605   u8 is_ipv6 = 0;
6606   u8 is_add = 1;
6607   u32 tbl_id;
6608   u8 tbl_id_set = 0;
6609   u32 oui;
6610   u8 oui_set = 0;
6611   u32 fib_id;
6612   u8 fib_id_set = 0;
6613
6614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6615     {
6616       if (unformat (i, "tbl_id %d", &tbl_id))
6617         tbl_id_set = 1;
6618       if (unformat (i, "fib_id %d", &fib_id))
6619         fib_id_set = 1;
6620       if (unformat (i, "oui %d", &oui))
6621         oui_set = 1;
6622       else if (unformat (i, "ipv6"))
6623         is_ipv6 = 1;
6624       else if (unformat (i, "del"))
6625         is_add = 0;
6626       else
6627         {
6628           clib_warning ("parse error '%U'", format_unformat_error, i);
6629           return -99;
6630         }
6631     }
6632
6633   if (tbl_id_set == 0)
6634     {
6635       errmsg ("missing tbl id\n");
6636       return -99;
6637     }
6638
6639   if (fib_id_set == 0)
6640     {
6641       errmsg ("missing fib id\n");
6642       return -99;
6643     }
6644   if (oui_set == 0)
6645     {
6646       errmsg ("missing oui\n");
6647       return -99;
6648     }
6649
6650   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6651   mp->tbl_id = ntohl (tbl_id);
6652   mp->fib_id = ntohl (fib_id);
6653   mp->oui = ntohl (oui);
6654   mp->is_ipv6 = is_ipv6;
6655   mp->is_add = is_add;
6656
6657   S;
6658   W;
6659   /* NOTREACHED */
6660   return 0;
6661 }
6662
6663 static int
6664 api_dhcp_client_config (vat_main_t * vam)
6665 {
6666   unformat_input_t *i = vam->input;
6667   vl_api_dhcp_client_config_t *mp;
6668   f64 timeout;
6669   u32 sw_if_index;
6670   u8 sw_if_index_set = 0;
6671   u8 is_add = 1;
6672   u8 *hostname = 0;
6673   u8 disable_event = 0;
6674
6675   /* Parse args required to build the message */
6676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6677     {
6678       if (unformat (i, "del"))
6679         is_add = 0;
6680       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6681         sw_if_index_set = 1;
6682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6683         sw_if_index_set = 1;
6684       else if (unformat (i, "hostname %s", &hostname))
6685         ;
6686       else if (unformat (i, "disable_event"))
6687         disable_event = 1;
6688       else
6689         break;
6690     }
6691
6692   if (sw_if_index_set == 0)
6693     {
6694       errmsg ("missing interface name or sw_if_index\n");
6695       return -99;
6696     }
6697
6698   if (vec_len (hostname) > 63)
6699     {
6700       errmsg ("hostname too long\n");
6701     }
6702   vec_add1 (hostname, 0);
6703
6704   /* Construct the API message */
6705   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6706
6707   mp->sw_if_index = ntohl (sw_if_index);
6708   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6709   vec_free (hostname);
6710   mp->is_add = is_add;
6711   mp->want_dhcp_event = disable_event ? 0 : 1;
6712   mp->pid = getpid ();
6713
6714   /* send it... */
6715   S;
6716
6717   /* Wait for a reply, return good/bad news  */
6718   W;
6719   /* NOTREACHED */
6720   return 0;
6721 }
6722
6723 static int
6724 api_set_ip_flow_hash (vat_main_t * vam)
6725 {
6726   unformat_input_t *i = vam->input;
6727   vl_api_set_ip_flow_hash_t *mp;
6728   f64 timeout;
6729   u32 vrf_id = 0;
6730   u8 is_ipv6 = 0;
6731   u8 vrf_id_set = 0;
6732   u8 src = 0;
6733   u8 dst = 0;
6734   u8 sport = 0;
6735   u8 dport = 0;
6736   u8 proto = 0;
6737   u8 reverse = 0;
6738
6739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6740     {
6741       if (unformat (i, "vrf %d", &vrf_id))
6742         vrf_id_set = 1;
6743       else if (unformat (i, "ipv6"))
6744         is_ipv6 = 1;
6745       else if (unformat (i, "src"))
6746         src = 1;
6747       else if (unformat (i, "dst"))
6748         dst = 1;
6749       else if (unformat (i, "sport"))
6750         sport = 1;
6751       else if (unformat (i, "dport"))
6752         dport = 1;
6753       else if (unformat (i, "proto"))
6754         proto = 1;
6755       else if (unformat (i, "reverse"))
6756         reverse = 1;
6757
6758       else
6759         {
6760           clib_warning ("parse error '%U'", format_unformat_error, i);
6761           return -99;
6762         }
6763     }
6764
6765   if (vrf_id_set == 0)
6766     {
6767       errmsg ("missing vrf id\n");
6768       return -99;
6769     }
6770
6771   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6772   mp->src = src;
6773   mp->dst = dst;
6774   mp->sport = sport;
6775   mp->dport = dport;
6776   mp->proto = proto;
6777   mp->reverse = reverse;
6778   mp->vrf_id = ntohl (vrf_id);
6779   mp->is_ipv6 = is_ipv6;
6780
6781   S;
6782   W;
6783   /* NOTREACHED */
6784   return 0;
6785 }
6786
6787 static int
6788 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6789 {
6790   unformat_input_t *i = vam->input;
6791   vl_api_sw_interface_ip6_enable_disable_t *mp;
6792   f64 timeout;
6793   u32 sw_if_index;
6794   u8 sw_if_index_set = 0;
6795   u8 enable = 0;
6796
6797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6798     {
6799       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6800         sw_if_index_set = 1;
6801       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6802         sw_if_index_set = 1;
6803       else if (unformat (i, "enable"))
6804         enable = 1;
6805       else if (unformat (i, "disable"))
6806         enable = 0;
6807       else
6808         {
6809           clib_warning ("parse error '%U'", format_unformat_error, i);
6810           return -99;
6811         }
6812     }
6813
6814   if (sw_if_index_set == 0)
6815     {
6816       errmsg ("missing interface name or sw_if_index\n");
6817       return -99;
6818     }
6819
6820   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6821
6822   mp->sw_if_index = ntohl (sw_if_index);
6823   mp->enable = enable;
6824
6825   S;
6826   W;
6827   /* NOTREACHED */
6828   return 0;
6829 }
6830
6831 static int
6832 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6833 {
6834   unformat_input_t *i = vam->input;
6835   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6836   f64 timeout;
6837   u32 sw_if_index;
6838   u8 sw_if_index_set = 0;
6839   u32 address_length = 0;
6840   u8 v6_address_set = 0;
6841   ip6_address_t v6address;
6842
6843   /* Parse args required to build the message */
6844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6845     {
6846       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6847         sw_if_index_set = 1;
6848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6849         sw_if_index_set = 1;
6850       else if (unformat (i, "%U/%d",
6851                          unformat_ip6_address, &v6address, &address_length))
6852         v6_address_set = 1;
6853       else
6854         break;
6855     }
6856
6857   if (sw_if_index_set == 0)
6858     {
6859       errmsg ("missing interface name or sw_if_index\n");
6860       return -99;
6861     }
6862   if (!v6_address_set)
6863     {
6864       errmsg ("no address set\n");
6865       return -99;
6866     }
6867
6868   /* Construct the API message */
6869   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6870      sw_interface_ip6_set_link_local_address);
6871
6872   mp->sw_if_index = ntohl (sw_if_index);
6873   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6874   mp->address_length = address_length;
6875
6876   /* send it... */
6877   S;
6878
6879   /* Wait for a reply, return good/bad news  */
6880   W;
6881
6882   /* NOTREACHED */
6883   return 0;
6884 }
6885
6886
6887 static int
6888 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6892   f64 timeout;
6893   u32 sw_if_index;
6894   u8 sw_if_index_set = 0;
6895   u32 address_length = 0;
6896   u8 v6_address_set = 0;
6897   ip6_address_t v6address;
6898   u8 use_default = 0;
6899   u8 no_advertise = 0;
6900   u8 off_link = 0;
6901   u8 no_autoconfig = 0;
6902   u8 no_onlink = 0;
6903   u8 is_no = 0;
6904   u32 val_lifetime = 0;
6905   u32 pref_lifetime = 0;
6906
6907   /* Parse args required to build the message */
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6911         sw_if_index_set = 1;
6912       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6913         sw_if_index_set = 1;
6914       else if (unformat (i, "%U/%d",
6915                          unformat_ip6_address, &v6address, &address_length))
6916         v6_address_set = 1;
6917       else if (unformat (i, "val_life %d", &val_lifetime))
6918         ;
6919       else if (unformat (i, "pref_life %d", &pref_lifetime))
6920         ;
6921       else if (unformat (i, "def"))
6922         use_default = 1;
6923       else if (unformat (i, "noadv"))
6924         no_advertise = 1;
6925       else if (unformat (i, "offl"))
6926         off_link = 1;
6927       else if (unformat (i, "noauto"))
6928         no_autoconfig = 1;
6929       else if (unformat (i, "nolink"))
6930         no_onlink = 1;
6931       else if (unformat (i, "isno"))
6932         is_no = 1;
6933       else
6934         {
6935           clib_warning ("parse error '%U'", format_unformat_error, i);
6936           return -99;
6937         }
6938     }
6939
6940   if (sw_if_index_set == 0)
6941     {
6942       errmsg ("missing interface name or sw_if_index\n");
6943       return -99;
6944     }
6945   if (!v6_address_set)
6946     {
6947       errmsg ("no address set\n");
6948       return -99;
6949     }
6950
6951   /* Construct the API message */
6952   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6953
6954   mp->sw_if_index = ntohl (sw_if_index);
6955   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6956   mp->address_length = address_length;
6957   mp->use_default = use_default;
6958   mp->no_advertise = no_advertise;
6959   mp->off_link = off_link;
6960   mp->no_autoconfig = no_autoconfig;
6961   mp->no_onlink = no_onlink;
6962   mp->is_no = is_no;
6963   mp->val_lifetime = ntohl (val_lifetime);
6964   mp->pref_lifetime = ntohl (pref_lifetime);
6965
6966   /* send it... */
6967   S;
6968
6969   /* Wait for a reply, return good/bad news  */
6970   W;
6971
6972   /* NOTREACHED */
6973   return 0;
6974 }
6975
6976 static int
6977 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6978 {
6979   unformat_input_t *i = vam->input;
6980   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6981   f64 timeout;
6982   u32 sw_if_index;
6983   u8 sw_if_index_set = 0;
6984   u8 suppress = 0;
6985   u8 managed = 0;
6986   u8 other = 0;
6987   u8 ll_option = 0;
6988   u8 send_unicast = 0;
6989   u8 cease = 0;
6990   u8 is_no = 0;
6991   u8 default_router = 0;
6992   u32 max_interval = 0;
6993   u32 min_interval = 0;
6994   u32 lifetime = 0;
6995   u32 initial_count = 0;
6996   u32 initial_interval = 0;
6997
6998
6999   /* Parse args required to build the message */
7000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7001     {
7002       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7003         sw_if_index_set = 1;
7004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7005         sw_if_index_set = 1;
7006       else if (unformat (i, "maxint %d", &max_interval))
7007         ;
7008       else if (unformat (i, "minint %d", &min_interval))
7009         ;
7010       else if (unformat (i, "life %d", &lifetime))
7011         ;
7012       else if (unformat (i, "count %d", &initial_count))
7013         ;
7014       else if (unformat (i, "interval %d", &initial_interval))
7015         ;
7016       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7017         suppress = 1;
7018       else if (unformat (i, "managed"))
7019         managed = 1;
7020       else if (unformat (i, "other"))
7021         other = 1;
7022       else if (unformat (i, "ll"))
7023         ll_option = 1;
7024       else if (unformat (i, "send"))
7025         send_unicast = 1;
7026       else if (unformat (i, "cease"))
7027         cease = 1;
7028       else if (unformat (i, "isno"))
7029         is_no = 1;
7030       else if (unformat (i, "def"))
7031         default_router = 1;
7032       else
7033         {
7034           clib_warning ("parse error '%U'", format_unformat_error, i);
7035           return -99;
7036         }
7037     }
7038
7039   if (sw_if_index_set == 0)
7040     {
7041       errmsg ("missing interface name or sw_if_index\n");
7042       return -99;
7043     }
7044
7045   /* Construct the API message */
7046   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7047
7048   mp->sw_if_index = ntohl (sw_if_index);
7049   mp->max_interval = ntohl (max_interval);
7050   mp->min_interval = ntohl (min_interval);
7051   mp->lifetime = ntohl (lifetime);
7052   mp->initial_count = ntohl (initial_count);
7053   mp->initial_interval = ntohl (initial_interval);
7054   mp->suppress = suppress;
7055   mp->managed = managed;
7056   mp->other = other;
7057   mp->ll_option = ll_option;
7058   mp->send_unicast = send_unicast;
7059   mp->cease = cease;
7060   mp->is_no = is_no;
7061   mp->default_router = default_router;
7062
7063   /* send it... */
7064   S;
7065
7066   /* Wait for a reply, return good/bad news  */
7067   W;
7068
7069   /* NOTREACHED */
7070   return 0;
7071 }
7072
7073 static int
7074 api_set_arp_neighbor_limit (vat_main_t * vam)
7075 {
7076   unformat_input_t *i = vam->input;
7077   vl_api_set_arp_neighbor_limit_t *mp;
7078   f64 timeout;
7079   u32 arp_nbr_limit;
7080   u8 limit_set = 0;
7081   u8 is_ipv6 = 0;
7082
7083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7084     {
7085       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7086         limit_set = 1;
7087       else if (unformat (i, "ipv6"))
7088         is_ipv6 = 1;
7089       else
7090         {
7091           clib_warning ("parse error '%U'", format_unformat_error, i);
7092           return -99;
7093         }
7094     }
7095
7096   if (limit_set == 0)
7097     {
7098       errmsg ("missing limit value\n");
7099       return -99;
7100     }
7101
7102   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7103
7104   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7105   mp->is_ipv6 = is_ipv6;
7106
7107   S;
7108   W;
7109   /* NOTREACHED */
7110   return 0;
7111 }
7112
7113 static int
7114 api_l2_patch_add_del (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_l2_patch_add_del_t *mp;
7118   f64 timeout;
7119   u32 rx_sw_if_index;
7120   u8 rx_sw_if_index_set = 0;
7121   u32 tx_sw_if_index;
7122   u8 tx_sw_if_index_set = 0;
7123   u8 is_add = 1;
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7129         rx_sw_if_index_set = 1;
7130       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7131         tx_sw_if_index_set = 1;
7132       else if (unformat (i, "rx"))
7133         {
7134           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7135             {
7136               if (unformat (i, "%U", unformat_sw_if_index, vam,
7137                             &rx_sw_if_index))
7138                 rx_sw_if_index_set = 1;
7139             }
7140           else
7141             break;
7142         }
7143       else if (unformat (i, "tx"))
7144         {
7145           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7146             {
7147               if (unformat (i, "%U", unformat_sw_if_index, vam,
7148                             &tx_sw_if_index))
7149                 tx_sw_if_index_set = 1;
7150             }
7151           else
7152             break;
7153         }
7154       else if (unformat (i, "del"))
7155         is_add = 0;
7156       else
7157         break;
7158     }
7159
7160   if (rx_sw_if_index_set == 0)
7161     {
7162       errmsg ("missing rx interface name or rx_sw_if_index\n");
7163       return -99;
7164     }
7165
7166   if (tx_sw_if_index_set == 0)
7167     {
7168       errmsg ("missing tx interface name or tx_sw_if_index\n");
7169       return -99;
7170     }
7171
7172   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7173
7174   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7175   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7176   mp->is_add = is_add;
7177
7178   S;
7179   W;
7180   /* NOTREACHED */
7181   return 0;
7182 }
7183
7184 static int
7185 api_ioam_enable (vat_main_t * vam)
7186 {
7187   unformat_input_t *input = vam->input;
7188   vl_api_ioam_enable_t *mp;
7189   f64 timeout;
7190   u32 id = 0;
7191   int has_trace_option = 0;
7192   int has_pow_option = 0;
7193   int has_ppc_option = 0;
7194
7195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7196     {
7197       if (unformat (input, "trace"))
7198         has_trace_option = 1;
7199       else if (unformat (input, "pow"))
7200         has_pow_option = 1;
7201       else if (unformat (input, "ppc encap"))
7202         has_ppc_option = PPC_ENCAP;
7203       else if (unformat (input, "ppc decap"))
7204         has_ppc_option = PPC_DECAP;
7205       else if (unformat (input, "ppc none"))
7206         has_ppc_option = PPC_NONE;
7207       else
7208         break;
7209     }
7210   M (IOAM_ENABLE, ioam_enable);
7211   mp->id = htons (id);
7212   mp->trace_ppc = has_ppc_option;
7213   mp->pow_enable = has_pow_option;
7214   mp->trace_enable = has_trace_option;
7215
7216   S;
7217   W;
7218
7219   return (0);
7220
7221 }
7222
7223
7224 static int
7225 api_ioam_disable (vat_main_t * vam)
7226 {
7227   vl_api_ioam_disable_t *mp;
7228   f64 timeout;
7229
7230   M (IOAM_DISABLE, ioam_disable);
7231   S;
7232   W;
7233   return 0;
7234 }
7235
7236 static int
7237 api_sr_tunnel_add_del (vat_main_t * vam)
7238 {
7239   unformat_input_t *i = vam->input;
7240   vl_api_sr_tunnel_add_del_t *mp;
7241   f64 timeout;
7242   int is_del = 0;
7243   int pl_index;
7244   ip6_address_t src_address;
7245   int src_address_set = 0;
7246   ip6_address_t dst_address;
7247   u32 dst_mask_width;
7248   int dst_address_set = 0;
7249   u16 flags = 0;
7250   u32 rx_table_id = 0;
7251   u32 tx_table_id = 0;
7252   ip6_address_t *segments = 0;
7253   ip6_address_t *this_seg;
7254   ip6_address_t *tags = 0;
7255   ip6_address_t *this_tag;
7256   ip6_address_t next_address, tag;
7257   u8 *name = 0;
7258   u8 *policy_name = 0;
7259
7260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261     {
7262       if (unformat (i, "del"))
7263         is_del = 1;
7264       else if (unformat (i, "name %s", &name))
7265         ;
7266       else if (unformat (i, "policy %s", &policy_name))
7267         ;
7268       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7269         ;
7270       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7271         ;
7272       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7273         src_address_set = 1;
7274       else if (unformat (i, "dst %U/%d",
7275                          unformat_ip6_address, &dst_address, &dst_mask_width))
7276         dst_address_set = 1;
7277       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7278         {
7279           vec_add2 (segments, this_seg, 1);
7280           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7281                        sizeof (*this_seg));
7282         }
7283       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7284         {
7285           vec_add2 (tags, this_tag, 1);
7286           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7287         }
7288       else if (unformat (i, "clean"))
7289         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7290       else if (unformat (i, "protected"))
7291         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7292       else if (unformat (i, "InPE %d", &pl_index))
7293         {
7294           if (pl_index <= 0 || pl_index > 4)
7295             {
7296             pl_index_range_error:
7297               errmsg ("pl index %d out of range\n", pl_index);
7298               return -99;
7299             }
7300           flags |=
7301             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7302         }
7303       else if (unformat (i, "EgPE %d", &pl_index))
7304         {
7305           if (pl_index <= 0 || pl_index > 4)
7306             goto pl_index_range_error;
7307           flags |=
7308             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7309         }
7310       else if (unformat (i, "OrgSrc %d", &pl_index))
7311         {
7312           if (pl_index <= 0 || pl_index > 4)
7313             goto pl_index_range_error;
7314           flags |=
7315             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7316         }
7317       else
7318         break;
7319     }
7320
7321   if (!src_address_set)
7322     {
7323       errmsg ("src address required\n");
7324       return -99;
7325     }
7326
7327   if (!dst_address_set)
7328     {
7329       errmsg ("dst address required\n");
7330       return -99;
7331     }
7332
7333   if (!segments)
7334     {
7335       errmsg ("at least one sr segment required\n");
7336       return -99;
7337     }
7338
7339   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7340       vec_len (segments) * sizeof (ip6_address_t)
7341       + vec_len (tags) * sizeof (ip6_address_t));
7342
7343   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7344   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7345   mp->dst_mask_width = dst_mask_width;
7346   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7347   mp->n_segments = vec_len (segments);
7348   mp->n_tags = vec_len (tags);
7349   mp->is_add = is_del == 0;
7350   clib_memcpy (mp->segs_and_tags, segments,
7351                vec_len (segments) * sizeof (ip6_address_t));
7352   clib_memcpy (mp->segs_and_tags +
7353                vec_len (segments) * sizeof (ip6_address_t), tags,
7354                vec_len (tags) * sizeof (ip6_address_t));
7355
7356   mp->outer_vrf_id = ntohl (rx_table_id);
7357   mp->inner_vrf_id = ntohl (tx_table_id);
7358   memcpy (mp->name, name, vec_len (name));
7359   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7360
7361   vec_free (segments);
7362   vec_free (tags);
7363
7364   S;
7365   W;
7366   /* NOTREACHED */
7367 }
7368
7369 static int
7370 api_sr_policy_add_del (vat_main_t * vam)
7371 {
7372   unformat_input_t *input = vam->input;
7373   vl_api_sr_policy_add_del_t *mp;
7374   f64 timeout;
7375   int is_del = 0;
7376   u8 *name = 0;
7377   u8 *tunnel_name = 0;
7378   u8 **tunnel_names = 0;
7379
7380   int name_set = 0;
7381   int tunnel_set = 0;
7382   int j = 0;
7383   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7384   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7385
7386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7387     {
7388       if (unformat (input, "del"))
7389         is_del = 1;
7390       else if (unformat (input, "name %s", &name))
7391         name_set = 1;
7392       else if (unformat (input, "tunnel %s", &tunnel_name))
7393         {
7394           if (tunnel_name)
7395             {
7396               vec_add1 (tunnel_names, tunnel_name);
7397               /* For serializer:
7398                  - length = #bytes to store in serial vector
7399                  - +1 = byte to store that length
7400                */
7401               tunnel_names_length += (vec_len (tunnel_name) + 1);
7402               tunnel_set = 1;
7403               tunnel_name = 0;
7404             }
7405         }
7406       else
7407         break;
7408     }
7409
7410   if (!name_set)
7411     {
7412       errmsg ("policy name required\n");
7413       return -99;
7414     }
7415
7416   if ((!tunnel_set) && (!is_del))
7417     {
7418       errmsg ("tunnel name required\n");
7419       return -99;
7420     }
7421
7422   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7423
7424
7425
7426   mp->is_add = !is_del;
7427
7428   memcpy (mp->name, name, vec_len (name));
7429   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7430   u8 *serial_orig = 0;
7431   vec_validate (serial_orig, tunnel_names_length);
7432   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7433   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7434
7435   for (j = 0; j < vec_len (tunnel_names); j++)
7436     {
7437       tun_name_len = vec_len (tunnel_names[j]);
7438       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7439       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7440       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7441       serial_orig += tun_name_len;      // Advance past the copy
7442     }
7443   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7444
7445   vec_free (tunnel_names);
7446   vec_free (tunnel_name);
7447
7448   S;
7449   W;
7450   /* NOTREACHED */
7451 }
7452
7453 static int
7454 api_sr_multicast_map_add_del (vat_main_t * vam)
7455 {
7456   unformat_input_t *input = vam->input;
7457   vl_api_sr_multicast_map_add_del_t *mp;
7458   f64 timeout;
7459   int is_del = 0;
7460   ip6_address_t multicast_address;
7461   u8 *policy_name = 0;
7462   int multicast_address_set = 0;
7463
7464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7465     {
7466       if (unformat (input, "del"))
7467         is_del = 1;
7468       else
7469         if (unformat
7470             (input, "address %U", unformat_ip6_address, &multicast_address))
7471         multicast_address_set = 1;
7472       else if (unformat (input, "sr-policy %s", &policy_name))
7473         ;
7474       else
7475         break;
7476     }
7477
7478   if (!is_del && !policy_name)
7479     {
7480       errmsg ("sr-policy name required\n");
7481       return -99;
7482     }
7483
7484
7485   if (!multicast_address_set)
7486     {
7487       errmsg ("address required\n");
7488       return -99;
7489     }
7490
7491   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7492
7493   mp->is_add = !is_del;
7494   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7495   clib_memcpy (mp->multicast_address, &multicast_address,
7496                sizeof (mp->multicast_address));
7497
7498
7499   vec_free (policy_name);
7500
7501   S;
7502   W;
7503   /* NOTREACHED */
7504 }
7505
7506
7507 #define foreach_ip4_proto_field                 \
7508 _(src_address)                                  \
7509 _(dst_address)                                  \
7510 _(tos)                                          \
7511 _(length)                                       \
7512 _(fragment_id)                                  \
7513 _(ttl)                                          \
7514 _(protocol)                                     \
7515 _(checksum)
7516
7517 uword
7518 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7519 {
7520   u8 **maskp = va_arg (*args, u8 **);
7521   u8 *mask = 0;
7522   u8 found_something = 0;
7523   ip4_header_t *ip;
7524
7525 #define _(a) u8 a=0;
7526   foreach_ip4_proto_field;
7527 #undef _
7528   u8 version = 0;
7529   u8 hdr_length = 0;
7530
7531
7532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7533     {
7534       if (unformat (input, "version"))
7535         version = 1;
7536       else if (unformat (input, "hdr_length"))
7537         hdr_length = 1;
7538       else if (unformat (input, "src"))
7539         src_address = 1;
7540       else if (unformat (input, "dst"))
7541         dst_address = 1;
7542       else if (unformat (input, "proto"))
7543         protocol = 1;
7544
7545 #define _(a) else if (unformat (input, #a)) a=1;
7546       foreach_ip4_proto_field
7547 #undef _
7548         else
7549         break;
7550     }
7551
7552 #define _(a) found_something += a;
7553   foreach_ip4_proto_field;
7554 #undef _
7555
7556   if (found_something == 0)
7557     return 0;
7558
7559   vec_validate (mask, sizeof (*ip) - 1);
7560
7561   ip = (ip4_header_t *) mask;
7562
7563 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7564   foreach_ip4_proto_field;
7565 #undef _
7566
7567   ip->ip_version_and_header_length = 0;
7568
7569   if (version)
7570     ip->ip_version_and_header_length |= 0xF0;
7571
7572   if (hdr_length)
7573     ip->ip_version_and_header_length |= 0x0F;
7574
7575   *maskp = mask;
7576   return 1;
7577 }
7578
7579 #define foreach_ip6_proto_field                 \
7580 _(src_address)                                  \
7581 _(dst_address)                                  \
7582 _(payload_length)                               \
7583 _(hop_limit)                                    \
7584 _(protocol)
7585
7586 uword
7587 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7588 {
7589   u8 **maskp = va_arg (*args, u8 **);
7590   u8 *mask = 0;
7591   u8 found_something = 0;
7592   ip6_header_t *ip;
7593   u32 ip_version_traffic_class_and_flow_label;
7594
7595 #define _(a) u8 a=0;
7596   foreach_ip6_proto_field;
7597 #undef _
7598   u8 version = 0;
7599   u8 traffic_class = 0;
7600   u8 flow_label = 0;
7601
7602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7603     {
7604       if (unformat (input, "version"))
7605         version = 1;
7606       else if (unformat (input, "traffic-class"))
7607         traffic_class = 1;
7608       else if (unformat (input, "flow-label"))
7609         flow_label = 1;
7610       else if (unformat (input, "src"))
7611         src_address = 1;
7612       else if (unformat (input, "dst"))
7613         dst_address = 1;
7614       else if (unformat (input, "proto"))
7615         protocol = 1;
7616
7617 #define _(a) else if (unformat (input, #a)) a=1;
7618       foreach_ip6_proto_field
7619 #undef _
7620         else
7621         break;
7622     }
7623
7624 #define _(a) found_something += a;
7625   foreach_ip6_proto_field;
7626 #undef _
7627
7628   if (found_something == 0)
7629     return 0;
7630
7631   vec_validate (mask, sizeof (*ip) - 1);
7632
7633   ip = (ip6_header_t *) mask;
7634
7635 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7636   foreach_ip6_proto_field;
7637 #undef _
7638
7639   ip_version_traffic_class_and_flow_label = 0;
7640
7641   if (version)
7642     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7643
7644   if (traffic_class)
7645     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7646
7647   if (flow_label)
7648     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7649
7650   ip->ip_version_traffic_class_and_flow_label =
7651     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7652
7653   *maskp = mask;
7654   return 1;
7655 }
7656
7657 uword
7658 unformat_l3_mask (unformat_input_t * input, va_list * args)
7659 {
7660   u8 **maskp = va_arg (*args, u8 **);
7661
7662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7663     {
7664       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7665         return 1;
7666       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7667         return 1;
7668       else
7669         break;
7670     }
7671   return 0;
7672 }
7673
7674 uword
7675 unformat_l2_mask (unformat_input_t * input, va_list * args)
7676 {
7677   u8 **maskp = va_arg (*args, u8 **);
7678   u8 *mask = 0;
7679   u8 src = 0;
7680   u8 dst = 0;
7681   u8 proto = 0;
7682   u8 tag1 = 0;
7683   u8 tag2 = 0;
7684   u8 ignore_tag1 = 0;
7685   u8 ignore_tag2 = 0;
7686   u8 cos1 = 0;
7687   u8 cos2 = 0;
7688   u8 dot1q = 0;
7689   u8 dot1ad = 0;
7690   int len = 14;
7691
7692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7693     {
7694       if (unformat (input, "src"))
7695         src = 1;
7696       else if (unformat (input, "dst"))
7697         dst = 1;
7698       else if (unformat (input, "proto"))
7699         proto = 1;
7700       else if (unformat (input, "tag1"))
7701         tag1 = 1;
7702       else if (unformat (input, "tag2"))
7703         tag2 = 1;
7704       else if (unformat (input, "ignore-tag1"))
7705         ignore_tag1 = 1;
7706       else if (unformat (input, "ignore-tag2"))
7707         ignore_tag2 = 1;
7708       else if (unformat (input, "cos1"))
7709         cos1 = 1;
7710       else if (unformat (input, "cos2"))
7711         cos2 = 1;
7712       else if (unformat (input, "dot1q"))
7713         dot1q = 1;
7714       else if (unformat (input, "dot1ad"))
7715         dot1ad = 1;
7716       else
7717         break;
7718     }
7719   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7720        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7721     return 0;
7722
7723   if (tag1 || ignore_tag1 || cos1 || dot1q)
7724     len = 18;
7725   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7726     len = 22;
7727
7728   vec_validate (mask, len - 1);
7729
7730   if (dst)
7731     memset (mask, 0xff, 6);
7732
7733   if (src)
7734     memset (mask + 6, 0xff, 6);
7735
7736   if (tag2 || dot1ad)
7737     {
7738       /* inner vlan tag */
7739       if (tag2)
7740         {
7741           mask[19] = 0xff;
7742           mask[18] = 0x0f;
7743         }
7744       if (cos2)
7745         mask[18] |= 0xe0;
7746       if (proto)
7747         mask[21] = mask[20] = 0xff;
7748       if (tag1)
7749         {
7750           mask[15] = 0xff;
7751           mask[14] = 0x0f;
7752         }
7753       if (cos1)
7754         mask[14] |= 0xe0;
7755       *maskp = mask;
7756       return 1;
7757     }
7758   if (tag1 | dot1q)
7759     {
7760       if (tag1)
7761         {
7762           mask[15] = 0xff;
7763           mask[14] = 0x0f;
7764         }
7765       if (cos1)
7766         mask[14] |= 0xe0;
7767       if (proto)
7768         mask[16] = mask[17] = 0xff;
7769
7770       *maskp = mask;
7771       return 1;
7772     }
7773   if (cos2)
7774     mask[18] |= 0xe0;
7775   if (cos1)
7776     mask[14] |= 0xe0;
7777   if (proto)
7778     mask[12] = mask[13] = 0xff;
7779
7780   *maskp = mask;
7781   return 1;
7782 }
7783
7784 uword
7785 unformat_classify_mask (unformat_input_t * input, va_list * args)
7786 {
7787   u8 **maskp = va_arg (*args, u8 **);
7788   u32 *skipp = va_arg (*args, u32 *);
7789   u32 *matchp = va_arg (*args, u32 *);
7790   u32 match;
7791   u8 *mask = 0;
7792   u8 *l2 = 0;
7793   u8 *l3 = 0;
7794   int i;
7795
7796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7797     {
7798       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7799         ;
7800       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7801         ;
7802       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7803         ;
7804       else
7805         break;
7806     }
7807
7808   if (mask || l2 || l3)
7809     {
7810       if (l2 || l3)
7811         {
7812           /* "With a free Ethernet header in every package" */
7813           if (l2 == 0)
7814             vec_validate (l2, 13);
7815           mask = l2;
7816           if (vec_len (l3))
7817             {
7818               vec_append (mask, l3);
7819               vec_free (l3);
7820             }
7821         }
7822
7823       /* Scan forward looking for the first significant mask octet */
7824       for (i = 0; i < vec_len (mask); i++)
7825         if (mask[i])
7826           break;
7827
7828       /* compute (skip, match) params */
7829       *skipp = i / sizeof (u32x4);
7830       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7831
7832       /* Pad mask to an even multiple of the vector size */
7833       while (vec_len (mask) % sizeof (u32x4))
7834         vec_add1 (mask, 0);
7835
7836       match = vec_len (mask) / sizeof (u32x4);
7837
7838       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7839         {
7840           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7841           if (*tmp || *(tmp + 1))
7842             break;
7843           match--;
7844         }
7845       if (match == 0)
7846         clib_warning ("BUG: match 0");
7847
7848       _vec_len (mask) = match * sizeof (u32x4);
7849
7850       *matchp = match;
7851       *maskp = mask;
7852
7853       return 1;
7854     }
7855
7856   return 0;
7857 }
7858
7859 #define foreach_l2_next                         \
7860 _(drop, DROP)                                   \
7861 _(ethernet, ETHERNET_INPUT)                     \
7862 _(ip4, IP4_INPUT)                               \
7863 _(ip6, IP6_INPUT)
7864
7865 uword
7866 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7867 {
7868   u32 *miss_next_indexp = va_arg (*args, u32 *);
7869   u32 next_index = 0;
7870   u32 tmp;
7871
7872 #define _(n,N) \
7873   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7874   foreach_l2_next;
7875 #undef _
7876
7877   if (unformat (input, "%d", &tmp))
7878     {
7879       next_index = tmp;
7880       goto out;
7881     }
7882
7883   return 0;
7884
7885 out:
7886   *miss_next_indexp = next_index;
7887   return 1;
7888 }
7889
7890 #define foreach_ip_next                         \
7891 _(miss, MISS)                                   \
7892 _(drop, DROP)                                   \
7893 _(local, LOCAL)                                 \
7894 _(rewrite, REWRITE)
7895
7896 uword
7897 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7898 {
7899   u32 *miss_next_indexp = va_arg (*args, u32 *);
7900   u32 next_index = 0;
7901   u32 tmp;
7902
7903 #define _(n,N) \
7904   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7905   foreach_ip_next;
7906 #undef _
7907
7908   if (unformat (input, "%d", &tmp))
7909     {
7910       next_index = tmp;
7911       goto out;
7912     }
7913
7914   return 0;
7915
7916 out:
7917   *miss_next_indexp = next_index;
7918   return 1;
7919 }
7920
7921 #define foreach_acl_next                        \
7922 _(deny, DENY)
7923
7924 uword
7925 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7926 {
7927   u32 *miss_next_indexp = va_arg (*args, u32 *);
7928   u32 next_index = 0;
7929   u32 tmp;
7930
7931 #define _(n,N) \
7932   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7933   foreach_acl_next;
7934 #undef _
7935
7936   if (unformat (input, "permit"))
7937     {
7938       next_index = ~0;
7939       goto out;
7940     }
7941   else if (unformat (input, "%d", &tmp))
7942     {
7943       next_index = tmp;
7944       goto out;
7945     }
7946
7947   return 0;
7948
7949 out:
7950   *miss_next_indexp = next_index;
7951   return 1;
7952 }
7953
7954 uword
7955 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7956 {
7957   u32 *r = va_arg (*args, u32 *);
7958
7959   if (unformat (input, "conform-color"))
7960     *r = POLICE_CONFORM;
7961   else if (unformat (input, "exceed-color"))
7962     *r = POLICE_EXCEED;
7963   else
7964     return 0;
7965
7966   return 1;
7967 }
7968
7969 static int
7970 api_classify_add_del_table (vat_main_t * vam)
7971 {
7972   unformat_input_t *i = vam->input;
7973   vl_api_classify_add_del_table_t *mp;
7974
7975   u32 nbuckets = 2;
7976   u32 skip = ~0;
7977   u32 match = ~0;
7978   int is_add = 1;
7979   u32 table_index = ~0;
7980   u32 next_table_index = ~0;
7981   u32 miss_next_index = ~0;
7982   u32 memory_size = 32 << 20;
7983   u8 *mask = 0;
7984   f64 timeout;
7985
7986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7987     {
7988       if (unformat (i, "del"))
7989         is_add = 0;
7990       else if (unformat (i, "buckets %d", &nbuckets))
7991         ;
7992       else if (unformat (i, "memory_size %d", &memory_size))
7993         ;
7994       else if (unformat (i, "skip %d", &skip))
7995         ;
7996       else if (unformat (i, "match %d", &match))
7997         ;
7998       else if (unformat (i, "table %d", &table_index))
7999         ;
8000       else if (unformat (i, "mask %U", unformat_classify_mask,
8001                          &mask, &skip, &match))
8002         ;
8003       else if (unformat (i, "next-table %d", &next_table_index))
8004         ;
8005       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8006                          &miss_next_index))
8007         ;
8008       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8009                          &miss_next_index))
8010         ;
8011       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8012                          &miss_next_index))
8013         ;
8014       else
8015         break;
8016     }
8017
8018   if (is_add && mask == 0)
8019     {
8020       errmsg ("Mask required\n");
8021       return -99;
8022     }
8023
8024   if (is_add && skip == ~0)
8025     {
8026       errmsg ("skip count required\n");
8027       return -99;
8028     }
8029
8030   if (is_add && match == ~0)
8031     {
8032       errmsg ("match count required\n");
8033       return -99;
8034     }
8035
8036   if (!is_add && table_index == ~0)
8037     {
8038       errmsg ("table index required for delete\n");
8039       return -99;
8040     }
8041
8042   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8043
8044   mp->is_add = is_add;
8045   mp->table_index = ntohl (table_index);
8046   mp->nbuckets = ntohl (nbuckets);
8047   mp->memory_size = ntohl (memory_size);
8048   mp->skip_n_vectors = ntohl (skip);
8049   mp->match_n_vectors = ntohl (match);
8050   mp->next_table_index = ntohl (next_table_index);
8051   mp->miss_next_index = ntohl (miss_next_index);
8052   clib_memcpy (mp->mask, mask, vec_len (mask));
8053
8054   vec_free (mask);
8055
8056   S;
8057   W;
8058   /* NOTREACHED */
8059 }
8060
8061 uword
8062 unformat_ip4_match (unformat_input_t * input, va_list * args)
8063 {
8064   u8 **matchp = va_arg (*args, u8 **);
8065   u8 *match = 0;
8066   ip4_header_t *ip;
8067   int version = 0;
8068   u32 version_val;
8069   int hdr_length = 0;
8070   u32 hdr_length_val;
8071   int src = 0, dst = 0;
8072   ip4_address_t src_val, dst_val;
8073   int proto = 0;
8074   u32 proto_val;
8075   int tos = 0;
8076   u32 tos_val;
8077   int length = 0;
8078   u32 length_val;
8079   int fragment_id = 0;
8080   u32 fragment_id_val;
8081   int ttl = 0;
8082   int ttl_val;
8083   int checksum = 0;
8084   u32 checksum_val;
8085
8086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8087     {
8088       if (unformat (input, "version %d", &version_val))
8089         version = 1;
8090       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8091         hdr_length = 1;
8092       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8093         src = 1;
8094       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8095         dst = 1;
8096       else if (unformat (input, "proto %d", &proto_val))
8097         proto = 1;
8098       else if (unformat (input, "tos %d", &tos_val))
8099         tos = 1;
8100       else if (unformat (input, "length %d", &length_val))
8101         length = 1;
8102       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8103         fragment_id = 1;
8104       else if (unformat (input, "ttl %d", &ttl_val))
8105         ttl = 1;
8106       else if (unformat (input, "checksum %d", &checksum_val))
8107         checksum = 1;
8108       else
8109         break;
8110     }
8111
8112   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8113       + ttl + checksum == 0)
8114     return 0;
8115
8116   /*
8117    * Aligned because we use the real comparison functions
8118    */
8119   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8120
8121   ip = (ip4_header_t *) match;
8122
8123   /* These are realistically matched in practice */
8124   if (src)
8125     ip->src_address.as_u32 = src_val.as_u32;
8126
8127   if (dst)
8128     ip->dst_address.as_u32 = dst_val.as_u32;
8129
8130   if (proto)
8131     ip->protocol = proto_val;
8132
8133
8134   /* These are not, but they're included for completeness */
8135   if (version)
8136     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8137
8138   if (hdr_length)
8139     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8140
8141   if (tos)
8142     ip->tos = tos_val;
8143
8144   if (length)
8145     ip->length = length_val;
8146
8147   if (ttl)
8148     ip->ttl = ttl_val;
8149
8150   if (checksum)
8151     ip->checksum = checksum_val;
8152
8153   *matchp = match;
8154   return 1;
8155 }
8156
8157 uword
8158 unformat_ip6_match (unformat_input_t * input, va_list * args)
8159 {
8160   u8 **matchp = va_arg (*args, u8 **);
8161   u8 *match = 0;
8162   ip6_header_t *ip;
8163   int version = 0;
8164   u32 version_val;
8165   u8 traffic_class = 0;
8166   u32 traffic_class_val = 0;
8167   u8 flow_label = 0;
8168   u8 flow_label_val;
8169   int src = 0, dst = 0;
8170   ip6_address_t src_val, dst_val;
8171   int proto = 0;
8172   u32 proto_val;
8173   int payload_length = 0;
8174   u32 payload_length_val;
8175   int hop_limit = 0;
8176   int hop_limit_val;
8177   u32 ip_version_traffic_class_and_flow_label;
8178
8179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8180     {
8181       if (unformat (input, "version %d", &version_val))
8182         version = 1;
8183       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8184         traffic_class = 1;
8185       else if (unformat (input, "flow_label %d", &flow_label_val))
8186         flow_label = 1;
8187       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8188         src = 1;
8189       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8190         dst = 1;
8191       else if (unformat (input, "proto %d", &proto_val))
8192         proto = 1;
8193       else if (unformat (input, "payload_length %d", &payload_length_val))
8194         payload_length = 1;
8195       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8196         hop_limit = 1;
8197       else
8198         break;
8199     }
8200
8201   if (version + traffic_class + flow_label + src + dst + proto +
8202       payload_length + hop_limit == 0)
8203     return 0;
8204
8205   /*
8206    * Aligned because we use the real comparison functions
8207    */
8208   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8209
8210   ip = (ip6_header_t *) match;
8211
8212   if (src)
8213     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8214
8215   if (dst)
8216     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8217
8218   if (proto)
8219     ip->protocol = proto_val;
8220
8221   ip_version_traffic_class_and_flow_label = 0;
8222
8223   if (version)
8224     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8225
8226   if (traffic_class)
8227     ip_version_traffic_class_and_flow_label |=
8228       (traffic_class_val & 0xFF) << 20;
8229
8230   if (flow_label)
8231     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8232
8233   ip->ip_version_traffic_class_and_flow_label =
8234     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8235
8236   if (payload_length)
8237     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8238
8239   if (hop_limit)
8240     ip->hop_limit = hop_limit_val;
8241
8242   *matchp = match;
8243   return 1;
8244 }
8245
8246 uword
8247 unformat_l3_match (unformat_input_t * input, va_list * args)
8248 {
8249   u8 **matchp = va_arg (*args, u8 **);
8250
8251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8252     {
8253       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8254         return 1;
8255       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8256         return 1;
8257       else
8258         break;
8259     }
8260   return 0;
8261 }
8262
8263 uword
8264 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8265 {
8266   u8 *tagp = va_arg (*args, u8 *);
8267   u32 tag;
8268
8269   if (unformat (input, "%d", &tag))
8270     {
8271       tagp[0] = (tag >> 8) & 0x0F;
8272       tagp[1] = tag & 0xFF;
8273       return 1;
8274     }
8275
8276   return 0;
8277 }
8278
8279 uword
8280 unformat_l2_match (unformat_input_t * input, va_list * args)
8281 {
8282   u8 **matchp = va_arg (*args, u8 **);
8283   u8 *match = 0;
8284   u8 src = 0;
8285   u8 src_val[6];
8286   u8 dst = 0;
8287   u8 dst_val[6];
8288   u8 proto = 0;
8289   u16 proto_val;
8290   u8 tag1 = 0;
8291   u8 tag1_val[2];
8292   u8 tag2 = 0;
8293   u8 tag2_val[2];
8294   int len = 14;
8295   u8 ignore_tag1 = 0;
8296   u8 ignore_tag2 = 0;
8297   u8 cos1 = 0;
8298   u8 cos2 = 0;
8299   u32 cos1_val = 0;
8300   u32 cos2_val = 0;
8301
8302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8303     {
8304       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8305         src = 1;
8306       else
8307         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8308         dst = 1;
8309       else if (unformat (input, "proto %U",
8310                          unformat_ethernet_type_host_byte_order, &proto_val))
8311         proto = 1;
8312       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8313         tag1 = 1;
8314       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8315         tag2 = 1;
8316       else if (unformat (input, "ignore-tag1"))
8317         ignore_tag1 = 1;
8318       else if (unformat (input, "ignore-tag2"))
8319         ignore_tag2 = 1;
8320       else if (unformat (input, "cos1 %d", &cos1_val))
8321         cos1 = 1;
8322       else if (unformat (input, "cos2 %d", &cos2_val))
8323         cos2 = 1;
8324       else
8325         break;
8326     }
8327   if ((src + dst + proto + tag1 + tag2 +
8328        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8329     return 0;
8330
8331   if (tag1 || ignore_tag1 || cos1)
8332     len = 18;
8333   if (tag2 || ignore_tag2 || cos2)
8334     len = 22;
8335
8336   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8337
8338   if (dst)
8339     clib_memcpy (match, dst_val, 6);
8340
8341   if (src)
8342     clib_memcpy (match + 6, src_val, 6);
8343
8344   if (tag2)
8345     {
8346       /* inner vlan tag */
8347       match[19] = tag2_val[1];
8348       match[18] = tag2_val[0];
8349       if (cos2)
8350         match[18] |= (cos2_val & 0x7) << 5;
8351       if (proto)
8352         {
8353           match[21] = proto_val & 0xff;
8354           match[20] = proto_val >> 8;
8355         }
8356       if (tag1)
8357         {
8358           match[15] = tag1_val[1];
8359           match[14] = tag1_val[0];
8360         }
8361       if (cos1)
8362         match[14] |= (cos1_val & 0x7) << 5;
8363       *matchp = match;
8364       return 1;
8365     }
8366   if (tag1)
8367     {
8368       match[15] = tag1_val[1];
8369       match[14] = tag1_val[0];
8370       if (proto)
8371         {
8372           match[17] = proto_val & 0xff;
8373           match[16] = proto_val >> 8;
8374         }
8375       if (cos1)
8376         match[14] |= (cos1_val & 0x7) << 5;
8377
8378       *matchp = match;
8379       return 1;
8380     }
8381   if (cos2)
8382     match[18] |= (cos2_val & 0x7) << 5;
8383   if (cos1)
8384     match[14] |= (cos1_val & 0x7) << 5;
8385   if (proto)
8386     {
8387       match[13] = proto_val & 0xff;
8388       match[12] = proto_val >> 8;
8389     }
8390
8391   *matchp = match;
8392   return 1;
8393 }
8394
8395
8396 uword
8397 unformat_classify_match (unformat_input_t * input, va_list * args)
8398 {
8399   u8 **matchp = va_arg (*args, u8 **);
8400   u32 skip_n_vectors = va_arg (*args, u32);
8401   u32 match_n_vectors = va_arg (*args, u32);
8402
8403   u8 *match = 0;
8404   u8 *l2 = 0;
8405   u8 *l3 = 0;
8406
8407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (input, "hex %U", unformat_hex_string, &match))
8410         ;
8411       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8412         ;
8413       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8414         ;
8415       else
8416         break;
8417     }
8418
8419   if (match || l2 || l3)
8420     {
8421       if (l2 || l3)
8422         {
8423           /* "Win a free Ethernet header in every packet" */
8424           if (l2 == 0)
8425             vec_validate_aligned (l2, 13, sizeof (u32x4));
8426           match = l2;
8427           if (vec_len (l3))
8428             {
8429               vec_append_aligned (match, l3, sizeof (u32x4));
8430               vec_free (l3);
8431             }
8432         }
8433
8434       /* Make sure the vector is big enough even if key is all 0's */
8435       vec_validate_aligned
8436         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8437          sizeof (u32x4));
8438
8439       /* Set size, include skipped vectors */
8440       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8441
8442       *matchp = match;
8443
8444       return 1;
8445     }
8446
8447   return 0;
8448 }
8449
8450 static int
8451 api_classify_add_del_session (vat_main_t * vam)
8452 {
8453   unformat_input_t *i = vam->input;
8454   vl_api_classify_add_del_session_t *mp;
8455   int is_add = 1;
8456   u32 table_index = ~0;
8457   u32 hit_next_index = ~0;
8458   u32 opaque_index = ~0;
8459   u8 *match = 0;
8460   i32 advance = 0;
8461   f64 timeout;
8462   u32 skip_n_vectors = 0;
8463   u32 match_n_vectors = 0;
8464
8465   /*
8466    * Warning: you have to supply skip_n and match_n
8467    * because the API client cant simply look at the classify
8468    * table object.
8469    */
8470
8471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8472     {
8473       if (unformat (i, "del"))
8474         is_add = 0;
8475       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8476                          &hit_next_index))
8477         ;
8478       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8479                          &hit_next_index))
8480         ;
8481       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8482                          &hit_next_index))
8483         ;
8484       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8485         ;
8486       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8487         ;
8488       else if (unformat (i, "opaque-index %d", &opaque_index))
8489         ;
8490       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8491         ;
8492       else if (unformat (i, "match_n %d", &match_n_vectors))
8493         ;
8494       else if (unformat (i, "match %U", unformat_classify_match,
8495                          &match, skip_n_vectors, match_n_vectors))
8496         ;
8497       else if (unformat (i, "advance %d", &advance))
8498         ;
8499       else if (unformat (i, "table-index %d", &table_index))
8500         ;
8501       else
8502         break;
8503     }
8504
8505   if (table_index == ~0)
8506     {
8507       errmsg ("Table index required\n");
8508       return -99;
8509     }
8510
8511   if (is_add && match == 0)
8512     {
8513       errmsg ("Match value required\n");
8514       return -99;
8515     }
8516
8517   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8518
8519   mp->is_add = is_add;
8520   mp->table_index = ntohl (table_index);
8521   mp->hit_next_index = ntohl (hit_next_index);
8522   mp->opaque_index = ntohl (opaque_index);
8523   mp->advance = ntohl (advance);
8524   clib_memcpy (mp->match, match, vec_len (match));
8525   vec_free (match);
8526
8527   S;
8528   W;
8529   /* NOTREACHED */
8530 }
8531
8532 static int
8533 api_classify_set_interface_ip_table (vat_main_t * vam)
8534 {
8535   unformat_input_t *i = vam->input;
8536   vl_api_classify_set_interface_ip_table_t *mp;
8537   f64 timeout;
8538   u32 sw_if_index;
8539   int sw_if_index_set;
8540   u32 table_index = ~0;
8541   u8 is_ipv6 = 0;
8542
8543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8544     {
8545       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8546         sw_if_index_set = 1;
8547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8548         sw_if_index_set = 1;
8549       else if (unformat (i, "table %d", &table_index))
8550         ;
8551       else
8552         {
8553           clib_warning ("parse error '%U'", format_unformat_error, i);
8554           return -99;
8555         }
8556     }
8557
8558   if (sw_if_index_set == 0)
8559     {
8560       errmsg ("missing interface name or sw_if_index\n");
8561       return -99;
8562     }
8563
8564
8565   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8566
8567   mp->sw_if_index = ntohl (sw_if_index);
8568   mp->table_index = ntohl (table_index);
8569   mp->is_ipv6 = is_ipv6;
8570
8571   S;
8572   W;
8573   /* NOTREACHED */
8574   return 0;
8575 }
8576
8577 static int
8578 api_classify_set_interface_l2_tables (vat_main_t * vam)
8579 {
8580   unformat_input_t *i = vam->input;
8581   vl_api_classify_set_interface_l2_tables_t *mp;
8582   f64 timeout;
8583   u32 sw_if_index;
8584   int sw_if_index_set;
8585   u32 ip4_table_index = ~0;
8586   u32 ip6_table_index = ~0;
8587   u32 other_table_index = ~0;
8588   u32 is_input = 1;
8589
8590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8591     {
8592       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8593         sw_if_index_set = 1;
8594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8595         sw_if_index_set = 1;
8596       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8597         ;
8598       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8599         ;
8600       else if (unformat (i, "other-table %d", &other_table_index))
8601         ;
8602       else if (unformat (i, "is-input %d", &is_input))
8603         ;
8604       else
8605         {
8606           clib_warning ("parse error '%U'", format_unformat_error, i);
8607           return -99;
8608         }
8609     }
8610
8611   if (sw_if_index_set == 0)
8612     {
8613       errmsg ("missing interface name or sw_if_index\n");
8614       return -99;
8615     }
8616
8617
8618   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8619
8620   mp->sw_if_index = ntohl (sw_if_index);
8621   mp->ip4_table_index = ntohl (ip4_table_index);
8622   mp->ip6_table_index = ntohl (ip6_table_index);
8623   mp->other_table_index = ntohl (other_table_index);
8624   mp->is_input = (u8) is_input;
8625
8626   S;
8627   W;
8628   /* NOTREACHED */
8629   return 0;
8630 }
8631
8632 static int
8633 api_set_ipfix_exporter (vat_main_t * vam)
8634 {
8635   unformat_input_t *i = vam->input;
8636   vl_api_set_ipfix_exporter_t *mp;
8637   ip4_address_t collector_address;
8638   u8 collector_address_set = 0;
8639   u32 collector_port = ~0;
8640   ip4_address_t src_address;
8641   u8 src_address_set = 0;
8642   u32 vrf_id = ~0;
8643   u32 path_mtu = ~0;
8644   u32 template_interval = ~0;
8645   u8 udp_checksum = 0;
8646   f64 timeout;
8647
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "collector_address %U", unformat_ip4_address,
8651                     &collector_address))
8652         collector_address_set = 1;
8653       else if (unformat (i, "collector_port %d", &collector_port))
8654         ;
8655       else if (unformat (i, "src_address %U", unformat_ip4_address,
8656                          &src_address))
8657         src_address_set = 1;
8658       else if (unformat (i, "vrf_id %d", &vrf_id))
8659         ;
8660       else if (unformat (i, "path_mtu %d", &path_mtu))
8661         ;
8662       else if (unformat (i, "template_interval %d", &template_interval))
8663         ;
8664       else if (unformat (i, "udp_checksum"))
8665         udp_checksum = 1;
8666       else
8667         break;
8668     }
8669
8670   if (collector_address_set == 0)
8671     {
8672       errmsg ("collector_address required\n");
8673       return -99;
8674     }
8675
8676   if (src_address_set == 0)
8677     {
8678       errmsg ("src_address required\n");
8679       return -99;
8680     }
8681
8682   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8683
8684   memcpy (mp->collector_address, collector_address.data,
8685           sizeof (collector_address.data));
8686   mp->collector_port = htons ((u16) collector_port);
8687   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8688   mp->vrf_id = htonl (vrf_id);
8689   mp->path_mtu = htonl (path_mtu);
8690   mp->template_interval = htonl (template_interval);
8691   mp->udp_checksum = udp_checksum;
8692
8693   S;
8694   W;
8695   /* NOTREACHED */
8696 }
8697
8698 static int
8699 api_set_ipfix_classify_stream (vat_main_t * vam)
8700 {
8701   unformat_input_t *i = vam->input;
8702   vl_api_set_ipfix_classify_stream_t *mp;
8703   u32 domain_id = 0;
8704   u32 src_port = UDP_DST_PORT_ipfix;
8705   f64 timeout;
8706
8707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8708     {
8709       if (unformat (i, "domain %d", &domain_id))
8710         ;
8711       else if (unformat (i, "src_port %d", &src_port))
8712         ;
8713       else
8714         {
8715           errmsg ("unknown input `%U'", format_unformat_error, i);
8716           return -99;
8717         }
8718     }
8719
8720   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8721
8722   mp->domain_id = htonl (domain_id);
8723   mp->src_port = htons ((u16) src_port);
8724
8725   S;
8726   W;
8727   /* NOTREACHED */
8728 }
8729
8730 static int
8731 api_ipfix_classify_table_add_del (vat_main_t * vam)
8732 {
8733   unformat_input_t *i = vam->input;
8734   vl_api_ipfix_classify_table_add_del_t *mp;
8735   int is_add = -1;
8736   u32 classify_table_index = ~0;
8737   u8 ip_version = 0;
8738   u8 transport_protocol = 255;
8739   f64 timeout;
8740
8741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8742     {
8743       if (unformat (i, "add"))
8744         is_add = 1;
8745       else if (unformat (i, "del"))
8746         is_add = 0;
8747       else if (unformat (i, "table %d", &classify_table_index))
8748         ;
8749       else if (unformat (i, "ip4"))
8750         ip_version = 4;
8751       else if (unformat (i, "ip6"))
8752         ip_version = 6;
8753       else if (unformat (i, "tcp"))
8754         transport_protocol = 6;
8755       else if (unformat (i, "udp"))
8756         transport_protocol = 17;
8757       else
8758         {
8759           errmsg ("unknown input `%U'", format_unformat_error, i);
8760           return -99;
8761         }
8762     }
8763
8764   if (is_add == -1)
8765     {
8766       errmsg ("expecting: add|del");
8767       return -99;
8768     }
8769   if (classify_table_index == ~0)
8770     {
8771       errmsg ("classifier table not specified");
8772       return -99;
8773     }
8774   if (ip_version == 0)
8775     {
8776       errmsg ("IP version not specified");
8777       return -99;
8778     }
8779
8780   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
8781
8782   mp->is_add = is_add;
8783   mp->table_id = htonl (classify_table_index);
8784   mp->ip_version = ip_version;
8785   mp->transport_protocol = transport_protocol;
8786
8787   S;
8788   W;
8789   /* NOTREACHED */
8790 }
8791
8792 static int
8793 api_get_node_index (vat_main_t * vam)
8794 {
8795   unformat_input_t *i = vam->input;
8796   vl_api_get_node_index_t *mp;
8797   f64 timeout;
8798   u8 *name = 0;
8799
8800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8801     {
8802       if (unformat (i, "node %s", &name))
8803         ;
8804       else
8805         break;
8806     }
8807   if (name == 0)
8808     {
8809       errmsg ("node name required\n");
8810       return -99;
8811     }
8812   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8813     {
8814       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8815       return -99;
8816     }
8817
8818   M (GET_NODE_INDEX, get_node_index);
8819   clib_memcpy (mp->node_name, name, vec_len (name));
8820   vec_free (name);
8821
8822   S;
8823   W;
8824   /* NOTREACHED */
8825   return 0;
8826 }
8827
8828 static int
8829 api_get_next_index (vat_main_t * vam)
8830 {
8831   unformat_input_t *i = vam->input;
8832   vl_api_get_next_index_t *mp;
8833   f64 timeout;
8834   u8 *node_name = 0, *next_node_name = 0;
8835
8836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8837     {
8838       if (unformat (i, "node-name %s", &node_name))
8839         ;
8840       else if (unformat (i, "next-node-name %s", &next_node_name))
8841         break;
8842     }
8843
8844   if (node_name == 0)
8845     {
8846       errmsg ("node name required\n");
8847       return -99;
8848     }
8849   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8850     {
8851       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8852       return -99;
8853     }
8854
8855   if (next_node_name == 0)
8856     {
8857       errmsg ("next node name required\n");
8858       return -99;
8859     }
8860   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8861     {
8862       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8863       return -99;
8864     }
8865
8866   M (GET_NEXT_INDEX, get_next_index);
8867   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8868   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8869   vec_free (node_name);
8870   vec_free (next_node_name);
8871
8872   S;
8873   W;
8874   /* NOTREACHED */
8875   return 0;
8876 }
8877
8878 static int
8879 api_add_node_next (vat_main_t * vam)
8880 {
8881   unformat_input_t *i = vam->input;
8882   vl_api_add_node_next_t *mp;
8883   f64 timeout;
8884   u8 *name = 0;
8885   u8 *next = 0;
8886
8887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8888     {
8889       if (unformat (i, "node %s", &name))
8890         ;
8891       else if (unformat (i, "next %s", &next))
8892         ;
8893       else
8894         break;
8895     }
8896   if (name == 0)
8897     {
8898       errmsg ("node name required\n");
8899       return -99;
8900     }
8901   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8902     {
8903       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8904       return -99;
8905     }
8906   if (next == 0)
8907     {
8908       errmsg ("next node required\n");
8909       return -99;
8910     }
8911   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8912     {
8913       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8914       return -99;
8915     }
8916
8917   M (ADD_NODE_NEXT, add_node_next);
8918   clib_memcpy (mp->node_name, name, vec_len (name));
8919   clib_memcpy (mp->next_name, next, vec_len (next));
8920   vec_free (name);
8921   vec_free (next);
8922
8923   S;
8924   W;
8925   /* NOTREACHED */
8926   return 0;
8927 }
8928
8929 static int
8930 api_l2tpv3_create_tunnel (vat_main_t * vam)
8931 {
8932   unformat_input_t *i = vam->input;
8933   ip6_address_t client_address, our_address;
8934   int client_address_set = 0;
8935   int our_address_set = 0;
8936   u32 local_session_id = 0;
8937   u32 remote_session_id = 0;
8938   u64 local_cookie = 0;
8939   u64 remote_cookie = 0;
8940   u8 l2_sublayer_present = 0;
8941   vl_api_l2tpv3_create_tunnel_t *mp;
8942   f64 timeout;
8943
8944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8945     {
8946       if (unformat (i, "client_address %U", unformat_ip6_address,
8947                     &client_address))
8948         client_address_set = 1;
8949       else if (unformat (i, "our_address %U", unformat_ip6_address,
8950                          &our_address))
8951         our_address_set = 1;
8952       else if (unformat (i, "local_session_id %d", &local_session_id))
8953         ;
8954       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8955         ;
8956       else if (unformat (i, "local_cookie %lld", &local_cookie))
8957         ;
8958       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8959         ;
8960       else if (unformat (i, "l2-sublayer-present"))
8961         l2_sublayer_present = 1;
8962       else
8963         break;
8964     }
8965
8966   if (client_address_set == 0)
8967     {
8968       errmsg ("client_address required\n");
8969       return -99;
8970     }
8971
8972   if (our_address_set == 0)
8973     {
8974       errmsg ("our_address required\n");
8975       return -99;
8976     }
8977
8978   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8979
8980   clib_memcpy (mp->client_address, client_address.as_u8,
8981                sizeof (mp->client_address));
8982
8983   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8984
8985   mp->local_session_id = ntohl (local_session_id);
8986   mp->remote_session_id = ntohl (remote_session_id);
8987   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8988   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8989   mp->l2_sublayer_present = l2_sublayer_present;
8990   mp->is_ipv6 = 1;
8991
8992   S;
8993   W;
8994   /* NOTREACHED */
8995   return 0;
8996 }
8997
8998 static int
8999 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9000 {
9001   unformat_input_t *i = vam->input;
9002   u32 sw_if_index;
9003   u8 sw_if_index_set = 0;
9004   u64 new_local_cookie = 0;
9005   u64 new_remote_cookie = 0;
9006   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9007   f64 timeout;
9008
9009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9010     {
9011       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9012         sw_if_index_set = 1;
9013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9014         sw_if_index_set = 1;
9015       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9016         ;
9017       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9018         ;
9019       else
9020         break;
9021     }
9022
9023   if (sw_if_index_set == 0)
9024     {
9025       errmsg ("missing interface name or sw_if_index\n");
9026       return -99;
9027     }
9028
9029   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9030
9031   mp->sw_if_index = ntohl (sw_if_index);
9032   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9033   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9034
9035   S;
9036   W;
9037   /* NOTREACHED */
9038   return 0;
9039 }
9040
9041 static int
9042 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9043 {
9044   unformat_input_t *i = vam->input;
9045   vl_api_l2tpv3_interface_enable_disable_t *mp;
9046   f64 timeout;
9047   u32 sw_if_index;
9048   u8 sw_if_index_set = 0;
9049   u8 enable_disable = 1;
9050
9051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9052     {
9053       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9054         sw_if_index_set = 1;
9055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9056         sw_if_index_set = 1;
9057       else if (unformat (i, "enable"))
9058         enable_disable = 1;
9059       else if (unformat (i, "disable"))
9060         enable_disable = 0;
9061       else
9062         break;
9063     }
9064
9065   if (sw_if_index_set == 0)
9066     {
9067       errmsg ("missing interface name or sw_if_index\n");
9068       return -99;
9069     }
9070
9071   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9072
9073   mp->sw_if_index = ntohl (sw_if_index);
9074   mp->enable_disable = enable_disable;
9075
9076   S;
9077   W;
9078   /* NOTREACHED */
9079   return 0;
9080 }
9081
9082 static int
9083 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9084 {
9085   unformat_input_t *i = vam->input;
9086   vl_api_l2tpv3_set_lookup_key_t *mp;
9087   f64 timeout;
9088   u8 key = ~0;
9089
9090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (i, "lookup_v6_src"))
9093         key = L2T_LOOKUP_SRC_ADDRESS;
9094       else if (unformat (i, "lookup_v6_dst"))
9095         key = L2T_LOOKUP_DST_ADDRESS;
9096       else if (unformat (i, "lookup_session_id"))
9097         key = L2T_LOOKUP_SESSION_ID;
9098       else
9099         break;
9100     }
9101
9102   if (key == (u8) ~ 0)
9103     {
9104       errmsg ("l2tp session lookup key unset\n");
9105       return -99;
9106     }
9107
9108   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9109
9110   mp->key = key;
9111
9112   S;
9113   W;
9114   /* NOTREACHED */
9115   return 0;
9116 }
9117
9118 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9119   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9120 {
9121   vat_main_t *vam = &vat_main;
9122
9123   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9124            format_ip6_address, mp->our_address,
9125            format_ip6_address, mp->client_address,
9126            clib_net_to_host_u32 (mp->sw_if_index));
9127
9128   fformat (vam->ofp,
9129            "   local cookies %016llx %016llx remote cookie %016llx\n",
9130            clib_net_to_host_u64 (mp->local_cookie[0]),
9131            clib_net_to_host_u64 (mp->local_cookie[1]),
9132            clib_net_to_host_u64 (mp->remote_cookie));
9133
9134   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9135            clib_net_to_host_u32 (mp->local_session_id),
9136            clib_net_to_host_u32 (mp->remote_session_id));
9137
9138   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9139            mp->l2_sublayer_present ? "preset" : "absent");
9140
9141 }
9142
9143 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9144   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9145 {
9146   vat_main_t *vam = &vat_main;
9147   vat_json_node_t *node = NULL;
9148   struct in6_addr addr;
9149
9150   if (VAT_JSON_ARRAY != vam->json_tree.type)
9151     {
9152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9153       vat_json_init_array (&vam->json_tree);
9154     }
9155   node = vat_json_array_add (&vam->json_tree);
9156
9157   vat_json_init_object (node);
9158
9159   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9160   vat_json_object_add_ip6 (node, "our_address", addr);
9161   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9162   vat_json_object_add_ip6 (node, "client_address", addr);
9163
9164   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9165   vat_json_init_array (lc);
9166   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9167   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9168   vat_json_object_add_uint (node, "remote_cookie",
9169                             clib_net_to_host_u64 (mp->remote_cookie));
9170
9171   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9172   vat_json_object_add_uint (node, "local_session_id",
9173                             clib_net_to_host_u32 (mp->local_session_id));
9174   vat_json_object_add_uint (node, "remote_session_id",
9175                             clib_net_to_host_u32 (mp->remote_session_id));
9176   vat_json_object_add_string_copy (node, "l2_sublayer",
9177                                    mp->l2_sublayer_present ? (u8 *) "present"
9178                                    : (u8 *) "absent");
9179 }
9180
9181 static int
9182 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9183 {
9184   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9185   f64 timeout;
9186
9187   /* Get list of l2tpv3-tunnel interfaces */
9188   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9189   S;
9190
9191   /* Use a control ping for synchronization */
9192   {
9193     vl_api_control_ping_t *mp;
9194     M (CONTROL_PING, control_ping);
9195     S;
9196   }
9197   W;
9198 }
9199
9200
9201 static void vl_api_sw_interface_tap_details_t_handler
9202   (vl_api_sw_interface_tap_details_t * mp)
9203 {
9204   vat_main_t *vam = &vat_main;
9205
9206   fformat (vam->ofp, "%-16s %d\n",
9207            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9208 }
9209
9210 static void vl_api_sw_interface_tap_details_t_handler_json
9211   (vl_api_sw_interface_tap_details_t * mp)
9212 {
9213   vat_main_t *vam = &vat_main;
9214   vat_json_node_t *node = NULL;
9215
9216   if (VAT_JSON_ARRAY != vam->json_tree.type)
9217     {
9218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9219       vat_json_init_array (&vam->json_tree);
9220     }
9221   node = vat_json_array_add (&vam->json_tree);
9222
9223   vat_json_init_object (node);
9224   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9225   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9226 }
9227
9228 static int
9229 api_sw_interface_tap_dump (vat_main_t * vam)
9230 {
9231   vl_api_sw_interface_tap_dump_t *mp;
9232   f64 timeout;
9233
9234   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9235   /* Get list of tap interfaces */
9236   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9237   S;
9238
9239   /* Use a control ping for synchronization */
9240   {
9241     vl_api_control_ping_t *mp;
9242     M (CONTROL_PING, control_ping);
9243     S;
9244   }
9245   W;
9246 }
9247
9248 static uword unformat_vxlan_decap_next
9249   (unformat_input_t * input, va_list * args)
9250 {
9251   u32 *result = va_arg (*args, u32 *);
9252   u32 tmp;
9253
9254   if (unformat (input, "drop"))
9255     *result = VXLAN_INPUT_NEXT_DROP;
9256   else if (unformat (input, "ip4"))
9257     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9258   else if (unformat (input, "ip6"))
9259     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9260   else if (unformat (input, "l2"))
9261     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9262   else if (unformat (input, "%d", &tmp))
9263     *result = tmp;
9264   else
9265     return 0;
9266   return 1;
9267 }
9268
9269 static int
9270 api_vxlan_add_del_tunnel (vat_main_t * vam)
9271 {
9272   unformat_input_t *line_input = vam->input;
9273   vl_api_vxlan_add_del_tunnel_t *mp;
9274   f64 timeout;
9275   ip4_address_t src4, dst4;
9276   ip6_address_t src6, dst6;
9277   u8 is_add = 1;
9278   u8 ipv4_set = 0, ipv6_set = 0;
9279   u8 src_set = 0;
9280   u8 dst_set = 0;
9281   u32 encap_vrf_id = 0;
9282   u32 decap_next_index = ~0;
9283   u32 vni = 0;
9284
9285   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9286     {
9287       if (unformat (line_input, "del"))
9288         is_add = 0;
9289       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9290         {
9291           ipv4_set = 1;
9292           src_set = 1;
9293         }
9294       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9295         {
9296           ipv4_set = 1;
9297           dst_set = 1;
9298         }
9299       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9300         {
9301           ipv6_set = 1;
9302           src_set = 1;
9303         }
9304       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9305         {
9306           ipv6_set = 1;
9307           dst_set = 1;
9308         }
9309       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9310         ;
9311       else if (unformat (line_input, "decap-next %U",
9312                          unformat_vxlan_decap_next, &decap_next_index))
9313         ;
9314       else if (unformat (line_input, "vni %d", &vni))
9315         ;
9316       else
9317         {
9318           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9319           return -99;
9320         }
9321     }
9322
9323   if (src_set == 0)
9324     {
9325       errmsg ("tunnel src address not specified\n");
9326       return -99;
9327     }
9328   if (dst_set == 0)
9329     {
9330       errmsg ("tunnel dst address not specified\n");
9331       return -99;
9332     }
9333
9334   if (ipv4_set && ipv6_set)
9335     {
9336       errmsg ("both IPv4 and IPv6 addresses specified");
9337       return -99;
9338     }
9339
9340   if ((vni == 0) || (vni >> 24))
9341     {
9342       errmsg ("vni not specified or out of range\n");
9343       return -99;
9344     }
9345
9346   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9347
9348   if (ipv6_set)
9349     {
9350       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9351       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9352     }
9353   else
9354     {
9355       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9356       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9357     }
9358   mp->encap_vrf_id = ntohl (encap_vrf_id);
9359   mp->decap_next_index = ntohl (decap_next_index);
9360   mp->vni = ntohl (vni);
9361   mp->is_add = is_add;
9362   mp->is_ipv6 = ipv6_set;
9363
9364   S;
9365   W;
9366   /* NOTREACHED */
9367   return 0;
9368 }
9369
9370 static void vl_api_vxlan_tunnel_details_t_handler
9371   (vl_api_vxlan_tunnel_details_t * mp)
9372 {
9373   vat_main_t *vam = &vat_main;
9374
9375   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9376            ntohl (mp->sw_if_index),
9377            format_ip46_address, &(mp->src_address[0]),
9378            IP46_TYPE_ANY,
9379            format_ip46_address, &(mp->dst_address[0]),
9380            IP46_TYPE_ANY,
9381            ntohl (mp->encap_vrf_id),
9382            ntohl (mp->decap_next_index), ntohl (mp->vni));
9383 }
9384
9385 static void vl_api_vxlan_tunnel_details_t_handler_json
9386   (vl_api_vxlan_tunnel_details_t * mp)
9387 {
9388   vat_main_t *vam = &vat_main;
9389   vat_json_node_t *node = NULL;
9390   struct in_addr ip4;
9391   struct in6_addr ip6;
9392
9393   if (VAT_JSON_ARRAY != vam->json_tree.type)
9394     {
9395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9396       vat_json_init_array (&vam->json_tree);
9397     }
9398   node = vat_json_array_add (&vam->json_tree);
9399
9400   vat_json_init_object (node);
9401   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9402   if (mp->is_ipv6)
9403     {
9404       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9405       vat_json_object_add_ip6 (node, "src_address", ip6);
9406       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9407       vat_json_object_add_ip6 (node, "dst_address", ip6);
9408     }
9409   else
9410     {
9411       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9412       vat_json_object_add_ip4 (node, "src_address", ip4);
9413       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9414       vat_json_object_add_ip4 (node, "dst_address", ip4);
9415     }
9416   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9417   vat_json_object_add_uint (node, "decap_next_index",
9418                             ntohl (mp->decap_next_index));
9419   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9420   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9421 }
9422
9423 static int
9424 api_vxlan_tunnel_dump (vat_main_t * vam)
9425 {
9426   unformat_input_t *i = vam->input;
9427   vl_api_vxlan_tunnel_dump_t *mp;
9428   f64 timeout;
9429   u32 sw_if_index;
9430   u8 sw_if_index_set = 0;
9431
9432   /* Parse args required to build the message */
9433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (i, "sw_if_index %d", &sw_if_index))
9436         sw_if_index_set = 1;
9437       else
9438         break;
9439     }
9440
9441   if (sw_if_index_set == 0)
9442     {
9443       sw_if_index = ~0;
9444     }
9445
9446   if (!vam->json_output)
9447     {
9448       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9449                "sw_if_index", "src_address", "dst_address",
9450                "encap_vrf_id", "decap_next_index", "vni");
9451     }
9452
9453   /* Get list of vxlan-tunnel interfaces */
9454   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9455
9456   mp->sw_if_index = htonl (sw_if_index);
9457
9458   S;
9459
9460   /* Use a control ping for synchronization */
9461   {
9462     vl_api_control_ping_t *mp;
9463     M (CONTROL_PING, control_ping);
9464     S;
9465   }
9466   W;
9467 }
9468
9469 static int
9470 api_gre_add_del_tunnel (vat_main_t * vam)
9471 {
9472   unformat_input_t *line_input = vam->input;
9473   vl_api_gre_add_del_tunnel_t *mp;
9474   f64 timeout;
9475   ip4_address_t src4, dst4;
9476   u8 is_add = 1;
9477   u8 src_set = 0;
9478   u8 dst_set = 0;
9479   u32 outer_fib_id = 0;
9480
9481   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9482     {
9483       if (unformat (line_input, "del"))
9484         is_add = 0;
9485       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9486         src_set = 1;
9487       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9488         dst_set = 1;
9489       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9490         ;
9491       else
9492         {
9493           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9494           return -99;
9495         }
9496     }
9497
9498   if (src_set == 0)
9499     {
9500       errmsg ("tunnel src address not specified\n");
9501       return -99;
9502     }
9503   if (dst_set == 0)
9504     {
9505       errmsg ("tunnel dst address not specified\n");
9506       return -99;
9507     }
9508
9509
9510   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9511
9512   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9513   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9514   mp->outer_fib_id = ntohl (outer_fib_id);
9515   mp->is_add = is_add;
9516
9517   S;
9518   W;
9519   /* NOTREACHED */
9520   return 0;
9521 }
9522
9523 static void vl_api_gre_tunnel_details_t_handler
9524   (vl_api_gre_tunnel_details_t * mp)
9525 {
9526   vat_main_t *vam = &vat_main;
9527
9528   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9529            ntohl (mp->sw_if_index),
9530            format_ip4_address, &mp->src_address,
9531            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9532 }
9533
9534 static void vl_api_gre_tunnel_details_t_handler_json
9535   (vl_api_gre_tunnel_details_t * mp)
9536 {
9537   vat_main_t *vam = &vat_main;
9538   vat_json_node_t *node = NULL;
9539   struct in_addr ip4;
9540
9541   if (VAT_JSON_ARRAY != vam->json_tree.type)
9542     {
9543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9544       vat_json_init_array (&vam->json_tree);
9545     }
9546   node = vat_json_array_add (&vam->json_tree);
9547
9548   vat_json_init_object (node);
9549   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9550   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9551   vat_json_object_add_ip4 (node, "src_address", ip4);
9552   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9553   vat_json_object_add_ip4 (node, "dst_address", ip4);
9554   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9555 }
9556
9557 static int
9558 api_gre_tunnel_dump (vat_main_t * vam)
9559 {
9560   unformat_input_t *i = vam->input;
9561   vl_api_gre_tunnel_dump_t *mp;
9562   f64 timeout;
9563   u32 sw_if_index;
9564   u8 sw_if_index_set = 0;
9565
9566   /* Parse args required to build the message */
9567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9568     {
9569       if (unformat (i, "sw_if_index %d", &sw_if_index))
9570         sw_if_index_set = 1;
9571       else
9572         break;
9573     }
9574
9575   if (sw_if_index_set == 0)
9576     {
9577       sw_if_index = ~0;
9578     }
9579
9580   if (!vam->json_output)
9581     {
9582       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9583                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9584     }
9585
9586   /* Get list of gre-tunnel interfaces */
9587   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9588
9589   mp->sw_if_index = htonl (sw_if_index);
9590
9591   S;
9592
9593   /* Use a control ping for synchronization */
9594   {
9595     vl_api_control_ping_t *mp;
9596     M (CONTROL_PING, control_ping);
9597     S;
9598   }
9599   W;
9600 }
9601
9602 static int
9603 api_l2_fib_clear_table (vat_main_t * vam)
9604 {
9605 //  unformat_input_t * i = vam->input;
9606   vl_api_l2_fib_clear_table_t *mp;
9607   f64 timeout;
9608
9609   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9610
9611   S;
9612   W;
9613   /* NOTREACHED */
9614   return 0;
9615 }
9616
9617 static int
9618 api_l2_interface_efp_filter (vat_main_t * vam)
9619 {
9620   unformat_input_t *i = vam->input;
9621   vl_api_l2_interface_efp_filter_t *mp;
9622   f64 timeout;
9623   u32 sw_if_index;
9624   u8 enable = 1;
9625   u8 sw_if_index_set = 0;
9626
9627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9628     {
9629       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9630         sw_if_index_set = 1;
9631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9632         sw_if_index_set = 1;
9633       else if (unformat (i, "enable"))
9634         enable = 1;
9635       else if (unformat (i, "disable"))
9636         enable = 0;
9637       else
9638         {
9639           clib_warning ("parse error '%U'", format_unformat_error, i);
9640           return -99;
9641         }
9642     }
9643
9644   if (sw_if_index_set == 0)
9645     {
9646       errmsg ("missing sw_if_index\n");
9647       return -99;
9648     }
9649
9650   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9651
9652   mp->sw_if_index = ntohl (sw_if_index);
9653   mp->enable_disable = enable;
9654
9655   S;
9656   W;
9657   /* NOTREACHED */
9658   return 0;
9659 }
9660
9661 #define foreach_vtr_op                          \
9662 _("disable",  L2_VTR_DISABLED)                  \
9663 _("push-1",  L2_VTR_PUSH_1)                     \
9664 _("push-2",  L2_VTR_PUSH_2)                     \
9665 _("pop-1",  L2_VTR_POP_1)                       \
9666 _("pop-2",  L2_VTR_POP_2)                       \
9667 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9668 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9669 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9670 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9671
9672 static int
9673 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9674 {
9675   unformat_input_t *i = vam->input;
9676   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9677   f64 timeout;
9678   u32 sw_if_index;
9679   u8 sw_if_index_set = 0;
9680   u8 vtr_op_set = 0;
9681   u32 vtr_op = 0;
9682   u32 push_dot1q = 1;
9683   u32 tag1 = ~0;
9684   u32 tag2 = ~0;
9685
9686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9687     {
9688       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9689         sw_if_index_set = 1;
9690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9691         sw_if_index_set = 1;
9692       else if (unformat (i, "vtr_op %d", &vtr_op))
9693         vtr_op_set = 1;
9694 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9695       foreach_vtr_op
9696 #undef _
9697         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9698         ;
9699       else if (unformat (i, "tag1 %d", &tag1))
9700         ;
9701       else if (unformat (i, "tag2 %d", &tag2))
9702         ;
9703       else
9704         {
9705           clib_warning ("parse error '%U'", format_unformat_error, i);
9706           return -99;
9707         }
9708     }
9709
9710   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9711     {
9712       errmsg ("missing vtr operation or sw_if_index\n");
9713       return -99;
9714     }
9715
9716   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9717     mp->sw_if_index = ntohl (sw_if_index);
9718   mp->vtr_op = ntohl (vtr_op);
9719   mp->push_dot1q = ntohl (push_dot1q);
9720   mp->tag1 = ntohl (tag1);
9721   mp->tag2 = ntohl (tag2);
9722
9723   S;
9724   W;
9725   /* NOTREACHED */
9726   return 0;
9727 }
9728
9729 static int
9730 api_create_vhost_user_if (vat_main_t * vam)
9731 {
9732   unformat_input_t *i = vam->input;
9733   vl_api_create_vhost_user_if_t *mp;
9734   f64 timeout;
9735   u8 *file_name;
9736   u8 is_server = 0;
9737   u8 file_name_set = 0;
9738   u32 custom_dev_instance = ~0;
9739   u8 hwaddr[6];
9740   u8 use_custom_mac = 0;
9741
9742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9743     {
9744       if (unformat (i, "socket %s", &file_name))
9745         {
9746           file_name_set = 1;
9747         }
9748       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9749         ;
9750       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9751         use_custom_mac = 1;
9752       else if (unformat (i, "server"))
9753         is_server = 1;
9754       else
9755         break;
9756     }
9757
9758   if (file_name_set == 0)
9759     {
9760       errmsg ("missing socket file name\n");
9761       return -99;
9762     }
9763
9764   if (vec_len (file_name) > 255)
9765     {
9766       errmsg ("socket file name too long\n");
9767       return -99;
9768     }
9769   vec_add1 (file_name, 0);
9770
9771   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9772
9773   mp->is_server = is_server;
9774   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9775   vec_free (file_name);
9776   if (custom_dev_instance != ~0)
9777     {
9778       mp->renumber = 1;
9779       mp->custom_dev_instance = ntohl (custom_dev_instance);
9780     }
9781   mp->use_custom_mac = use_custom_mac;
9782   clib_memcpy (mp->mac_address, hwaddr, 6);
9783
9784   S;
9785   W;
9786   /* NOTREACHED */
9787   return 0;
9788 }
9789
9790 static int
9791 api_modify_vhost_user_if (vat_main_t * vam)
9792 {
9793   unformat_input_t *i = vam->input;
9794   vl_api_modify_vhost_user_if_t *mp;
9795   f64 timeout;
9796   u8 *file_name;
9797   u8 is_server = 0;
9798   u8 file_name_set = 0;
9799   u32 custom_dev_instance = ~0;
9800   u8 sw_if_index_set = 0;
9801   u32 sw_if_index = (u32) ~ 0;
9802
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9806         sw_if_index_set = 1;
9807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9808         sw_if_index_set = 1;
9809       else if (unformat (i, "socket %s", &file_name))
9810         {
9811           file_name_set = 1;
9812         }
9813       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9814         ;
9815       else if (unformat (i, "server"))
9816         is_server = 1;
9817       else
9818         break;
9819     }
9820
9821   if (sw_if_index_set == 0)
9822     {
9823       errmsg ("missing sw_if_index or interface name\n");
9824       return -99;
9825     }
9826
9827   if (file_name_set == 0)
9828     {
9829       errmsg ("missing socket file name\n");
9830       return -99;
9831     }
9832
9833   if (vec_len (file_name) > 255)
9834     {
9835       errmsg ("socket file name too long\n");
9836       return -99;
9837     }
9838   vec_add1 (file_name, 0);
9839
9840   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9841
9842   mp->sw_if_index = ntohl (sw_if_index);
9843   mp->is_server = is_server;
9844   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9845   vec_free (file_name);
9846   if (custom_dev_instance != ~0)
9847     {
9848       mp->renumber = 1;
9849       mp->custom_dev_instance = ntohl (custom_dev_instance);
9850     }
9851
9852   S;
9853   W;
9854   /* NOTREACHED */
9855   return 0;
9856 }
9857
9858 static int
9859 api_delete_vhost_user_if (vat_main_t * vam)
9860 {
9861   unformat_input_t *i = vam->input;
9862   vl_api_delete_vhost_user_if_t *mp;
9863   f64 timeout;
9864   u32 sw_if_index = ~0;
9865   u8 sw_if_index_set = 0;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else
9874         break;
9875     }
9876
9877   if (sw_if_index_set == 0)
9878     {
9879       errmsg ("missing sw_if_index or interface name\n");
9880       return -99;
9881     }
9882
9883
9884   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9885
9886   mp->sw_if_index = ntohl (sw_if_index);
9887
9888   S;
9889   W;
9890   /* NOTREACHED */
9891   return 0;
9892 }
9893
9894 static void vl_api_sw_interface_vhost_user_details_t_handler
9895   (vl_api_sw_interface_vhost_user_details_t * mp)
9896 {
9897   vat_main_t *vam = &vat_main;
9898
9899   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9900            (char *) mp->interface_name,
9901            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9902            clib_net_to_host_u64 (mp->features), mp->is_server,
9903            ntohl (mp->num_regions), (char *) mp->sock_filename);
9904   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9905 }
9906
9907 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9908   (vl_api_sw_interface_vhost_user_details_t * mp)
9909 {
9910   vat_main_t *vam = &vat_main;
9911   vat_json_node_t *node = NULL;
9912
9913   if (VAT_JSON_ARRAY != vam->json_tree.type)
9914     {
9915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9916       vat_json_init_array (&vam->json_tree);
9917     }
9918   node = vat_json_array_add (&vam->json_tree);
9919
9920   vat_json_init_object (node);
9921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9922   vat_json_object_add_string_copy (node, "interface_name",
9923                                    mp->interface_name);
9924   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9925                             ntohl (mp->virtio_net_hdr_sz));
9926   vat_json_object_add_uint (node, "features",
9927                             clib_net_to_host_u64 (mp->features));
9928   vat_json_object_add_uint (node, "is_server", mp->is_server);
9929   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9930   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9931   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9932 }
9933
9934 static int
9935 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9936 {
9937   vl_api_sw_interface_vhost_user_dump_t *mp;
9938   f64 timeout;
9939   fformat (vam->ofp,
9940            "Interface name           idx hdr_sz features server regions filename\n");
9941
9942   /* Get list of vhost-user interfaces */
9943   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9944   S;
9945
9946   /* Use a control ping for synchronization */
9947   {
9948     vl_api_control_ping_t *mp;
9949     M (CONTROL_PING, control_ping);
9950     S;
9951   }
9952   W;
9953 }
9954
9955 static int
9956 api_show_version (vat_main_t * vam)
9957 {
9958   vl_api_show_version_t *mp;
9959   f64 timeout;
9960
9961   M (SHOW_VERSION, show_version);
9962
9963   S;
9964   W;
9965   /* NOTREACHED */
9966   return 0;
9967 }
9968
9969
9970 static int
9971 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9972 {
9973   unformat_input_t *line_input = vam->input;
9974   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9975   f64 timeout;
9976   ip4_address_t local4, remote4;
9977   ip6_address_t local6, remote6;
9978   u8 is_add = 1;
9979   u8 ipv4_set = 0, ipv6_set = 0;
9980   u8 local_set = 0;
9981   u8 remote_set = 0;
9982   u32 encap_vrf_id = 0;
9983   u32 decap_vrf_id = 0;
9984   u8 protocol = ~0;
9985   u32 vni;
9986   u8 vni_set = 0;
9987
9988   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9989     {
9990       if (unformat (line_input, "del"))
9991         is_add = 0;
9992       else if (unformat (line_input, "local %U",
9993                          unformat_ip4_address, &local4))
9994         {
9995           local_set = 1;
9996           ipv4_set = 1;
9997         }
9998       else if (unformat (line_input, "remote %U",
9999                          unformat_ip4_address, &remote4))
10000         {
10001           remote_set = 1;
10002           ipv4_set = 1;
10003         }
10004       else if (unformat (line_input, "local %U",
10005                          unformat_ip6_address, &local6))
10006         {
10007           local_set = 1;
10008           ipv6_set = 1;
10009         }
10010       else if (unformat (line_input, "remote %U",
10011                          unformat_ip6_address, &remote6))
10012         {
10013           remote_set = 1;
10014           ipv6_set = 1;
10015         }
10016       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10017         ;
10018       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10019         ;
10020       else if (unformat (line_input, "vni %d", &vni))
10021         vni_set = 1;
10022       else if (unformat (line_input, "next-ip4"))
10023         protocol = 1;
10024       else if (unformat (line_input, "next-ip6"))
10025         protocol = 2;
10026       else if (unformat (line_input, "next-ethernet"))
10027         protocol = 3;
10028       else if (unformat (line_input, "next-nsh"))
10029         protocol = 4;
10030       else
10031         {
10032           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10033           return -99;
10034         }
10035     }
10036
10037   if (local_set == 0)
10038     {
10039       errmsg ("tunnel local address not specified\n");
10040       return -99;
10041     }
10042   if (remote_set == 0)
10043     {
10044       errmsg ("tunnel remote address not specified\n");
10045       return -99;
10046     }
10047   if (ipv4_set && ipv6_set)
10048     {
10049       errmsg ("both IPv4 and IPv6 addresses specified");
10050       return -99;
10051     }
10052
10053   if (vni_set == 0)
10054     {
10055       errmsg ("vni not specified\n");
10056       return -99;
10057     }
10058
10059   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10060
10061
10062   if (ipv6_set)
10063     {
10064       clib_memcpy (&mp->local, &local6, sizeof (local6));
10065       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10066     }
10067   else
10068     {
10069       clib_memcpy (&mp->local, &local4, sizeof (local4));
10070       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10071     }
10072
10073   mp->encap_vrf_id = ntohl (encap_vrf_id);
10074   mp->decap_vrf_id = ntohl (decap_vrf_id);
10075   mp->protocol = ntohl (protocol);
10076   mp->vni = ntohl (vni);
10077   mp->is_add = is_add;
10078   mp->is_ipv6 = ipv6_set;
10079
10080   S;
10081   W;
10082   /* NOTREACHED */
10083   return 0;
10084 }
10085
10086 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10087   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10088 {
10089   vat_main_t *vam = &vat_main;
10090
10091   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10092            ntohl (mp->sw_if_index),
10093            format_ip46_address, &(mp->local[0]),
10094            format_ip46_address, &(mp->remote[0]),
10095            ntohl (mp->vni),
10096            ntohl (mp->protocol),
10097            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10098 }
10099
10100 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10101   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10102 {
10103   vat_main_t *vam = &vat_main;
10104   vat_json_node_t *node = NULL;
10105   struct in_addr ip4;
10106   struct in6_addr ip6;
10107
10108   if (VAT_JSON_ARRAY != vam->json_tree.type)
10109     {
10110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10111       vat_json_init_array (&vam->json_tree);
10112     }
10113   node = vat_json_array_add (&vam->json_tree);
10114
10115   vat_json_init_object (node);
10116   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10117   if (mp->is_ipv6)
10118     {
10119       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10120       vat_json_object_add_ip6 (node, "local", ip6);
10121       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10122       vat_json_object_add_ip6 (node, "remote", ip6);
10123     }
10124   else
10125     {
10126       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10127       vat_json_object_add_ip4 (node, "local", ip4);
10128       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10129       vat_json_object_add_ip4 (node, "remote", ip4);
10130     }
10131   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10132   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10133   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10134   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10135   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10136 }
10137
10138 static int
10139 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10140 {
10141   unformat_input_t *i = vam->input;
10142   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10143   f64 timeout;
10144   u32 sw_if_index;
10145   u8 sw_if_index_set = 0;
10146
10147   /* Parse args required to build the message */
10148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10149     {
10150       if (unformat (i, "sw_if_index %d", &sw_if_index))
10151         sw_if_index_set = 1;
10152       else
10153         break;
10154     }
10155
10156   if (sw_if_index_set == 0)
10157     {
10158       sw_if_index = ~0;
10159     }
10160
10161   if (!vam->json_output)
10162     {
10163       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10164                "sw_if_index", "local", "remote", "vni",
10165                "protocol", "encap_vrf_id", "decap_vrf_id");
10166     }
10167
10168   /* Get list of vxlan-tunnel interfaces */
10169   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10170
10171   mp->sw_if_index = htonl (sw_if_index);
10172
10173   S;
10174
10175   /* Use a control ping for synchronization */
10176   {
10177     vl_api_control_ping_t *mp;
10178     M (CONTROL_PING, control_ping);
10179     S;
10180   }
10181   W;
10182 }
10183
10184 u8 *
10185 format_l2_fib_mac_address (u8 * s, va_list * args)
10186 {
10187   u8 *a = va_arg (*args, u8 *);
10188
10189   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10190                  a[2], a[3], a[4], a[5], a[6], a[7]);
10191 }
10192
10193 static void vl_api_l2_fib_table_entry_t_handler
10194   (vl_api_l2_fib_table_entry_t * mp)
10195 {
10196   vat_main_t *vam = &vat_main;
10197
10198   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10199            "       %d       %d     %d\n",
10200            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10201            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10202            mp->bvi_mac);
10203 }
10204
10205 static void vl_api_l2_fib_table_entry_t_handler_json
10206   (vl_api_l2_fib_table_entry_t * mp)
10207 {
10208   vat_main_t *vam = &vat_main;
10209   vat_json_node_t *node = NULL;
10210
10211   if (VAT_JSON_ARRAY != vam->json_tree.type)
10212     {
10213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10214       vat_json_init_array (&vam->json_tree);
10215     }
10216   node = vat_json_array_add (&vam->json_tree);
10217
10218   vat_json_init_object (node);
10219   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10220   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10221   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10222   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10223   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10224   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10225 }
10226
10227 static int
10228 api_l2_fib_table_dump (vat_main_t * vam)
10229 {
10230   unformat_input_t *i = vam->input;
10231   vl_api_l2_fib_table_dump_t *mp;
10232   f64 timeout;
10233   u32 bd_id;
10234   u8 bd_id_set = 0;
10235
10236   /* Parse args required to build the message */
10237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10238     {
10239       if (unformat (i, "bd_id %d", &bd_id))
10240         bd_id_set = 1;
10241       else
10242         break;
10243     }
10244
10245   if (bd_id_set == 0)
10246     {
10247       errmsg ("missing bridge domain\n");
10248       return -99;
10249     }
10250
10251   fformat (vam->ofp,
10252            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10253
10254   /* Get list of l2 fib entries */
10255   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10256
10257   mp->bd_id = ntohl (bd_id);
10258   S;
10259
10260   /* Use a control ping for synchronization */
10261   {
10262     vl_api_control_ping_t *mp;
10263     M (CONTROL_PING, control_ping);
10264     S;
10265   }
10266   W;
10267 }
10268
10269
10270 static int
10271 api_interface_name_renumber (vat_main_t * vam)
10272 {
10273   unformat_input_t *line_input = vam->input;
10274   vl_api_interface_name_renumber_t *mp;
10275   u32 sw_if_index = ~0;
10276   f64 timeout;
10277   u32 new_show_dev_instance = ~0;
10278
10279   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10280     {
10281       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10282                     &sw_if_index))
10283         ;
10284       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10285         ;
10286       else if (unformat (line_input, "new_show_dev_instance %d",
10287                          &new_show_dev_instance))
10288         ;
10289       else
10290         break;
10291     }
10292
10293   if (sw_if_index == ~0)
10294     {
10295       errmsg ("missing interface name or sw_if_index\n");
10296       return -99;
10297     }
10298
10299   if (new_show_dev_instance == ~0)
10300     {
10301       errmsg ("missing new_show_dev_instance\n");
10302       return -99;
10303     }
10304
10305   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10306
10307   mp->sw_if_index = ntohl (sw_if_index);
10308   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10309
10310   S;
10311   W;
10312 }
10313
10314 static int
10315 api_want_ip4_arp_events (vat_main_t * vam)
10316 {
10317   unformat_input_t *line_input = vam->input;
10318   vl_api_want_ip4_arp_events_t *mp;
10319   f64 timeout;
10320   ip4_address_t address;
10321   int address_set = 0;
10322   u32 enable_disable = 1;
10323
10324   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10325     {
10326       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10327         address_set = 1;
10328       else if (unformat (line_input, "del"))
10329         enable_disable = 0;
10330       else
10331         break;
10332     }
10333
10334   if (address_set == 0)
10335     {
10336       errmsg ("missing addresses\n");
10337       return -99;
10338     }
10339
10340   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10341   mp->enable_disable = enable_disable;
10342   mp->pid = getpid ();
10343   mp->address = address.as_u32;
10344
10345   S;
10346   W;
10347 }
10348
10349 static int
10350 api_want_ip6_nd_events (vat_main_t * vam)
10351 {
10352   unformat_input_t *line_input = vam->input;
10353   vl_api_want_ip6_nd_events_t *mp;
10354   f64 timeout;
10355   ip6_address_t address;
10356   int address_set = 0;
10357   u32 enable_disable = 1;
10358
10359   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10360     {
10361       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10362         address_set = 1;
10363       else if (unformat (line_input, "del"))
10364         enable_disable = 0;
10365       else
10366         break;
10367     }
10368
10369   if (address_set == 0)
10370     {
10371       errmsg ("missing addresses\n");
10372       return -99;
10373     }
10374
10375   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10376   mp->enable_disable = enable_disable;
10377   mp->pid = getpid ();
10378   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10379
10380   S;
10381   W;
10382 }
10383
10384 static int
10385 api_input_acl_set_interface (vat_main_t * vam)
10386 {
10387   unformat_input_t *i = vam->input;
10388   vl_api_input_acl_set_interface_t *mp;
10389   f64 timeout;
10390   u32 sw_if_index;
10391   int sw_if_index_set;
10392   u32 ip4_table_index = ~0;
10393   u32 ip6_table_index = ~0;
10394   u32 l2_table_index = ~0;
10395   u8 is_add = 1;
10396
10397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10398     {
10399       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10400         sw_if_index_set = 1;
10401       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10402         sw_if_index_set = 1;
10403       else if (unformat (i, "del"))
10404         is_add = 0;
10405       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10406         ;
10407       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10408         ;
10409       else if (unformat (i, "l2-table %d", &l2_table_index))
10410         ;
10411       else
10412         {
10413           clib_warning ("parse error '%U'", format_unformat_error, i);
10414           return -99;
10415         }
10416     }
10417
10418   if (sw_if_index_set == 0)
10419     {
10420       errmsg ("missing interface name or sw_if_index\n");
10421       return -99;
10422     }
10423
10424   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10425
10426   mp->sw_if_index = ntohl (sw_if_index);
10427   mp->ip4_table_index = ntohl (ip4_table_index);
10428   mp->ip6_table_index = ntohl (ip6_table_index);
10429   mp->l2_table_index = ntohl (l2_table_index);
10430   mp->is_add = is_add;
10431
10432   S;
10433   W;
10434   /* NOTREACHED */
10435   return 0;
10436 }
10437
10438 static int
10439 api_ip_address_dump (vat_main_t * vam)
10440 {
10441   unformat_input_t *i = vam->input;
10442   vl_api_ip_address_dump_t *mp;
10443   u32 sw_if_index = ~0;
10444   u8 sw_if_index_set = 0;
10445   u8 ipv4_set = 0;
10446   u8 ipv6_set = 0;
10447   f64 timeout;
10448
10449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (i, "sw_if_index %d", &sw_if_index))
10452         sw_if_index_set = 1;
10453       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10454         sw_if_index_set = 1;
10455       else if (unformat (i, "ipv4"))
10456         ipv4_set = 1;
10457       else if (unformat (i, "ipv6"))
10458         ipv6_set = 1;
10459       else
10460         break;
10461     }
10462
10463   if (ipv4_set && ipv6_set)
10464     {
10465       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10466       return -99;
10467     }
10468
10469   if ((!ipv4_set) && (!ipv6_set))
10470     {
10471       errmsg ("no ipv4 nor ipv6 flag set\n");
10472       return -99;
10473     }
10474
10475   if (sw_if_index_set == 0)
10476     {
10477       errmsg ("missing interface name or sw_if_index\n");
10478       return -99;
10479     }
10480
10481   vam->current_sw_if_index = sw_if_index;
10482   vam->is_ipv6 = ipv6_set;
10483
10484   M (IP_ADDRESS_DUMP, ip_address_dump);
10485   mp->sw_if_index = ntohl (sw_if_index);
10486   mp->is_ipv6 = ipv6_set;
10487   S;
10488
10489   /* Use a control ping for synchronization */
10490   {
10491     vl_api_control_ping_t *mp;
10492     M (CONTROL_PING, control_ping);
10493     S;
10494   }
10495   W;
10496 }
10497
10498 static int
10499 api_ip_dump (vat_main_t * vam)
10500 {
10501   vl_api_ip_dump_t *mp;
10502   unformat_input_t *in = vam->input;
10503   int ipv4_set = 0;
10504   int ipv6_set = 0;
10505   int is_ipv6;
10506   f64 timeout;
10507   int i;
10508
10509   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10510     {
10511       if (unformat (in, "ipv4"))
10512         ipv4_set = 1;
10513       else if (unformat (in, "ipv6"))
10514         ipv6_set = 1;
10515       else
10516         break;
10517     }
10518
10519   if (ipv4_set && ipv6_set)
10520     {
10521       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10522       return -99;
10523     }
10524
10525   if ((!ipv4_set) && (!ipv6_set))
10526     {
10527       errmsg ("no ipv4 nor ipv6 flag set\n");
10528       return -99;
10529     }
10530
10531   is_ipv6 = ipv6_set;
10532   vam->is_ipv6 = is_ipv6;
10533
10534   /* free old data */
10535   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10536     {
10537       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10538     }
10539   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10540
10541   M (IP_DUMP, ip_dump);
10542   mp->is_ipv6 = ipv6_set;
10543   S;
10544
10545   /* Use a control ping for synchronization */
10546   {
10547     vl_api_control_ping_t *mp;
10548     M (CONTROL_PING, control_ping);
10549     S;
10550   }
10551   W;
10552 }
10553
10554 static int
10555 api_ipsec_spd_add_del (vat_main_t * vam)
10556 {
10557 #if DPDK > 0
10558   unformat_input_t *i = vam->input;
10559   vl_api_ipsec_spd_add_del_t *mp;
10560   f64 timeout;
10561   u32 spd_id = ~0;
10562   u8 is_add = 1;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "spd_id %d", &spd_id))
10567         ;
10568       else if (unformat (i, "del"))
10569         is_add = 0;
10570       else
10571         {
10572           clib_warning ("parse error '%U'", format_unformat_error, i);
10573           return -99;
10574         }
10575     }
10576   if (spd_id == ~0)
10577     {
10578       errmsg ("spd_id must be set\n");
10579       return -99;
10580     }
10581
10582   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10583
10584   mp->spd_id = ntohl (spd_id);
10585   mp->is_add = is_add;
10586
10587   S;
10588   W;
10589   /* NOTREACHED */
10590   return 0;
10591 #else
10592   clib_warning ("unsupported (no dpdk)");
10593   return -99;
10594 #endif
10595 }
10596
10597 static int
10598 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10599 {
10600 #if DPDK > 0
10601   unformat_input_t *i = vam->input;
10602   vl_api_ipsec_interface_add_del_spd_t *mp;
10603   f64 timeout;
10604   u32 sw_if_index;
10605   u8 sw_if_index_set = 0;
10606   u32 spd_id = (u32) ~ 0;
10607   u8 is_add = 1;
10608
10609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10610     {
10611       if (unformat (i, "del"))
10612         is_add = 0;
10613       else if (unformat (i, "spd_id %d", &spd_id))
10614         ;
10615       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10616         sw_if_index_set = 1;
10617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10618         sw_if_index_set = 1;
10619       else
10620         {
10621           clib_warning ("parse error '%U'", format_unformat_error, i);
10622           return -99;
10623         }
10624
10625     }
10626
10627   if (spd_id == (u32) ~ 0)
10628     {
10629       errmsg ("spd_id must be set\n");
10630       return -99;
10631     }
10632
10633   if (sw_if_index_set == 0)
10634     {
10635       errmsg ("missing interface name or sw_if_index\n");
10636       return -99;
10637     }
10638
10639   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10640
10641   mp->spd_id = ntohl (spd_id);
10642   mp->sw_if_index = ntohl (sw_if_index);
10643   mp->is_add = is_add;
10644
10645   S;
10646   W;
10647   /* NOTREACHED */
10648   return 0;
10649 #else
10650   clib_warning ("unsupported (no dpdk)");
10651   return -99;
10652 #endif
10653 }
10654
10655 static int
10656 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10657 {
10658 #if DPDK > 0
10659   unformat_input_t *i = vam->input;
10660   vl_api_ipsec_spd_add_del_entry_t *mp;
10661   f64 timeout;
10662   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10663   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10664   i32 priority = 0;
10665   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10666   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10667   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10668   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10669
10670   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10671   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10672   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10673   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10674   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10675   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10676
10677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10678     {
10679       if (unformat (i, "del"))
10680         is_add = 0;
10681       if (unformat (i, "outbound"))
10682         is_outbound = 1;
10683       if (unformat (i, "inbound"))
10684         is_outbound = 0;
10685       else if (unformat (i, "spd_id %d", &spd_id))
10686         ;
10687       else if (unformat (i, "sa_id %d", &sa_id))
10688         ;
10689       else if (unformat (i, "priority %d", &priority))
10690         ;
10691       else if (unformat (i, "protocol %d", &protocol))
10692         ;
10693       else if (unformat (i, "lport_start %d", &lport_start))
10694         ;
10695       else if (unformat (i, "lport_stop %d", &lport_stop))
10696         ;
10697       else if (unformat (i, "rport_start %d", &rport_start))
10698         ;
10699       else if (unformat (i, "rport_stop %d", &rport_stop))
10700         ;
10701       else
10702         if (unformat
10703             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10704         {
10705           is_ipv6 = 0;
10706           is_ip_any = 0;
10707         }
10708       else
10709         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10710         {
10711           is_ipv6 = 0;
10712           is_ip_any = 0;
10713         }
10714       else
10715         if (unformat
10716             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10717         {
10718           is_ipv6 = 0;
10719           is_ip_any = 0;
10720         }
10721       else
10722         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10723         {
10724           is_ipv6 = 0;
10725           is_ip_any = 0;
10726         }
10727       else
10728         if (unformat
10729             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10730         {
10731           is_ipv6 = 1;
10732           is_ip_any = 0;
10733         }
10734       else
10735         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10736         {
10737           is_ipv6 = 1;
10738           is_ip_any = 0;
10739         }
10740       else
10741         if (unformat
10742             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10743         {
10744           is_ipv6 = 1;
10745           is_ip_any = 0;
10746         }
10747       else
10748         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10749         {
10750           is_ipv6 = 1;
10751           is_ip_any = 0;
10752         }
10753       else
10754         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10755         {
10756           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10757             {
10758               clib_warning ("unsupported action: 'resolve'");
10759               return -99;
10760             }
10761         }
10762       else
10763         {
10764           clib_warning ("parse error '%U'", format_unformat_error, i);
10765           return -99;
10766         }
10767
10768     }
10769
10770   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10771
10772   mp->spd_id = ntohl (spd_id);
10773   mp->priority = ntohl (priority);
10774   mp->is_outbound = is_outbound;
10775
10776   mp->is_ipv6 = is_ipv6;
10777   if (is_ipv6 || is_ip_any)
10778     {
10779       clib_memcpy (mp->remote_address_start, &raddr6_start,
10780                    sizeof (ip6_address_t));
10781       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10782                    sizeof (ip6_address_t));
10783       clib_memcpy (mp->local_address_start, &laddr6_start,
10784                    sizeof (ip6_address_t));
10785       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10786                    sizeof (ip6_address_t));
10787     }
10788   else
10789     {
10790       clib_memcpy (mp->remote_address_start, &raddr4_start,
10791                    sizeof (ip4_address_t));
10792       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10793                    sizeof (ip4_address_t));
10794       clib_memcpy (mp->local_address_start, &laddr4_start,
10795                    sizeof (ip4_address_t));
10796       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10797                    sizeof (ip4_address_t));
10798     }
10799   mp->protocol = (u8) protocol;
10800   mp->local_port_start = ntohs ((u16) lport_start);
10801   mp->local_port_stop = ntohs ((u16) lport_stop);
10802   mp->remote_port_start = ntohs ((u16) rport_start);
10803   mp->remote_port_stop = ntohs ((u16) rport_stop);
10804   mp->policy = (u8) policy;
10805   mp->sa_id = ntohl (sa_id);
10806   mp->is_add = is_add;
10807   mp->is_ip_any = is_ip_any;
10808   S;
10809   W;
10810   /* NOTREACHED */
10811   return 0;
10812 #else
10813   clib_warning ("unsupported (no dpdk)");
10814   return -99;
10815 #endif
10816 }
10817
10818 static int
10819 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10820 {
10821 #if DPDK > 0
10822   unformat_input_t *i = vam->input;
10823   vl_api_ipsec_sad_add_del_entry_t *mp;
10824   f64 timeout;
10825   u32 sad_id = 0, spi = 0;
10826   u8 *ck = 0, *ik = 0;
10827   u8 is_add = 1;
10828
10829   u8 protocol = IPSEC_PROTOCOL_AH;
10830   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10831   u32 crypto_alg = 0, integ_alg = 0;
10832   ip4_address_t tun_src4;
10833   ip4_address_t tun_dst4;
10834   ip6_address_t tun_src6;
10835   ip6_address_t tun_dst6;
10836
10837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10838     {
10839       if (unformat (i, "del"))
10840         is_add = 0;
10841       else if (unformat (i, "sad_id %d", &sad_id))
10842         ;
10843       else if (unformat (i, "spi %d", &spi))
10844         ;
10845       else if (unformat (i, "esp"))
10846         protocol = IPSEC_PROTOCOL_ESP;
10847       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10848         {
10849           is_tunnel = 1;
10850           is_tunnel_ipv6 = 0;
10851         }
10852       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10853         {
10854           is_tunnel = 1;
10855           is_tunnel_ipv6 = 0;
10856         }
10857       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10858         {
10859           is_tunnel = 1;
10860           is_tunnel_ipv6 = 1;
10861         }
10862       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10863         {
10864           is_tunnel = 1;
10865           is_tunnel_ipv6 = 1;
10866         }
10867       else
10868         if (unformat
10869             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10870         {
10871           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10872               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10873             {
10874               clib_warning ("unsupported crypto-alg: '%U'",
10875                             format_ipsec_crypto_alg, crypto_alg);
10876               return -99;
10877             }
10878         }
10879       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10880         ;
10881       else
10882         if (unformat
10883             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10884         {
10885           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10886               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10887             {
10888               clib_warning ("unsupported integ-alg: '%U'",
10889                             format_ipsec_integ_alg, integ_alg);
10890               return -99;
10891             }
10892         }
10893       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10894         ;
10895       else
10896         {
10897           clib_warning ("parse error '%U'", format_unformat_error, i);
10898           return -99;
10899         }
10900
10901     }
10902
10903   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10904
10905   mp->sad_id = ntohl (sad_id);
10906   mp->is_add = is_add;
10907   mp->protocol = protocol;
10908   mp->spi = ntohl (spi);
10909   mp->is_tunnel = is_tunnel;
10910   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10911   mp->crypto_algorithm = crypto_alg;
10912   mp->integrity_algorithm = integ_alg;
10913   mp->crypto_key_length = vec_len (ck);
10914   mp->integrity_key_length = vec_len (ik);
10915
10916   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10917     mp->crypto_key_length = sizeof (mp->crypto_key);
10918
10919   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10920     mp->integrity_key_length = sizeof (mp->integrity_key);
10921
10922   if (ck)
10923     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10924   if (ik)
10925     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10926
10927   if (is_tunnel)
10928     {
10929       if (is_tunnel_ipv6)
10930         {
10931           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10932                        sizeof (ip6_address_t));
10933           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10934                        sizeof (ip6_address_t));
10935         }
10936       else
10937         {
10938           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10939                        sizeof (ip4_address_t));
10940           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10941                        sizeof (ip4_address_t));
10942         }
10943     }
10944
10945   S;
10946   W;
10947   /* NOTREACHED */
10948   return 0;
10949 #else
10950   clib_warning ("unsupported (no dpdk)");
10951   return -99;
10952 #endif
10953 }
10954
10955 static int
10956 api_ipsec_sa_set_key (vat_main_t * vam)
10957 {
10958 #if DPDK > 0
10959   unformat_input_t *i = vam->input;
10960   vl_api_ipsec_sa_set_key_t *mp;
10961   f64 timeout;
10962   u32 sa_id;
10963   u8 *ck = 0, *ik = 0;
10964
10965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10966     {
10967       if (unformat (i, "sa_id %d", &sa_id))
10968         ;
10969       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10970         ;
10971       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10972         ;
10973       else
10974         {
10975           clib_warning ("parse error '%U'", format_unformat_error, i);
10976           return -99;
10977         }
10978     }
10979
10980   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10981
10982   mp->sa_id = ntohl (sa_id);
10983   mp->crypto_key_length = vec_len (ck);
10984   mp->integrity_key_length = vec_len (ik);
10985
10986   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10987     mp->crypto_key_length = sizeof (mp->crypto_key);
10988
10989   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10990     mp->integrity_key_length = sizeof (mp->integrity_key);
10991
10992   if (ck)
10993     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10994   if (ik)
10995     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10996
10997   S;
10998   W;
10999   /* NOTREACHED */
11000   return 0;
11001 #else
11002   clib_warning ("unsupported (no dpdk)");
11003   return -99;
11004 #endif
11005 }
11006
11007 static int
11008 api_ikev2_profile_add_del (vat_main_t * vam)
11009 {
11010 #if DPDK > 0
11011   unformat_input_t *i = vam->input;
11012   vl_api_ikev2_profile_add_del_t *mp;
11013   f64 timeout;
11014   u8 is_add = 1;
11015   u8 *name = 0;
11016
11017   const char *valid_chars = "a-zA-Z0-9_";
11018
11019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11020     {
11021       if (unformat (i, "del"))
11022         is_add = 0;
11023       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11024         vec_add1 (name, 0);
11025       else
11026         {
11027           errmsg ("parse error '%U'", format_unformat_error, i);
11028           return -99;
11029         }
11030     }
11031
11032   if (!vec_len (name))
11033     {
11034       errmsg ("profile name must be specified");
11035       return -99;
11036     }
11037
11038   if (vec_len (name) > 64)
11039     {
11040       errmsg ("profile name too long");
11041       return -99;
11042     }
11043
11044   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11045
11046   clib_memcpy (mp->name, name, vec_len (name));
11047   mp->is_add = is_add;
11048   vec_free (name);
11049
11050   S;
11051   W;
11052   /* NOTREACHED */
11053   return 0;
11054 #else
11055   clib_warning ("unsupported (no dpdk)");
11056   return -99;
11057 #endif
11058 }
11059
11060 static int
11061 api_ikev2_profile_set_auth (vat_main_t * vam)
11062 {
11063 #if DPDK > 0
11064   unformat_input_t *i = vam->input;
11065   vl_api_ikev2_profile_set_auth_t *mp;
11066   f64 timeout;
11067   u8 *name = 0;
11068   u8 *data = 0;
11069   u32 auth_method = 0;
11070   u8 is_hex = 0;
11071
11072   const char *valid_chars = "a-zA-Z0-9_";
11073
11074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11075     {
11076       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11077         vec_add1 (name, 0);
11078       else if (unformat (i, "auth_method %U",
11079                          unformat_ikev2_auth_method, &auth_method))
11080         ;
11081       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11082         is_hex = 1;
11083       else if (unformat (i, "auth_data %v", &data))
11084         ;
11085       else
11086         {
11087           errmsg ("parse error '%U'", format_unformat_error, i);
11088           return -99;
11089         }
11090     }
11091
11092   if (!vec_len (name))
11093     {
11094       errmsg ("profile name must be specified");
11095       return -99;
11096     }
11097
11098   if (vec_len (name) > 64)
11099     {
11100       errmsg ("profile name too long");
11101       return -99;
11102     }
11103
11104   if (!vec_len (data))
11105     {
11106       errmsg ("auth_data must be specified");
11107       return -99;
11108     }
11109
11110   if (!auth_method)
11111     {
11112       errmsg ("auth_method must be specified");
11113       return -99;
11114     }
11115
11116   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11117
11118   mp->is_hex = is_hex;
11119   mp->auth_method = (u8) auth_method;
11120   mp->data_len = vec_len (data);
11121   clib_memcpy (mp->name, name, vec_len (name));
11122   clib_memcpy (mp->data, data, vec_len (data));
11123   vec_free (name);
11124   vec_free (data);
11125
11126   S;
11127   W;
11128   /* NOTREACHED */
11129   return 0;
11130 #else
11131   clib_warning ("unsupported (no dpdk)");
11132   return -99;
11133 #endif
11134 }
11135
11136 static int
11137 api_ikev2_profile_set_id (vat_main_t * vam)
11138 {
11139 #if DPDK > 0
11140   unformat_input_t *i = vam->input;
11141   vl_api_ikev2_profile_set_id_t *mp;
11142   f64 timeout;
11143   u8 *name = 0;
11144   u8 *data = 0;
11145   u8 is_local = 0;
11146   u32 id_type = 0;
11147   ip4_address_t ip4;
11148
11149   const char *valid_chars = "a-zA-Z0-9_";
11150
11151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11152     {
11153       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11154         vec_add1 (name, 0);
11155       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11156         ;
11157       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11158         {
11159           data = vec_new (u8, 4);
11160           clib_memcpy (data, ip4.as_u8, 4);
11161         }
11162       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11163         ;
11164       else if (unformat (i, "id_data %v", &data))
11165         ;
11166       else if (unformat (i, "local"))
11167         is_local = 1;
11168       else if (unformat (i, "remote"))
11169         is_local = 0;
11170       else
11171         {
11172           errmsg ("parse error '%U'", format_unformat_error, i);
11173           return -99;
11174         }
11175     }
11176
11177   if (!vec_len (name))
11178     {
11179       errmsg ("profile name must be specified");
11180       return -99;
11181     }
11182
11183   if (vec_len (name) > 64)
11184     {
11185       errmsg ("profile name too long");
11186       return -99;
11187     }
11188
11189   if (!vec_len (data))
11190     {
11191       errmsg ("id_data must be specified");
11192       return -99;
11193     }
11194
11195   if (!id_type)
11196     {
11197       errmsg ("id_type must be specified");
11198       return -99;
11199     }
11200
11201   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11202
11203   mp->is_local = is_local;
11204   mp->id_type = (u8) id_type;
11205   mp->data_len = vec_len (data);
11206   clib_memcpy (mp->name, name, vec_len (name));
11207   clib_memcpy (mp->data, data, vec_len (data));
11208   vec_free (name);
11209   vec_free (data);
11210
11211   S;
11212   W;
11213   /* NOTREACHED */
11214   return 0;
11215 #else
11216   clib_warning ("unsupported (no dpdk)");
11217   return -99;
11218 #endif
11219 }
11220
11221 static int
11222 api_ikev2_profile_set_ts (vat_main_t * vam)
11223 {
11224 #if DPDK > 0
11225   unformat_input_t *i = vam->input;
11226   vl_api_ikev2_profile_set_ts_t *mp;
11227   f64 timeout;
11228   u8 *name = 0;
11229   u8 is_local = 0;
11230   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11231   ip4_address_t start_addr, end_addr;
11232
11233   const char *valid_chars = "a-zA-Z0-9_";
11234
11235   start_addr.as_u32 = 0;
11236   end_addr.as_u32 = (u32) ~ 0;
11237
11238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11239     {
11240       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11241         vec_add1 (name, 0);
11242       else if (unformat (i, "protocol %d", &proto))
11243         ;
11244       else if (unformat (i, "start_port %d", &start_port))
11245         ;
11246       else if (unformat (i, "end_port %d", &end_port))
11247         ;
11248       else
11249         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11250         ;
11251       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11252         ;
11253       else if (unformat (i, "local"))
11254         is_local = 1;
11255       else if (unformat (i, "remote"))
11256         is_local = 0;
11257       else
11258         {
11259           errmsg ("parse error '%U'", format_unformat_error, i);
11260           return -99;
11261         }
11262     }
11263
11264   if (!vec_len (name))
11265     {
11266       errmsg ("profile name must be specified");
11267       return -99;
11268     }
11269
11270   if (vec_len (name) > 64)
11271     {
11272       errmsg ("profile name too long");
11273       return -99;
11274     }
11275
11276   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11277
11278   mp->is_local = is_local;
11279   mp->proto = (u8) proto;
11280   mp->start_port = (u16) start_port;
11281   mp->end_port = (u16) end_port;
11282   mp->start_addr = start_addr.as_u32;
11283   mp->end_addr = end_addr.as_u32;
11284   clib_memcpy (mp->name, name, vec_len (name));
11285   vec_free (name);
11286
11287   S;
11288   W;
11289   /* NOTREACHED */
11290   return 0;
11291 #else
11292   clib_warning ("unsupported (no dpdk)");
11293   return -99;
11294 #endif
11295 }
11296
11297 static int
11298 api_ikev2_set_local_key (vat_main_t * vam)
11299 {
11300 #if DPDK > 0
11301   unformat_input_t *i = vam->input;
11302   vl_api_ikev2_set_local_key_t *mp;
11303   f64 timeout;
11304   u8 *file = 0;
11305
11306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11307     {
11308       if (unformat (i, "file %v", &file))
11309         vec_add1 (file, 0);
11310       else
11311         {
11312           errmsg ("parse error '%U'", format_unformat_error, i);
11313           return -99;
11314         }
11315     }
11316
11317   if (!vec_len (file))
11318     {
11319       errmsg ("RSA key file must be specified");
11320       return -99;
11321     }
11322
11323   if (vec_len (file) > 256)
11324     {
11325       errmsg ("file name too long");
11326       return -99;
11327     }
11328
11329   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11330
11331   clib_memcpy (mp->key_file, file, vec_len (file));
11332   vec_free (file);
11333
11334   S;
11335   W;
11336   /* NOTREACHED */
11337   return 0;
11338 #else
11339   clib_warning ("unsupported (no dpdk)");
11340   return -99;
11341 #endif
11342 }
11343
11344 /*
11345  * MAP
11346  */
11347 static int
11348 api_map_add_domain (vat_main_t * vam)
11349 {
11350   unformat_input_t *i = vam->input;
11351   vl_api_map_add_domain_t *mp;
11352   f64 timeout;
11353
11354   ip4_address_t ip4_prefix;
11355   ip6_address_t ip6_prefix;
11356   ip6_address_t ip6_src;
11357   u32 num_m_args = 0;
11358   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11359     0, psid_length = 0;
11360   u8 is_translation = 0;
11361   u32 mtu = 0;
11362   u32 ip6_src_len = 128;
11363
11364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11365     {
11366       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11367                     &ip4_prefix, &ip4_prefix_len))
11368         num_m_args++;
11369       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11370                          &ip6_prefix, &ip6_prefix_len))
11371         num_m_args++;
11372       else
11373         if (unformat
11374             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11375              &ip6_src_len))
11376         num_m_args++;
11377       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11378         num_m_args++;
11379       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11380         num_m_args++;
11381       else if (unformat (i, "psid-offset %d", &psid_offset))
11382         num_m_args++;
11383       else if (unformat (i, "psid-len %d", &psid_length))
11384         num_m_args++;
11385       else if (unformat (i, "mtu %d", &mtu))
11386         num_m_args++;
11387       else if (unformat (i, "map-t"))
11388         is_translation = 1;
11389       else
11390         {
11391           clib_warning ("parse error '%U'", format_unformat_error, i);
11392           return -99;
11393         }
11394     }
11395
11396   if (num_m_args < 3)
11397     {
11398       errmsg ("mandatory argument(s) missing\n");
11399       return -99;
11400     }
11401
11402   /* Construct the API message */
11403   M (MAP_ADD_DOMAIN, map_add_domain);
11404
11405   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11406   mp->ip4_prefix_len = ip4_prefix_len;
11407
11408   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11409   mp->ip6_prefix_len = ip6_prefix_len;
11410
11411   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11412   mp->ip6_src_prefix_len = ip6_src_len;
11413
11414   mp->ea_bits_len = ea_bits_len;
11415   mp->psid_offset = psid_offset;
11416   mp->psid_length = psid_length;
11417   mp->is_translation = is_translation;
11418   mp->mtu = htons (mtu);
11419
11420   /* send it... */
11421   S;
11422
11423   /* Wait for a reply, return good/bad news  */
11424   W;
11425 }
11426
11427 static int
11428 api_map_del_domain (vat_main_t * vam)
11429 {
11430   unformat_input_t *i = vam->input;
11431   vl_api_map_del_domain_t *mp;
11432   f64 timeout;
11433
11434   u32 num_m_args = 0;
11435   u32 index;
11436
11437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11438     {
11439       if (unformat (i, "index %d", &index))
11440         num_m_args++;
11441       else
11442         {
11443           clib_warning ("parse error '%U'", format_unformat_error, i);
11444           return -99;
11445         }
11446     }
11447
11448   if (num_m_args != 1)
11449     {
11450       errmsg ("mandatory argument(s) missing\n");
11451       return -99;
11452     }
11453
11454   /* Construct the API message */
11455   M (MAP_DEL_DOMAIN, map_del_domain);
11456
11457   mp->index = ntohl (index);
11458
11459   /* send it... */
11460   S;
11461
11462   /* Wait for a reply, return good/bad news  */
11463   W;
11464 }
11465
11466 static int
11467 api_map_add_del_rule (vat_main_t * vam)
11468 {
11469   unformat_input_t *i = vam->input;
11470   vl_api_map_add_del_rule_t *mp;
11471   f64 timeout;
11472   u8 is_add = 1;
11473   ip6_address_t ip6_dst;
11474   u32 num_m_args = 0, index, psid = 0;
11475
11476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11477     {
11478       if (unformat (i, "index %d", &index))
11479         num_m_args++;
11480       else if (unformat (i, "psid %d", &psid))
11481         num_m_args++;
11482       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11483         num_m_args++;
11484       else if (unformat (i, "del"))
11485         {
11486           is_add = 0;
11487         }
11488       else
11489         {
11490           clib_warning ("parse error '%U'", format_unformat_error, i);
11491           return -99;
11492         }
11493     }
11494
11495   /* Construct the API message */
11496   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11497
11498   mp->index = ntohl (index);
11499   mp->is_add = is_add;
11500   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11501   mp->psid = ntohs (psid);
11502
11503   /* send it... */
11504   S;
11505
11506   /* Wait for a reply, return good/bad news  */
11507   W;
11508 }
11509
11510 static int
11511 api_map_domain_dump (vat_main_t * vam)
11512 {
11513   vl_api_map_domain_dump_t *mp;
11514   f64 timeout;
11515
11516   /* Construct the API message */
11517   M (MAP_DOMAIN_DUMP, map_domain_dump);
11518
11519   /* send it... */
11520   S;
11521
11522   /* Use a control ping for synchronization */
11523   {
11524     vl_api_control_ping_t *mp;
11525     M (CONTROL_PING, control_ping);
11526     S;
11527   }
11528   W;
11529 }
11530
11531 static int
11532 api_map_rule_dump (vat_main_t * vam)
11533 {
11534   unformat_input_t *i = vam->input;
11535   vl_api_map_rule_dump_t *mp;
11536   f64 timeout;
11537   u32 domain_index = ~0;
11538
11539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (i, "index %u", &domain_index))
11542         ;
11543       else
11544         break;
11545     }
11546
11547   if (domain_index == ~0)
11548     {
11549       clib_warning ("parse error: domain index expected");
11550       return -99;
11551     }
11552
11553   /* Construct the API message */
11554   M (MAP_RULE_DUMP, map_rule_dump);
11555
11556   mp->domain_index = htonl (domain_index);
11557
11558   /* send it... */
11559   S;
11560
11561   /* Use a control ping for synchronization */
11562   {
11563     vl_api_control_ping_t *mp;
11564     M (CONTROL_PING, control_ping);
11565     S;
11566   }
11567   W;
11568 }
11569
11570 static void vl_api_map_add_domain_reply_t_handler
11571   (vl_api_map_add_domain_reply_t * mp)
11572 {
11573   vat_main_t *vam = &vat_main;
11574   i32 retval = ntohl (mp->retval);
11575
11576   if (vam->async_mode)
11577     {
11578       vam->async_errors += (retval < 0);
11579     }
11580   else
11581     {
11582       vam->retval = retval;
11583       vam->result_ready = 1;
11584     }
11585 }
11586
11587 static void vl_api_map_add_domain_reply_t_handler_json
11588   (vl_api_map_add_domain_reply_t * mp)
11589 {
11590   vat_main_t *vam = &vat_main;
11591   vat_json_node_t node;
11592
11593   vat_json_init_object (&node);
11594   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11595   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11596
11597   vat_json_print (vam->ofp, &node);
11598   vat_json_free (&node);
11599
11600   vam->retval = ntohl (mp->retval);
11601   vam->result_ready = 1;
11602 }
11603
11604 static int
11605 api_get_first_msg_id (vat_main_t * vam)
11606 {
11607   vl_api_get_first_msg_id_t *mp;
11608   f64 timeout;
11609   unformat_input_t *i = vam->input;
11610   u8 *name;
11611   u8 name_set = 0;
11612
11613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11614     {
11615       if (unformat (i, "client %s", &name))
11616         name_set = 1;
11617       else
11618         break;
11619     }
11620
11621   if (name_set == 0)
11622     {
11623       errmsg ("missing client name\n");
11624       return -99;
11625     }
11626   vec_add1 (name, 0);
11627
11628   if (vec_len (name) > 63)
11629     {
11630       errmsg ("client name too long\n");
11631       return -99;
11632     }
11633
11634   M (GET_FIRST_MSG_ID, get_first_msg_id);
11635   clib_memcpy (mp->name, name, vec_len (name));
11636   S;
11637   W;
11638   /* NOTREACHED */
11639   return 0;
11640 }
11641
11642 static int
11643 api_cop_interface_enable_disable (vat_main_t * vam)
11644 {
11645   unformat_input_t *line_input = vam->input;
11646   vl_api_cop_interface_enable_disable_t *mp;
11647   f64 timeout;
11648   u32 sw_if_index = ~0;
11649   u8 enable_disable = 1;
11650
11651   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11652     {
11653       if (unformat (line_input, "disable"))
11654         enable_disable = 0;
11655       if (unformat (line_input, "enable"))
11656         enable_disable = 1;
11657       else if (unformat (line_input, "%U", unformat_sw_if_index,
11658                          vam, &sw_if_index))
11659         ;
11660       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11661         ;
11662       else
11663         break;
11664     }
11665
11666   if (sw_if_index == ~0)
11667     {
11668       errmsg ("missing interface name or sw_if_index\n");
11669       return -99;
11670     }
11671
11672   /* Construct the API message */
11673   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11674   mp->sw_if_index = ntohl (sw_if_index);
11675   mp->enable_disable = enable_disable;
11676
11677   /* send it... */
11678   S;
11679   /* Wait for the reply */
11680   W;
11681 }
11682
11683 static int
11684 api_cop_whitelist_enable_disable (vat_main_t * vam)
11685 {
11686   unformat_input_t *line_input = vam->input;
11687   vl_api_cop_whitelist_enable_disable_t *mp;
11688   f64 timeout;
11689   u32 sw_if_index = ~0;
11690   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11691   u32 fib_id = 0;
11692
11693   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11694     {
11695       if (unformat (line_input, "ip4"))
11696         ip4 = 1;
11697       else if (unformat (line_input, "ip6"))
11698         ip6 = 1;
11699       else if (unformat (line_input, "default"))
11700         default_cop = 1;
11701       else if (unformat (line_input, "%U", unformat_sw_if_index,
11702                          vam, &sw_if_index))
11703         ;
11704       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11705         ;
11706       else if (unformat (line_input, "fib-id %d", &fib_id))
11707         ;
11708       else
11709         break;
11710     }
11711
11712   if (sw_if_index == ~0)
11713     {
11714       errmsg ("missing interface name or sw_if_index\n");
11715       return -99;
11716     }
11717
11718   /* Construct the API message */
11719   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11720   mp->sw_if_index = ntohl (sw_if_index);
11721   mp->fib_id = ntohl (fib_id);
11722   mp->ip4 = ip4;
11723   mp->ip6 = ip6;
11724   mp->default_cop = default_cop;
11725
11726   /* send it... */
11727   S;
11728   /* Wait for the reply */
11729   W;
11730 }
11731
11732 static int
11733 api_get_node_graph (vat_main_t * vam)
11734 {
11735   vl_api_get_node_graph_t *mp;
11736   f64 timeout;
11737
11738   M (GET_NODE_GRAPH, get_node_graph);
11739
11740   /* send it... */
11741   S;
11742   /* Wait for the reply */
11743   W;
11744 }
11745
11746 /* *INDENT-OFF* */
11747 /** Used for parsing LISP eids */
11748 typedef CLIB_PACKED(struct{
11749   u8 addr[16];   /**< eid address */
11750   u32 len;       /**< prefix length if IP */
11751   u8 type;      /**< type of eid */
11752 }) lisp_eid_vat_t;
11753 /* *INDENT-ON* */
11754
11755 static uword
11756 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11757 {
11758   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11759
11760   memset (a, 0, sizeof (a[0]));
11761
11762   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11763     {
11764       a->type = 0;              /* ipv4 type */
11765     }
11766   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11767     {
11768       a->type = 1;              /* ipv6 type */
11769     }
11770   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11771     {
11772       a->type = 2;              /* mac type */
11773     }
11774   else
11775     {
11776       return 0;
11777     }
11778
11779   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11780     {
11781       return 0;
11782     }
11783
11784   return 1;
11785 }
11786
11787 static int
11788 lisp_eid_size_vat (u8 type)
11789 {
11790   switch (type)
11791     {
11792     case 0:
11793       return 4;
11794     case 1:
11795       return 16;
11796     case 2:
11797       return 6;
11798     }
11799   return 0;
11800 }
11801
11802 static void
11803 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11804 {
11805   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11806 }
11807
11808 /* *INDENT-OFF* */
11809 /** Used for transferring locators via VPP API */
11810 typedef CLIB_PACKED(struct
11811 {
11812   u32 sw_if_index; /**< locator sw_if_index */
11813   u8 priority; /**< locator priority */
11814   u8 weight;   /**< locator weight */
11815 }) ls_locator_t;
11816 /* *INDENT-ON* */
11817
11818 static int
11819 api_lisp_add_del_locator_set (vat_main_t * vam)
11820 {
11821   unformat_input_t *input = vam->input;
11822   vl_api_lisp_add_del_locator_set_t *mp;
11823   f64 timeout = ~0;
11824   u8 is_add = 1;
11825   u8 *locator_set_name = NULL;
11826   u8 locator_set_name_set = 0;
11827   ls_locator_t locator, *locators = 0;
11828   u32 sw_if_index, priority, weight;
11829
11830   /* Parse args required to build the message */
11831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11832     {
11833       if (unformat (input, "del"))
11834         {
11835           is_add = 0;
11836         }
11837       else if (unformat (input, "locator-set %s", &locator_set_name))
11838         {
11839           locator_set_name_set = 1;
11840         }
11841       else if (unformat (input, "sw_if_index %u p %u w %u",
11842                          &sw_if_index, &priority, &weight))
11843         {
11844           locator.sw_if_index = htonl (sw_if_index);
11845           locator.priority = priority;
11846           locator.weight = weight;
11847           vec_add1 (locators, locator);
11848         }
11849       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11850                          vam, &sw_if_index, &priority, &weight))
11851         {
11852           locator.sw_if_index = htonl (sw_if_index);
11853           locator.priority = priority;
11854           locator.weight = weight;
11855           vec_add1 (locators, locator);
11856         }
11857       else
11858         break;
11859     }
11860
11861   if (locator_set_name_set == 0)
11862     {
11863       errmsg ("missing locator-set name");
11864       vec_free (locators);
11865       return -99;
11866     }
11867
11868   if (vec_len (locator_set_name) > 64)
11869     {
11870       errmsg ("locator-set name too long\n");
11871       vec_free (locator_set_name);
11872       vec_free (locators);
11873       return -99;
11874     }
11875   vec_add1 (locator_set_name, 0);
11876
11877   /* Construct the API message */
11878   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11879
11880   mp->is_add = is_add;
11881   clib_memcpy (mp->locator_set_name, locator_set_name,
11882                vec_len (locator_set_name));
11883   vec_free (locator_set_name);
11884
11885   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11886   if (locators)
11887     clib_memcpy (mp->locators, locators,
11888                  (sizeof (ls_locator_t) * vec_len (locators)));
11889   vec_free (locators);
11890
11891   /* send it... */
11892   S;
11893
11894   /* Wait for a reply... */
11895   W;
11896
11897   /* NOTREACHED */
11898   return 0;
11899 }
11900
11901 static int
11902 api_lisp_add_del_locator (vat_main_t * vam)
11903 {
11904   unformat_input_t *input = vam->input;
11905   vl_api_lisp_add_del_locator_t *mp;
11906   f64 timeout = ~0;
11907   u32 tmp_if_index = ~0;
11908   u32 sw_if_index = ~0;
11909   u8 sw_if_index_set = 0;
11910   u8 sw_if_index_if_name_set = 0;
11911   u32 priority = ~0;
11912   u8 priority_set = 0;
11913   u32 weight = ~0;
11914   u8 weight_set = 0;
11915   u8 is_add = 1;
11916   u8 *locator_set_name = NULL;
11917   u8 locator_set_name_set = 0;
11918
11919   /* Parse args required to build the message */
11920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11921     {
11922       if (unformat (input, "del"))
11923         {
11924           is_add = 0;
11925         }
11926       else if (unformat (input, "locator-set %s", &locator_set_name))
11927         {
11928           locator_set_name_set = 1;
11929         }
11930       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11931                          &tmp_if_index))
11932         {
11933           sw_if_index_if_name_set = 1;
11934           sw_if_index = tmp_if_index;
11935         }
11936       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11937         {
11938           sw_if_index_set = 1;
11939           sw_if_index = tmp_if_index;
11940         }
11941       else if (unformat (input, "p %d", &priority))
11942         {
11943           priority_set = 1;
11944         }
11945       else if (unformat (input, "w %d", &weight))
11946         {
11947           weight_set = 1;
11948         }
11949       else
11950         break;
11951     }
11952
11953   if (locator_set_name_set == 0)
11954     {
11955       errmsg ("missing locator-set name");
11956       return -99;
11957     }
11958
11959   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11960     {
11961       errmsg ("missing sw_if_index");
11962       vec_free (locator_set_name);
11963       return -99;
11964     }
11965
11966   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11967     {
11968       errmsg ("cannot use both params interface name and sw_if_index");
11969       vec_free (locator_set_name);
11970       return -99;
11971     }
11972
11973   if (priority_set == 0)
11974     {
11975       errmsg ("missing locator-set priority\n");
11976       vec_free (locator_set_name);
11977       return -99;
11978     }
11979
11980   if (weight_set == 0)
11981     {
11982       errmsg ("missing locator-set weight\n");
11983       vec_free (locator_set_name);
11984       return -99;
11985     }
11986
11987   if (vec_len (locator_set_name) > 64)
11988     {
11989       errmsg ("locator-set name too long\n");
11990       vec_free (locator_set_name);
11991       return -99;
11992     }
11993   vec_add1 (locator_set_name, 0);
11994
11995   /* Construct the API message */
11996   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11997
11998   mp->is_add = is_add;
11999   mp->sw_if_index = ntohl (sw_if_index);
12000   mp->priority = priority;
12001   mp->weight = weight;
12002   clib_memcpy (mp->locator_set_name, locator_set_name,
12003                vec_len (locator_set_name));
12004   vec_free (locator_set_name);
12005
12006   /* send it... */
12007   S;
12008
12009   /* Wait for a reply... */
12010   W;
12011
12012   /* NOTREACHED */
12013   return 0;
12014 }
12015
12016 static int
12017 api_lisp_add_del_local_eid (vat_main_t * vam)
12018 {
12019   unformat_input_t *input = vam->input;
12020   vl_api_lisp_add_del_local_eid_t *mp;
12021   f64 timeout = ~0;
12022   u8 is_add = 1;
12023   u8 eid_set = 0;
12024   lisp_eid_vat_t _eid, *eid = &_eid;
12025   u8 *locator_set_name = 0;
12026   u8 locator_set_name_set = 0;
12027   u32 vni = 0;
12028
12029   /* Parse args required to build the message */
12030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12031     {
12032       if (unformat (input, "del"))
12033         {
12034           is_add = 0;
12035         }
12036       else if (unformat (input, "vni %d", &vni))
12037         {
12038           ;
12039         }
12040       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12041         {
12042           eid_set = 1;
12043         }
12044       else if (unformat (input, "locator-set %s", &locator_set_name))
12045         {
12046           locator_set_name_set = 1;
12047         }
12048       else
12049         break;
12050     }
12051
12052   if (locator_set_name_set == 0)
12053     {
12054       errmsg ("missing locator-set name\n");
12055       return -99;
12056     }
12057
12058   if (0 == eid_set)
12059     {
12060       errmsg ("EID address not set!");
12061       vec_free (locator_set_name);
12062       return -99;
12063     }
12064
12065   if (vec_len (locator_set_name) > 64)
12066     {
12067       errmsg ("locator-set name too long\n");
12068       vec_free (locator_set_name);
12069       return -99;
12070     }
12071   vec_add1 (locator_set_name, 0);
12072
12073   /* Construct the API message */
12074   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12075
12076   mp->is_add = is_add;
12077   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12078   mp->eid_type = eid->type;
12079   mp->prefix_len = eid->len;
12080   mp->vni = clib_host_to_net_u32 (vni);
12081   clib_memcpy (mp->locator_set_name, locator_set_name,
12082                vec_len (locator_set_name));
12083
12084   vec_free (locator_set_name);
12085
12086   /* send it... */
12087   S;
12088
12089   /* Wait for a reply... */
12090   W;
12091
12092   /* NOTREACHED */
12093   return 0;
12094 }
12095
12096 /* *INDENT-OFF* */
12097 /** Used for transferring locators via VPP API */
12098 typedef CLIB_PACKED(struct
12099 {
12100   u8 is_ip4; /**< is locator an IPv4 address? */
12101   u8 priority; /**< locator priority */
12102   u8 weight;   /**< locator weight */
12103   u8 addr[16]; /**< IPv4/IPv6 address */
12104 }) rloc_t;
12105 /* *INDENT-ON* */
12106
12107 static int
12108 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12109 {
12110   unformat_input_t *input = vam->input;
12111   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12112   f64 timeout = ~0;
12113   u8 is_add = 1;
12114   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12115   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12116   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12117   u32 action = ~0, p, w;
12118   ip4_address_t rmt_rloc4, lcl_rloc4;
12119   ip6_address_t rmt_rloc6, lcl_rloc6;
12120   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12121
12122   memset (&rloc, 0, sizeof (rloc));
12123
12124   /* Parse args required to build the message */
12125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (input, "del"))
12128         {
12129           is_add = 0;
12130         }
12131       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12132         {
12133           rmt_eid_set = 1;
12134         }
12135       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12136         {
12137           lcl_eid_set = 1;
12138         }
12139       else if (unformat (input, "p %d w %d", &p, &w))
12140         {
12141           if (!curr_rloc)
12142             {
12143               errmsg ("No RLOC configured for setting priority/weight!");
12144               return -99;
12145             }
12146           curr_rloc->priority = p;
12147           curr_rloc->weight = w;
12148         }
12149       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12150                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12151         {
12152           rloc.is_ip4 = 1;
12153
12154           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12155           rloc.priority = rloc.weight = 0;
12156           vec_add1 (lcl_locs, rloc);
12157
12158           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12159           vec_add1 (rmt_locs, rloc);
12160           /* priority and weight saved in rmt loc */
12161           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12162         }
12163       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12164                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12165         {
12166           rloc.is_ip4 = 0;
12167           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12168           rloc.priority = rloc.weight = 0;
12169           vec_add1 (lcl_locs, rloc);
12170
12171           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12172           vec_add1 (rmt_locs, rloc);
12173           /* priority and weight saved in rmt loc */
12174           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12175         }
12176       else if (unformat (input, "action %d", &action))
12177         {
12178           ;
12179         }
12180       else
12181         {
12182           clib_warning ("parse error '%U'", format_unformat_error, input);
12183           return -99;
12184         }
12185     }
12186
12187   if (!rmt_eid_set)
12188     {
12189       errmsg ("remote eid addresses not set\n");
12190       return -99;
12191     }
12192
12193   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12194     {
12195       errmsg ("eid types don't match\n");
12196       return -99;
12197     }
12198
12199   if (0 == rmt_locs && (u32) ~ 0 == action)
12200     {
12201       errmsg ("action not set for negative mapping\n");
12202       return -99;
12203     }
12204
12205   /* Construct the API message */
12206   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12207
12208   mp->is_add = is_add;
12209   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12210   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12211   mp->eid_type = rmt_eid->type;
12212   mp->rmt_len = rmt_eid->len;
12213   mp->lcl_len = lcl_eid->len;
12214   mp->action = action;
12215
12216   if (0 != rmt_locs && 0 != lcl_locs)
12217     {
12218       mp->loc_num = vec_len (rmt_locs);
12219       clib_memcpy (mp->lcl_locs, lcl_locs,
12220                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12221       clib_memcpy (mp->rmt_locs, rmt_locs,
12222                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12223     }
12224   vec_free (lcl_locs);
12225   vec_free (rmt_locs);
12226
12227   /* send it... */
12228   S;
12229
12230   /* Wait for a reply... */
12231   W;
12232
12233   /* NOTREACHED */
12234   return 0;
12235 }
12236
12237 static int
12238 api_lisp_add_del_map_resolver (vat_main_t * vam)
12239 {
12240   unformat_input_t *input = vam->input;
12241   vl_api_lisp_add_del_map_resolver_t *mp;
12242   f64 timeout = ~0;
12243   u8 is_add = 1;
12244   u8 ipv4_set = 0;
12245   u8 ipv6_set = 0;
12246   ip4_address_t ipv4;
12247   ip6_address_t ipv6;
12248
12249   /* Parse args required to build the message */
12250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12251     {
12252       if (unformat (input, "del"))
12253         {
12254           is_add = 0;
12255         }
12256       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12257         {
12258           ipv4_set = 1;
12259         }
12260       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12261         {
12262           ipv6_set = 1;
12263         }
12264       else
12265         break;
12266     }
12267
12268   if (ipv4_set && ipv6_set)
12269     {
12270       errmsg ("both eid v4 and v6 addresses set\n");
12271       return -99;
12272     }
12273
12274   if (!ipv4_set && !ipv6_set)
12275     {
12276       errmsg ("eid addresses not set\n");
12277       return -99;
12278     }
12279
12280   /* Construct the API message */
12281   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12282
12283   mp->is_add = is_add;
12284   if (ipv6_set)
12285     {
12286       mp->is_ipv6 = 1;
12287       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12288     }
12289   else
12290     {
12291       mp->is_ipv6 = 0;
12292       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12293     }
12294
12295   /* send it... */
12296   S;
12297
12298   /* Wait for a reply... */
12299   W;
12300
12301   /* NOTREACHED */
12302   return 0;
12303 }
12304
12305 static int
12306 api_lisp_gpe_enable_disable (vat_main_t * vam)
12307 {
12308   unformat_input_t *input = vam->input;
12309   vl_api_lisp_gpe_enable_disable_t *mp;
12310   f64 timeout = ~0;
12311   u8 is_set = 0;
12312   u8 is_en = 1;
12313
12314   /* Parse args required to build the message */
12315   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12316     {
12317       if (unformat (input, "enable"))
12318         {
12319           is_set = 1;
12320           is_en = 1;
12321         }
12322       else if (unformat (input, "disable"))
12323         {
12324           is_set = 1;
12325           is_en = 0;
12326         }
12327       else
12328         break;
12329     }
12330
12331   if (is_set == 0)
12332     {
12333       errmsg ("Value not set\n");
12334       return -99;
12335     }
12336
12337   /* Construct the API message */
12338   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12339
12340   mp->is_en = is_en;
12341
12342   /* send it... */
12343   S;
12344
12345   /* Wait for a reply... */
12346   W;
12347
12348   /* NOTREACHED */
12349   return 0;
12350 }
12351
12352 static int
12353 api_lisp_enable_disable (vat_main_t * vam)
12354 {
12355   unformat_input_t *input = vam->input;
12356   vl_api_lisp_enable_disable_t *mp;
12357   f64 timeout = ~0;
12358   u8 is_set = 0;
12359   u8 is_en = 0;
12360
12361   /* Parse args required to build the message */
12362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12363     {
12364       if (unformat (input, "enable"))
12365         {
12366           is_set = 1;
12367           is_en = 1;
12368         }
12369       else if (unformat (input, "disable"))
12370         {
12371           is_set = 1;
12372         }
12373       else
12374         break;
12375     }
12376
12377   if (!is_set)
12378     {
12379       errmsg ("Value not set\n");
12380       return -99;
12381     }
12382
12383   /* Construct the API message */
12384   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12385
12386   mp->is_en = is_en;
12387
12388   /* send it... */
12389   S;
12390
12391   /* Wait for a reply... */
12392   W;
12393
12394   /* NOTREACHED */
12395   return 0;
12396 }
12397
12398 /**
12399  * Enable/disable LISP proxy ITR.
12400  *
12401  * @param vam vpp API test context
12402  * @return return code
12403  */
12404 static int
12405 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12406 {
12407   f64 timeout = ~0;
12408   u8 ls_name_set = 0;
12409   unformat_input_t *input = vam->input;
12410   vl_api_lisp_pitr_set_locator_set_t *mp;
12411   u8 is_add = 1;
12412   u8 *ls_name = 0;
12413
12414   /* Parse args required to build the message */
12415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12416     {
12417       if (unformat (input, "del"))
12418         is_add = 0;
12419       else if (unformat (input, "locator-set %s", &ls_name))
12420         ls_name_set = 1;
12421       else
12422         {
12423           errmsg ("parse error '%U'", format_unformat_error, input);
12424           return -99;
12425         }
12426     }
12427
12428   if (!ls_name_set)
12429     {
12430       errmsg ("locator-set name not set!");
12431       return -99;
12432     }
12433
12434   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12435
12436   mp->is_add = is_add;
12437   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12438   vec_free (ls_name);
12439
12440   /* send */
12441   S;
12442
12443   /* wait for reply */
12444   W;
12445
12446   /* notreached */
12447   return 0;
12448 }
12449
12450 static int
12451 api_show_lisp_pitr (vat_main_t * vam)
12452 {
12453   vl_api_show_lisp_pitr_t *mp;
12454   f64 timeout = ~0;
12455
12456   if (!vam->json_output)
12457     {
12458       fformat (vam->ofp, "%=20s\n", "lisp status:");
12459     }
12460
12461   M (SHOW_LISP_PITR, show_lisp_pitr);
12462   /* send it... */
12463   S;
12464
12465   /* Wait for a reply... */
12466   W;
12467
12468   /* NOTREACHED */
12469   return 0;
12470 }
12471
12472 /**
12473  * Add/delete mapping between vni and vrf
12474  */
12475 static int
12476 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12477 {
12478   f64 timeout = ~0;
12479   unformat_input_t *input = vam->input;
12480   vl_api_lisp_eid_table_add_del_map_t *mp;
12481   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12482   u32 vni, vrf, bd_index;
12483
12484   /* Parse args required to build the message */
12485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (input, "del"))
12488         is_add = 0;
12489       else if (unformat (input, "vrf %d", &vrf))
12490         vrf_set = 1;
12491       else if (unformat (input, "bd_index %d", &bd_index))
12492         bd_index_set = 1;
12493       else if (unformat (input, "vni %d", &vni))
12494         vni_set = 1;
12495       else
12496         break;
12497     }
12498
12499   if (!vni_set || (!vrf_set && !bd_index_set))
12500     {
12501       errmsg ("missing arguments!");
12502       return -99;
12503     }
12504
12505   if (vrf_set && bd_index_set)
12506     {
12507       errmsg ("error: both vrf and bd entered!");
12508       return -99;
12509     }
12510
12511   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12512
12513   mp->is_add = is_add;
12514   mp->vni = htonl (vni);
12515   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12516   mp->is_l2 = bd_index_set;
12517
12518   /* send */
12519   S;
12520
12521   /* wait for reply */
12522   W;
12523
12524   /* notreached */
12525   return 0;
12526 }
12527
12528 /**
12529  * Add/del remote mapping to/from LISP control plane
12530  *
12531  * @param vam vpp API test context
12532  * @return return code
12533  */
12534 static int
12535 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12536 {
12537   unformat_input_t *input = vam->input;
12538   vl_api_lisp_add_del_remote_mapping_t *mp;
12539   f64 timeout = ~0;
12540   u32 vni = 0;
12541   //TODO: seid need remove
12542   lisp_eid_vat_t _eid, *eid = &_eid;
12543   lisp_eid_vat_t _seid, *seid = &_seid;
12544   u8 is_add = 1, del_all = 0, eid_set = 0;
12545   u32 action = ~0, p, w;
12546   ip4_address_t rloc4;
12547   ip6_address_t rloc6;
12548   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12549
12550   memset (&rloc, 0, sizeof (rloc));
12551
12552   /* Parse args required to build the message */
12553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12554     {
12555       if (unformat (input, "del-all"))
12556         {
12557           del_all = 1;
12558         }
12559       else if (unformat (input, "del"))
12560         {
12561           is_add = 0;
12562         }
12563       else if (unformat (input, "add"))
12564         {
12565           is_add = 1;
12566         }
12567       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12568         {
12569           eid_set = 1;
12570         }
12571       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12572         {
12573           //TODO: Need remove, but first must be remove from CSIT test
12574         }
12575       else if (unformat (input, "vni %d", &vni))
12576         {
12577           ;
12578         }
12579       else if (unformat (input, "p %d w %d", &p, &w))
12580         {
12581           if (!curr_rloc)
12582             {
12583               errmsg ("No RLOC configured for setting priority/weight!");
12584               return -99;
12585             }
12586           curr_rloc->priority = p;
12587           curr_rloc->weight = w;
12588         }
12589       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12590         {
12591           rloc.is_ip4 = 1;
12592           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12593           vec_add1 (rlocs, rloc);
12594           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12595         }
12596       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12597         {
12598           rloc.is_ip4 = 0;
12599           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12600           vec_add1 (rlocs, rloc);
12601           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12602         }
12603       else if (unformat (input, "action %d", &action))
12604         {
12605           ;
12606         }
12607       else
12608         {
12609           clib_warning ("parse error '%U'", format_unformat_error, input);
12610           return -99;
12611         }
12612     }
12613
12614   if (0 == eid_set)
12615     {
12616       errmsg ("missing params!");
12617       return -99;
12618     }
12619
12620   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12621     {
12622       errmsg ("no action set for negative map-reply!");
12623       return -99;
12624     }
12625
12626   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12627   mp->is_add = is_add;
12628   mp->vni = htonl (vni);
12629   mp->action = (u8) action;
12630   mp->eid_len = eid->len;
12631   mp->del_all = del_all;
12632   mp->eid_type = eid->type;
12633   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12634
12635   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12636   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12637   vec_free (rlocs);
12638
12639   /* send it... */
12640   S;
12641
12642   /* Wait for a reply... */
12643   W;
12644
12645   /* NOTREACHED */
12646   return 0;
12647 }
12648
12649 /**
12650  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12651  * forwarding entries in data-plane accordingly.
12652  *
12653  * @param vam vpp API test context
12654  * @return return code
12655  */
12656 static int
12657 api_lisp_add_del_adjacency (vat_main_t * vam)
12658 {
12659   unformat_input_t *input = vam->input;
12660   vl_api_lisp_add_del_adjacency_t *mp;
12661   f64 timeout = ~0;
12662   u32 vni = 0;
12663   ip4_address_t seid4, deid4;
12664   ip6_address_t seid6, deid6;
12665   u8 deid_mac[6] = { 0 };
12666   u8 seid_mac[6] = { 0 };
12667   u8 deid_type, seid_type;
12668   u32 seid_len = 0, deid_len = 0, len;
12669   u8 is_add = 1;
12670
12671   seid_type = deid_type = (u8) ~ 0;
12672
12673   /* Parse args required to build the message */
12674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12675     {
12676       if (unformat (input, "del"))
12677         {
12678           is_add = 0;
12679         }
12680       else if (unformat (input, "add"))
12681         {
12682           is_add = 1;
12683         }
12684       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12685                          &deid4, &len))
12686         {
12687           deid_type = 0;        /* ipv4 */
12688           deid_len = len;
12689         }
12690       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12691                          &deid6, &len))
12692         {
12693           deid_type = 1;        /* ipv6 */
12694           deid_len = len;
12695         }
12696       else if (unformat (input, "deid %U", unformat_ethernet_address,
12697                          deid_mac))
12698         {
12699           deid_type = 2;        /* mac */
12700         }
12701       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12702                          &seid4, &len))
12703         {
12704           seid_type = 0;        /* ipv4 */
12705           seid_len = len;
12706         }
12707       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12708                          &seid6, &len))
12709         {
12710           seid_type = 1;        /* ipv6 */
12711           seid_len = len;
12712         }
12713       else if (unformat (input, "seid %U", unformat_ethernet_address,
12714                          seid_mac))
12715         {
12716           seid_type = 2;        /* mac */
12717         }
12718       else if (unformat (input, "vni %d", &vni))
12719         {
12720           ;
12721         }
12722       else
12723         {
12724           errmsg ("parse error '%U'", format_unformat_error, input);
12725           return -99;
12726         }
12727     }
12728
12729   if ((u8) ~ 0 == deid_type)
12730     {
12731       errmsg ("missing params!");
12732       return -99;
12733     }
12734
12735   if (seid_type != deid_type)
12736     {
12737       errmsg ("source and destination EIDs are of different types!");
12738       return -99;
12739     }
12740
12741   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12742   mp->is_add = is_add;
12743   mp->vni = htonl (vni);
12744   mp->seid_len = seid_len;
12745   mp->deid_len = deid_len;
12746   mp->eid_type = deid_type;
12747
12748   switch (mp->eid_type)
12749     {
12750     case 0:
12751       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12752       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12753       break;
12754     case 1:
12755       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12756       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12757       break;
12758     case 2:
12759       clib_memcpy (mp->seid, seid_mac, 6);
12760       clib_memcpy (mp->deid, deid_mac, 6);
12761       break;
12762     default:
12763       errmsg ("unknown EID type %d!", mp->eid_type);
12764       return 0;
12765     }
12766
12767   /* send it... */
12768   S;
12769
12770   /* Wait for a reply... */
12771   W;
12772
12773   /* NOTREACHED */
12774   return 0;
12775 }
12776
12777 static int
12778 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12779 {
12780   unformat_input_t *input = vam->input;
12781   vl_api_lisp_gpe_add_del_iface_t *mp;
12782   f64 timeout = ~0;
12783   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12784   u32 dp_table = 0, vni = 0;
12785
12786   /* Parse args required to build the message */
12787   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12788     {
12789       if (unformat (input, "up"))
12790         {
12791           action_set = 1;
12792           is_add = 1;
12793         }
12794       else if (unformat (input, "down"))
12795         {
12796           action_set = 1;
12797           is_add = 0;
12798         }
12799       else if (unformat (input, "table_id %d", &dp_table))
12800         {
12801           dp_table_set = 1;
12802         }
12803       else if (unformat (input, "bd_id %d", &dp_table))
12804         {
12805           dp_table_set = 1;
12806           is_l2 = 1;
12807         }
12808       else if (unformat (input, "vni %d", &vni))
12809         {
12810           vni_set = 1;
12811         }
12812       else
12813         break;
12814     }
12815
12816   if (action_set == 0)
12817     {
12818       errmsg ("Action not set\n");
12819       return -99;
12820     }
12821   if (dp_table_set == 0 || vni_set == 0)
12822     {
12823       errmsg ("vni and dp_table must be set\n");
12824       return -99;
12825     }
12826
12827   /* Construct the API message */
12828   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12829
12830   mp->is_add = is_add;
12831   mp->dp_table = dp_table;
12832   mp->is_l2 = is_l2;
12833   mp->vni = vni;
12834
12835   /* send it... */
12836   S;
12837
12838   /* Wait for a reply... */
12839   W;
12840
12841   /* NOTREACHED */
12842   return 0;
12843 }
12844
12845 /**
12846  * Add/del map request itr rlocs from LISP control plane and updates
12847  *
12848  * @param vam vpp API test context
12849  * @return return code
12850  */
12851 static int
12852 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12853 {
12854   unformat_input_t *input = vam->input;
12855   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12856   f64 timeout = ~0;
12857   u8 *locator_set_name = 0;
12858   u8 locator_set_name_set = 0;
12859   u8 is_add = 1;
12860
12861   /* Parse args required to build the message */
12862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12863     {
12864       if (unformat (input, "del"))
12865         {
12866           is_add = 0;
12867         }
12868       else if (unformat (input, "%_%v%_", &locator_set_name))
12869         {
12870           locator_set_name_set = 1;
12871         }
12872       else
12873         {
12874           clib_warning ("parse error '%U'", format_unformat_error, input);
12875           return -99;
12876         }
12877     }
12878
12879   if (is_add && !locator_set_name_set)
12880     {
12881       errmsg ("itr-rloc is not set!");
12882       return -99;
12883     }
12884
12885   if (is_add && vec_len (locator_set_name) > 64)
12886     {
12887       errmsg ("itr-rloc locator-set name too long\n");
12888       vec_free (locator_set_name);
12889       return -99;
12890     }
12891
12892   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12893   mp->is_add = is_add;
12894   if (is_add)
12895     {
12896       clib_memcpy (mp->locator_set_name, locator_set_name,
12897                    vec_len (locator_set_name));
12898     }
12899   else
12900     {
12901       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12902     }
12903   vec_free (locator_set_name);
12904
12905   /* send it... */
12906   S;
12907
12908   /* Wait for a reply... */
12909   W;
12910
12911   /* NOTREACHED */
12912   return 0;
12913 }
12914
12915 static int
12916 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12917                             u8 filter)
12918 {
12919   vl_api_lisp_locator_dump_t *mp;
12920   f64 timeout = ~0;
12921
12922   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12923
12924   mp->locator_set_index = htonl (locator_set_index);
12925   mp->filter = filter;
12926
12927   /* send it... */
12928   S;
12929
12930   /* Use a control ping for synchronization */
12931   {
12932     vl_api_noprint_control_ping_t *mp;
12933     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12934     S;
12935   }
12936   /* Wait for a reply... */
12937   W;
12938 }
12939
12940 static inline void
12941 clean_locator_set_message (vat_main_t * vam)
12942 {
12943   locator_set_msg_t *ls = 0;
12944
12945   vec_foreach (ls, vam->locator_set_msg)
12946   {
12947     vec_free (ls->locator_set_name);
12948   }
12949
12950   vec_free (vam->locator_set_msg);
12951 }
12952
12953 static int
12954 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12955 {
12956   locator_set_msg_t *ls;
12957   locator_msg_t *loc;
12958   u8 *tmp_str = 0;
12959   int i = 0, ret = 0;
12960
12961   vec_foreach (ls, vam->locator_set_msg)
12962   {
12963     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12964     if (ret)
12965       {
12966         vec_free (vam->locator_msg);
12967         clean_locator_set_message (vam);
12968         return ret;
12969       }
12970
12971     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12972                       ls->locator_set_index,
12973                       vec_len (vam->locator_msg) ? "" : "\n");
12974     i = 0;
12975     vec_foreach (loc, vam->locator_msg)
12976     {
12977       if (i)
12978         {
12979           tmp_str = format (tmp_str, "%=37s", " ");
12980         }
12981       if (loc->local)
12982         {
12983           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12984                             loc->sw_if_index, loc->priority, loc->weight);
12985         }
12986       else
12987         {
12988           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12989                             loc->is_ipv6 ? format_ip6_address :
12990                             format_ip4_address,
12991                             loc->ip_address, loc->priority, loc->weight);
12992         }
12993       i++;
12994     }
12995
12996     fformat (vam->ofp, "%s", tmp_str);
12997     vec_free (tmp_str);
12998     vec_free (vam->locator_msg);
12999   }
13000
13001   clean_locator_set_message (vam);
13002
13003   return ret;
13004 }
13005
13006 static int
13007 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
13008 {
13009   locator_set_msg_t *ls;
13010   locator_msg_t *loc;
13011   vat_json_node_t *node = NULL;
13012   vat_json_node_t *locator_array;
13013   vat_json_node_t *locator;
13014   struct in6_addr ip6;
13015   struct in_addr ip4;
13016   int ret = 0;
13017
13018   if (!vec_len (vam->locator_set_msg))
13019     {
13020       /* just print [] */
13021       vat_json_init_array (&vam->json_tree);
13022       vat_json_print (vam->ofp, &vam->json_tree);
13023       vam->json_tree.type = VAT_JSON_NONE;
13024       return ret;
13025     }
13026
13027   if (VAT_JSON_ARRAY != vam->json_tree.type)
13028     {
13029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13030       vat_json_init_array (&vam->json_tree);
13031     }
13032
13033   vec_foreach (ls, vam->locator_set_msg)
13034   {
13035     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
13036     if (ret)
13037       {
13038         vec_free (ls->locator_set_name);
13039         vec_free (vam->locator_msg);
13040         vec_free (vam->locator_set_msg);
13041         vat_json_free (&vam->json_tree);
13042         vam->json_tree.type = VAT_JSON_NONE;
13043         return ret;
13044       }
13045
13046     node = vat_json_array_add (&vam->json_tree);
13047     vat_json_init_object (node);
13048
13049     vat_json_object_add_uint (node, "locator-set-index",
13050                               ls->locator_set_index);
13051     vat_json_object_add_string_copy (node, "locator-set",
13052                                      ls->locator_set_name);
13053     locator_array = vat_json_object_add_list (node, "locator");
13054     vec_foreach (loc, vam->locator_msg)
13055     {
13056       locator = vat_json_array_add (locator_array);
13057       vat_json_init_object (locator);
13058       if (loc->local)
13059         {
13060           vat_json_object_add_uint (locator, "locator-index",
13061                                     loc->sw_if_index);
13062         }
13063       else
13064         {
13065           if (loc->is_ipv6)
13066             {
13067               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13068               vat_json_object_add_ip6 (locator, "locator", ip6);
13069             }
13070           else
13071             {
13072               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13073               vat_json_object_add_ip4 (locator, "locator", ip4);
13074             }
13075         }
13076       vat_json_object_add_uint (locator, "priority", loc->priority);
13077       vat_json_object_add_uint (locator, "weight", loc->weight);
13078     }
13079
13080     vec_free (ls->locator_set_name);
13081     vec_free (vam->locator_msg);
13082   }
13083
13084   vat_json_print (vam->ofp, &vam->json_tree);
13085   vat_json_free (&vam->json_tree);
13086   vam->json_tree.type = VAT_JSON_NONE;
13087
13088   vec_free (vam->locator_set_msg);
13089
13090   return ret;
13091 }
13092
13093 static int
13094 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
13095                                 u32 * locator_set_index)
13096 {
13097   locator_set_msg_t *ls;
13098   int ret = 0;
13099
13100   *locator_set_index = ~0;
13101
13102   if (!vec_len (vam->locator_set_msg))
13103     {
13104       return ret;
13105     }
13106
13107   vec_foreach (ls, vam->locator_set_msg)
13108   {
13109     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
13110       {
13111         *locator_set_index = ls->locator_set_index;
13112         vec_free (vam->locator_set_msg);
13113         return ret;
13114       }
13115   }
13116
13117   vec_free (vam->locator_set_msg);
13118
13119   return ret;
13120 }
13121
13122 static int
13123 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13124                        u32 * locator_set_index)
13125 {
13126   vl_api_lisp_locator_set_dump_t *mp;
13127   f64 timeout = ~0;
13128
13129   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13130   /* send it... */
13131   S;
13132
13133   /* Use a control ping for synchronization */
13134   {
13135     vl_api_noprint_control_ping_t *mp;
13136     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13137     S;
13138   }
13139
13140   vam->noprint_msg = 1;
13141   /* Wait for a reply... */
13142   /* *INDENT-OFF* */
13143   W_L
13144   ({
13145     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13146     vam->noprint_msg = 0;
13147   });
13148   /* *INDENT-ON* */
13149
13150   /* NOTREACHED */
13151   return 0;
13152 }
13153
13154 static inline int
13155 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13156                    u8 filter)
13157 {
13158   int ret = 0;
13159
13160   ASSERT (vam);
13161
13162   if (!vam->json_output)
13163     {
13164       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13165                "locator", "priority", "weight");
13166     }
13167
13168   if (locator_set)
13169     {
13170       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13171     }
13172
13173   if (!ret && ~0 == locator_set_index)
13174     {
13175       return -99;
13176     }
13177
13178   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13179
13180   return ret;
13181 }
13182
13183 static int
13184 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13185 {
13186   vl_api_lisp_locator_set_dump_t *mp;
13187   f64 timeout = ~0;
13188
13189   if (!vam->json_output)
13190     {
13191       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13192                "locator-set", "locator-set-index", "locator", "priority",
13193                "weight");
13194     }
13195
13196   vam->noprint_msg = 1;
13197
13198   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13199
13200   mp->filter = filter;
13201
13202   /* send it... */
13203   S;
13204
13205   /* Use a control ping for synchronization */
13206   {
13207     vl_api_noprint_control_ping_t *mp;
13208     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13209     S;
13210   }
13211
13212   /* Wait for a reply... */
13213   /* *INDENT-OFF* */
13214   W_L
13215   ({
13216     if (vam->noprint_msg)
13217       {
13218         if (!vam->json_output)
13219           {
13220             print_locator_in_locator_set(vam, filter);
13221           }
13222         else
13223           {
13224             json_locator_in_locator_set(vam, filter);
13225           }
13226       }
13227     vam->noprint_msg = 0;
13228   });
13229   /* *INDENT-ON* */
13230
13231   /* NOTREACHED */
13232   return 0;
13233 }
13234
13235 static int
13236 api_lisp_locator_set_dump (vat_main_t * vam)
13237 {
13238   unformat_input_t *input = vam->input;
13239   vam->noprint_msg = 0;
13240   u32 locator_set_index = ~0;
13241   u8 locator_set_index_set = 0;
13242   u8 *locator_set = 0;
13243   u8 locator_set_set = 0;
13244   u8 filter = 0;
13245   int ret = 0;
13246
13247   /* Parse args required to build the message */
13248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13249     {
13250       if (unformat (input, "locator-set-index %u", &locator_set_index))
13251         {
13252           locator_set_index_set = 1;
13253         }
13254       else if (unformat (input, "locator-set %s", &locator_set))
13255         {
13256           locator_set_set = 1;
13257         }
13258       else if (unformat (input, "local"))
13259         {
13260           filter = 1;
13261         }
13262       else if (unformat (input, "remote"))
13263         {
13264           filter = 2;
13265         }
13266       else
13267         {
13268           break;
13269         }
13270     }
13271
13272   if (locator_set_index_set && locator_set_set)
13273     {
13274       errmsg ("use only input parameter!\n");
13275       return -99;
13276     }
13277
13278   if (locator_set_index_set || locator_set_set)
13279     {
13280       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13281     }
13282   else
13283     {
13284       ret = lisp_locator_set_dump (vam, filter);
13285     }
13286
13287   vec_free (locator_set);
13288
13289   return ret;
13290 }
13291
13292 static int
13293 api_lisp_eid_table_map_dump (vat_main_t * vam)
13294 {
13295   u8 is_l2 = 0;
13296   u8 mode_set = 0;
13297   unformat_input_t *input = vam->input;
13298   vl_api_lisp_eid_table_map_dump_t *mp;
13299   f64 timeout = ~0;
13300
13301   /* Parse args required to build the message */
13302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13303     {
13304       if (unformat (input, "l2"))
13305         {
13306           is_l2 = 1;
13307           mode_set = 1;
13308         }
13309       else if (unformat (input, "l3"))
13310         {
13311           is_l2 = 0;
13312           mode_set = 1;
13313         }
13314       else
13315         {
13316           errmsg ("parse error '%U'", format_unformat_error, input);
13317           return -99;
13318         }
13319     }
13320
13321   if (!mode_set)
13322     {
13323       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13324       return -99;
13325     }
13326
13327   if (!vam->json_output)
13328     {
13329       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13330     }
13331
13332   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13333   mp->is_l2 = is_l2;
13334
13335   /* send it... */
13336   S;
13337
13338   /* Use a control ping for synchronization */
13339   {
13340     vl_api_control_ping_t *mp;
13341     M (CONTROL_PING, control_ping);
13342     S;
13343   }
13344   /* Wait for a reply... */
13345   W;
13346
13347   /* NOTREACHED */
13348   return 0;
13349 }
13350
13351 static int
13352 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13353 {
13354   vl_api_lisp_eid_table_vni_dump_t *mp;
13355   f64 timeout = ~0;
13356
13357   if (!vam->json_output)
13358     {
13359       fformat (vam->ofp, "VNI\n");
13360     }
13361
13362   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13363
13364   /* send it... */
13365   S;
13366
13367   /* Use a control ping for synchronization */
13368   {
13369     vl_api_control_ping_t *mp;
13370     M (CONTROL_PING, control_ping);
13371     S;
13372   }
13373   /* Wait for a reply... */
13374   W;
13375
13376   /* NOTREACHED */
13377   return 0;
13378 }
13379
13380 static int
13381 get_locator_set (vat_main_t * vam)
13382 {
13383   vl_api_lisp_locator_set_dump_t *mp;
13384   f64 timeout = ~0;
13385
13386   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13387   /* send it... */
13388   S;
13389
13390   /* Use a control ping for synchronization */
13391   {
13392     vl_api_noprint_control_ping_t *mp;
13393     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13394     S;
13395   }
13396
13397   /* Wait for a reply... */
13398   W;
13399
13400   /* NOTREACHED */
13401   return 0;
13402 }
13403
13404 static inline u8 *
13405 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13406                           int *ret)
13407 {
13408   u8 *(*format_eid) (u8 *, va_list *) = 0;
13409
13410   ASSERT (vam != NULL);
13411   ASSERT (eid_table != NULL);
13412
13413   if (ret)
13414     {
13415       *ret = 0;
13416     }
13417
13418   switch (eid_table->eid_type)
13419     {
13420     case 0:
13421     case 1:
13422       format_eid = (eid_table->eid_type ? format_ip6_address :
13423                     format_ip4_address);
13424       str = format (0, "[%d] %U/%d", eid_table->vni,
13425                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13426       break;
13427     case 2:
13428       str = format (0, "[%d] %U", eid_table->vni,
13429                     format_ethernet_address, eid_table->eid);
13430       break;
13431     default:
13432       errmsg ("unknown EID type %d!", eid_table->eid_type);
13433       if (ret)
13434         {
13435           *ret = -99;
13436         }
13437       return 0;
13438     }
13439
13440   return str;
13441 }
13442
13443 static inline u8 *
13444 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13445                                   eid_table_t * eid_table)
13446 {
13447   locator_set_msg_t *ls = 0;
13448
13449   ASSERT (vam != NULL);
13450   ASSERT (eid_table != NULL);
13451
13452   if (eid_table->is_local)
13453     {
13454       vec_foreach (ls, vam->locator_set_msg)
13455       {
13456         if (ls->locator_set_index == eid_table->locator_set_index)
13457           {
13458             str = format (0, "local(%s)", ls->locator_set_name);
13459             return str;
13460           }
13461       }
13462
13463       str = format (0, "local(N/A)");
13464     }
13465   else
13466     {
13467       str = format (0, "remote");
13468     }
13469
13470   return str;
13471 }
13472
13473 static inline u8 *
13474 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13475                               eid_table_t * eid_table)
13476 {
13477   locator_msg_t *loc = 0;
13478   int first_line = 1;
13479
13480   ASSERT (vam != NULL);
13481   ASSERT (eid_table != NULL);
13482
13483   if (~0 == eid_table->locator_set_index)
13484     {
13485       return format (0, "action: %d\n", eid_table->action);
13486     }
13487
13488   vec_foreach (loc, vam->locator_msg)
13489   {
13490     if (!first_line)
13491       {
13492         if (loc->local)
13493           {
13494             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13495           }
13496         else
13497           {
13498             str = format (str, "%=55s%-U\n", " ",
13499                           loc->is_ipv6 ? format_ip6_address :
13500                           format_ip4_address, loc->ip_address);
13501           }
13502
13503         continue;
13504       }
13505
13506     if (loc->local)
13507       {
13508         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13509                       eid_table->ttl, eid_table->authoritative);
13510       }
13511     else
13512       {
13513         str = format (str, "%-30U%-20u%-u\n",
13514                       loc->is_ipv6 ? format_ip6_address :
13515                       format_ip4_address,
13516                       loc->ip_address, eid_table->ttl,
13517                       eid_table->authoritative);
13518       }
13519     first_line = 0;
13520   }
13521
13522   return str;
13523 }
13524
13525 static int
13526 print_lisp_eid_table_dump (vat_main_t * vam)
13527 {
13528   eid_table_t *eid_table = 0;
13529   u8 *tmp_str = 0, *tmp_str2 = 0;
13530   int ret = 0;
13531
13532   ASSERT (vam != NULL);
13533
13534   ret = get_locator_set (vam);
13535   if (ret)
13536     {
13537       vec_free (vam->eid_tables);
13538       return ret;
13539     }
13540
13541   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13542            "ttl", "authoritative");
13543
13544   vec_foreach (eid_table, vam->eid_tables)
13545   {
13546     if (~0 != eid_table->locator_set_index)
13547       {
13548         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13549                                           0);
13550         if (ret)
13551           {
13552             vec_free (vam->locator_msg);
13553             clean_locator_set_message (vam);
13554             vec_free (vam->eid_tables);
13555             return ret;
13556           }
13557       }
13558
13559     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13560     if (ret)
13561       {
13562         vec_free (vam->locator_msg);
13563         clean_locator_set_message (vam);
13564         vec_free (vam->eid_tables);
13565         return ret;
13566       }
13567
13568     tmp_str = format (0, "%-35s", tmp_str2);
13569     vec_free (tmp_str2);
13570
13571     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13572     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13573     vec_free (tmp_str2);
13574
13575     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13576     tmp_str = format (tmp_str, "%-s", tmp_str2);
13577     vec_free (tmp_str2);
13578
13579     fformat (vam->ofp, "%s", tmp_str);
13580     vec_free (tmp_str);
13581     vec_free (vam->locator_msg);
13582   }
13583
13584   clean_locator_set_message (vam);
13585   vec_free (vam->eid_tables);
13586
13587   return ret;
13588 }
13589
13590 static inline void
13591 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13592                                 eid_table_t * eid_table)
13593 {
13594   locator_set_msg_t *ls = 0;
13595   u8 *s = 0;
13596
13597   ASSERT (vam != NULL);
13598   ASSERT (node != NULL);
13599   ASSERT (eid_table != NULL);
13600
13601   if (eid_table->is_local)
13602     {
13603       vec_foreach (ls, vam->locator_set_msg)
13604       {
13605         if (ls->locator_set_index == eid_table->locator_set_index)
13606           {
13607             vat_json_object_add_string_copy (node, "locator-set",
13608                                              ls->locator_set_name);
13609             return;
13610           }
13611       }
13612
13613       s = format (0, "N/A");
13614       vec_add1 (s, 0);
13615       vat_json_object_add_string_copy (node, "locator-set", s);
13616       vec_free (s);
13617     }
13618   else
13619     {
13620       s = format (0, "remote");
13621       vec_add1 (s, 0);
13622       vat_json_object_add_string_copy (node, "locator-set", s);
13623       vec_free (s);
13624     }
13625 }
13626
13627 static inline int
13628 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13629                         eid_table_t * eid_table)
13630 {
13631   u8 *s = 0;
13632   struct in6_addr ip6;
13633   struct in_addr ip4;
13634
13635   ASSERT (vam != NULL);
13636   ASSERT (node != NULL);
13637   ASSERT (eid_table != NULL);
13638
13639   switch (eid_table->eid_type)
13640     {
13641     case 0:
13642       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13643       vat_json_object_add_ip4 (node, "eid", ip4);
13644       vat_json_object_add_uint (node, "eid-prefix-len",
13645                                 eid_table->eid_prefix_len);
13646       break;
13647     case 1:
13648       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13649       vat_json_object_add_ip6 (node, "eid", ip6);
13650       vat_json_object_add_uint (node, "eid-prefix-len",
13651                                 eid_table->eid_prefix_len);
13652       break;
13653     case 2:
13654       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13655       vec_add1 (s, 0);
13656       vat_json_object_add_string_copy (node, "eid", s);
13657       vec_free (s);
13658       break;
13659     default:
13660       errmsg ("unknown EID type %d!", eid_table->eid_type);
13661       return -99;
13662     }
13663
13664   return 0;
13665 }
13666
13667 static inline void
13668 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13669                             eid_table_t * eid_table)
13670 {
13671   locator_msg_t *loc = 0;
13672   vat_json_node_t *locator_array = 0;
13673   vat_json_node_t *locator = 0;
13674   struct in6_addr ip6;
13675   struct in_addr ip4;
13676
13677   ASSERT (vam != NULL);
13678   ASSERT (node != NULL);
13679   ASSERT (eid_table != NULL);
13680
13681   locator_array = vat_json_object_add_list (node, "locator");
13682   vec_foreach (loc, vam->locator_msg)
13683   {
13684     locator = vat_json_array_add (locator_array);
13685     vat_json_init_object (locator);
13686     if (loc->local)
13687       {
13688         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13689       }
13690     else
13691       {
13692         if (loc->is_ipv6)
13693           {
13694             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13695             vat_json_object_add_ip6 (locator, "locator", ip6);
13696           }
13697         else
13698           {
13699             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13700             vat_json_object_add_ip4 (locator, "locator", ip4);
13701           }
13702       }
13703   }
13704 }
13705
13706 static int
13707 json_lisp_eid_table_dump (vat_main_t * vam)
13708 {
13709   eid_table_t *eid_table;
13710   vat_json_node_t *node = 0;
13711   int ret = 0;
13712
13713   ASSERT (vam != NULL);
13714
13715   ret = get_locator_set (vam);
13716   if (ret)
13717     {
13718       vec_free (vam->eid_tables);
13719       return ret;
13720     }
13721
13722   if (!vec_len (vam->eid_tables))
13723     {
13724       /* just print [] */
13725       vat_json_init_array (&vam->json_tree);
13726       vat_json_print (vam->ofp, &vam->json_tree);
13727       vam->json_tree.type = VAT_JSON_NONE;
13728       return ret;
13729     }
13730
13731   if (VAT_JSON_ARRAY != vam->json_tree.type)
13732     {
13733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13734       vat_json_init_array (&vam->json_tree);
13735     }
13736
13737   vec_foreach (eid_table, vam->eid_tables)
13738   {
13739     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13740     if (ret)
13741       {
13742         vec_free (vam->locator_msg);
13743         vec_free (vam->eid_tables);
13744         clean_locator_set_message (vam);
13745         vat_json_free (&vam->json_tree);
13746         vam->json_tree.type = VAT_JSON_NONE;
13747         return ret;
13748       }
13749
13750     node = vat_json_array_add (&vam->json_tree);
13751     vat_json_init_object (node);
13752
13753     vat_json_object_add_uint (node, "vni", eid_table->vni);
13754
13755     json_locator_set_for_eid_table (vam, node, eid_table);
13756     ret = json_eid_for_eid_table (vam, node, eid_table);
13757     if (ret)
13758       {
13759         vec_free (vam->locator_msg);
13760         vec_free (vam->eid_tables);
13761         clean_locator_set_message (vam);
13762         vat_json_free (&vam->json_tree);
13763         vam->json_tree.type = VAT_JSON_NONE;
13764         return ret;
13765       }
13766
13767     json_locator_for_eid_table (vam, node, eid_table);
13768
13769     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13770     vat_json_object_add_uint (node, "authoritative",
13771                               eid_table->authoritative);
13772
13773     vec_free (vam->locator_msg);
13774   }
13775
13776   vat_json_print (vam->ofp, &vam->json_tree);
13777   vat_json_free (&vam->json_tree);
13778   vam->json_tree.type = VAT_JSON_NONE;
13779
13780   clean_locator_set_message (vam);
13781   vec_free (vam->eid_tables);
13782
13783   return ret;
13784 }
13785
13786 static int
13787 api_lisp_eid_table_dump (vat_main_t * vam)
13788 {
13789   unformat_input_t *i = vam->input;
13790   vl_api_lisp_eid_table_dump_t *mp;
13791   f64 timeout = ~0;
13792   struct in_addr ip4;
13793   struct in6_addr ip6;
13794   u8 mac[6];
13795   u8 eid_type = ~0, eid_set = 0;
13796   u32 prefix_length = ~0, t, vni = 0;
13797   u8 filter = 0;
13798
13799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13802         {
13803           eid_set = 1;
13804           eid_type = 0;
13805           prefix_length = t;
13806         }
13807       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13808         {
13809           eid_set = 1;
13810           eid_type = 1;
13811           prefix_length = t;
13812         }
13813       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13814         {
13815           eid_set = 1;
13816           eid_type = 2;
13817         }
13818       else if (unformat (i, "vni %d", &t))
13819         {
13820           vni = t;
13821         }
13822       else if (unformat (i, "local"))
13823         {
13824           filter = 1;
13825         }
13826       else if (unformat (i, "remote"))
13827         {
13828           filter = 2;
13829         }
13830       else
13831         {
13832           errmsg ("parse error '%U'", format_unformat_error, i);
13833           return -99;
13834         }
13835     }
13836
13837   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13838
13839   mp->filter = filter;
13840   if (eid_set)
13841     {
13842       mp->eid_set = 1;
13843       mp->vni = htonl (vni);
13844       mp->eid_type = eid_type;
13845       switch (eid_type)
13846         {
13847         case 0:
13848           mp->prefix_length = prefix_length;
13849           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13850           break;
13851         case 1:
13852           mp->prefix_length = prefix_length;
13853           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13854           break;
13855         case 2:
13856           clib_memcpy (mp->eid, mac, sizeof (mac));
13857           break;
13858         default:
13859           errmsg ("unknown EID type %d!", eid_type);
13860           return -99;
13861         }
13862     }
13863
13864   vam->noprint_msg = 1;
13865
13866   /* send it... */
13867   S;
13868
13869   /* Use a control ping for synchronization */
13870   {
13871     vl_api_noprint_control_ping_t *mp;
13872     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13873     S;
13874   }
13875
13876   /* Wait for a reply... */
13877   /* *INDENT-OFF* */
13878   W_L
13879   ({
13880     if (vam->noprint_msg)
13881       {
13882         if (!vam->json_output)
13883           {
13884             vam->retval = print_lisp_eid_table_dump(vam);
13885           }
13886         else
13887           {
13888             vam->retval = json_lisp_eid_table_dump(vam);
13889           }
13890       }
13891     vam->noprint_msg = 0;
13892   });
13893   /* *INDENT-ON* */
13894
13895   /* NOTREACHED */
13896   return 0;
13897 }
13898
13899 static int
13900 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13901 {
13902   vl_api_lisp_gpe_tunnel_dump_t *mp;
13903   f64 timeout = ~0;
13904
13905   if (!vam->json_output)
13906     {
13907       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13908                "%=16s%=16s%=16s%=16s%=16s\n",
13909                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13910                "Decap next", "Lisp version", "Flags", "Next protocol",
13911                "ver_res", "res", "iid");
13912     }
13913
13914   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13915   /* send it... */
13916   S;
13917
13918   /* Use a control ping for synchronization */
13919   {
13920     vl_api_control_ping_t *mp;
13921     M (CONTROL_PING, control_ping);
13922     S;
13923   }
13924   /* Wait for a reply... */
13925   W;
13926
13927   /* NOTREACHED */
13928   return 0;
13929 }
13930
13931 static int
13932 api_lisp_map_resolver_dump (vat_main_t * vam)
13933 {
13934   vl_api_lisp_map_resolver_dump_t *mp;
13935   f64 timeout = ~0;
13936
13937   if (!vam->json_output)
13938     {
13939       fformat (vam->ofp, "%=20s\n", "Map resolver");
13940     }
13941
13942   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
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_show_lisp_status (vat_main_t * vam)
13961 {
13962   vl_api_show_lisp_status_t *mp;
13963   f64 timeout = ~0;
13964
13965   if (!vam->json_output)
13966     {
13967       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13968     }
13969
13970   M (SHOW_LISP_STATUS, show_lisp_status);
13971   /* send it... */
13972   S;
13973   /* Wait for a reply... */
13974   W;
13975
13976   /* NOTREACHED */
13977   return 0;
13978 }
13979
13980 static int
13981 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13982 {
13983   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13984   f64 timeout = ~0;
13985
13986   if (!vam->json_output)
13987     {
13988       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13989     }
13990
13991   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13992   /* send it... */
13993   S;
13994   /* Wait for a reply... */
13995   W;
13996
13997   /* NOTREACHED */
13998   return 0;
13999 }
14000
14001 static int
14002 api_af_packet_create (vat_main_t * vam)
14003 {
14004   unformat_input_t *i = vam->input;
14005   vl_api_af_packet_create_t *mp;
14006   f64 timeout;
14007   u8 *host_if_name = 0;
14008   u8 hw_addr[6];
14009   u8 random_hw_addr = 1;
14010
14011   memset (hw_addr, 0, sizeof (hw_addr));
14012
14013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (i, "name %s", &host_if_name))
14016         vec_add1 (host_if_name, 0);
14017       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14018         random_hw_addr = 0;
14019       else
14020         break;
14021     }
14022
14023   if (!vec_len (host_if_name))
14024     {
14025       errmsg ("host-interface name must be specified");
14026       return -99;
14027     }
14028
14029   if (vec_len (host_if_name) > 64)
14030     {
14031       errmsg ("host-interface name too long");
14032       return -99;
14033     }
14034
14035   M (AF_PACKET_CREATE, af_packet_create);
14036
14037   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14038   clib_memcpy (mp->hw_addr, hw_addr, 6);
14039   mp->use_random_hw_addr = random_hw_addr;
14040   vec_free (host_if_name);
14041
14042   S;
14043   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14044   /* NOTREACHED */
14045   return 0;
14046 }
14047
14048 static int
14049 api_af_packet_delete (vat_main_t * vam)
14050 {
14051   unformat_input_t *i = vam->input;
14052   vl_api_af_packet_delete_t *mp;
14053   f64 timeout;
14054   u8 *host_if_name = 0;
14055
14056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14057     {
14058       if (unformat (i, "name %s", &host_if_name))
14059         vec_add1 (host_if_name, 0);
14060       else
14061         break;
14062     }
14063
14064   if (!vec_len (host_if_name))
14065     {
14066       errmsg ("host-interface name must be specified");
14067       return -99;
14068     }
14069
14070   if (vec_len (host_if_name) > 64)
14071     {
14072       errmsg ("host-interface name too long");
14073       return -99;
14074     }
14075
14076   M (AF_PACKET_DELETE, af_packet_delete);
14077
14078   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14079   vec_free (host_if_name);
14080
14081   S;
14082   W;
14083   /* NOTREACHED */
14084   return 0;
14085 }
14086
14087 static int
14088 api_policer_add_del (vat_main_t * vam)
14089 {
14090   unformat_input_t *i = vam->input;
14091   vl_api_policer_add_del_t *mp;
14092   f64 timeout;
14093   u8 is_add = 1;
14094   u8 *name = 0;
14095   u32 cir = 0;
14096   u32 eir = 0;
14097   u64 cb = 0;
14098   u64 eb = 0;
14099   u8 rate_type = 0;
14100   u8 round_type = 0;
14101   u8 type = 0;
14102   u8 color_aware = 0;
14103   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14104
14105   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14106   conform_action.dscp = 0;
14107   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14108   exceed_action.dscp = 0;
14109   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14110   violate_action.dscp = 0;
14111
14112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (i, "del"))
14115         is_add = 0;
14116       else if (unformat (i, "name %s", &name))
14117         vec_add1 (name, 0);
14118       else if (unformat (i, "cir %u", &cir))
14119         ;
14120       else if (unformat (i, "eir %u", &eir))
14121         ;
14122       else if (unformat (i, "cb %u", &cb))
14123         ;
14124       else if (unformat (i, "eb %u", &eb))
14125         ;
14126       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14127                          &rate_type))
14128         ;
14129       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14130                          &round_type))
14131         ;
14132       else if (unformat (i, "type %U", unformat_policer_type, &type))
14133         ;
14134       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14135                          &conform_action))
14136         ;
14137       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14138                          &exceed_action))
14139         ;
14140       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14141                          &violate_action))
14142         ;
14143       else if (unformat (i, "color-aware"))
14144         color_aware = 1;
14145       else
14146         break;
14147     }
14148
14149   if (!vec_len (name))
14150     {
14151       errmsg ("policer name must be specified");
14152       return -99;
14153     }
14154
14155   if (vec_len (name) > 64)
14156     {
14157       errmsg ("policer name too long");
14158       return -99;
14159     }
14160
14161   M (POLICER_ADD_DEL, policer_add_del);
14162
14163   clib_memcpy (mp->name, name, vec_len (name));
14164   vec_free (name);
14165   mp->is_add = is_add;
14166   mp->cir = cir;
14167   mp->eir = eir;
14168   mp->cb = cb;
14169   mp->eb = eb;
14170   mp->rate_type = rate_type;
14171   mp->round_type = round_type;
14172   mp->type = type;
14173   mp->conform_action_type = conform_action.action_type;
14174   mp->conform_dscp = conform_action.dscp;
14175   mp->exceed_action_type = exceed_action.action_type;
14176   mp->exceed_dscp = exceed_action.dscp;
14177   mp->violate_action_type = violate_action.action_type;
14178   mp->violate_dscp = violate_action.dscp;
14179   mp->color_aware = color_aware;
14180
14181   S;
14182   W;
14183   /* NOTREACHED */
14184   return 0;
14185 }
14186
14187 static int
14188 api_policer_dump (vat_main_t * vam)
14189 {
14190   unformat_input_t *i = vam->input;
14191   vl_api_policer_dump_t *mp;
14192   f64 timeout = ~0;
14193   u8 *match_name = 0;
14194   u8 match_name_valid = 0;
14195
14196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14197     {
14198       if (unformat (i, "name %s", &match_name))
14199         {
14200           vec_add1 (match_name, 0);
14201           match_name_valid = 1;
14202         }
14203       else
14204         break;
14205     }
14206
14207   M (POLICER_DUMP, policer_dump);
14208   mp->match_name_valid = match_name_valid;
14209   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14210   vec_free (match_name);
14211   /* send it... */
14212   S;
14213
14214   /* Use a control ping for synchronization */
14215   {
14216     vl_api_control_ping_t *mp;
14217     M (CONTROL_PING, control_ping);
14218     S;
14219   }
14220   /* Wait for a reply... */
14221   W;
14222
14223   /* NOTREACHED */
14224   return 0;
14225 }
14226
14227 static int
14228 api_policer_classify_set_interface (vat_main_t * vam)
14229 {
14230   unformat_input_t *i = vam->input;
14231   vl_api_policer_classify_set_interface_t *mp;
14232   f64 timeout;
14233   u32 sw_if_index;
14234   int sw_if_index_set;
14235   u32 ip4_table_index = ~0;
14236   u32 ip6_table_index = ~0;
14237   u32 l2_table_index = ~0;
14238   u8 is_add = 1;
14239
14240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14241     {
14242       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14243         sw_if_index_set = 1;
14244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14245         sw_if_index_set = 1;
14246       else if (unformat (i, "del"))
14247         is_add = 0;
14248       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14249         ;
14250       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14251         ;
14252       else if (unformat (i, "l2-table %d", &l2_table_index))
14253         ;
14254       else
14255         {
14256           clib_warning ("parse error '%U'", format_unformat_error, i);
14257           return -99;
14258         }
14259     }
14260
14261   if (sw_if_index_set == 0)
14262     {
14263       errmsg ("missing interface name or sw_if_index\n");
14264       return -99;
14265     }
14266
14267   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14268
14269   mp->sw_if_index = ntohl (sw_if_index);
14270   mp->ip4_table_index = ntohl (ip4_table_index);
14271   mp->ip6_table_index = ntohl (ip6_table_index);
14272   mp->l2_table_index = ntohl (l2_table_index);
14273   mp->is_add = is_add;
14274
14275   S;
14276   W;
14277   /* NOTREACHED */
14278   return 0;
14279 }
14280
14281 static int
14282 api_policer_classify_dump (vat_main_t * vam)
14283 {
14284   unformat_input_t *i = vam->input;
14285   vl_api_policer_classify_dump_t *mp;
14286   f64 timeout = ~0;
14287   u8 type = POLICER_CLASSIFY_N_TABLES;
14288
14289   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14290     ;
14291   else
14292     {
14293       errmsg ("classify table type must be specified\n");
14294       return -99;
14295     }
14296
14297   if (!vam->json_output)
14298     {
14299       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14300     }
14301
14302   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14303   mp->type = type;
14304   /* send it... */
14305   S;
14306
14307   /* Use a control ping for synchronization */
14308   {
14309     vl_api_control_ping_t *mp;
14310     M (CONTROL_PING, control_ping);
14311     S;
14312   }
14313   /* Wait for a reply... */
14314   W;
14315
14316   /* NOTREACHED */
14317   return 0;
14318 }
14319
14320 static int
14321 api_netmap_create (vat_main_t * vam)
14322 {
14323   unformat_input_t *i = vam->input;
14324   vl_api_netmap_create_t *mp;
14325   f64 timeout;
14326   u8 *if_name = 0;
14327   u8 hw_addr[6];
14328   u8 random_hw_addr = 1;
14329   u8 is_pipe = 0;
14330   u8 is_master = 0;
14331
14332   memset (hw_addr, 0, sizeof (hw_addr));
14333
14334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14335     {
14336       if (unformat (i, "name %s", &if_name))
14337         vec_add1 (if_name, 0);
14338       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14339         random_hw_addr = 0;
14340       else if (unformat (i, "pipe"))
14341         is_pipe = 1;
14342       else if (unformat (i, "master"))
14343         is_master = 1;
14344       else if (unformat (i, "slave"))
14345         is_master = 0;
14346       else
14347         break;
14348     }
14349
14350   if (!vec_len (if_name))
14351     {
14352       errmsg ("interface name must be specified");
14353       return -99;
14354     }
14355
14356   if (vec_len (if_name) > 64)
14357     {
14358       errmsg ("interface name too long");
14359       return -99;
14360     }
14361
14362   M (NETMAP_CREATE, netmap_create);
14363
14364   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14365   clib_memcpy (mp->hw_addr, hw_addr, 6);
14366   mp->use_random_hw_addr = random_hw_addr;
14367   mp->is_pipe = is_pipe;
14368   mp->is_master = is_master;
14369   vec_free (if_name);
14370
14371   S;
14372   W;
14373   /* NOTREACHED */
14374   return 0;
14375 }
14376
14377 static int
14378 api_netmap_delete (vat_main_t * vam)
14379 {
14380   unformat_input_t *i = vam->input;
14381   vl_api_netmap_delete_t *mp;
14382   f64 timeout;
14383   u8 *if_name = 0;
14384
14385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14386     {
14387       if (unformat (i, "name %s", &if_name))
14388         vec_add1 (if_name, 0);
14389       else
14390         break;
14391     }
14392
14393   if (!vec_len (if_name))
14394     {
14395       errmsg ("interface name must be specified");
14396       return -99;
14397     }
14398
14399   if (vec_len (if_name) > 64)
14400     {
14401       errmsg ("interface name too long");
14402       return -99;
14403     }
14404
14405   M (NETMAP_DELETE, netmap_delete);
14406
14407   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14408   vec_free (if_name);
14409
14410   S;
14411   W;
14412   /* NOTREACHED */
14413   return 0;
14414 }
14415
14416 static void vl_api_mpls_gre_tunnel_details_t_handler
14417   (vl_api_mpls_gre_tunnel_details_t * mp)
14418 {
14419   vat_main_t *vam = &vat_main;
14420   i32 i;
14421   i32 len = ntohl (mp->nlabels);
14422
14423   if (mp->l2_only == 0)
14424     {
14425       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14426                ntohl (mp->tunnel_index),
14427                format_ip4_address, &mp->tunnel_src,
14428                format_ip4_address, &mp->tunnel_dst,
14429                format_ip4_address, &mp->intfc_address,
14430                ntohl (mp->mask_width));
14431       for (i = 0; i < len; i++)
14432         {
14433           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14434         }
14435       fformat (vam->ofp, "\n");
14436       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14437                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14438     }
14439   else
14440     {
14441       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14442                ntohl (mp->tunnel_index),
14443                format_ip4_address, &mp->tunnel_src,
14444                format_ip4_address, &mp->tunnel_dst,
14445                format_ip4_address, &mp->intfc_address);
14446       for (i = 0; i < len; i++)
14447         {
14448           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14449         }
14450       fformat (vam->ofp, "\n");
14451       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14452                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14453     }
14454 }
14455
14456 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14457   (vl_api_mpls_gre_tunnel_details_t * mp)
14458 {
14459   vat_main_t *vam = &vat_main;
14460   vat_json_node_t *node = NULL;
14461   struct in_addr ip4;
14462   i32 i;
14463   i32 len = ntohl (mp->nlabels);
14464
14465   if (VAT_JSON_ARRAY != vam->json_tree.type)
14466     {
14467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14468       vat_json_init_array (&vam->json_tree);
14469     }
14470   node = vat_json_array_add (&vam->json_tree);
14471
14472   vat_json_init_object (node);
14473   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14474   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14475   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14476   vat_json_object_add_uint (node, "inner_fib_index",
14477                             ntohl (mp->inner_fib_index));
14478   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14479   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14480   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14481   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14482   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14483   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14484   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14485   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14486   vat_json_object_add_uint (node, "outer_fib_index",
14487                             ntohl (mp->outer_fib_index));
14488   vat_json_object_add_uint (node, "label_count", len);
14489   for (i = 0; i < len; i++)
14490     {
14491       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14492     }
14493 }
14494
14495 static int
14496 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14497 {
14498   vl_api_mpls_gre_tunnel_dump_t *mp;
14499   f64 timeout;
14500   i32 index = -1;
14501
14502   /* Parse args required to build the message */
14503   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14504     {
14505       if (!unformat (vam->input, "tunnel_index %d", &index))
14506         {
14507           index = -1;
14508           break;
14509         }
14510     }
14511
14512   fformat (vam->ofp, "  tunnel_index %d\n", index);
14513
14514   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14515   mp->tunnel_index = htonl (index);
14516   S;
14517
14518   /* Use a control ping for synchronization */
14519   {
14520     vl_api_control_ping_t *mp;
14521     M (CONTROL_PING, control_ping);
14522     S;
14523   }
14524   W;
14525 }
14526
14527 static void vl_api_mpls_eth_tunnel_details_t_handler
14528   (vl_api_mpls_eth_tunnel_details_t * mp)
14529 {
14530   vat_main_t *vam = &vat_main;
14531   i32 i;
14532   i32 len = ntohl (mp->nlabels);
14533
14534   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14535            ntohl (mp->tunnel_index),
14536            format_ethernet_address, &mp->tunnel_dst_mac,
14537            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14538   for (i = 0; i < len; i++)
14539     {
14540       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14541     }
14542   fformat (vam->ofp, "\n");
14543   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14544            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14545 }
14546
14547 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14548   (vl_api_mpls_eth_tunnel_details_t * mp)
14549 {
14550   vat_main_t *vam = &vat_main;
14551   vat_json_node_t *node = NULL;
14552   struct in_addr ip4;
14553   i32 i;
14554   i32 len = ntohl (mp->nlabels);
14555
14556   if (VAT_JSON_ARRAY != vam->json_tree.type)
14557     {
14558       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14559       vat_json_init_array (&vam->json_tree);
14560     }
14561   node = vat_json_array_add (&vam->json_tree);
14562
14563   vat_json_init_object (node);
14564   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14565   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14566   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14567   vat_json_object_add_uint (node, "inner_fib_index",
14568                             ntohl (mp->inner_fib_index));
14569   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14570   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14571   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14572   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14573   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14574                                    format (0, "%U", format_ethernet_address,
14575                                            &mp->tunnel_dst_mac));
14576   vat_json_object_add_uint (node, "tx_sw_if_index",
14577                             ntohl (mp->tx_sw_if_index));
14578   vat_json_object_add_uint (node, "label_count", len);
14579   for (i = 0; i < len; i++)
14580     {
14581       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14582     }
14583 }
14584
14585 static int
14586 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14587 {
14588   vl_api_mpls_eth_tunnel_dump_t *mp;
14589   f64 timeout;
14590   i32 index = -1;
14591
14592   /* Parse args required to build the message */
14593   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14594     {
14595       if (!unformat (vam->input, "tunnel_index %d", &index))
14596         {
14597           index = -1;
14598           break;
14599         }
14600     }
14601
14602   fformat (vam->ofp, "  tunnel_index %d\n", index);
14603
14604   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14605   mp->tunnel_index = htonl (index);
14606   S;
14607
14608   /* Use a control ping for synchronization */
14609   {
14610     vl_api_control_ping_t *mp;
14611     M (CONTROL_PING, control_ping);
14612     S;
14613   }
14614   W;
14615 }
14616
14617 static void vl_api_mpls_fib_encap_details_t_handler
14618   (vl_api_mpls_fib_encap_details_t * mp)
14619 {
14620   vat_main_t *vam = &vat_main;
14621   i32 i;
14622   i32 len = ntohl (mp->nlabels);
14623
14624   fformat (vam->ofp, "table %d, dest %U, label ",
14625            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14626   for (i = 0; i < len; i++)
14627     {
14628       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14629     }
14630   fformat (vam->ofp, "\n");
14631 }
14632
14633 static void vl_api_mpls_fib_encap_details_t_handler_json
14634   (vl_api_mpls_fib_encap_details_t * mp)
14635 {
14636   vat_main_t *vam = &vat_main;
14637   vat_json_node_t *node = NULL;
14638   i32 i;
14639   i32 len = ntohl (mp->nlabels);
14640   struct in_addr ip4;
14641
14642   if (VAT_JSON_ARRAY != vam->json_tree.type)
14643     {
14644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14645       vat_json_init_array (&vam->json_tree);
14646     }
14647   node = vat_json_array_add (&vam->json_tree);
14648
14649   vat_json_init_object (node);
14650   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14651   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14652   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14653   vat_json_object_add_ip4 (node, "dest", ip4);
14654   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14655   vat_json_object_add_uint (node, "label_count", len);
14656   for (i = 0; i < len; i++)
14657     {
14658       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14659     }
14660 }
14661
14662 static int
14663 api_mpls_fib_encap_dump (vat_main_t * vam)
14664 {
14665   vl_api_mpls_fib_encap_dump_t *mp;
14666   f64 timeout;
14667
14668   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14669   S;
14670
14671   /* Use a control ping for synchronization */
14672   {
14673     vl_api_control_ping_t *mp;
14674     M (CONTROL_PING, control_ping);
14675     S;
14676   }
14677   W;
14678 }
14679
14680 static void vl_api_mpls_fib_decap_details_t_handler
14681   (vl_api_mpls_fib_decap_details_t * mp)
14682 {
14683   vat_main_t *vam = &vat_main;
14684
14685   fformat (vam->ofp,
14686            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14687            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14688            ntohl (mp->label), ntohl (mp->s_bit));
14689 }
14690
14691 static void vl_api_mpls_fib_decap_details_t_handler_json
14692   (vl_api_mpls_fib_decap_details_t * mp)
14693 {
14694   vat_main_t *vam = &vat_main;
14695   vat_json_node_t *node = NULL;
14696   struct in_addr ip4;
14697
14698   if (VAT_JSON_ARRAY != vam->json_tree.type)
14699     {
14700       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14701       vat_json_init_array (&vam->json_tree);
14702     }
14703   node = vat_json_array_add (&vam->json_tree);
14704
14705   vat_json_init_object (node);
14706   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14707   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14708   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14709   vat_json_object_add_ip4 (node, "dest", ip4);
14710   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14711   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14712   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14713   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14714   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14715 }
14716
14717 static int
14718 api_mpls_fib_decap_dump (vat_main_t * vam)
14719 {
14720   vl_api_mpls_fib_decap_dump_t *mp;
14721   f64 timeout;
14722
14723   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14724   S;
14725
14726   /* Use a control ping for synchronization */
14727   {
14728     vl_api_control_ping_t *mp;
14729     M (CONTROL_PING, control_ping);
14730     S;
14731   }
14732   W;
14733 }
14734
14735 int
14736 api_classify_table_ids (vat_main_t * vam)
14737 {
14738   vl_api_classify_table_ids_t *mp;
14739   f64 timeout;
14740
14741   /* Construct the API message */
14742   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14743   mp->context = 0;
14744
14745   S;
14746   W;
14747   /* NOTREACHED */
14748   return 0;
14749 }
14750
14751 int
14752 api_classify_table_by_interface (vat_main_t * vam)
14753 {
14754   unformat_input_t *input = vam->input;
14755   vl_api_classify_table_by_interface_t *mp;
14756   f64 timeout;
14757
14758   u32 sw_if_index = ~0;
14759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14760     {
14761       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14762         ;
14763       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14764         ;
14765       else
14766         break;
14767     }
14768   if (sw_if_index == ~0)
14769     {
14770       errmsg ("missing interface name or sw_if_index\n");
14771       return -99;
14772     }
14773
14774   /* Construct the API message */
14775   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14776   mp->context = 0;
14777   mp->sw_if_index = ntohl (sw_if_index);
14778
14779   S;
14780   W;
14781   /* NOTREACHED */
14782   return 0;
14783 }
14784
14785 int
14786 api_classify_table_info (vat_main_t * vam)
14787 {
14788   unformat_input_t *input = vam->input;
14789   vl_api_classify_table_info_t *mp;
14790   f64 timeout;
14791
14792   u32 table_id = ~0;
14793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14794     {
14795       if (unformat (input, "table_id %d", &table_id))
14796         ;
14797       else
14798         break;
14799     }
14800   if (table_id == ~0)
14801     {
14802       errmsg ("missing table id\n");
14803       return -99;
14804     }
14805
14806   /* Construct the API message */
14807   M (CLASSIFY_TABLE_INFO, classify_table_info);
14808   mp->context = 0;
14809   mp->table_id = ntohl (table_id);
14810
14811   S;
14812   W;
14813   /* NOTREACHED */
14814   return 0;
14815 }
14816
14817 int
14818 api_classify_session_dump (vat_main_t * vam)
14819 {
14820   unformat_input_t *input = vam->input;
14821   vl_api_classify_session_dump_t *mp;
14822   f64 timeout;
14823
14824   u32 table_id = ~0;
14825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14826     {
14827       if (unformat (input, "table_id %d", &table_id))
14828         ;
14829       else
14830         break;
14831     }
14832   if (table_id == ~0)
14833     {
14834       errmsg ("missing table id\n");
14835       return -99;
14836     }
14837
14838   /* Construct the API message */
14839   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14840   mp->context = 0;
14841   mp->table_id = ntohl (table_id);
14842   S;
14843
14844   /* Use a control ping for synchronization */
14845   {
14846     vl_api_control_ping_t *mp;
14847     M (CONTROL_PING, control_ping);
14848     S;
14849   }
14850   W;
14851   /* NOTREACHED */
14852   return 0;
14853 }
14854
14855 static void
14856 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14857 {
14858   vat_main_t *vam = &vat_main;
14859
14860   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14861            "src_address %U, vrf_id %d, path_mtu %u, "
14862            "template_interval %u, udp_checksum %d\n",
14863            format_ip4_address, mp->collector_address,
14864            ntohs (mp->collector_port),
14865            format_ip4_address, mp->src_address,
14866            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14867            ntohl (mp->template_interval), mp->udp_checksum);
14868
14869   vam->retval = 0;
14870   vam->result_ready = 1;
14871 }
14872
14873 static void
14874   vl_api_ipfix_exporter_details_t_handler_json
14875   (vl_api_ipfix_exporter_details_t * mp)
14876 {
14877   vat_main_t *vam = &vat_main;
14878   vat_json_node_t node;
14879   struct in_addr collector_address;
14880   struct in_addr src_address;
14881
14882   vat_json_init_object (&node);
14883   clib_memcpy (&collector_address, &mp->collector_address,
14884                sizeof (collector_address));
14885   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14886   vat_json_object_add_uint (&node, "collector_port",
14887                             ntohs (mp->collector_port));
14888   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14889   vat_json_object_add_ip4 (&node, "src_address", src_address);
14890   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14891   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14892   vat_json_object_add_uint (&node, "template_interval",
14893                             ntohl (mp->template_interval));
14894   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14895
14896   vat_json_print (vam->ofp, &node);
14897   vat_json_free (&node);
14898   vam->retval = 0;
14899   vam->result_ready = 1;
14900 }
14901
14902 int
14903 api_ipfix_exporter_dump (vat_main_t * vam)
14904 {
14905   vl_api_ipfix_exporter_dump_t *mp;
14906   f64 timeout;
14907
14908   /* Construct the API message */
14909   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14910   mp->context = 0;
14911
14912   S;
14913   W;
14914   /* NOTREACHED */
14915   return 0;
14916 }
14917
14918 static int
14919 api_ipfix_classify_stream_dump (vat_main_t * vam)
14920 {
14921   vl_api_ipfix_classify_stream_dump_t *mp;
14922   f64 timeout;
14923
14924   /* Construct the API message */
14925   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14926   mp->context = 0;
14927
14928   S;
14929   W;
14930   /* NOTREACHED */
14931   return 0;
14932 }
14933
14934 static void
14935   vl_api_ipfix_classify_stream_details_t_handler
14936   (vl_api_ipfix_classify_stream_details_t * mp)
14937 {
14938   vat_main_t *vam = &vat_main;
14939   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14940            ntohl (mp->domain_id), ntohs (mp->src_port));
14941   vam->retval = 0;
14942   vam->result_ready = 1;
14943 }
14944
14945 static void
14946   vl_api_ipfix_classify_stream_details_t_handler_json
14947   (vl_api_ipfix_classify_stream_details_t * mp)
14948 {
14949   vat_main_t *vam = &vat_main;
14950   vat_json_node_t node;
14951
14952   vat_json_init_object (&node);
14953   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14954   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14955
14956   vat_json_print (vam->ofp, &node);
14957   vat_json_free (&node);
14958   vam->retval = 0;
14959   vam->result_ready = 1;
14960 }
14961
14962 static int
14963 api_ipfix_classify_table_dump (vat_main_t * vam)
14964 {
14965   vl_api_ipfix_classify_table_dump_t *mp;
14966   f64 timeout;
14967
14968   if (!vam->json_output)
14969     {
14970       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14971                "transport_protocol");
14972     }
14973
14974   /* Construct the API message */
14975   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14976
14977   /* send it... */
14978   S;
14979
14980   /* Use a control ping for synchronization */
14981   {
14982     vl_api_control_ping_t *mp;
14983     M (CONTROL_PING, control_ping);
14984     S;
14985   }
14986   W;
14987 }
14988
14989 static void
14990   vl_api_ipfix_classify_table_details_t_handler
14991   (vl_api_ipfix_classify_table_details_t * mp)
14992 {
14993   vat_main_t *vam = &vat_main;
14994   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14995            mp->transport_protocol);
14996 }
14997
14998 static void
14999   vl_api_ipfix_classify_table_details_t_handler_json
15000   (vl_api_ipfix_classify_table_details_t * mp)
15001 {
15002   vat_json_node_t *node = NULL;
15003   vat_main_t *vam = &vat_main;
15004
15005   if (VAT_JSON_ARRAY != vam->json_tree.type)
15006     {
15007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15008       vat_json_init_array (&vam->json_tree);
15009     }
15010
15011   node = vat_json_array_add (&vam->json_tree);
15012   vat_json_init_object (node);
15013
15014   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15015   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15016   vat_json_object_add_uint (node, "transport_protocol",
15017                             mp->transport_protocol);
15018 }
15019
15020 int
15021 api_pg_create_interface (vat_main_t * vam)
15022 {
15023   unformat_input_t *input = vam->input;
15024   vl_api_pg_create_interface_t *mp;
15025   f64 timeout;
15026
15027   u32 if_id = ~0;
15028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15029     {
15030       if (unformat (input, "if_id %d", &if_id))
15031         ;
15032       else
15033         break;
15034     }
15035   if (if_id == ~0)
15036     {
15037       errmsg ("missing pg interface index\n");
15038       return -99;
15039     }
15040
15041   /* Construct the API message */
15042   M (PG_CREATE_INTERFACE, pg_create_interface);
15043   mp->context = 0;
15044   mp->interface_id = ntohl (if_id);
15045
15046   S;
15047   W;
15048   /* NOTREACHED */
15049   return 0;
15050 }
15051
15052 int
15053 api_pg_capture (vat_main_t * vam)
15054 {
15055   unformat_input_t *input = vam->input;
15056   vl_api_pg_capture_t *mp;
15057   f64 timeout;
15058
15059   u32 if_id = ~0;
15060   u8 enable = 1;
15061   u32 count = 1;
15062   u8 pcap_file_set = 0;
15063   u8 *pcap_file = 0;
15064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15065     {
15066       if (unformat (input, "if_id %d", &if_id))
15067         ;
15068       else if (unformat (input, "pcap %s", &pcap_file))
15069         pcap_file_set = 1;
15070       else if (unformat (input, "count %d", &count))
15071         ;
15072       else if (unformat (input, "disable"))
15073         enable = 0;
15074       else
15075         break;
15076     }
15077   if (if_id == ~0)
15078     {
15079       errmsg ("missing pg interface index\n");
15080       return -99;
15081     }
15082   if (pcap_file_set > 0)
15083     {
15084       if (vec_len (pcap_file) > 255)
15085         {
15086           errmsg ("pcap file name is too long\n");
15087           return -99;
15088         }
15089     }
15090
15091   u32 name_len = vec_len (pcap_file);
15092   /* Construct the API message */
15093   M (PG_CAPTURE, pg_capture);
15094   mp->context = 0;
15095   mp->interface_id = ntohl (if_id);
15096   mp->is_enabled = enable;
15097   mp->count = ntohl (count);
15098   mp->pcap_name_length = ntohl (name_len);
15099   if (pcap_file_set != 0)
15100     {
15101       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15102     }
15103   vec_free (pcap_file);
15104
15105   S;
15106   W;
15107   /* NOTREACHED */
15108   return 0;
15109 }
15110
15111 int
15112 api_pg_enable_disable (vat_main_t * vam)
15113 {
15114   unformat_input_t *input = vam->input;
15115   vl_api_pg_enable_disable_t *mp;
15116   f64 timeout;
15117
15118   u8 enable = 1;
15119   u8 stream_name_set = 0;
15120   u8 *stream_name = 0;
15121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15122     {
15123       if (unformat (input, "stream %s", &stream_name))
15124         stream_name_set = 1;
15125       else if (unformat (input, "disable"))
15126         enable = 0;
15127       else
15128         break;
15129     }
15130
15131   if (stream_name_set > 0)
15132     {
15133       if (vec_len (stream_name) > 255)
15134         {
15135           errmsg ("stream name too long\n");
15136           return -99;
15137         }
15138     }
15139
15140   u32 name_len = vec_len (stream_name);
15141   /* Construct the API message */
15142   M (PG_ENABLE_DISABLE, pg_enable_disable);
15143   mp->context = 0;
15144   mp->is_enabled = enable;
15145   if (stream_name_set != 0)
15146     {
15147       mp->stream_name_length = ntohl (name_len);
15148       clib_memcpy (mp->stream_name, stream_name, name_len);
15149     }
15150   vec_free (stream_name);
15151
15152   S;
15153   W;
15154   /* NOTREACHED */
15155   return 0;
15156 }
15157
15158 int
15159 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15160 {
15161   unformat_input_t *input = vam->input;
15162   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15163   f64 timeout;
15164
15165   u16 *low_ports = 0;
15166   u16 *high_ports = 0;
15167   u16 this_low;
15168   u16 this_hi;
15169   ip4_address_t ip4_addr;
15170   ip6_address_t ip6_addr;
15171   u32 length;
15172   u32 tmp, tmp2;
15173   u8 prefix_set = 0;
15174   u32 vrf_id = ~0;
15175   u8 is_add = 1;
15176   u8 is_ipv6 = 0;
15177
15178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15179     {
15180       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15181         {
15182           prefix_set = 1;
15183         }
15184       else
15185         if (unformat
15186             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15187         {
15188           prefix_set = 1;
15189           is_ipv6 = 1;
15190         }
15191       else if (unformat (input, "vrf %d", &vrf_id))
15192         ;
15193       else if (unformat (input, "del"))
15194         is_add = 0;
15195       else if (unformat (input, "port %d", &tmp))
15196         {
15197           if (tmp == 0 || tmp > 65535)
15198             {
15199               errmsg ("port %d out of range", tmp);
15200               return -99;
15201             }
15202           this_low = tmp;
15203           this_hi = this_low + 1;
15204           vec_add1 (low_ports, this_low);
15205           vec_add1 (high_ports, this_hi);
15206         }
15207       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15208         {
15209           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15210             {
15211               errmsg ("incorrect range parameters\n");
15212               return -99;
15213             }
15214           this_low = tmp;
15215           /* Note: in debug CLI +1 is added to high before
15216              passing to real fn that does "the work"
15217              (ip_source_and_port_range_check_add_del).
15218              This fn is a wrapper around the binary API fn a
15219              control plane will call, which expects this increment
15220              to have occurred. Hence letting the binary API control
15221              plane fn do the increment for consistency between VAT
15222              and other control planes.
15223            */
15224           this_hi = tmp2;
15225           vec_add1 (low_ports, this_low);
15226           vec_add1 (high_ports, this_hi);
15227         }
15228       else
15229         break;
15230     }
15231
15232   if (prefix_set == 0)
15233     {
15234       errmsg ("<address>/<mask> not specified\n");
15235       return -99;
15236     }
15237
15238   if (vrf_id == ~0)
15239     {
15240       errmsg ("VRF ID required, not specified\n");
15241       return -99;
15242     }
15243
15244   if (vrf_id == 0)
15245     {
15246       errmsg
15247         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15248       return -99;
15249     }
15250
15251   if (vec_len (low_ports) == 0)
15252     {
15253       errmsg ("At least one port or port range required\n");
15254       return -99;
15255     }
15256
15257   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15258      ip_source_and_port_range_check_add_del);
15259
15260   mp->is_add = is_add;
15261
15262   if (is_ipv6)
15263     {
15264       mp->is_ipv6 = 1;
15265       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15266     }
15267   else
15268     {
15269       mp->is_ipv6 = 0;
15270       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15271     }
15272
15273   mp->mask_length = length;
15274   mp->number_of_ranges = vec_len (low_ports);
15275
15276   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15277   vec_free (low_ports);
15278
15279   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15280   vec_free (high_ports);
15281
15282   mp->vrf_id = ntohl (vrf_id);
15283
15284   S;
15285   W;
15286   /* NOTREACHED */
15287   return 0;
15288 }
15289
15290 int
15291 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15292 {
15293   unformat_input_t *input = vam->input;
15294   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15295   f64 timeout;
15296   u32 sw_if_index = ~0;
15297   int vrf_set = 0;
15298   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15299   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15300   u8 is_add = 1;
15301
15302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15303     {
15304       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15305         ;
15306       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15307         ;
15308       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15309         vrf_set = 1;
15310       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15311         vrf_set = 1;
15312       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15313         vrf_set = 1;
15314       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15315         vrf_set = 1;
15316       else if (unformat (input, "del"))
15317         is_add = 0;
15318       else
15319         break;
15320     }
15321
15322   if (sw_if_index == ~0)
15323     {
15324       errmsg ("Interface required but not specified\n");
15325       return -99;
15326     }
15327
15328   if (vrf_set == 0)
15329     {
15330       errmsg ("VRF ID required but not specified\n");
15331       return -99;
15332     }
15333
15334   if (tcp_out_vrf_id == 0
15335       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15336     {
15337       errmsg
15338         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15339       return -99;
15340     }
15341
15342   /* Construct the API message */
15343   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15344      ip_source_and_port_range_check_interface_add_del);
15345
15346   mp->sw_if_index = ntohl (sw_if_index);
15347   mp->is_add = is_add;
15348   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15349   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15350   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15351   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15352
15353   /* send it... */
15354   S;
15355
15356   /* Wait for a reply... */
15357   W;
15358 }
15359
15360 static int
15361 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15362 {
15363   unformat_input_t *i = vam->input;
15364   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15365   f64 timeout;
15366   u32 local_sa_id = 0;
15367   u32 remote_sa_id = 0;
15368   ip4_address_t src_address;
15369   ip4_address_t dst_address;
15370   u8 is_add = 1;
15371
15372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15373     {
15374       if (unformat (i, "local_sa %d", &local_sa_id))
15375         ;
15376       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15377         ;
15378       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15379         ;
15380       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15381         ;
15382       else if (unformat (i, "del"))
15383         is_add = 0;
15384       else
15385         {
15386           clib_warning ("parse error '%U'", format_unformat_error, i);
15387           return -99;
15388         }
15389     }
15390
15391   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15392
15393   mp->local_sa_id = ntohl (local_sa_id);
15394   mp->remote_sa_id = ntohl (remote_sa_id);
15395   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15396   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15397   mp->is_add = is_add;
15398
15399   S;
15400   W;
15401   /* NOTREACHED */
15402   return 0;
15403 }
15404
15405 static void vl_api_ipsec_gre_tunnel_details_t_handler
15406   (vl_api_ipsec_gre_tunnel_details_t * mp)
15407 {
15408   vat_main_t *vam = &vat_main;
15409
15410   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15411            ntohl (mp->sw_if_index),
15412            format_ip4_address, &mp->src_address,
15413            format_ip4_address, &mp->dst_address,
15414            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15415 }
15416
15417 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15418   (vl_api_ipsec_gre_tunnel_details_t * mp)
15419 {
15420   vat_main_t *vam = &vat_main;
15421   vat_json_node_t *node = NULL;
15422   struct in_addr ip4;
15423
15424   if (VAT_JSON_ARRAY != vam->json_tree.type)
15425     {
15426       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15427       vat_json_init_array (&vam->json_tree);
15428     }
15429   node = vat_json_array_add (&vam->json_tree);
15430
15431   vat_json_init_object (node);
15432   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15433   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15434   vat_json_object_add_ip4 (node, "src_address", ip4);
15435   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15436   vat_json_object_add_ip4 (node, "dst_address", ip4);
15437   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15438   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15439 }
15440
15441 static int
15442 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15443 {
15444   unformat_input_t *i = vam->input;
15445   vl_api_ipsec_gre_tunnel_dump_t *mp;
15446   f64 timeout;
15447   u32 sw_if_index;
15448   u8 sw_if_index_set = 0;
15449
15450   /* Parse args required to build the message */
15451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15452     {
15453       if (unformat (i, "sw_if_index %d", &sw_if_index))
15454         sw_if_index_set = 1;
15455       else
15456         break;
15457     }
15458
15459   if (sw_if_index_set == 0)
15460     {
15461       sw_if_index = ~0;
15462     }
15463
15464   if (!vam->json_output)
15465     {
15466       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15467                "sw_if_index", "src_address", "dst_address",
15468                "local_sa_id", "remote_sa_id");
15469     }
15470
15471   /* Get list of gre-tunnel interfaces */
15472   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15473
15474   mp->sw_if_index = htonl (sw_if_index);
15475
15476   S;
15477
15478   /* Use a control ping for synchronization */
15479   {
15480     vl_api_control_ping_t *mp;
15481     M (CONTROL_PING, control_ping);
15482     S;
15483   }
15484   W;
15485 }
15486
15487 static int
15488 api_delete_subif (vat_main_t * vam)
15489 {
15490   unformat_input_t *i = vam->input;
15491   vl_api_delete_subif_t *mp;
15492   f64 timeout;
15493   u32 sw_if_index = ~0;
15494
15495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15496     {
15497       if (unformat (i, "sw_if_index %d", &sw_if_index))
15498         ;
15499       else
15500         break;
15501     }
15502
15503   if (sw_if_index == ~0)
15504     {
15505       errmsg ("missing sw_if_index\n");
15506       return -99;
15507     }
15508
15509   /* Construct the API message */
15510   M (DELETE_SUBIF, delete_subif);
15511   mp->sw_if_index = ntohl (sw_if_index);
15512
15513   S;
15514   W;
15515 }
15516
15517 static int
15518 q_or_quit (vat_main_t * vam)
15519 {
15520   longjmp (vam->jump_buf, 1);
15521   return 0;                     /* not so much */
15522 }
15523
15524 static int
15525 q (vat_main_t * vam)
15526 {
15527   return q_or_quit (vam);
15528 }
15529
15530 static int
15531 quit (vat_main_t * vam)
15532 {
15533   return q_or_quit (vam);
15534 }
15535
15536 static int
15537 comment (vat_main_t * vam)
15538 {
15539   return 0;
15540 }
15541
15542 static int
15543 cmd_cmp (void *a1, void *a2)
15544 {
15545   u8 **c1 = a1;
15546   u8 **c2 = a2;
15547
15548   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15549 }
15550
15551 static int
15552 help (vat_main_t * vam)
15553 {
15554   u8 **cmds = 0;
15555   u8 *name = 0;
15556   hash_pair_t *p;
15557   unformat_input_t *i = vam->input;
15558   int j;
15559
15560   if (unformat (i, "%s", &name))
15561     {
15562       uword *hs;
15563
15564       vec_add1 (name, 0);
15565
15566       hs = hash_get_mem (vam->help_by_name, name);
15567       if (hs)
15568         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15569       else
15570         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15571       vec_free (name);
15572       return 0;
15573     }
15574
15575   fformat (vam->ofp, "Help is available for the following:\n");
15576
15577     /* *INDENT-OFF* */
15578     hash_foreach_pair (p, vam->function_by_name,
15579     ({
15580       vec_add1 (cmds, (u8 *)(p->key));
15581     }));
15582     /* *INDENT-ON* */
15583
15584   vec_sort_with_function (cmds, cmd_cmp);
15585
15586   for (j = 0; j < vec_len (cmds); j++)
15587     fformat (vam->ofp, "%s\n", cmds[j]);
15588
15589   vec_free (cmds);
15590   return 0;
15591 }
15592
15593 static int
15594 set (vat_main_t * vam)
15595 {
15596   u8 *name = 0, *value = 0;
15597   unformat_input_t *i = vam->input;
15598
15599   if (unformat (i, "%s", &name))
15600     {
15601       /* The input buffer is a vector, not a string. */
15602       value = vec_dup (i->buffer);
15603       vec_delete (value, i->index, 0);
15604       /* Almost certainly has a trailing newline */
15605       if (value[vec_len (value) - 1] == '\n')
15606         value[vec_len (value) - 1] = 0;
15607       /* Make sure it's a proper string, one way or the other */
15608       vec_add1 (value, 0);
15609       (void) clib_macro_set_value (&vam->macro_main,
15610                                    (char *) name, (char *) value);
15611     }
15612   else
15613     errmsg ("usage: set <name> <value>\n");
15614
15615   vec_free (name);
15616   vec_free (value);
15617   return 0;
15618 }
15619
15620 static int
15621 unset (vat_main_t * vam)
15622 {
15623   u8 *name = 0;
15624
15625   if (unformat (vam->input, "%s", &name))
15626     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15627       errmsg ("unset: %s wasn't set\n", name);
15628   vec_free (name);
15629   return 0;
15630 }
15631
15632 typedef struct
15633 {
15634   u8 *name;
15635   u8 *value;
15636 } macro_sort_t;
15637
15638
15639 static int
15640 macro_sort_cmp (void *a1, void *a2)
15641 {
15642   macro_sort_t *s1 = a1;
15643   macro_sort_t *s2 = a2;
15644
15645   return strcmp ((char *) (s1->name), (char *) (s2->name));
15646 }
15647
15648 static int
15649 dump_macro_table (vat_main_t * vam)
15650 {
15651   macro_sort_t *sort_me = 0, *sm;
15652   int i;
15653   hash_pair_t *p;
15654
15655     /* *INDENT-OFF* */
15656     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15657     ({
15658       vec_add2 (sort_me, sm, 1);
15659       sm->name = (u8 *)(p->key);
15660       sm->value = (u8 *) (p->value[0]);
15661     }));
15662     /* *INDENT-ON* */
15663
15664   vec_sort_with_function (sort_me, macro_sort_cmp);
15665
15666   if (vec_len (sort_me))
15667     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15668   else
15669     fformat (vam->ofp, "The macro table is empty...\n");
15670
15671   for (i = 0; i < vec_len (sort_me); i++)
15672     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15673   return 0;
15674 }
15675
15676 static int
15677 dump_node_table (vat_main_t * vam)
15678 {
15679   int i, j;
15680   vlib_node_t *node, *next_node;
15681
15682   if (vec_len (vam->graph_nodes) == 0)
15683     {
15684       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15685       return 0;
15686     }
15687
15688   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15689     {
15690       node = vam->graph_nodes[i];
15691       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15692       for (j = 0; j < vec_len (node->next_nodes); j++)
15693         {
15694           if (node->next_nodes[j] != ~0)
15695             {
15696               next_node = vam->graph_nodes[node->next_nodes[j]];
15697               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15698             }
15699         }
15700     }
15701   return 0;
15702 }
15703
15704 static int
15705 search_node_table (vat_main_t * vam)
15706 {
15707   unformat_input_t *line_input = vam->input;
15708   u8 *node_to_find;
15709   int j;
15710   vlib_node_t *node, *next_node;
15711   uword *p;
15712
15713   if (vam->graph_node_index_by_name == 0)
15714     {
15715       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15716       return 0;
15717     }
15718
15719   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15720     {
15721       if (unformat (line_input, "%s", &node_to_find))
15722         {
15723           vec_add1 (node_to_find, 0);
15724           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15725           if (p == 0)
15726             {
15727               fformat (vam->ofp, "%s not found...\n", node_to_find);
15728               goto out;
15729             }
15730           node = vam->graph_nodes[p[0]];
15731           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15732           for (j = 0; j < vec_len (node->next_nodes); j++)
15733             {
15734               if (node->next_nodes[j] != ~0)
15735                 {
15736                   next_node = vam->graph_nodes[node->next_nodes[j]];
15737                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15738                 }
15739             }
15740         }
15741
15742       else
15743         {
15744           clib_warning ("parse error '%U'", format_unformat_error,
15745                         line_input);
15746           return -99;
15747         }
15748
15749     out:
15750       vec_free (node_to_find);
15751
15752     }
15753
15754   return 0;
15755 }
15756
15757
15758 static int
15759 script (vat_main_t * vam)
15760 {
15761   u8 *s = 0;
15762   char *save_current_file;
15763   unformat_input_t save_input;
15764   jmp_buf save_jump_buf;
15765   u32 save_line_number;
15766
15767   FILE *new_fp, *save_ifp;
15768
15769   if (unformat (vam->input, "%s", &s))
15770     {
15771       new_fp = fopen ((char *) s, "r");
15772       if (new_fp == 0)
15773         {
15774           errmsg ("Couldn't open script file %s\n", s);
15775           vec_free (s);
15776           return -99;
15777         }
15778     }
15779   else
15780     {
15781       errmsg ("Missing script name\n");
15782       return -99;
15783     }
15784
15785   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15786   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15787   save_ifp = vam->ifp;
15788   save_line_number = vam->input_line_number;
15789   save_current_file = (char *) vam->current_file;
15790
15791   vam->input_line_number = 0;
15792   vam->ifp = new_fp;
15793   vam->current_file = s;
15794   do_one_file (vam);
15795
15796   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15797   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15798   vam->ifp = save_ifp;
15799   vam->input_line_number = save_line_number;
15800   vam->current_file = (u8 *) save_current_file;
15801   vec_free (s);
15802
15803   return 0;
15804 }
15805
15806 static int
15807 echo (vat_main_t * vam)
15808 {
15809   fformat (vam->ofp, "%v", vam->input->buffer);
15810   return 0;
15811 }
15812
15813 /* List of API message constructors, CLI names map to api_xxx */
15814 #define foreach_vpe_api_msg                                             \
15815 _(create_loopback,"[mac <mac-addr>]")                                   \
15816 _(sw_interface_dump,"")                                                 \
15817 _(sw_interface_set_flags,                                               \
15818   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15819 _(sw_interface_add_del_address,                                         \
15820   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15821 _(sw_interface_set_table,                                               \
15822   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15823 _(sw_interface_set_vpath,                                               \
15824   "<intfc> | sw_if_index <id> enable | disable")                        \
15825 _(sw_interface_set_l2_xconnect,                                         \
15826   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15827   "enable | disable")                                                   \
15828 _(sw_interface_set_l2_bridge,                                           \
15829   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15830   "[shg <split-horizon-group>] [bvi]\n"                                 \
15831   "enable | disable")                                                   \
15832 _(bridge_domain_add_del,                                                \
15833   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15834 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15835 _(l2fib_add_del,                                                        \
15836   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15837 _(l2_flags,                                                             \
15838   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15839 _(bridge_flags,                                                         \
15840   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15841 _(tap_connect,                                                          \
15842   "tapname <name> mac <mac-addr> | random-mac")                         \
15843 _(tap_modify,                                                           \
15844   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15845 _(tap_delete,                                                           \
15846   "<vpp-if-name> | sw_if_index <id>")                                   \
15847 _(sw_interface_tap_dump, "")                                            \
15848 _(ip_add_del_route,                                                     \
15849   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15850   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15851   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15852   "[multipath] [count <n>]")                                            \
15853 _(proxy_arp_add_del,                                                    \
15854   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15855 _(proxy_arp_intfc_enable_disable,                                       \
15856   "<intfc> | sw_if_index <id> enable | disable")                        \
15857 _(mpls_add_del_encap,                                                   \
15858   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15859 _(mpls_add_del_decap,                                                   \
15860   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15861 _(mpls_gre_add_del_tunnel,                                              \
15862   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15863   "adj <ip4-address>/<mask-width> [del]")                               \
15864 _(sw_interface_set_unnumbered,                                          \
15865   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15866 _(ip_neighbor_add_del,                                                  \
15867   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15868   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15869 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15870 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15871 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15872   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15873   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15874   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15875 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15876 _(reset_fib, "vrf <n> [ipv6]")                                          \
15877 _(dhcp_proxy_config,                                                    \
15878   "svr <v46-address> src <v46-address>\n"                               \
15879    "insert-cid <n> [del]")                                              \
15880 _(dhcp_proxy_config_2,                                                  \
15881   "svr <v46-address> src <v46-address>\n"                               \
15882    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15883 _(dhcp_proxy_set_vss,                                                   \
15884   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15885 _(dhcp_client_config,                                                   \
15886   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15887 _(set_ip_flow_hash,                                                     \
15888   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15889 _(sw_interface_ip6_enable_disable,                                      \
15890   "<intfc> | sw_if_index <id> enable | disable")                        \
15891 _(sw_interface_ip6_set_link_local_address,                              \
15892   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15893 _(sw_interface_ip6nd_ra_prefix,                                         \
15894   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15895   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15896   "[nolink] [isno]")                                                    \
15897 _(sw_interface_ip6nd_ra_config,                                         \
15898   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15899   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15900   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15901 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15902 _(l2_patch_add_del,                                                     \
15903   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15904   "enable | disable")                                                   \
15905 _(mpls_ethernet_add_del_tunnel,                                         \
15906   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15907   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15908 _(mpls_ethernet_add_del_tunnel_2,                                       \
15909   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15910   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15911 _(sr_tunnel_add_del,                                                    \
15912   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15913   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15914   "[policy <policy_name>]")                                             \
15915 _(sr_policy_add_del,                                                    \
15916   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15917 _(sr_multicast_map_add_del,                                             \
15918   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15919 _(classify_add_del_table,                                               \
15920   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15921   "[del] mask <mask-value>\n"                                           \
15922   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15923 _(classify_add_del_session,                                             \
15924   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15925   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15926   "  [l3 [ip4|ip6]]")                                                   \
15927 _(classify_set_interface_ip_table,                                      \
15928   "<intfc> | sw_if_index <nn> table <nn>")                              \
15929 _(classify_set_interface_l2_tables,                                     \
15930   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15931   "  [other-table <nn>]")                                               \
15932 _(get_node_index, "node <node-name")                                    \
15933 _(add_node_next, "node <node-name> next <next-node-name>")              \
15934 _(l2tpv3_create_tunnel,                                                 \
15935   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15936   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15937   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15938 _(l2tpv3_set_tunnel_cookies,                                            \
15939   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15940   "[new_remote_cookie <nn>]\n")                                         \
15941 _(l2tpv3_interface_enable_disable,                                      \
15942   "<intfc> | sw_if_index <nn> enable | disable")                        \
15943 _(l2tpv3_set_lookup_key,                                                \
15944   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15945 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15946 _(vxlan_add_del_tunnel,                                                 \
15947   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15948   " [decap-next l2|ip4|ip6] [del]")                                     \
15949 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15950 _(gre_add_del_tunnel,                                                   \
15951   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15952 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15953 _(l2_fib_clear_table, "")                                               \
15954 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15955 _(l2_interface_vlan_tag_rewrite,                                        \
15956   "<intfc> | sw_if_index <nn> \n"                                       \
15957   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15958   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15959 _(create_vhost_user_if,                                                 \
15960         "socket <filename> [server] [renumber <dev_instance>] "         \
15961         "[mac <mac_address>]")                                          \
15962 _(modify_vhost_user_if,                                                 \
15963         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15964         "[server] [renumber <dev_instance>]")                           \
15965 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15966 _(sw_interface_vhost_user_dump, "")                                     \
15967 _(show_version, "")                                                     \
15968 _(vxlan_gpe_add_del_tunnel,                                             \
15969   "local <addr> remote <addr> vni <nn>\n"                               \
15970     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15971   "[next-ethernet] [next-nsh]\n")                                       \
15972 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15973 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15974 _(interface_name_renumber,                                              \
15975   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15976 _(input_acl_set_interface,                                              \
15977   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15978   "  [l2-table <nn>] [del]")                                            \
15979 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15980 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15981 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15982 _(ip_dump, "ipv4 | ipv6")                                               \
15983 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15984 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15985   "  spid_id <n> ")                                                     \
15986 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15987   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15988   "  integ_alg <alg> integ_key <hex>")                                  \
15989 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15990   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15991   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15992   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15993 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15994 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15995 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15996   "(auth_data 0x<data> | auth_data <data>)")                            \
15997 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15998   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15999 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16000   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16001   "(local|remote)")                                                     \
16002 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16003 _(delete_loopback,"sw_if_index <nn>")                                   \
16004 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16005 _(map_add_domain,                                                       \
16006   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16007   "ip6-src <ip6addr> "                                                  \
16008   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16009 _(map_del_domain, "index <n>")                                          \
16010 _(map_add_del_rule,                                                     \
16011   "index <n> psid <n> dst <ip6addr> [del]")                             \
16012 _(map_domain_dump, "")                                                  \
16013 _(map_rule_dump, "index <map-domain>")                                  \
16014 _(want_interface_events,  "enable|disable")                             \
16015 _(want_stats,"enable|disable")                                          \
16016 _(get_first_msg_id, "client <name>")                                    \
16017 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16018 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16019   "fib-id <nn> [ip4][ip6][default]")                                    \
16020 _(get_node_graph, " ")                                                  \
16021 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16022 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16023 _(ioam_disable, "")                                                \
16024 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16025                             " sw_if_index <sw_if_index> p <priority> "  \
16026                             "w <weight>] [del]")                        \
16027 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16028                         "iface <intf> | sw_if_index <sw_if_index> "     \
16029                         "p <priority> w <weight> [del]")                \
16030 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16031                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16032                           "locator-set <locator_name> [del]")           \
16033 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16034   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16035 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16036 _(lisp_gpe_enable_disable, "enable|disable")                            \
16037 _(lisp_enable_disable, "enable|disable")                                \
16038 _(lisp_gpe_add_del_iface, "up|down")                                    \
16039 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
16040                                "rloc <locator> p <prio> "               \
16041                                "w <weight> [rloc <loc> ... ] "          \
16042                                "action <action> [del-all]")             \
16043 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
16044                           "<src-eid> rloc <locator> p <prio> w <weight>"\
16045                           "[rloc <loc> ... ] action <action>")          \
16046 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16047 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16048 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16049 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
16050                          "locator-set <loc-set-name>] [local | remote]")\
16051 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16052                        "[local] | [remote]")                            \
16053 _(lisp_eid_table_vni_dump, "")                                          \
16054 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16055 _(lisp_gpe_tunnel_dump, "")                                             \
16056 _(lisp_map_resolver_dump, "")                                           \
16057 _(show_lisp_status, "")                                                 \
16058 _(lisp_get_map_request_itr_rlocs, "")                                   \
16059 _(show_lisp_pitr, "")                                                   \
16060 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16061 _(af_packet_delete, "name <host interface name>")                       \
16062 _(policer_add_del, "name <policer name> <params> [del]")                \
16063 _(policer_dump, "[name <policer name>]")                                \
16064 _(policer_classify_set_interface,                                       \
16065   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16066   "  [l2-table <nn>] [del]")                                            \
16067 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16068 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16069     "[master|slave]")                                                   \
16070 _(netmap_delete, "name <interface name>")                               \
16071 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16072 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16073 _(mpls_fib_encap_dump, "")                                              \
16074 _(mpls_fib_decap_dump, "")                                              \
16075 _(classify_table_ids, "")                                               \
16076 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16077 _(classify_table_info, "table_id <nn>")                                 \
16078 _(classify_session_dump, "table_id <nn>")                               \
16079 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16080     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16081     "[template_interval <nn>] [udp_checksum]")                          \
16082 _(ipfix_exporter_dump, "")                                              \
16083 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16084 _(ipfix_classify_stream_dump, "")                                       \
16085 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16086 _(ipfix_classify_table_dump, "")                                        \
16087 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16088 _(pg_create_interface, "if_id <nn>")                                    \
16089 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16090 _(pg_enable_disable, "[stream <id>] disable")                           \
16091 _(ip_source_and_port_range_check_add_del,                               \
16092   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16093 _(ip_source_and_port_range_check_interface_add_del,                     \
16094   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16095   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16096 _(ipsec_gre_add_del_tunnel,                                             \
16097   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16098 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16099 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
16100
16101 /* List of command functions, CLI names map directly to functions */
16102 #define foreach_cli_function                                    \
16103 _(comment, "usage: comment <ignore-rest-of-line>")              \
16104 _(dump_interface_table, "usage: dump_interface_table")          \
16105 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16106 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16107 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16108 _(dump_stats_table, "usage: dump_stats_table")                  \
16109 _(dump_macro_table, "usage: dump_macro_table ")                 \
16110 _(dump_node_table, "usage: dump_node_table")                    \
16111 _(echo, "usage: echo <message>")                                \
16112 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16113 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16114 _(help, "usage: help")                                          \
16115 _(q, "usage: quit")                                             \
16116 _(quit, "usage: quit")                                          \
16117 _(search_node_table, "usage: search_node_table <name>...")      \
16118 _(set, "usage: set <variable-name> <value>")                    \
16119 _(script, "usage: script <file-name>")                          \
16120 _(unset, "usage: unset <variable-name>")
16121
16122 #define _(N,n)                                  \
16123     static void vl_api_##n##_t_handler_uni      \
16124     (vl_api_##n##_t * mp)                       \
16125     {                                           \
16126         vat_main_t * vam = &vat_main;           \
16127         if (vam->json_output) {                 \
16128             vl_api_##n##_t_handler_json(mp);    \
16129         } else {                                \
16130             vl_api_##n##_t_handler(mp);         \
16131         }                                       \
16132     }
16133 foreach_vpe_api_reply_msg;
16134 #undef _
16135
16136 void
16137 vat_api_hookup (vat_main_t * vam)
16138 {
16139 #define _(N,n)                                                  \
16140     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16141                            vl_api_##n##_t_handler_uni,          \
16142                            vl_noop_handler,                     \
16143                            vl_api_##n##_t_endian,               \
16144                            vl_api_##n##_t_print,                \
16145                            sizeof(vl_api_##n##_t), 1);
16146   foreach_vpe_api_reply_msg;
16147 #undef _
16148
16149   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16150
16151   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16152
16153   vam->function_by_name = hash_create_string (0, sizeof (uword));
16154
16155   vam->help_by_name = hash_create_string (0, sizeof (uword));
16156
16157   /* API messages we can send */
16158 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16159   foreach_vpe_api_msg;
16160 #undef _
16161
16162   /* Help strings */
16163 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16164   foreach_vpe_api_msg;
16165 #undef _
16166
16167   /* CLI functions */
16168 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16169   foreach_cli_function;
16170 #undef _
16171
16172   /* Help strings */
16173 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16174   foreach_cli_function;
16175 #undef _
16176 }
16177
16178 #undef vl_api_version
16179 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16180 #include <vpp-api/vpe.api.h>
16181 #undef vl_api_version
16182
16183 void
16184 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16185 {
16186   /*
16187    * Send the main API signature in slot 0. This bit of code must
16188    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16189    */
16190   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16191 }
16192
16193 /*
16194  * fd.io coding-style-patch-verification: ON
16195  *
16196  * Local Variables:
16197  * eval: (c-set-style "gnu")
16198  * End:
16199  */