VPP-369 Add an L2 output classification feature
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 static void
1138 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1139 {
1140   vat_main_t *vam = &vat_main;
1141   errmsg ("ip6 nd event: address %U new mac %U sw_if_index %d\n",
1142           format_ip6_address, mp->address,
1143           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1144 }
1145
1146 static void
1147 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1148 {
1149   /* JSON output not supported */
1150 }
1151
1152 /*
1153  * Special-case: build the bridge domain table, maintain
1154  * the next bd id vbl.
1155  */
1156 static void vl_api_bridge_domain_details_t_handler
1157   (vl_api_bridge_domain_details_t * mp)
1158 {
1159   vat_main_t *vam = &vat_main;
1160   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1161
1162   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1163            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1164
1165   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1166            ntohl (mp->bd_id), mp->learn, mp->forward,
1167            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1168
1169   if (n_sw_ifs)
1170     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1171              "Interface Name");
1172 }
1173
1174 static void vl_api_bridge_domain_details_t_handler_json
1175   (vl_api_bridge_domain_details_t * mp)
1176 {
1177   vat_main_t *vam = &vat_main;
1178   vat_json_node_t *node, *array = NULL;
1179
1180   if (VAT_JSON_ARRAY != vam->json_tree.type)
1181     {
1182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1183       vat_json_init_array (&vam->json_tree);
1184     }
1185   node = vat_json_array_add (&vam->json_tree);
1186
1187   vat_json_init_object (node);
1188   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1189   vat_json_object_add_uint (node, "flood", mp->flood);
1190   vat_json_object_add_uint (node, "forward", mp->forward);
1191   vat_json_object_add_uint (node, "learn", mp->learn);
1192   vat_json_object_add_uint (node, "bvi_sw_if_index",
1193                             ntohl (mp->bvi_sw_if_index));
1194   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1195   array = vat_json_object_add (node, "sw_if");
1196   vat_json_init_array (array);
1197 }
1198
1199 /*
1200  * Special-case: build the bridge domain sw if table.
1201  */
1202 static void vl_api_bridge_domain_sw_if_details_t_handler
1203   (vl_api_bridge_domain_sw_if_details_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   hash_pair_t *p;
1207   u8 *sw_if_name = 0;
1208   u32 sw_if_index;
1209
1210   sw_if_index = ntohl (mp->sw_if_index);
1211   /* *INDENT-OFF* */
1212   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1213   ({
1214     if ((u32) p->value[0] == sw_if_index)
1215       {
1216         sw_if_name = (u8 *)(p->key);
1217         break;
1218       }
1219   }));
1220   /* *INDENT-ON* */
1221
1222   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1223            mp->shg, sw_if_name ? (char *) sw_if_name :
1224            "sw_if_index not found!");
1225 }
1226
1227 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1228   (vl_api_bridge_domain_sw_if_details_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   vat_json_node_t *node = NULL;
1232   uword last_index = 0;
1233
1234   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1235   ASSERT (vec_len (vam->json_tree.array) >= 1);
1236   last_index = vec_len (vam->json_tree.array) - 1;
1237   node = &vam->json_tree.array[last_index];
1238   node = vat_json_object_get_element (node, "sw_if");
1239   ASSERT (NULL != node);
1240   node = vat_json_array_add (node);
1241
1242   vat_json_init_object (node);
1243   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1245   vat_json_object_add_uint (node, "shg", mp->shg);
1246 }
1247
1248 static void vl_api_control_ping_reply_t_handler
1249   (vl_api_control_ping_reply_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   i32 retval = ntohl (mp->retval);
1253   if (vam->async_mode)
1254     {
1255       vam->async_errors += (retval < 0);
1256     }
1257   else
1258     {
1259       vam->retval = retval;
1260       vam->result_ready = 1;
1261     }
1262 }
1263
1264 static void vl_api_control_ping_reply_t_handler_json
1265   (vl_api_control_ping_reply_t * mp)
1266 {
1267   vat_main_t *vam = &vat_main;
1268   i32 retval = ntohl (mp->retval);
1269
1270   if (VAT_JSON_NONE != vam->json_tree.type)
1271     {
1272       vat_json_print (vam->ofp, &vam->json_tree);
1273       vat_json_free (&vam->json_tree);
1274       vam->json_tree.type = VAT_JSON_NONE;
1275     }
1276   else
1277     {
1278       /* just print [] */
1279       vat_json_init_array (&vam->json_tree);
1280       vat_json_print (vam->ofp, &vam->json_tree);
1281       vam->json_tree.type = VAT_JSON_NONE;
1282     }
1283
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_noprint_control_ping_reply_t_handler
1289   (vl_api_noprint_control_ping_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   i32 retval = ntohl (mp->retval);
1293   if (vam->async_mode)
1294     {
1295       vam->async_errors += (retval < 0);
1296     }
1297   else
1298     {
1299       vam->retval = retval;
1300       vam->result_ready = 1;
1301     }
1302 }
1303
1304 static void vl_api_noprint_control_ping_reply_t_handler_json
1305   (vl_api_noprint_control_ping_reply_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   i32 retval = ntohl (mp->retval);
1309
1310   if (vam->noprint_msg)
1311     {
1312       vam->retval = retval;
1313       vam->result_ready = 1;
1314       return;
1315     }
1316
1317   if (VAT_JSON_NONE != vam->json_tree.type)
1318     {
1319       vat_json_print (vam->ofp, &vam->json_tree);
1320       vat_json_free (&vam->json_tree);
1321       vam->json_tree.type = VAT_JSON_NONE;
1322     }
1323   else
1324     {
1325       /* just print [] */
1326       vat_json_init_array (&vam->json_tree);
1327       vat_json_print (vam->ofp, &vam->json_tree);
1328       vam->json_tree.type = VAT_JSON_NONE;
1329     }
1330
1331   vam->retval = retval;
1332   vam->result_ready = 1;
1333 }
1334
1335 static void
1336 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   i32 retval = ntohl (mp->retval);
1340   if (vam->async_mode)
1341     {
1342       vam->async_errors += (retval < 0);
1343     }
1344   else
1345     {
1346       vam->retval = retval;
1347       vam->result_ready = 1;
1348     }
1349 }
1350
1351 static void vl_api_l2_flags_reply_t_handler_json
1352   (vl_api_l2_flags_reply_t * mp)
1353 {
1354   vat_main_t *vam = &vat_main;
1355   vat_json_node_t node;
1356
1357   vat_json_init_object (&node);
1358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1359   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1360                             ntohl (mp->resulting_feature_bitmap));
1361
1362   vat_json_print (vam->ofp, &node);
1363   vat_json_free (&node);
1364
1365   vam->retval = ntohl (mp->retval);
1366   vam->result_ready = 1;
1367 }
1368
1369 static void vl_api_bridge_flags_reply_t_handler
1370   (vl_api_bridge_flags_reply_t * mp)
1371 {
1372   vat_main_t *vam = &vat_main;
1373   i32 retval = ntohl (mp->retval);
1374   if (vam->async_mode)
1375     {
1376       vam->async_errors += (retval < 0);
1377     }
1378   else
1379     {
1380       vam->retval = retval;
1381       vam->result_ready = 1;
1382     }
1383 }
1384
1385 static void vl_api_bridge_flags_reply_t_handler_json
1386   (vl_api_bridge_flags_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   vat_json_node_t node;
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1393   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1394                             ntohl (mp->resulting_feature_bitmap));
1395
1396   vat_json_print (vam->ofp, &node);
1397   vat_json_free (&node);
1398
1399   vam->retval = ntohl (mp->retval);
1400   vam->result_ready = 1;
1401 }
1402
1403 static void vl_api_tap_connect_reply_t_handler
1404   (vl_api_tap_connect_reply_t * mp)
1405 {
1406   vat_main_t *vam = &vat_main;
1407   i32 retval = ntohl (mp->retval);
1408   if (vam->async_mode)
1409     {
1410       vam->async_errors += (retval < 0);
1411     }
1412   else
1413     {
1414       vam->retval = retval;
1415       vam->sw_if_index = ntohl (mp->sw_if_index);
1416       vam->result_ready = 1;
1417     }
1418
1419 }
1420
1421 static void vl_api_tap_connect_reply_t_handler_json
1422   (vl_api_tap_connect_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   vat_json_node_t node;
1426
1427   vat_json_init_object (&node);
1428   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1429   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1430
1431   vat_json_print (vam->ofp, &node);
1432   vat_json_free (&node);
1433
1434   vam->retval = ntohl (mp->retval);
1435   vam->result_ready = 1;
1436
1437 }
1438
1439 static void
1440 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   i32 retval = ntohl (mp->retval);
1444   if (vam->async_mode)
1445     {
1446       vam->async_errors += (retval < 0);
1447     }
1448   else
1449     {
1450       vam->retval = retval;
1451       vam->sw_if_index = ntohl (mp->sw_if_index);
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_modify_reply_t_handler_json
1457   (vl_api_tap_modify_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1465
1466   vat_json_print (vam->ofp, &node);
1467   vat_json_free (&node);
1468
1469   vam->retval = ntohl (mp->retval);
1470   vam->result_ready = 1;
1471 }
1472
1473 static void
1474 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1475 {
1476   vat_main_t *vam = &vat_main;
1477   i32 retval = ntohl (mp->retval);
1478   if (vam->async_mode)
1479     {
1480       vam->async_errors += (retval < 0);
1481     }
1482   else
1483     {
1484       vam->retval = retval;
1485       vam->result_ready = 1;
1486     }
1487 }
1488
1489 static void vl_api_tap_delete_reply_t_handler_json
1490   (vl_api_tap_delete_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   vat_json_node_t node;
1494
1495   vat_json_init_object (&node);
1496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1497
1498   vat_json_print (vam->ofp, &node);
1499   vat_json_free (&node);
1500
1501   vam->retval = ntohl (mp->retval);
1502   vam->result_ready = 1;
1503 }
1504
1505 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1506   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1507 {
1508   vat_main_t *vam = &vat_main;
1509   i32 retval = ntohl (mp->retval);
1510   if (vam->async_mode)
1511     {
1512       vam->async_errors += (retval < 0);
1513     }
1514   else
1515     {
1516       vam->retval = retval;
1517       vam->result_ready = 1;
1518     }
1519 }
1520
1521 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1522   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   vat_json_node_t node;
1526
1527   vat_json_init_object (&node);
1528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1529   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1530                             ntohl (mp->tunnel_sw_if_index));
1531
1532   vat_json_print (vam->ofp, &node);
1533   vat_json_free (&node);
1534
1535   vam->retval = ntohl (mp->retval);
1536   vam->result_ready = 1;
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   i32 retval = ntohl (mp->retval);
1544   if (vam->async_mode)
1545     {
1546       vam->async_errors += (retval < 0);
1547     }
1548   else
1549     {
1550       vam->retval = retval;
1551       vam->sw_if_index = ntohl (mp->sw_if_index);
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1557   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1565
1566   vat_json_print (vam->ofp, &node);
1567   vat_json_free (&node);
1568
1569   vam->retval = ntohl (mp->retval);
1570   vam->result_ready = 1;
1571 }
1572
1573
1574 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1575   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1591   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1599
1600   vat_json_print (vam->ofp, &node);
1601   vat_json_free (&node);
1602
1603   vam->retval = ntohl (mp->retval);
1604   vam->result_ready = 1;
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612   if (vam->async_mode)
1613     {
1614       vam->async_errors += (retval < 0);
1615     }
1616   else
1617     {
1618       vam->retval = retval;
1619       vam->sw_if_index = ntohl (mp->sw_if_index);
1620       vam->result_ready = 1;
1621     }
1622 }
1623
1624 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1625   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   vat_json_node_t node;
1629
1630   vat_json_init_object (&node);
1631   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1632   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1633
1634   vat_json_print (vam->ofp, &node);
1635   vat_json_free (&node);
1636
1637   vam->retval = ntohl (mp->retval);
1638   vam->result_ready = 1;
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   i32 retval = ntohl (mp->retval);
1646   if (vam->async_mode)
1647     {
1648       vam->async_errors += (retval < 0);
1649     }
1650   else
1651     {
1652       vam->retval = retval;
1653       vam->sw_if_index = ntohl (mp->sw_if_index);
1654       vam->result_ready = 1;
1655     }
1656 }
1657
1658 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1659   (vl_api_gre_add_del_tunnel_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   vat_json_node_t node;
1663
1664   vat_json_init_object (&node);
1665   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1666   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1667
1668   vat_json_print (vam->ofp, &node);
1669   vat_json_free (&node);
1670
1671   vam->retval = ntohl (mp->retval);
1672   vam->result_ready = 1;
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   i32 retval = ntohl (mp->retval);
1680   if (vam->async_mode)
1681     {
1682       vam->async_errors += (retval < 0);
1683     }
1684   else
1685     {
1686       vam->retval = retval;
1687       vam->sw_if_index = ntohl (mp->sw_if_index);
1688       vam->result_ready = 1;
1689     }
1690 }
1691
1692 static void vl_api_create_vhost_user_if_reply_t_handler_json
1693   (vl_api_create_vhost_user_if_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   vat_json_node_t node;
1697
1698   vat_json_init_object (&node);
1699   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1700   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1701
1702   vat_json_print (vam->ofp, &node);
1703   vat_json_free (&node);
1704
1705   vam->retval = ntohl (mp->retval);
1706   vam->result_ready = 1;
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_address_details_t empty_ip_address_details = { {0} };
1714   ip_address_details_t *address = NULL;
1715   ip_details_t *current_ip_details = NULL;
1716   ip_details_t *details = NULL;
1717
1718   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1719
1720   if (!details || vam->current_sw_if_index >= vec_len (details)
1721       || !details[vam->current_sw_if_index].present)
1722     {
1723       errmsg ("ip address details arrived but not stored\n");
1724       errmsg ("ip_dump should be called first\n");
1725       return;
1726     }
1727
1728   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1729
1730 #define addresses (current_ip_details->addr)
1731
1732   vec_validate_init_empty (addresses, vec_len (addresses),
1733                            empty_ip_address_details);
1734
1735   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1736
1737   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1738   address->prefix_length = mp->prefix_length;
1739 #undef addresses
1740 }
1741
1742 static void vl_api_ip_address_details_t_handler_json
1743   (vl_api_ip_address_details_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t *node = NULL;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755   node = vat_json_array_add (&vam->json_tree);
1756
1757   vat_json_init_object (node);
1758   if (vam->is_ipv6)
1759     {
1760       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1761       vat_json_object_add_ip6 (node, "ip", ip6);
1762     }
1763   else
1764     {
1765       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1766       vat_json_object_add_ip4 (node, "ip", ip4);
1767     }
1768   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1769 }
1770
1771 static void
1772 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   static ip_details_t empty_ip_details = { 0 };
1776   ip_details_t *ip = NULL;
1777   u32 sw_if_index = ~0;
1778
1779   sw_if_index = ntohl (mp->sw_if_index);
1780
1781   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1782                            sw_if_index, empty_ip_details);
1783
1784   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1785                          sw_if_index);
1786
1787   ip->present = 1;
1788 }
1789
1790 static void
1791 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1792 {
1793   vat_main_t *vam = &vat_main;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800   vat_json_array_add_uint (&vam->json_tree,
1801                            clib_net_to_host_u32 (mp->sw_if_index));
1802 }
1803
1804 static void vl_api_map_domain_details_t_handler_json
1805   (vl_api_map_domain_details_t * mp)
1806 {
1807   vat_json_node_t *node = NULL;
1808   vat_main_t *vam = &vat_main;
1809   struct in6_addr ip6;
1810   struct in_addr ip4;
1811
1812   if (VAT_JSON_ARRAY != vam->json_tree.type)
1813     {
1814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1815       vat_json_init_array (&vam->json_tree);
1816     }
1817
1818   node = vat_json_array_add (&vam->json_tree);
1819   vat_json_init_object (node);
1820
1821   vat_json_object_add_uint (node, "domain_index",
1822                             clib_net_to_host_u32 (mp->domain_index));
1823   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1825   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1826   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1827   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1828   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1829   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1830   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1831   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1832   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1833   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1834   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1835   vat_json_object_add_uint (node, "flags", mp->flags);
1836   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1837   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1838 }
1839
1840 static void vl_api_map_domain_details_t_handler
1841   (vl_api_map_domain_details_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844
1845   if (mp->is_translation)
1846     {
1847       fformat (vam->ofp,
1848                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1849                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1850                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1851                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1852                clib_net_to_host_u32 (mp->domain_index));
1853     }
1854   else
1855     {
1856       fformat (vam->ofp,
1857                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1858                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1859                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1860                format_ip6_address, mp->ip6_src,
1861                clib_net_to_host_u32 (mp->domain_index));
1862     }
1863   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1864            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1865            mp->is_translation ? "map-t" : "");
1866 }
1867
1868 static void vl_api_map_rule_details_t_handler_json
1869   (vl_api_map_rule_details_t * mp)
1870 {
1871   struct in6_addr ip6;
1872   vat_json_node_t *node = NULL;
1873   vat_main_t *vam = &vat_main;
1874
1875   if (VAT_JSON_ARRAY != vam->json_tree.type)
1876     {
1877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1878       vat_json_init_array (&vam->json_tree);
1879     }
1880
1881   node = vat_json_array_add (&vam->json_tree);
1882   vat_json_init_object (node);
1883
1884   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1885   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1886   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1887 }
1888
1889 static void
1890 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1894            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1895 }
1896
1897 static void
1898 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1902           "router_addr %U host_mac %U\n",
1903           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1904           format_ip4_address, &mp->host_address,
1905           format_ip4_address, &mp->router_address,
1906           format_ethernet_address, mp->host_mac);
1907 }
1908
1909 static void vl_api_dhcp_compl_event_t_handler_json
1910   (vl_api_dhcp_compl_event_t * mp)
1911 {
1912   /* JSON output not supported */
1913 }
1914
1915 static void
1916 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1917                               u32 counter)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   static u64 default_counter = 0;
1921
1922   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1923                            NULL);
1924   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1925                            sw_if_index, default_counter);
1926   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1927 }
1928
1929 static void
1930 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1931                                 interface_counter_t counter)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static interface_counter_t default_counter = { 0, };
1935
1936   vec_validate_init_empty (vam->combined_interface_counters,
1937                            vnet_counter_type, NULL);
1938   vec_validate_init_empty (vam->combined_interface_counters
1939                            [vnet_counter_type], sw_if_index, default_counter);
1940   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1941 }
1942
1943 static void vl_api_vnet_interface_counters_t_handler
1944   (vl_api_vnet_interface_counters_t * mp)
1945 {
1946   /* not supported */
1947 }
1948
1949 static void vl_api_vnet_interface_counters_t_handler_json
1950   (vl_api_vnet_interface_counters_t * mp)
1951 {
1952   interface_counter_t counter;
1953   vlib_counter_t *v;
1954   u64 *v_packets;
1955   u64 packets;
1956   u32 count;
1957   u32 first_sw_if_index;
1958   int i;
1959
1960   count = ntohl (mp->count);
1961   first_sw_if_index = ntohl (mp->first_sw_if_index);
1962
1963   if (!mp->is_combined)
1964     {
1965       v_packets = (u64 *) & mp->data;
1966       for (i = 0; i < count; i++)
1967         {
1968           packets =
1969             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1970           set_simple_interface_counter (mp->vnet_counter_type,
1971                                         first_sw_if_index + i, packets);
1972           v_packets++;
1973         }
1974     }
1975   else
1976     {
1977       v = (vlib_counter_t *) & mp->data;
1978       for (i = 0; i < count; i++)
1979         {
1980           counter.packets =
1981             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1982           counter.bytes =
1983             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1984           set_combined_interface_counter (mp->vnet_counter_type,
1985                                           first_sw_if_index + i, counter);
1986           v++;
1987         }
1988     }
1989 }
1990
1991 static u32
1992 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   u32 i;
1996
1997   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1998     {
1999       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2000         {
2001           return i;
2002         }
2003     }
2004   return ~0;
2005 }
2006
2007 static u32
2008 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   u32 i;
2012
2013   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2014     {
2015       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2016         {
2017           return i;
2018         }
2019     }
2020   return ~0;
2021 }
2022
2023 static void vl_api_vnet_ip4_fib_counters_t_handler
2024   (vl_api_vnet_ip4_fib_counters_t * mp)
2025 {
2026   /* not supported */
2027 }
2028
2029 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2030   (vl_api_vnet_ip4_fib_counters_t * mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   vl_api_ip4_fib_counter_t *v;
2034   ip4_fib_counter_t *counter;
2035   struct in_addr ip4;
2036   u32 vrf_id;
2037   u32 vrf_index;
2038   u32 count;
2039   int i;
2040
2041   vrf_id = ntohl (mp->vrf_id);
2042   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2043   if (~0 == vrf_index)
2044     {
2045       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2046       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2047       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2048       vec_validate (vam->ip4_fib_counters, vrf_index);
2049       vam->ip4_fib_counters[vrf_index] = NULL;
2050     }
2051
2052   vec_free (vam->ip4_fib_counters[vrf_index]);
2053   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2054   count = ntohl (mp->count);
2055   for (i = 0; i < count; i++)
2056     {
2057       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2058       counter = &vam->ip4_fib_counters[vrf_index][i];
2059       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2060       counter->address = ip4;
2061       counter->address_length = v->address_length;
2062       counter->packets = clib_net_to_host_u64 (v->packets);
2063       counter->bytes = clib_net_to_host_u64 (v->bytes);
2064       v++;
2065     }
2066 }
2067
2068 static void vl_api_vnet_ip6_fib_counters_t_handler
2069   (vl_api_vnet_ip6_fib_counters_t * mp)
2070 {
2071   /* not supported */
2072 }
2073
2074 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2075   (vl_api_vnet_ip6_fib_counters_t * mp)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   vl_api_ip6_fib_counter_t *v;
2079   ip6_fib_counter_t *counter;
2080   struct in6_addr ip6;
2081   u32 vrf_id;
2082   u32 vrf_index;
2083   u32 count;
2084   int i;
2085
2086   vrf_id = ntohl (mp->vrf_id);
2087   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2088   if (~0 == vrf_index)
2089     {
2090       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2091       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2092       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2093       vec_validate (vam->ip6_fib_counters, vrf_index);
2094       vam->ip6_fib_counters[vrf_index] = NULL;
2095     }
2096
2097   vec_free (vam->ip6_fib_counters[vrf_index]);
2098   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2099   count = ntohl (mp->count);
2100   for (i = 0; i < count; i++)
2101     {
2102       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2103       counter = &vam->ip6_fib_counters[vrf_index][i];
2104       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2105       counter->address = ip6;
2106       counter->address_length = v->address_length;
2107       counter->packets = clib_net_to_host_u64 (v->packets);
2108       counter->bytes = clib_net_to_host_u64 (v->bytes);
2109       v++;
2110     }
2111 }
2112
2113 static void vl_api_get_first_msg_id_reply_t_handler
2114   (vl_api_get_first_msg_id_reply_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   i32 retval = ntohl (mp->retval);
2118
2119   if (vam->async_mode)
2120     {
2121       vam->async_errors += (retval < 0);
2122     }
2123   else
2124     {
2125       vam->retval = retval;
2126       vam->result_ready = 1;
2127     }
2128   if (retval >= 0)
2129     {
2130       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2131     }
2132 }
2133
2134 static void vl_api_get_first_msg_id_reply_t_handler_json
2135   (vl_api_get_first_msg_id_reply_t * mp)
2136 {
2137   vat_main_t *vam = &vat_main;
2138   vat_json_node_t node;
2139
2140   vat_json_init_object (&node);
2141   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2142   vat_json_object_add_uint (&node, "first_msg_id",
2143                             (uint) ntohs (mp->first_msg_id));
2144
2145   vat_json_print (vam->ofp, &node);
2146   vat_json_free (&node);
2147
2148   vam->retval = ntohl (mp->retval);
2149   vam->result_ready = 1;
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   i32 retval = ntohl (mp->retval);
2158   u8 *pvt_copy, *reply;
2159   void *oldheap;
2160   vlib_node_t *node;
2161   int i;
2162
2163   if (vam->async_mode)
2164     {
2165       vam->async_errors += (retval < 0);
2166     }
2167   else
2168     {
2169       vam->retval = retval;
2170       vam->result_ready = 1;
2171     }
2172
2173   /* "Should never happen..." */
2174   if (retval != 0)
2175     return;
2176
2177   reply = (u8 *) (mp->reply_in_shmem);
2178   pvt_copy = vec_dup (reply);
2179
2180   /* Toss the shared-memory original... */
2181   pthread_mutex_lock (&am->vlib_rp->mutex);
2182   oldheap = svm_push_data_heap (am->vlib_rp);
2183
2184   vec_free (reply);
2185
2186   svm_pop_heap (oldheap);
2187   pthread_mutex_unlock (&am->vlib_rp->mutex);
2188
2189   if (vam->graph_nodes)
2190     {
2191       hash_free (vam->graph_node_index_by_name);
2192
2193       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2194         {
2195           node = vam->graph_nodes[i];
2196           vec_free (node->name);
2197           vec_free (node->next_nodes);
2198           vec_free (node);
2199         }
2200       vec_free (vam->graph_nodes);
2201     }
2202
2203   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2204   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2205   vec_free (pvt_copy);
2206
2207   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2208     {
2209       node = vam->graph_nodes[i];
2210       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2211     }
2212 }
2213
2214 static void vl_api_get_node_graph_reply_t_handler_json
2215   (vl_api_get_node_graph_reply_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   api_main_t *am = &api_main;
2219   void *oldheap;
2220   vat_json_node_t node;
2221   u8 *reply;
2222
2223   /* $$$$ make this real? */
2224   vat_json_init_object (&node);
2225   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2226   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2227
2228   reply = (u8 *) (mp->reply_in_shmem);
2229
2230   /* Toss the shared-memory original... */
2231   pthread_mutex_lock (&am->vlib_rp->mutex);
2232   oldheap = svm_push_data_heap (am->vlib_rp);
2233
2234   vec_free (reply);
2235
2236   svm_pop_heap (oldheap);
2237   pthread_mutex_unlock (&am->vlib_rp->mutex);
2238
2239   vat_json_print (vam->ofp, &node);
2240   vat_json_free (&node);
2241
2242   vam->retval = ntohl (mp->retval);
2243   vam->result_ready = 1;
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   locator_msg_t loc;
2251   u8 *tmp_str = 0;
2252
2253   memset (&loc, 0, sizeof (loc));
2254   if (vam->noprint_msg)
2255     {
2256       loc.local = mp->local;
2257       loc.priority = mp->priority;
2258       loc.weight = mp->weight;
2259       if (loc.local)
2260         {
2261           loc.sw_if_index = ntohl (mp->sw_if_index);
2262         }
2263       else
2264         {
2265           loc.is_ipv6 = mp->is_ipv6;
2266           clib_memcpy (loc.ip_address, mp->ip_address,
2267                        sizeof (loc.ip_address));
2268         }
2269       vec_add1 (vam->locator_msg, loc);
2270     }
2271   else
2272     {
2273       if (mp->local)
2274         {
2275           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2276                             ntohl (mp->sw_if_index),
2277                             mp->priority, mp->weight);
2278         }
2279       else
2280         {
2281           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2282                             mp->is_ipv6 ? format_ip6_address :
2283                             format_ip4_address,
2284                             mp->ip_address, mp->priority, mp->weight);
2285         }
2286
2287       fformat (vam->ofp, "%s", tmp_str);
2288
2289       vec_free (tmp_str);
2290     }
2291 }
2292
2293 static void
2294 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2295                                             mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   vat_json_node_t *node = NULL;
2299   locator_msg_t loc;
2300   struct in6_addr ip6;
2301   struct in_addr ip4;
2302
2303   memset (&loc, 0, sizeof (loc));
2304   if (vam->noprint_msg)
2305     {
2306       loc.local = mp->local;
2307       loc.priority = mp->priority;
2308       loc.weight = mp->weight;
2309       if (loc.local)
2310         {
2311           loc.sw_if_index = ntohl (mp->sw_if_index);
2312         }
2313       else
2314         {
2315           loc.is_ipv6 = mp->is_ipv6;
2316           clib_memcpy (loc.ip_address, mp->ip_address,
2317                        sizeof (loc.ip_address));
2318         }
2319       vec_add1 (vam->locator_msg, loc);
2320       return;
2321     }
2322
2323   if (VAT_JSON_ARRAY != vam->json_tree.type)
2324     {
2325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2326       vat_json_init_array (&vam->json_tree);
2327     }
2328   node = vat_json_array_add (&vam->json_tree);
2329
2330   vat_json_init_object (node);
2331
2332   if (mp->local)
2333     {
2334       vat_json_object_add_uint (node, "locator_index",
2335                                 ntohl (mp->sw_if_index));
2336     }
2337   else
2338     {
2339       if (mp->is_ipv6)
2340         {
2341           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2342           vat_json_object_add_ip6 (node, "locator", ip6);
2343         }
2344       else
2345         {
2346           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2347           vat_json_object_add_ip4 (node, "locator", ip4);
2348         }
2349     }
2350   vat_json_object_add_uint (node, "priority", mp->priority);
2351   vat_json_object_add_uint (node, "weight", mp->weight);
2352 }
2353
2354 static void
2355 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2356                                            mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   locator_set_msg_t ls;
2360
2361   ls.locator_set_index = ntohl (mp->locator_set_index);
2362   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2363   vec_add1 (vam->locator_set_msg, ls);
2364 }
2365
2366 static void
2367   vl_api_lisp_locator_set_details_t_handler_json
2368   (vl_api_lisp_locator_set_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   locator_set_msg_t ls;
2372
2373   ls.locator_set_index = ntohl (mp->locator_set_index);
2374   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2375   vec_add1 (vam->locator_set_msg, ls);
2376 }
2377
2378 static void
2379 add_lisp_eid_table_entry (vat_main_t * vam,
2380                           vl_api_lisp_eid_table_details_t * mp)
2381 {
2382   eid_table_t eid_table;
2383
2384   memset (&eid_table, 0, sizeof (eid_table));
2385   eid_table.is_local = mp->is_local;
2386   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2387   eid_table.eid_type = mp->eid_type;
2388   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2389   eid_table.eid_prefix_len = mp->eid_prefix_len;
2390   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2391   eid_table.action = mp->action;
2392   eid_table.authoritative = mp->authoritative;
2393   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2394   vec_add1 (vam->eid_tables, eid_table);
2395 }
2396
2397 static void
2398 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   add_lisp_eid_table_entry (vam, mp);
2402 }
2403
2404 static void
2405 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2406                                               * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   add_lisp_eid_table_entry (vam, mp);
2410 }
2411
2412 static void
2413   vl_api_lisp_eid_table_map_details_t_handler
2414   (vl_api_lisp_eid_table_map_details_t * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417
2418   u8 *line = format (0, "%=10d%=10d",
2419                      clib_net_to_host_u32 (mp->vni),
2420                      clib_net_to_host_u32 (mp->dp_table));
2421   fformat (vam->ofp, "%v\n", line);
2422   vec_free (line);
2423 }
2424
2425 static void
2426   vl_api_lisp_eid_table_map_details_t_handler_json
2427   (vl_api_lisp_eid_table_map_details_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t *node = NULL;
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437   node = vat_json_array_add (&vam->json_tree);
2438   vat_json_init_object (node);
2439   vat_json_object_add_uint (node, "dp_table",
2440                             clib_net_to_host_u32 (mp->dp_table));
2441   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2442 }
2443
2444 static void
2445   vl_api_lisp_eid_table_vni_details_t_handler
2446   (vl_api_lisp_eid_table_vni_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_vni_details_t_handler_json
2457   (vl_api_lisp_eid_table_vni_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, "vni", clib_net_to_host_u32 (mp->vni));
2470 }
2471
2472 static u8 *
2473 format_decap_next (u8 * s, va_list * args)
2474 {
2475   u32 next_index = va_arg (*args, u32);
2476
2477   switch (next_index)
2478     {
2479     case LISP_GPE_INPUT_NEXT_DROP:
2480       return format (s, "drop");
2481     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2482       return format (s, "ip4");
2483     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2484       return format (s, "ip6");
2485     default:
2486       return format (s, "unknown %d", next_index);
2487     }
2488   return s;
2489 }
2490
2491 static void
2492 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2493                                           mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   u8 *iid_str;
2497   u8 *flag_str = NULL;
2498
2499   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2500
2501 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2502   foreach_lisp_gpe_flag_bit;
2503 #undef _
2504
2505   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2506            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2507            mp->tunnels,
2508            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2509            mp->source_ip,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->destination_ip,
2512            ntohl (mp->encap_fib_id),
2513            ntohl (mp->decap_fib_id),
2514            format_decap_next, ntohl (mp->dcap_next),
2515            mp->ver_res >> 6,
2516            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2517
2518   vec_free (iid_str);
2519 }
2520
2521 static void
2522   vl_api_lisp_gpe_tunnel_details_t_handler_json
2523   (vl_api_lisp_gpe_tunnel_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   vat_json_node_t *node = NULL;
2527   struct in6_addr ip6;
2528   struct in_addr ip4;
2529   u8 *next_decap_str;
2530
2531   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2532
2533   if (VAT_JSON_ARRAY != vam->json_tree.type)
2534     {
2535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2536       vat_json_init_array (&vam->json_tree);
2537     }
2538   node = vat_json_array_add (&vam->json_tree);
2539
2540   vat_json_init_object (node);
2541   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2542   if (mp->is_ipv6)
2543     {
2544       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2545       vat_json_object_add_ip6 (node, "source address", ip6);
2546       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "destination address", ip6);
2548     }
2549   else
2550     {
2551       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2552       vat_json_object_add_ip4 (node, "source address", ip4);
2553       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "destination address", ip4);
2555     }
2556   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2557   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2558   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2559   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2560   vat_json_object_add_uint (node, "flags", mp->flags);
2561   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2562   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2563   vat_json_object_add_uint (node, "res", mp->res);
2564   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2565
2566   vec_free (next_decap_str);
2567 }
2568
2569 static void
2570 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2571                                             * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574
2575   fformat (vam->ofp, "%=20U\n",
2576            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2577            mp->ip_address);
2578 }
2579
2580 static void
2581   vl_api_lisp_map_resolver_details_t_handler_json
2582   (vl_api_lisp_map_resolver_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   vat_json_node_t *node = NULL;
2586   struct in6_addr ip6;
2587   struct in_addr ip4;
2588
2589   if (VAT_JSON_ARRAY != vam->json_tree.type)
2590     {
2591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2592       vat_json_init_array (&vam->json_tree);
2593     }
2594   node = vat_json_array_add (&vam->json_tree);
2595
2596   vat_json_init_object (node);
2597   if (mp->is_ipv6)
2598     {
2599       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2600       vat_json_object_add_ip6 (node, "map resolver", ip6);
2601     }
2602   else
2603     {
2604       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2605       vat_json_object_add_ip4 (node, "map resolver", ip4);
2606     }
2607 }
2608
2609 static void
2610   vl_api_show_lisp_status_reply_t_handler
2611   (vl_api_show_lisp_status_reply_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614   i32 retval = ntohl (mp->retval);
2615
2616   if (0 <= retval)
2617     {
2618       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2619                mp->feature_status ? "enabled" : "disabled",
2620                mp->gpe_status ? "enabled" : "disabled");
2621     }
2622
2623   vam->retval = retval;
2624   vam->result_ready = 1;
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler_json
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   vat_json_node_t node;
2633   u8 *gpe_status = NULL;
2634   u8 *feature_status = NULL;
2635
2636   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2637   feature_status = format (0, "%s",
2638                            mp->feature_status ? "enabled" : "disabled");
2639   vec_add1 (gpe_status, 0);
2640   vec_add1 (feature_status, 0);
2641
2642   vat_json_init_object (&node);
2643   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2644   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2645
2646   vec_free (gpe_status);
2647   vec_free (feature_status);
2648
2649   vat_json_print (vam->ofp, &node);
2650   vat_json_free (&node);
2651
2652   vam->retval = ntohl (mp->retval);
2653   vam->result_ready = 1;
2654 }
2655
2656 static void
2657   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2658   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   i32 retval = ntohl (mp->retval);
2662
2663   if (retval >= 0)
2664     {
2665       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2674   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t *node = NULL;
2678
2679   if (VAT_JSON_ARRAY != vam->json_tree.type)
2680     {
2681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2682       vat_json_init_array (&vam->json_tree);
2683     }
2684   node = vat_json_array_add (&vam->json_tree);
2685
2686   vat_json_init_object (node);
2687   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2688
2689   vat_json_print (vam->ofp, node);
2690   vat_json_free (node);
2691
2692   vam->retval = ntohl (mp->retval);
2693   vam->result_ready = 1;
2694 }
2695
2696 static void
2697 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2698 {
2699   vat_main_t *vam = &vat_main;
2700   i32 retval = ntohl (mp->retval);
2701
2702   if (0 <= retval)
2703     {
2704       fformat (vam->ofp, "%-20s%-16s\n",
2705                mp->status ? "enabled" : "disabled",
2706                mp->status ? (char *) mp->locator_set_name : "");
2707     }
2708
2709   vam->retval = retval;
2710   vam->result_ready = 1;
2711 }
2712
2713 static void
2714 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2715                                             mp)
2716 {
2717   vat_main_t *vam = &vat_main;
2718   vat_json_node_t node;
2719   u8 *status = 0;
2720
2721   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2722   vec_add1 (status, 0);
2723
2724   vat_json_init_object (&node);
2725   vat_json_object_add_string_copy (&node, "status", status);
2726   if (mp->status)
2727     {
2728       vat_json_object_add_string_copy (&node, "locator_set",
2729                                        mp->locator_set_name);
2730     }
2731
2732   vec_free (status);
2733
2734   vat_json_print (vam->ofp, &node);
2735   vat_json_free (&node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_policer_type (u8 * s, va_list * va)
2743 {
2744   u32 i = va_arg (*va, u32);
2745
2746   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2747     s = format (s, "1r2c");
2748   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2749     s = format (s, "1r3c");
2750   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2751     s = format (s, "2r3c-2698");
2752   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2753     s = format (s, "2r3c-4115");
2754   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2755     s = format (s, "2r3c-mef5cf1");
2756   else
2757     s = format (s, "ILLEGAL");
2758   return s;
2759 }
2760
2761 static u8 *
2762 format_policer_rate_type (u8 * s, va_list * va)
2763 {
2764   u32 i = va_arg (*va, u32);
2765
2766   if (i == SSE2_QOS_RATE_KBPS)
2767     s = format (s, "kbps");
2768   else if (i == SSE2_QOS_RATE_PPS)
2769     s = format (s, "pps");
2770   else
2771     s = format (s, "ILLEGAL");
2772   return s;
2773 }
2774
2775 static u8 *
2776 format_policer_round_type (u8 * s, va_list * va)
2777 {
2778   u32 i = va_arg (*va, u32);
2779
2780   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2781     s = format (s, "closest");
2782   else if (i == SSE2_QOS_ROUND_TO_UP)
2783     s = format (s, "up");
2784   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2785     s = format (s, "down");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_action_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_ACTION_DROP)
2797     s = format (s, "drop");
2798   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2799     s = format (s, "transmit");
2800   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2801     s = format (s, "mark-and-transmit");
2802   else
2803     s = format (s, "ILLEGAL");
2804   return s;
2805 }
2806
2807 static u8 *
2808 format_dscp (u8 * s, va_list * va)
2809 {
2810   u32 i = va_arg (*va, u32);
2811   char *t = 0;
2812
2813   switch (i)
2814     {
2815 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2816       foreach_vnet_dscp
2817 #undef _
2818     default:
2819       return format (s, "ILLEGAL");
2820     }
2821   s = format (s, "%s", t);
2822   return s;
2823 }
2824
2825 static void
2826 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2830
2831   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2832     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2833   else
2834     conform_dscp_str = format (0, "");
2835
2836   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2837     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2838   else
2839     exceed_dscp_str = format (0, "");
2840
2841   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2842     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2843   else
2844     violate_dscp_str = format (0, "");
2845
2846   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2847            "rate type %U, round type %U, %s rate, %s color-aware, "
2848            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2849            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2850            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2851            mp->name,
2852            format_policer_type, mp->type,
2853            ntohl (mp->cir),
2854            ntohl (mp->eir),
2855            clib_net_to_host_u64 (mp->cb),
2856            clib_net_to_host_u64 (mp->eb),
2857            format_policer_rate_type, mp->rate_type,
2858            format_policer_round_type, mp->round_type,
2859            mp->single_rate ? "single" : "dual",
2860            mp->color_aware ? "is" : "not",
2861            ntohl (mp->cir_tokens_per_period),
2862            ntohl (mp->pir_tokens_per_period),
2863            ntohl (mp->scale),
2864            ntohl (mp->current_limit),
2865            ntohl (mp->current_bucket),
2866            ntohl (mp->extended_limit),
2867            ntohl (mp->extended_bucket),
2868            clib_net_to_host_u64 (mp->last_update_time),
2869            format_policer_action_type, mp->conform_action_type,
2870            conform_dscp_str,
2871            format_policer_action_type, mp->exceed_action_type,
2872            exceed_dscp_str,
2873            format_policer_action_type, mp->violate_action_type,
2874            violate_dscp_str);
2875
2876   vec_free (conform_dscp_str);
2877   vec_free (exceed_dscp_str);
2878   vec_free (violate_dscp_str);
2879 }
2880
2881 static void vl_api_policer_details_t_handler_json
2882   (vl_api_policer_details_t * mp)
2883 {
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *node;
2886   u8 *rate_type_str, *round_type_str, *type_str;
2887   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2888
2889   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2890   round_type_str =
2891     format (0, "%U", format_policer_round_type, mp->round_type);
2892   type_str = format (0, "%U", format_policer_type, mp->type);
2893   conform_action_str = format (0, "%U", format_policer_action_type,
2894                                mp->conform_action_type);
2895   exceed_action_str = format (0, "%U", format_policer_action_type,
2896                               mp->exceed_action_type);
2897   violate_action_str = format (0, "%U", format_policer_action_type,
2898                                mp->violate_action_type);
2899
2900   if (VAT_JSON_ARRAY != vam->json_tree.type)
2901     {
2902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2903       vat_json_init_array (&vam->json_tree);
2904     }
2905   node = vat_json_array_add (&vam->json_tree);
2906
2907   vat_json_init_object (node);
2908   vat_json_object_add_string_copy (node, "name", mp->name);
2909   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2910   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2911   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2912   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2913   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2914   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2915   vat_json_object_add_string_copy (node, "type", type_str);
2916   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2917   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2918   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2919   vat_json_object_add_uint (node, "cir_tokens_per_period",
2920                             ntohl (mp->cir_tokens_per_period));
2921   vat_json_object_add_uint (node, "eir_tokens_per_period",
2922                             ntohl (mp->pir_tokens_per_period));
2923   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2924   vat_json_object_add_uint (node, "current_bucket",
2925                             ntohl (mp->current_bucket));
2926   vat_json_object_add_uint (node, "extended_limit",
2927                             ntohl (mp->extended_limit));
2928   vat_json_object_add_uint (node, "extended_bucket",
2929                             ntohl (mp->extended_bucket));
2930   vat_json_object_add_uint (node, "last_update_time",
2931                             ntohl (mp->last_update_time));
2932   vat_json_object_add_string_copy (node, "conform_action",
2933                                    conform_action_str);
2934   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2935     {
2936       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2937       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2938       vec_free (dscp_str);
2939     }
2940   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2941   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2942     {
2943       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2944       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2945       vec_free (dscp_str);
2946     }
2947   vat_json_object_add_string_copy (node, "violate_action",
2948                                    violate_action_str);
2949   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2950     {
2951       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2952       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2953       vec_free (dscp_str);
2954     }
2955
2956   vec_free (rate_type_str);
2957   vec_free (round_type_str);
2958   vec_free (type_str);
2959   vec_free (conform_action_str);
2960   vec_free (exceed_action_str);
2961   vec_free (violate_action_str);
2962 }
2963
2964 static void
2965 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2966                                            mp)
2967 {
2968   vat_main_t *vam = &vat_main;
2969   int i, count = ntohl (mp->count);
2970
2971   if (count > 0)
2972     fformat (vam->ofp, "classify table ids (%d) : ", count);
2973   for (i = 0; i < count; i++)
2974     {
2975       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2976       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2977     }
2978   vam->retval = ntohl (mp->retval);
2979   vam->result_ready = 1;
2980 }
2981
2982 static void
2983   vl_api_classify_table_ids_reply_t_handler_json
2984   (vl_api_classify_table_ids_reply_t * mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   int i, count = ntohl (mp->count);
2988
2989   if (count > 0)
2990     {
2991       vat_json_node_t node;
2992
2993       vat_json_init_object (&node);
2994       for (i = 0; i < count; i++)
2995         {
2996           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2997         }
2998       vat_json_print (vam->ofp, &node);
2999       vat_json_free (&node);
3000     }
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_classify_table_by_interface_reply_t_handler
3007   (vl_api_classify_table_by_interface_reply_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u32 table_id;
3011
3012   table_id = ntohl (mp->l2_table_id);
3013   if (table_id != ~0)
3014     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3015   else
3016     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3017   table_id = ntohl (mp->ip4_table_id);
3018   if (table_id != ~0)
3019     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3020   else
3021     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3022   table_id = ntohl (mp->ip6_table_id);
3023   if (table_id != ~0)
3024     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3025   else
3026     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3027   vam->retval = ntohl (mp->retval);
3028   vam->result_ready = 1;
3029 }
3030
3031 static void
3032   vl_api_classify_table_by_interface_reply_t_handler_json
3033   (vl_api_classify_table_by_interface_reply_t * mp)
3034 {
3035   vat_main_t *vam = &vat_main;
3036   vat_json_node_t node;
3037
3038   vat_json_init_object (&node);
3039
3040   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3041   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3042   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void vl_api_policer_add_del_reply_t_handler
3052   (vl_api_policer_add_del_reply_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   i32 retval = ntohl (mp->retval);
3056   if (vam->async_mode)
3057     {
3058       vam->async_errors += (retval < 0);
3059     }
3060   else
3061     {
3062       vam->retval = retval;
3063       vam->result_ready = 1;
3064       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3065         /*
3066          * Note: this is just barely thread-safe, depends on
3067          * the main thread spinning waiting for an answer...
3068          */
3069         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3070     }
3071 }
3072
3073 static void vl_api_policer_add_del_reply_t_handler_json
3074   (vl_api_policer_add_del_reply_t * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   vat_json_node_t node;
3078
3079   vat_json_init_object (&node);
3080   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3081   vat_json_object_add_uint (&node, "policer_index",
3082                             ntohl (mp->policer_index));
3083
3084   vat_json_print (vam->ofp, &node);
3085   vat_json_free (&node);
3086
3087   vam->retval = ntohl (mp->retval);
3088   vam->result_ready = 1;
3089 }
3090
3091 /* Format hex dump. */
3092 u8 *
3093 format_hex_bytes (u8 * s, va_list * va)
3094 {
3095   u8 *bytes = va_arg (*va, u8 *);
3096   int n_bytes = va_arg (*va, int);
3097   uword i;
3098
3099   /* Print short or long form depending on byte count. */
3100   uword short_form = n_bytes <= 32;
3101   uword indent = format_get_indent (s);
3102
3103   if (n_bytes == 0)
3104     return s;
3105
3106   for (i = 0; i < n_bytes; i++)
3107     {
3108       if (!short_form && (i % 32) == 0)
3109         s = format (s, "%08x: ", i);
3110       s = format (s, "%02x", bytes[i]);
3111       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3112         s = format (s, "\n%U", format_white_space, indent);
3113     }
3114
3115   return s;
3116 }
3117
3118 static void
3119 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3120                                             * mp)
3121 {
3122   vat_main_t *vam = &vat_main;
3123   i32 retval = ntohl (mp->retval);
3124   if (retval == 0)
3125     {
3126       fformat (vam->ofp, "classify table info :\n");
3127       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3128                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3129                ntohl (mp->miss_next_index));
3130       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3131                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3132                ntohl (mp->match_n_vectors));
3133       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3134                ntohl (mp->mask_length));
3135     }
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_classify_table_info_reply_t_handler_json
3142   (vl_api_classify_table_info_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   vat_json_node_t node;
3146
3147   i32 retval = ntohl (mp->retval);
3148   if (retval == 0)
3149     {
3150       vat_json_init_object (&node);
3151
3152       vat_json_object_add_int (&node, "sessions",
3153                                ntohl (mp->active_sessions));
3154       vat_json_object_add_int (&node, "nexttbl",
3155                                ntohl (mp->next_table_index));
3156       vat_json_object_add_int (&node, "nextnode",
3157                                ntohl (mp->miss_next_index));
3158       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3159       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3160       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3161       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3162                       ntohl (mp->mask_length), 0);
3163       vat_json_object_add_string_copy (&node, "mask", s);
3164
3165       vat_json_print (vam->ofp, &node);
3166       vat_json_free (&node);
3167     }
3168   vam->retval = ntohl (mp->retval);
3169   vam->result_ready = 1;
3170 }
3171
3172 static void
3173 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3174                                            mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177
3178   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3179            ntohl (mp->hit_next_index), ntohl (mp->advance),
3180            ntohl (mp->opaque_index));
3181   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3182            ntohl (mp->match_length));
3183 }
3184
3185 static void
3186   vl_api_classify_session_details_t_handler_json
3187   (vl_api_classify_session_details_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   vat_json_node_t *node = NULL;
3191
3192   if (VAT_JSON_ARRAY != vam->json_tree.type)
3193     {
3194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195       vat_json_init_array (&vam->json_tree);
3196     }
3197   node = vat_json_array_add (&vam->json_tree);
3198
3199   vat_json_init_object (node);
3200   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3201   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3202   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3203   u8 *s =
3204     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3205             0);
3206   vat_json_object_add_string_copy (node, "match", s);
3207 }
3208
3209 static void vl_api_pg_create_interface_reply_t_handler
3210   (vl_api_pg_create_interface_reply_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213
3214   vam->retval = ntohl (mp->retval);
3215   vam->result_ready = 1;
3216 }
3217
3218 static void vl_api_pg_create_interface_reply_t_handler_json
3219   (vl_api_pg_create_interface_reply_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   vat_json_node_t node;
3223
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       vat_json_init_object (&node);
3228
3229       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3230
3231       vat_json_print (vam->ofp, &node);
3232       vat_json_free (&node);
3233     }
3234   vam->retval = ntohl (mp->retval);
3235   vam->result_ready = 1;
3236 }
3237
3238 static void vl_api_policer_classify_details_t_handler
3239   (vl_api_policer_classify_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242
3243   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3244            ntohl (mp->table_index));
3245 }
3246
3247 static void vl_api_policer_classify_details_t_handler_json
3248   (vl_api_policer_classify_details_t * mp)
3249 {
3250   vat_main_t *vam = &vat_main;
3251   vat_json_node_t *node;
3252
3253   if (VAT_JSON_ARRAY != vam->json_tree.type)
3254     {
3255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3256       vat_json_init_array (&vam->json_tree);
3257     }
3258   node = vat_json_array_add (&vam->json_tree);
3259
3260   vat_json_init_object (node);
3261   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3262   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3263 }
3264
3265 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3266   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   i32 retval = ntohl (mp->retval);
3270   if (vam->async_mode)
3271     {
3272       vam->async_errors += (retval < 0);
3273     }
3274   else
3275     {
3276       vam->retval = retval;
3277       vam->sw_if_index = ntohl (mp->sw_if_index);
3278       vam->result_ready = 1;
3279     }
3280 }
3281
3282 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3283   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3284 {
3285   vat_main_t *vam = &vat_main;
3286   vat_json_node_t node;
3287
3288   vat_json_init_object (&node);
3289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3290   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3291
3292   vat_json_print (vam->ofp, &node);
3293   vat_json_free (&node);
3294
3295   vam->retval = ntohl (mp->retval);
3296   vam->result_ready = 1;
3297 }
3298
3299 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3300 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3301 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3302 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3303
3304 /*
3305  * Generate boilerplate reply handlers, which
3306  * dig the return value out of the xxx_reply_t API message,
3307  * stick it into vam->retval, and set vam->result_ready
3308  *
3309  * Could also do this by pointing N message decode slots at
3310  * a single function, but that could break in subtle ways.
3311  */
3312
3313 #define foreach_standard_reply_retval_handler           \
3314 _(sw_interface_set_flags_reply)                         \
3315 _(sw_interface_add_del_address_reply)                   \
3316 _(sw_interface_set_table_reply)                         \
3317 _(sw_interface_set_vpath_reply)                         \
3318 _(sw_interface_set_l2_bridge_reply)                     \
3319 _(bridge_domain_add_del_reply)                          \
3320 _(sw_interface_set_l2_xconnect_reply)                   \
3321 _(l2fib_add_del_reply)                                  \
3322 _(ip_add_del_route_reply)                               \
3323 _(proxy_arp_add_del_reply)                              \
3324 _(proxy_arp_intfc_enable_disable_reply)                 \
3325 _(mpls_add_del_encap_reply)                             \
3326 _(mpls_add_del_decap_reply)                             \
3327 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3328 _(sw_interface_set_unnumbered_reply)                    \
3329 _(ip_neighbor_add_del_reply)                            \
3330 _(reset_vrf_reply)                                      \
3331 _(oam_add_del_reply)                                    \
3332 _(reset_fib_reply)                                      \
3333 _(dhcp_proxy_config_reply)                              \
3334 _(dhcp_proxy_config_2_reply)                            \
3335 _(dhcp_proxy_set_vss_reply)                             \
3336 _(dhcp_client_config_reply)                             \
3337 _(set_ip_flow_hash_reply)                               \
3338 _(sw_interface_ip6_enable_disable_reply)                \
3339 _(sw_interface_ip6_set_link_local_address_reply)        \
3340 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3341 _(sw_interface_ip6nd_ra_config_reply)                   \
3342 _(set_arp_neighbor_limit_reply)                         \
3343 _(l2_patch_add_del_reply)                               \
3344 _(sr_tunnel_add_del_reply)                              \
3345 _(sr_policy_add_del_reply)                              \
3346 _(sr_multicast_map_add_del_reply)                       \
3347 _(classify_add_del_session_reply)                       \
3348 _(classify_set_interface_ip_table_reply)                \
3349 _(classify_set_interface_l2_tables_reply)               \
3350 _(l2tpv3_set_tunnel_cookies_reply)                      \
3351 _(l2tpv3_interface_enable_disable_reply)                \
3352 _(l2tpv3_set_lookup_key_reply)                          \
3353 _(l2_fib_clear_table_reply)                             \
3354 _(l2_interface_efp_filter_reply)                        \
3355 _(l2_interface_vlan_tag_rewrite_reply)                  \
3356 _(modify_vhost_user_if_reply)                           \
3357 _(delete_vhost_user_if_reply)                           \
3358 _(want_ip4_arp_events_reply)                            \
3359 _(want_ip6_nd_events_reply)                             \
3360 _(input_acl_set_interface_reply)                        \
3361 _(ipsec_spd_add_del_reply)                              \
3362 _(ipsec_interface_add_del_spd_reply)                    \
3363 _(ipsec_spd_add_del_entry_reply)                        \
3364 _(ipsec_sad_add_del_entry_reply)                        \
3365 _(ipsec_sa_set_key_reply)                               \
3366 _(ikev2_profile_add_del_reply)                          \
3367 _(ikev2_profile_set_auth_reply)                         \
3368 _(ikev2_profile_set_id_reply)                           \
3369 _(ikev2_profile_set_ts_reply)                           \
3370 _(ikev2_set_local_key_reply)                            \
3371 _(delete_loopback_reply)                                \
3372 _(bd_ip_mac_add_del_reply)                              \
3373 _(map_del_domain_reply)                                 \
3374 _(map_add_del_rule_reply)                               \
3375 _(want_interface_events_reply)                          \
3376 _(want_stats_reply)                                     \
3377 _(cop_interface_enable_disable_reply)                   \
3378 _(cop_whitelist_enable_disable_reply)                   \
3379 _(sw_interface_clear_stats_reply)                       \
3380 _(trace_profile_add_reply)                              \
3381 _(trace_profile_apply_reply)                            \
3382 _(trace_profile_del_reply)                              \
3383 _(lisp_add_del_locator_reply)                           \
3384 _(lisp_add_del_local_eid_reply)                         \
3385 _(lisp_add_del_remote_mapping_reply)                    \
3386 _(lisp_add_del_adjacency_reply)                         \
3387 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3388 _(lisp_add_del_map_resolver_reply)                      \
3389 _(lisp_gpe_enable_disable_reply)                        \
3390 _(lisp_gpe_add_del_iface_reply)                         \
3391 _(lisp_enable_disable_reply)                            \
3392 _(lisp_pitr_set_locator_set_reply)                      \
3393 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3394 _(lisp_eid_table_add_del_map_reply)                     \
3395 _(vxlan_gpe_add_del_tunnel_reply)                       \
3396 _(af_packet_delete_reply)                               \
3397 _(policer_classify_set_interface_reply)                 \
3398 _(netmap_create_reply)                                  \
3399 _(netmap_delete_reply)                                  \
3400 _(ipfix_enable_reply)                                   \
3401 _(pg_capture_reply)                                     \
3402 _(pg_enable_disable_reply)                              \
3403 _(ip_source_and_port_range_check_add_del_reply)         \
3404 _(ip_source_and_port_range_check_interface_add_del_reply)\
3405 _(delete_subif_reply)
3406
3407 #define _(n)                                    \
3408     static void vl_api_##n##_t_handler          \
3409     (vl_api_##n##_t * mp)                       \
3410     {                                           \
3411         vat_main_t * vam = &vat_main;           \
3412         i32 retval = ntohl(mp->retval);         \
3413         if (vam->async_mode) {                  \
3414             vam->async_errors += (retval < 0);  \
3415         } else {                                \
3416             vam->retval = retval;               \
3417             vam->result_ready = 1;              \
3418         }                                       \
3419     }
3420 foreach_standard_reply_retval_handler;
3421 #undef _
3422
3423 #define _(n)                                    \
3424     static void vl_api_##n##_t_handler_json     \
3425     (vl_api_##n##_t * mp)                       \
3426     {                                           \
3427         vat_main_t * vam = &vat_main;           \
3428         vat_json_node_t node;                   \
3429         vat_json_init_object(&node);            \
3430         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3431         vat_json_print(vam->ofp, &node);        \
3432         vam->retval = ntohl(mp->retval);        \
3433         vam->result_ready = 1;                  \
3434     }
3435 foreach_standard_reply_retval_handler;
3436 #undef _
3437
3438 /*
3439  * Table of message reply handlers, must include boilerplate handlers
3440  * we just generated
3441  */
3442
3443 #define foreach_vpe_api_reply_msg                                       \
3444 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3445 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3446 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3447 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3448 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3449 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3450 _(CLI_REPLY, cli_reply)                                                 \
3451 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3452   sw_interface_add_del_address_reply)                                   \
3453 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3454 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3455 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3456   sw_interface_set_l2_xconnect_reply)                                   \
3457 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3458   sw_interface_set_l2_bridge_reply)                                     \
3459 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3460 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3461 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3462 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3463 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3464 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3465 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3466 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3467 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3468 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3469 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3470 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3471 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3472   proxy_arp_intfc_enable_disable_reply)                                 \
3473 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3474 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3475 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3476 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3477   mpls_ethernet_add_del_tunnel_reply)                                   \
3478 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3479   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3480 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3481   sw_interface_set_unnumbered_reply)                                    \
3482 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3483 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3484 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3485 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3486 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3487 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3488 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3489 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3490 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3491 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3492 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3493 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3494   sw_interface_ip6_enable_disable_reply)                                \
3495 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3496   sw_interface_ip6_set_link_local_address_reply)                        \
3497 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3498   sw_interface_ip6nd_ra_prefix_reply)                                   \
3499 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3500   sw_interface_ip6nd_ra_config_reply)                                   \
3501 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3502 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3503 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3504 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3505 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3506 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3507 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3508 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3509 classify_set_interface_ip_table_reply)                                  \
3510 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3511   classify_set_interface_l2_tables_reply)                               \
3512 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3513 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3514 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3515 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3516 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3517   l2tpv3_interface_enable_disable_reply)                                \
3518 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3519 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3520 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3521 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3522 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3523 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3524 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3525 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3526 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3527 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3528 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3529 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3530 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3531 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3532 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3533 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3534 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3535 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3536 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3537 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3538 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3539 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3540 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3541 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3542 _(IP_DETAILS, ip_details)                                               \
3543 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3544 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3545 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3546 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3547 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3548 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3549 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3550 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3551 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3552 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3553 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3554 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3555 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3556 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3557 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3558 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3571 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3572 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3573 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3574 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3575 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3576 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3577 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3578 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3579 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3580 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3581 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3582 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3583 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3584 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3585 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3586 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3587 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3588 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3589 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3590 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3591 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3592 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3593 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3594 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3595   lisp_add_del_map_request_itr_rlocs_reply)                             \
3596 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3597   lisp_get_map_request_itr_rlocs_reply)                                 \
3598 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3599 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3600 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3601 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3602 _(POLICER_DETAILS, policer_details)                                     \
3603 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3604 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3605 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3606 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3607 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3608 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3609 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3610 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3611 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3612 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3613 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3614 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3615 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3616 _(IPFIX_DETAILS, ipfix_details)                                         \
3617 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3618 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3619 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3620 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3621 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3622  ip_source_and_port_range_check_add_del_reply)                          \
3623 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3624  ip_source_and_port_range_check_interface_add_del_reply)                \
3625 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3626 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3627 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3628
3629 /* M: construct, but don't yet send a message */
3630
3631 #define M(T,t)                                  \
3632 do {                                            \
3633     vam->result_ready = 0;                      \
3634     mp = vl_msg_api_alloc(sizeof(*mp));         \
3635     memset (mp, 0, sizeof (*mp));               \
3636     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3637     mp->client_index = vam->my_client_index;    \
3638 } while(0);
3639
3640 #define M2(T,t,n)                               \
3641 do {                                            \
3642     vam->result_ready = 0;                      \
3643     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3644     memset (mp, 0, sizeof (*mp));               \
3645     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3646     mp->client_index = vam->my_client_index;    \
3647 } while(0);
3648
3649
3650 /* S: send a message */
3651 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3652
3653 /* W: wait for results, with timeout */
3654 #define W                                       \
3655 do {                                            \
3656     timeout = vat_time_now (vam) + 1.0;         \
3657                                                 \
3658     while (vat_time_now (vam) < timeout) {      \
3659         if (vam->result_ready == 1) {           \
3660             return (vam->retval);               \
3661         }                                       \
3662     }                                           \
3663     return -99;                                 \
3664 } while(0);
3665
3666 /* W2: wait for results, with timeout */
3667 #define W2(body)                                \
3668 do {                                            \
3669     timeout = vat_time_now (vam) + 1.0;         \
3670                                                 \
3671     while (vat_time_now (vam) < timeout) {      \
3672         if (vam->result_ready == 1) {           \
3673           (body);                               \
3674           return (vam->retval);                 \
3675         }                                       \
3676     }                                           \
3677     return -99;                                 \
3678 } while(0);
3679
3680 /* W_L: wait for results, with timeout */
3681 #define W_L(body)                               \
3682 do {                                            \
3683     timeout = vat_time_now (vam) + 1.0;         \
3684                                                 \
3685     while (vat_time_now (vam) < timeout) {      \
3686         if (vam->result_ready == 1) {           \
3687           (body);                               \
3688           return (vam->retval);                 \
3689         }                                       \
3690     }                                           \
3691     vam->noprint_msg = 0;     \
3692     return -99;                                 \
3693 } while(0);
3694
3695 typedef struct
3696 {
3697   u8 *name;
3698   u32 value;
3699 } name_sort_t;
3700
3701
3702 #define STR_VTR_OP_CASE(op)     \
3703     case L2_VTR_ ## op:         \
3704         return "" # op;
3705
3706 static const char *
3707 str_vtr_op (u32 vtr_op)
3708 {
3709   switch (vtr_op)
3710     {
3711       STR_VTR_OP_CASE (DISABLED);
3712       STR_VTR_OP_CASE (PUSH_1);
3713       STR_VTR_OP_CASE (PUSH_2);
3714       STR_VTR_OP_CASE (POP_1);
3715       STR_VTR_OP_CASE (POP_2);
3716       STR_VTR_OP_CASE (TRANSLATE_1_1);
3717       STR_VTR_OP_CASE (TRANSLATE_1_2);
3718       STR_VTR_OP_CASE (TRANSLATE_2_1);
3719       STR_VTR_OP_CASE (TRANSLATE_2_2);
3720     }
3721
3722   return "UNKNOWN";
3723 }
3724
3725 static int
3726 dump_sub_interface_table (vat_main_t * vam)
3727 {
3728   const sw_interface_subif_t *sub = NULL;
3729
3730   if (vam->json_output)
3731     {
3732       clib_warning
3733         ("JSON output supported only for VPE API calls and dump_stats_table");
3734       return -99;
3735     }
3736
3737   fformat (vam->ofp,
3738            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3739            "Interface", "sw_if_index",
3740            "sub id", "dot1ad", "tags", "outer id",
3741            "inner id", "exact", "default", "outer any", "inner any");
3742
3743   vec_foreach (sub, vam->sw_if_subif_table)
3744   {
3745     fformat (vam->ofp,
3746              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3747              sub->interface_name,
3748              sub->sw_if_index,
3749              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3750              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3751              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3752              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3753     if (sub->vtr_op != L2_VTR_DISABLED)
3754       {
3755         fformat (vam->ofp,
3756                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3757                  "tag1: %d tag2: %d ]\n",
3758                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3759                  sub->vtr_tag1, sub->vtr_tag2);
3760       }
3761   }
3762
3763   return 0;
3764 }
3765
3766 static int
3767 name_sort_cmp (void *a1, void *a2)
3768 {
3769   name_sort_t *n1 = a1;
3770   name_sort_t *n2 = a2;
3771
3772   return strcmp ((char *) n1->name, (char *) n2->name);
3773 }
3774
3775 static int
3776 dump_interface_table (vat_main_t * vam)
3777 {
3778   hash_pair_t *p;
3779   name_sort_t *nses = 0, *ns;
3780
3781   if (vam->json_output)
3782     {
3783       clib_warning
3784         ("JSON output supported only for VPE API calls and dump_stats_table");
3785       return -99;
3786     }
3787
3788   /* *INDENT-OFF* */
3789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3790   ({
3791     vec_add2 (nses, ns, 1);
3792     ns->name = (u8 *)(p->key);
3793     ns->value = (u32) p->value[0];
3794   }));
3795   /* *INDENT-ON* */
3796
3797   vec_sort_with_function (nses, name_sort_cmp);
3798
3799   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3800   vec_foreach (ns, nses)
3801   {
3802     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3803   }
3804   vec_free (nses);
3805   return 0;
3806 }
3807
3808 static int
3809 dump_ip_table (vat_main_t * vam, int is_ipv6)
3810 {
3811   const ip_details_t *det = NULL;
3812   const ip_address_details_t *address = NULL;
3813   u32 i = ~0;
3814
3815   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3816
3817   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3818   {
3819     i++;
3820     if (!det->present)
3821       {
3822         continue;
3823       }
3824     fformat (vam->ofp, "%-12d\n", i);
3825     fformat (vam->ofp,
3826              "            %-30s%-13s\n", "Address", "Prefix length");
3827     if (!det->addr)
3828       {
3829         continue;
3830       }
3831     vec_foreach (address, det->addr)
3832     {
3833       fformat (vam->ofp,
3834                "            %-30U%-13d\n",
3835                is_ipv6 ? format_ip6_address : format_ip4_address,
3836                address->ip, address->prefix_length);
3837     }
3838   }
3839
3840   return 0;
3841 }
3842
3843 static int
3844 dump_ipv4_table (vat_main_t * vam)
3845 {
3846   if (vam->json_output)
3847     {
3848       clib_warning
3849         ("JSON output supported only for VPE API calls and dump_stats_table");
3850       return -99;
3851     }
3852
3853   return dump_ip_table (vam, 0);
3854 }
3855
3856 static int
3857 dump_ipv6_table (vat_main_t * vam)
3858 {
3859   if (vam->json_output)
3860     {
3861       clib_warning
3862         ("JSON output supported only for VPE API calls and dump_stats_table");
3863       return -99;
3864     }
3865
3866   return dump_ip_table (vam, 1);
3867 }
3868
3869 static char *
3870 counter_type_to_str (u8 counter_type, u8 is_combined)
3871 {
3872   if (!is_combined)
3873     {
3874       switch (counter_type)
3875         {
3876         case VNET_INTERFACE_COUNTER_DROP:
3877           return "drop";
3878         case VNET_INTERFACE_COUNTER_PUNT:
3879           return "punt";
3880         case VNET_INTERFACE_COUNTER_IP4:
3881           return "ip4";
3882         case VNET_INTERFACE_COUNTER_IP6:
3883           return "ip6";
3884         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3885           return "rx-no-buf";
3886         case VNET_INTERFACE_COUNTER_RX_MISS:
3887           return "rx-miss";
3888         case VNET_INTERFACE_COUNTER_RX_ERROR:
3889           return "rx-error";
3890         case VNET_INTERFACE_COUNTER_TX_ERROR:
3891           return "tx-error";
3892         default:
3893           return "INVALID-COUNTER-TYPE";
3894         }
3895     }
3896   else
3897     {
3898       switch (counter_type)
3899         {
3900         case VNET_INTERFACE_COUNTER_RX:
3901           return "rx";
3902         case VNET_INTERFACE_COUNTER_TX:
3903           return "tx";
3904         default:
3905           return "INVALID-COUNTER-TYPE";
3906         }
3907     }
3908 }
3909
3910 static int
3911 dump_stats_table (vat_main_t * vam)
3912 {
3913   vat_json_node_t node;
3914   vat_json_node_t *msg_array;
3915   vat_json_node_t *msg;
3916   vat_json_node_t *counter_array;
3917   vat_json_node_t *counter;
3918   interface_counter_t c;
3919   u64 packets;
3920   ip4_fib_counter_t *c4;
3921   ip6_fib_counter_t *c6;
3922   int i, j;
3923
3924   if (!vam->json_output)
3925     {
3926       clib_warning ("dump_stats_table supported only in JSON format");
3927       return -99;
3928     }
3929
3930   vat_json_init_object (&node);
3931
3932   /* interface counters */
3933   msg_array = vat_json_object_add (&node, "interface_counters");
3934   vat_json_init_array (msg_array);
3935   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3936     {
3937       msg = vat_json_array_add (msg_array);
3938       vat_json_init_object (msg);
3939       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3940                                        (u8 *) counter_type_to_str (i, 0));
3941       vat_json_object_add_int (msg, "is_combined", 0);
3942       counter_array = vat_json_object_add (msg, "data");
3943       vat_json_init_array (counter_array);
3944       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3945         {
3946           packets = vam->simple_interface_counters[i][j];
3947           vat_json_array_add_uint (counter_array, packets);
3948         }
3949     }
3950   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3951     {
3952       msg = vat_json_array_add (msg_array);
3953       vat_json_init_object (msg);
3954       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3955                                        (u8 *) counter_type_to_str (i, 1));
3956       vat_json_object_add_int (msg, "is_combined", 1);
3957       counter_array = vat_json_object_add (msg, "data");
3958       vat_json_init_array (counter_array);
3959       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3960         {
3961           c = vam->combined_interface_counters[i][j];
3962           counter = vat_json_array_add (counter_array);
3963           vat_json_init_object (counter);
3964           vat_json_object_add_uint (counter, "packets", c.packets);
3965           vat_json_object_add_uint (counter, "bytes", c.bytes);
3966         }
3967     }
3968
3969   /* ip4 fib counters */
3970   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3971   vat_json_init_array (msg_array);
3972   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3973     {
3974       msg = vat_json_array_add (msg_array);
3975       vat_json_init_object (msg);
3976       vat_json_object_add_uint (msg, "vrf_id",
3977                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3978       counter_array = vat_json_object_add (msg, "c");
3979       vat_json_init_array (counter_array);
3980       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3981         {
3982           counter = vat_json_array_add (counter_array);
3983           vat_json_init_object (counter);
3984           c4 = &vam->ip4_fib_counters[i][j];
3985           vat_json_object_add_ip4 (counter, "address", c4->address);
3986           vat_json_object_add_uint (counter, "address_length",
3987                                     c4->address_length);
3988           vat_json_object_add_uint (counter, "packets", c4->packets);
3989           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3990         }
3991     }
3992
3993   /* ip6 fib counters */
3994   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3995   vat_json_init_array (msg_array);
3996   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3997     {
3998       msg = vat_json_array_add (msg_array);
3999       vat_json_init_object (msg);
4000       vat_json_object_add_uint (msg, "vrf_id",
4001                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4002       counter_array = vat_json_object_add (msg, "c");
4003       vat_json_init_array (counter_array);
4004       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4005         {
4006           counter = vat_json_array_add (counter_array);
4007           vat_json_init_object (counter);
4008           c6 = &vam->ip6_fib_counters[i][j];
4009           vat_json_object_add_ip6 (counter, "address", c6->address);
4010           vat_json_object_add_uint (counter, "address_length",
4011                                     c6->address_length);
4012           vat_json_object_add_uint (counter, "packets", c6->packets);
4013           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4014         }
4015     }
4016
4017   vat_json_print (vam->ofp, &node);
4018   vat_json_free (&node);
4019
4020   return 0;
4021 }
4022
4023 int
4024 exec (vat_main_t * vam)
4025 {
4026   api_main_t *am = &api_main;
4027   vl_api_cli_request_t *mp;
4028   f64 timeout;
4029   void *oldheap;
4030   u8 *cmd = 0;
4031   unformat_input_t *i = vam->input;
4032
4033   if (vec_len (i->buffer) == 0)
4034     return -1;
4035
4036   if (vam->exec_mode == 0 && unformat (i, "mode"))
4037     {
4038       vam->exec_mode = 1;
4039       return 0;
4040     }
4041   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4042     {
4043       vam->exec_mode = 0;
4044       return 0;
4045     }
4046
4047
4048   M (CLI_REQUEST, cli_request);
4049
4050   /*
4051    * Copy cmd into shared memory.
4052    * In order for the CLI command to work, it
4053    * must be a vector ending in \n, not a C-string ending
4054    * in \n\0.
4055    */
4056   pthread_mutex_lock (&am->vlib_rp->mutex);
4057   oldheap = svm_push_data_heap (am->vlib_rp);
4058
4059   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4060   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4061
4062   svm_pop_heap (oldheap);
4063   pthread_mutex_unlock (&am->vlib_rp->mutex);
4064
4065   mp->cmd_in_shmem = (u64) cmd;
4066   S;
4067   timeout = vat_time_now (vam) + 10.0;
4068
4069   while (vat_time_now (vam) < timeout)
4070     {
4071       if (vam->result_ready == 1)
4072         {
4073           u8 *free_me;
4074           if (vam->shmem_result != NULL)
4075             fformat (vam->ofp, "%s", vam->shmem_result);
4076           pthread_mutex_lock (&am->vlib_rp->mutex);
4077           oldheap = svm_push_data_heap (am->vlib_rp);
4078
4079           free_me = (u8 *) vam->shmem_result;
4080           vec_free (free_me);
4081
4082           svm_pop_heap (oldheap);
4083           pthread_mutex_unlock (&am->vlib_rp->mutex);
4084           return 0;
4085         }
4086     }
4087   return -99;
4088 }
4089
4090 static int
4091 api_create_loopback (vat_main_t * vam)
4092 {
4093   unformat_input_t *i = vam->input;
4094   vl_api_create_loopback_t *mp;
4095   f64 timeout;
4096   u8 mac_address[6];
4097   u8 mac_set = 0;
4098
4099   memset (mac_address, 0, sizeof (mac_address));
4100
4101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4102     {
4103       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4104         mac_set = 1;
4105       else
4106         break;
4107     }
4108
4109   /* Construct the API message */
4110   M (CREATE_LOOPBACK, create_loopback);
4111   if (mac_set)
4112     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4113
4114   S;
4115   W;
4116 }
4117
4118 static int
4119 api_delete_loopback (vat_main_t * vam)
4120 {
4121   unformat_input_t *i = vam->input;
4122   vl_api_delete_loopback_t *mp;
4123   f64 timeout;
4124   u32 sw_if_index = ~0;
4125
4126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4127     {
4128       if (unformat (i, "sw_if_index %d", &sw_if_index))
4129         ;
4130       else
4131         break;
4132     }
4133
4134   if (sw_if_index == ~0)
4135     {
4136       errmsg ("missing sw_if_index\n");
4137       return -99;
4138     }
4139
4140   /* Construct the API message */
4141   M (DELETE_LOOPBACK, delete_loopback);
4142   mp->sw_if_index = ntohl (sw_if_index);
4143
4144   S;
4145   W;
4146 }
4147
4148 static int
4149 api_want_stats (vat_main_t * vam)
4150 {
4151   unformat_input_t *i = vam->input;
4152   vl_api_want_stats_t *mp;
4153   f64 timeout;
4154   int enable = -1;
4155
4156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4157     {
4158       if (unformat (i, "enable"))
4159         enable = 1;
4160       else if (unformat (i, "disable"))
4161         enable = 0;
4162       else
4163         break;
4164     }
4165
4166   if (enable == -1)
4167     {
4168       errmsg ("missing enable|disable\n");
4169       return -99;
4170     }
4171
4172   M (WANT_STATS, want_stats);
4173   mp->enable_disable = enable;
4174
4175   S;
4176   W;
4177 }
4178
4179 static int
4180 api_want_interface_events (vat_main_t * vam)
4181 {
4182   unformat_input_t *i = vam->input;
4183   vl_api_want_interface_events_t *mp;
4184   f64 timeout;
4185   int enable = -1;
4186
4187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4188     {
4189       if (unformat (i, "enable"))
4190         enable = 1;
4191       else if (unformat (i, "disable"))
4192         enable = 0;
4193       else
4194         break;
4195     }
4196
4197   if (enable == -1)
4198     {
4199       errmsg ("missing enable|disable\n");
4200       return -99;
4201     }
4202
4203   M (WANT_INTERFACE_EVENTS, want_interface_events);
4204   mp->enable_disable = enable;
4205
4206   vam->interface_event_display = enable;
4207
4208   S;
4209   W;
4210 }
4211
4212
4213 /* Note: non-static, called once to set up the initial intfc table */
4214 int
4215 api_sw_interface_dump (vat_main_t * vam)
4216 {
4217   vl_api_sw_interface_dump_t *mp;
4218   f64 timeout;
4219   hash_pair_t *p;
4220   name_sort_t *nses = 0, *ns;
4221   sw_interface_subif_t *sub = NULL;
4222
4223   /* Toss the old name table */
4224   /* *INDENT-OFF* */
4225   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4226   ({
4227     vec_add2 (nses, ns, 1);
4228     ns->name = (u8 *)(p->key);
4229     ns->value = (u32) p->value[0];
4230   }));
4231   /* *INDENT-ON* */
4232
4233   hash_free (vam->sw_if_index_by_interface_name);
4234
4235   vec_foreach (ns, nses) vec_free (ns->name);
4236
4237   vec_free (nses);
4238
4239   vec_foreach (sub, vam->sw_if_subif_table)
4240   {
4241     vec_free (sub->interface_name);
4242   }
4243   vec_free (vam->sw_if_subif_table);
4244
4245   /* recreate the interface name hash table */
4246   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4247
4248   /* Get list of ethernets */
4249   M (SW_INTERFACE_DUMP, sw_interface_dump);
4250   mp->name_filter_valid = 1;
4251   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4252   S;
4253
4254   /* and local / loopback interfaces */
4255   M (SW_INTERFACE_DUMP, sw_interface_dump);
4256   mp->name_filter_valid = 1;
4257   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4258   S;
4259
4260
4261   /* and vxlan-gpe tunnel interfaces */
4262   M (SW_INTERFACE_DUMP, sw_interface_dump);
4263   mp->name_filter_valid = 1;
4264   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4265            sizeof (mp->name_filter) - 1);
4266   S;
4267
4268   /* and vxlan tunnel interfaces */
4269   M (SW_INTERFACE_DUMP, sw_interface_dump);
4270   mp->name_filter_valid = 1;
4271   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4272   S;
4273
4274   /* and host (af_packet) interfaces */
4275   M (SW_INTERFACE_DUMP, sw_interface_dump);
4276   mp->name_filter_valid = 1;
4277   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4278   S;
4279
4280   /* and l2tpv3 tunnel interfaces */
4281   M (SW_INTERFACE_DUMP, sw_interface_dump);
4282   mp->name_filter_valid = 1;
4283   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4284            sizeof (mp->name_filter) - 1);
4285   S;
4286
4287   /* and GRE tunnel interfaces */
4288   M (SW_INTERFACE_DUMP, sw_interface_dump);
4289   mp->name_filter_valid = 1;
4290   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4291   S;
4292
4293   /* Use a control ping for synchronization */
4294   {
4295     vl_api_control_ping_t *mp;
4296     M (CONTROL_PING, control_ping);
4297     S;
4298   }
4299   W;
4300 }
4301
4302 static int
4303 api_sw_interface_set_flags (vat_main_t * vam)
4304 {
4305   unformat_input_t *i = vam->input;
4306   vl_api_sw_interface_set_flags_t *mp;
4307   f64 timeout;
4308   u32 sw_if_index;
4309   u8 sw_if_index_set = 0;
4310   u8 admin_up = 0, link_up = 0;
4311
4312   /* Parse args required to build the message */
4313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4314     {
4315       if (unformat (i, "admin-up"))
4316         admin_up = 1;
4317       else if (unformat (i, "admin-down"))
4318         admin_up = 0;
4319       else if (unformat (i, "link-up"))
4320         link_up = 1;
4321       else if (unformat (i, "link-down"))
4322         link_up = 0;
4323       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4324         sw_if_index_set = 1;
4325       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4326         sw_if_index_set = 1;
4327       else
4328         break;
4329     }
4330
4331   if (sw_if_index_set == 0)
4332     {
4333       errmsg ("missing interface name or sw_if_index\n");
4334       return -99;
4335     }
4336
4337   /* Construct the API message */
4338   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4339   mp->sw_if_index = ntohl (sw_if_index);
4340   mp->admin_up_down = admin_up;
4341   mp->link_up_down = link_up;
4342
4343   /* send it... */
4344   S;
4345
4346   /* Wait for a reply, return the good/bad news... */
4347   W;
4348 }
4349
4350 static int
4351 api_sw_interface_clear_stats (vat_main_t * vam)
4352 {
4353   unformat_input_t *i = vam->input;
4354   vl_api_sw_interface_clear_stats_t *mp;
4355   f64 timeout;
4356   u32 sw_if_index;
4357   u8 sw_if_index_set = 0;
4358
4359   /* Parse args required to build the message */
4360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4361     {
4362       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4363         sw_if_index_set = 1;
4364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4365         sw_if_index_set = 1;
4366       else
4367         break;
4368     }
4369
4370   /* Construct the API message */
4371   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4372
4373   if (sw_if_index_set == 1)
4374     mp->sw_if_index = ntohl (sw_if_index);
4375   else
4376     mp->sw_if_index = ~0;
4377
4378   /* send it... */
4379   S;
4380
4381   /* Wait for a reply, return the good/bad news... */
4382   W;
4383 }
4384
4385 static int
4386 api_sw_interface_add_del_address (vat_main_t * vam)
4387 {
4388   unformat_input_t *i = vam->input;
4389   vl_api_sw_interface_add_del_address_t *mp;
4390   f64 timeout;
4391   u32 sw_if_index;
4392   u8 sw_if_index_set = 0;
4393   u8 is_add = 1, del_all = 0;
4394   u32 address_length = 0;
4395   u8 v4_address_set = 0;
4396   u8 v6_address_set = 0;
4397   ip4_address_t v4address;
4398   ip6_address_t v6address;
4399
4400   /* Parse args required to build the message */
4401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4402     {
4403       if (unformat (i, "del-all"))
4404         del_all = 1;
4405       else if (unformat (i, "del"))
4406         is_add = 0;
4407       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4408         sw_if_index_set = 1;
4409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4410         sw_if_index_set = 1;
4411       else if (unformat (i, "%U/%d",
4412                          unformat_ip4_address, &v4address, &address_length))
4413         v4_address_set = 1;
4414       else if (unformat (i, "%U/%d",
4415                          unformat_ip6_address, &v6address, &address_length))
4416         v6_address_set = 1;
4417       else
4418         break;
4419     }
4420
4421   if (sw_if_index_set == 0)
4422     {
4423       errmsg ("missing interface name or sw_if_index\n");
4424       return -99;
4425     }
4426   if (v4_address_set && v6_address_set)
4427     {
4428       errmsg ("both v4 and v6 addresses set\n");
4429       return -99;
4430     }
4431   if (!v4_address_set && !v6_address_set && !del_all)
4432     {
4433       errmsg ("no addresses set\n");
4434       return -99;
4435     }
4436
4437   /* Construct the API message */
4438   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4439
4440   mp->sw_if_index = ntohl (sw_if_index);
4441   mp->is_add = is_add;
4442   mp->del_all = del_all;
4443   if (v6_address_set)
4444     {
4445       mp->is_ipv6 = 1;
4446       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4447     }
4448   else
4449     {
4450       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4451     }
4452   mp->address_length = address_length;
4453
4454   /* send it... */
4455   S;
4456
4457   /* Wait for a reply, return good/bad news  */
4458   W;
4459 }
4460
4461 static int
4462 api_sw_interface_set_table (vat_main_t * vam)
4463 {
4464   unformat_input_t *i = vam->input;
4465   vl_api_sw_interface_set_table_t *mp;
4466   f64 timeout;
4467   u32 sw_if_index, vrf_id = 0;
4468   u8 sw_if_index_set = 0;
4469   u8 is_ipv6 = 0;
4470
4471   /* Parse args required to build the message */
4472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4473     {
4474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4475         sw_if_index_set = 1;
4476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4477         sw_if_index_set = 1;
4478       else if (unformat (i, "vrf %d", &vrf_id))
4479         ;
4480       else if (unformat (i, "ipv6"))
4481         is_ipv6 = 1;
4482       else
4483         break;
4484     }
4485
4486   if (sw_if_index_set == 0)
4487     {
4488       errmsg ("missing interface name or sw_if_index\n");
4489       return -99;
4490     }
4491
4492   /* Construct the API message */
4493   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4494
4495   mp->sw_if_index = ntohl (sw_if_index);
4496   mp->is_ipv6 = is_ipv6;
4497   mp->vrf_id = ntohl (vrf_id);
4498
4499   /* send it... */
4500   S;
4501
4502   /* Wait for a reply... */
4503   W;
4504 }
4505
4506 static int
4507 api_sw_interface_set_vpath (vat_main_t * vam)
4508 {
4509   unformat_input_t *i = vam->input;
4510   vl_api_sw_interface_set_vpath_t *mp;
4511   f64 timeout;
4512   u32 sw_if_index = 0;
4513   u8 sw_if_index_set = 0;
4514   u8 is_enable = 0;
4515
4516   /* Parse args required to build the message */
4517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4518     {
4519       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4520         sw_if_index_set = 1;
4521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4522         sw_if_index_set = 1;
4523       else if (unformat (i, "enable"))
4524         is_enable = 1;
4525       else if (unformat (i, "disable"))
4526         is_enable = 0;
4527       else
4528         break;
4529     }
4530
4531   if (sw_if_index_set == 0)
4532     {
4533       errmsg ("missing interface name or sw_if_index\n");
4534       return -99;
4535     }
4536
4537   /* Construct the API message */
4538   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4539
4540   mp->sw_if_index = ntohl (sw_if_index);
4541   mp->enable = is_enable;
4542
4543   /* send it... */
4544   S;
4545
4546   /* Wait for a reply... */
4547   W;
4548 }
4549
4550 static int
4551 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4552 {
4553   unformat_input_t *i = vam->input;
4554   vl_api_sw_interface_set_l2_xconnect_t *mp;
4555   f64 timeout;
4556   u32 rx_sw_if_index;
4557   u8 rx_sw_if_index_set = 0;
4558   u32 tx_sw_if_index;
4559   u8 tx_sw_if_index_set = 0;
4560   u8 enable = 1;
4561
4562   /* Parse args required to build the message */
4563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4564     {
4565       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4566         rx_sw_if_index_set = 1;
4567       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4568         tx_sw_if_index_set = 1;
4569       else if (unformat (i, "rx"))
4570         {
4571           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4572             {
4573               if (unformat (i, "%U", unformat_sw_if_index, vam,
4574                             &rx_sw_if_index))
4575                 rx_sw_if_index_set = 1;
4576             }
4577           else
4578             break;
4579         }
4580       else if (unformat (i, "tx"))
4581         {
4582           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4583             {
4584               if (unformat (i, "%U", unformat_sw_if_index, vam,
4585                             &tx_sw_if_index))
4586                 tx_sw_if_index_set = 1;
4587             }
4588           else
4589             break;
4590         }
4591       else if (unformat (i, "enable"))
4592         enable = 1;
4593       else if (unformat (i, "disable"))
4594         enable = 0;
4595       else
4596         break;
4597     }
4598
4599   if (rx_sw_if_index_set == 0)
4600     {
4601       errmsg ("missing rx interface name or rx_sw_if_index\n");
4602       return -99;
4603     }
4604
4605   if (enable && (tx_sw_if_index_set == 0))
4606     {
4607       errmsg ("missing tx interface name or tx_sw_if_index\n");
4608       return -99;
4609     }
4610
4611   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4612
4613   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4614   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4615   mp->enable = enable;
4616
4617   S;
4618   W;
4619   /* NOTREACHED */
4620   return 0;
4621 }
4622
4623 static int
4624 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4625 {
4626   unformat_input_t *i = vam->input;
4627   vl_api_sw_interface_set_l2_bridge_t *mp;
4628   f64 timeout;
4629   u32 rx_sw_if_index;
4630   u8 rx_sw_if_index_set = 0;
4631   u32 bd_id;
4632   u8 bd_id_set = 0;
4633   u8 bvi = 0;
4634   u32 shg = 0;
4635   u8 enable = 1;
4636
4637   /* Parse args required to build the message */
4638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4639     {
4640       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4641         rx_sw_if_index_set = 1;
4642       else if (unformat (i, "bd_id %d", &bd_id))
4643         bd_id_set = 1;
4644       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4645         rx_sw_if_index_set = 1;
4646       else if (unformat (i, "shg %d", &shg))
4647         ;
4648       else if (unformat (i, "bvi"))
4649         bvi = 1;
4650       else if (unformat (i, "enable"))
4651         enable = 1;
4652       else if (unformat (i, "disable"))
4653         enable = 0;
4654       else
4655         break;
4656     }
4657
4658   if (rx_sw_if_index_set == 0)
4659     {
4660       errmsg ("missing rx interface name or sw_if_index\n");
4661       return -99;
4662     }
4663
4664   if (enable && (bd_id_set == 0))
4665     {
4666       errmsg ("missing bridge domain\n");
4667       return -99;
4668     }
4669
4670   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4671
4672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4673   mp->bd_id = ntohl (bd_id);
4674   mp->shg = (u8) shg;
4675   mp->bvi = bvi;
4676   mp->enable = enable;
4677
4678   S;
4679   W;
4680   /* NOTREACHED */
4681   return 0;
4682 }
4683
4684 static int
4685 api_bridge_domain_dump (vat_main_t * vam)
4686 {
4687   unformat_input_t *i = vam->input;
4688   vl_api_bridge_domain_dump_t *mp;
4689   f64 timeout;
4690   u32 bd_id = ~0;
4691
4692   /* Parse args required to build the message */
4693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4694     {
4695       if (unformat (i, "bd_id %d", &bd_id))
4696         ;
4697       else
4698         break;
4699     }
4700
4701   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4702   mp->bd_id = ntohl (bd_id);
4703   S;
4704
4705   /* Use a control ping for synchronization */
4706   {
4707     vl_api_control_ping_t *mp;
4708     M (CONTROL_PING, control_ping);
4709     S;
4710   }
4711
4712   W;
4713   /* NOTREACHED */
4714   return 0;
4715 }
4716
4717 static int
4718 api_bridge_domain_add_del (vat_main_t * vam)
4719 {
4720   unformat_input_t *i = vam->input;
4721   vl_api_bridge_domain_add_del_t *mp;
4722   f64 timeout;
4723   u32 bd_id = ~0;
4724   u8 is_add = 1;
4725   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4726
4727   /* Parse args required to build the message */
4728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4729     {
4730       if (unformat (i, "bd_id %d", &bd_id))
4731         ;
4732       else if (unformat (i, "flood %d", &flood))
4733         ;
4734       else if (unformat (i, "uu-flood %d", &uu_flood))
4735         ;
4736       else if (unformat (i, "forward %d", &forward))
4737         ;
4738       else if (unformat (i, "learn %d", &learn))
4739         ;
4740       else if (unformat (i, "arp-term %d", &arp_term))
4741         ;
4742       else if (unformat (i, "del"))
4743         {
4744           is_add = 0;
4745           flood = uu_flood = forward = learn = 0;
4746         }
4747       else
4748         break;
4749     }
4750
4751   if (bd_id == ~0)
4752     {
4753       errmsg ("missing bridge domain\n");
4754       return -99;
4755     }
4756
4757   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4758
4759   mp->bd_id = ntohl (bd_id);
4760   mp->flood = flood;
4761   mp->uu_flood = uu_flood;
4762   mp->forward = forward;
4763   mp->learn = learn;
4764   mp->arp_term = arp_term;
4765   mp->is_add = is_add;
4766
4767   S;
4768   W;
4769   /* NOTREACHED */
4770   return 0;
4771 }
4772
4773 static int
4774 api_l2fib_add_del (vat_main_t * vam)
4775 {
4776   unformat_input_t *i = vam->input;
4777   vl_api_l2fib_add_del_t *mp;
4778   f64 timeout;
4779   u64 mac = 0;
4780   u8 mac_set = 0;
4781   u32 bd_id;
4782   u8 bd_id_set = 0;
4783   u32 sw_if_index;
4784   u8 sw_if_index_set = 0;
4785   u8 is_add = 1;
4786   u8 static_mac = 0;
4787   u8 filter_mac = 0;
4788   u8 bvi_mac = 0;
4789   int count = 1;
4790   f64 before = 0;
4791   int j;
4792
4793   /* Parse args required to build the message */
4794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4795     {
4796       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4797         mac_set = 1;
4798       else if (unformat (i, "bd_id %d", &bd_id))
4799         bd_id_set = 1;
4800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4801         sw_if_index_set = 1;
4802       else if (unformat (i, "sw_if"))
4803         {
4804           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4805             {
4806               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4807                 sw_if_index_set = 1;
4808             }
4809           else
4810             break;
4811         }
4812       else if (unformat (i, "static"))
4813         static_mac = 1;
4814       else if (unformat (i, "filter"))
4815         {
4816           filter_mac = 1;
4817           static_mac = 1;
4818         }
4819       else if (unformat (i, "bvi"))
4820         {
4821           bvi_mac = 1;
4822           static_mac = 1;
4823         }
4824       else if (unformat (i, "del"))
4825         is_add = 0;
4826       else if (unformat (i, "count %d", &count))
4827         ;
4828       else
4829         break;
4830     }
4831
4832   if (mac_set == 0)
4833     {
4834       errmsg ("missing mac address\n");
4835       return -99;
4836     }
4837
4838   if (bd_id_set == 0)
4839     {
4840       errmsg ("missing bridge domain\n");
4841       return -99;
4842     }
4843
4844   if (is_add && (sw_if_index_set == 0))
4845     {
4846       errmsg ("missing interface name or sw_if_index\n");
4847       return -99;
4848     }
4849
4850   if (count > 1)
4851     {
4852       /* Turn on async mode */
4853       vam->async_mode = 1;
4854       vam->async_errors = 0;
4855       before = vat_time_now (vam);
4856     }
4857
4858   for (j = 0; j < count; j++)
4859     {
4860       M (L2FIB_ADD_DEL, l2fib_add_del);
4861
4862       mp->mac = mac;
4863       mp->bd_id = ntohl (bd_id);
4864       mp->is_add = is_add;
4865
4866       if (is_add)
4867         {
4868           mp->sw_if_index = ntohl (sw_if_index);
4869           mp->static_mac = static_mac;
4870           mp->filter_mac = filter_mac;
4871           mp->bvi_mac = bvi_mac;
4872         }
4873       increment_mac_address (&mac);
4874       /* send it... */
4875       S;
4876     }
4877
4878   if (count > 1)
4879     {
4880       vl_api_control_ping_t *mp;
4881       f64 after;
4882
4883       /* Shut off async mode */
4884       vam->async_mode = 0;
4885
4886       M (CONTROL_PING, control_ping);
4887       S;
4888
4889       timeout = vat_time_now (vam) + 1.0;
4890       while (vat_time_now (vam) < timeout)
4891         if (vam->result_ready == 1)
4892           goto out;
4893       vam->retval = -99;
4894
4895     out:
4896       if (vam->retval == -99)
4897         errmsg ("timeout\n");
4898
4899       if (vam->async_errors > 0)
4900         {
4901           errmsg ("%d asynchronous errors\n", vam->async_errors);
4902           vam->retval = -98;
4903         }
4904       vam->async_errors = 0;
4905       after = vat_time_now (vam);
4906
4907       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4908                count, after - before, count / (after - before));
4909     }
4910   else
4911     {
4912       /* Wait for a reply... */
4913       W;
4914     }
4915   /* Return the good/bad news */
4916   return (vam->retval);
4917 }
4918
4919 static int
4920 api_l2_flags (vat_main_t * vam)
4921 {
4922   unformat_input_t *i = vam->input;
4923   vl_api_l2_flags_t *mp;
4924   f64 timeout;
4925   u32 sw_if_index;
4926   u32 feature_bitmap = 0;
4927   u8 sw_if_index_set = 0;
4928
4929   /* Parse args required to build the message */
4930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4931     {
4932       if (unformat (i, "sw_if_index %d", &sw_if_index))
4933         sw_if_index_set = 1;
4934       else if (unformat (i, "sw_if"))
4935         {
4936           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4937             {
4938               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4939                 sw_if_index_set = 1;
4940             }
4941           else
4942             break;
4943         }
4944       else if (unformat (i, "learn"))
4945         feature_bitmap |= L2INPUT_FEAT_LEARN;
4946       else if (unformat (i, "forward"))
4947         feature_bitmap |= L2INPUT_FEAT_FWD;
4948       else if (unformat (i, "flood"))
4949         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4950       else if (unformat (i, "uu-flood"))
4951         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   M (L2_FLAGS, l2_flags);
4963
4964   mp->sw_if_index = ntohl (sw_if_index);
4965   mp->feature_bitmap = ntohl (feature_bitmap);
4966
4967   S;
4968   W;
4969   /* NOTREACHED */
4970   return 0;
4971 }
4972
4973 static int
4974 api_bridge_flags (vat_main_t * vam)
4975 {
4976   unformat_input_t *i = vam->input;
4977   vl_api_bridge_flags_t *mp;
4978   f64 timeout;
4979   u32 bd_id;
4980   u8 bd_id_set = 0;
4981   u8 is_set = 1;
4982   u32 flags = 0;
4983
4984   /* Parse args required to build the message */
4985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4986     {
4987       if (unformat (i, "bd_id %d", &bd_id))
4988         bd_id_set = 1;
4989       else if (unformat (i, "learn"))
4990         flags |= L2_LEARN;
4991       else if (unformat (i, "forward"))
4992         flags |= L2_FWD;
4993       else if (unformat (i, "flood"))
4994         flags |= L2_FLOOD;
4995       else if (unformat (i, "uu-flood"))
4996         flags |= L2_UU_FLOOD;
4997       else if (unformat (i, "arp-term"))
4998         flags |= L2_ARP_TERM;
4999       else if (unformat (i, "off"))
5000         is_set = 0;
5001       else if (unformat (i, "disable"))
5002         is_set = 0;
5003       else
5004         break;
5005     }
5006
5007   if (bd_id_set == 0)
5008     {
5009       errmsg ("missing bridge domain\n");
5010       return -99;
5011     }
5012
5013   M (BRIDGE_FLAGS, bridge_flags);
5014
5015   mp->bd_id = ntohl (bd_id);
5016   mp->feature_bitmap = ntohl (flags);
5017   mp->is_set = is_set;
5018
5019   S;
5020   W;
5021   /* NOTREACHED */
5022   return 0;
5023 }
5024
5025 static int
5026 api_bd_ip_mac_add_del (vat_main_t * vam)
5027 {
5028   unformat_input_t *i = vam->input;
5029   vl_api_bd_ip_mac_add_del_t *mp;
5030   f64 timeout;
5031   u32 bd_id;
5032   u8 is_ipv6 = 0;
5033   u8 is_add = 1;
5034   u8 bd_id_set = 0;
5035   u8 ip_set = 0;
5036   u8 mac_set = 0;
5037   ip4_address_t v4addr;
5038   ip6_address_t v6addr;
5039   u8 macaddr[6];
5040
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "bd_id %d", &bd_id))
5046         {
5047           bd_id_set++;
5048         }
5049       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5050         {
5051           ip_set++;
5052         }
5053       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5054         {
5055           ip_set++;
5056           is_ipv6++;
5057         }
5058       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5059         {
5060           mac_set++;
5061         }
5062       else if (unformat (i, "del"))
5063         is_add = 0;
5064       else
5065         break;
5066     }
5067
5068   if (bd_id_set == 0)
5069     {
5070       errmsg ("missing bridge domain\n");
5071       return -99;
5072     }
5073   else if (ip_set == 0)
5074     {
5075       errmsg ("missing IP address\n");
5076       return -99;
5077     }
5078   else if (mac_set == 0)
5079     {
5080       errmsg ("missing MAC address\n");
5081       return -99;
5082     }
5083
5084   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5085
5086   mp->bd_id = ntohl (bd_id);
5087   mp->is_ipv6 = is_ipv6;
5088   mp->is_add = is_add;
5089   if (is_ipv6)
5090     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5091   else
5092     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5093   clib_memcpy (mp->mac_address, macaddr, 6);
5094   S;
5095   W;
5096   /* NOTREACHED */
5097   return 0;
5098 }
5099
5100 static int
5101 api_tap_connect (vat_main_t * vam)
5102 {
5103   unformat_input_t *i = vam->input;
5104   vl_api_tap_connect_t *mp;
5105   f64 timeout;
5106   u8 mac_address[6];
5107   u8 random_mac = 1;
5108   u8 name_set = 0;
5109   u8 *tap_name;
5110
5111   memset (mac_address, 0, sizeof (mac_address));
5112
5113   /* Parse args required to build the message */
5114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5115     {
5116       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5117         {
5118           random_mac = 0;
5119         }
5120       else if (unformat (i, "random-mac"))
5121         random_mac = 1;
5122       else if (unformat (i, "tapname %s", &tap_name))
5123         name_set = 1;
5124       else
5125         break;
5126     }
5127
5128   if (name_set == 0)
5129     {
5130       errmsg ("missing tap name\n");
5131       return -99;
5132     }
5133   if (vec_len (tap_name) > 63)
5134     {
5135       errmsg ("tap name too long\n");
5136     }
5137   vec_add1 (tap_name, 0);
5138
5139   /* Construct the API message */
5140   M (TAP_CONNECT, tap_connect);
5141
5142   mp->use_random_mac = random_mac;
5143   clib_memcpy (mp->mac_address, mac_address, 6);
5144   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5145   vec_free (tap_name);
5146
5147   /* send it... */
5148   S;
5149
5150   /* Wait for a reply... */
5151   W;
5152 }
5153
5154 static int
5155 api_tap_modify (vat_main_t * vam)
5156 {
5157   unformat_input_t *i = vam->input;
5158   vl_api_tap_modify_t *mp;
5159   f64 timeout;
5160   u8 mac_address[6];
5161   u8 random_mac = 1;
5162   u8 name_set = 0;
5163   u8 *tap_name;
5164   u32 sw_if_index = ~0;
5165   u8 sw_if_index_set = 0;
5166
5167   memset (mac_address, 0, sizeof (mac_address));
5168
5169   /* Parse args required to build the message */
5170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5171     {
5172       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5173         sw_if_index_set = 1;
5174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5175         sw_if_index_set = 1;
5176       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5177         {
5178           random_mac = 0;
5179         }
5180       else if (unformat (i, "random-mac"))
5181         random_mac = 1;
5182       else if (unformat (i, "tapname %s", &tap_name))
5183         name_set = 1;
5184       else
5185         break;
5186     }
5187
5188   if (sw_if_index_set == 0)
5189     {
5190       errmsg ("missing vpp interface name");
5191       return -99;
5192     }
5193   if (name_set == 0)
5194     {
5195       errmsg ("missing tap name\n");
5196       return -99;
5197     }
5198   if (vec_len (tap_name) > 63)
5199     {
5200       errmsg ("tap name too long\n");
5201     }
5202   vec_add1 (tap_name, 0);
5203
5204   /* Construct the API message */
5205   M (TAP_MODIFY, tap_modify);
5206
5207   mp->use_random_mac = random_mac;
5208   mp->sw_if_index = ntohl (sw_if_index);
5209   clib_memcpy (mp->mac_address, mac_address, 6);
5210   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5211   vec_free (tap_name);
5212
5213   /* send it... */
5214   S;
5215
5216   /* Wait for a reply... */
5217   W;
5218 }
5219
5220 static int
5221 api_tap_delete (vat_main_t * vam)
5222 {
5223   unformat_input_t *i = vam->input;
5224   vl_api_tap_delete_t *mp;
5225   f64 timeout;
5226   u32 sw_if_index = ~0;
5227   u8 sw_if_index_set = 0;
5228
5229   /* Parse args required to build the message */
5230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5231     {
5232       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5233         sw_if_index_set = 1;
5234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5235         sw_if_index_set = 1;
5236       else
5237         break;
5238     }
5239
5240   if (sw_if_index_set == 0)
5241     {
5242       errmsg ("missing vpp interface name");
5243       return -99;
5244     }
5245
5246   /* Construct the API message */
5247   M (TAP_DELETE, tap_delete);
5248
5249   mp->sw_if_index = ntohl (sw_if_index);
5250
5251   /* send it... */
5252   S;
5253
5254   /* Wait for a reply... */
5255   W;
5256 }
5257
5258 static int
5259 api_ip_add_del_route (vat_main_t * vam)
5260 {
5261   unformat_input_t *i = vam->input;
5262   vl_api_ip_add_del_route_t *mp;
5263   f64 timeout;
5264   u32 sw_if_index = ~0, vrf_id = 0;
5265   u8 sw_if_index_set = 0;
5266   u8 is_ipv6 = 0;
5267   u8 is_local = 0, is_drop = 0;
5268   u8 create_vrf_if_needed = 0;
5269   u8 is_add = 1;
5270   u8 next_hop_weight = 1;
5271   u8 not_last = 0;
5272   u8 is_multipath = 0;
5273   u8 address_set = 0;
5274   u8 address_length_set = 0;
5275   u32 lookup_in_vrf = 0;
5276   u32 resolve_attempts = 0;
5277   u32 dst_address_length = 0;
5278   u8 next_hop_set = 0;
5279   ip4_address_t v4_dst_address, v4_next_hop_address;
5280   ip6_address_t v6_dst_address, v6_next_hop_address;
5281   int count = 1;
5282   int j;
5283   f64 before = 0;
5284   u32 random_add_del = 0;
5285   u32 *random_vector = 0;
5286   uword *random_hash;
5287   u32 random_seed = 0xdeaddabe;
5288   u32 classify_table_index = ~0;
5289   u8 is_classify = 0;
5290
5291   /* Parse args required to build the message */
5292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5293     {
5294       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5297         sw_if_index_set = 1;
5298       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5299         {
5300           address_set = 1;
5301           is_ipv6 = 0;
5302         }
5303       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5304         {
5305           address_set = 1;
5306           is_ipv6 = 1;
5307         }
5308       else if (unformat (i, "/%d", &dst_address_length))
5309         {
5310           address_length_set = 1;
5311         }
5312
5313       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5314                                          &v4_next_hop_address))
5315         {
5316           next_hop_set = 1;
5317         }
5318       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5319                                          &v6_next_hop_address))
5320         {
5321           next_hop_set = 1;
5322         }
5323       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5324         ;
5325       else if (unformat (i, "weight %d", &next_hop_weight))
5326         ;
5327       else if (unformat (i, "drop"))
5328         {
5329           is_drop = 1;
5330         }
5331       else if (unformat (i, "local"))
5332         {
5333           is_local = 1;
5334         }
5335       else if (unformat (i, "classify %d", &classify_table_index))
5336         {
5337           is_classify = 1;
5338         }
5339       else if (unformat (i, "del"))
5340         is_add = 0;
5341       else if (unformat (i, "add"))
5342         is_add = 1;
5343       else if (unformat (i, "not-last"))
5344         not_last = 1;
5345       else if (unformat (i, "multipath"))
5346         is_multipath = 1;
5347       else if (unformat (i, "vrf %d", &vrf_id))
5348         ;
5349       else if (unformat (i, "create-vrf"))
5350         create_vrf_if_needed = 1;
5351       else if (unformat (i, "count %d", &count))
5352         ;
5353       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5354         ;
5355       else if (unformat (i, "random"))
5356         random_add_del = 1;
5357       else if (unformat (i, "seed %d", &random_seed))
5358         ;
5359       else
5360         {
5361           clib_warning ("parse error '%U'", format_unformat_error, i);
5362           return -99;
5363         }
5364     }
5365
5366   if (resolve_attempts > 0 && sw_if_index_set == 0)
5367     {
5368       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5369       return -99;
5370     }
5371
5372   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5373     {
5374       errmsg ("next hop / local / drop / classify not set\n");
5375       return -99;
5376     }
5377
5378   if (address_set == 0)
5379     {
5380       errmsg ("missing addresses\n");
5381       return -99;
5382     }
5383
5384   if (address_length_set == 0)
5385     {
5386       errmsg ("missing address length\n");
5387       return -99;
5388     }
5389
5390   /* Generate a pile of unique, random routes */
5391   if (random_add_del)
5392     {
5393       u32 this_random_address;
5394       random_hash = hash_create (count, sizeof (uword));
5395
5396       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5397       for (j = 0; j <= count; j++)
5398         {
5399           do
5400             {
5401               this_random_address = random_u32 (&random_seed);
5402               this_random_address =
5403                 clib_host_to_net_u32 (this_random_address);
5404             }
5405           while (hash_get (random_hash, this_random_address));
5406           vec_add1 (random_vector, this_random_address);
5407           hash_set (random_hash, this_random_address, 1);
5408         }
5409       hash_free (random_hash);
5410       v4_dst_address.as_u32 = random_vector[0];
5411     }
5412
5413   if (count > 1)
5414     {
5415       /* Turn on async mode */
5416       vam->async_mode = 1;
5417       vam->async_errors = 0;
5418       before = vat_time_now (vam);
5419     }
5420
5421   for (j = 0; j < count; j++)
5422     {
5423       /* Construct the API message */
5424       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5425
5426       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5427       mp->vrf_id = ntohl (vrf_id);
5428       if (resolve_attempts > 0)
5429         {
5430           mp->resolve_attempts = ntohl (resolve_attempts);
5431           mp->resolve_if_needed = 1;
5432         }
5433       mp->create_vrf_if_needed = create_vrf_if_needed;
5434
5435       mp->is_add = is_add;
5436       mp->is_drop = is_drop;
5437       mp->is_ipv6 = is_ipv6;
5438       mp->is_local = is_local;
5439       mp->is_classify = is_classify;
5440       mp->is_multipath = is_multipath;
5441       mp->not_last = not_last;
5442       mp->next_hop_weight = next_hop_weight;
5443       mp->dst_address_length = dst_address_length;
5444       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5445       mp->classify_table_index = ntohl (classify_table_index);
5446
5447       if (is_ipv6)
5448         {
5449           clib_memcpy (mp->dst_address, &v6_dst_address,
5450                        sizeof (v6_dst_address));
5451           if (next_hop_set)
5452             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5453                          sizeof (v6_next_hop_address));
5454           increment_v6_address (&v6_dst_address);
5455         }
5456       else
5457         {
5458           clib_memcpy (mp->dst_address, &v4_dst_address,
5459                        sizeof (v4_dst_address));
5460           if (next_hop_set)
5461             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5462                          sizeof (v4_next_hop_address));
5463           if (random_add_del)
5464             v4_dst_address.as_u32 = random_vector[j + 1];
5465           else
5466             increment_v4_address (&v4_dst_address);
5467         }
5468       /* send it... */
5469       S;
5470     }
5471
5472   /* When testing multiple add/del ops, use a control-ping to sync */
5473   if (count > 1)
5474     {
5475       vl_api_control_ping_t *mp;
5476       f64 after;
5477
5478       /* Shut off async mode */
5479       vam->async_mode = 0;
5480
5481       M (CONTROL_PING, control_ping);
5482       S;
5483
5484       timeout = vat_time_now (vam) + 1.0;
5485       while (vat_time_now (vam) < timeout)
5486         if (vam->result_ready == 1)
5487           goto out;
5488       vam->retval = -99;
5489
5490     out:
5491       if (vam->retval == -99)
5492         errmsg ("timeout\n");
5493
5494       if (vam->async_errors > 0)
5495         {
5496           errmsg ("%d asynchronous errors\n", vam->async_errors);
5497           vam->retval = -98;
5498         }
5499       vam->async_errors = 0;
5500       after = vat_time_now (vam);
5501
5502       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5503                count, after - before, count / (after - before));
5504     }
5505   else
5506     {
5507       /* Wait for a reply... */
5508       W;
5509     }
5510
5511   /* Return the good/bad news */
5512   return (vam->retval);
5513 }
5514
5515 static int
5516 api_proxy_arp_add_del (vat_main_t * vam)
5517 {
5518   unformat_input_t *i = vam->input;
5519   vl_api_proxy_arp_add_del_t *mp;
5520   f64 timeout;
5521   u32 vrf_id = 0;
5522   u8 is_add = 1;
5523   ip4_address_t lo, hi;
5524   u8 range_set = 0;
5525
5526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5527     {
5528       if (unformat (i, "vrf %d", &vrf_id))
5529         ;
5530       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5531                          unformat_ip4_address, &hi))
5532         range_set = 1;
5533       else if (unformat (i, "del"))
5534         is_add = 0;
5535       else
5536         {
5537           clib_warning ("parse error '%U'", format_unformat_error, i);
5538           return -99;
5539         }
5540     }
5541
5542   if (range_set == 0)
5543     {
5544       errmsg ("address range not set\n");
5545       return -99;
5546     }
5547
5548   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5549
5550   mp->vrf_id = ntohl (vrf_id);
5551   mp->is_add = is_add;
5552   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5553   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5554
5555   S;
5556   W;
5557   /* NOTREACHED */
5558   return 0;
5559 }
5560
5561 static int
5562 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5563 {
5564   unformat_input_t *i = vam->input;
5565   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5566   f64 timeout;
5567   u32 sw_if_index;
5568   u8 enable = 1;
5569   u8 sw_if_index_set = 0;
5570
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5574         sw_if_index_set = 1;
5575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5576         sw_if_index_set = 1;
5577       else if (unformat (i, "enable"))
5578         enable = 1;
5579       else if (unformat (i, "disable"))
5580         enable = 0;
5581       else
5582         {
5583           clib_warning ("parse error '%U'", format_unformat_error, i);
5584           return -99;
5585         }
5586     }
5587
5588   if (sw_if_index_set == 0)
5589     {
5590       errmsg ("missing interface name or sw_if_index\n");
5591       return -99;
5592     }
5593
5594   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5595
5596   mp->sw_if_index = ntohl (sw_if_index);
5597   mp->enable_disable = enable;
5598
5599   S;
5600   W;
5601   /* NOTREACHED */
5602   return 0;
5603 }
5604
5605 static int
5606 api_mpls_add_del_decap (vat_main_t * vam)
5607 {
5608   unformat_input_t *i = vam->input;
5609   vl_api_mpls_add_del_decap_t *mp;
5610   f64 timeout;
5611   u32 rx_vrf_id = 0;
5612   u32 tx_vrf_id = 0;
5613   u32 label = 0;
5614   u8 is_add = 1;
5615   u8 s_bit = 1;
5616   u32 next_index = 1;
5617
5618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5619     {
5620       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5621         ;
5622       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5623         ;
5624       else if (unformat (i, "label %d", &label))
5625         ;
5626       else if (unformat (i, "next-index %d", &next_index))
5627         ;
5628       else if (unformat (i, "del"))
5629         is_add = 0;
5630       else if (unformat (i, "s-bit-clear"))
5631         s_bit = 0;
5632       else
5633         {
5634           clib_warning ("parse error '%U'", format_unformat_error, i);
5635           return -99;
5636         }
5637     }
5638
5639   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5640
5641   mp->rx_vrf_id = ntohl (rx_vrf_id);
5642   mp->tx_vrf_id = ntohl (tx_vrf_id);
5643   mp->label = ntohl (label);
5644   mp->next_index = ntohl (next_index);
5645   mp->s_bit = s_bit;
5646   mp->is_add = is_add;
5647
5648   S;
5649   W;
5650   /* NOTREACHED */
5651   return 0;
5652 }
5653
5654 static int
5655 api_mpls_add_del_encap (vat_main_t * vam)
5656 {
5657   unformat_input_t *i = vam->input;
5658   vl_api_mpls_add_del_encap_t *mp;
5659   f64 timeout;
5660   u32 vrf_id = 0;
5661   u32 *labels = 0;
5662   u32 label;
5663   ip4_address_t dst_address;
5664   u8 is_add = 1;
5665
5666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5667     {
5668       if (unformat (i, "vrf %d", &vrf_id))
5669         ;
5670       else if (unformat (i, "label %d", &label))
5671         vec_add1 (labels, ntohl (label));
5672       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5673         ;
5674       else if (unformat (i, "del"))
5675         is_add = 0;
5676       else
5677         {
5678           clib_warning ("parse error '%U'", format_unformat_error, i);
5679           return -99;
5680         }
5681     }
5682
5683   if (vec_len (labels) == 0)
5684     {
5685       errmsg ("missing encap label stack\n");
5686       return -99;
5687     }
5688
5689   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5690       sizeof (u32) * vec_len (labels));
5691
5692   mp->vrf_id = ntohl (vrf_id);
5693   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5694   mp->is_add = is_add;
5695   mp->nlabels = vec_len (labels);
5696   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5697
5698   vec_free (labels);
5699
5700   S;
5701   W;
5702   /* NOTREACHED */
5703   return 0;
5704 }
5705
5706 static int
5707 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5708 {
5709   unformat_input_t *i = vam->input;
5710   vl_api_mpls_gre_add_del_tunnel_t *mp;
5711   f64 timeout;
5712   u32 inner_vrf_id = 0;
5713   u32 outer_vrf_id = 0;
5714   ip4_address_t src_address;
5715   ip4_address_t dst_address;
5716   ip4_address_t intfc_address;
5717   u32 tmp;
5718   u8 intfc_address_length = 0;
5719   u8 is_add = 1;
5720   u8 l2_only = 0;
5721
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5725         ;
5726       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5727         ;
5728       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5729         ;
5730       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5731         ;
5732       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5733                          &intfc_address, &tmp))
5734         intfc_address_length = tmp;
5735       else if (unformat (i, "l2-only"))
5736         l2_only = 1;
5737       else if (unformat (i, "del"))
5738         is_add = 0;
5739       else
5740         {
5741           clib_warning ("parse error '%U'", format_unformat_error, i);
5742           return -99;
5743         }
5744     }
5745
5746   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5747
5748   mp->inner_vrf_id = ntohl (inner_vrf_id);
5749   mp->outer_vrf_id = ntohl (outer_vrf_id);
5750   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5751   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5752   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5753   mp->intfc_address_length = intfc_address_length;
5754   mp->l2_only = l2_only;
5755   mp->is_add = is_add;
5756
5757   S;
5758   W;
5759   /* NOTREACHED */
5760   return 0;
5761 }
5762
5763 static int
5764 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5765 {
5766   unformat_input_t *i = vam->input;
5767   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5768   f64 timeout;
5769   u32 inner_vrf_id = 0;
5770   ip4_address_t intfc_address;
5771   u8 dst_mac_address[6];
5772   int dst_set = 1;
5773   u32 tmp;
5774   u8 intfc_address_length = 0;
5775   u8 is_add = 1;
5776   u8 l2_only = 0;
5777   u32 tx_sw_if_index;
5778   int tx_sw_if_index_set = 0;
5779
5780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5781     {
5782       if (unformat (i, "vrf %d", &inner_vrf_id))
5783         ;
5784       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5785                          &intfc_address, &tmp))
5786         intfc_address_length = tmp;
5787       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5788         tx_sw_if_index_set = 1;
5789       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5790         tx_sw_if_index_set = 1;
5791       else if (unformat (i, "dst %U", unformat_ethernet_address,
5792                          dst_mac_address))
5793         dst_set = 1;
5794       else if (unformat (i, "l2-only"))
5795         l2_only = 1;
5796       else if (unformat (i, "del"))
5797         is_add = 0;
5798       else
5799         {
5800           clib_warning ("parse error '%U'", format_unformat_error, i);
5801           return -99;
5802         }
5803     }
5804
5805   if (!dst_set)
5806     {
5807       errmsg ("dst (mac address) not set\n");
5808       return -99;
5809     }
5810   if (!tx_sw_if_index_set)
5811     {
5812       errmsg ("tx-intfc not set\n");
5813       return -99;
5814     }
5815
5816   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5817
5818   mp->vrf_id = ntohl (inner_vrf_id);
5819   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5820   mp->adj_address_length = intfc_address_length;
5821   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5822                sizeof (dst_mac_address));
5823   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5824   mp->l2_only = l2_only;
5825   mp->is_add = is_add;
5826
5827   S;
5828   W;
5829   /* NOTREACHED */
5830   return 0;
5831 }
5832
5833 static int
5834 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5835 {
5836   unformat_input_t *i = vam->input;
5837   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5838   f64 timeout;
5839   u32 inner_vrf_id = 0;
5840   u32 outer_vrf_id = 0;
5841   ip4_address_t adj_address;
5842   int adj_address_set = 0;
5843   ip4_address_t next_hop_address;
5844   int next_hop_address_set = 0;
5845   u32 tmp;
5846   u8 adj_address_length = 0;
5847   u8 l2_only = 0;
5848   u8 is_add = 1;
5849   u32 resolve_attempts = 5;
5850   u8 resolve_if_needed = 1;
5851
5852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5853     {
5854       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5855         ;
5856       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5857         ;
5858       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5859                          &adj_address, &tmp))
5860         {
5861           adj_address_length = tmp;
5862           adj_address_set = 1;
5863         }
5864       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5865                          &next_hop_address))
5866         next_hop_address_set = 1;
5867       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5868         ;
5869       else if (unformat (i, "resolve-if-needed %d", &tmp))
5870         resolve_if_needed = tmp;
5871       else if (unformat (i, "l2-only"))
5872         l2_only = 1;
5873       else if (unformat (i, "del"))
5874         is_add = 0;
5875       else
5876         {
5877           clib_warning ("parse error '%U'", format_unformat_error, i);
5878           return -99;
5879         }
5880     }
5881
5882   if (!adj_address_set)
5883     {
5884       errmsg ("adjacency address/mask not set\n");
5885       return -99;
5886     }
5887   if (!next_hop_address_set)
5888     {
5889       errmsg ("ip4 next hop address (in outer fib) not set\n");
5890       return -99;
5891     }
5892
5893   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5894
5895   mp->inner_vrf_id = ntohl (inner_vrf_id);
5896   mp->outer_vrf_id = ntohl (outer_vrf_id);
5897   mp->resolve_attempts = ntohl (resolve_attempts);
5898   mp->resolve_if_needed = resolve_if_needed;
5899   mp->is_add = is_add;
5900   mp->l2_only = l2_only;
5901   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5902   mp->adj_address_length = adj_address_length;
5903   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5904                sizeof (next_hop_address));
5905
5906   S;
5907   W;
5908   /* NOTREACHED */
5909   return 0;
5910 }
5911
5912 static int
5913 api_sw_interface_set_unnumbered (vat_main_t * vam)
5914 {
5915   unformat_input_t *i = vam->input;
5916   vl_api_sw_interface_set_unnumbered_t *mp;
5917   f64 timeout;
5918   u32 sw_if_index;
5919   u32 unnum_sw_index = ~0;
5920   u8 is_add = 1;
5921   u8 sw_if_index_set = 0;
5922
5923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5924     {
5925       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5926         sw_if_index_set = 1;
5927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5928         sw_if_index_set = 1;
5929       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5930         ;
5931       else if (unformat (i, "del"))
5932         is_add = 0;
5933       else
5934         {
5935           clib_warning ("parse error '%U'", format_unformat_error, i);
5936           return -99;
5937         }
5938     }
5939
5940   if (sw_if_index_set == 0)
5941     {
5942       errmsg ("missing interface name or sw_if_index\n");
5943       return -99;
5944     }
5945
5946   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5947
5948   mp->sw_if_index = ntohl (sw_if_index);
5949   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5950   mp->is_add = is_add;
5951
5952   S;
5953   W;
5954   /* NOTREACHED */
5955   return 0;
5956 }
5957
5958 static int
5959 api_ip_neighbor_add_del (vat_main_t * vam)
5960 {
5961   unformat_input_t *i = vam->input;
5962   vl_api_ip_neighbor_add_del_t *mp;
5963   f64 timeout;
5964   u32 sw_if_index;
5965   u8 sw_if_index_set = 0;
5966   u32 vrf_id = 0;
5967   u8 is_add = 1;
5968   u8 is_static = 0;
5969   u8 mac_address[6];
5970   u8 mac_set = 0;
5971   u8 v4_address_set = 0;
5972   u8 v6_address_set = 0;
5973   ip4_address_t v4address;
5974   ip6_address_t v6address;
5975
5976   memset (mac_address, 0, sizeof (mac_address));
5977
5978   /* Parse args required to build the message */
5979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5980     {
5981       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5982         {
5983           mac_set = 1;
5984         }
5985       else if (unformat (i, "del"))
5986         is_add = 0;
5987       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5988         sw_if_index_set = 1;
5989       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5990         sw_if_index_set = 1;
5991       else if (unformat (i, "is_static"))
5992         is_static = 1;
5993       else if (unformat (i, "vrf %d", &vrf_id))
5994         ;
5995       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5996         v4_address_set = 1;
5997       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5998         v6_address_set = 1;
5999       else
6000         {
6001           clib_warning ("parse error '%U'", format_unformat_error, i);
6002           return -99;
6003         }
6004     }
6005
6006   if (sw_if_index_set == 0)
6007     {
6008       errmsg ("missing interface name or sw_if_index\n");
6009       return -99;
6010     }
6011   if (v4_address_set && v6_address_set)
6012     {
6013       errmsg ("both v4 and v6 addresses set\n");
6014       return -99;
6015     }
6016   if (!v4_address_set && !v6_address_set)
6017     {
6018       errmsg ("no address set\n");
6019       return -99;
6020     }
6021
6022   /* Construct the API message */
6023   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6024
6025   mp->sw_if_index = ntohl (sw_if_index);
6026   mp->is_add = is_add;
6027   mp->vrf_id = ntohl (vrf_id);
6028   mp->is_static = is_static;
6029   if (mac_set)
6030     clib_memcpy (mp->mac_address, mac_address, 6);
6031   if (v6_address_set)
6032     {
6033       mp->is_ipv6 = 1;
6034       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6035     }
6036   else
6037     {
6038       /* mp->is_ipv6 = 0; via memset in M macro above */
6039       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6040     }
6041
6042   /* send it... */
6043   S;
6044
6045   /* Wait for a reply, return good/bad news  */
6046   W;
6047
6048   /* NOTREACHED */
6049   return 0;
6050 }
6051
6052 static int
6053 api_reset_vrf (vat_main_t * vam)
6054 {
6055   unformat_input_t *i = vam->input;
6056   vl_api_reset_vrf_t *mp;
6057   f64 timeout;
6058   u32 vrf_id = 0;
6059   u8 is_ipv6 = 0;
6060   u8 vrf_id_set = 0;
6061
6062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6063     {
6064       if (unformat (i, "vrf %d", &vrf_id))
6065         vrf_id_set = 1;
6066       else if (unformat (i, "ipv6"))
6067         is_ipv6 = 1;
6068       else
6069         {
6070           clib_warning ("parse error '%U'", format_unformat_error, i);
6071           return -99;
6072         }
6073     }
6074
6075   if (vrf_id_set == 0)
6076     {
6077       errmsg ("missing vrf id\n");
6078       return -99;
6079     }
6080
6081   M (RESET_VRF, reset_vrf);
6082
6083   mp->vrf_id = ntohl (vrf_id);
6084   mp->is_ipv6 = is_ipv6;
6085
6086   S;
6087   W;
6088   /* NOTREACHED */
6089   return 0;
6090 }
6091
6092 static int
6093 api_create_vlan_subif (vat_main_t * vam)
6094 {
6095   unformat_input_t *i = vam->input;
6096   vl_api_create_vlan_subif_t *mp;
6097   f64 timeout;
6098   u32 sw_if_index;
6099   u8 sw_if_index_set = 0;
6100   u32 vlan_id;
6101   u8 vlan_id_set = 0;
6102
6103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6104     {
6105       if (unformat (i, "sw_if_index %d", &sw_if_index))
6106         sw_if_index_set = 1;
6107       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6108         sw_if_index_set = 1;
6109       else if (unformat (i, "vlan %d", &vlan_id))
6110         vlan_id_set = 1;
6111       else
6112         {
6113           clib_warning ("parse error '%U'", format_unformat_error, i);
6114           return -99;
6115         }
6116     }
6117
6118   if (sw_if_index_set == 0)
6119     {
6120       errmsg ("missing interface name or sw_if_index\n");
6121       return -99;
6122     }
6123
6124   if (vlan_id_set == 0)
6125     {
6126       errmsg ("missing vlan_id\n");
6127       return -99;
6128     }
6129   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6130
6131   mp->sw_if_index = ntohl (sw_if_index);
6132   mp->vlan_id = ntohl (vlan_id);
6133
6134   S;
6135   W;
6136   /* NOTREACHED */
6137   return 0;
6138 }
6139
6140 #define foreach_create_subif_bit                \
6141 _(no_tags)                                      \
6142 _(one_tag)                                      \
6143 _(two_tags)                                     \
6144 _(dot1ad)                                       \
6145 _(exact_match)                                  \
6146 _(default_sub)                                  \
6147 _(outer_vlan_id_any)                            \
6148 _(inner_vlan_id_any)
6149
6150 static int
6151 api_create_subif (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_create_subif_t *mp;
6155   f64 timeout;
6156   u32 sw_if_index;
6157   u8 sw_if_index_set = 0;
6158   u32 sub_id;
6159   u8 sub_id_set = 0;
6160   u32 no_tags = 0;
6161   u32 one_tag = 0;
6162   u32 two_tags = 0;
6163   u32 dot1ad = 0;
6164   u32 exact_match = 0;
6165   u32 default_sub = 0;
6166   u32 outer_vlan_id_any = 0;
6167   u32 inner_vlan_id_any = 0;
6168   u32 tmp;
6169   u16 outer_vlan_id = 0;
6170   u16 inner_vlan_id = 0;
6171
6172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6173     {
6174       if (unformat (i, "sw_if_index %d", &sw_if_index))
6175         sw_if_index_set = 1;
6176       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6177         sw_if_index_set = 1;
6178       else if (unformat (i, "sub_id %d", &sub_id))
6179         sub_id_set = 1;
6180       else if (unformat (i, "outer_vlan_id %d", &tmp))
6181         outer_vlan_id = tmp;
6182       else if (unformat (i, "inner_vlan_id %d", &tmp))
6183         inner_vlan_id = tmp;
6184
6185 #define _(a) else if (unformat (i, #a)) a = 1 ;
6186       foreach_create_subif_bit
6187 #undef _
6188         else
6189         {
6190           clib_warning ("parse error '%U'", format_unformat_error, i);
6191           return -99;
6192         }
6193     }
6194
6195   if (sw_if_index_set == 0)
6196     {
6197       errmsg ("missing interface name or sw_if_index\n");
6198       return -99;
6199     }
6200
6201   if (sub_id_set == 0)
6202     {
6203       errmsg ("missing sub_id\n");
6204       return -99;
6205     }
6206   M (CREATE_SUBIF, create_subif);
6207
6208   mp->sw_if_index = ntohl (sw_if_index);
6209   mp->sub_id = ntohl (sub_id);
6210
6211 #define _(a) mp->a = a;
6212   foreach_create_subif_bit;
6213 #undef _
6214
6215   mp->outer_vlan_id = ntohs (outer_vlan_id);
6216   mp->inner_vlan_id = ntohs (inner_vlan_id);
6217
6218   S;
6219   W;
6220   /* NOTREACHED */
6221   return 0;
6222 }
6223
6224 static int
6225 api_oam_add_del (vat_main_t * vam)
6226 {
6227   unformat_input_t *i = vam->input;
6228   vl_api_oam_add_del_t *mp;
6229   f64 timeout;
6230   u32 vrf_id = 0;
6231   u8 is_add = 1;
6232   ip4_address_t src, dst;
6233   u8 src_set = 0;
6234   u8 dst_set = 0;
6235
6236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6237     {
6238       if (unformat (i, "vrf %d", &vrf_id))
6239         ;
6240       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6241         src_set = 1;
6242       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6243         dst_set = 1;
6244       else if (unformat (i, "del"))
6245         is_add = 0;
6246       else
6247         {
6248           clib_warning ("parse error '%U'", format_unformat_error, i);
6249           return -99;
6250         }
6251     }
6252
6253   if (src_set == 0)
6254     {
6255       errmsg ("missing src addr\n");
6256       return -99;
6257     }
6258
6259   if (dst_set == 0)
6260     {
6261       errmsg ("missing dst addr\n");
6262       return -99;
6263     }
6264
6265   M (OAM_ADD_DEL, oam_add_del);
6266
6267   mp->vrf_id = ntohl (vrf_id);
6268   mp->is_add = is_add;
6269   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6270   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6271
6272   S;
6273   W;
6274   /* NOTREACHED */
6275   return 0;
6276 }
6277
6278 static int
6279 api_reset_fib (vat_main_t * vam)
6280 {
6281   unformat_input_t *i = vam->input;
6282   vl_api_reset_fib_t *mp;
6283   f64 timeout;
6284   u32 vrf_id = 0;
6285   u8 is_ipv6 = 0;
6286   u8 vrf_id_set = 0;
6287
6288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6289     {
6290       if (unformat (i, "vrf %d", &vrf_id))
6291         vrf_id_set = 1;
6292       else if (unformat (i, "ipv6"))
6293         is_ipv6 = 1;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (vrf_id_set == 0)
6302     {
6303       errmsg ("missing vrf id\n");
6304       return -99;
6305     }
6306
6307   M (RESET_FIB, reset_fib);
6308
6309   mp->vrf_id = ntohl (vrf_id);
6310   mp->is_ipv6 = is_ipv6;
6311
6312   S;
6313   W;
6314   /* NOTREACHED */
6315   return 0;
6316 }
6317
6318 static int
6319 api_dhcp_proxy_config (vat_main_t * vam)
6320 {
6321   unformat_input_t *i = vam->input;
6322   vl_api_dhcp_proxy_config_t *mp;
6323   f64 timeout;
6324   u32 vrf_id = 0;
6325   u8 is_add = 1;
6326   u8 insert_cid = 1;
6327   u8 v4_address_set = 0;
6328   u8 v6_address_set = 0;
6329   ip4_address_t v4address;
6330   ip6_address_t v6address;
6331   u8 v4_src_address_set = 0;
6332   u8 v6_src_address_set = 0;
6333   ip4_address_t v4srcaddress;
6334   ip6_address_t v6srcaddress;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "del"))
6340         is_add = 0;
6341       else if (unformat (i, "vrf %d", &vrf_id))
6342         ;
6343       else if (unformat (i, "insert-cid %d", &insert_cid))
6344         ;
6345       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6346         v4_address_set = 1;
6347       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6348         v6_address_set = 1;
6349       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6350         v4_src_address_set = 1;
6351       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6352         v6_src_address_set = 1;
6353       else
6354         break;
6355     }
6356
6357   if (v4_address_set && v6_address_set)
6358     {
6359       errmsg ("both v4 and v6 server addresses set\n");
6360       return -99;
6361     }
6362   if (!v4_address_set && !v6_address_set)
6363     {
6364       errmsg ("no server addresses set\n");
6365       return -99;
6366     }
6367
6368   if (v4_src_address_set && v6_src_address_set)
6369     {
6370       errmsg ("both v4 and v6  src addresses set\n");
6371       return -99;
6372     }
6373   if (!v4_src_address_set && !v6_src_address_set)
6374     {
6375       errmsg ("no src addresses set\n");
6376       return -99;
6377     }
6378
6379   if (!(v4_src_address_set && v4_address_set) &&
6380       !(v6_src_address_set && v6_address_set))
6381     {
6382       errmsg ("no matching server and src addresses set\n");
6383       return -99;
6384     }
6385
6386   /* Construct the API message */
6387   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6388
6389   mp->insert_circuit_id = insert_cid;
6390   mp->is_add = is_add;
6391   mp->vrf_id = ntohl (vrf_id);
6392   if (v6_address_set)
6393     {
6394       mp->is_ipv6 = 1;
6395       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6396       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6397     }
6398   else
6399     {
6400       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6401       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6402     }
6403
6404   /* send it... */
6405   S;
6406
6407   /* Wait for a reply, return good/bad news  */
6408   W;
6409   /* NOTREACHED */
6410   return 0;
6411 }
6412
6413 static int
6414 api_dhcp_proxy_config_2 (vat_main_t * vam)
6415 {
6416   unformat_input_t *i = vam->input;
6417   vl_api_dhcp_proxy_config_2_t *mp;
6418   f64 timeout;
6419   u32 rx_vrf_id = 0;
6420   u32 server_vrf_id = 0;
6421   u8 is_add = 1;
6422   u8 insert_cid = 1;
6423   u8 v4_address_set = 0;
6424   u8 v6_address_set = 0;
6425   ip4_address_t v4address;
6426   ip6_address_t v6address;
6427   u8 v4_src_address_set = 0;
6428   u8 v6_src_address_set = 0;
6429   ip4_address_t v4srcaddress;
6430   ip6_address_t v6srcaddress;
6431
6432   /* Parse args required to build the message */
6433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6434     {
6435       if (unformat (i, "del"))
6436         is_add = 0;
6437       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6438         ;
6439       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6440         ;
6441       else if (unformat (i, "insert-cid %d", &insert_cid))
6442         ;
6443       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6444         v4_address_set = 1;
6445       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6446         v6_address_set = 1;
6447       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6448         v4_src_address_set = 1;
6449       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6450         v6_src_address_set = 1;
6451       else
6452         break;
6453     }
6454
6455   if (v4_address_set && v6_address_set)
6456     {
6457       errmsg ("both v4 and v6 server addresses set\n");
6458       return -99;
6459     }
6460   if (!v4_address_set && !v6_address_set)
6461     {
6462       errmsg ("no server addresses set\n");
6463       return -99;
6464     }
6465
6466   if (v4_src_address_set && v6_src_address_set)
6467     {
6468       errmsg ("both v4 and v6  src addresses set\n");
6469       return -99;
6470     }
6471   if (!v4_src_address_set && !v6_src_address_set)
6472     {
6473       errmsg ("no src addresses set\n");
6474       return -99;
6475     }
6476
6477   if (!(v4_src_address_set && v4_address_set) &&
6478       !(v6_src_address_set && v6_address_set))
6479     {
6480       errmsg ("no matching server and src addresses set\n");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6486
6487   mp->insert_circuit_id = insert_cid;
6488   mp->is_add = is_add;
6489   mp->rx_vrf_id = ntohl (rx_vrf_id);
6490   mp->server_vrf_id = ntohl (server_vrf_id);
6491   if (v6_address_set)
6492     {
6493       mp->is_ipv6 = 1;
6494       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6495       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6496     }
6497   else
6498     {
6499       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6500       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6501     }
6502
6503   /* send it... */
6504   S;
6505
6506   /* Wait for a reply, return good/bad news  */
6507   W;
6508   /* NOTREACHED */
6509   return 0;
6510 }
6511
6512 static int
6513 api_dhcp_proxy_set_vss (vat_main_t * vam)
6514 {
6515   unformat_input_t *i = vam->input;
6516   vl_api_dhcp_proxy_set_vss_t *mp;
6517   f64 timeout;
6518   u8 is_ipv6 = 0;
6519   u8 is_add = 1;
6520   u32 tbl_id;
6521   u8 tbl_id_set = 0;
6522   u32 oui;
6523   u8 oui_set = 0;
6524   u32 fib_id;
6525   u8 fib_id_set = 0;
6526
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "tbl_id %d", &tbl_id))
6530         tbl_id_set = 1;
6531       if (unformat (i, "fib_id %d", &fib_id))
6532         fib_id_set = 1;
6533       if (unformat (i, "oui %d", &oui))
6534         oui_set = 1;
6535       else if (unformat (i, "ipv6"))
6536         is_ipv6 = 1;
6537       else if (unformat (i, "del"))
6538         is_add = 0;
6539       else
6540         {
6541           clib_warning ("parse error '%U'", format_unformat_error, i);
6542           return -99;
6543         }
6544     }
6545
6546   if (tbl_id_set == 0)
6547     {
6548       errmsg ("missing tbl id\n");
6549       return -99;
6550     }
6551
6552   if (fib_id_set == 0)
6553     {
6554       errmsg ("missing fib id\n");
6555       return -99;
6556     }
6557   if (oui_set == 0)
6558     {
6559       errmsg ("missing oui\n");
6560       return -99;
6561     }
6562
6563   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6564   mp->tbl_id = ntohl (tbl_id);
6565   mp->fib_id = ntohl (fib_id);
6566   mp->oui = ntohl (oui);
6567   mp->is_ipv6 = is_ipv6;
6568   mp->is_add = is_add;
6569
6570   S;
6571   W;
6572   /* NOTREACHED */
6573   return 0;
6574 }
6575
6576 static int
6577 api_dhcp_client_config (vat_main_t * vam)
6578 {
6579   unformat_input_t *i = vam->input;
6580   vl_api_dhcp_client_config_t *mp;
6581   f64 timeout;
6582   u32 sw_if_index;
6583   u8 sw_if_index_set = 0;
6584   u8 is_add = 1;
6585   u8 *hostname = 0;
6586   u8 disable_event = 0;
6587
6588   /* Parse args required to build the message */
6589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6590     {
6591       if (unformat (i, "del"))
6592         is_add = 0;
6593       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "hostname %s", &hostname))
6598         ;
6599       else if (unformat (i, "disable_event"))
6600         disable_event = 1;
6601       else
6602         break;
6603     }
6604
6605   if (sw_if_index_set == 0)
6606     {
6607       errmsg ("missing interface name or sw_if_index\n");
6608       return -99;
6609     }
6610
6611   if (vec_len (hostname) > 63)
6612     {
6613       errmsg ("hostname too long\n");
6614     }
6615   vec_add1 (hostname, 0);
6616
6617   /* Construct the API message */
6618   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6619
6620   mp->sw_if_index = ntohl (sw_if_index);
6621   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6622   vec_free (hostname);
6623   mp->is_add = is_add;
6624   mp->want_dhcp_event = disable_event ? 0 : 1;
6625   mp->pid = getpid ();
6626
6627   /* send it... */
6628   S;
6629
6630   /* Wait for a reply, return good/bad news  */
6631   W;
6632   /* NOTREACHED */
6633   return 0;
6634 }
6635
6636 static int
6637 api_set_ip_flow_hash (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_set_ip_flow_hash_t *mp;
6641   f64 timeout;
6642   u32 vrf_id = 0;
6643   u8 is_ipv6 = 0;
6644   u8 vrf_id_set = 0;
6645   u8 src = 0;
6646   u8 dst = 0;
6647   u8 sport = 0;
6648   u8 dport = 0;
6649   u8 proto = 0;
6650   u8 reverse = 0;
6651
6652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6653     {
6654       if (unformat (i, "vrf %d", &vrf_id))
6655         vrf_id_set = 1;
6656       else if (unformat (i, "ipv6"))
6657         is_ipv6 = 1;
6658       else if (unformat (i, "src"))
6659         src = 1;
6660       else if (unformat (i, "dst"))
6661         dst = 1;
6662       else if (unformat (i, "sport"))
6663         sport = 1;
6664       else if (unformat (i, "dport"))
6665         dport = 1;
6666       else if (unformat (i, "proto"))
6667         proto = 1;
6668       else if (unformat (i, "reverse"))
6669         reverse = 1;
6670
6671       else
6672         {
6673           clib_warning ("parse error '%U'", format_unformat_error, i);
6674           return -99;
6675         }
6676     }
6677
6678   if (vrf_id_set == 0)
6679     {
6680       errmsg ("missing vrf id\n");
6681       return -99;
6682     }
6683
6684   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6685   mp->src = src;
6686   mp->dst = dst;
6687   mp->sport = sport;
6688   mp->dport = dport;
6689   mp->proto = proto;
6690   mp->reverse = reverse;
6691   mp->vrf_id = ntohl (vrf_id);
6692   mp->is_ipv6 = is_ipv6;
6693
6694   S;
6695   W;
6696   /* NOTREACHED */
6697   return 0;
6698 }
6699
6700 static int
6701 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_ip6_enable_disable_t *mp;
6705   f64 timeout;
6706   u32 sw_if_index;
6707   u8 sw_if_index_set = 0;
6708   u8 enable = 0;
6709
6710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6711     {
6712       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "enable"))
6717         enable = 1;
6718       else if (unformat (i, "disable"))
6719         enable = 0;
6720       else
6721         {
6722           clib_warning ("parse error '%U'", format_unformat_error, i);
6723           return -99;
6724         }
6725     }
6726
6727   if (sw_if_index_set == 0)
6728     {
6729       errmsg ("missing interface name or sw_if_index\n");
6730       return -99;
6731     }
6732
6733   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6734
6735   mp->sw_if_index = ntohl (sw_if_index);
6736   mp->enable = enable;
6737
6738   S;
6739   W;
6740   /* NOTREACHED */
6741   return 0;
6742 }
6743
6744 static int
6745 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6749   f64 timeout;
6750   u32 sw_if_index;
6751   u8 sw_if_index_set = 0;
6752   u32 address_length = 0;
6753   u8 v6_address_set = 0;
6754   ip6_address_t v6address;
6755
6756   /* Parse args required to build the message */
6757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6758     {
6759       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6762         sw_if_index_set = 1;
6763       else if (unformat (i, "%U/%d",
6764                          unformat_ip6_address, &v6address, &address_length))
6765         v6_address_set = 1;
6766       else
6767         break;
6768     }
6769
6770   if (sw_if_index_set == 0)
6771     {
6772       errmsg ("missing interface name or sw_if_index\n");
6773       return -99;
6774     }
6775   if (!v6_address_set)
6776     {
6777       errmsg ("no address set\n");
6778       return -99;
6779     }
6780
6781   /* Construct the API message */
6782   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6783      sw_interface_ip6_set_link_local_address);
6784
6785   mp->sw_if_index = ntohl (sw_if_index);
6786   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6787   mp->address_length = address_length;
6788
6789   /* send it... */
6790   S;
6791
6792   /* Wait for a reply, return good/bad news  */
6793   W;
6794
6795   /* NOTREACHED */
6796   return 0;
6797 }
6798
6799
6800 static int
6801 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6802 {
6803   unformat_input_t *i = vam->input;
6804   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6805   f64 timeout;
6806   u32 sw_if_index;
6807   u8 sw_if_index_set = 0;
6808   u32 address_length = 0;
6809   u8 v6_address_set = 0;
6810   ip6_address_t v6address;
6811   u8 use_default = 0;
6812   u8 no_advertise = 0;
6813   u8 off_link = 0;
6814   u8 no_autoconfig = 0;
6815   u8 no_onlink = 0;
6816   u8 is_no = 0;
6817   u32 val_lifetime = 0;
6818   u32 pref_lifetime = 0;
6819
6820   /* Parse args required to build the message */
6821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6822     {
6823       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6824         sw_if_index_set = 1;
6825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "%U/%d",
6828                          unformat_ip6_address, &v6address, &address_length))
6829         v6_address_set = 1;
6830       else if (unformat (i, "val_life %d", &val_lifetime))
6831         ;
6832       else if (unformat (i, "pref_life %d", &pref_lifetime))
6833         ;
6834       else if (unformat (i, "def"))
6835         use_default = 1;
6836       else if (unformat (i, "noadv"))
6837         no_advertise = 1;
6838       else if (unformat (i, "offl"))
6839         off_link = 1;
6840       else if (unformat (i, "noauto"))
6841         no_autoconfig = 1;
6842       else if (unformat (i, "nolink"))
6843         no_onlink = 1;
6844       else if (unformat (i, "isno"))
6845         is_no = 1;
6846       else
6847         {
6848           clib_warning ("parse error '%U'", format_unformat_error, i);
6849           return -99;
6850         }
6851     }
6852
6853   if (sw_if_index_set == 0)
6854     {
6855       errmsg ("missing interface name or sw_if_index\n");
6856       return -99;
6857     }
6858   if (!v6_address_set)
6859     {
6860       errmsg ("no address set\n");
6861       return -99;
6862     }
6863
6864   /* Construct the API message */
6865   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6866
6867   mp->sw_if_index = ntohl (sw_if_index);
6868   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6869   mp->address_length = address_length;
6870   mp->use_default = use_default;
6871   mp->no_advertise = no_advertise;
6872   mp->off_link = off_link;
6873   mp->no_autoconfig = no_autoconfig;
6874   mp->no_onlink = no_onlink;
6875   mp->is_no = is_no;
6876   mp->val_lifetime = ntohl (val_lifetime);
6877   mp->pref_lifetime = ntohl (pref_lifetime);
6878
6879   /* send it... */
6880   S;
6881
6882   /* Wait for a reply, return good/bad news  */
6883   W;
6884
6885   /* NOTREACHED */
6886   return 0;
6887 }
6888
6889 static int
6890 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6894   f64 timeout;
6895   u32 sw_if_index;
6896   u8 sw_if_index_set = 0;
6897   u8 suppress = 0;
6898   u8 managed = 0;
6899   u8 other = 0;
6900   u8 ll_option = 0;
6901   u8 send_unicast = 0;
6902   u8 cease = 0;
6903   u8 is_no = 0;
6904   u8 default_router = 0;
6905   u32 max_interval = 0;
6906   u32 min_interval = 0;
6907   u32 lifetime = 0;
6908   u32 initial_count = 0;
6909   u32 initial_interval = 0;
6910
6911
6912   /* Parse args required to build the message */
6913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6914     {
6915       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6916         sw_if_index_set = 1;
6917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6918         sw_if_index_set = 1;
6919       else if (unformat (i, "maxint %d", &max_interval))
6920         ;
6921       else if (unformat (i, "minint %d", &min_interval))
6922         ;
6923       else if (unformat (i, "life %d", &lifetime))
6924         ;
6925       else if (unformat (i, "count %d", &initial_count))
6926         ;
6927       else if (unformat (i, "interval %d", &initial_interval))
6928         ;
6929       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6930         suppress = 1;
6931       else if (unformat (i, "managed"))
6932         managed = 1;
6933       else if (unformat (i, "other"))
6934         other = 1;
6935       else if (unformat (i, "ll"))
6936         ll_option = 1;
6937       else if (unformat (i, "send"))
6938         send_unicast = 1;
6939       else if (unformat (i, "cease"))
6940         cease = 1;
6941       else if (unformat (i, "isno"))
6942         is_no = 1;
6943       else if (unformat (i, "def"))
6944         default_router = 1;
6945       else
6946         {
6947           clib_warning ("parse error '%U'", format_unformat_error, i);
6948           return -99;
6949         }
6950     }
6951
6952   if (sw_if_index_set == 0)
6953     {
6954       errmsg ("missing interface name or sw_if_index\n");
6955       return -99;
6956     }
6957
6958   /* Construct the API message */
6959   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6960
6961   mp->sw_if_index = ntohl (sw_if_index);
6962   mp->max_interval = ntohl (max_interval);
6963   mp->min_interval = ntohl (min_interval);
6964   mp->lifetime = ntohl (lifetime);
6965   mp->initial_count = ntohl (initial_count);
6966   mp->initial_interval = ntohl (initial_interval);
6967   mp->suppress = suppress;
6968   mp->managed = managed;
6969   mp->other = other;
6970   mp->ll_option = ll_option;
6971   mp->send_unicast = send_unicast;
6972   mp->cease = cease;
6973   mp->is_no = is_no;
6974   mp->default_router = default_router;
6975
6976   /* send it... */
6977   S;
6978
6979   /* Wait for a reply, return good/bad news  */
6980   W;
6981
6982   /* NOTREACHED */
6983   return 0;
6984 }
6985
6986 static int
6987 api_set_arp_neighbor_limit (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_set_arp_neighbor_limit_t *mp;
6991   f64 timeout;
6992   u32 arp_nbr_limit;
6993   u8 limit_set = 0;
6994   u8 is_ipv6 = 0;
6995
6996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6997     {
6998       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6999         limit_set = 1;
7000       else if (unformat (i, "ipv6"))
7001         is_ipv6 = 1;
7002       else
7003         {
7004           clib_warning ("parse error '%U'", format_unformat_error, i);
7005           return -99;
7006         }
7007     }
7008
7009   if (limit_set == 0)
7010     {
7011       errmsg ("missing limit value\n");
7012       return -99;
7013     }
7014
7015   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7016
7017   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7018   mp->is_ipv6 = is_ipv6;
7019
7020   S;
7021   W;
7022   /* NOTREACHED */
7023   return 0;
7024 }
7025
7026 static int
7027 api_l2_patch_add_del (vat_main_t * vam)
7028 {
7029   unformat_input_t *i = vam->input;
7030   vl_api_l2_patch_add_del_t *mp;
7031   f64 timeout;
7032   u32 rx_sw_if_index;
7033   u8 rx_sw_if_index_set = 0;
7034   u32 tx_sw_if_index;
7035   u8 tx_sw_if_index_set = 0;
7036   u8 is_add = 1;
7037
7038   /* Parse args required to build the message */
7039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7040     {
7041       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7042         rx_sw_if_index_set = 1;
7043       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7044         tx_sw_if_index_set = 1;
7045       else if (unformat (i, "rx"))
7046         {
7047           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048             {
7049               if (unformat (i, "%U", unformat_sw_if_index, vam,
7050                             &rx_sw_if_index))
7051                 rx_sw_if_index_set = 1;
7052             }
7053           else
7054             break;
7055         }
7056       else if (unformat (i, "tx"))
7057         {
7058           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059             {
7060               if (unformat (i, "%U", unformat_sw_if_index, vam,
7061                             &tx_sw_if_index))
7062                 tx_sw_if_index_set = 1;
7063             }
7064           else
7065             break;
7066         }
7067       else if (unformat (i, "del"))
7068         is_add = 0;
7069       else
7070         break;
7071     }
7072
7073   if (rx_sw_if_index_set == 0)
7074     {
7075       errmsg ("missing rx interface name or rx_sw_if_index\n");
7076       return -99;
7077     }
7078
7079   if (tx_sw_if_index_set == 0)
7080     {
7081       errmsg ("missing tx interface name or tx_sw_if_index\n");
7082       return -99;
7083     }
7084
7085   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7086
7087   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7088   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7089   mp->is_add = is_add;
7090
7091   S;
7092   W;
7093   /* NOTREACHED */
7094   return 0;
7095 }
7096
7097 static int
7098 api_trace_profile_add (vat_main_t * vam)
7099 {
7100   unformat_input_t *input = vam->input;
7101   vl_api_trace_profile_add_t *mp;
7102   f64 timeout;
7103   u32 id = 0;
7104   u32 trace_option_elts = 0;
7105   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7106   int has_pow_option = 0;
7107   int has_ppc_option = 0;
7108
7109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7110     {
7111       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7112                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7113                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7114                     &node_id, &app_data))
7115         ;
7116       else if (unformat (input, "pow"))
7117         has_pow_option = 1;
7118       else if (unformat (input, "ppc encap"))
7119         has_ppc_option = PPC_ENCAP;
7120       else if (unformat (input, "ppc decap"))
7121         has_ppc_option = PPC_DECAP;
7122       else if (unformat (input, "ppc none"))
7123         has_ppc_option = PPC_NONE;
7124       else
7125         break;
7126     }
7127   M (TRACE_PROFILE_ADD, trace_profile_add);
7128   mp->id = htons (id);
7129   mp->trace_type = trace_type;
7130   mp->trace_num_elt = trace_option_elts;
7131   mp->trace_ppc = has_ppc_option;
7132   mp->trace_app_data = htonl (app_data);
7133   mp->pow_enable = has_pow_option;
7134   mp->trace_tsp = trace_tsp;
7135   mp->node_id = htonl (node_id);
7136
7137   S;
7138   W;
7139
7140   return (0);
7141
7142 }
7143
7144 static int
7145 api_trace_profile_apply (vat_main_t * vam)
7146 {
7147   unformat_input_t *input = vam->input;
7148   vl_api_trace_profile_apply_t *mp;
7149   f64 timeout;
7150   ip6_address_t addr;
7151   u32 mask_width = ~0;
7152   int is_add = 0;
7153   int is_pop = 0;
7154   int is_none = 0;
7155   u32 vrf_id = 0;
7156   u32 id = 0;
7157
7158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7159     {
7160       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7161         ;
7162       else if (unformat (input, "id %d", &id))
7163         ;
7164       else if (unformat (input, "vrf-id %d", &vrf_id))
7165         ;
7166       else if (unformat (input, "add"))
7167         is_add = 1;
7168       else if (unformat (input, "pop"))
7169         is_pop = 1;
7170       else if (unformat (input, "none"))
7171         is_none = 1;
7172       else
7173         break;
7174     }
7175
7176   if ((is_add + is_pop + is_none) != 1)
7177     {
7178       errmsg ("One of (add, pop, none) required");
7179       return -99;
7180     }
7181   if (mask_width == ~0)
7182     {
7183       errmsg ("<address>/<mask-width> required");
7184       return -99;
7185     }
7186   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7187   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7188   mp->id = htons (id);
7189   mp->prefix_length = htonl (mask_width);
7190   mp->vrf_id = htonl (vrf_id);
7191   if (is_add)
7192     mp->trace_op = IOAM_HBYH_ADD;
7193   else if (is_pop)
7194     mp->trace_op = IOAM_HBYH_POP;
7195   else
7196     mp->trace_op = IOAM_HBYH_MOD;
7197
7198   if (is_none)
7199     mp->enable = 0;
7200   else
7201     mp->enable = 1;
7202
7203   S;
7204   W;
7205
7206   return 0;
7207 }
7208
7209 static int
7210 api_trace_profile_del (vat_main_t * vam)
7211 {
7212   vl_api_trace_profile_del_t *mp;
7213   f64 timeout;
7214
7215   M (TRACE_PROFILE_DEL, trace_profile_del);
7216   S;
7217   W;
7218   return 0;
7219 }
7220
7221 static int
7222 api_sr_tunnel_add_del (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_sr_tunnel_add_del_t *mp;
7226   f64 timeout;
7227   int is_del = 0;
7228   int pl_index;
7229   ip6_address_t src_address;
7230   int src_address_set = 0;
7231   ip6_address_t dst_address;
7232   u32 dst_mask_width;
7233   int dst_address_set = 0;
7234   u16 flags = 0;
7235   u32 rx_table_id = 0;
7236   u32 tx_table_id = 0;
7237   ip6_address_t *segments = 0;
7238   ip6_address_t *this_seg;
7239   ip6_address_t *tags = 0;
7240   ip6_address_t *this_tag;
7241   ip6_address_t next_address, tag;
7242   u8 *name = 0;
7243   u8 *policy_name = 0;
7244
7245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7246     {
7247       if (unformat (i, "del"))
7248         is_del = 1;
7249       else if (unformat (i, "name %s", &name))
7250         ;
7251       else if (unformat (i, "policy %s", &policy_name))
7252         ;
7253       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7254         ;
7255       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7256         ;
7257       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7258         src_address_set = 1;
7259       else if (unformat (i, "dst %U/%d",
7260                          unformat_ip6_address, &dst_address, &dst_mask_width))
7261         dst_address_set = 1;
7262       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7263         {
7264           vec_add2 (segments, this_seg, 1);
7265           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7266                        sizeof (*this_seg));
7267         }
7268       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7269         {
7270           vec_add2 (tags, this_tag, 1);
7271           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7272         }
7273       else if (unformat (i, "clean"))
7274         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7275       else if (unformat (i, "protected"))
7276         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7277       else if (unformat (i, "InPE %d", &pl_index))
7278         {
7279           if (pl_index <= 0 || pl_index > 4)
7280             {
7281             pl_index_range_error:
7282               errmsg ("pl index %d out of range\n", pl_index);
7283               return -99;
7284             }
7285           flags |=
7286             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7287         }
7288       else if (unformat (i, "EgPE %d", &pl_index))
7289         {
7290           if (pl_index <= 0 || pl_index > 4)
7291             goto pl_index_range_error;
7292           flags |=
7293             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7294         }
7295       else if (unformat (i, "OrgSrc %d", &pl_index))
7296         {
7297           if (pl_index <= 0 || pl_index > 4)
7298             goto pl_index_range_error;
7299           flags |=
7300             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7301         }
7302       else
7303         break;
7304     }
7305
7306   if (!src_address_set)
7307     {
7308       errmsg ("src address required\n");
7309       return -99;
7310     }
7311
7312   if (!dst_address_set)
7313     {
7314       errmsg ("dst address required\n");
7315       return -99;
7316     }
7317
7318   if (!segments)
7319     {
7320       errmsg ("at least one sr segment required\n");
7321       return -99;
7322     }
7323
7324   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7325       vec_len (segments) * sizeof (ip6_address_t)
7326       + vec_len (tags) * sizeof (ip6_address_t));
7327
7328   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7329   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7330   mp->dst_mask_width = dst_mask_width;
7331   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7332   mp->n_segments = vec_len (segments);
7333   mp->n_tags = vec_len (tags);
7334   mp->is_add = is_del == 0;
7335   clib_memcpy (mp->segs_and_tags, segments,
7336                vec_len (segments) * sizeof (ip6_address_t));
7337   clib_memcpy (mp->segs_and_tags +
7338                vec_len (segments) * sizeof (ip6_address_t), tags,
7339                vec_len (tags) * sizeof (ip6_address_t));
7340
7341   mp->outer_vrf_id = ntohl (rx_table_id);
7342   mp->inner_vrf_id = ntohl (tx_table_id);
7343   memcpy (mp->name, name, vec_len (name));
7344   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7345
7346   vec_free (segments);
7347   vec_free (tags);
7348
7349   S;
7350   W;
7351   /* NOTREACHED */
7352 }
7353
7354 static int
7355 api_sr_policy_add_del (vat_main_t * vam)
7356 {
7357   unformat_input_t *input = vam->input;
7358   vl_api_sr_policy_add_del_t *mp;
7359   f64 timeout;
7360   int is_del = 0;
7361   u8 *name = 0;
7362   u8 *tunnel_name = 0;
7363   u8 **tunnel_names = 0;
7364
7365   int name_set = 0;
7366   int tunnel_set = 0;
7367   int j = 0;
7368   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7369   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7370
7371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (input, "del"))
7374         is_del = 1;
7375       else if (unformat (input, "name %s", &name))
7376         name_set = 1;
7377       else if (unformat (input, "tunnel %s", &tunnel_name))
7378         {
7379           if (tunnel_name)
7380             {
7381               vec_add1 (tunnel_names, tunnel_name);
7382               /* For serializer:
7383                  - length = #bytes to store in serial vector
7384                  - +1 = byte to store that length
7385                */
7386               tunnel_names_length += (vec_len (tunnel_name) + 1);
7387               tunnel_set = 1;
7388               tunnel_name = 0;
7389             }
7390         }
7391       else
7392         break;
7393     }
7394
7395   if (!name_set)
7396     {
7397       errmsg ("policy name required\n");
7398       return -99;
7399     }
7400
7401   if ((!tunnel_set) && (!is_del))
7402     {
7403       errmsg ("tunnel name required\n");
7404       return -99;
7405     }
7406
7407   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7408
7409
7410
7411   mp->is_add = !is_del;
7412
7413   memcpy (mp->name, name, vec_len (name));
7414   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7415   u8 *serial_orig = 0;
7416   vec_validate (serial_orig, tunnel_names_length);
7417   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7418   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7419
7420   for (j = 0; j < vec_len (tunnel_names); j++)
7421     {
7422       tun_name_len = vec_len (tunnel_names[j]);
7423       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7424       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7425       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7426       serial_orig += tun_name_len;      // Advance past the copy
7427     }
7428   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7429
7430   vec_free (tunnel_names);
7431   vec_free (tunnel_name);
7432
7433   S;
7434   W;
7435   /* NOTREACHED */
7436 }
7437
7438 static int
7439 api_sr_multicast_map_add_del (vat_main_t * vam)
7440 {
7441   unformat_input_t *input = vam->input;
7442   vl_api_sr_multicast_map_add_del_t *mp;
7443   f64 timeout;
7444   int is_del = 0;
7445   ip6_address_t multicast_address;
7446   u8 *policy_name = 0;
7447   int multicast_address_set = 0;
7448
7449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (input, "del"))
7452         is_del = 1;
7453       else
7454         if (unformat
7455             (input, "address %U", unformat_ip6_address, &multicast_address))
7456         multicast_address_set = 1;
7457       else if (unformat (input, "sr-policy %s", &policy_name))
7458         ;
7459       else
7460         break;
7461     }
7462
7463   if (!is_del && !policy_name)
7464     {
7465       errmsg ("sr-policy name required\n");
7466       return -99;
7467     }
7468
7469
7470   if (!multicast_address_set)
7471     {
7472       errmsg ("address required\n");
7473       return -99;
7474     }
7475
7476   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7477
7478   mp->is_add = !is_del;
7479   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7480   clib_memcpy (mp->multicast_address, &multicast_address,
7481                sizeof (mp->multicast_address));
7482
7483
7484   vec_free (policy_name);
7485
7486   S;
7487   W;
7488   /* NOTREACHED */
7489 }
7490
7491
7492 #define foreach_ip4_proto_field                 \
7493 _(src_address)                                  \
7494 _(dst_address)                                  \
7495 _(tos)                                          \
7496 _(length)                                       \
7497 _(fragment_id)                                  \
7498 _(ttl)                                          \
7499 _(protocol)                                     \
7500 _(checksum)
7501
7502 uword
7503 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7504 {
7505   u8 **maskp = va_arg (*args, u8 **);
7506   u8 *mask = 0;
7507   u8 found_something = 0;
7508   ip4_header_t *ip;
7509
7510 #define _(a) u8 a=0;
7511   foreach_ip4_proto_field;
7512 #undef _
7513   u8 version = 0;
7514   u8 hdr_length = 0;
7515
7516
7517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (input, "version"))
7520         version = 1;
7521       else if (unformat (input, "hdr_length"))
7522         hdr_length = 1;
7523       else if (unformat (input, "src"))
7524         src_address = 1;
7525       else if (unformat (input, "dst"))
7526         dst_address = 1;
7527       else if (unformat (input, "proto"))
7528         protocol = 1;
7529
7530 #define _(a) else if (unformat (input, #a)) a=1;
7531       foreach_ip4_proto_field
7532 #undef _
7533         else
7534         break;
7535     }
7536
7537 #define _(a) found_something += a;
7538   foreach_ip4_proto_field;
7539 #undef _
7540
7541   if (found_something == 0)
7542     return 0;
7543
7544   vec_validate (mask, sizeof (*ip) - 1);
7545
7546   ip = (ip4_header_t *) mask;
7547
7548 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7549   foreach_ip4_proto_field;
7550 #undef _
7551
7552   ip->ip_version_and_header_length = 0;
7553
7554   if (version)
7555     ip->ip_version_and_header_length |= 0xF0;
7556
7557   if (hdr_length)
7558     ip->ip_version_and_header_length |= 0x0F;
7559
7560   *maskp = mask;
7561   return 1;
7562 }
7563
7564 #define foreach_ip6_proto_field                 \
7565 _(src_address)                                  \
7566 _(dst_address)                                  \
7567 _(payload_length)                               \
7568 _(hop_limit)                                    \
7569 _(protocol)
7570
7571 uword
7572 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7573 {
7574   u8 **maskp = va_arg (*args, u8 **);
7575   u8 *mask = 0;
7576   u8 found_something = 0;
7577   ip6_header_t *ip;
7578   u32 ip_version_traffic_class_and_flow_label;
7579
7580 #define _(a) u8 a=0;
7581   foreach_ip6_proto_field;
7582 #undef _
7583   u8 version = 0;
7584   u8 traffic_class = 0;
7585   u8 flow_label = 0;
7586
7587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (input, "version"))
7590         version = 1;
7591       else if (unformat (input, "traffic-class"))
7592         traffic_class = 1;
7593       else if (unformat (input, "flow-label"))
7594         flow_label = 1;
7595       else if (unformat (input, "src"))
7596         src_address = 1;
7597       else if (unformat (input, "dst"))
7598         dst_address = 1;
7599       else if (unformat (input, "proto"))
7600         protocol = 1;
7601
7602 #define _(a) else if (unformat (input, #a)) a=1;
7603       foreach_ip6_proto_field
7604 #undef _
7605         else
7606         break;
7607     }
7608
7609 #define _(a) found_something += a;
7610   foreach_ip6_proto_field;
7611 #undef _
7612
7613   if (found_something == 0)
7614     return 0;
7615
7616   vec_validate (mask, sizeof (*ip) - 1);
7617
7618   ip = (ip6_header_t *) mask;
7619
7620 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7621   foreach_ip6_proto_field;
7622 #undef _
7623
7624   ip_version_traffic_class_and_flow_label = 0;
7625
7626   if (version)
7627     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7628
7629   if (traffic_class)
7630     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7631
7632   if (flow_label)
7633     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7634
7635   ip->ip_version_traffic_class_and_flow_label =
7636     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7637
7638   *maskp = mask;
7639   return 1;
7640 }
7641
7642 uword
7643 unformat_l3_mask (unformat_input_t * input, va_list * args)
7644 {
7645   u8 **maskp = va_arg (*args, u8 **);
7646
7647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7648     {
7649       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7650         return 1;
7651       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7652         return 1;
7653       else
7654         break;
7655     }
7656   return 0;
7657 }
7658
7659 uword
7660 unformat_l2_mask (unformat_input_t * input, va_list * args)
7661 {
7662   u8 **maskp = va_arg (*args, u8 **);
7663   u8 *mask = 0;
7664   u8 src = 0;
7665   u8 dst = 0;
7666   u8 proto = 0;
7667   u8 tag1 = 0;
7668   u8 tag2 = 0;
7669   u8 ignore_tag1 = 0;
7670   u8 ignore_tag2 = 0;
7671   u8 cos1 = 0;
7672   u8 cos2 = 0;
7673   u8 dot1q = 0;
7674   u8 dot1ad = 0;
7675   int len = 14;
7676
7677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (input, "src"))
7680         src = 1;
7681       else if (unformat (input, "dst"))
7682         dst = 1;
7683       else if (unformat (input, "proto"))
7684         proto = 1;
7685       else if (unformat (input, "tag1"))
7686         tag1 = 1;
7687       else if (unformat (input, "tag2"))
7688         tag2 = 1;
7689       else if (unformat (input, "ignore-tag1"))
7690         ignore_tag1 = 1;
7691       else if (unformat (input, "ignore-tag2"))
7692         ignore_tag2 = 1;
7693       else if (unformat (input, "cos1"))
7694         cos1 = 1;
7695       else if (unformat (input, "cos2"))
7696         cos2 = 1;
7697       else if (unformat (input, "dot1q"))
7698         dot1q = 1;
7699       else if (unformat (input, "dot1ad"))
7700         dot1ad = 1;
7701       else
7702         break;
7703     }
7704   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7705        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7706     return 0;
7707
7708   if (tag1 || ignore_tag1 || cos1 || dot1q)
7709     len = 18;
7710   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7711     len = 22;
7712
7713   vec_validate (mask, len - 1);
7714
7715   if (dst)
7716     memset (mask, 0xff, 6);
7717
7718   if (src)
7719     memset (mask + 6, 0xff, 6);
7720
7721   if (tag2 || dot1ad)
7722     {
7723       /* inner vlan tag */
7724       if (tag2)
7725         {
7726           mask[19] = 0xff;
7727           mask[18] = 0x0f;
7728         }
7729       if (cos2)
7730         mask[18] |= 0xe0;
7731       if (proto)
7732         mask[21] = mask[20] = 0xff;
7733       if (tag1)
7734         {
7735           mask[15] = 0xff;
7736           mask[14] = 0x0f;
7737         }
7738       if (cos1)
7739         mask[14] |= 0xe0;
7740       *maskp = mask;
7741       return 1;
7742     }
7743   if (tag1 | dot1q)
7744     {
7745       if (tag1)
7746         {
7747           mask[15] = 0xff;
7748           mask[14] = 0x0f;
7749         }
7750       if (cos1)
7751         mask[14] |= 0xe0;
7752       if (proto)
7753         mask[16] = mask[17] = 0xff;
7754
7755       *maskp = mask;
7756       return 1;
7757     }
7758   if (cos2)
7759     mask[18] |= 0xe0;
7760   if (cos1)
7761     mask[14] |= 0xe0;
7762   if (proto)
7763     mask[12] = mask[13] = 0xff;
7764
7765   *maskp = mask;
7766   return 1;
7767 }
7768
7769 uword
7770 unformat_classify_mask (unformat_input_t * input, va_list * args)
7771 {
7772   u8 **maskp = va_arg (*args, u8 **);
7773   u32 *skipp = va_arg (*args, u32 *);
7774   u32 *matchp = va_arg (*args, u32 *);
7775   u32 match;
7776   u8 *mask = 0;
7777   u8 *l2 = 0;
7778   u8 *l3 = 0;
7779   int i;
7780
7781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7782     {
7783       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7784         ;
7785       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7786         ;
7787       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7788         ;
7789       else
7790         break;
7791     }
7792
7793   if (mask || l2 || l3)
7794     {
7795       if (l2 || l3)
7796         {
7797           /* "With a free Ethernet header in every package" */
7798           if (l2 == 0)
7799             vec_validate (l2, 13);
7800           mask = l2;
7801           if (vec_len (l3))
7802             {
7803               vec_append (mask, l3);
7804               vec_free (l3);
7805             }
7806         }
7807
7808       /* Scan forward looking for the first significant mask octet */
7809       for (i = 0; i < vec_len (mask); i++)
7810         if (mask[i])
7811           break;
7812
7813       /* compute (skip, match) params */
7814       *skipp = i / sizeof (u32x4);
7815       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7816
7817       /* Pad mask to an even multiple of the vector size */
7818       while (vec_len (mask) % sizeof (u32x4))
7819         vec_add1 (mask, 0);
7820
7821       match = vec_len (mask) / sizeof (u32x4);
7822
7823       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7824         {
7825           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7826           if (*tmp || *(tmp + 1))
7827             break;
7828           match--;
7829         }
7830       if (match == 0)
7831         clib_warning ("BUG: match 0");
7832
7833       _vec_len (mask) = match * sizeof (u32x4);
7834
7835       *matchp = match;
7836       *maskp = mask;
7837
7838       return 1;
7839     }
7840
7841   return 0;
7842 }
7843
7844 #define foreach_l2_next                         \
7845 _(drop, DROP)                                   \
7846 _(ethernet, ETHERNET_INPUT)                     \
7847 _(ip4, IP4_INPUT)                               \
7848 _(ip6, IP6_INPUT)
7849
7850 uword
7851 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7852 {
7853   u32 *miss_next_indexp = va_arg (*args, u32 *);
7854   u32 next_index = 0;
7855   u32 tmp;
7856
7857 #define _(n,N) \
7858   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7859   foreach_l2_next;
7860 #undef _
7861
7862   if (unformat (input, "%d", &tmp))
7863     {
7864       next_index = tmp;
7865       goto out;
7866     }
7867
7868   return 0;
7869
7870 out:
7871   *miss_next_indexp = next_index;
7872   return 1;
7873 }
7874
7875 #define foreach_ip_next                         \
7876 _(miss, MISS)                                   \
7877 _(drop, DROP)                                   \
7878 _(local, LOCAL)                                 \
7879 _(rewrite, REWRITE)
7880
7881 uword
7882 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7883 {
7884   u32 *miss_next_indexp = va_arg (*args, u32 *);
7885   u32 next_index = 0;
7886   u32 tmp;
7887
7888 #define _(n,N) \
7889   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7890   foreach_ip_next;
7891 #undef _
7892
7893   if (unformat (input, "%d", &tmp))
7894     {
7895       next_index = tmp;
7896       goto out;
7897     }
7898
7899   return 0;
7900
7901 out:
7902   *miss_next_indexp = next_index;
7903   return 1;
7904 }
7905
7906 #define foreach_acl_next                        \
7907 _(deny, DENY)
7908
7909 uword
7910 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7911 {
7912   u32 *miss_next_indexp = va_arg (*args, u32 *);
7913   u32 next_index = 0;
7914   u32 tmp;
7915
7916 #define _(n,N) \
7917   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7918   foreach_acl_next;
7919 #undef _
7920
7921   if (unformat (input, "permit"))
7922     {
7923       next_index = ~0;
7924       goto out;
7925     }
7926   else if (unformat (input, "%d", &tmp))
7927     {
7928       next_index = tmp;
7929       goto out;
7930     }
7931
7932   return 0;
7933
7934 out:
7935   *miss_next_indexp = next_index;
7936   return 1;
7937 }
7938
7939 uword
7940 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7941 {
7942   u32 *r = va_arg (*args, u32 *);
7943
7944   if (unformat (input, "conform-color"))
7945     *r = POLICE_CONFORM;
7946   else if (unformat (input, "exceed-color"))
7947     *r = POLICE_EXCEED;
7948   else
7949     return 0;
7950
7951   return 1;
7952 }
7953
7954 static int
7955 api_classify_add_del_table (vat_main_t * vam)
7956 {
7957   unformat_input_t *i = vam->input;
7958   vl_api_classify_add_del_table_t *mp;
7959
7960   u32 nbuckets = 2;
7961   u32 skip = ~0;
7962   u32 match = ~0;
7963   int is_add = 1;
7964   u32 table_index = ~0;
7965   u32 next_table_index = ~0;
7966   u32 miss_next_index = ~0;
7967   u32 memory_size = 32 << 20;
7968   u8 *mask = 0;
7969   f64 timeout;
7970
7971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7972     {
7973       if (unformat (i, "del"))
7974         is_add = 0;
7975       else if (unformat (i, "buckets %d", &nbuckets))
7976         ;
7977       else if (unformat (i, "memory_size %d", &memory_size))
7978         ;
7979       else if (unformat (i, "skip %d", &skip))
7980         ;
7981       else if (unformat (i, "match %d", &match))
7982         ;
7983       else if (unformat (i, "table %d", &table_index))
7984         ;
7985       else if (unformat (i, "mask %U", unformat_classify_mask,
7986                          &mask, &skip, &match))
7987         ;
7988       else if (unformat (i, "next-table %d", &next_table_index))
7989         ;
7990       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7991                          &miss_next_index))
7992         ;
7993       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7994                          &miss_next_index))
7995         ;
7996       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7997                          &miss_next_index))
7998         ;
7999       else
8000         break;
8001     }
8002
8003   if (is_add && mask == 0)
8004     {
8005       errmsg ("Mask required\n");
8006       return -99;
8007     }
8008
8009   if (is_add && skip == ~0)
8010     {
8011       errmsg ("skip count required\n");
8012       return -99;
8013     }
8014
8015   if (is_add && match == ~0)
8016     {
8017       errmsg ("match count required\n");
8018       return -99;
8019     }
8020
8021   if (!is_add && table_index == ~0)
8022     {
8023       errmsg ("table index required for delete\n");
8024       return -99;
8025     }
8026
8027   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8028
8029   mp->is_add = is_add;
8030   mp->table_index = ntohl (table_index);
8031   mp->nbuckets = ntohl (nbuckets);
8032   mp->memory_size = ntohl (memory_size);
8033   mp->skip_n_vectors = ntohl (skip);
8034   mp->match_n_vectors = ntohl (match);
8035   mp->next_table_index = ntohl (next_table_index);
8036   mp->miss_next_index = ntohl (miss_next_index);
8037   clib_memcpy (mp->mask, mask, vec_len (mask));
8038
8039   vec_free (mask);
8040
8041   S;
8042   W;
8043   /* NOTREACHED */
8044 }
8045
8046 uword
8047 unformat_ip4_match (unformat_input_t * input, va_list * args)
8048 {
8049   u8 **matchp = va_arg (*args, u8 **);
8050   u8 *match = 0;
8051   ip4_header_t *ip;
8052   int version = 0;
8053   u32 version_val;
8054   int hdr_length = 0;
8055   u32 hdr_length_val;
8056   int src = 0, dst = 0;
8057   ip4_address_t src_val, dst_val;
8058   int proto = 0;
8059   u32 proto_val;
8060   int tos = 0;
8061   u32 tos_val;
8062   int length = 0;
8063   u32 length_val;
8064   int fragment_id = 0;
8065   u32 fragment_id_val;
8066   int ttl = 0;
8067   int ttl_val;
8068   int checksum = 0;
8069   u32 checksum_val;
8070
8071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (input, "version %d", &version_val))
8074         version = 1;
8075       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8076         hdr_length = 1;
8077       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8078         src = 1;
8079       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8080         dst = 1;
8081       else if (unformat (input, "proto %d", &proto_val))
8082         proto = 1;
8083       else if (unformat (input, "tos %d", &tos_val))
8084         tos = 1;
8085       else if (unformat (input, "length %d", &length_val))
8086         length = 1;
8087       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8088         fragment_id = 1;
8089       else if (unformat (input, "ttl %d", &ttl_val))
8090         ttl = 1;
8091       else if (unformat (input, "checksum %d", &checksum_val))
8092         checksum = 1;
8093       else
8094         break;
8095     }
8096
8097   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8098       + ttl + checksum == 0)
8099     return 0;
8100
8101   /*
8102    * Aligned because we use the real comparison functions
8103    */
8104   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8105
8106   ip = (ip4_header_t *) match;
8107
8108   /* These are realistically matched in practice */
8109   if (src)
8110     ip->src_address.as_u32 = src_val.as_u32;
8111
8112   if (dst)
8113     ip->dst_address.as_u32 = dst_val.as_u32;
8114
8115   if (proto)
8116     ip->protocol = proto_val;
8117
8118
8119   /* These are not, but they're included for completeness */
8120   if (version)
8121     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8122
8123   if (hdr_length)
8124     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8125
8126   if (tos)
8127     ip->tos = tos_val;
8128
8129   if (length)
8130     ip->length = length_val;
8131
8132   if (ttl)
8133     ip->ttl = ttl_val;
8134
8135   if (checksum)
8136     ip->checksum = checksum_val;
8137
8138   *matchp = match;
8139   return 1;
8140 }
8141
8142 uword
8143 unformat_ip6_match (unformat_input_t * input, va_list * args)
8144 {
8145   u8 **matchp = va_arg (*args, u8 **);
8146   u8 *match = 0;
8147   ip6_header_t *ip;
8148   int version = 0;
8149   u32 version_val;
8150   u8 traffic_class = 0;
8151   u32 traffic_class_val = 0;
8152   u8 flow_label = 0;
8153   u8 flow_label_val;
8154   int src = 0, dst = 0;
8155   ip6_address_t src_val, dst_val;
8156   int proto = 0;
8157   u32 proto_val;
8158   int payload_length = 0;
8159   u32 payload_length_val;
8160   int hop_limit = 0;
8161   int hop_limit_val;
8162   u32 ip_version_traffic_class_and_flow_label;
8163
8164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8165     {
8166       if (unformat (input, "version %d", &version_val))
8167         version = 1;
8168       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8169         traffic_class = 1;
8170       else if (unformat (input, "flow_label %d", &flow_label_val))
8171         flow_label = 1;
8172       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8173         src = 1;
8174       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8175         dst = 1;
8176       else if (unformat (input, "proto %d", &proto_val))
8177         proto = 1;
8178       else if (unformat (input, "payload_length %d", &payload_length_val))
8179         payload_length = 1;
8180       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8181         hop_limit = 1;
8182       else
8183         break;
8184     }
8185
8186   if (version + traffic_class + flow_label + src + dst + proto +
8187       payload_length + hop_limit == 0)
8188     return 0;
8189
8190   /*
8191    * Aligned because we use the real comparison functions
8192    */
8193   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8194
8195   ip = (ip6_header_t *) match;
8196
8197   if (src)
8198     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8199
8200   if (dst)
8201     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8202
8203   if (proto)
8204     ip->protocol = proto_val;
8205
8206   ip_version_traffic_class_and_flow_label = 0;
8207
8208   if (version)
8209     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8210
8211   if (traffic_class)
8212     ip_version_traffic_class_and_flow_label |=
8213       (traffic_class_val & 0xFF) << 20;
8214
8215   if (flow_label)
8216     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8217
8218   ip->ip_version_traffic_class_and_flow_label =
8219     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8220
8221   if (payload_length)
8222     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8223
8224   if (hop_limit)
8225     ip->hop_limit = hop_limit_val;
8226
8227   *matchp = match;
8228   return 1;
8229 }
8230
8231 uword
8232 unformat_l3_match (unformat_input_t * input, va_list * args)
8233 {
8234   u8 **matchp = va_arg (*args, u8 **);
8235
8236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8237     {
8238       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8239         return 1;
8240       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8241         return 1;
8242       else
8243         break;
8244     }
8245   return 0;
8246 }
8247
8248 uword
8249 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8250 {
8251   u8 *tagp = va_arg (*args, u8 *);
8252   u32 tag;
8253
8254   if (unformat (input, "%d", &tag))
8255     {
8256       tagp[0] = (tag >> 8) & 0x0F;
8257       tagp[1] = tag & 0xFF;
8258       return 1;
8259     }
8260
8261   return 0;
8262 }
8263
8264 uword
8265 unformat_l2_match (unformat_input_t * input, va_list * args)
8266 {
8267   u8 **matchp = va_arg (*args, u8 **);
8268   u8 *match = 0;
8269   u8 src = 0;
8270   u8 src_val[6];
8271   u8 dst = 0;
8272   u8 dst_val[6];
8273   u8 proto = 0;
8274   u16 proto_val;
8275   u8 tag1 = 0;
8276   u8 tag1_val[2];
8277   u8 tag2 = 0;
8278   u8 tag2_val[2];
8279   int len = 14;
8280   u8 ignore_tag1 = 0;
8281   u8 ignore_tag2 = 0;
8282   u8 cos1 = 0;
8283   u8 cos2 = 0;
8284   u32 cos1_val = 0;
8285   u32 cos2_val = 0;
8286
8287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8288     {
8289       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8290         src = 1;
8291       else
8292         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8293         dst = 1;
8294       else if (unformat (input, "proto %U",
8295                          unformat_ethernet_type_host_byte_order, &proto_val))
8296         proto = 1;
8297       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8298         tag1 = 1;
8299       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8300         tag2 = 1;
8301       else if (unformat (input, "ignore-tag1"))
8302         ignore_tag1 = 1;
8303       else if (unformat (input, "ignore-tag2"))
8304         ignore_tag2 = 1;
8305       else if (unformat (input, "cos1 %d", &cos1_val))
8306         cos1 = 1;
8307       else if (unformat (input, "cos2 %d", &cos2_val))
8308         cos2 = 1;
8309       else
8310         break;
8311     }
8312   if ((src + dst + proto + tag1 + tag2 +
8313        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8314     return 0;
8315
8316   if (tag1 || ignore_tag1 || cos1)
8317     len = 18;
8318   if (tag2 || ignore_tag2 || cos2)
8319     len = 22;
8320
8321   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8322
8323   if (dst)
8324     clib_memcpy (match, dst_val, 6);
8325
8326   if (src)
8327     clib_memcpy (match + 6, src_val, 6);
8328
8329   if (tag2)
8330     {
8331       /* inner vlan tag */
8332       match[19] = tag2_val[1];
8333       match[18] = tag2_val[0];
8334       if (cos2)
8335         match[18] |= (cos2_val & 0x7) << 5;
8336       if (proto)
8337         {
8338           match[21] = proto_val & 0xff;
8339           match[20] = proto_val >> 8;
8340         }
8341       if (tag1)
8342         {
8343           match[15] = tag1_val[1];
8344           match[14] = tag1_val[0];
8345         }
8346       if (cos1)
8347         match[14] |= (cos1_val & 0x7) << 5;
8348       *matchp = match;
8349       return 1;
8350     }
8351   if (tag1)
8352     {
8353       match[15] = tag1_val[1];
8354       match[14] = tag1_val[0];
8355       if (proto)
8356         {
8357           match[17] = proto_val & 0xff;
8358           match[16] = proto_val >> 8;
8359         }
8360       if (cos1)
8361         match[14] |= (cos1_val & 0x7) << 5;
8362
8363       *matchp = match;
8364       return 1;
8365     }
8366   if (cos2)
8367     match[18] |= (cos2_val & 0x7) << 5;
8368   if (cos1)
8369     match[14] |= (cos1_val & 0x7) << 5;
8370   if (proto)
8371     {
8372       match[13] = proto_val & 0xff;
8373       match[12] = proto_val >> 8;
8374     }
8375
8376   *matchp = match;
8377   return 1;
8378 }
8379
8380
8381 uword
8382 unformat_classify_match (unformat_input_t * input, va_list * args)
8383 {
8384   u8 **matchp = va_arg (*args, u8 **);
8385   u32 skip_n_vectors = va_arg (*args, u32);
8386   u32 match_n_vectors = va_arg (*args, u32);
8387
8388   u8 *match = 0;
8389   u8 *l2 = 0;
8390   u8 *l3 = 0;
8391
8392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8393     {
8394       if (unformat (input, "hex %U", unformat_hex_string, &match))
8395         ;
8396       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8397         ;
8398       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8399         ;
8400       else
8401         break;
8402     }
8403
8404   if (match || l2 || l3)
8405     {
8406       if (l2 || l3)
8407         {
8408           /* "Win a free Ethernet header in every packet" */
8409           if (l2 == 0)
8410             vec_validate_aligned (l2, 13, sizeof (u32x4));
8411           match = l2;
8412           if (vec_len (l3))
8413             {
8414               vec_append_aligned (match, l3, sizeof (u32x4));
8415               vec_free (l3);
8416             }
8417         }
8418
8419       /* Make sure the vector is big enough even if key is all 0's */
8420       vec_validate_aligned
8421         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8422          sizeof (u32x4));
8423
8424       /* Set size, include skipped vectors */
8425       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8426
8427       *matchp = match;
8428
8429       return 1;
8430     }
8431
8432   return 0;
8433 }
8434
8435 static int
8436 api_classify_add_del_session (vat_main_t * vam)
8437 {
8438   unformat_input_t *i = vam->input;
8439   vl_api_classify_add_del_session_t *mp;
8440   int is_add = 1;
8441   u32 table_index = ~0;
8442   u32 hit_next_index = ~0;
8443   u32 opaque_index = ~0;
8444   u8 *match = 0;
8445   i32 advance = 0;
8446   f64 timeout;
8447   u32 skip_n_vectors = 0;
8448   u32 match_n_vectors = 0;
8449
8450   /*
8451    * Warning: you have to supply skip_n and match_n
8452    * because the API client cant simply look at the classify
8453    * table object.
8454    */
8455
8456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8457     {
8458       if (unformat (i, "del"))
8459         is_add = 0;
8460       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8461                          &hit_next_index))
8462         ;
8463       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8464                          &hit_next_index))
8465         ;
8466       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8467                          &hit_next_index))
8468         ;
8469       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8470         ;
8471       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8472         ;
8473       else if (unformat (i, "opaque-index %d", &opaque_index))
8474         ;
8475       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8476         ;
8477       else if (unformat (i, "match_n %d", &match_n_vectors))
8478         ;
8479       else if (unformat (i, "match %U", unformat_classify_match,
8480                          &match, skip_n_vectors, match_n_vectors))
8481         ;
8482       else if (unformat (i, "advance %d", &advance))
8483         ;
8484       else if (unformat (i, "table-index %d", &table_index))
8485         ;
8486       else
8487         break;
8488     }
8489
8490   if (table_index == ~0)
8491     {
8492       errmsg ("Table index required\n");
8493       return -99;
8494     }
8495
8496   if (is_add && match == 0)
8497     {
8498       errmsg ("Match value required\n");
8499       return -99;
8500     }
8501
8502   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8503
8504   mp->is_add = is_add;
8505   mp->table_index = ntohl (table_index);
8506   mp->hit_next_index = ntohl (hit_next_index);
8507   mp->opaque_index = ntohl (opaque_index);
8508   mp->advance = ntohl (advance);
8509   clib_memcpy (mp->match, match, vec_len (match));
8510   vec_free (match);
8511
8512   S;
8513   W;
8514   /* NOTREACHED */
8515 }
8516
8517 static int
8518 api_classify_set_interface_ip_table (vat_main_t * vam)
8519 {
8520   unformat_input_t *i = vam->input;
8521   vl_api_classify_set_interface_ip_table_t *mp;
8522   f64 timeout;
8523   u32 sw_if_index;
8524   int sw_if_index_set;
8525   u32 table_index = ~0;
8526   u8 is_ipv6 = 0;
8527
8528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8529     {
8530       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8531         sw_if_index_set = 1;
8532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8533         sw_if_index_set = 1;
8534       else if (unformat (i, "table %d", &table_index))
8535         ;
8536       else
8537         {
8538           clib_warning ("parse error '%U'", format_unformat_error, i);
8539           return -99;
8540         }
8541     }
8542
8543   if (sw_if_index_set == 0)
8544     {
8545       errmsg ("missing interface name or sw_if_index\n");
8546       return -99;
8547     }
8548
8549
8550   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8551
8552   mp->sw_if_index = ntohl (sw_if_index);
8553   mp->table_index = ntohl (table_index);
8554   mp->is_ipv6 = is_ipv6;
8555
8556   S;
8557   W;
8558   /* NOTREACHED */
8559   return 0;
8560 }
8561
8562 static int
8563 api_classify_set_interface_l2_tables (vat_main_t * vam)
8564 {
8565   unformat_input_t *i = vam->input;
8566   vl_api_classify_set_interface_l2_tables_t *mp;
8567   f64 timeout;
8568   u32 sw_if_index;
8569   int sw_if_index_set;
8570   u32 ip4_table_index = ~0;
8571   u32 ip6_table_index = ~0;
8572   u32 other_table_index = ~0;
8573   u32 is_input = 1;
8574
8575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8576     {
8577       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8578         sw_if_index_set = 1;
8579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8580         sw_if_index_set = 1;
8581       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8582         ;
8583       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8584         ;
8585       else if (unformat (i, "other-table %d", &other_table_index))
8586         ;
8587       else if (unformat (i, "is-input %d", &is_input))
8588         ;
8589       else
8590         {
8591           clib_warning ("parse error '%U'", format_unformat_error, i);
8592           return -99;
8593         }
8594     }
8595
8596   if (sw_if_index_set == 0)
8597     {
8598       errmsg ("missing interface name or sw_if_index\n");
8599       return -99;
8600     }
8601
8602
8603   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8604
8605   mp->sw_if_index = ntohl (sw_if_index);
8606   mp->ip4_table_index = ntohl (ip4_table_index);
8607   mp->ip6_table_index = ntohl (ip6_table_index);
8608   mp->other_table_index = ntohl (other_table_index);
8609   mp->is_input = (u8) is_input;
8610
8611   S;
8612   W;
8613   /* NOTREACHED */
8614   return 0;
8615 }
8616
8617 static int
8618 api_ipfix_enable (vat_main_t * vam)
8619 {
8620   unformat_input_t *i = vam->input;
8621   vl_api_ipfix_enable_t *mp;
8622   ip4_address_t collector_address;
8623   u8 collector_address_set = 0;
8624   u32 collector_port = ~0;
8625   ip4_address_t src_address;
8626   u8 src_address_set = 0;
8627   u32 vrf_id = ~0;
8628   u32 path_mtu = ~0;
8629   u32 template_interval = ~0;
8630   f64 timeout;
8631
8632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8633     {
8634       if (unformat (i, "collector_address %U", unformat_ip4_address,
8635                     &collector_address))
8636         collector_address_set = 1;
8637       else if (unformat (i, "collector_port %d", &collector_port))
8638         ;
8639       else if (unformat (i, "src_address %U", unformat_ip4_address,
8640                          &src_address))
8641         src_address_set = 1;
8642       else if (unformat (i, "vrf_id %d", &vrf_id))
8643         ;
8644       else if (unformat (i, "path_mtu %d", &path_mtu))
8645         ;
8646       else if (unformat (i, "template_interval %d", &template_interval))
8647         ;
8648       else
8649         break;
8650     }
8651
8652   if (collector_address_set == 0)
8653     {
8654       errmsg ("collector_address required\n");
8655       return -99;
8656     }
8657
8658   if (src_address_set == 0)
8659     {
8660       errmsg ("src_address required\n");
8661       return -99;
8662     }
8663
8664   M (IPFIX_ENABLE, ipfix_enable);
8665
8666   memcpy (mp->collector_address, collector_address.data,
8667           sizeof (collector_address.data));
8668   mp->collector_port = htons ((u16) collector_port);
8669   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8670   mp->vrf_id = htonl (vrf_id);
8671   mp->path_mtu = htonl (path_mtu);
8672   mp->template_interval = htonl (template_interval);
8673
8674   S;
8675   W;
8676   /* NOTREACHED */
8677 }
8678
8679 static int
8680 api_get_node_index (vat_main_t * vam)
8681 {
8682   unformat_input_t *i = vam->input;
8683   vl_api_get_node_index_t *mp;
8684   f64 timeout;
8685   u8 *name = 0;
8686
8687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8688     {
8689       if (unformat (i, "node %s", &name))
8690         ;
8691       else
8692         break;
8693     }
8694   if (name == 0)
8695     {
8696       errmsg ("node name required\n");
8697       return -99;
8698     }
8699   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8700     {
8701       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8702       return -99;
8703     }
8704
8705   M (GET_NODE_INDEX, get_node_index);
8706   clib_memcpy (mp->node_name, name, vec_len (name));
8707   vec_free (name);
8708
8709   S;
8710   W;
8711   /* NOTREACHED */
8712   return 0;
8713 }
8714
8715 static int
8716 api_get_next_index (vat_main_t * vam)
8717 {
8718   unformat_input_t *i = vam->input;
8719   vl_api_get_next_index_t *mp;
8720   f64 timeout;
8721   u8 *node_name = 0, *next_node_name = 0;
8722
8723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8724     {
8725       if (unformat (i, "node-name %s", &node_name))
8726         ;
8727       else if (unformat (i, "next-node-name %s", &next_node_name))
8728         break;
8729     }
8730
8731   if (node_name == 0)
8732     {
8733       errmsg ("node name required\n");
8734       return -99;
8735     }
8736   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8737     {
8738       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8739       return -99;
8740     }
8741
8742   if (next_node_name == 0)
8743     {
8744       errmsg ("next node name required\n");
8745       return -99;
8746     }
8747   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8748     {
8749       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8750       return -99;
8751     }
8752
8753   M (GET_NEXT_INDEX, get_next_index);
8754   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8755   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8756   vec_free (node_name);
8757   vec_free (next_node_name);
8758
8759   S;
8760   W;
8761   /* NOTREACHED */
8762   return 0;
8763 }
8764
8765 static int
8766 api_add_node_next (vat_main_t * vam)
8767 {
8768   unformat_input_t *i = vam->input;
8769   vl_api_add_node_next_t *mp;
8770   f64 timeout;
8771   u8 *name = 0;
8772   u8 *next = 0;
8773
8774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8775     {
8776       if (unformat (i, "node %s", &name))
8777         ;
8778       else if (unformat (i, "next %s", &next))
8779         ;
8780       else
8781         break;
8782     }
8783   if (name == 0)
8784     {
8785       errmsg ("node name required\n");
8786       return -99;
8787     }
8788   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8789     {
8790       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8791       return -99;
8792     }
8793   if (next == 0)
8794     {
8795       errmsg ("next node required\n");
8796       return -99;
8797     }
8798   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8799     {
8800       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8801       return -99;
8802     }
8803
8804   M (ADD_NODE_NEXT, add_node_next);
8805   clib_memcpy (mp->node_name, name, vec_len (name));
8806   clib_memcpy (mp->next_name, next, vec_len (next));
8807   vec_free (name);
8808   vec_free (next);
8809
8810   S;
8811   W;
8812   /* NOTREACHED */
8813   return 0;
8814 }
8815
8816 static int
8817 api_l2tpv3_create_tunnel (vat_main_t * vam)
8818 {
8819   unformat_input_t *i = vam->input;
8820   ip6_address_t client_address, our_address;
8821   int client_address_set = 0;
8822   int our_address_set = 0;
8823   u32 local_session_id = 0;
8824   u32 remote_session_id = 0;
8825   u64 local_cookie = 0;
8826   u64 remote_cookie = 0;
8827   u8 l2_sublayer_present = 0;
8828   vl_api_l2tpv3_create_tunnel_t *mp;
8829   f64 timeout;
8830
8831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8832     {
8833       if (unformat (i, "client_address %U", unformat_ip6_address,
8834                     &client_address))
8835         client_address_set = 1;
8836       else if (unformat (i, "our_address %U", unformat_ip6_address,
8837                          &our_address))
8838         our_address_set = 1;
8839       else if (unformat (i, "local_session_id %d", &local_session_id))
8840         ;
8841       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8842         ;
8843       else if (unformat (i, "local_cookie %lld", &local_cookie))
8844         ;
8845       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8846         ;
8847       else if (unformat (i, "l2-sublayer-present"))
8848         l2_sublayer_present = 1;
8849       else
8850         break;
8851     }
8852
8853   if (client_address_set == 0)
8854     {
8855       errmsg ("client_address required\n");
8856       return -99;
8857     }
8858
8859   if (our_address_set == 0)
8860     {
8861       errmsg ("our_address required\n");
8862       return -99;
8863     }
8864
8865   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8866
8867   clib_memcpy (mp->client_address, client_address.as_u8,
8868                sizeof (mp->client_address));
8869
8870   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8871
8872   mp->local_session_id = ntohl (local_session_id);
8873   mp->remote_session_id = ntohl (remote_session_id);
8874   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8875   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8876   mp->l2_sublayer_present = l2_sublayer_present;
8877   mp->is_ipv6 = 1;
8878
8879   S;
8880   W;
8881   /* NOTREACHED */
8882   return 0;
8883 }
8884
8885 static int
8886 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8887 {
8888   unformat_input_t *i = vam->input;
8889   u32 sw_if_index;
8890   u8 sw_if_index_set = 0;
8891   u64 new_local_cookie = 0;
8892   u64 new_remote_cookie = 0;
8893   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8894   f64 timeout;
8895
8896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8897     {
8898       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8899         sw_if_index_set = 1;
8900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8901         sw_if_index_set = 1;
8902       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8903         ;
8904       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8905         ;
8906       else
8907         break;
8908     }
8909
8910   if (sw_if_index_set == 0)
8911     {
8912       errmsg ("missing interface name or sw_if_index\n");
8913       return -99;
8914     }
8915
8916   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8917
8918   mp->sw_if_index = ntohl (sw_if_index);
8919   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8920   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8921
8922   S;
8923   W;
8924   /* NOTREACHED */
8925   return 0;
8926 }
8927
8928 static int
8929 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8930 {
8931   unformat_input_t *i = vam->input;
8932   vl_api_l2tpv3_interface_enable_disable_t *mp;
8933   f64 timeout;
8934   u32 sw_if_index;
8935   u8 sw_if_index_set = 0;
8936   u8 enable_disable = 1;
8937
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8941         sw_if_index_set = 1;
8942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8943         sw_if_index_set = 1;
8944       else if (unformat (i, "enable"))
8945         enable_disable = 1;
8946       else if (unformat (i, "disable"))
8947         enable_disable = 0;
8948       else
8949         break;
8950     }
8951
8952   if (sw_if_index_set == 0)
8953     {
8954       errmsg ("missing interface name or sw_if_index\n");
8955       return -99;
8956     }
8957
8958   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8959
8960   mp->sw_if_index = ntohl (sw_if_index);
8961   mp->enable_disable = enable_disable;
8962
8963   S;
8964   W;
8965   /* NOTREACHED */
8966   return 0;
8967 }
8968
8969 static int
8970 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8971 {
8972   unformat_input_t *i = vam->input;
8973   vl_api_l2tpv3_set_lookup_key_t *mp;
8974   f64 timeout;
8975   u8 key = ~0;
8976
8977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (i, "lookup_v6_src"))
8980         key = L2T_LOOKUP_SRC_ADDRESS;
8981       else if (unformat (i, "lookup_v6_dst"))
8982         key = L2T_LOOKUP_DST_ADDRESS;
8983       else if (unformat (i, "lookup_session_id"))
8984         key = L2T_LOOKUP_SESSION_ID;
8985       else
8986         break;
8987     }
8988
8989   if (key == (u8) ~ 0)
8990     {
8991       errmsg ("l2tp session lookup key unset\n");
8992       return -99;
8993     }
8994
8995   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8996
8997   mp->key = key;
8998
8999   S;
9000   W;
9001   /* NOTREACHED */
9002   return 0;
9003 }
9004
9005 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9006   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9007 {
9008   vat_main_t *vam = &vat_main;
9009
9010   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9011            format_ip6_address, mp->our_address,
9012            format_ip6_address, mp->client_address,
9013            clib_net_to_host_u32 (mp->sw_if_index));
9014
9015   fformat (vam->ofp,
9016            "   local cookies %016llx %016llx remote cookie %016llx\n",
9017            clib_net_to_host_u64 (mp->local_cookie[0]),
9018            clib_net_to_host_u64 (mp->local_cookie[1]),
9019            clib_net_to_host_u64 (mp->remote_cookie));
9020
9021   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9022            clib_net_to_host_u32 (mp->local_session_id),
9023            clib_net_to_host_u32 (mp->remote_session_id));
9024
9025   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9026            mp->l2_sublayer_present ? "preset" : "absent");
9027
9028 }
9029
9030 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9031   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9032 {
9033   vat_main_t *vam = &vat_main;
9034   vat_json_node_t *node = NULL;
9035   struct in6_addr addr;
9036
9037   if (VAT_JSON_ARRAY != vam->json_tree.type)
9038     {
9039       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9040       vat_json_init_array (&vam->json_tree);
9041     }
9042   node = vat_json_array_add (&vam->json_tree);
9043
9044   vat_json_init_object (node);
9045
9046   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9047   vat_json_object_add_ip6 (node, "our_address", addr);
9048   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9049   vat_json_object_add_ip6 (node, "client_address", addr);
9050
9051   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9052   vat_json_init_array (lc);
9053   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9054   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9055   vat_json_object_add_uint (node, "remote_cookie",
9056                             clib_net_to_host_u64 (mp->remote_cookie));
9057
9058   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9059   vat_json_object_add_uint (node, "local_session_id",
9060                             clib_net_to_host_u32 (mp->local_session_id));
9061   vat_json_object_add_uint (node, "remote_session_id",
9062                             clib_net_to_host_u32 (mp->remote_session_id));
9063   vat_json_object_add_string_copy (node, "l2_sublayer",
9064                                    mp->l2_sublayer_present ? (u8 *) "present"
9065                                    : (u8 *) "absent");
9066 }
9067
9068 static int
9069 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9070 {
9071   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9072   f64 timeout;
9073
9074   /* Get list of l2tpv3-tunnel interfaces */
9075   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9076   S;
9077
9078   /* Use a control ping for synchronization */
9079   {
9080     vl_api_control_ping_t *mp;
9081     M (CONTROL_PING, control_ping);
9082     S;
9083   }
9084   W;
9085 }
9086
9087
9088 static void vl_api_sw_interface_tap_details_t_handler
9089   (vl_api_sw_interface_tap_details_t * mp)
9090 {
9091   vat_main_t *vam = &vat_main;
9092
9093   fformat (vam->ofp, "%-16s %d\n",
9094            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9095 }
9096
9097 static void vl_api_sw_interface_tap_details_t_handler_json
9098   (vl_api_sw_interface_tap_details_t * mp)
9099 {
9100   vat_main_t *vam = &vat_main;
9101   vat_json_node_t *node = NULL;
9102
9103   if (VAT_JSON_ARRAY != vam->json_tree.type)
9104     {
9105       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9106       vat_json_init_array (&vam->json_tree);
9107     }
9108   node = vat_json_array_add (&vam->json_tree);
9109
9110   vat_json_init_object (node);
9111   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9112   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9113 }
9114
9115 static int
9116 api_sw_interface_tap_dump (vat_main_t * vam)
9117 {
9118   vl_api_sw_interface_tap_dump_t *mp;
9119   f64 timeout;
9120
9121   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9122   /* Get list of tap interfaces */
9123   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9124   S;
9125
9126   /* Use a control ping for synchronization */
9127   {
9128     vl_api_control_ping_t *mp;
9129     M (CONTROL_PING, control_ping);
9130     S;
9131   }
9132   W;
9133 }
9134
9135 static uword unformat_vxlan_decap_next
9136   (unformat_input_t * input, va_list * args)
9137 {
9138   u32 *result = va_arg (*args, u32 *);
9139   u32 tmp;
9140
9141   if (unformat (input, "drop"))
9142     *result = VXLAN_INPUT_NEXT_DROP;
9143   else if (unformat (input, "ip4"))
9144     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9145   else if (unformat (input, "ip6"))
9146     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9147   else if (unformat (input, "l2"))
9148     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9149   else if (unformat (input, "%d", &tmp))
9150     *result = tmp;
9151   else
9152     return 0;
9153   return 1;
9154 }
9155
9156 static int
9157 api_vxlan_add_del_tunnel (vat_main_t * vam)
9158 {
9159   unformat_input_t *line_input = vam->input;
9160   vl_api_vxlan_add_del_tunnel_t *mp;
9161   f64 timeout;
9162   ip4_address_t src4, dst4;
9163   ip6_address_t src6, dst6;
9164   u8 is_add = 1;
9165   u8 ipv4_set = 0, ipv6_set = 0;
9166   u8 src_set = 0;
9167   u8 dst_set = 0;
9168   u32 encap_vrf_id = 0;
9169   u32 decap_next_index = ~0;
9170   u32 vni = 0;
9171
9172   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9173     {
9174       if (unformat (line_input, "del"))
9175         is_add = 0;
9176       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9177         {
9178           ipv4_set = 1;
9179           src_set = 1;
9180         }
9181       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9182         {
9183           ipv4_set = 1;
9184           dst_set = 1;
9185         }
9186       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9187         {
9188           ipv6_set = 1;
9189           src_set = 1;
9190         }
9191       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9192         {
9193           ipv6_set = 1;
9194           dst_set = 1;
9195         }
9196       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9197         ;
9198       else if (unformat (line_input, "decap-next %U",
9199                          unformat_vxlan_decap_next, &decap_next_index))
9200         ;
9201       else if (unformat (line_input, "vni %d", &vni))
9202         ;
9203       else
9204         {
9205           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9206           return -99;
9207         }
9208     }
9209
9210   if (src_set == 0)
9211     {
9212       errmsg ("tunnel src address not specified\n");
9213       return -99;
9214     }
9215   if (dst_set == 0)
9216     {
9217       errmsg ("tunnel dst address not specified\n");
9218       return -99;
9219     }
9220
9221   if (ipv4_set && ipv6_set)
9222     {
9223       errmsg ("both IPv4 and IPv6 addresses specified");
9224       return -99;
9225     }
9226
9227   if ((vni == 0) || (vni >> 24))
9228     {
9229       errmsg ("vni not specified or out of range\n");
9230       return -99;
9231     }
9232
9233   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9234
9235   if (ipv6_set)
9236     {
9237       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9238       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9239     }
9240   else
9241     {
9242       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9243       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9244     }
9245   mp->encap_vrf_id = ntohl (encap_vrf_id);
9246   mp->decap_next_index = ntohl (decap_next_index);
9247   mp->vni = ntohl (vni);
9248   mp->is_add = is_add;
9249   mp->is_ipv6 = ipv6_set;
9250
9251   S;
9252   W;
9253   /* NOTREACHED */
9254   return 0;
9255 }
9256
9257 static void vl_api_vxlan_tunnel_details_t_handler
9258   (vl_api_vxlan_tunnel_details_t * mp)
9259 {
9260   vat_main_t *vam = &vat_main;
9261
9262   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9263            ntohl (mp->sw_if_index),
9264            format_ip46_address, &(mp->src_address[0]),
9265            IP46_TYPE_ANY,
9266            format_ip46_address, &(mp->dst_address[0]),
9267            IP46_TYPE_ANY,
9268            ntohl (mp->encap_vrf_id),
9269            ntohl (mp->decap_next_index), ntohl (mp->vni));
9270 }
9271
9272 static void vl_api_vxlan_tunnel_details_t_handler_json
9273   (vl_api_vxlan_tunnel_details_t * mp)
9274 {
9275   vat_main_t *vam = &vat_main;
9276   vat_json_node_t *node = NULL;
9277   struct in_addr ip4;
9278   struct in6_addr ip6;
9279
9280   if (VAT_JSON_ARRAY != vam->json_tree.type)
9281     {
9282       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9283       vat_json_init_array (&vam->json_tree);
9284     }
9285   node = vat_json_array_add (&vam->json_tree);
9286
9287   vat_json_init_object (node);
9288   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9289   if (mp->is_ipv6)
9290     {
9291       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9292       vat_json_object_add_ip6 (node, "src_address", ip6);
9293       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9294       vat_json_object_add_ip6 (node, "dst_address", ip6);
9295     }
9296   else
9297     {
9298       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9299       vat_json_object_add_ip4 (node, "src_address", ip4);
9300       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9301       vat_json_object_add_ip4 (node, "dst_address", ip4);
9302     }
9303   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9304   vat_json_object_add_uint (node, "decap_next_index",
9305                             ntohl (mp->decap_next_index));
9306   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9307   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9308 }
9309
9310 static int
9311 api_vxlan_tunnel_dump (vat_main_t * vam)
9312 {
9313   unformat_input_t *i = vam->input;
9314   vl_api_vxlan_tunnel_dump_t *mp;
9315   f64 timeout;
9316   u32 sw_if_index;
9317   u8 sw_if_index_set = 0;
9318
9319   /* Parse args required to build the message */
9320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9321     {
9322       if (unformat (i, "sw_if_index %d", &sw_if_index))
9323         sw_if_index_set = 1;
9324       else
9325         break;
9326     }
9327
9328   if (sw_if_index_set == 0)
9329     {
9330       sw_if_index = ~0;
9331     }
9332
9333   if (!vam->json_output)
9334     {
9335       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9336                "sw_if_index", "src_address", "dst_address",
9337                "encap_vrf_id", "decap_next_index", "vni");
9338     }
9339
9340   /* Get list of vxlan-tunnel interfaces */
9341   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9342
9343   mp->sw_if_index = htonl (sw_if_index);
9344
9345   S;
9346
9347   /* Use a control ping for synchronization */
9348   {
9349     vl_api_control_ping_t *mp;
9350     M (CONTROL_PING, control_ping);
9351     S;
9352   }
9353   W;
9354 }
9355
9356 static int
9357 api_gre_add_del_tunnel (vat_main_t * vam)
9358 {
9359   unformat_input_t *line_input = vam->input;
9360   vl_api_gre_add_del_tunnel_t *mp;
9361   f64 timeout;
9362   ip4_address_t src4, dst4;
9363   u8 is_add = 1;
9364   u8 src_set = 0;
9365   u8 dst_set = 0;
9366   u32 outer_fib_id = 0;
9367
9368   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9369     {
9370       if (unformat (line_input, "del"))
9371         is_add = 0;
9372       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9373         src_set = 1;
9374       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9375         dst_set = 1;
9376       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9377         ;
9378       else
9379         {
9380           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9381           return -99;
9382         }
9383     }
9384
9385   if (src_set == 0)
9386     {
9387       errmsg ("tunnel src address not specified\n");
9388       return -99;
9389     }
9390   if (dst_set == 0)
9391     {
9392       errmsg ("tunnel dst address not specified\n");
9393       return -99;
9394     }
9395
9396
9397   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9398
9399   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9400   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9401   mp->outer_fib_id = ntohl (outer_fib_id);
9402   mp->is_add = is_add;
9403
9404   S;
9405   W;
9406   /* NOTREACHED */
9407   return 0;
9408 }
9409
9410 static void vl_api_gre_tunnel_details_t_handler
9411   (vl_api_gre_tunnel_details_t * mp)
9412 {
9413   vat_main_t *vam = &vat_main;
9414
9415   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9416            ntohl (mp->sw_if_index),
9417            format_ip4_address, &mp->src_address,
9418            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9419 }
9420
9421 static void vl_api_gre_tunnel_details_t_handler_json
9422   (vl_api_gre_tunnel_details_t * mp)
9423 {
9424   vat_main_t *vam = &vat_main;
9425   vat_json_node_t *node = NULL;
9426   struct in_addr ip4;
9427
9428   if (VAT_JSON_ARRAY != vam->json_tree.type)
9429     {
9430       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9431       vat_json_init_array (&vam->json_tree);
9432     }
9433   node = vat_json_array_add (&vam->json_tree);
9434
9435   vat_json_init_object (node);
9436   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9437   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9438   vat_json_object_add_ip4 (node, "src_address", ip4);
9439   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9440   vat_json_object_add_ip4 (node, "dst_address", ip4);
9441   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9442 }
9443
9444 static int
9445 api_gre_tunnel_dump (vat_main_t * vam)
9446 {
9447   unformat_input_t *i = vam->input;
9448   vl_api_gre_tunnel_dump_t *mp;
9449   f64 timeout;
9450   u32 sw_if_index;
9451   u8 sw_if_index_set = 0;
9452
9453   /* Parse args required to build the message */
9454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9455     {
9456       if (unformat (i, "sw_if_index %d", &sw_if_index))
9457         sw_if_index_set = 1;
9458       else
9459         break;
9460     }
9461
9462   if (sw_if_index_set == 0)
9463     {
9464       sw_if_index = ~0;
9465     }
9466
9467   if (!vam->json_output)
9468     {
9469       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9470                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9471     }
9472
9473   /* Get list of gre-tunnel interfaces */
9474   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9475
9476   mp->sw_if_index = htonl (sw_if_index);
9477
9478   S;
9479
9480   /* Use a control ping for synchronization */
9481   {
9482     vl_api_control_ping_t *mp;
9483     M (CONTROL_PING, control_ping);
9484     S;
9485   }
9486   W;
9487 }
9488
9489 static int
9490 api_l2_fib_clear_table (vat_main_t * vam)
9491 {
9492 //  unformat_input_t * i = vam->input;
9493   vl_api_l2_fib_clear_table_t *mp;
9494   f64 timeout;
9495
9496   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9497
9498   S;
9499   W;
9500   /* NOTREACHED */
9501   return 0;
9502 }
9503
9504 static int
9505 api_l2_interface_efp_filter (vat_main_t * vam)
9506 {
9507   unformat_input_t *i = vam->input;
9508   vl_api_l2_interface_efp_filter_t *mp;
9509   f64 timeout;
9510   u32 sw_if_index;
9511   u8 enable = 1;
9512   u8 sw_if_index_set = 0;
9513
9514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9515     {
9516       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9517         sw_if_index_set = 1;
9518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9519         sw_if_index_set = 1;
9520       else if (unformat (i, "enable"))
9521         enable = 1;
9522       else if (unformat (i, "disable"))
9523         enable = 0;
9524       else
9525         {
9526           clib_warning ("parse error '%U'", format_unformat_error, i);
9527           return -99;
9528         }
9529     }
9530
9531   if (sw_if_index_set == 0)
9532     {
9533       errmsg ("missing sw_if_index\n");
9534       return -99;
9535     }
9536
9537   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9538
9539   mp->sw_if_index = ntohl (sw_if_index);
9540   mp->enable_disable = enable;
9541
9542   S;
9543   W;
9544   /* NOTREACHED */
9545   return 0;
9546 }
9547
9548 #define foreach_vtr_op                          \
9549 _("disable",  L2_VTR_DISABLED)                  \
9550 _("push-1",  L2_VTR_PUSH_1)                     \
9551 _("push-2",  L2_VTR_PUSH_2)                     \
9552 _("pop-1",  L2_VTR_POP_1)                       \
9553 _("pop-2",  L2_VTR_POP_2)                       \
9554 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9555 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9556 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9557 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9558
9559 static int
9560 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9561 {
9562   unformat_input_t *i = vam->input;
9563   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9564   f64 timeout;
9565   u32 sw_if_index;
9566   u8 sw_if_index_set = 0;
9567   u8 vtr_op_set = 0;
9568   u32 vtr_op = 0;
9569   u32 push_dot1q = 1;
9570   u32 tag1 = ~0;
9571   u32 tag2 = ~0;
9572
9573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9574     {
9575       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9576         sw_if_index_set = 1;
9577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9578         sw_if_index_set = 1;
9579       else if (unformat (i, "vtr_op %d", &vtr_op))
9580         vtr_op_set = 1;
9581 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9582       foreach_vtr_op
9583 #undef _
9584         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9585         ;
9586       else if (unformat (i, "tag1 %d", &tag1))
9587         ;
9588       else if (unformat (i, "tag2 %d", &tag2))
9589         ;
9590       else
9591         {
9592           clib_warning ("parse error '%U'", format_unformat_error, i);
9593           return -99;
9594         }
9595     }
9596
9597   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9598     {
9599       errmsg ("missing vtr operation or sw_if_index\n");
9600       return -99;
9601     }
9602
9603   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9604     mp->sw_if_index = ntohl (sw_if_index);
9605   mp->vtr_op = ntohl (vtr_op);
9606   mp->push_dot1q = ntohl (push_dot1q);
9607   mp->tag1 = ntohl (tag1);
9608   mp->tag2 = ntohl (tag2);
9609
9610   S;
9611   W;
9612   /* NOTREACHED */
9613   return 0;
9614 }
9615
9616 static int
9617 api_create_vhost_user_if (vat_main_t * vam)
9618 {
9619   unformat_input_t *i = vam->input;
9620   vl_api_create_vhost_user_if_t *mp;
9621   f64 timeout;
9622   u8 *file_name;
9623   u8 is_server = 0;
9624   u8 file_name_set = 0;
9625   u32 custom_dev_instance = ~0;
9626   u8 hwaddr[6];
9627   u8 use_custom_mac = 0;
9628
9629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9630     {
9631       if (unformat (i, "socket %s", &file_name))
9632         {
9633           file_name_set = 1;
9634         }
9635       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9636         ;
9637       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9638         use_custom_mac = 1;
9639       else if (unformat (i, "server"))
9640         is_server = 1;
9641       else
9642         break;
9643     }
9644
9645   if (file_name_set == 0)
9646     {
9647       errmsg ("missing socket file name\n");
9648       return -99;
9649     }
9650
9651   if (vec_len (file_name) > 255)
9652     {
9653       errmsg ("socket file name too long\n");
9654       return -99;
9655     }
9656   vec_add1 (file_name, 0);
9657
9658   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9659
9660   mp->is_server = is_server;
9661   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9662   vec_free (file_name);
9663   if (custom_dev_instance != ~0)
9664     {
9665       mp->renumber = 1;
9666       mp->custom_dev_instance = ntohl (custom_dev_instance);
9667     }
9668   mp->use_custom_mac = use_custom_mac;
9669   clib_memcpy (mp->mac_address, hwaddr, 6);
9670
9671   S;
9672   W;
9673   /* NOTREACHED */
9674   return 0;
9675 }
9676
9677 static int
9678 api_modify_vhost_user_if (vat_main_t * vam)
9679 {
9680   unformat_input_t *i = vam->input;
9681   vl_api_modify_vhost_user_if_t *mp;
9682   f64 timeout;
9683   u8 *file_name;
9684   u8 is_server = 0;
9685   u8 file_name_set = 0;
9686   u32 custom_dev_instance = ~0;
9687   u8 sw_if_index_set = 0;
9688   u32 sw_if_index = (u32) ~ 0;
9689
9690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9691     {
9692       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9693         sw_if_index_set = 1;
9694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9695         sw_if_index_set = 1;
9696       else if (unformat (i, "socket %s", &file_name))
9697         {
9698           file_name_set = 1;
9699         }
9700       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9701         ;
9702       else if (unformat (i, "server"))
9703         is_server = 1;
9704       else
9705         break;
9706     }
9707
9708   if (sw_if_index_set == 0)
9709     {
9710       errmsg ("missing sw_if_index or interface name\n");
9711       return -99;
9712     }
9713
9714   if (file_name_set == 0)
9715     {
9716       errmsg ("missing socket file name\n");
9717       return -99;
9718     }
9719
9720   if (vec_len (file_name) > 255)
9721     {
9722       errmsg ("socket file name too long\n");
9723       return -99;
9724     }
9725   vec_add1 (file_name, 0);
9726
9727   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9728
9729   mp->sw_if_index = ntohl (sw_if_index);
9730   mp->is_server = is_server;
9731   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9732   vec_free (file_name);
9733   if (custom_dev_instance != ~0)
9734     {
9735       mp->renumber = 1;
9736       mp->custom_dev_instance = ntohl (custom_dev_instance);
9737     }
9738
9739   S;
9740   W;
9741   /* NOTREACHED */
9742   return 0;
9743 }
9744
9745 static int
9746 api_delete_vhost_user_if (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   vl_api_delete_vhost_user_if_t *mp;
9750   f64 timeout;
9751   u32 sw_if_index = ~0;
9752   u8 sw_if_index_set = 0;
9753
9754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9755     {
9756       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9757         sw_if_index_set = 1;
9758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9759         sw_if_index_set = 1;
9760       else
9761         break;
9762     }
9763
9764   if (sw_if_index_set == 0)
9765     {
9766       errmsg ("missing sw_if_index or interface name\n");
9767       return -99;
9768     }
9769
9770
9771   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9772
9773   mp->sw_if_index = ntohl (sw_if_index);
9774
9775   S;
9776   W;
9777   /* NOTREACHED */
9778   return 0;
9779 }
9780
9781 static void vl_api_sw_interface_vhost_user_details_t_handler
9782   (vl_api_sw_interface_vhost_user_details_t * mp)
9783 {
9784   vat_main_t *vam = &vat_main;
9785
9786   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9787            (char *) mp->interface_name,
9788            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9789            clib_net_to_host_u64 (mp->features), mp->is_server,
9790            ntohl (mp->num_regions), (char *) mp->sock_filename);
9791   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9792 }
9793
9794 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9795   (vl_api_sw_interface_vhost_user_details_t * mp)
9796 {
9797   vat_main_t *vam = &vat_main;
9798   vat_json_node_t *node = NULL;
9799
9800   if (VAT_JSON_ARRAY != vam->json_tree.type)
9801     {
9802       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9803       vat_json_init_array (&vam->json_tree);
9804     }
9805   node = vat_json_array_add (&vam->json_tree);
9806
9807   vat_json_init_object (node);
9808   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9809   vat_json_object_add_string_copy (node, "interface_name",
9810                                    mp->interface_name);
9811   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9812                             ntohl (mp->virtio_net_hdr_sz));
9813   vat_json_object_add_uint (node, "features",
9814                             clib_net_to_host_u64 (mp->features));
9815   vat_json_object_add_uint (node, "is_server", mp->is_server);
9816   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9817   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9818   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9819 }
9820
9821 static int
9822 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9823 {
9824   vl_api_sw_interface_vhost_user_dump_t *mp;
9825   f64 timeout;
9826   fformat (vam->ofp,
9827            "Interface name           idx hdr_sz features server regions filename\n");
9828
9829   /* Get list of vhost-user interfaces */
9830   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9831   S;
9832
9833   /* Use a control ping for synchronization */
9834   {
9835     vl_api_control_ping_t *mp;
9836     M (CONTROL_PING, control_ping);
9837     S;
9838   }
9839   W;
9840 }
9841
9842 static int
9843 api_show_version (vat_main_t * vam)
9844 {
9845   vl_api_show_version_t *mp;
9846   f64 timeout;
9847
9848   M (SHOW_VERSION, show_version);
9849
9850   S;
9851   W;
9852   /* NOTREACHED */
9853   return 0;
9854 }
9855
9856
9857 static int
9858 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9859 {
9860   unformat_input_t *line_input = vam->input;
9861   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9862   f64 timeout;
9863   ip4_address_t local4, remote4;
9864   ip6_address_t local6, remote6;
9865   u8 is_add = 1;
9866   u8 ipv4_set = 0, ipv6_set = 0;
9867   u8 local_set = 0;
9868   u8 remote_set = 0;
9869   u32 encap_vrf_id = 0;
9870   u32 decap_vrf_id = 0;
9871   u8 protocol = ~0;
9872   u32 vni;
9873   u8 vni_set = 0;
9874
9875   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9876     {
9877       if (unformat (line_input, "del"))
9878         is_add = 0;
9879       else if (unformat (line_input, "local %U",
9880                          unformat_ip4_address, &local4))
9881         {
9882           local_set = 1;
9883           ipv4_set = 1;
9884         }
9885       else if (unformat (line_input, "remote %U",
9886                          unformat_ip4_address, &remote4))
9887         {
9888           remote_set = 1;
9889           ipv4_set = 1;
9890         }
9891       else if (unformat (line_input, "local %U",
9892                          unformat_ip6_address, &local6))
9893         {
9894           local_set = 1;
9895           ipv6_set = 1;
9896         }
9897       else if (unformat (line_input, "remote %U",
9898                          unformat_ip6_address, &remote6))
9899         {
9900           remote_set = 1;
9901           ipv6_set = 1;
9902         }
9903       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9904         ;
9905       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9906         ;
9907       else if (unformat (line_input, "vni %d", &vni))
9908         vni_set = 1;
9909       else if (unformat (line_input, "next-ip4"))
9910         protocol = 1;
9911       else if (unformat (line_input, "next-ip6"))
9912         protocol = 2;
9913       else if (unformat (line_input, "next-ethernet"))
9914         protocol = 3;
9915       else if (unformat (line_input, "next-nsh"))
9916         protocol = 4;
9917       else
9918         {
9919           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9920           return -99;
9921         }
9922     }
9923
9924   if (local_set == 0)
9925     {
9926       errmsg ("tunnel local address not specified\n");
9927       return -99;
9928     }
9929   if (remote_set == 0)
9930     {
9931       errmsg ("tunnel remote address not specified\n");
9932       return -99;
9933     }
9934   if (ipv4_set && ipv6_set)
9935     {
9936       errmsg ("both IPv4 and IPv6 addresses specified");
9937       return -99;
9938     }
9939
9940   if (vni_set == 0)
9941     {
9942       errmsg ("vni not specified\n");
9943       return -99;
9944     }
9945
9946   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9947
9948
9949   if (ipv6_set)
9950     {
9951       clib_memcpy (&mp->local, &local6, sizeof (local6));
9952       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9953     }
9954   else
9955     {
9956       clib_memcpy (&mp->local, &local4, sizeof (local4));
9957       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9958     }
9959
9960   mp->encap_vrf_id = ntohl (encap_vrf_id);
9961   mp->decap_vrf_id = ntohl (decap_vrf_id);
9962   mp->protocol = ntohl (protocol);
9963   mp->vni = ntohl (vni);
9964   mp->is_add = is_add;
9965   mp->is_ipv6 = ipv6_set;
9966
9967   S;
9968   W;
9969   /* NOTREACHED */
9970   return 0;
9971 }
9972
9973 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9974   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9975 {
9976   vat_main_t *vam = &vat_main;
9977
9978   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9979            ntohl (mp->sw_if_index),
9980            format_ip46_address, &(mp->local[0]),
9981            format_ip46_address, &(mp->remote[0]),
9982            ntohl (mp->vni),
9983            ntohl (mp->protocol),
9984            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9985 }
9986
9987 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9988   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9989 {
9990   vat_main_t *vam = &vat_main;
9991   vat_json_node_t *node = NULL;
9992   struct in_addr ip4;
9993   struct in6_addr ip6;
9994
9995   if (VAT_JSON_ARRAY != vam->json_tree.type)
9996     {
9997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9998       vat_json_init_array (&vam->json_tree);
9999     }
10000   node = vat_json_array_add (&vam->json_tree);
10001
10002   vat_json_init_object (node);
10003   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10004   if (mp->is_ipv6)
10005     {
10006       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10007       vat_json_object_add_ip6 (node, "local", ip6);
10008       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10009       vat_json_object_add_ip6 (node, "remote", ip6);
10010     }
10011   else
10012     {
10013       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10014       vat_json_object_add_ip4 (node, "local", ip4);
10015       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10016       vat_json_object_add_ip4 (node, "remote", ip4);
10017     }
10018   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10019   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10020   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10021   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10022   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10023 }
10024
10025 static int
10026 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10027 {
10028   unformat_input_t *i = vam->input;
10029   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10030   f64 timeout;
10031   u32 sw_if_index;
10032   u8 sw_if_index_set = 0;
10033
10034   /* Parse args required to build the message */
10035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10036     {
10037       if (unformat (i, "sw_if_index %d", &sw_if_index))
10038         sw_if_index_set = 1;
10039       else
10040         break;
10041     }
10042
10043   if (sw_if_index_set == 0)
10044     {
10045       sw_if_index = ~0;
10046     }
10047
10048   if (!vam->json_output)
10049     {
10050       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10051                "sw_if_index", "local", "remote", "vni",
10052                "protocol", "encap_vrf_id", "decap_vrf_id");
10053     }
10054
10055   /* Get list of vxlan-tunnel interfaces */
10056   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10057
10058   mp->sw_if_index = htonl (sw_if_index);
10059
10060   S;
10061
10062   /* Use a control ping for synchronization */
10063   {
10064     vl_api_control_ping_t *mp;
10065     M (CONTROL_PING, control_ping);
10066     S;
10067   }
10068   W;
10069 }
10070
10071 u8 *
10072 format_l2_fib_mac_address (u8 * s, va_list * args)
10073 {
10074   u8 *a = va_arg (*args, u8 *);
10075
10076   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10077                  a[2], a[3], a[4], a[5], a[6], a[7]);
10078 }
10079
10080 static void vl_api_l2_fib_table_entry_t_handler
10081   (vl_api_l2_fib_table_entry_t * mp)
10082 {
10083   vat_main_t *vam = &vat_main;
10084
10085   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10086            "       %d       %d     %d\n",
10087            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10088            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10089            mp->bvi_mac);
10090 }
10091
10092 static void vl_api_l2_fib_table_entry_t_handler_json
10093   (vl_api_l2_fib_table_entry_t * mp)
10094 {
10095   vat_main_t *vam = &vat_main;
10096   vat_json_node_t *node = NULL;
10097
10098   if (VAT_JSON_ARRAY != vam->json_tree.type)
10099     {
10100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10101       vat_json_init_array (&vam->json_tree);
10102     }
10103   node = vat_json_array_add (&vam->json_tree);
10104
10105   vat_json_init_object (node);
10106   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10107   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10108   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10109   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10110   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10111   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10112 }
10113
10114 static int
10115 api_l2_fib_table_dump (vat_main_t * vam)
10116 {
10117   unformat_input_t *i = vam->input;
10118   vl_api_l2_fib_table_dump_t *mp;
10119   f64 timeout;
10120   u32 bd_id;
10121   u8 bd_id_set = 0;
10122
10123   /* Parse args required to build the message */
10124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10125     {
10126       if (unformat (i, "bd_id %d", &bd_id))
10127         bd_id_set = 1;
10128       else
10129         break;
10130     }
10131
10132   if (bd_id_set == 0)
10133     {
10134       errmsg ("missing bridge domain\n");
10135       return -99;
10136     }
10137
10138   fformat (vam->ofp,
10139            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10140
10141   /* Get list of l2 fib entries */
10142   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10143
10144   mp->bd_id = ntohl (bd_id);
10145   S;
10146
10147   /* Use a control ping for synchronization */
10148   {
10149     vl_api_control_ping_t *mp;
10150     M (CONTROL_PING, control_ping);
10151     S;
10152   }
10153   W;
10154 }
10155
10156
10157 static int
10158 api_interface_name_renumber (vat_main_t * vam)
10159 {
10160   unformat_input_t *line_input = vam->input;
10161   vl_api_interface_name_renumber_t *mp;
10162   u32 sw_if_index = ~0;
10163   f64 timeout;
10164   u32 new_show_dev_instance = ~0;
10165
10166   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10167     {
10168       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10169                     &sw_if_index))
10170         ;
10171       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10172         ;
10173       else if (unformat (line_input, "new_show_dev_instance %d",
10174                          &new_show_dev_instance))
10175         ;
10176       else
10177         break;
10178     }
10179
10180   if (sw_if_index == ~0)
10181     {
10182       errmsg ("missing interface name or sw_if_index\n");
10183       return -99;
10184     }
10185
10186   if (new_show_dev_instance == ~0)
10187     {
10188       errmsg ("missing new_show_dev_instance\n");
10189       return -99;
10190     }
10191
10192   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10193
10194   mp->sw_if_index = ntohl (sw_if_index);
10195   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10196
10197   S;
10198   W;
10199 }
10200
10201 static int
10202 api_want_ip4_arp_events (vat_main_t * vam)
10203 {
10204   unformat_input_t *line_input = vam->input;
10205   vl_api_want_ip4_arp_events_t *mp;
10206   f64 timeout;
10207   ip4_address_t address;
10208   int address_set = 0;
10209   u32 enable_disable = 1;
10210
10211   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10212     {
10213       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10214         address_set = 1;
10215       else if (unformat (line_input, "del"))
10216         enable_disable = 0;
10217       else
10218         break;
10219     }
10220
10221   if (address_set == 0)
10222     {
10223       errmsg ("missing addresses\n");
10224       return -99;
10225     }
10226
10227   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10228   mp->enable_disable = enable_disable;
10229   mp->pid = getpid ();
10230   mp->address = address.as_u32;
10231
10232   S;
10233   W;
10234 }
10235
10236 static int
10237 api_want_ip6_nd_events (vat_main_t * vam)
10238 {
10239   unformat_input_t *line_input = vam->input;
10240   vl_api_want_ip6_nd_events_t *mp;
10241   f64 timeout;
10242   ip6_address_t address;
10243   int address_set = 0;
10244   u32 enable_disable = 1;
10245
10246   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10247     {
10248       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10249         address_set = 1;
10250       else if (unformat (line_input, "del"))
10251         enable_disable = 0;
10252       else
10253         break;
10254     }
10255
10256   if (address_set == 0)
10257     {
10258       errmsg ("missing addresses\n");
10259       return -99;
10260     }
10261
10262   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10263   mp->enable_disable = enable_disable;
10264   mp->pid = getpid ();
10265   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10266
10267   S;
10268   W;
10269 }
10270
10271 static int
10272 api_input_acl_set_interface (vat_main_t * vam)
10273 {
10274   unformat_input_t *i = vam->input;
10275   vl_api_input_acl_set_interface_t *mp;
10276   f64 timeout;
10277   u32 sw_if_index;
10278   int sw_if_index_set;
10279   u32 ip4_table_index = ~0;
10280   u32 ip6_table_index = ~0;
10281   u32 l2_table_index = ~0;
10282   u8 is_add = 1;
10283
10284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10285     {
10286       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10287         sw_if_index_set = 1;
10288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10289         sw_if_index_set = 1;
10290       else if (unformat (i, "del"))
10291         is_add = 0;
10292       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10293         ;
10294       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10295         ;
10296       else if (unformat (i, "l2-table %d", &l2_table_index))
10297         ;
10298       else
10299         {
10300           clib_warning ("parse error '%U'", format_unformat_error, i);
10301           return -99;
10302         }
10303     }
10304
10305   if (sw_if_index_set == 0)
10306     {
10307       errmsg ("missing interface name or sw_if_index\n");
10308       return -99;
10309     }
10310
10311   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10312
10313   mp->sw_if_index = ntohl (sw_if_index);
10314   mp->ip4_table_index = ntohl (ip4_table_index);
10315   mp->ip6_table_index = ntohl (ip6_table_index);
10316   mp->l2_table_index = ntohl (l2_table_index);
10317   mp->is_add = is_add;
10318
10319   S;
10320   W;
10321   /* NOTREACHED */
10322   return 0;
10323 }
10324
10325 static int
10326 api_ip_address_dump (vat_main_t * vam)
10327 {
10328   unformat_input_t *i = vam->input;
10329   vl_api_ip_address_dump_t *mp;
10330   u32 sw_if_index = ~0;
10331   u8 sw_if_index_set = 0;
10332   u8 ipv4_set = 0;
10333   u8 ipv6_set = 0;
10334   f64 timeout;
10335
10336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10337     {
10338       if (unformat (i, "sw_if_index %d", &sw_if_index))
10339         sw_if_index_set = 1;
10340       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10341         sw_if_index_set = 1;
10342       else if (unformat (i, "ipv4"))
10343         ipv4_set = 1;
10344       else if (unformat (i, "ipv6"))
10345         ipv6_set = 1;
10346       else
10347         break;
10348     }
10349
10350   if (ipv4_set && ipv6_set)
10351     {
10352       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10353       return -99;
10354     }
10355
10356   if ((!ipv4_set) && (!ipv6_set))
10357     {
10358       errmsg ("no ipv4 nor ipv6 flag set\n");
10359       return -99;
10360     }
10361
10362   if (sw_if_index_set == 0)
10363     {
10364       errmsg ("missing interface name or sw_if_index\n");
10365       return -99;
10366     }
10367
10368   vam->current_sw_if_index = sw_if_index;
10369   vam->is_ipv6 = ipv6_set;
10370
10371   M (IP_ADDRESS_DUMP, ip_address_dump);
10372   mp->sw_if_index = ntohl (sw_if_index);
10373   mp->is_ipv6 = ipv6_set;
10374   S;
10375
10376   /* Use a control ping for synchronization */
10377   {
10378     vl_api_control_ping_t *mp;
10379     M (CONTROL_PING, control_ping);
10380     S;
10381   }
10382   W;
10383 }
10384
10385 static int
10386 api_ip_dump (vat_main_t * vam)
10387 {
10388   vl_api_ip_dump_t *mp;
10389   unformat_input_t *in = vam->input;
10390   int ipv4_set = 0;
10391   int ipv6_set = 0;
10392   int is_ipv6;
10393   f64 timeout;
10394   int i;
10395
10396   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10397     {
10398       if (unformat (in, "ipv4"))
10399         ipv4_set = 1;
10400       else if (unformat (in, "ipv6"))
10401         ipv6_set = 1;
10402       else
10403         break;
10404     }
10405
10406   if (ipv4_set && ipv6_set)
10407     {
10408       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10409       return -99;
10410     }
10411
10412   if ((!ipv4_set) && (!ipv6_set))
10413     {
10414       errmsg ("no ipv4 nor ipv6 flag set\n");
10415       return -99;
10416     }
10417
10418   is_ipv6 = ipv6_set;
10419   vam->is_ipv6 = is_ipv6;
10420
10421   /* free old data */
10422   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10423     {
10424       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10425     }
10426   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10427
10428   M (IP_DUMP, ip_dump);
10429   mp->is_ipv6 = ipv6_set;
10430   S;
10431
10432   /* Use a control ping for synchronization */
10433   {
10434     vl_api_control_ping_t *mp;
10435     M (CONTROL_PING, control_ping);
10436     S;
10437   }
10438   W;
10439 }
10440
10441 static int
10442 api_ipsec_spd_add_del (vat_main_t * vam)
10443 {
10444 #if DPDK > 0
10445   unformat_input_t *i = vam->input;
10446   vl_api_ipsec_spd_add_del_t *mp;
10447   f64 timeout;
10448   u32 spd_id = ~0;
10449   u8 is_add = 1;
10450
10451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10452     {
10453       if (unformat (i, "spd_id %d", &spd_id))
10454         ;
10455       else if (unformat (i, "del"))
10456         is_add = 0;
10457       else
10458         {
10459           clib_warning ("parse error '%U'", format_unformat_error, i);
10460           return -99;
10461         }
10462     }
10463   if (spd_id == ~0)
10464     {
10465       errmsg ("spd_id must be set\n");
10466       return -99;
10467     }
10468
10469   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10470
10471   mp->spd_id = ntohl (spd_id);
10472   mp->is_add = is_add;
10473
10474   S;
10475   W;
10476   /* NOTREACHED */
10477   return 0;
10478 #else
10479   clib_warning ("unsupported (no dpdk)");
10480   return -99;
10481 #endif
10482 }
10483
10484 static int
10485 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10486 {
10487 #if DPDK > 0
10488   unformat_input_t *i = vam->input;
10489   vl_api_ipsec_interface_add_del_spd_t *mp;
10490   f64 timeout;
10491   u32 sw_if_index;
10492   u8 sw_if_index_set = 0;
10493   u32 spd_id = (u32) ~ 0;
10494   u8 is_add = 1;
10495
10496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10497     {
10498       if (unformat (i, "del"))
10499         is_add = 0;
10500       else if (unformat (i, "spd_id %d", &spd_id))
10501         ;
10502       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10503         sw_if_index_set = 1;
10504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10505         sw_if_index_set = 1;
10506       else
10507         {
10508           clib_warning ("parse error '%U'", format_unformat_error, i);
10509           return -99;
10510         }
10511
10512     }
10513
10514   if (spd_id == (u32) ~ 0)
10515     {
10516       errmsg ("spd_id must be set\n");
10517       return -99;
10518     }
10519
10520   if (sw_if_index_set == 0)
10521     {
10522       errmsg ("missing interface name or sw_if_index\n");
10523       return -99;
10524     }
10525
10526   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10527
10528   mp->spd_id = ntohl (spd_id);
10529   mp->sw_if_index = ntohl (sw_if_index);
10530   mp->is_add = is_add;
10531
10532   S;
10533   W;
10534   /* NOTREACHED */
10535   return 0;
10536 #else
10537   clib_warning ("unsupported (no dpdk)");
10538   return -99;
10539 #endif
10540 }
10541
10542 static int
10543 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10544 {
10545 #if DPDK > 0
10546   unformat_input_t *i = vam->input;
10547   vl_api_ipsec_spd_add_del_entry_t *mp;
10548   f64 timeout;
10549   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10550   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10551   i32 priority = 0;
10552   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10553   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10554   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10555   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10556
10557   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10558   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10559   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10560   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10561   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10562   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "del"))
10567         is_add = 0;
10568       if (unformat (i, "outbound"))
10569         is_outbound = 1;
10570       if (unformat (i, "inbound"))
10571         is_outbound = 0;
10572       else if (unformat (i, "spd_id %d", &spd_id))
10573         ;
10574       else if (unformat (i, "sa_id %d", &sa_id))
10575         ;
10576       else if (unformat (i, "priority %d", &priority))
10577         ;
10578       else if (unformat (i, "protocol %d", &protocol))
10579         ;
10580       else if (unformat (i, "lport_start %d", &lport_start))
10581         ;
10582       else if (unformat (i, "lport_stop %d", &lport_stop))
10583         ;
10584       else if (unformat (i, "rport_start %d", &rport_start))
10585         ;
10586       else if (unformat (i, "rport_stop %d", &rport_stop))
10587         ;
10588       else
10589         if (unformat
10590             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10591         {
10592           is_ipv6 = 0;
10593           is_ip_any = 0;
10594         }
10595       else
10596         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10597         {
10598           is_ipv6 = 0;
10599           is_ip_any = 0;
10600         }
10601       else
10602         if (unformat
10603             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10604         {
10605           is_ipv6 = 0;
10606           is_ip_any = 0;
10607         }
10608       else
10609         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10610         {
10611           is_ipv6 = 0;
10612           is_ip_any = 0;
10613         }
10614       else
10615         if (unformat
10616             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10617         {
10618           is_ipv6 = 1;
10619           is_ip_any = 0;
10620         }
10621       else
10622         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10623         {
10624           is_ipv6 = 1;
10625           is_ip_any = 0;
10626         }
10627       else
10628         if (unformat
10629             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10630         {
10631           is_ipv6 = 1;
10632           is_ip_any = 0;
10633         }
10634       else
10635         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10636         {
10637           is_ipv6 = 1;
10638           is_ip_any = 0;
10639         }
10640       else
10641         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10642         {
10643           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10644             {
10645               clib_warning ("unsupported action: 'resolve'");
10646               return -99;
10647             }
10648         }
10649       else
10650         {
10651           clib_warning ("parse error '%U'", format_unformat_error, i);
10652           return -99;
10653         }
10654
10655     }
10656
10657   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10658
10659   mp->spd_id = ntohl (spd_id);
10660   mp->priority = ntohl (priority);
10661   mp->is_outbound = is_outbound;
10662
10663   mp->is_ipv6 = is_ipv6;
10664   if (is_ipv6 || is_ip_any)
10665     {
10666       clib_memcpy (mp->remote_address_start, &raddr6_start,
10667                    sizeof (ip6_address_t));
10668       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10669                    sizeof (ip6_address_t));
10670       clib_memcpy (mp->local_address_start, &laddr6_start,
10671                    sizeof (ip6_address_t));
10672       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10673                    sizeof (ip6_address_t));
10674     }
10675   else
10676     {
10677       clib_memcpy (mp->remote_address_start, &raddr4_start,
10678                    sizeof (ip4_address_t));
10679       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10680                    sizeof (ip4_address_t));
10681       clib_memcpy (mp->local_address_start, &laddr4_start,
10682                    sizeof (ip4_address_t));
10683       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10684                    sizeof (ip4_address_t));
10685     }
10686   mp->protocol = (u8) protocol;
10687   mp->local_port_start = ntohs ((u16) lport_start);
10688   mp->local_port_stop = ntohs ((u16) lport_stop);
10689   mp->remote_port_start = ntohs ((u16) rport_start);
10690   mp->remote_port_stop = ntohs ((u16) rport_stop);
10691   mp->policy = (u8) policy;
10692   mp->sa_id = ntohl (sa_id);
10693   mp->is_add = is_add;
10694   mp->is_ip_any = is_ip_any;
10695   S;
10696   W;
10697   /* NOTREACHED */
10698   return 0;
10699 #else
10700   clib_warning ("unsupported (no dpdk)");
10701   return -99;
10702 #endif
10703 }
10704
10705 static int
10706 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10707 {
10708 #if DPDK > 0
10709   unformat_input_t *i = vam->input;
10710   vl_api_ipsec_sad_add_del_entry_t *mp;
10711   f64 timeout;
10712   u32 sad_id = 0, spi = 0;
10713   u8 *ck = 0, *ik = 0;
10714   u8 is_add = 1;
10715
10716   u8 protocol = IPSEC_PROTOCOL_AH;
10717   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10718   u32 crypto_alg = 0, integ_alg = 0;
10719   ip4_address_t tun_src4;
10720   ip4_address_t tun_dst4;
10721   ip6_address_t tun_src6;
10722   ip6_address_t tun_dst6;
10723
10724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10725     {
10726       if (unformat (i, "del"))
10727         is_add = 0;
10728       else if (unformat (i, "sad_id %d", &sad_id))
10729         ;
10730       else if (unformat (i, "spi %d", &spi))
10731         ;
10732       else if (unformat (i, "esp"))
10733         protocol = IPSEC_PROTOCOL_ESP;
10734       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10735         {
10736           is_tunnel = 1;
10737           is_tunnel_ipv6 = 0;
10738         }
10739       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10740         {
10741           is_tunnel = 1;
10742           is_tunnel_ipv6 = 0;
10743         }
10744       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10745         {
10746           is_tunnel = 1;
10747           is_tunnel_ipv6 = 1;
10748         }
10749       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10750         {
10751           is_tunnel = 1;
10752           is_tunnel_ipv6 = 1;
10753         }
10754       else
10755         if (unformat
10756             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10757         {
10758           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10759               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10760             {
10761               clib_warning ("unsupported crypto-alg: '%U'",
10762                             format_ipsec_crypto_alg, crypto_alg);
10763               return -99;
10764             }
10765         }
10766       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10767         ;
10768       else
10769         if (unformat
10770             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10771         {
10772           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10773               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10774             {
10775               clib_warning ("unsupported integ-alg: '%U'",
10776                             format_ipsec_integ_alg, integ_alg);
10777               return -99;
10778             }
10779         }
10780       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10781         ;
10782       else
10783         {
10784           clib_warning ("parse error '%U'", format_unformat_error, i);
10785           return -99;
10786         }
10787
10788     }
10789
10790   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10791
10792   mp->sad_id = ntohl (sad_id);
10793   mp->is_add = is_add;
10794   mp->protocol = protocol;
10795   mp->spi = ntohl (spi);
10796   mp->is_tunnel = is_tunnel;
10797   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10798   mp->crypto_algorithm = crypto_alg;
10799   mp->integrity_algorithm = integ_alg;
10800   mp->crypto_key_length = vec_len (ck);
10801   mp->integrity_key_length = vec_len (ik);
10802
10803   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10804     mp->crypto_key_length = sizeof (mp->crypto_key);
10805
10806   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10807     mp->integrity_key_length = sizeof (mp->integrity_key);
10808
10809   if (ck)
10810     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10811   if (ik)
10812     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10813
10814   if (is_tunnel)
10815     {
10816       if (is_tunnel_ipv6)
10817         {
10818           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10819                        sizeof (ip6_address_t));
10820           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10821                        sizeof (ip6_address_t));
10822         }
10823       else
10824         {
10825           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10826                        sizeof (ip4_address_t));
10827           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10828                        sizeof (ip4_address_t));
10829         }
10830     }
10831
10832   S;
10833   W;
10834   /* NOTREACHED */
10835   return 0;
10836 #else
10837   clib_warning ("unsupported (no dpdk)");
10838   return -99;
10839 #endif
10840 }
10841
10842 static int
10843 api_ipsec_sa_set_key (vat_main_t * vam)
10844 {
10845 #if DPDK > 0
10846   unformat_input_t *i = vam->input;
10847   vl_api_ipsec_sa_set_key_t *mp;
10848   f64 timeout;
10849   u32 sa_id;
10850   u8 *ck = 0, *ik = 0;
10851
10852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (i, "sa_id %d", &sa_id))
10855         ;
10856       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10857         ;
10858       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10859         ;
10860       else
10861         {
10862           clib_warning ("parse error '%U'", format_unformat_error, i);
10863           return -99;
10864         }
10865     }
10866
10867   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10868
10869   mp->sa_id = ntohl (sa_id);
10870   mp->crypto_key_length = vec_len (ck);
10871   mp->integrity_key_length = vec_len (ik);
10872
10873   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10874     mp->crypto_key_length = sizeof (mp->crypto_key);
10875
10876   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10877     mp->integrity_key_length = sizeof (mp->integrity_key);
10878
10879   if (ck)
10880     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10881   if (ik)
10882     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10883
10884   S;
10885   W;
10886   /* NOTREACHED */
10887   return 0;
10888 #else
10889   clib_warning ("unsupported (no dpdk)");
10890   return -99;
10891 #endif
10892 }
10893
10894 static int
10895 api_ikev2_profile_add_del (vat_main_t * vam)
10896 {
10897 #if DPDK > 0
10898   unformat_input_t *i = vam->input;
10899   vl_api_ikev2_profile_add_del_t *mp;
10900   f64 timeout;
10901   u8 is_add = 1;
10902   u8 *name = 0;
10903
10904   const char *valid_chars = "a-zA-Z0-9_";
10905
10906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10907     {
10908       if (unformat (i, "del"))
10909         is_add = 0;
10910       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10911         vec_add1 (name, 0);
10912       else
10913         {
10914           errmsg ("parse error '%U'", format_unformat_error, i);
10915           return -99;
10916         }
10917     }
10918
10919   if (!vec_len (name))
10920     {
10921       errmsg ("profile name must be specified");
10922       return -99;
10923     }
10924
10925   if (vec_len (name) > 64)
10926     {
10927       errmsg ("profile name too long");
10928       return -99;
10929     }
10930
10931   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10932
10933   clib_memcpy (mp->name, name, vec_len (name));
10934   mp->is_add = is_add;
10935   vec_free (name);
10936
10937   S;
10938   W;
10939   /* NOTREACHED */
10940   return 0;
10941 #else
10942   clib_warning ("unsupported (no dpdk)");
10943   return -99;
10944 #endif
10945 }
10946
10947 static int
10948 api_ikev2_profile_set_auth (vat_main_t * vam)
10949 {
10950 #if DPDK > 0
10951   unformat_input_t *i = vam->input;
10952   vl_api_ikev2_profile_set_auth_t *mp;
10953   f64 timeout;
10954   u8 *name = 0;
10955   u8 *data = 0;
10956   u32 auth_method = 0;
10957   u8 is_hex = 0;
10958
10959   const char *valid_chars = "a-zA-Z0-9_";
10960
10961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10962     {
10963       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10964         vec_add1 (name, 0);
10965       else if (unformat (i, "auth_method %U",
10966                          unformat_ikev2_auth_method, &auth_method))
10967         ;
10968       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10969         is_hex = 1;
10970       else if (unformat (i, "auth_data %v", &data))
10971         ;
10972       else
10973         {
10974           errmsg ("parse error '%U'", format_unformat_error, i);
10975           return -99;
10976         }
10977     }
10978
10979   if (!vec_len (name))
10980     {
10981       errmsg ("profile name must be specified");
10982       return -99;
10983     }
10984
10985   if (vec_len (name) > 64)
10986     {
10987       errmsg ("profile name too long");
10988       return -99;
10989     }
10990
10991   if (!vec_len (data))
10992     {
10993       errmsg ("auth_data must be specified");
10994       return -99;
10995     }
10996
10997   if (!auth_method)
10998     {
10999       errmsg ("auth_method must be specified");
11000       return -99;
11001     }
11002
11003   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11004
11005   mp->is_hex = is_hex;
11006   mp->auth_method = (u8) auth_method;
11007   mp->data_len = vec_len (data);
11008   clib_memcpy (mp->name, name, vec_len (name));
11009   clib_memcpy (mp->data, data, vec_len (data));
11010   vec_free (name);
11011   vec_free (data);
11012
11013   S;
11014   W;
11015   /* NOTREACHED */
11016   return 0;
11017 #else
11018   clib_warning ("unsupported (no dpdk)");
11019   return -99;
11020 #endif
11021 }
11022
11023 static int
11024 api_ikev2_profile_set_id (vat_main_t * vam)
11025 {
11026 #if DPDK > 0
11027   unformat_input_t *i = vam->input;
11028   vl_api_ikev2_profile_set_id_t *mp;
11029   f64 timeout;
11030   u8 *name = 0;
11031   u8 *data = 0;
11032   u8 is_local = 0;
11033   u32 id_type = 0;
11034   ip4_address_t ip4;
11035
11036   const char *valid_chars = "a-zA-Z0-9_";
11037
11038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11039     {
11040       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11041         vec_add1 (name, 0);
11042       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11043         ;
11044       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11045         {
11046           data = vec_new (u8, 4);
11047           clib_memcpy (data, ip4.as_u8, 4);
11048         }
11049       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11050         ;
11051       else if (unformat (i, "id_data %v", &data))
11052         ;
11053       else if (unformat (i, "local"))
11054         is_local = 1;
11055       else if (unformat (i, "remote"))
11056         is_local = 0;
11057       else
11058         {
11059           errmsg ("parse error '%U'", format_unformat_error, i);
11060           return -99;
11061         }
11062     }
11063
11064   if (!vec_len (name))
11065     {
11066       errmsg ("profile name must be specified");
11067       return -99;
11068     }
11069
11070   if (vec_len (name) > 64)
11071     {
11072       errmsg ("profile name too long");
11073       return -99;
11074     }
11075
11076   if (!vec_len (data))
11077     {
11078       errmsg ("id_data must be specified");
11079       return -99;
11080     }
11081
11082   if (!id_type)
11083     {
11084       errmsg ("id_type must be specified");
11085       return -99;
11086     }
11087
11088   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11089
11090   mp->is_local = is_local;
11091   mp->id_type = (u8) id_type;
11092   mp->data_len = vec_len (data);
11093   clib_memcpy (mp->name, name, vec_len (name));
11094   clib_memcpy (mp->data, data, vec_len (data));
11095   vec_free (name);
11096   vec_free (data);
11097
11098   S;
11099   W;
11100   /* NOTREACHED */
11101   return 0;
11102 #else
11103   clib_warning ("unsupported (no dpdk)");
11104   return -99;
11105 #endif
11106 }
11107
11108 static int
11109 api_ikev2_profile_set_ts (vat_main_t * vam)
11110 {
11111 #if DPDK > 0
11112   unformat_input_t *i = vam->input;
11113   vl_api_ikev2_profile_set_ts_t *mp;
11114   f64 timeout;
11115   u8 *name = 0;
11116   u8 is_local = 0;
11117   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11118   ip4_address_t start_addr, end_addr;
11119
11120   const char *valid_chars = "a-zA-Z0-9_";
11121
11122   start_addr.as_u32 = 0;
11123   end_addr.as_u32 = (u32) ~ 0;
11124
11125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11126     {
11127       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11128         vec_add1 (name, 0);
11129       else if (unformat (i, "protocol %d", &proto))
11130         ;
11131       else if (unformat (i, "start_port %d", &start_port))
11132         ;
11133       else if (unformat (i, "end_port %d", &end_port))
11134         ;
11135       else
11136         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11137         ;
11138       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11139         ;
11140       else if (unformat (i, "local"))
11141         is_local = 1;
11142       else if (unformat (i, "remote"))
11143         is_local = 0;
11144       else
11145         {
11146           errmsg ("parse error '%U'", format_unformat_error, i);
11147           return -99;
11148         }
11149     }
11150
11151   if (!vec_len (name))
11152     {
11153       errmsg ("profile name must be specified");
11154       return -99;
11155     }
11156
11157   if (vec_len (name) > 64)
11158     {
11159       errmsg ("profile name too long");
11160       return -99;
11161     }
11162
11163   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11164
11165   mp->is_local = is_local;
11166   mp->proto = (u8) proto;
11167   mp->start_port = (u16) start_port;
11168   mp->end_port = (u16) end_port;
11169   mp->start_addr = start_addr.as_u32;
11170   mp->end_addr = end_addr.as_u32;
11171   clib_memcpy (mp->name, name, vec_len (name));
11172   vec_free (name);
11173
11174   S;
11175   W;
11176   /* NOTREACHED */
11177   return 0;
11178 #else
11179   clib_warning ("unsupported (no dpdk)");
11180   return -99;
11181 #endif
11182 }
11183
11184 static int
11185 api_ikev2_set_local_key (vat_main_t * vam)
11186 {
11187 #if DPDK > 0
11188   unformat_input_t *i = vam->input;
11189   vl_api_ikev2_set_local_key_t *mp;
11190   f64 timeout;
11191   u8 *file = 0;
11192
11193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11194     {
11195       if (unformat (i, "file %v", &file))
11196         vec_add1 (file, 0);
11197       else
11198         {
11199           errmsg ("parse error '%U'", format_unformat_error, i);
11200           return -99;
11201         }
11202     }
11203
11204   if (!vec_len (file))
11205     {
11206       errmsg ("RSA key file must be specified");
11207       return -99;
11208     }
11209
11210   if (vec_len (file) > 256)
11211     {
11212       errmsg ("file name too long");
11213       return -99;
11214     }
11215
11216   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11217
11218   clib_memcpy (mp->key_file, file, vec_len (file));
11219   vec_free (file);
11220
11221   S;
11222   W;
11223   /* NOTREACHED */
11224   return 0;
11225 #else
11226   clib_warning ("unsupported (no dpdk)");
11227   return -99;
11228 #endif
11229 }
11230
11231 /*
11232  * MAP
11233  */
11234 static int
11235 api_map_add_domain (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_map_add_domain_t *mp;
11239   f64 timeout;
11240
11241   ip4_address_t ip4_prefix;
11242   ip6_address_t ip6_prefix;
11243   ip6_address_t ip6_src;
11244   u32 num_m_args = 0;
11245   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11246     0, psid_length = 0;
11247   u8 is_translation = 0;
11248   u32 mtu = 0;
11249   u32 ip6_src_len = 128;
11250
11251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11252     {
11253       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11254                     &ip4_prefix, &ip4_prefix_len))
11255         num_m_args++;
11256       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11257                          &ip6_prefix, &ip6_prefix_len))
11258         num_m_args++;
11259       else
11260         if (unformat
11261             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11262              &ip6_src_len))
11263         num_m_args++;
11264       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11265         num_m_args++;
11266       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11267         num_m_args++;
11268       else if (unformat (i, "psid-offset %d", &psid_offset))
11269         num_m_args++;
11270       else if (unformat (i, "psid-len %d", &psid_length))
11271         num_m_args++;
11272       else if (unformat (i, "mtu %d", &mtu))
11273         num_m_args++;
11274       else if (unformat (i, "map-t"))
11275         is_translation = 1;
11276       else
11277         {
11278           clib_warning ("parse error '%U'", format_unformat_error, i);
11279           return -99;
11280         }
11281     }
11282
11283   if (num_m_args < 3)
11284     {
11285       errmsg ("mandatory argument(s) missing\n");
11286       return -99;
11287     }
11288
11289   /* Construct the API message */
11290   M (MAP_ADD_DOMAIN, map_add_domain);
11291
11292   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11293   mp->ip4_prefix_len = ip4_prefix_len;
11294
11295   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11296   mp->ip6_prefix_len = ip6_prefix_len;
11297
11298   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11299   mp->ip6_src_prefix_len = ip6_src_len;
11300
11301   mp->ea_bits_len = ea_bits_len;
11302   mp->psid_offset = psid_offset;
11303   mp->psid_length = psid_length;
11304   mp->is_translation = is_translation;
11305   mp->mtu = htons (mtu);
11306
11307   /* send it... */
11308   S;
11309
11310   /* Wait for a reply, return good/bad news  */
11311   W;
11312 }
11313
11314 static int
11315 api_map_del_domain (vat_main_t * vam)
11316 {
11317   unformat_input_t *i = vam->input;
11318   vl_api_map_del_domain_t *mp;
11319   f64 timeout;
11320
11321   u32 num_m_args = 0;
11322   u32 index;
11323
11324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11325     {
11326       if (unformat (i, "index %d", &index))
11327         num_m_args++;
11328       else
11329         {
11330           clib_warning ("parse error '%U'", format_unformat_error, i);
11331           return -99;
11332         }
11333     }
11334
11335   if (num_m_args != 1)
11336     {
11337       errmsg ("mandatory argument(s) missing\n");
11338       return -99;
11339     }
11340
11341   /* Construct the API message */
11342   M (MAP_DEL_DOMAIN, map_del_domain);
11343
11344   mp->index = ntohl (index);
11345
11346   /* send it... */
11347   S;
11348
11349   /* Wait for a reply, return good/bad news  */
11350   W;
11351 }
11352
11353 static int
11354 api_map_add_del_rule (vat_main_t * vam)
11355 {
11356   unformat_input_t *i = vam->input;
11357   vl_api_map_add_del_rule_t *mp;
11358   f64 timeout;
11359   u8 is_add = 1;
11360   ip6_address_t ip6_dst;
11361   u32 num_m_args = 0, index, psid = 0;
11362
11363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11364     {
11365       if (unformat (i, "index %d", &index))
11366         num_m_args++;
11367       else if (unformat (i, "psid %d", &psid))
11368         num_m_args++;
11369       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11370         num_m_args++;
11371       else if (unformat (i, "del"))
11372         {
11373           is_add = 0;
11374         }
11375       else
11376         {
11377           clib_warning ("parse error '%U'", format_unformat_error, i);
11378           return -99;
11379         }
11380     }
11381
11382   /* Construct the API message */
11383   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11384
11385   mp->index = ntohl (index);
11386   mp->is_add = is_add;
11387   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11388   mp->psid = ntohs (psid);
11389
11390   /* send it... */
11391   S;
11392
11393   /* Wait for a reply, return good/bad news  */
11394   W;
11395 }
11396
11397 static int
11398 api_map_domain_dump (vat_main_t * vam)
11399 {
11400   vl_api_map_domain_dump_t *mp;
11401   f64 timeout;
11402
11403   /* Construct the API message */
11404   M (MAP_DOMAIN_DUMP, map_domain_dump);
11405
11406   /* send it... */
11407   S;
11408
11409   /* Use a control ping for synchronization */
11410   {
11411     vl_api_control_ping_t *mp;
11412     M (CONTROL_PING, control_ping);
11413     S;
11414   }
11415   W;
11416 }
11417
11418 static int
11419 api_map_rule_dump (vat_main_t * vam)
11420 {
11421   unformat_input_t *i = vam->input;
11422   vl_api_map_rule_dump_t *mp;
11423   f64 timeout;
11424   u32 domain_index = ~0;
11425
11426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11427     {
11428       if (unformat (i, "index %u", &domain_index))
11429         ;
11430       else
11431         break;
11432     }
11433
11434   if (domain_index == ~0)
11435     {
11436       clib_warning ("parse error: domain index expected");
11437       return -99;
11438     }
11439
11440   /* Construct the API message */
11441   M (MAP_RULE_DUMP, map_rule_dump);
11442
11443   mp->domain_index = htonl (domain_index);
11444
11445   /* send it... */
11446   S;
11447
11448   /* Use a control ping for synchronization */
11449   {
11450     vl_api_control_ping_t *mp;
11451     M (CONTROL_PING, control_ping);
11452     S;
11453   }
11454   W;
11455 }
11456
11457 static void vl_api_map_add_domain_reply_t_handler
11458   (vl_api_map_add_domain_reply_t * mp)
11459 {
11460   vat_main_t *vam = &vat_main;
11461   i32 retval = ntohl (mp->retval);
11462
11463   if (vam->async_mode)
11464     {
11465       vam->async_errors += (retval < 0);
11466     }
11467   else
11468     {
11469       vam->retval = retval;
11470       vam->result_ready = 1;
11471     }
11472 }
11473
11474 static void vl_api_map_add_domain_reply_t_handler_json
11475   (vl_api_map_add_domain_reply_t * mp)
11476 {
11477   vat_main_t *vam = &vat_main;
11478   vat_json_node_t node;
11479
11480   vat_json_init_object (&node);
11481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11482   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11483
11484   vat_json_print (vam->ofp, &node);
11485   vat_json_free (&node);
11486
11487   vam->retval = ntohl (mp->retval);
11488   vam->result_ready = 1;
11489 }
11490
11491 static int
11492 api_get_first_msg_id (vat_main_t * vam)
11493 {
11494   vl_api_get_first_msg_id_t *mp;
11495   f64 timeout;
11496   unformat_input_t *i = vam->input;
11497   u8 *name;
11498   u8 name_set = 0;
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "client %s", &name))
11503         name_set = 1;
11504       else
11505         break;
11506     }
11507
11508   if (name_set == 0)
11509     {
11510       errmsg ("missing client name\n");
11511       return -99;
11512     }
11513   vec_add1 (name, 0);
11514
11515   if (vec_len (name) > 63)
11516     {
11517       errmsg ("client name too long\n");
11518       return -99;
11519     }
11520
11521   M (GET_FIRST_MSG_ID, get_first_msg_id);
11522   clib_memcpy (mp->name, name, vec_len (name));
11523   S;
11524   W;
11525   /* NOTREACHED */
11526   return 0;
11527 }
11528
11529 static int
11530 api_cop_interface_enable_disable (vat_main_t * vam)
11531 {
11532   unformat_input_t *line_input = vam->input;
11533   vl_api_cop_interface_enable_disable_t *mp;
11534   f64 timeout;
11535   u32 sw_if_index = ~0;
11536   u8 enable_disable = 1;
11537
11538   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11539     {
11540       if (unformat (line_input, "disable"))
11541         enable_disable = 0;
11542       if (unformat (line_input, "enable"))
11543         enable_disable = 1;
11544       else if (unformat (line_input, "%U", unformat_sw_if_index,
11545                          vam, &sw_if_index))
11546         ;
11547       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11548         ;
11549       else
11550         break;
11551     }
11552
11553   if (sw_if_index == ~0)
11554     {
11555       errmsg ("missing interface name or sw_if_index\n");
11556       return -99;
11557     }
11558
11559   /* Construct the API message */
11560   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11561   mp->sw_if_index = ntohl (sw_if_index);
11562   mp->enable_disable = enable_disable;
11563
11564   /* send it... */
11565   S;
11566   /* Wait for the reply */
11567   W;
11568 }
11569
11570 static int
11571 api_cop_whitelist_enable_disable (vat_main_t * vam)
11572 {
11573   unformat_input_t *line_input = vam->input;
11574   vl_api_cop_whitelist_enable_disable_t *mp;
11575   f64 timeout;
11576   u32 sw_if_index = ~0;
11577   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11578   u32 fib_id = 0;
11579
11580   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11581     {
11582       if (unformat (line_input, "ip4"))
11583         ip4 = 1;
11584       else if (unformat (line_input, "ip6"))
11585         ip6 = 1;
11586       else if (unformat (line_input, "default"))
11587         default_cop = 1;
11588       else if (unformat (line_input, "%U", unformat_sw_if_index,
11589                          vam, &sw_if_index))
11590         ;
11591       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11592         ;
11593       else if (unformat (line_input, "fib-id %d", &fib_id))
11594         ;
11595       else
11596         break;
11597     }
11598
11599   if (sw_if_index == ~0)
11600     {
11601       errmsg ("missing interface name or sw_if_index\n");
11602       return -99;
11603     }
11604
11605   /* Construct the API message */
11606   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11607   mp->sw_if_index = ntohl (sw_if_index);
11608   mp->fib_id = ntohl (fib_id);
11609   mp->ip4 = ip4;
11610   mp->ip6 = ip6;
11611   mp->default_cop = default_cop;
11612
11613   /* send it... */
11614   S;
11615   /* Wait for the reply */
11616   W;
11617 }
11618
11619 static int
11620 api_get_node_graph (vat_main_t * vam)
11621 {
11622   vl_api_get_node_graph_t *mp;
11623   f64 timeout;
11624
11625   M (GET_NODE_GRAPH, get_node_graph);
11626
11627   /* send it... */
11628   S;
11629   /* Wait for the reply */
11630   W;
11631 }
11632
11633 /* *INDENT-OFF* */
11634 /** Used for parsing LISP eids */
11635 typedef CLIB_PACKED(struct{
11636   u8 addr[16];   /**< eid address */
11637   u32 len;       /**< prefix length if IP */
11638   u8 type;      /**< type of eid */
11639 }) lisp_eid_vat_t;
11640 /* *INDENT-ON* */
11641
11642 static uword
11643 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11644 {
11645   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11646
11647   memset (a, 0, sizeof (a[0]));
11648
11649   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11650     {
11651       a->type = 0;              /* ipv4 type */
11652     }
11653   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11654     {
11655       a->type = 1;              /* ipv6 type */
11656     }
11657   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11658     {
11659       a->type = 2;              /* mac type */
11660     }
11661   else
11662     {
11663       return 0;
11664     }
11665
11666   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11667     {
11668       return 0;
11669     }
11670
11671   return 1;
11672 }
11673
11674 static int
11675 lisp_eid_size_vat (u8 type)
11676 {
11677   switch (type)
11678     {
11679     case 0:
11680       return 4;
11681     case 1:
11682       return 16;
11683     case 2:
11684       return 6;
11685     }
11686   return 0;
11687 }
11688
11689 static void
11690 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11691 {
11692   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11693 }
11694
11695 /* *INDENT-OFF* */
11696 /** Used for transferring locators via VPP API */
11697 typedef CLIB_PACKED(struct
11698 {
11699   u32 sw_if_index; /**< locator sw_if_index */
11700   u8 priority; /**< locator priority */
11701   u8 weight;   /**< locator weight */
11702 }) ls_locator_t;
11703 /* *INDENT-ON* */
11704
11705 static int
11706 api_lisp_add_del_locator_set (vat_main_t * vam)
11707 {
11708   unformat_input_t *input = vam->input;
11709   vl_api_lisp_add_del_locator_set_t *mp;
11710   f64 timeout = ~0;
11711   u8 is_add = 1;
11712   u8 *locator_set_name = NULL;
11713   u8 locator_set_name_set = 0;
11714   ls_locator_t locator, *locators = 0;
11715   u32 sw_if_index, priority, weight;
11716
11717   /* Parse args required to build the message */
11718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11719     {
11720       if (unformat (input, "del"))
11721         {
11722           is_add = 0;
11723         }
11724       else if (unformat (input, "locator-set %s", &locator_set_name))
11725         {
11726           locator_set_name_set = 1;
11727         }
11728       else if (unformat (input, "sw_if_index %u p %u w %u",
11729                          &sw_if_index, &priority, &weight))
11730         {
11731           locator.sw_if_index = htonl (sw_if_index);
11732           locator.priority = priority;
11733           locator.weight = weight;
11734           vec_add1 (locators, locator);
11735         }
11736       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11737                          vam, &sw_if_index, &priority, &weight))
11738         {
11739           locator.sw_if_index = htonl (sw_if_index);
11740           locator.priority = priority;
11741           locator.weight = weight;
11742           vec_add1 (locators, locator);
11743         }
11744       else
11745         break;
11746     }
11747
11748   if (locator_set_name_set == 0)
11749     {
11750       errmsg ("missing locator-set name");
11751       vec_free (locators);
11752       return -99;
11753     }
11754
11755   if (vec_len (locator_set_name) > 64)
11756     {
11757       errmsg ("locator-set name too long\n");
11758       vec_free (locator_set_name);
11759       vec_free (locators);
11760       return -99;
11761     }
11762   vec_add1 (locator_set_name, 0);
11763
11764   /* Construct the API message */
11765   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11766
11767   mp->is_add = is_add;
11768   clib_memcpy (mp->locator_set_name, locator_set_name,
11769                vec_len (locator_set_name));
11770   vec_free (locator_set_name);
11771
11772   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11773   if (locators)
11774     clib_memcpy (mp->locators, locators,
11775                  (sizeof (ls_locator_t) * vec_len (locators)));
11776   vec_free (locators);
11777
11778   /* send it... */
11779   S;
11780
11781   /* Wait for a reply... */
11782   W;
11783
11784   /* NOTREACHED */
11785   return 0;
11786 }
11787
11788 static int
11789 api_lisp_add_del_locator (vat_main_t * vam)
11790 {
11791   unformat_input_t *input = vam->input;
11792   vl_api_lisp_add_del_locator_t *mp;
11793   f64 timeout = ~0;
11794   u32 tmp_if_index = ~0;
11795   u32 sw_if_index = ~0;
11796   u8 sw_if_index_set = 0;
11797   u8 sw_if_index_if_name_set = 0;
11798   u32 priority = ~0;
11799   u8 priority_set = 0;
11800   u32 weight = ~0;
11801   u8 weight_set = 0;
11802   u8 is_add = 1;
11803   u8 *locator_set_name = NULL;
11804   u8 locator_set_name_set = 0;
11805
11806   /* Parse args required to build the message */
11807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11808     {
11809       if (unformat (input, "del"))
11810         {
11811           is_add = 0;
11812         }
11813       else if (unformat (input, "locator-set %s", &locator_set_name))
11814         {
11815           locator_set_name_set = 1;
11816         }
11817       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11818                          &tmp_if_index))
11819         {
11820           sw_if_index_if_name_set = 1;
11821           sw_if_index = tmp_if_index;
11822         }
11823       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11824         {
11825           sw_if_index_set = 1;
11826           sw_if_index = tmp_if_index;
11827         }
11828       else if (unformat (input, "p %d", &priority))
11829         {
11830           priority_set = 1;
11831         }
11832       else if (unformat (input, "w %d", &weight))
11833         {
11834           weight_set = 1;
11835         }
11836       else
11837         break;
11838     }
11839
11840   if (locator_set_name_set == 0)
11841     {
11842       errmsg ("missing locator-set name");
11843       return -99;
11844     }
11845
11846   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11847     {
11848       errmsg ("missing sw_if_index");
11849       vec_free (locator_set_name);
11850       return -99;
11851     }
11852
11853   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11854     {
11855       errmsg ("cannot use both params interface name and sw_if_index");
11856       vec_free (locator_set_name);
11857       return -99;
11858     }
11859
11860   if (priority_set == 0)
11861     {
11862       errmsg ("missing locator-set priority\n");
11863       vec_free (locator_set_name);
11864       return -99;
11865     }
11866
11867   if (weight_set == 0)
11868     {
11869       errmsg ("missing locator-set weight\n");
11870       vec_free (locator_set_name);
11871       return -99;
11872     }
11873
11874   if (vec_len (locator_set_name) > 64)
11875     {
11876       errmsg ("locator-set name too long\n");
11877       vec_free (locator_set_name);
11878       return -99;
11879     }
11880   vec_add1 (locator_set_name, 0);
11881
11882   /* Construct the API message */
11883   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11884
11885   mp->is_add = is_add;
11886   mp->sw_if_index = ntohl (sw_if_index);
11887   mp->priority = priority;
11888   mp->weight = weight;
11889   clib_memcpy (mp->locator_set_name, locator_set_name,
11890                vec_len (locator_set_name));
11891   vec_free (locator_set_name);
11892
11893   /* send it... */
11894   S;
11895
11896   /* Wait for a reply... */
11897   W;
11898
11899   /* NOTREACHED */
11900   return 0;
11901 }
11902
11903 static int
11904 api_lisp_add_del_local_eid (vat_main_t * vam)
11905 {
11906   unformat_input_t *input = vam->input;
11907   vl_api_lisp_add_del_local_eid_t *mp;
11908   f64 timeout = ~0;
11909   u8 is_add = 1;
11910   u8 eid_set = 0;
11911   lisp_eid_vat_t _eid, *eid = &_eid;
11912   u8 *locator_set_name = 0;
11913   u8 locator_set_name_set = 0;
11914   u32 vni = 0;
11915
11916   /* Parse args required to build the message */
11917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11918     {
11919       if (unformat (input, "del"))
11920         {
11921           is_add = 0;
11922         }
11923       else if (unformat (input, "vni %d", &vni))
11924         {
11925           ;
11926         }
11927       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11928         {
11929           eid_set = 1;
11930         }
11931       else if (unformat (input, "locator-set %s", &locator_set_name))
11932         {
11933           locator_set_name_set = 1;
11934         }
11935       else
11936         break;
11937     }
11938
11939   if (locator_set_name_set == 0)
11940     {
11941       errmsg ("missing locator-set name\n");
11942       return -99;
11943     }
11944
11945   if (0 == eid_set)
11946     {
11947       errmsg ("EID address not set!");
11948       vec_free (locator_set_name);
11949       return -99;
11950     }
11951
11952   if (vec_len (locator_set_name) > 64)
11953     {
11954       errmsg ("locator-set name too long\n");
11955       vec_free (locator_set_name);
11956       return -99;
11957     }
11958   vec_add1 (locator_set_name, 0);
11959
11960   /* Construct the API message */
11961   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11962
11963   mp->is_add = is_add;
11964   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11965   mp->eid_type = eid->type;
11966   mp->prefix_len = eid->len;
11967   mp->vni = clib_host_to_net_u32 (vni);
11968   clib_memcpy (mp->locator_set_name, locator_set_name,
11969                vec_len (locator_set_name));
11970
11971   vec_free (locator_set_name);
11972
11973   /* send it... */
11974   S;
11975
11976   /* Wait for a reply... */
11977   W;
11978
11979   /* NOTREACHED */
11980   return 0;
11981 }
11982
11983 /* *INDENT-OFF* */
11984 /** Used for transferring locators via VPP API */
11985 typedef CLIB_PACKED(struct
11986 {
11987   u8 is_ip4; /**< is locator an IPv4 address? */
11988   u8 priority; /**< locator priority */
11989   u8 weight;   /**< locator weight */
11990   u8 addr[16]; /**< IPv4/IPv6 address */
11991 }) rloc_t;
11992 /* *INDENT-ON* */
11993
11994 static int
11995 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11996 {
11997   unformat_input_t *input = vam->input;
11998   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11999   f64 timeout = ~0;
12000   u8 is_add = 1;
12001   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12002   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12003   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12004   u32 action = ~0, p, w;
12005   ip4_address_t rmt_rloc4, lcl_rloc4;
12006   ip6_address_t rmt_rloc6, lcl_rloc6;
12007   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12008
12009   memset (&rloc, 0, sizeof (rloc));
12010
12011   /* Parse args required to build the message */
12012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12013     {
12014       if (unformat (input, "del"))
12015         {
12016           is_add = 0;
12017         }
12018       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12019         {
12020           rmt_eid_set = 1;
12021         }
12022       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12023         {
12024           lcl_eid_set = 1;
12025         }
12026       else if (unformat (input, "p %d w %d", &p, &w))
12027         {
12028           if (!curr_rloc)
12029             {
12030               errmsg ("No RLOC configured for setting priority/weight!");
12031               return -99;
12032             }
12033           curr_rloc->priority = p;
12034           curr_rloc->weight = w;
12035         }
12036       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12037                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12038         {
12039           rloc.is_ip4 = 1;
12040
12041           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12042           rloc.priority = rloc.weight = 0;
12043           vec_add1 (lcl_locs, rloc);
12044
12045           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12046           vec_add1 (rmt_locs, rloc);
12047           /* priority and weight saved in rmt loc */
12048           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12049         }
12050       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12051                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12052         {
12053           rloc.is_ip4 = 0;
12054           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12055           rloc.priority = rloc.weight = 0;
12056           vec_add1 (lcl_locs, rloc);
12057
12058           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12059           vec_add1 (rmt_locs, rloc);
12060           /* priority and weight saved in rmt loc */
12061           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12062         }
12063       else if (unformat (input, "action %d", &action))
12064         {
12065           ;
12066         }
12067       else
12068         {
12069           clib_warning ("parse error '%U'", format_unformat_error, input);
12070           return -99;
12071         }
12072     }
12073
12074   if (!rmt_eid_set)
12075     {
12076       errmsg ("remote eid addresses not set\n");
12077       return -99;
12078     }
12079
12080   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12081     {
12082       errmsg ("eid types don't match\n");
12083       return -99;
12084     }
12085
12086   if (0 == rmt_locs && (u32) ~ 0 == action)
12087     {
12088       errmsg ("action not set for negative mapping\n");
12089       return -99;
12090     }
12091
12092   /* Construct the API message */
12093   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12094
12095   mp->is_add = is_add;
12096   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12097   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12098   mp->eid_type = rmt_eid->type;
12099   mp->rmt_len = rmt_eid->len;
12100   mp->lcl_len = lcl_eid->len;
12101   mp->action = action;
12102
12103   if (0 != rmt_locs && 0 != lcl_locs)
12104     {
12105       mp->loc_num = vec_len (rmt_locs);
12106       clib_memcpy (mp->lcl_locs, lcl_locs,
12107                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12108       clib_memcpy (mp->rmt_locs, rmt_locs,
12109                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12110     }
12111   vec_free (lcl_locs);
12112   vec_free (rmt_locs);
12113
12114   /* send it... */
12115   S;
12116
12117   /* Wait for a reply... */
12118   W;
12119
12120   /* NOTREACHED */
12121   return 0;
12122 }
12123
12124 static int
12125 api_lisp_add_del_map_resolver (vat_main_t * vam)
12126 {
12127   unformat_input_t *input = vam->input;
12128   vl_api_lisp_add_del_map_resolver_t *mp;
12129   f64 timeout = ~0;
12130   u8 is_add = 1;
12131   u8 ipv4_set = 0;
12132   u8 ipv6_set = 0;
12133   ip4_address_t ipv4;
12134   ip6_address_t ipv6;
12135
12136   /* Parse args required to build the message */
12137   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (input, "del"))
12140         {
12141           is_add = 0;
12142         }
12143       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12144         {
12145           ipv4_set = 1;
12146         }
12147       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12148         {
12149           ipv6_set = 1;
12150         }
12151       else
12152         break;
12153     }
12154
12155   if (ipv4_set && ipv6_set)
12156     {
12157       errmsg ("both eid v4 and v6 addresses set\n");
12158       return -99;
12159     }
12160
12161   if (!ipv4_set && !ipv6_set)
12162     {
12163       errmsg ("eid addresses not set\n");
12164       return -99;
12165     }
12166
12167   /* Construct the API message */
12168   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12169
12170   mp->is_add = is_add;
12171   if (ipv6_set)
12172     {
12173       mp->is_ipv6 = 1;
12174       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12175     }
12176   else
12177     {
12178       mp->is_ipv6 = 0;
12179       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12180     }
12181
12182   /* send it... */
12183   S;
12184
12185   /* Wait for a reply... */
12186   W;
12187
12188   /* NOTREACHED */
12189   return 0;
12190 }
12191
12192 static int
12193 api_lisp_gpe_enable_disable (vat_main_t * vam)
12194 {
12195   unformat_input_t *input = vam->input;
12196   vl_api_lisp_gpe_enable_disable_t *mp;
12197   f64 timeout = ~0;
12198   u8 is_set = 0;
12199   u8 is_en = 1;
12200
12201   /* Parse args required to build the message */
12202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12203     {
12204       if (unformat (input, "enable"))
12205         {
12206           is_set = 1;
12207           is_en = 1;
12208         }
12209       else if (unformat (input, "disable"))
12210         {
12211           is_set = 1;
12212           is_en = 0;
12213         }
12214       else
12215         break;
12216     }
12217
12218   if (is_set == 0)
12219     {
12220       errmsg ("Value not set\n");
12221       return -99;
12222     }
12223
12224   /* Construct the API message */
12225   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12226
12227   mp->is_en = is_en;
12228
12229   /* send it... */
12230   S;
12231
12232   /* Wait for a reply... */
12233   W;
12234
12235   /* NOTREACHED */
12236   return 0;
12237 }
12238
12239 static int
12240 api_lisp_enable_disable (vat_main_t * vam)
12241 {
12242   unformat_input_t *input = vam->input;
12243   vl_api_lisp_enable_disable_t *mp;
12244   f64 timeout = ~0;
12245   u8 is_set = 0;
12246   u8 is_en = 0;
12247
12248   /* Parse args required to build the message */
12249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12250     {
12251       if (unformat (input, "enable"))
12252         {
12253           is_set = 1;
12254           is_en = 1;
12255         }
12256       else if (unformat (input, "disable"))
12257         {
12258           is_set = 1;
12259         }
12260       else
12261         break;
12262     }
12263
12264   if (!is_set)
12265     {
12266       errmsg ("Value not set\n");
12267       return -99;
12268     }
12269
12270   /* Construct the API message */
12271   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12272
12273   mp->is_en = is_en;
12274
12275   /* send it... */
12276   S;
12277
12278   /* Wait for a reply... */
12279   W;
12280
12281   /* NOTREACHED */
12282   return 0;
12283 }
12284
12285 /**
12286  * Enable/disable LISP proxy ITR.
12287  *
12288  * @param vam vpp API test context
12289  * @return return code
12290  */
12291 static int
12292 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12293 {
12294   f64 timeout = ~0;
12295   u8 ls_name_set = 0;
12296   unformat_input_t *input = vam->input;
12297   vl_api_lisp_pitr_set_locator_set_t *mp;
12298   u8 is_add = 1;
12299   u8 *ls_name = 0;
12300
12301   /* Parse args required to build the message */
12302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12303     {
12304       if (unformat (input, "del"))
12305         is_add = 0;
12306       else if (unformat (input, "locator-set %s", &ls_name))
12307         ls_name_set = 1;
12308       else
12309         {
12310           errmsg ("parse error '%U'", format_unformat_error, input);
12311           return -99;
12312         }
12313     }
12314
12315   if (!ls_name_set)
12316     {
12317       errmsg ("locator-set name not set!");
12318       return -99;
12319     }
12320
12321   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12322
12323   mp->is_add = is_add;
12324   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12325   vec_free (ls_name);
12326
12327   /* send */
12328   S;
12329
12330   /* wait for reply */
12331   W;
12332
12333   /* notreached */
12334   return 0;
12335 }
12336
12337 static int
12338 api_show_lisp_pitr (vat_main_t * vam)
12339 {
12340   vl_api_show_lisp_pitr_t *mp;
12341   f64 timeout = ~0;
12342
12343   if (!vam->json_output)
12344     {
12345       fformat (vam->ofp, "%=20s\n", "lisp status:");
12346     }
12347
12348   M (SHOW_LISP_PITR, show_lisp_pitr);
12349   /* send it... */
12350   S;
12351
12352   /* Wait for a reply... */
12353   W;
12354
12355   /* NOTREACHED */
12356   return 0;
12357 }
12358
12359 /**
12360  * Add/delete mapping between vni and vrf
12361  */
12362 static int
12363 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12364 {
12365   f64 timeout = ~0;
12366   unformat_input_t *input = vam->input;
12367   vl_api_lisp_eid_table_add_del_map_t *mp;
12368   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12369   u32 vni, vrf, bd_index;
12370
12371   /* Parse args required to build the message */
12372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (input, "del"))
12375         is_add = 0;
12376       else if (unformat (input, "vrf %d", &vrf))
12377         vrf_set = 1;
12378       else if (unformat (input, "bd_index %d", &bd_index))
12379         bd_index_set = 1;
12380       else if (unformat (input, "vni %d", &vni))
12381         vni_set = 1;
12382       else
12383         break;
12384     }
12385
12386   if (!vni_set || (!vrf_set && !bd_index_set))
12387     {
12388       errmsg ("missing arguments!");
12389       return -99;
12390     }
12391
12392   if (vrf_set && bd_index_set)
12393     {
12394       errmsg ("error: both vrf and bd entered!");
12395       return -99;
12396     }
12397
12398   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12399
12400   mp->is_add = is_add;
12401   mp->vni = htonl (vni);
12402   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12403   mp->is_l2 = bd_index_set;
12404
12405   /* send */
12406   S;
12407
12408   /* wait for reply */
12409   W;
12410
12411   /* notreached */
12412   return 0;
12413 }
12414
12415 /**
12416  * Add/del remote mapping to/from LISP control plane
12417  *
12418  * @param vam vpp API test context
12419  * @return return code
12420  */
12421 static int
12422 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12423 {
12424   unformat_input_t *input = vam->input;
12425   vl_api_lisp_add_del_remote_mapping_t *mp;
12426   f64 timeout = ~0;
12427   u32 vni = 0;
12428   //TODO: seid need remove
12429   lisp_eid_vat_t _eid, *eid = &_eid;
12430   lisp_eid_vat_t _seid, *seid = &_seid;
12431   u8 is_add = 1, del_all = 0, eid_set = 0;
12432   u32 action = ~0, p, w;
12433   ip4_address_t rloc4;
12434   ip6_address_t rloc6;
12435   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12436
12437   memset (&rloc, 0, sizeof (rloc));
12438
12439   /* Parse args required to build the message */
12440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12441     {
12442       if (unformat (input, "del-all"))
12443         {
12444           del_all = 1;
12445         }
12446       else if (unformat (input, "del"))
12447         {
12448           is_add = 0;
12449         }
12450       else if (unformat (input, "add"))
12451         {
12452           is_add = 1;
12453         }
12454       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12455         {
12456           eid_set = 1;
12457         }
12458       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12459         {
12460           //TODO: Need remove, but first must be remove from CSIT test
12461         }
12462       else if (unformat (input, "vni %d", &vni))
12463         {
12464           ;
12465         }
12466       else if (unformat (input, "p %d w %d", &p, &w))
12467         {
12468           if (!curr_rloc)
12469             {
12470               errmsg ("No RLOC configured for setting priority/weight!");
12471               return -99;
12472             }
12473           curr_rloc->priority = p;
12474           curr_rloc->weight = w;
12475         }
12476       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12477         {
12478           rloc.is_ip4 = 1;
12479           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12480           vec_add1 (rlocs, rloc);
12481           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12482         }
12483       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12484         {
12485           rloc.is_ip4 = 0;
12486           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12487           vec_add1 (rlocs, rloc);
12488           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12489         }
12490       else if (unformat (input, "action %d", &action))
12491         {
12492           ;
12493         }
12494       else
12495         {
12496           clib_warning ("parse error '%U'", format_unformat_error, input);
12497           return -99;
12498         }
12499     }
12500
12501   if (0 == eid_set)
12502     {
12503       errmsg ("missing params!");
12504       return -99;
12505     }
12506
12507   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12508     {
12509       errmsg ("no action set for negative map-reply!");
12510       return -99;
12511     }
12512
12513   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12514   mp->is_add = is_add;
12515   mp->vni = htonl (vni);
12516   mp->action = (u8) action;
12517   mp->eid_len = eid->len;
12518   mp->del_all = del_all;
12519   mp->eid_type = eid->type;
12520   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12521
12522   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12523   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12524   vec_free (rlocs);
12525
12526   /* send it... */
12527   S;
12528
12529   /* Wait for a reply... */
12530   W;
12531
12532   /* NOTREACHED */
12533   return 0;
12534 }
12535
12536 /**
12537  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12538  * forwarding entries in data-plane accordingly.
12539  *
12540  * @param vam vpp API test context
12541  * @return return code
12542  */
12543 static int
12544 api_lisp_add_del_adjacency (vat_main_t * vam)
12545 {
12546   unformat_input_t *input = vam->input;
12547   vl_api_lisp_add_del_adjacency_t *mp;
12548   f64 timeout = ~0;
12549   u32 vni = 0;
12550   ip4_address_t seid4, deid4;
12551   ip6_address_t seid6, deid6;
12552   u8 deid_mac[6] = { 0 };
12553   u8 seid_mac[6] = { 0 };
12554   u8 deid_type, seid_type;
12555   u32 seid_len = 0, deid_len = 0, len;
12556   u8 is_add = 1;
12557
12558   seid_type = deid_type = (u8) ~ 0;
12559
12560   /* Parse args required to build the message */
12561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12562     {
12563       if (unformat (input, "del"))
12564         {
12565           is_add = 0;
12566         }
12567       else if (unformat (input, "add"))
12568         {
12569           is_add = 1;
12570         }
12571       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12572                          &deid4, &len))
12573         {
12574           deid_type = 0;        /* ipv4 */
12575           deid_len = len;
12576         }
12577       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12578                          &deid6, &len))
12579         {
12580           deid_type = 1;        /* ipv6 */
12581           deid_len = len;
12582         }
12583       else if (unformat (input, "deid %U", unformat_ethernet_address,
12584                          deid_mac))
12585         {
12586           deid_type = 2;        /* mac */
12587         }
12588       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12589                          &seid4, &len))
12590         {
12591           seid_type = 0;        /* ipv4 */
12592           seid_len = len;
12593         }
12594       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12595                          &seid6, &len))
12596         {
12597           seid_type = 1;        /* ipv6 */
12598           seid_len = len;
12599         }
12600       else if (unformat (input, "seid %U", unformat_ethernet_address,
12601                          seid_mac))
12602         {
12603           seid_type = 2;        /* mac */
12604         }
12605       else if (unformat (input, "vni %d", &vni))
12606         {
12607           ;
12608         }
12609       else
12610         {
12611           errmsg ("parse error '%U'", format_unformat_error, input);
12612           return -99;
12613         }
12614     }
12615
12616   if ((u8) ~ 0 == deid_type)
12617     {
12618       errmsg ("missing params!");
12619       return -99;
12620     }
12621
12622   if (seid_type != deid_type)
12623     {
12624       errmsg ("source and destination EIDs are of different types!");
12625       return -99;
12626     }
12627
12628   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12629   mp->is_add = is_add;
12630   mp->vni = htonl (vni);
12631   mp->seid_len = seid_len;
12632   mp->deid_len = deid_len;
12633   mp->eid_type = deid_type;
12634
12635   switch (mp->eid_type)
12636     {
12637     case 0:
12638       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12639       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12640       break;
12641     case 1:
12642       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12643       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12644       break;
12645     case 2:
12646       clib_memcpy (mp->seid, seid_mac, 6);
12647       clib_memcpy (mp->deid, deid_mac, 6);
12648       break;
12649     default:
12650       errmsg ("unknown EID type %d!", mp->eid_type);
12651       return 0;
12652     }
12653
12654   /* send it... */
12655   S;
12656
12657   /* Wait for a reply... */
12658   W;
12659
12660   /* NOTREACHED */
12661   return 0;
12662 }
12663
12664 static int
12665 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12666 {
12667   unformat_input_t *input = vam->input;
12668   vl_api_lisp_gpe_add_del_iface_t *mp;
12669   f64 timeout = ~0;
12670   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12671   u32 dp_table = 0, vni = 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, "up"))
12677         {
12678           action_set = 1;
12679           is_add = 1;
12680         }
12681       else if (unformat (input, "down"))
12682         {
12683           action_set = 1;
12684           is_add = 0;
12685         }
12686       else if (unformat (input, "table_id %d", &dp_table))
12687         {
12688           dp_table_set = 1;
12689         }
12690       else if (unformat (input, "bd_id %d", &dp_table))
12691         {
12692           dp_table_set = 1;
12693           is_l2 = 1;
12694         }
12695       else if (unformat (input, "vni %d", &vni))
12696         {
12697           vni_set = 1;
12698         }
12699       else
12700         break;
12701     }
12702
12703   if (action_set == 0)
12704     {
12705       errmsg ("Action not set\n");
12706       return -99;
12707     }
12708   if (dp_table_set == 0 || vni_set == 0)
12709     {
12710       errmsg ("vni and dp_table must be set\n");
12711       return -99;
12712     }
12713
12714   /* Construct the API message */
12715   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12716
12717   mp->is_add = is_add;
12718   mp->dp_table = dp_table;
12719   mp->is_l2 = is_l2;
12720   mp->vni = vni;
12721
12722   /* send it... */
12723   S;
12724
12725   /* Wait for a reply... */
12726   W;
12727
12728   /* NOTREACHED */
12729   return 0;
12730 }
12731
12732 /**
12733  * Add/del map request itr rlocs from LISP control plane and updates
12734  *
12735  * @param vam vpp API test context
12736  * @return return code
12737  */
12738 static int
12739 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12740 {
12741   unformat_input_t *input = vam->input;
12742   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12743   f64 timeout = ~0;
12744   u8 *locator_set_name = 0;
12745   u8 locator_set_name_set = 0;
12746   u8 is_add = 1;
12747
12748   /* Parse args required to build the message */
12749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12750     {
12751       if (unformat (input, "del"))
12752         {
12753           is_add = 0;
12754         }
12755       else if (unformat (input, "%_%v%_", &locator_set_name))
12756         {
12757           locator_set_name_set = 1;
12758         }
12759       else
12760         {
12761           clib_warning ("parse error '%U'", format_unformat_error, input);
12762           return -99;
12763         }
12764     }
12765
12766   if (is_add && !locator_set_name_set)
12767     {
12768       errmsg ("itr-rloc is not set!");
12769       return -99;
12770     }
12771
12772   if (is_add && vec_len (locator_set_name) > 64)
12773     {
12774       errmsg ("itr-rloc locator-set name too long\n");
12775       vec_free (locator_set_name);
12776       return -99;
12777     }
12778
12779   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12780   mp->is_add = is_add;
12781   if (is_add)
12782     {
12783       clib_memcpy (mp->locator_set_name, locator_set_name,
12784                    vec_len (locator_set_name));
12785     }
12786   else
12787     {
12788       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12789     }
12790   vec_free (locator_set_name);
12791
12792   /* send it... */
12793   S;
12794
12795   /* Wait for a reply... */
12796   W;
12797
12798   /* NOTREACHED */
12799   return 0;
12800 }
12801
12802 static int
12803 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12804                             u8 filter)
12805 {
12806   vl_api_lisp_locator_dump_t *mp;
12807   f64 timeout = ~0;
12808
12809   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12810
12811   mp->locator_set_index = htonl (locator_set_index);
12812   mp->filter = filter;
12813
12814   /* send it... */
12815   S;
12816
12817   /* Use a control ping for synchronization */
12818   {
12819     vl_api_noprint_control_ping_t *mp;
12820     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12821     S;
12822   }
12823   /* Wait for a reply... */
12824   W;
12825 }
12826
12827 static inline void
12828 clean_locator_set_message (vat_main_t * vam)
12829 {
12830   locator_set_msg_t *ls = 0;
12831
12832   vec_foreach (ls, vam->locator_set_msg)
12833   {
12834     vec_free (ls->locator_set_name);
12835   }
12836
12837   vec_free (vam->locator_set_msg);
12838 }
12839
12840 static int
12841 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12842 {
12843   locator_set_msg_t *ls;
12844   locator_msg_t *loc;
12845   u8 *tmp_str = 0;
12846   int i = 0, ret = 0;
12847
12848   vec_foreach (ls, vam->locator_set_msg)
12849   {
12850     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12851     if (ret)
12852       {
12853         vec_free (vam->locator_msg);
12854         clean_locator_set_message (vam);
12855         return ret;
12856       }
12857
12858     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12859                       ls->locator_set_index,
12860                       vec_len (vam->locator_msg) ? "" : "\n");
12861     i = 0;
12862     vec_foreach (loc, vam->locator_msg)
12863     {
12864       if (i)
12865         {
12866           tmp_str = format (tmp_str, "%=37s", " ");
12867         }
12868       if (loc->local)
12869         {
12870           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12871                             loc->sw_if_index, loc->priority, loc->weight);
12872         }
12873       else
12874         {
12875           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12876                             loc->is_ipv6 ? format_ip6_address :
12877                             format_ip4_address,
12878                             loc->ip_address, loc->priority, loc->weight);
12879         }
12880       i++;
12881     }
12882
12883     fformat (vam->ofp, "%s", tmp_str);
12884     vec_free (tmp_str);
12885     vec_free (vam->locator_msg);
12886   }
12887
12888   clean_locator_set_message (vam);
12889
12890   return ret;
12891 }
12892
12893 static int
12894 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12895 {
12896   locator_set_msg_t *ls;
12897   locator_msg_t *loc;
12898   vat_json_node_t *node = NULL;
12899   vat_json_node_t *locator_array;
12900   vat_json_node_t *locator;
12901   struct in6_addr ip6;
12902   struct in_addr ip4;
12903   int ret = 0;
12904
12905   if (!vec_len (vam->locator_set_msg))
12906     {
12907       /* just print [] */
12908       vat_json_init_array (&vam->json_tree);
12909       vat_json_print (vam->ofp, &vam->json_tree);
12910       vam->json_tree.type = VAT_JSON_NONE;
12911       return ret;
12912     }
12913
12914   if (VAT_JSON_ARRAY != vam->json_tree.type)
12915     {
12916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12917       vat_json_init_array (&vam->json_tree);
12918     }
12919
12920   vec_foreach (ls, vam->locator_set_msg)
12921   {
12922     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12923     if (ret)
12924       {
12925         vec_free (ls->locator_set_name);
12926         vec_free (vam->locator_msg);
12927         vec_free (vam->locator_set_msg);
12928         vat_json_free (&vam->json_tree);
12929         vam->json_tree.type = VAT_JSON_NONE;
12930         return ret;
12931       }
12932
12933     node = vat_json_array_add (&vam->json_tree);
12934     vat_json_init_object (node);
12935
12936     vat_json_object_add_uint (node, "locator-set-index",
12937                               ls->locator_set_index);
12938     vat_json_object_add_string_copy (node, "locator-set",
12939                                      ls->locator_set_name);
12940     locator_array = vat_json_object_add_list (node, "locator");
12941     vec_foreach (loc, vam->locator_msg)
12942     {
12943       locator = vat_json_array_add (locator_array);
12944       vat_json_init_object (locator);
12945       if (loc->local)
12946         {
12947           vat_json_object_add_uint (locator, "locator-index",
12948                                     loc->sw_if_index);
12949         }
12950       else
12951         {
12952           if (loc->is_ipv6)
12953             {
12954               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12955               vat_json_object_add_ip6 (locator, "locator", ip6);
12956             }
12957           else
12958             {
12959               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12960               vat_json_object_add_ip4 (locator, "locator", ip4);
12961             }
12962         }
12963       vat_json_object_add_uint (locator, "priority", loc->priority);
12964       vat_json_object_add_uint (locator, "weight", loc->weight);
12965     }
12966
12967     vec_free (ls->locator_set_name);
12968     vec_free (vam->locator_msg);
12969   }
12970
12971   vat_json_print (vam->ofp, &vam->json_tree);
12972   vat_json_free (&vam->json_tree);
12973   vam->json_tree.type = VAT_JSON_NONE;
12974
12975   vec_free (vam->locator_set_msg);
12976
12977   return ret;
12978 }
12979
12980 static int
12981 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12982                                 u32 * locator_set_index)
12983 {
12984   locator_set_msg_t *ls;
12985   int ret = 0;
12986
12987   *locator_set_index = ~0;
12988
12989   if (!vec_len (vam->locator_set_msg))
12990     {
12991       return ret;
12992     }
12993
12994   vec_foreach (ls, vam->locator_set_msg)
12995   {
12996     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12997       {
12998         *locator_set_index = ls->locator_set_index;
12999         vec_free (vam->locator_set_msg);
13000         return ret;
13001       }
13002   }
13003
13004   vec_free (vam->locator_set_msg);
13005
13006   return ret;
13007 }
13008
13009 static int
13010 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13011                        u32 * locator_set_index)
13012 {
13013   vl_api_lisp_locator_set_dump_t *mp;
13014   f64 timeout = ~0;
13015
13016   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13017   /* send it... */
13018   S;
13019
13020   /* Use a control ping for synchronization */
13021   {
13022     vl_api_noprint_control_ping_t *mp;
13023     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13024     S;
13025   }
13026
13027   vam->noprint_msg = 1;
13028   /* Wait for a reply... */
13029   /* *INDENT-OFF* */
13030   W_L
13031   ({
13032     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13033     vam->noprint_msg = 0;
13034   });
13035   /* *INDENT-ON* */
13036
13037   /* NOTREACHED */
13038   return 0;
13039 }
13040
13041 static inline int
13042 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13043                    u8 filter)
13044 {
13045   int ret = 0;
13046
13047   ASSERT (vam);
13048
13049   if (!vam->json_output)
13050     {
13051       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13052                "locator", "priority", "weight");
13053     }
13054
13055   if (locator_set)
13056     {
13057       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13058     }
13059
13060   if (!ret && ~0 == locator_set_index)
13061     {
13062       return -99;
13063     }
13064
13065   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13066
13067   return ret;
13068 }
13069
13070 static int
13071 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13072 {
13073   vl_api_lisp_locator_set_dump_t *mp;
13074   f64 timeout = ~0;
13075
13076   if (!vam->json_output)
13077     {
13078       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13079                "locator-set", "locator-set-index", "locator", "priority",
13080                "weight");
13081     }
13082
13083   vam->noprint_msg = 1;
13084
13085   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13086
13087   mp->filter = filter;
13088
13089   /* send it... */
13090   S;
13091
13092   /* Use a control ping for synchronization */
13093   {
13094     vl_api_noprint_control_ping_t *mp;
13095     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13096     S;
13097   }
13098
13099   /* Wait for a reply... */
13100   /* *INDENT-OFF* */
13101   W_L
13102   ({
13103     if (vam->noprint_msg)
13104       {
13105         if (!vam->json_output)
13106           {
13107             print_locator_in_locator_set(vam, filter);
13108           }
13109         else
13110           {
13111             json_locator_in_locator_set(vam, filter);
13112           }
13113       }
13114     vam->noprint_msg = 0;
13115   });
13116   /* *INDENT-ON* */
13117
13118   /* NOTREACHED */
13119   return 0;
13120 }
13121
13122 static int
13123 api_lisp_locator_set_dump (vat_main_t * vam)
13124 {
13125   unformat_input_t *input = vam->input;
13126   vam->noprint_msg = 0;
13127   u32 locator_set_index = ~0;
13128   u8 locator_set_index_set = 0;
13129   u8 *locator_set = 0;
13130   u8 locator_set_set = 0;
13131   u8 filter = 0;
13132   int ret = 0;
13133
13134   /* Parse args required to build the message */
13135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13136     {
13137       if (unformat (input, "locator-set-index %u", &locator_set_index))
13138         {
13139           locator_set_index_set = 1;
13140         }
13141       else if (unformat (input, "locator-set %s", &locator_set))
13142         {
13143           locator_set_set = 1;
13144         }
13145       else if (unformat (input, "local"))
13146         {
13147           filter = 1;
13148         }
13149       else if (unformat (input, "remote"))
13150         {
13151           filter = 2;
13152         }
13153       else
13154         {
13155           break;
13156         }
13157     }
13158
13159   if (locator_set_index_set && locator_set_set)
13160     {
13161       errmsg ("use only input parameter!\n");
13162       return -99;
13163     }
13164
13165   if (locator_set_index_set || locator_set_set)
13166     {
13167       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13168     }
13169   else
13170     {
13171       ret = lisp_locator_set_dump (vam, filter);
13172     }
13173
13174   vec_free (locator_set);
13175
13176   return ret;
13177 }
13178
13179 static int
13180 api_lisp_eid_table_map_dump (vat_main_t * vam)
13181 {
13182   u8 is_l2 = 0;
13183   u8 mode_set = 0;
13184   unformat_input_t *input = vam->input;
13185   vl_api_lisp_eid_table_map_dump_t *mp;
13186   f64 timeout = ~0;
13187
13188   /* Parse args required to build the message */
13189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13190     {
13191       if (unformat (input, "l2"))
13192         {
13193           is_l2 = 1;
13194           mode_set = 1;
13195         }
13196       else if (unformat (input, "l3"))
13197         {
13198           is_l2 = 0;
13199           mode_set = 1;
13200         }
13201       else
13202         {
13203           errmsg ("parse error '%U'", format_unformat_error, input);
13204           return -99;
13205         }
13206     }
13207
13208   if (!mode_set)
13209     {
13210       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13211       return -99;
13212     }
13213
13214   if (!vam->json_output)
13215     {
13216       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13217     }
13218
13219   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13220   mp->is_l2 = is_l2;
13221
13222   /* send it... */
13223   S;
13224
13225   /* Use a control ping for synchronization */
13226   {
13227     vl_api_control_ping_t *mp;
13228     M (CONTROL_PING, control_ping);
13229     S;
13230   }
13231   /* Wait for a reply... */
13232   W;
13233
13234   /* NOTREACHED */
13235   return 0;
13236 }
13237
13238 static int
13239 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13240 {
13241   vl_api_lisp_eid_table_vni_dump_t *mp;
13242   f64 timeout = ~0;
13243
13244   if (!vam->json_output)
13245     {
13246       fformat (vam->ofp, "VNI\n");
13247     }
13248
13249   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13250
13251   /* send it... */
13252   S;
13253
13254   /* Use a control ping for synchronization */
13255   {
13256     vl_api_control_ping_t *mp;
13257     M (CONTROL_PING, control_ping);
13258     S;
13259   }
13260   /* Wait for a reply... */
13261   W;
13262
13263   /* NOTREACHED */
13264   return 0;
13265 }
13266
13267 static int
13268 get_locator_set (vat_main_t * vam)
13269 {
13270   vl_api_lisp_locator_set_dump_t *mp;
13271   f64 timeout = ~0;
13272
13273   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13274   /* send it... */
13275   S;
13276
13277   /* Use a control ping for synchronization */
13278   {
13279     vl_api_noprint_control_ping_t *mp;
13280     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13281     S;
13282   }
13283
13284   /* Wait for a reply... */
13285   W;
13286
13287   /* NOTREACHED */
13288   return 0;
13289 }
13290
13291 static inline u8 *
13292 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13293                           int *ret)
13294 {
13295   u8 *(*format_eid) (u8 *, va_list *) = 0;
13296
13297   ASSERT (vam != NULL);
13298   ASSERT (eid_table != NULL);
13299
13300   if (ret)
13301     {
13302       *ret = 0;
13303     }
13304
13305   switch (eid_table->eid_type)
13306     {
13307     case 0:
13308     case 1:
13309       format_eid = (eid_table->eid_type ? format_ip6_address :
13310                     format_ip4_address);
13311       str = format (0, "[%d] %U/%d", eid_table->vni,
13312                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13313       break;
13314     case 2:
13315       str = format (0, "[%d] %U", eid_table->vni,
13316                     format_ethernet_address, eid_table->eid);
13317       break;
13318     default:
13319       errmsg ("unknown EID type %d!", eid_table->eid_type);
13320       if (ret)
13321         {
13322           *ret = -99;
13323         }
13324       return 0;
13325     }
13326
13327   return str;
13328 }
13329
13330 static inline u8 *
13331 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13332                                   eid_table_t * eid_table)
13333 {
13334   locator_set_msg_t *ls = 0;
13335
13336   ASSERT (vam != NULL);
13337   ASSERT (eid_table != NULL);
13338
13339   if (eid_table->is_local)
13340     {
13341       vec_foreach (ls, vam->locator_set_msg)
13342       {
13343         if (ls->locator_set_index == eid_table->locator_set_index)
13344           {
13345             str = format (0, "local(%s)", ls->locator_set_name);
13346             return str;
13347           }
13348       }
13349
13350       str = format (0, "local(N/A)");
13351     }
13352   else
13353     {
13354       str = format (0, "remote");
13355     }
13356
13357   return str;
13358 }
13359
13360 static inline u8 *
13361 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13362                               eid_table_t * eid_table)
13363 {
13364   locator_msg_t *loc = 0;
13365   int first_line = 1;
13366
13367   ASSERT (vam != NULL);
13368   ASSERT (eid_table != NULL);
13369
13370   if (~0 == eid_table->locator_set_index)
13371     {
13372       return format (0, "action: %d\n", eid_table->action);
13373     }
13374
13375   vec_foreach (loc, vam->locator_msg)
13376   {
13377     if (!first_line)
13378       {
13379         if (loc->local)
13380           {
13381             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13382           }
13383         else
13384           {
13385             str = format (str, "%=55s%-U\n", " ",
13386                           loc->is_ipv6 ? format_ip6_address :
13387                           format_ip4_address, loc->ip_address);
13388           }
13389
13390         continue;
13391       }
13392
13393     if (loc->local)
13394       {
13395         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13396                       eid_table->ttl, eid_table->authoritative);
13397       }
13398     else
13399       {
13400         str = format (str, "%-30U%-20u%-u\n",
13401                       loc->is_ipv6 ? format_ip6_address :
13402                       format_ip4_address,
13403                       loc->ip_address, eid_table->ttl,
13404                       eid_table->authoritative);
13405       }
13406     first_line = 0;
13407   }
13408
13409   return str;
13410 }
13411
13412 static int
13413 print_lisp_eid_table_dump (vat_main_t * vam)
13414 {
13415   eid_table_t *eid_table = 0;
13416   u8 *tmp_str = 0, *tmp_str2 = 0;
13417   int ret = 0;
13418
13419   ASSERT (vam != NULL);
13420
13421   ret = get_locator_set (vam);
13422   if (ret)
13423     {
13424       vec_free (vam->eid_tables);
13425       return ret;
13426     }
13427
13428   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13429            "ttl", "authoritative");
13430
13431   vec_foreach (eid_table, vam->eid_tables)
13432   {
13433     if (~0 != eid_table->locator_set_index)
13434       {
13435         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13436                                           0);
13437         if (ret)
13438           {
13439             vec_free (vam->locator_msg);
13440             clean_locator_set_message (vam);
13441             vec_free (vam->eid_tables);
13442             return ret;
13443           }
13444       }
13445
13446     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13447     if (ret)
13448       {
13449         vec_free (vam->locator_msg);
13450         clean_locator_set_message (vam);
13451         vec_free (vam->eid_tables);
13452         return ret;
13453       }
13454
13455     tmp_str = format (0, "%-35s", tmp_str2);
13456     vec_free (tmp_str2);
13457
13458     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13459     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13460     vec_free (tmp_str2);
13461
13462     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13463     tmp_str = format (tmp_str, "%-s", tmp_str2);
13464     vec_free (tmp_str2);
13465
13466     fformat (vam->ofp, "%s", tmp_str);
13467     vec_free (tmp_str);
13468     vec_free (vam->locator_msg);
13469   }
13470
13471   clean_locator_set_message (vam);
13472   vec_free (vam->eid_tables);
13473
13474   return ret;
13475 }
13476
13477 static inline void
13478 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13479                                 eid_table_t * eid_table)
13480 {
13481   locator_set_msg_t *ls = 0;
13482   u8 *s = 0;
13483
13484   ASSERT (vam != NULL);
13485   ASSERT (node != NULL);
13486   ASSERT (eid_table != NULL);
13487
13488   if (eid_table->is_local)
13489     {
13490       vec_foreach (ls, vam->locator_set_msg)
13491       {
13492         if (ls->locator_set_index == eid_table->locator_set_index)
13493           {
13494             vat_json_object_add_string_copy (node, "locator-set",
13495                                              ls->locator_set_name);
13496             return;
13497           }
13498       }
13499
13500       s = format (0, "N/A");
13501       vec_add1 (s, 0);
13502       vat_json_object_add_string_copy (node, "locator-set", s);
13503       vec_free (s);
13504     }
13505   else
13506     {
13507       s = format (0, "remote");
13508       vec_add1 (s, 0);
13509       vat_json_object_add_string_copy (node, "locator-set", s);
13510       vec_free (s);
13511     }
13512 }
13513
13514 static inline int
13515 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13516                         eid_table_t * eid_table)
13517 {
13518   u8 *s = 0;
13519   struct in6_addr ip6;
13520   struct in_addr ip4;
13521
13522   ASSERT (vam != NULL);
13523   ASSERT (node != NULL);
13524   ASSERT (eid_table != NULL);
13525
13526   switch (eid_table->eid_type)
13527     {
13528     case 0:
13529       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13530       vat_json_object_add_ip4 (node, "eid", ip4);
13531       vat_json_object_add_uint (node, "eid-prefix-len",
13532                                 eid_table->eid_prefix_len);
13533       break;
13534     case 1:
13535       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13536       vat_json_object_add_ip6 (node, "eid", ip6);
13537       vat_json_object_add_uint (node, "eid-prefix-len",
13538                                 eid_table->eid_prefix_len);
13539       break;
13540     case 2:
13541       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13542       vec_add1 (s, 0);
13543       vat_json_object_add_string_copy (node, "eid", s);
13544       vec_free (s);
13545       break;
13546     default:
13547       errmsg ("unknown EID type %d!", eid_table->eid_type);
13548       return -99;
13549     }
13550
13551   return 0;
13552 }
13553
13554 static inline void
13555 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13556                             eid_table_t * eid_table)
13557 {
13558   locator_msg_t *loc = 0;
13559   vat_json_node_t *locator_array = 0;
13560   vat_json_node_t *locator = 0;
13561   struct in6_addr ip6;
13562   struct in_addr ip4;
13563
13564   ASSERT (vam != NULL);
13565   ASSERT (node != NULL);
13566   ASSERT (eid_table != NULL);
13567
13568   locator_array = vat_json_object_add_list (node, "locator");
13569   vec_foreach (loc, vam->locator_msg)
13570   {
13571     locator = vat_json_array_add (locator_array);
13572     vat_json_init_object (locator);
13573     if (loc->local)
13574       {
13575         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13576       }
13577     else
13578       {
13579         if (loc->is_ipv6)
13580           {
13581             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13582             vat_json_object_add_ip6 (locator, "locator", ip6);
13583           }
13584         else
13585           {
13586             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13587             vat_json_object_add_ip4 (locator, "locator", ip4);
13588           }
13589       }
13590   }
13591 }
13592
13593 static int
13594 json_lisp_eid_table_dump (vat_main_t * vam)
13595 {
13596   eid_table_t *eid_table;
13597   vat_json_node_t *node = 0;
13598   int ret = 0;
13599
13600   ASSERT (vam != NULL);
13601
13602   ret = get_locator_set (vam);
13603   if (ret)
13604     {
13605       vec_free (vam->eid_tables);
13606       return ret;
13607     }
13608
13609   if (!vec_len (vam->eid_tables))
13610     {
13611       /* just print [] */
13612       vat_json_init_array (&vam->json_tree);
13613       vat_json_print (vam->ofp, &vam->json_tree);
13614       vam->json_tree.type = VAT_JSON_NONE;
13615       return ret;
13616     }
13617
13618   if (VAT_JSON_ARRAY != vam->json_tree.type)
13619     {
13620       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13621       vat_json_init_array (&vam->json_tree);
13622     }
13623
13624   vec_foreach (eid_table, vam->eid_tables)
13625   {
13626     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13627     if (ret)
13628       {
13629         vec_free (vam->locator_msg);
13630         vec_free (vam->eid_tables);
13631         clean_locator_set_message (vam);
13632         vat_json_free (&vam->json_tree);
13633         vam->json_tree.type = VAT_JSON_NONE;
13634         return ret;
13635       }
13636
13637     node = vat_json_array_add (&vam->json_tree);
13638     vat_json_init_object (node);
13639
13640     vat_json_object_add_uint (node, "vni", eid_table->vni);
13641
13642     json_locator_set_for_eid_table (vam, node, eid_table);
13643     ret = json_eid_for_eid_table (vam, node, eid_table);
13644     if (ret)
13645       {
13646         vec_free (vam->locator_msg);
13647         vec_free (vam->eid_tables);
13648         clean_locator_set_message (vam);
13649         vat_json_free (&vam->json_tree);
13650         vam->json_tree.type = VAT_JSON_NONE;
13651         return ret;
13652       }
13653
13654     json_locator_for_eid_table (vam, node, eid_table);
13655
13656     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13657     vat_json_object_add_uint (node, "authoritative",
13658                               eid_table->authoritative);
13659
13660     vec_free (vam->locator_msg);
13661   }
13662
13663   vat_json_print (vam->ofp, &vam->json_tree);
13664   vat_json_free (&vam->json_tree);
13665   vam->json_tree.type = VAT_JSON_NONE;
13666
13667   clean_locator_set_message (vam);
13668   vec_free (vam->eid_tables);
13669
13670   return ret;
13671 }
13672
13673 static int
13674 api_lisp_eid_table_dump (vat_main_t * vam)
13675 {
13676   unformat_input_t *i = vam->input;
13677   vl_api_lisp_eid_table_dump_t *mp;
13678   f64 timeout = ~0;
13679   struct in_addr ip4;
13680   struct in6_addr ip6;
13681   u8 mac[6];
13682   u8 eid_type = ~0, eid_set = 0;
13683   u32 prefix_length = ~0, t, vni = 0;
13684   u8 filter = 0;
13685
13686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13689         {
13690           eid_set = 1;
13691           eid_type = 0;
13692           prefix_length = t;
13693         }
13694       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13695         {
13696           eid_set = 1;
13697           eid_type = 1;
13698           prefix_length = t;
13699         }
13700       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13701         {
13702           eid_set = 1;
13703           eid_type = 2;
13704         }
13705       else if (unformat (i, "vni %d", &t))
13706         {
13707           vni = t;
13708         }
13709       else if (unformat (i, "local"))
13710         {
13711           filter = 1;
13712         }
13713       else if (unformat (i, "remote"))
13714         {
13715           filter = 2;
13716         }
13717       else
13718         {
13719           errmsg ("parse error '%U'", format_unformat_error, i);
13720           return -99;
13721         }
13722     }
13723
13724   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13725
13726   mp->filter = filter;
13727   if (eid_set)
13728     {
13729       mp->eid_set = 1;
13730       mp->vni = htonl (vni);
13731       mp->eid_type = eid_type;
13732       switch (eid_type)
13733         {
13734         case 0:
13735           mp->prefix_length = prefix_length;
13736           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13737           break;
13738         case 1:
13739           mp->prefix_length = prefix_length;
13740           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13741           break;
13742         case 2:
13743           clib_memcpy (mp->eid, mac, sizeof (mac));
13744           break;
13745         default:
13746           errmsg ("unknown EID type %d!", eid_type);
13747           return -99;
13748         }
13749     }
13750
13751   vam->noprint_msg = 1;
13752
13753   /* send it... */
13754   S;
13755
13756   /* Use a control ping for synchronization */
13757   {
13758     vl_api_noprint_control_ping_t *mp;
13759     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13760     S;
13761   }
13762
13763   /* Wait for a reply... */
13764   /* *INDENT-OFF* */
13765   W_L
13766   ({
13767     if (vam->noprint_msg)
13768       {
13769         if (!vam->json_output)
13770           {
13771             vam->retval = print_lisp_eid_table_dump(vam);
13772           }
13773         else
13774           {
13775             vam->retval = json_lisp_eid_table_dump(vam);
13776           }
13777       }
13778     vam->noprint_msg = 0;
13779   });
13780   /* *INDENT-ON* */
13781
13782   /* NOTREACHED */
13783   return 0;
13784 }
13785
13786 static int
13787 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13788 {
13789   vl_api_lisp_gpe_tunnel_dump_t *mp;
13790   f64 timeout = ~0;
13791
13792   if (!vam->json_output)
13793     {
13794       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13795                "%=16s%=16s%=16s%=16s%=16s\n",
13796                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13797                "Decap next", "Lisp version", "Flags", "Next protocol",
13798                "ver_res", "res", "iid");
13799     }
13800
13801   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13802   /* send it... */
13803   S;
13804
13805   /* Use a control ping for synchronization */
13806   {
13807     vl_api_control_ping_t *mp;
13808     M (CONTROL_PING, control_ping);
13809     S;
13810   }
13811   /* Wait for a reply... */
13812   W;
13813
13814   /* NOTREACHED */
13815   return 0;
13816 }
13817
13818 static int
13819 api_lisp_map_resolver_dump (vat_main_t * vam)
13820 {
13821   vl_api_lisp_map_resolver_dump_t *mp;
13822   f64 timeout = ~0;
13823
13824   if (!vam->json_output)
13825     {
13826       fformat (vam->ofp, "%=20s\n", "Map resolver");
13827     }
13828
13829   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13830   /* send it... */
13831   S;
13832
13833   /* Use a control ping for synchronization */
13834   {
13835     vl_api_control_ping_t *mp;
13836     M (CONTROL_PING, control_ping);
13837     S;
13838   }
13839   /* Wait for a reply... */
13840   W;
13841
13842   /* NOTREACHED */
13843   return 0;
13844 }
13845
13846 static int
13847 api_show_lisp_status (vat_main_t * vam)
13848 {
13849   vl_api_show_lisp_status_t *mp;
13850   f64 timeout = ~0;
13851
13852   if (!vam->json_output)
13853     {
13854       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13855     }
13856
13857   M (SHOW_LISP_STATUS, show_lisp_status);
13858   /* send it... */
13859   S;
13860   /* Wait for a reply... */
13861   W;
13862
13863   /* NOTREACHED */
13864   return 0;
13865 }
13866
13867 static int
13868 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13869 {
13870   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13871   f64 timeout = ~0;
13872
13873   if (!vam->json_output)
13874     {
13875       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13876     }
13877
13878   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13879   /* send it... */
13880   S;
13881   /* Wait for a reply... */
13882   W;
13883
13884   /* NOTREACHED */
13885   return 0;
13886 }
13887
13888 static int
13889 api_af_packet_create (vat_main_t * vam)
13890 {
13891   unformat_input_t *i = vam->input;
13892   vl_api_af_packet_create_t *mp;
13893   f64 timeout;
13894   u8 *host_if_name = 0;
13895   u8 hw_addr[6];
13896   u8 random_hw_addr = 1;
13897
13898   memset (hw_addr, 0, sizeof (hw_addr));
13899
13900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13901     {
13902       if (unformat (i, "name %s", &host_if_name))
13903         vec_add1 (host_if_name, 0);
13904       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13905         random_hw_addr = 0;
13906       else
13907         break;
13908     }
13909
13910   if (!vec_len (host_if_name))
13911     {
13912       errmsg ("host-interface name must be specified");
13913       return -99;
13914     }
13915
13916   if (vec_len (host_if_name) > 64)
13917     {
13918       errmsg ("host-interface name too long");
13919       return -99;
13920     }
13921
13922   M (AF_PACKET_CREATE, af_packet_create);
13923
13924   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13925   clib_memcpy (mp->hw_addr, hw_addr, 6);
13926   mp->use_random_hw_addr = random_hw_addr;
13927   vec_free (host_if_name);
13928
13929   S;
13930   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13931   /* NOTREACHED */
13932   return 0;
13933 }
13934
13935 static int
13936 api_af_packet_delete (vat_main_t * vam)
13937 {
13938   unformat_input_t *i = vam->input;
13939   vl_api_af_packet_delete_t *mp;
13940   f64 timeout;
13941   u8 *host_if_name = 0;
13942
13943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13944     {
13945       if (unformat (i, "name %s", &host_if_name))
13946         vec_add1 (host_if_name, 0);
13947       else
13948         break;
13949     }
13950
13951   if (!vec_len (host_if_name))
13952     {
13953       errmsg ("host-interface name must be specified");
13954       return -99;
13955     }
13956
13957   if (vec_len (host_if_name) > 64)
13958     {
13959       errmsg ("host-interface name too long");
13960       return -99;
13961     }
13962
13963   M (AF_PACKET_DELETE, af_packet_delete);
13964
13965   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13966   vec_free (host_if_name);
13967
13968   S;
13969   W;
13970   /* NOTREACHED */
13971   return 0;
13972 }
13973
13974 static int
13975 api_policer_add_del (vat_main_t * vam)
13976 {
13977   unformat_input_t *i = vam->input;
13978   vl_api_policer_add_del_t *mp;
13979   f64 timeout;
13980   u8 is_add = 1;
13981   u8 *name = 0;
13982   u32 cir = 0;
13983   u32 eir = 0;
13984   u64 cb = 0;
13985   u64 eb = 0;
13986   u8 rate_type = 0;
13987   u8 round_type = 0;
13988   u8 type = 0;
13989   u8 color_aware = 0;
13990   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13991
13992   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13993   conform_action.dscp = 0;
13994   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13995   exceed_action.dscp = 0;
13996   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13997   violate_action.dscp = 0;
13998
13999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14000     {
14001       if (unformat (i, "del"))
14002         is_add = 0;
14003       else if (unformat (i, "name %s", &name))
14004         vec_add1 (name, 0);
14005       else if (unformat (i, "cir %u", &cir))
14006         ;
14007       else if (unformat (i, "eir %u", &eir))
14008         ;
14009       else if (unformat (i, "cb %u", &cb))
14010         ;
14011       else if (unformat (i, "eb %u", &eb))
14012         ;
14013       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14014                          &rate_type))
14015         ;
14016       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14017                          &round_type))
14018         ;
14019       else if (unformat (i, "type %U", unformat_policer_type, &type))
14020         ;
14021       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14022                          &conform_action))
14023         ;
14024       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14025                          &exceed_action))
14026         ;
14027       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14028                          &violate_action))
14029         ;
14030       else if (unformat (i, "color-aware"))
14031         color_aware = 1;
14032       else
14033         break;
14034     }
14035
14036   if (!vec_len (name))
14037     {
14038       errmsg ("policer name must be specified");
14039       return -99;
14040     }
14041
14042   if (vec_len (name) > 64)
14043     {
14044       errmsg ("policer name too long");
14045       return -99;
14046     }
14047
14048   M (POLICER_ADD_DEL, policer_add_del);
14049
14050   clib_memcpy (mp->name, name, vec_len (name));
14051   vec_free (name);
14052   mp->is_add = is_add;
14053   mp->cir = cir;
14054   mp->eir = eir;
14055   mp->cb = cb;
14056   mp->eb = eb;
14057   mp->rate_type = rate_type;
14058   mp->round_type = round_type;
14059   mp->type = type;
14060   mp->conform_action_type = conform_action.action_type;
14061   mp->conform_dscp = conform_action.dscp;
14062   mp->exceed_action_type = exceed_action.action_type;
14063   mp->exceed_dscp = exceed_action.dscp;
14064   mp->violate_action_type = violate_action.action_type;
14065   mp->violate_dscp = violate_action.dscp;
14066   mp->color_aware = color_aware;
14067
14068   S;
14069   W;
14070   /* NOTREACHED */
14071   return 0;
14072 }
14073
14074 static int
14075 api_policer_dump (vat_main_t * vam)
14076 {
14077   unformat_input_t *i = vam->input;
14078   vl_api_policer_dump_t *mp;
14079   f64 timeout = ~0;
14080   u8 *match_name = 0;
14081   u8 match_name_valid = 0;
14082
14083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat (i, "name %s", &match_name))
14086         {
14087           vec_add1 (match_name, 0);
14088           match_name_valid = 1;
14089         }
14090       else
14091         break;
14092     }
14093
14094   M (POLICER_DUMP, policer_dump);
14095   mp->match_name_valid = match_name_valid;
14096   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14097   vec_free (match_name);
14098   /* send it... */
14099   S;
14100
14101   /* Use a control ping for synchronization */
14102   {
14103     vl_api_control_ping_t *mp;
14104     M (CONTROL_PING, control_ping);
14105     S;
14106   }
14107   /* Wait for a reply... */
14108   W;
14109
14110   /* NOTREACHED */
14111   return 0;
14112 }
14113
14114 static int
14115 api_policer_classify_set_interface (vat_main_t * vam)
14116 {
14117   unformat_input_t *i = vam->input;
14118   vl_api_policer_classify_set_interface_t *mp;
14119   f64 timeout;
14120   u32 sw_if_index;
14121   int sw_if_index_set;
14122   u32 ip4_table_index = ~0;
14123   u32 ip6_table_index = ~0;
14124   u32 l2_table_index = ~0;
14125   u8 is_add = 1;
14126
14127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14128     {
14129       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14130         sw_if_index_set = 1;
14131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14132         sw_if_index_set = 1;
14133       else if (unformat (i, "del"))
14134         is_add = 0;
14135       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14136         ;
14137       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14138         ;
14139       else if (unformat (i, "l2-table %d", &l2_table_index))
14140         ;
14141       else
14142         {
14143           clib_warning ("parse error '%U'", format_unformat_error, i);
14144           return -99;
14145         }
14146     }
14147
14148   if (sw_if_index_set == 0)
14149     {
14150       errmsg ("missing interface name or sw_if_index\n");
14151       return -99;
14152     }
14153
14154   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14155
14156   mp->sw_if_index = ntohl (sw_if_index);
14157   mp->ip4_table_index = ntohl (ip4_table_index);
14158   mp->ip6_table_index = ntohl (ip6_table_index);
14159   mp->l2_table_index = ntohl (l2_table_index);
14160   mp->is_add = is_add;
14161
14162   S;
14163   W;
14164   /* NOTREACHED */
14165   return 0;
14166 }
14167
14168 static int
14169 api_policer_classify_dump (vat_main_t * vam)
14170 {
14171   unformat_input_t *i = vam->input;
14172   vl_api_policer_classify_dump_t *mp;
14173   f64 timeout = ~0;
14174   u8 type = POLICER_CLASSIFY_N_TABLES;
14175
14176   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14177     ;
14178   else
14179     {
14180       errmsg ("classify table type must be specified\n");
14181       return -99;
14182     }
14183
14184   if (!vam->json_output)
14185     {
14186       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14187     }
14188
14189   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14190   mp->type = type;
14191   /* send it... */
14192   S;
14193
14194   /* Use a control ping for synchronization */
14195   {
14196     vl_api_control_ping_t *mp;
14197     M (CONTROL_PING, control_ping);
14198     S;
14199   }
14200   /* Wait for a reply... */
14201   W;
14202
14203   /* NOTREACHED */
14204   return 0;
14205 }
14206
14207 static int
14208 api_netmap_create (vat_main_t * vam)
14209 {
14210   unformat_input_t *i = vam->input;
14211   vl_api_netmap_create_t *mp;
14212   f64 timeout;
14213   u8 *if_name = 0;
14214   u8 hw_addr[6];
14215   u8 random_hw_addr = 1;
14216   u8 is_pipe = 0;
14217   u8 is_master = 0;
14218
14219   memset (hw_addr, 0, sizeof (hw_addr));
14220
14221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14222     {
14223       if (unformat (i, "name %s", &if_name))
14224         vec_add1 (if_name, 0);
14225       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14226         random_hw_addr = 0;
14227       else if (unformat (i, "pipe"))
14228         is_pipe = 1;
14229       else if (unformat (i, "master"))
14230         is_master = 1;
14231       else if (unformat (i, "slave"))
14232         is_master = 0;
14233       else
14234         break;
14235     }
14236
14237   if (!vec_len (if_name))
14238     {
14239       errmsg ("interface name must be specified");
14240       return -99;
14241     }
14242
14243   if (vec_len (if_name) > 64)
14244     {
14245       errmsg ("interface name too long");
14246       return -99;
14247     }
14248
14249   M (NETMAP_CREATE, netmap_create);
14250
14251   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14252   clib_memcpy (mp->hw_addr, hw_addr, 6);
14253   mp->use_random_hw_addr = random_hw_addr;
14254   mp->is_pipe = is_pipe;
14255   mp->is_master = is_master;
14256   vec_free (if_name);
14257
14258   S;
14259   W;
14260   /* NOTREACHED */
14261   return 0;
14262 }
14263
14264 static int
14265 api_netmap_delete (vat_main_t * vam)
14266 {
14267   unformat_input_t *i = vam->input;
14268   vl_api_netmap_delete_t *mp;
14269   f64 timeout;
14270   u8 *if_name = 0;
14271
14272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14273     {
14274       if (unformat (i, "name %s", &if_name))
14275         vec_add1 (if_name, 0);
14276       else
14277         break;
14278     }
14279
14280   if (!vec_len (if_name))
14281     {
14282       errmsg ("interface name must be specified");
14283       return -99;
14284     }
14285
14286   if (vec_len (if_name) > 64)
14287     {
14288       errmsg ("interface name too long");
14289       return -99;
14290     }
14291
14292   M (NETMAP_DELETE, netmap_delete);
14293
14294   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14295   vec_free (if_name);
14296
14297   S;
14298   W;
14299   /* NOTREACHED */
14300   return 0;
14301 }
14302
14303 static void vl_api_mpls_gre_tunnel_details_t_handler
14304   (vl_api_mpls_gre_tunnel_details_t * mp)
14305 {
14306   vat_main_t *vam = &vat_main;
14307   i32 i;
14308   i32 len = ntohl (mp->nlabels);
14309
14310   if (mp->l2_only == 0)
14311     {
14312       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14313                ntohl (mp->tunnel_index),
14314                format_ip4_address, &mp->tunnel_src,
14315                format_ip4_address, &mp->tunnel_dst,
14316                format_ip4_address, &mp->intfc_address,
14317                ntohl (mp->mask_width));
14318       for (i = 0; i < len; i++)
14319         {
14320           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14321         }
14322       fformat (vam->ofp, "\n");
14323       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14324                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14325     }
14326   else
14327     {
14328       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14329                ntohl (mp->tunnel_index),
14330                format_ip4_address, &mp->tunnel_src,
14331                format_ip4_address, &mp->tunnel_dst,
14332                format_ip4_address, &mp->intfc_address);
14333       for (i = 0; i < len; i++)
14334         {
14335           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14336         }
14337       fformat (vam->ofp, "\n");
14338       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14339                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14340     }
14341 }
14342
14343 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14344   (vl_api_mpls_gre_tunnel_details_t * mp)
14345 {
14346   vat_main_t *vam = &vat_main;
14347   vat_json_node_t *node = NULL;
14348   struct in_addr ip4;
14349   i32 i;
14350   i32 len = ntohl (mp->nlabels);
14351
14352   if (VAT_JSON_ARRAY != vam->json_tree.type)
14353     {
14354       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14355       vat_json_init_array (&vam->json_tree);
14356     }
14357   node = vat_json_array_add (&vam->json_tree);
14358
14359   vat_json_init_object (node);
14360   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14361   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14362   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14363   vat_json_object_add_uint (node, "inner_fib_index",
14364                             ntohl (mp->inner_fib_index));
14365   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14366   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14367   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14368   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14369   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14370   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14371   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14372   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14373   vat_json_object_add_uint (node, "outer_fib_index",
14374                             ntohl (mp->outer_fib_index));
14375   vat_json_object_add_uint (node, "label_count", len);
14376   for (i = 0; i < len; i++)
14377     {
14378       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14379     }
14380 }
14381
14382 static int
14383 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14384 {
14385   vl_api_mpls_gre_tunnel_dump_t *mp;
14386   f64 timeout;
14387   i32 index = -1;
14388
14389   /* Parse args required to build the message */
14390   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14391     {
14392       if (!unformat (vam->input, "tunnel_index %d", &index))
14393         {
14394           index = -1;
14395           break;
14396         }
14397     }
14398
14399   fformat (vam->ofp, "  tunnel_index %d\n", index);
14400
14401   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14402   mp->tunnel_index = htonl (index);
14403   S;
14404
14405   /* Use a control ping for synchronization */
14406   {
14407     vl_api_control_ping_t *mp;
14408     M (CONTROL_PING, control_ping);
14409     S;
14410   }
14411   W;
14412 }
14413
14414 static void vl_api_mpls_eth_tunnel_details_t_handler
14415   (vl_api_mpls_eth_tunnel_details_t * mp)
14416 {
14417   vat_main_t *vam = &vat_main;
14418   i32 i;
14419   i32 len = ntohl (mp->nlabels);
14420
14421   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14422            ntohl (mp->tunnel_index),
14423            format_ethernet_address, &mp->tunnel_dst_mac,
14424            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14425   for (i = 0; i < len; i++)
14426     {
14427       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14428     }
14429   fformat (vam->ofp, "\n");
14430   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14431            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14432 }
14433
14434 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14435   (vl_api_mpls_eth_tunnel_details_t * mp)
14436 {
14437   vat_main_t *vam = &vat_main;
14438   vat_json_node_t *node = NULL;
14439   struct in_addr ip4;
14440   i32 i;
14441   i32 len = ntohl (mp->nlabels);
14442
14443   if (VAT_JSON_ARRAY != vam->json_tree.type)
14444     {
14445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14446       vat_json_init_array (&vam->json_tree);
14447     }
14448   node = vat_json_array_add (&vam->json_tree);
14449
14450   vat_json_init_object (node);
14451   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14452   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14453   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14454   vat_json_object_add_uint (node, "inner_fib_index",
14455                             ntohl (mp->inner_fib_index));
14456   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14457   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14458   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14459   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14460   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14461                                    format (0, "%U", format_ethernet_address,
14462                                            &mp->tunnel_dst_mac));
14463   vat_json_object_add_uint (node, "tx_sw_if_index",
14464                             ntohl (mp->tx_sw_if_index));
14465   vat_json_object_add_uint (node, "label_count", len);
14466   for (i = 0; i < len; i++)
14467     {
14468       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14469     }
14470 }
14471
14472 static int
14473 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14474 {
14475   vl_api_mpls_eth_tunnel_dump_t *mp;
14476   f64 timeout;
14477   i32 index = -1;
14478
14479   /* Parse args required to build the message */
14480   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14481     {
14482       if (!unformat (vam->input, "tunnel_index %d", &index))
14483         {
14484           index = -1;
14485           break;
14486         }
14487     }
14488
14489   fformat (vam->ofp, "  tunnel_index %d\n", index);
14490
14491   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14492   mp->tunnel_index = htonl (index);
14493   S;
14494
14495   /* Use a control ping for synchronization */
14496   {
14497     vl_api_control_ping_t *mp;
14498     M (CONTROL_PING, control_ping);
14499     S;
14500   }
14501   W;
14502 }
14503
14504 static void vl_api_mpls_fib_encap_details_t_handler
14505   (vl_api_mpls_fib_encap_details_t * mp)
14506 {
14507   vat_main_t *vam = &vat_main;
14508   i32 i;
14509   i32 len = ntohl (mp->nlabels);
14510
14511   fformat (vam->ofp, "table %d, dest %U, label ",
14512            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14513   for (i = 0; i < len; i++)
14514     {
14515       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14516     }
14517   fformat (vam->ofp, "\n");
14518 }
14519
14520 static void vl_api_mpls_fib_encap_details_t_handler_json
14521   (vl_api_mpls_fib_encap_details_t * mp)
14522 {
14523   vat_main_t *vam = &vat_main;
14524   vat_json_node_t *node = NULL;
14525   i32 i;
14526   i32 len = ntohl (mp->nlabels);
14527   struct in_addr ip4;
14528
14529   if (VAT_JSON_ARRAY != vam->json_tree.type)
14530     {
14531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14532       vat_json_init_array (&vam->json_tree);
14533     }
14534   node = vat_json_array_add (&vam->json_tree);
14535
14536   vat_json_init_object (node);
14537   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14538   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14539   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14540   vat_json_object_add_ip4 (node, "dest", ip4);
14541   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14542   vat_json_object_add_uint (node, "label_count", len);
14543   for (i = 0; i < len; i++)
14544     {
14545       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14546     }
14547 }
14548
14549 static int
14550 api_mpls_fib_encap_dump (vat_main_t * vam)
14551 {
14552   vl_api_mpls_fib_encap_dump_t *mp;
14553   f64 timeout;
14554
14555   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14556   S;
14557
14558   /* Use a control ping for synchronization */
14559   {
14560     vl_api_control_ping_t *mp;
14561     M (CONTROL_PING, control_ping);
14562     S;
14563   }
14564   W;
14565 }
14566
14567 static void vl_api_mpls_fib_decap_details_t_handler
14568   (vl_api_mpls_fib_decap_details_t * mp)
14569 {
14570   vat_main_t *vam = &vat_main;
14571
14572   fformat (vam->ofp,
14573            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14574            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14575            ntohl (mp->label), ntohl (mp->s_bit));
14576 }
14577
14578 static void vl_api_mpls_fib_decap_details_t_handler_json
14579   (vl_api_mpls_fib_decap_details_t * mp)
14580 {
14581   vat_main_t *vam = &vat_main;
14582   vat_json_node_t *node = NULL;
14583   struct in_addr ip4;
14584
14585   if (VAT_JSON_ARRAY != vam->json_tree.type)
14586     {
14587       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14588       vat_json_init_array (&vam->json_tree);
14589     }
14590   node = vat_json_array_add (&vam->json_tree);
14591
14592   vat_json_init_object (node);
14593   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14594   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14595   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14596   vat_json_object_add_ip4 (node, "dest", ip4);
14597   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14598   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14599   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14600   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14601   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14602 }
14603
14604 static int
14605 api_mpls_fib_decap_dump (vat_main_t * vam)
14606 {
14607   vl_api_mpls_fib_decap_dump_t *mp;
14608   f64 timeout;
14609
14610   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14611   S;
14612
14613   /* Use a control ping for synchronization */
14614   {
14615     vl_api_control_ping_t *mp;
14616     M (CONTROL_PING, control_ping);
14617     S;
14618   }
14619   W;
14620 }
14621
14622 int
14623 api_classify_table_ids (vat_main_t * vam)
14624 {
14625   vl_api_classify_table_ids_t *mp;
14626   f64 timeout;
14627
14628   /* Construct the API message */
14629   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14630   mp->context = 0;
14631
14632   S;
14633   W;
14634   /* NOTREACHED */
14635   return 0;
14636 }
14637
14638 int
14639 api_classify_table_by_interface (vat_main_t * vam)
14640 {
14641   unformat_input_t *input = vam->input;
14642   vl_api_classify_table_by_interface_t *mp;
14643   f64 timeout;
14644
14645   u32 sw_if_index = ~0;
14646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14647     {
14648       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14649         ;
14650       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14651         ;
14652       else
14653         break;
14654     }
14655   if (sw_if_index == ~0)
14656     {
14657       errmsg ("missing interface name or sw_if_index\n");
14658       return -99;
14659     }
14660
14661   /* Construct the API message */
14662   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14663   mp->context = 0;
14664   mp->sw_if_index = ntohl (sw_if_index);
14665
14666   S;
14667   W;
14668   /* NOTREACHED */
14669   return 0;
14670 }
14671
14672 int
14673 api_classify_table_info (vat_main_t * vam)
14674 {
14675   unformat_input_t *input = vam->input;
14676   vl_api_classify_table_info_t *mp;
14677   f64 timeout;
14678
14679   u32 table_id = ~0;
14680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14681     {
14682       if (unformat (input, "table_id %d", &table_id))
14683         ;
14684       else
14685         break;
14686     }
14687   if (table_id == ~0)
14688     {
14689       errmsg ("missing table id\n");
14690       return -99;
14691     }
14692
14693   /* Construct the API message */
14694   M (CLASSIFY_TABLE_INFO, classify_table_info);
14695   mp->context = 0;
14696   mp->table_id = ntohl (table_id);
14697
14698   S;
14699   W;
14700   /* NOTREACHED */
14701   return 0;
14702 }
14703
14704 int
14705 api_classify_session_dump (vat_main_t * vam)
14706 {
14707   unformat_input_t *input = vam->input;
14708   vl_api_classify_session_dump_t *mp;
14709   f64 timeout;
14710
14711   u32 table_id = ~0;
14712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14713     {
14714       if (unformat (input, "table_id %d", &table_id))
14715         ;
14716       else
14717         break;
14718     }
14719   if (table_id == ~0)
14720     {
14721       errmsg ("missing table id\n");
14722       return -99;
14723     }
14724
14725   /* Construct the API message */
14726   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14727   mp->context = 0;
14728   mp->table_id = ntohl (table_id);
14729   S;
14730
14731   /* Use a control ping for synchronization */
14732   {
14733     vl_api_control_ping_t *mp;
14734     M (CONTROL_PING, control_ping);
14735     S;
14736   }
14737   W;
14738   /* NOTREACHED */
14739   return 0;
14740 }
14741
14742 static void
14743 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14744 {
14745   vat_main_t *vam = &vat_main;
14746
14747   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14748            "src_address %U, fib_index %u, path_mtu %u, "
14749            "template_interval %u\n",
14750            format_ip4_address, mp->collector_address,
14751            ntohs (mp->collector_port),
14752            format_ip4_address, mp->src_address,
14753            ntohl (mp->fib_index),
14754            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14755
14756   vam->retval = 0;
14757   vam->result_ready = 1;
14758 }
14759
14760 static void
14761 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14762 {
14763   vat_main_t *vam = &vat_main;
14764   vat_json_node_t node;
14765   struct in_addr collector_address;
14766   struct in_addr src_address;
14767
14768   vat_json_init_object (&node);
14769   clib_memcpy (&collector_address, &mp->collector_address,
14770                sizeof (collector_address));
14771   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14772   vat_json_object_add_uint (&node, "collector_port",
14773                             ntohs (mp->collector_port));
14774   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14775   vat_json_object_add_ip4 (&node, "src_address", src_address);
14776   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14777   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14778   vat_json_object_add_uint (&node, "template_interval",
14779                             ntohl (mp->template_interval));
14780
14781   vat_json_print (vam->ofp, &node);
14782   vat_json_free (&node);
14783   vam->retval = 0;
14784   vam->result_ready = 1;
14785 }
14786
14787 int
14788 api_ipfix_dump (vat_main_t * vam)
14789 {
14790   vl_api_ipfix_dump_t *mp;
14791   f64 timeout;
14792
14793   /* Construct the API message */
14794   M (IPFIX_DUMP, ipfix_dump);
14795   mp->context = 0;
14796
14797   S;
14798   W;
14799   /* NOTREACHED */
14800   return 0;
14801 }
14802
14803 int
14804 api_pg_create_interface (vat_main_t * vam)
14805 {
14806   unformat_input_t *input = vam->input;
14807   vl_api_pg_create_interface_t *mp;
14808   f64 timeout;
14809
14810   u32 if_id = ~0;
14811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14812     {
14813       if (unformat (input, "if_id %d", &if_id))
14814         ;
14815       else
14816         break;
14817     }
14818   if (if_id == ~0)
14819     {
14820       errmsg ("missing pg interface index\n");
14821       return -99;
14822     }
14823
14824   /* Construct the API message */
14825   M (PG_CREATE_INTERFACE, pg_create_interface);
14826   mp->context = 0;
14827   mp->interface_id = ntohl (if_id);
14828
14829   S;
14830   W;
14831   /* NOTREACHED */
14832   return 0;
14833 }
14834
14835 int
14836 api_pg_capture (vat_main_t * vam)
14837 {
14838   unformat_input_t *input = vam->input;
14839   vl_api_pg_capture_t *mp;
14840   f64 timeout;
14841
14842   u32 if_id = ~0;
14843   u8 enable = 1;
14844   u32 count = 1;
14845   u8 pcap_file_set = 0;
14846   u8 *pcap_file = 0;
14847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14848     {
14849       if (unformat (input, "if_id %d", &if_id))
14850         ;
14851       else if (unformat (input, "pcap %s", &pcap_file))
14852         pcap_file_set = 1;
14853       else if (unformat (input, "count %d", &count))
14854         ;
14855       else if (unformat (input, "disable"))
14856         enable = 0;
14857       else
14858         break;
14859     }
14860   if (if_id == ~0)
14861     {
14862       errmsg ("missing pg interface index\n");
14863       return -99;
14864     }
14865   if (pcap_file_set > 0)
14866     {
14867       if (vec_len (pcap_file) > 255)
14868         {
14869           errmsg ("pcap file name is too long\n");
14870           return -99;
14871         }
14872     }
14873
14874   u32 name_len = vec_len (pcap_file);
14875   /* Construct the API message */
14876   M (PG_CAPTURE, pg_capture);
14877   mp->context = 0;
14878   mp->interface_id = ntohl (if_id);
14879   mp->is_enabled = enable;
14880   mp->count = ntohl (count);
14881   mp->pcap_name_length = ntohl (name_len);
14882   if (pcap_file_set != 0)
14883     {
14884       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14885     }
14886   vec_free (pcap_file);
14887
14888   S;
14889   W;
14890   /* NOTREACHED */
14891   return 0;
14892 }
14893
14894 int
14895 api_pg_enable_disable (vat_main_t * vam)
14896 {
14897   unformat_input_t *input = vam->input;
14898   vl_api_pg_enable_disable_t *mp;
14899   f64 timeout;
14900
14901   u8 enable = 1;
14902   u8 stream_name_set = 0;
14903   u8 *stream_name = 0;
14904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14905     {
14906       if (unformat (input, "stream %s", &stream_name))
14907         stream_name_set = 1;
14908       else if (unformat (input, "disable"))
14909         enable = 0;
14910       else
14911         break;
14912     }
14913
14914   if (stream_name_set > 0)
14915     {
14916       if (vec_len (stream_name) > 255)
14917         {
14918           errmsg ("stream name too long\n");
14919           return -99;
14920         }
14921     }
14922
14923   u32 name_len = vec_len (stream_name);
14924   /* Construct the API message */
14925   M (PG_ENABLE_DISABLE, pg_enable_disable);
14926   mp->context = 0;
14927   mp->is_enabled = enable;
14928   if (stream_name_set != 0)
14929     {
14930       mp->stream_name_length = ntohl (name_len);
14931       clib_memcpy (mp->stream_name, stream_name, name_len);
14932     }
14933   vec_free (stream_name);
14934
14935   S;
14936   W;
14937   /* NOTREACHED */
14938   return 0;
14939 }
14940
14941 int
14942 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14943 {
14944   unformat_input_t *input = vam->input;
14945   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14946   f64 timeout;
14947
14948   u16 *low_ports = 0;
14949   u16 *high_ports = 0;
14950   u16 this_low;
14951   u16 this_hi;
14952   ip4_address_t ip4_addr;
14953   ip6_address_t ip6_addr;
14954   u32 length;
14955   u32 tmp, tmp2;
14956   u8 prefix_set = 0;
14957   u32 vrf_id = ~0;
14958   u8 is_add = 1;
14959   u8 is_ipv6 = 0;
14960
14961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14964         {
14965           prefix_set = 1;
14966         }
14967       else
14968         if (unformat
14969             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14970         {
14971           prefix_set = 1;
14972           is_ipv6 = 1;
14973         }
14974       else if (unformat (input, "vrf %d", &vrf_id))
14975         ;
14976       else if (unformat (input, "del"))
14977         is_add = 0;
14978       else if (unformat (input, "port %d", &tmp))
14979         {
14980           if (tmp == 0 || tmp > 65535)
14981             {
14982               errmsg ("port %d out of range", tmp);
14983               return -99;
14984             }
14985           this_low = tmp;
14986           this_hi = this_low + 1;
14987           vec_add1 (low_ports, this_low);
14988           vec_add1 (high_ports, this_hi);
14989         }
14990       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14991         {
14992           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14993             {
14994               errmsg ("incorrect range parameters\n");
14995               return -99;
14996             }
14997           this_low = tmp;
14998           /* Note: in debug CLI +1 is added to high before
14999              passing to real fn that does "the work"
15000              (ip_source_and_port_range_check_add_del).
15001              This fn is a wrapper around the binary API fn a
15002              control plane will call, which expects this increment
15003              to have occurred. Hence letting the binary API control
15004              plane fn do the increment for consistency between VAT
15005              and other control planes.
15006            */
15007           this_hi = tmp2;
15008           vec_add1 (low_ports, this_low);
15009           vec_add1 (high_ports, this_hi);
15010         }
15011       else
15012         break;
15013     }
15014
15015   if (prefix_set == 0)
15016     {
15017       errmsg ("<address>/<mask> not specified\n");
15018       return -99;
15019     }
15020
15021   if (vrf_id == ~0)
15022     {
15023       errmsg ("VRF ID required, not specified\n");
15024       return -99;
15025     }
15026
15027   if (vrf_id == 0)
15028     {
15029       errmsg
15030         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15031       return -99;
15032     }
15033
15034   if (vec_len (low_ports) == 0)
15035     {
15036       errmsg ("At least one port or port range required\n");
15037       return -99;
15038     }
15039
15040   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15041      ip_source_and_port_range_check_add_del);
15042
15043   mp->is_add = is_add;
15044
15045   if (is_ipv6)
15046     {
15047       mp->is_ipv6 = 1;
15048       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15049     }
15050   else
15051     {
15052       mp->is_ipv6 = 0;
15053       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15054     }
15055
15056   mp->mask_length = length;
15057   mp->number_of_ranges = vec_len (low_ports);
15058
15059   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15060   vec_free (low_ports);
15061
15062   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15063   vec_free (high_ports);
15064
15065   mp->vrf_id = ntohl (vrf_id);
15066
15067   S;
15068   W;
15069   /* NOTREACHED */
15070   return 0;
15071 }
15072
15073 int
15074 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15075 {
15076   unformat_input_t *input = vam->input;
15077   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15078   f64 timeout;
15079   u32 sw_if_index = ~0;
15080   int vrf_set = 0;
15081   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15082   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15083   u8 is_add = 1;
15084
15085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15086     {
15087       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15088         ;
15089       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15090         ;
15091       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15092         vrf_set = 1;
15093       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15094         vrf_set = 1;
15095       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15096         vrf_set = 1;
15097       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15098         vrf_set = 1;
15099       else if (unformat (input, "del"))
15100         is_add = 0;
15101       else
15102         break;
15103     }
15104
15105   if (sw_if_index == ~0)
15106     {
15107       errmsg ("Interface required but not specified\n");
15108       return -99;
15109     }
15110
15111   if (vrf_set == 0)
15112     {
15113       errmsg ("VRF ID required but not specified\n");
15114       return -99;
15115     }
15116
15117   if (tcp_out_vrf_id == 0
15118       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15119     {
15120       errmsg
15121         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15122       return -99;
15123     }
15124
15125   /* Construct the API message */
15126   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15127      ip_source_and_port_range_check_interface_add_del);
15128
15129   mp->sw_if_index = ntohl (sw_if_index);
15130   mp->is_add = is_add;
15131   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15132   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15133   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15134   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15135
15136   /* send it... */
15137   S;
15138
15139   /* Wait for a reply... */
15140   W;
15141 }
15142
15143 static int
15144 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15145 {
15146   unformat_input_t *i = vam->input;
15147   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15148   f64 timeout;
15149   u32 local_sa_id = 0;
15150   u32 remote_sa_id = 0;
15151   ip4_address_t src_address;
15152   ip4_address_t dst_address;
15153   u8 is_add = 1;
15154
15155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15156     {
15157       if (unformat (i, "local_sa %d", &local_sa_id))
15158         ;
15159       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15160         ;
15161       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15162         ;
15163       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15164         ;
15165       else if (unformat (i, "del"))
15166         is_add = 0;
15167       else
15168         {
15169           clib_warning ("parse error '%U'", format_unformat_error, i);
15170           return -99;
15171         }
15172     }
15173
15174   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15175
15176   mp->local_sa_id = ntohl (local_sa_id);
15177   mp->remote_sa_id = ntohl (remote_sa_id);
15178   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15179   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15180   mp->is_add = is_add;
15181
15182   S;
15183   W;
15184   /* NOTREACHED */
15185   return 0;
15186 }
15187
15188 static void vl_api_ipsec_gre_tunnel_details_t_handler
15189   (vl_api_ipsec_gre_tunnel_details_t * mp)
15190 {
15191   vat_main_t *vam = &vat_main;
15192
15193   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15194            ntohl (mp->sw_if_index),
15195            format_ip4_address, &mp->src_address,
15196            format_ip4_address, &mp->dst_address,
15197            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15198 }
15199
15200 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15201   (vl_api_ipsec_gre_tunnel_details_t * mp)
15202 {
15203   vat_main_t *vam = &vat_main;
15204   vat_json_node_t *node = NULL;
15205   struct in_addr ip4;
15206
15207   if (VAT_JSON_ARRAY != vam->json_tree.type)
15208     {
15209       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15210       vat_json_init_array (&vam->json_tree);
15211     }
15212   node = vat_json_array_add (&vam->json_tree);
15213
15214   vat_json_init_object (node);
15215   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15216   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15217   vat_json_object_add_ip4 (node, "src_address", ip4);
15218   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15219   vat_json_object_add_ip4 (node, "dst_address", ip4);
15220   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15221   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15222 }
15223
15224 static int
15225 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15226 {
15227   unformat_input_t *i = vam->input;
15228   vl_api_ipsec_gre_tunnel_dump_t *mp;
15229   f64 timeout;
15230   u32 sw_if_index;
15231   u8 sw_if_index_set = 0;
15232
15233   /* Parse args required to build the message */
15234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15235     {
15236       if (unformat (i, "sw_if_index %d", &sw_if_index))
15237         sw_if_index_set = 1;
15238       else
15239         break;
15240     }
15241
15242   if (sw_if_index_set == 0)
15243     {
15244       sw_if_index = ~0;
15245     }
15246
15247   if (!vam->json_output)
15248     {
15249       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15250                "sw_if_index", "src_address", "dst_address",
15251                "local_sa_id", "remote_sa_id");
15252     }
15253
15254   /* Get list of gre-tunnel interfaces */
15255   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15256
15257   mp->sw_if_index = htonl (sw_if_index);
15258
15259   S;
15260
15261   /* Use a control ping for synchronization */
15262   {
15263     vl_api_control_ping_t *mp;
15264     M (CONTROL_PING, control_ping);
15265     S;
15266   }
15267   W;
15268 }
15269
15270 static int
15271 api_delete_subif (vat_main_t * vam)
15272 {
15273   unformat_input_t *i = vam->input;
15274   vl_api_delete_subif_t *mp;
15275   f64 timeout;
15276   u32 sw_if_index = ~0;
15277
15278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15279     {
15280       if (unformat (i, "sw_if_index %d", &sw_if_index))
15281         ;
15282       else
15283         break;
15284     }
15285
15286   if (sw_if_index == ~0)
15287     {
15288       errmsg ("missing sw_if_index\n");
15289       return -99;
15290     }
15291
15292   /* Construct the API message */
15293   M (DELETE_SUBIF, delete_subif);
15294   mp->sw_if_index = ntohl (sw_if_index);
15295
15296   S;
15297   W;
15298 }
15299
15300 static int
15301 q_or_quit (vat_main_t * vam)
15302 {
15303   longjmp (vam->jump_buf, 1);
15304   return 0;                     /* not so much */
15305 }
15306
15307 static int
15308 q (vat_main_t * vam)
15309 {
15310   return q_or_quit (vam);
15311 }
15312
15313 static int
15314 quit (vat_main_t * vam)
15315 {
15316   return q_or_quit (vam);
15317 }
15318
15319 static int
15320 comment (vat_main_t * vam)
15321 {
15322   return 0;
15323 }
15324
15325 static int
15326 cmd_cmp (void *a1, void *a2)
15327 {
15328   u8 **c1 = a1;
15329   u8 **c2 = a2;
15330
15331   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15332 }
15333
15334 static int
15335 help (vat_main_t * vam)
15336 {
15337   u8 **cmds = 0;
15338   u8 *name = 0;
15339   hash_pair_t *p;
15340   unformat_input_t *i = vam->input;
15341   int j;
15342
15343   if (unformat (i, "%s", &name))
15344     {
15345       uword *hs;
15346
15347       vec_add1 (name, 0);
15348
15349       hs = hash_get_mem (vam->help_by_name, name);
15350       if (hs)
15351         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15352       else
15353         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15354       vec_free (name);
15355       return 0;
15356     }
15357
15358   fformat (vam->ofp, "Help is available for the following:\n");
15359
15360     /* *INDENT-OFF* */
15361     hash_foreach_pair (p, vam->function_by_name,
15362     ({
15363       vec_add1 (cmds, (u8 *)(p->key));
15364     }));
15365     /* *INDENT-ON* */
15366
15367   vec_sort_with_function (cmds, cmd_cmp);
15368
15369   for (j = 0; j < vec_len (cmds); j++)
15370     fformat (vam->ofp, "%s\n", cmds[j]);
15371
15372   vec_free (cmds);
15373   return 0;
15374 }
15375
15376 static int
15377 set (vat_main_t * vam)
15378 {
15379   u8 *name = 0, *value = 0;
15380   unformat_input_t *i = vam->input;
15381
15382   if (unformat (i, "%s", &name))
15383     {
15384       /* The input buffer is a vector, not a string. */
15385       value = vec_dup (i->buffer);
15386       vec_delete (value, i->index, 0);
15387       /* Almost certainly has a trailing newline */
15388       if (value[vec_len (value) - 1] == '\n')
15389         value[vec_len (value) - 1] = 0;
15390       /* Make sure it's a proper string, one way or the other */
15391       vec_add1 (value, 0);
15392       (void) clib_macro_set_value (&vam->macro_main,
15393                                    (char *) name, (char *) value);
15394     }
15395   else
15396     errmsg ("usage: set <name> <value>\n");
15397
15398   vec_free (name);
15399   vec_free (value);
15400   return 0;
15401 }
15402
15403 static int
15404 unset (vat_main_t * vam)
15405 {
15406   u8 *name = 0;
15407
15408   if (unformat (vam->input, "%s", &name))
15409     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15410       errmsg ("unset: %s wasn't set\n", name);
15411   vec_free (name);
15412   return 0;
15413 }
15414
15415 typedef struct
15416 {
15417   u8 *name;
15418   u8 *value;
15419 } macro_sort_t;
15420
15421
15422 static int
15423 macro_sort_cmp (void *a1, void *a2)
15424 {
15425   macro_sort_t *s1 = a1;
15426   macro_sort_t *s2 = a2;
15427
15428   return strcmp ((char *) (s1->name), (char *) (s2->name));
15429 }
15430
15431 static int
15432 dump_macro_table (vat_main_t * vam)
15433 {
15434   macro_sort_t *sort_me = 0, *sm;
15435   int i;
15436   hash_pair_t *p;
15437
15438     /* *INDENT-OFF* */
15439     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15440     ({
15441       vec_add2 (sort_me, sm, 1);
15442       sm->name = (u8 *)(p->key);
15443       sm->value = (u8 *) (p->value[0]);
15444     }));
15445     /* *INDENT-ON* */
15446
15447   vec_sort_with_function (sort_me, macro_sort_cmp);
15448
15449   if (vec_len (sort_me))
15450     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15451   else
15452     fformat (vam->ofp, "The macro table is empty...\n");
15453
15454   for (i = 0; i < vec_len (sort_me); i++)
15455     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15456   return 0;
15457 }
15458
15459 static int
15460 dump_node_table (vat_main_t * vam)
15461 {
15462   int i, j;
15463   vlib_node_t *node, *next_node;
15464
15465   if (vec_len (vam->graph_nodes) == 0)
15466     {
15467       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15468       return 0;
15469     }
15470
15471   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15472     {
15473       node = vam->graph_nodes[i];
15474       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15475       for (j = 0; j < vec_len (node->next_nodes); j++)
15476         {
15477           if (node->next_nodes[j] != ~0)
15478             {
15479               next_node = vam->graph_nodes[node->next_nodes[j]];
15480               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15481             }
15482         }
15483     }
15484   return 0;
15485 }
15486
15487 static int
15488 search_node_table (vat_main_t * vam)
15489 {
15490   unformat_input_t *line_input = vam->input;
15491   u8 *node_to_find;
15492   int j;
15493   vlib_node_t *node, *next_node;
15494   uword *p;
15495
15496   if (vam->graph_node_index_by_name == 0)
15497     {
15498       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15499       return 0;
15500     }
15501
15502   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15503     {
15504       if (unformat (line_input, "%s", &node_to_find))
15505         {
15506           vec_add1 (node_to_find, 0);
15507           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15508           if (p == 0)
15509             {
15510               fformat (vam->ofp, "%s not found...\n", node_to_find);
15511               goto out;
15512             }
15513           node = vam->graph_nodes[p[0]];
15514           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15515           for (j = 0; j < vec_len (node->next_nodes); j++)
15516             {
15517               if (node->next_nodes[j] != ~0)
15518                 {
15519                   next_node = vam->graph_nodes[node->next_nodes[j]];
15520                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15521                 }
15522             }
15523         }
15524
15525       else
15526         {
15527           clib_warning ("parse error '%U'", format_unformat_error,
15528                         line_input);
15529           return -99;
15530         }
15531
15532     out:
15533       vec_free (node_to_find);
15534
15535     }
15536
15537   return 0;
15538 }
15539
15540
15541 static int
15542 script (vat_main_t * vam)
15543 {
15544   u8 *s = 0;
15545   char *save_current_file;
15546   unformat_input_t save_input;
15547   jmp_buf save_jump_buf;
15548   u32 save_line_number;
15549
15550   FILE *new_fp, *save_ifp;
15551
15552   if (unformat (vam->input, "%s", &s))
15553     {
15554       new_fp = fopen ((char *) s, "r");
15555       if (new_fp == 0)
15556         {
15557           errmsg ("Couldn't open script file %s\n", s);
15558           vec_free (s);
15559           return -99;
15560         }
15561     }
15562   else
15563     {
15564       errmsg ("Missing script name\n");
15565       return -99;
15566     }
15567
15568   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15569   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15570   save_ifp = vam->ifp;
15571   save_line_number = vam->input_line_number;
15572   save_current_file = (char *) vam->current_file;
15573
15574   vam->input_line_number = 0;
15575   vam->ifp = new_fp;
15576   vam->current_file = s;
15577   do_one_file (vam);
15578
15579   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15580   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15581   vam->ifp = save_ifp;
15582   vam->input_line_number = save_line_number;
15583   vam->current_file = (u8 *) save_current_file;
15584   vec_free (s);
15585
15586   return 0;
15587 }
15588
15589 static int
15590 echo (vat_main_t * vam)
15591 {
15592   fformat (vam->ofp, "%v", vam->input->buffer);
15593   return 0;
15594 }
15595
15596 /* List of API message constructors, CLI names map to api_xxx */
15597 #define foreach_vpe_api_msg                                             \
15598 _(create_loopback,"[mac <mac-addr>]")                                   \
15599 _(sw_interface_dump,"")                                                 \
15600 _(sw_interface_set_flags,                                               \
15601   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15602 _(sw_interface_add_del_address,                                         \
15603   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15604 _(sw_interface_set_table,                                               \
15605   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15606 _(sw_interface_set_vpath,                                               \
15607   "<intfc> | sw_if_index <id> enable | disable")                        \
15608 _(sw_interface_set_l2_xconnect,                                         \
15609   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15610   "enable | disable")                                                   \
15611 _(sw_interface_set_l2_bridge,                                           \
15612   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15613   "[shg <split-horizon-group>] [bvi]\n"                                 \
15614   "enable | disable")                                                   \
15615 _(bridge_domain_add_del,                                                \
15616   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15617 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15618 _(l2fib_add_del,                                                        \
15619   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15620 _(l2_flags,                                                             \
15621   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15622 _(bridge_flags,                                                         \
15623   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15624 _(tap_connect,                                                          \
15625   "tapname <name> mac <mac-addr> | random-mac")                         \
15626 _(tap_modify,                                                           \
15627   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15628 _(tap_delete,                                                           \
15629   "<vpp-if-name> | sw_if_index <id>")                                   \
15630 _(sw_interface_tap_dump, "")                                            \
15631 _(ip_add_del_route,                                                     \
15632   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15633   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15634   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15635   "[multipath] [count <n>]")                                            \
15636 _(proxy_arp_add_del,                                                    \
15637   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15638 _(proxy_arp_intfc_enable_disable,                                       \
15639   "<intfc> | sw_if_index <id> enable | disable")                        \
15640 _(mpls_add_del_encap,                                                   \
15641   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15642 _(mpls_add_del_decap,                                                   \
15643   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15644 _(mpls_gre_add_del_tunnel,                                              \
15645   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15646   "adj <ip4-address>/<mask-width> [del]")                               \
15647 _(sw_interface_set_unnumbered,                                          \
15648   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15649 _(ip_neighbor_add_del,                                                  \
15650   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15651   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15652 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15653 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15654 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15655   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15656   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15657   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15658 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15659 _(reset_fib, "vrf <n> [ipv6]")                                          \
15660 _(dhcp_proxy_config,                                                    \
15661   "svr <v46-address> src <v46-address>\n"                               \
15662    "insert-cid <n> [del]")                                              \
15663 _(dhcp_proxy_config_2,                                                  \
15664   "svr <v46-address> src <v46-address>\n"                               \
15665    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15666 _(dhcp_proxy_set_vss,                                                   \
15667   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15668 _(dhcp_client_config,                                                   \
15669   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15670 _(set_ip_flow_hash,                                                     \
15671   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15672 _(sw_interface_ip6_enable_disable,                                      \
15673   "<intfc> | sw_if_index <id> enable | disable")                        \
15674 _(sw_interface_ip6_set_link_local_address,                              \
15675   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15676 _(sw_interface_ip6nd_ra_prefix,                                         \
15677   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15678   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15679   "[nolink] [isno]")                                                    \
15680 _(sw_interface_ip6nd_ra_config,                                         \
15681   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15682   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15683   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15684 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15685 _(l2_patch_add_del,                                                     \
15686   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15687   "enable | disable")                                                   \
15688 _(mpls_ethernet_add_del_tunnel,                                         \
15689   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15690   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15691 _(mpls_ethernet_add_del_tunnel_2,                                       \
15692   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15693   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15694 _(sr_tunnel_add_del,                                                    \
15695   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15696   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15697   "[policy <policy_name>]")                                             \
15698 _(sr_policy_add_del,                                                    \
15699   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15700 _(sr_multicast_map_add_del,                                             \
15701   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15702 _(classify_add_del_table,                                               \
15703   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15704   "[del] mask <mask-value>\n"                                           \
15705   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15706 _(classify_add_del_session,                                             \
15707   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15708   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15709   "  [l3 [ip4|ip6]]")                                                   \
15710 _(classify_set_interface_ip_table,                                      \
15711   "<intfc> | sw_if_index <nn> table <nn>")                              \
15712 _(classify_set_interface_l2_tables,                                     \
15713   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15714   "  [other-table <nn>]")                                               \
15715 _(get_node_index, "node <node-name")                                    \
15716 _(add_node_next, "node <node-name> next <next-node-name>")              \
15717 _(l2tpv3_create_tunnel,                                                 \
15718   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15719   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15720   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15721 _(l2tpv3_set_tunnel_cookies,                                            \
15722   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15723   "[new_remote_cookie <nn>]\n")                                         \
15724 _(l2tpv3_interface_enable_disable,                                      \
15725   "<intfc> | sw_if_index <nn> enable | disable")                        \
15726 _(l2tpv3_set_lookup_key,                                                \
15727   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15728 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15729 _(vxlan_add_del_tunnel,                                                 \
15730   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15731   " [decap-next l2|ip4|ip6] [del]")                                     \
15732 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15733 _(gre_add_del_tunnel,                                                   \
15734   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15735 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15736 _(l2_fib_clear_table, "")                                               \
15737 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15738 _(l2_interface_vlan_tag_rewrite,                                        \
15739   "<intfc> | sw_if_index <nn> \n"                                       \
15740   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15741   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15742 _(create_vhost_user_if,                                                 \
15743         "socket <filename> [server] [renumber <dev_instance>] "         \
15744         "[mac <mac_address>]")                                          \
15745 _(modify_vhost_user_if,                                                 \
15746         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15747         "[server] [renumber <dev_instance>]")                           \
15748 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15749 _(sw_interface_vhost_user_dump, "")                                     \
15750 _(show_version, "")                                                     \
15751 _(vxlan_gpe_add_del_tunnel,                                             \
15752   "local <addr> remote <addr> vni <nn>\n"                               \
15753     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15754   "[next-ethernet] [next-nsh]\n")                                       \
15755 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15756 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15757 _(interface_name_renumber,                                              \
15758   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15759 _(input_acl_set_interface,                                              \
15760   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15761   "  [l2-table <nn>] [del]")                                            \
15762 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15763 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15764 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15765 _(ip_dump, "ipv4 | ipv6")                                               \
15766 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15767 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15768   "  spid_id <n> ")                                                     \
15769 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15770   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15771   "  integ_alg <alg> integ_key <hex>")                                  \
15772 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15773   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15774   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15775   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15776 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15777 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15778 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15779   "(auth_data 0x<data> | auth_data <data>)")                            \
15780 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15781   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15782 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15783   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15784   "(local|remote)")                                                     \
15785 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15786 _(delete_loopback,"sw_if_index <nn>")                                   \
15787 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15788 _(map_add_domain,                                                       \
15789   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15790   "ip6-src <ip6addr> "                                                  \
15791   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15792 _(map_del_domain, "index <n>")                                          \
15793 _(map_add_del_rule,                                                     \
15794   "index <n> psid <n> dst <ip6addr> [del]")                             \
15795 _(map_domain_dump, "")                                                  \
15796 _(map_rule_dump, "index <map-domain>")                                  \
15797 _(want_interface_events,  "enable|disable")                             \
15798 _(want_stats,"enable|disable")                                          \
15799 _(get_first_msg_id, "client <name>")                                    \
15800 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15801 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15802   "fib-id <nn> [ip4][ip6][default]")                                    \
15803 _(get_node_graph, " ")                                                  \
15804 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15805 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15806   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15807   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15808 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15809   " vrf_id <nn>  add | pop | none")                                     \
15810 _(trace_profile_del, "")                                                \
15811 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15812                             " sw_if_index <sw_if_index> p <priority> "  \
15813                             "w <weight>] [del]")                        \
15814 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15815                         "iface <intf> | sw_if_index <sw_if_index> "     \
15816                         "p <priority> w <weight> [del]")                \
15817 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15818                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15819                           "locator-set <locator_name> [del]")           \
15820 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15821   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15822 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15823 _(lisp_gpe_enable_disable, "enable|disable")                            \
15824 _(lisp_enable_disable, "enable|disable")                                \
15825 _(lisp_gpe_add_del_iface, "up|down")                                    \
15826 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15827                                "rloc <locator> p <prio> "               \
15828                                "w <weight> [rloc <loc> ... ] "          \
15829                                "action <action> [del-all]")             \
15830 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15831                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15832                           "[rloc <loc> ... ] action <action>")          \
15833 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15834 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15835 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15836 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15837                          "locator-set <loc-set-name>] [local | remote]")\
15838 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15839                        "[local] | [remote]")                            \
15840 _(lisp_eid_table_vni_dump, "")                                          \
15841 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15842 _(lisp_gpe_tunnel_dump, "")                                             \
15843 _(lisp_map_resolver_dump, "")                                           \
15844 _(show_lisp_status, "")                                                 \
15845 _(lisp_get_map_request_itr_rlocs, "")                                   \
15846 _(show_lisp_pitr, "")                                                   \
15847 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15848 _(af_packet_delete, "name <host interface name>")                       \
15849 _(policer_add_del, "name <policer name> <params> [del]")                \
15850 _(policer_dump, "[name <policer name>]")                                \
15851 _(policer_classify_set_interface,                                       \
15852   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15853   "  [l2-table <nn>] [del]")                                            \
15854 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15855 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15856     "[master|slave]")                                                   \
15857 _(netmap_delete, "name <interface name>")                               \
15858 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15859 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15860 _(mpls_fib_encap_dump, "")                                              \
15861 _(mpls_fib_decap_dump, "")                                              \
15862 _(classify_table_ids, "")                                               \
15863 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15864 _(classify_table_info, "table_id <nn>")                                 \
15865 _(classify_session_dump, "table_id <nn>")                               \
15866 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15867                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15868                 "[template_interval <nn>]")                             \
15869 _(ipfix_dump, "")                                                       \
15870 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15871 _(pg_create_interface, "if_id <nn>")                                    \
15872 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15873 _(pg_enable_disable, "[stream <id>] disable")                           \
15874 _(ip_source_and_port_range_check_add_del,                               \
15875   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15876 _(ip_source_and_port_range_check_interface_add_del,                     \
15877   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15878   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15879 _(ipsec_gre_add_del_tunnel,                                             \
15880   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15881 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15882 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15883
15884 /* List of command functions, CLI names map directly to functions */
15885 #define foreach_cli_function                                    \
15886 _(comment, "usage: comment <ignore-rest-of-line>")              \
15887 _(dump_interface_table, "usage: dump_interface_table")          \
15888 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15889 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15890 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15891 _(dump_stats_table, "usage: dump_stats_table")                  \
15892 _(dump_macro_table, "usage: dump_macro_table ")                 \
15893 _(dump_node_table, "usage: dump_node_table")                    \
15894 _(echo, "usage: echo <message>")                                \
15895 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15896 _(help, "usage: help")                                          \
15897 _(q, "usage: quit")                                             \
15898 _(quit, "usage: quit")                                          \
15899 _(search_node_table, "usage: search_node_table <name>...")      \
15900 _(set, "usage: set <variable-name> <value>")                    \
15901 _(script, "usage: script <file-name>")                          \
15902 _(unset, "usage: unset <variable-name>")
15903
15904 #define _(N,n)                                  \
15905     static void vl_api_##n##_t_handler_uni      \
15906     (vl_api_##n##_t * mp)                       \
15907     {                                           \
15908         vat_main_t * vam = &vat_main;           \
15909         if (vam->json_output) {                 \
15910             vl_api_##n##_t_handler_json(mp);    \
15911         } else {                                \
15912             vl_api_##n##_t_handler(mp);         \
15913         }                                       \
15914     }
15915 foreach_vpe_api_reply_msg;
15916 #undef _
15917
15918 void
15919 vat_api_hookup (vat_main_t * vam)
15920 {
15921 #define _(N,n)                                                  \
15922     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15923                            vl_api_##n##_t_handler_uni,          \
15924                            vl_noop_handler,                     \
15925                            vl_api_##n##_t_endian,               \
15926                            vl_api_##n##_t_print,                \
15927                            sizeof(vl_api_##n##_t), 1);
15928   foreach_vpe_api_reply_msg;
15929 #undef _
15930
15931   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15932
15933   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15934
15935   vam->function_by_name = hash_create_string (0, sizeof (uword));
15936
15937   vam->help_by_name = hash_create_string (0, sizeof (uword));
15938
15939   /* API messages we can send */
15940 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15941   foreach_vpe_api_msg;
15942 #undef _
15943
15944   /* Help strings */
15945 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15946   foreach_vpe_api_msg;
15947 #undef _
15948
15949   /* CLI functions */
15950 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15951   foreach_cli_function;
15952 #undef _
15953
15954   /* Help strings */
15955 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15956   foreach_cli_function;
15957 #undef _
15958 }
15959
15960 #undef vl_api_version
15961 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15962 #include <vpp-api/vpe.api.h>
15963 #undef vl_api_version
15964
15965 void
15966 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15967 {
15968   /*
15969    * Send the main API signature in slot 0. This bit of code must
15970    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15971    */
15972   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15973 }
15974
15975 /*
15976  * fd.io coding-style-patch-verification: ON
15977  *
15978  * Local Variables:
15979  * eval: (c-set-style "gnu")
15980  * End:
15981  */