VPP-356: Fix wrong byte order in LISP API
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558
1559 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1560   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1610   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1644   (vl_api_gre_add_del_tunnel_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->sw_if_index = ntohl (mp->sw_if_index);
1673       vam->result_ready = 1;
1674     }
1675 }
1676
1677 static void vl_api_create_vhost_user_if_reply_t_handler_json
1678   (vl_api_create_vhost_user_if_reply_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   vat_json_node_t node;
1682
1683   vat_json_init_object (&node);
1684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1685   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_ip_address_details_t_handler
1695   (vl_api_ip_address_details_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   static ip_address_details_t empty_ip_address_details = { {0} };
1699   ip_address_details_t *address = NULL;
1700   ip_details_t *current_ip_details = NULL;
1701   ip_details_t *details = NULL;
1702
1703   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1704
1705   if (!details || vam->current_sw_if_index >= vec_len (details)
1706       || !details[vam->current_sw_if_index].present)
1707     {
1708       errmsg ("ip address details arrived but not stored\n");
1709       errmsg ("ip_dump should be called first\n");
1710       return;
1711     }
1712
1713   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1714
1715 #define addresses (current_ip_details->addr)
1716
1717   vec_validate_init_empty (addresses, vec_len (addresses),
1718                            empty_ip_address_details);
1719
1720   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1721
1722   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1723   address->prefix_length = mp->prefix_length;
1724 #undef addresses
1725 }
1726
1727 static void vl_api_ip_address_details_t_handler_json
1728   (vl_api_ip_address_details_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   vat_json_node_t *node = NULL;
1732   struct in6_addr ip6;
1733   struct in_addr ip4;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   node = vat_json_array_add (&vam->json_tree);
1741
1742   vat_json_init_object (node);
1743   if (vam->is_ipv6)
1744     {
1745       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1746       vat_json_object_add_ip6 (node, "ip", ip6);
1747     }
1748   else
1749     {
1750       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1751       vat_json_object_add_ip4 (node, "ip", ip4);
1752     }
1753   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1754 }
1755
1756 static void
1757 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   static ip_details_t empty_ip_details = { 0 };
1761   ip_details_t *ip = NULL;
1762   u32 sw_if_index = ~0;
1763
1764   sw_if_index = ntohl (mp->sw_if_index);
1765
1766   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1767                            sw_if_index, empty_ip_details);
1768
1769   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1770                          sw_if_index);
1771
1772   ip->present = 1;
1773 }
1774
1775 static void
1776 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   vat_json_array_add_uint (&vam->json_tree,
1786                            clib_net_to_host_u32 (mp->sw_if_index));
1787 }
1788
1789 static void vl_api_map_domain_details_t_handler_json
1790   (vl_api_map_domain_details_t * mp)
1791 {
1792   vat_json_node_t *node = NULL;
1793   vat_main_t *vam = &vat_main;
1794   struct in6_addr ip6;
1795   struct in_addr ip4;
1796
1797   if (VAT_JSON_ARRAY != vam->json_tree.type)
1798     {
1799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1800       vat_json_init_array (&vam->json_tree);
1801     }
1802
1803   node = vat_json_array_add (&vam->json_tree);
1804   vat_json_init_object (node);
1805
1806   vat_json_object_add_uint (node, "domain_index",
1807                             clib_net_to_host_u32 (mp->domain_index));
1808   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1809   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1810   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1811   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1812   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1813   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1814   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1815   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1816   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1817   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1818   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1819   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1820   vat_json_object_add_uint (node, "flags", mp->flags);
1821   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1822   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1823 }
1824
1825 static void vl_api_map_domain_details_t_handler
1826   (vl_api_map_domain_details_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829
1830   if (mp->is_translation)
1831     {
1832       fformat (vam->ofp,
1833                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1834                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1835                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1836                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1837                clib_net_to_host_u32 (mp->domain_index));
1838     }
1839   else
1840     {
1841       fformat (vam->ofp,
1842                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1843                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1844                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1845                format_ip6_address, mp->ip6_src,
1846                clib_net_to_host_u32 (mp->domain_index));
1847     }
1848   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1849            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1850            mp->is_translation ? "map-t" : "");
1851 }
1852
1853 static void vl_api_map_rule_details_t_handler_json
1854   (vl_api_map_rule_details_t * mp)
1855 {
1856   struct in6_addr ip6;
1857   vat_json_node_t *node = NULL;
1858   vat_main_t *vam = &vat_main;
1859
1860   if (VAT_JSON_ARRAY != vam->json_tree.type)
1861     {
1862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1863       vat_json_init_array (&vam->json_tree);
1864     }
1865
1866   node = vat_json_array_add (&vam->json_tree);
1867   vat_json_init_object (node);
1868
1869   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1870   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1871   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1872 }
1873
1874 static void
1875 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1879            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1880 }
1881
1882 static void
1883 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1887           "router_addr %U host_mac %U\n",
1888           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1889           format_ip4_address, &mp->host_address,
1890           format_ip4_address, &mp->router_address,
1891           format_ethernet_address, mp->host_mac);
1892 }
1893
1894 static void vl_api_dhcp_compl_event_t_handler_json
1895   (vl_api_dhcp_compl_event_t * mp)
1896 {
1897   /* JSON output not supported */
1898 }
1899
1900 static void
1901 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1902                               u32 counter)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   static u64 default_counter = 0;
1906
1907   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1908                            NULL);
1909   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1910                            sw_if_index, default_counter);
1911   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1912 }
1913
1914 static void
1915 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1916                                 interface_counter_t counter)
1917 {
1918   vat_main_t *vam = &vat_main;
1919   static interface_counter_t default_counter = { 0, };
1920
1921   vec_validate_init_empty (vam->combined_interface_counters,
1922                            vnet_counter_type, NULL);
1923   vec_validate_init_empty (vam->combined_interface_counters
1924                            [vnet_counter_type], sw_if_index, default_counter);
1925   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1926 }
1927
1928 static void vl_api_vnet_interface_counters_t_handler
1929   (vl_api_vnet_interface_counters_t * mp)
1930 {
1931   /* not supported */
1932 }
1933
1934 static void vl_api_vnet_interface_counters_t_handler_json
1935   (vl_api_vnet_interface_counters_t * mp)
1936 {
1937   interface_counter_t counter;
1938   vlib_counter_t *v;
1939   u64 *v_packets;
1940   u64 packets;
1941   u32 count;
1942   u32 first_sw_if_index;
1943   int i;
1944
1945   count = ntohl (mp->count);
1946   first_sw_if_index = ntohl (mp->first_sw_if_index);
1947
1948   if (!mp->is_combined)
1949     {
1950       v_packets = (u64 *) & mp->data;
1951       for (i = 0; i < count; i++)
1952         {
1953           packets =
1954             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1955           set_simple_interface_counter (mp->vnet_counter_type,
1956                                         first_sw_if_index + i, packets);
1957           v_packets++;
1958         }
1959     }
1960   else
1961     {
1962       v = (vlib_counter_t *) & mp->data;
1963       for (i = 0; i < count; i++)
1964         {
1965           counter.packets =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1967           counter.bytes =
1968             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1969           set_combined_interface_counter (mp->vnet_counter_type,
1970                                           first_sw_if_index + i, counter);
1971           v++;
1972         }
1973     }
1974 }
1975
1976 static u32
1977 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   u32 i;
1981
1982   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1983     {
1984       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1985         {
1986           return i;
1987         }
1988     }
1989   return ~0;
1990 }
1991
1992 static u32
1993 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static void vl_api_vnet_ip4_fib_counters_t_handler
2009   (vl_api_vnet_ip4_fib_counters_t * mp)
2010 {
2011   /* not supported */
2012 }
2013
2014 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2015   (vl_api_vnet_ip4_fib_counters_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vl_api_ip4_fib_counter_t *v;
2019   ip4_fib_counter_t *counter;
2020   struct in_addr ip4;
2021   u32 vrf_id;
2022   u32 vrf_index;
2023   u32 count;
2024   int i;
2025
2026   vrf_id = ntohl (mp->vrf_id);
2027   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2028   if (~0 == vrf_index)
2029     {
2030       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2031       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2032       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2033       vec_validate (vam->ip4_fib_counters, vrf_index);
2034       vam->ip4_fib_counters[vrf_index] = NULL;
2035     }
2036
2037   vec_free (vam->ip4_fib_counters[vrf_index]);
2038   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2039   count = ntohl (mp->count);
2040   for (i = 0; i < count; i++)
2041     {
2042       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2043       counter = &vam->ip4_fib_counters[vrf_index][i];
2044       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2045       counter->address = ip4;
2046       counter->address_length = v->address_length;
2047       counter->packets = clib_net_to_host_u64 (v->packets);
2048       counter->bytes = clib_net_to_host_u64 (v->bytes);
2049       v++;
2050     }
2051 }
2052
2053 static void vl_api_vnet_ip6_fib_counters_t_handler
2054   (vl_api_vnet_ip6_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2060   (vl_api_vnet_ip6_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip6_fib_counter_t *v;
2064   ip6_fib_counter_t *counter;
2065   struct in6_addr ip6;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip6_fib_counters, vrf_index);
2079       vam->ip6_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip6_fib_counters[vrf_index]);
2083   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2088       counter = &vam->ip6_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2090       counter->address = ip6;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_get_first_msg_id_reply_t_handler
2099   (vl_api_get_first_msg_id_reply_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102   i32 retval = ntohl (mp->retval);
2103
2104   if (vam->async_mode)
2105     {
2106       vam->async_errors += (retval < 0);
2107     }
2108   else
2109     {
2110       vam->retval = retval;
2111       vam->result_ready = 1;
2112     }
2113   if (retval >= 0)
2114     {
2115       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2116     }
2117 }
2118
2119 static void vl_api_get_first_msg_id_reply_t_handler_json
2120   (vl_api_get_first_msg_id_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t node;
2124
2125   vat_json_init_object (&node);
2126   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2127   vat_json_object_add_uint (&node, "first_msg_id",
2128                             (uint) ntohs (mp->first_msg_id));
2129
2130   vat_json_print (vam->ofp, &node);
2131   vat_json_free (&node);
2132
2133   vam->retval = ntohl (mp->retval);
2134   vam->result_ready = 1;
2135 }
2136
2137 static void vl_api_get_node_graph_reply_t_handler
2138   (vl_api_get_node_graph_reply_t * mp)
2139 {
2140   vat_main_t *vam = &vat_main;
2141   api_main_t *am = &api_main;
2142   i32 retval = ntohl (mp->retval);
2143   u8 *pvt_copy, *reply;
2144   void *oldheap;
2145   vlib_node_t *node;
2146   int i;
2147
2148   if (vam->async_mode)
2149     {
2150       vam->async_errors += (retval < 0);
2151     }
2152   else
2153     {
2154       vam->retval = retval;
2155       vam->result_ready = 1;
2156     }
2157
2158   /* "Should never happen..." */
2159   if (retval != 0)
2160     return;
2161
2162   reply = (u8 *) (mp->reply_in_shmem);
2163   pvt_copy = vec_dup (reply);
2164
2165   /* Toss the shared-memory original... */
2166   pthread_mutex_lock (&am->vlib_rp->mutex);
2167   oldheap = svm_push_data_heap (am->vlib_rp);
2168
2169   vec_free (reply);
2170
2171   svm_pop_heap (oldheap);
2172   pthread_mutex_unlock (&am->vlib_rp->mutex);
2173
2174   if (vam->graph_nodes)
2175     {
2176       hash_free (vam->graph_node_index_by_name);
2177
2178       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2179         {
2180           node = vam->graph_nodes[i];
2181           vec_free (node->name);
2182           vec_free (node->next_nodes);
2183           vec_free (node);
2184         }
2185       vec_free (vam->graph_nodes);
2186     }
2187
2188   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2189   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2190   vec_free (pvt_copy);
2191
2192   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2193     {
2194       node = vam->graph_nodes[i];
2195       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2196     }
2197 }
2198
2199 static void vl_api_get_node_graph_reply_t_handler_json
2200   (vl_api_get_node_graph_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   api_main_t *am = &api_main;
2204   void *oldheap;
2205   vat_json_node_t node;
2206   u8 *reply;
2207
2208   /* $$$$ make this real? */
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2212
2213   reply = (u8 *) (mp->reply_in_shmem);
2214
2215   /* Toss the shared-memory original... */
2216   pthread_mutex_lock (&am->vlib_rp->mutex);
2217   oldheap = svm_push_data_heap (am->vlib_rp);
2218
2219   vec_free (reply);
2220
2221   svm_pop_heap (oldheap);
2222   pthread_mutex_unlock (&am->vlib_rp->mutex);
2223
2224   vat_json_print (vam->ofp, &node);
2225   vat_json_free (&node);
2226
2227   vam->retval = ntohl (mp->retval);
2228   vam->result_ready = 1;
2229 }
2230
2231 static void
2232 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   locator_msg_t loc;
2236   u8 *tmp_str = 0;
2237
2238   memset (&loc, 0, sizeof (loc));
2239   if (vam->noprint_msg)
2240     {
2241       loc.local = mp->local;
2242       loc.priority = mp->priority;
2243       loc.weight = mp->weight;
2244       if (loc.local)
2245         {
2246           loc.sw_if_index = ntohl (mp->sw_if_index);
2247         }
2248       else
2249         {
2250           loc.is_ipv6 = mp->is_ipv6;
2251           clib_memcpy (loc.ip_address, mp->ip_address,
2252                        sizeof (loc.ip_address));
2253         }
2254       vec_add1 (vam->locator_msg, loc);
2255     }
2256   else
2257     {
2258       if (mp->local)
2259         {
2260           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2261                             ntohl (mp->sw_if_index),
2262                             mp->priority, mp->weight);
2263         }
2264       else
2265         {
2266           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2267                             mp->is_ipv6 ? format_ip6_address :
2268                             format_ip4_address,
2269                             mp->ip_address, mp->priority, mp->weight);
2270         }
2271
2272       fformat (vam->ofp, "%s", tmp_str);
2273
2274       vec_free (tmp_str);
2275     }
2276 }
2277
2278 static void
2279 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2280                                             mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t *node = NULL;
2284   locator_msg_t loc;
2285   struct in6_addr ip6;
2286   struct in_addr ip4;
2287
2288   memset (&loc, 0, sizeof (loc));
2289   if (vam->noprint_msg)
2290     {
2291       loc.local = mp->local;
2292       loc.priority = mp->priority;
2293       loc.weight = mp->weight;
2294       if (loc.local)
2295         {
2296           loc.sw_if_index = ntohl (mp->sw_if_index);
2297         }
2298       else
2299         {
2300           loc.is_ipv6 = mp->is_ipv6;
2301           clib_memcpy (loc.ip_address, mp->ip_address,
2302                        sizeof (loc.ip_address));
2303         }
2304       vec_add1 (vam->locator_msg, loc);
2305       return;
2306     }
2307
2308   if (VAT_JSON_ARRAY != vam->json_tree.type)
2309     {
2310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2311       vat_json_init_array (&vam->json_tree);
2312     }
2313   node = vat_json_array_add (&vam->json_tree);
2314
2315   vat_json_init_object (node);
2316
2317   if (mp->local)
2318     {
2319       vat_json_object_add_uint (node, "locator_index",
2320                                 ntohl (mp->sw_if_index));
2321     }
2322   else
2323     {
2324       if (mp->is_ipv6)
2325         {
2326           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2327           vat_json_object_add_ip6 (node, "locator", ip6);
2328         }
2329       else
2330         {
2331           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2332           vat_json_object_add_ip4 (node, "locator", ip4);
2333         }
2334     }
2335   vat_json_object_add_uint (node, "priority", mp->priority);
2336   vat_json_object_add_uint (node, "weight", mp->weight);
2337 }
2338
2339 static void
2340 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2341                                            mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   locator_set_msg_t ls;
2345
2346   ls.locator_set_index = ntohl (mp->locator_set_index);
2347   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2348   vec_add1 (vam->locator_set_msg, ls);
2349 }
2350
2351 static void
2352   vl_api_lisp_locator_set_details_t_handler_json
2353   (vl_api_lisp_locator_set_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   locator_set_msg_t ls;
2357
2358   ls.locator_set_index = ntohl (mp->locator_set_index);
2359   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2360   vec_add1 (vam->locator_set_msg, ls);
2361 }
2362
2363 static void
2364 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   eid_table_t eid_table;
2368
2369   memset (&eid_table, 0, sizeof (eid_table));
2370   eid_table.is_local = mp->is_local;
2371   eid_table.locator_set_index = mp->locator_set_index;
2372   eid_table.eid_type = mp->eid_type;
2373   eid_table.vni = mp->vni;
2374   eid_table.eid_prefix_len = mp->eid_prefix_len;
2375   eid_table.ttl = mp->ttl;
2376   eid_table.authoritative = mp->authoritative;
2377   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2378   vec_add1 (vam->eid_tables, eid_table);
2379 }
2380
2381 static void
2382 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2383                                               * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   eid_table_t eid_table;
2387
2388   memset (&eid_table, 0, sizeof (eid_table));
2389   eid_table.is_local = mp->is_local;
2390   eid_table.locator_set_index = mp->locator_set_index;
2391   eid_table.eid_type = mp->eid_type;
2392   eid_table.vni = mp->vni;
2393   eid_table.eid_prefix_len = mp->eid_prefix_len;
2394   eid_table.ttl = mp->ttl;
2395   eid_table.authoritative = mp->authoritative;
2396   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2397   vec_add1 (vam->eid_tables, eid_table);
2398 }
2399
2400 static void
2401   vl_api_lisp_eid_table_map_details_t_handler
2402   (vl_api_lisp_eid_table_map_details_t * mp)
2403 {
2404   vat_main_t *vam = &vat_main;
2405
2406   u8 *line = format (0, "%=10d%=10d",
2407                      clib_net_to_host_u32 (mp->vni),
2408                      clib_net_to_host_u32 (mp->dp_table));
2409   fformat (vam->ofp, "%v\n", line);
2410   vec_free (line);
2411 }
2412
2413 static void
2414   vl_api_lisp_eid_table_map_details_t_handler_json
2415   (vl_api_lisp_eid_table_map_details_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t *node = NULL;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426   vat_json_init_object (node);
2427   vat_json_object_add_uint (node, "dp_table",
2428                             clib_net_to_host_u32 (mp->dp_table));
2429   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2430 }
2431
2432 static void
2433   vl_api_lisp_eid_table_vni_details_t_handler
2434   (vl_api_lisp_eid_table_vni_details_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437
2438   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_vni_details_t_handler_json
2445   (vl_api_lisp_eid_table_vni_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2458 }
2459
2460 static u8 *
2461 format_decap_next (u8 * s, va_list * args)
2462 {
2463   u32 next_index = va_arg (*args, u32);
2464
2465   switch (next_index)
2466     {
2467     case LISP_GPE_INPUT_NEXT_DROP:
2468       return format (s, "drop");
2469     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2470       return format (s, "ip4");
2471     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2472       return format (s, "ip6");
2473     default:
2474       return format (s, "unknown %d", next_index);
2475     }
2476   return s;
2477 }
2478
2479 static void
2480 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2481                                           mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   u8 *iid_str;
2485   u8 *flag_str = NULL;
2486
2487   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2488
2489 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2490   foreach_lisp_gpe_flag_bit;
2491 #undef _
2492
2493   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2494            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2495            mp->tunnels,
2496            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2497            mp->source_ip,
2498            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2499            mp->destination_ip,
2500            ntohl (mp->encap_fib_id),
2501            ntohl (mp->decap_fib_id),
2502            format_decap_next, ntohl (mp->dcap_next),
2503            mp->ver_res >> 6,
2504            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2505
2506   vec_free (iid_str);
2507 }
2508
2509 static void
2510   vl_api_lisp_gpe_tunnel_details_t_handler_json
2511   (vl_api_lisp_gpe_tunnel_details_t * mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   vat_json_node_t *node = NULL;
2515   struct in6_addr ip6;
2516   struct in_addr ip4;
2517   u8 *next_decap_str;
2518
2519   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2520
2521   if (VAT_JSON_ARRAY != vam->json_tree.type)
2522     {
2523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2524       vat_json_init_array (&vam->json_tree);
2525     }
2526   node = vat_json_array_add (&vam->json_tree);
2527
2528   vat_json_init_object (node);
2529   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2530   if (mp->is_ipv6)
2531     {
2532       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2533       vat_json_object_add_ip6 (node, "source address", ip6);
2534       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2535       vat_json_object_add_ip6 (node, "destination address", ip6);
2536     }
2537   else
2538     {
2539       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2540       vat_json_object_add_ip4 (node, "source address", ip4);
2541       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2542       vat_json_object_add_ip4 (node, "destination address", ip4);
2543     }
2544   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2545   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2546   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2547   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2548   vat_json_object_add_uint (node, "flags", mp->flags);
2549   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2550   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2551   vat_json_object_add_uint (node, "res", mp->res);
2552   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2553
2554   vec_free (next_decap_str);
2555 }
2556
2557 static void
2558 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2559                                             * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562
2563   fformat (vam->ofp, "%=20U\n",
2564            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2565            mp->ip_address);
2566 }
2567
2568 static void
2569   vl_api_lisp_map_resolver_details_t_handler_json
2570   (vl_api_lisp_map_resolver_details_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t *node = NULL;
2574   struct in6_addr ip6;
2575   struct in_addr ip4;
2576
2577   if (VAT_JSON_ARRAY != vam->json_tree.type)
2578     {
2579       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2580       vat_json_init_array (&vam->json_tree);
2581     }
2582   node = vat_json_array_add (&vam->json_tree);
2583
2584   vat_json_init_object (node);
2585   if (mp->is_ipv6)
2586     {
2587       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2588       vat_json_object_add_ip6 (node, "map resolver", ip6);
2589     }
2590   else
2591     {
2592       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2593       vat_json_object_add_ip4 (node, "map resolver", ip4);
2594     }
2595 }
2596
2597 static void
2598   vl_api_show_lisp_status_reply_t_handler
2599   (vl_api_show_lisp_status_reply_t * mp)
2600 {
2601   vat_main_t *vam = &vat_main;
2602   i32 retval = ntohl (mp->retval);
2603
2604   if (0 <= retval)
2605     {
2606       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2607                mp->feature_status ? "enabled" : "disabled",
2608                mp->gpe_status ? "enabled" : "disabled");
2609     }
2610
2611   vam->retval = retval;
2612   vam->result_ready = 1;
2613 }
2614
2615 static void
2616   vl_api_show_lisp_status_reply_t_handler_json
2617   (vl_api_show_lisp_status_reply_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   vat_json_node_t node;
2621   u8 *gpe_status = NULL;
2622   u8 *feature_status = NULL;
2623
2624   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2625   feature_status = format (0, "%s",
2626                            mp->feature_status ? "enabled" : "disabled");
2627   vec_add1 (gpe_status, 0);
2628   vec_add1 (feature_status, 0);
2629
2630   vat_json_init_object (&node);
2631   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2632   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2633
2634   vec_free (gpe_status);
2635   vec_free (feature_status);
2636
2637   vat_json_print (vam->ofp, &node);
2638   vat_json_free (&node);
2639
2640   vam->retval = ntohl (mp->retval);
2641   vam->result_ready = 1;
2642 }
2643
2644 static void
2645   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2646   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649   i32 retval = ntohl (mp->retval);
2650
2651   if (retval >= 0)
2652     {
2653       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2654     }
2655
2656   vam->retval = retval;
2657   vam->result_ready = 1;
2658 }
2659
2660 static void
2661   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2662   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2663 {
2664   vat_main_t *vam = &vat_main;
2665   vat_json_node_t *node = NULL;
2666
2667   if (VAT_JSON_ARRAY != vam->json_tree.type)
2668     {
2669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2670       vat_json_init_array (&vam->json_tree);
2671     }
2672   node = vat_json_array_add (&vam->json_tree);
2673
2674   vat_json_init_object (node);
2675   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2676
2677   vat_json_print (vam->ofp, node);
2678   vat_json_free (node);
2679
2680   vam->retval = ntohl (mp->retval);
2681   vam->result_ready = 1;
2682 }
2683
2684 static void
2685 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2686 {
2687   vat_main_t *vam = &vat_main;
2688   i32 retval = ntohl (mp->retval);
2689
2690   if (0 <= retval)
2691     {
2692       fformat (vam->ofp, "%-20s%-16s\n",
2693                mp->status ? "enabled" : "disabled",
2694                mp->status ? (char *) mp->locator_set_name : "");
2695     }
2696
2697   vam->retval = retval;
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2703                                             mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   vat_json_node_t node;
2707   u8 *status = 0;
2708
2709   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2710   vec_add1 (status, 0);
2711
2712   vat_json_init_object (&node);
2713   vat_json_object_add_string_copy (&node, "status", status);
2714   if (mp->status)
2715     {
2716       vat_json_object_add_string_copy (&node, "locator_set",
2717                                        mp->locator_set_name);
2718     }
2719
2720   vec_free (status);
2721
2722   vat_json_print (vam->ofp, &node);
2723   vat_json_free (&node);
2724
2725   vam->retval = ntohl (mp->retval);
2726   vam->result_ready = 1;
2727 }
2728
2729 static u8 *
2730 format_policer_type (u8 * s, va_list * va)
2731 {
2732   u32 i = va_arg (*va, u32);
2733
2734   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2735     s = format (s, "1r2c");
2736   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2737     s = format (s, "1r3c");
2738   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2739     s = format (s, "2r3c-2698");
2740   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2741     s = format (s, "2r3c-4115");
2742   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2743     s = format (s, "2r3c-mef5cf1");
2744   else
2745     s = format (s, "ILLEGAL");
2746   return s;
2747 }
2748
2749 static u8 *
2750 format_policer_rate_type (u8 * s, va_list * va)
2751 {
2752   u32 i = va_arg (*va, u32);
2753
2754   if (i == SSE2_QOS_RATE_KBPS)
2755     s = format (s, "kbps");
2756   else if (i == SSE2_QOS_RATE_PPS)
2757     s = format (s, "pps");
2758   else
2759     s = format (s, "ILLEGAL");
2760   return s;
2761 }
2762
2763 static u8 *
2764 format_policer_round_type (u8 * s, va_list * va)
2765 {
2766   u32 i = va_arg (*va, u32);
2767
2768   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2769     s = format (s, "closest");
2770   else if (i == SSE2_QOS_ROUND_TO_UP)
2771     s = format (s, "up");
2772   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2773     s = format (s, "down");
2774   else
2775     s = format (s, "ILLEGAL");
2776   return s;
2777 }
2778
2779 static u8 *
2780 format_policer_action_type (u8 * s, va_list * va)
2781 {
2782   u32 i = va_arg (*va, u32);
2783
2784   if (i == SSE2_QOS_ACTION_DROP)
2785     s = format (s, "drop");
2786   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2787     s = format (s, "transmit");
2788   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2789     s = format (s, "mark-and-transmit");
2790   else
2791     s = format (s, "ILLEGAL");
2792   return s;
2793 }
2794
2795 static u8 *
2796 format_dscp (u8 * s, va_list * va)
2797 {
2798   u32 i = va_arg (*va, u32);
2799   char *t = 0;
2800
2801   switch (i)
2802     {
2803 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2804       foreach_vnet_dscp
2805 #undef _
2806     default:
2807       return format (s, "ILLEGAL");
2808     }
2809   s = format (s, "%s", t);
2810   return s;
2811 }
2812
2813 static void
2814 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2815 {
2816   vat_main_t *vam = &vat_main;
2817   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2818
2819   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2820     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2821   else
2822     conform_dscp_str = format (0, "");
2823
2824   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2825     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2826   else
2827     exceed_dscp_str = format (0, "");
2828
2829   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2830     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2831   else
2832     violate_dscp_str = format (0, "");
2833
2834   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2835            "rate type %U, round type %U, %s rate, %s color-aware, "
2836            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2837            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2838            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2839            mp->name,
2840            format_policer_type, mp->type,
2841            ntohl (mp->cir),
2842            ntohl (mp->eir),
2843            clib_net_to_host_u64 (mp->cb),
2844            clib_net_to_host_u64 (mp->eb),
2845            format_policer_rate_type, mp->rate_type,
2846            format_policer_round_type, mp->round_type,
2847            mp->single_rate ? "single" : "dual",
2848            mp->color_aware ? "is" : "not",
2849            ntohl (mp->cir_tokens_per_period),
2850            ntohl (mp->pir_tokens_per_period),
2851            ntohl (mp->scale),
2852            ntohl (mp->current_limit),
2853            ntohl (mp->current_bucket),
2854            ntohl (mp->extended_limit),
2855            ntohl (mp->extended_bucket),
2856            clib_net_to_host_u64 (mp->last_update_time),
2857            format_policer_action_type, mp->conform_action_type,
2858            conform_dscp_str,
2859            format_policer_action_type, mp->exceed_action_type,
2860            exceed_dscp_str,
2861            format_policer_action_type, mp->violate_action_type,
2862            violate_dscp_str);
2863
2864   vec_free (conform_dscp_str);
2865   vec_free (exceed_dscp_str);
2866   vec_free (violate_dscp_str);
2867 }
2868
2869 static void vl_api_policer_details_t_handler_json
2870   (vl_api_policer_details_t * mp)
2871 {
2872   vat_main_t *vam = &vat_main;
2873   vat_json_node_t *node;
2874   u8 *rate_type_str, *round_type_str, *type_str;
2875   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2876
2877   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2878   round_type_str =
2879     format (0, "%U", format_policer_round_type, mp->round_type);
2880   type_str = format (0, "%U", format_policer_type, mp->type);
2881   conform_action_str = format (0, "%U", format_policer_action_type,
2882                                mp->conform_action_type);
2883   exceed_action_str = format (0, "%U", format_policer_action_type,
2884                               mp->exceed_action_type);
2885   violate_action_str = format (0, "%U", format_policer_action_type,
2886                                mp->violate_action_type);
2887
2888   if (VAT_JSON_ARRAY != vam->json_tree.type)
2889     {
2890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2891       vat_json_init_array (&vam->json_tree);
2892     }
2893   node = vat_json_array_add (&vam->json_tree);
2894
2895   vat_json_init_object (node);
2896   vat_json_object_add_string_copy (node, "name", mp->name);
2897   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2898   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2899   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2900   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2901   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2902   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2903   vat_json_object_add_string_copy (node, "type", type_str);
2904   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2905   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2906   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2907   vat_json_object_add_uint (node, "cir_tokens_per_period",
2908                             ntohl (mp->cir_tokens_per_period));
2909   vat_json_object_add_uint (node, "eir_tokens_per_period",
2910                             ntohl (mp->pir_tokens_per_period));
2911   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2912   vat_json_object_add_uint (node, "current_bucket",
2913                             ntohl (mp->current_bucket));
2914   vat_json_object_add_uint (node, "extended_limit",
2915                             ntohl (mp->extended_limit));
2916   vat_json_object_add_uint (node, "extended_bucket",
2917                             ntohl (mp->extended_bucket));
2918   vat_json_object_add_uint (node, "last_update_time",
2919                             ntohl (mp->last_update_time));
2920   vat_json_object_add_string_copy (node, "conform_action",
2921                                    conform_action_str);
2922   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2923     {
2924       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2925       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2926       vec_free (dscp_str);
2927     }
2928   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2929   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2930     {
2931       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2932       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2933       vec_free (dscp_str);
2934     }
2935   vat_json_object_add_string_copy (node, "violate_action",
2936                                    violate_action_str);
2937   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     {
2939       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2940       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2941       vec_free (dscp_str);
2942     }
2943
2944   vec_free (rate_type_str);
2945   vec_free (round_type_str);
2946   vec_free (type_str);
2947   vec_free (conform_action_str);
2948   vec_free (exceed_action_str);
2949   vec_free (violate_action_str);
2950 }
2951
2952 static void
2953 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2954                                            mp)
2955 {
2956   vat_main_t *vam = &vat_main;
2957   int i, count = ntohl (mp->count);
2958
2959   if (count > 0)
2960     fformat (vam->ofp, "classify table ids (%d) : ", count);
2961   for (i = 0; i < count; i++)
2962     {
2963       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2964       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2965     }
2966   vam->retval = ntohl (mp->retval);
2967   vam->result_ready = 1;
2968 }
2969
2970 static void
2971   vl_api_classify_table_ids_reply_t_handler_json
2972   (vl_api_classify_table_ids_reply_t * mp)
2973 {
2974   vat_main_t *vam = &vat_main;
2975   int i, count = ntohl (mp->count);
2976
2977   if (count > 0)
2978     {
2979       vat_json_node_t node;
2980
2981       vat_json_init_object (&node);
2982       for (i = 0; i < count; i++)
2983         {
2984           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2985         }
2986       vat_json_print (vam->ofp, &node);
2987       vat_json_free (&node);
2988     }
2989   vam->retval = ntohl (mp->retval);
2990   vam->result_ready = 1;
2991 }
2992
2993 static void
2994   vl_api_classify_table_by_interface_reply_t_handler
2995   (vl_api_classify_table_by_interface_reply_t * mp)
2996 {
2997   vat_main_t *vam = &vat_main;
2998   u32 table_id;
2999
3000   table_id = ntohl (mp->l2_table_id);
3001   if (table_id != ~0)
3002     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3003   else
3004     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3005   table_id = ntohl (mp->ip4_table_id);
3006   if (table_id != ~0)
3007     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3008   else
3009     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3010   table_id = ntohl (mp->ip6_table_id);
3011   if (table_id != ~0)
3012     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3013   else
3014     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3015   vam->retval = ntohl (mp->retval);
3016   vam->result_ready = 1;
3017 }
3018
3019 static void
3020   vl_api_classify_table_by_interface_reply_t_handler_json
3021   (vl_api_classify_table_by_interface_reply_t * mp)
3022 {
3023   vat_main_t *vam = &vat_main;
3024   vat_json_node_t node;
3025
3026   vat_json_init_object (&node);
3027
3028   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3029   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3030   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3031
3032   vat_json_print (vam->ofp, &node);
3033   vat_json_free (&node);
3034
3035   vam->retval = ntohl (mp->retval);
3036   vam->result_ready = 1;
3037 }
3038
3039 static void vl_api_policer_add_del_reply_t_handler
3040   (vl_api_policer_add_del_reply_t * mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   i32 retval = ntohl (mp->retval);
3044   if (vam->async_mode)
3045     {
3046       vam->async_errors += (retval < 0);
3047     }
3048   else
3049     {
3050       vam->retval = retval;
3051       vam->result_ready = 1;
3052       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3053         /*
3054          * Note: this is just barely thread-safe, depends on
3055          * the main thread spinning waiting for an answer...
3056          */
3057         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3058     }
3059 }
3060
3061 static void vl_api_policer_add_del_reply_t_handler_json
3062   (vl_api_policer_add_del_reply_t * mp)
3063 {
3064   vat_main_t *vam = &vat_main;
3065   vat_json_node_t node;
3066
3067   vat_json_init_object (&node);
3068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3069   vat_json_object_add_uint (&node, "policer_index",
3070                             ntohl (mp->policer_index));
3071
3072   vat_json_print (vam->ofp, &node);
3073   vat_json_free (&node);
3074
3075   vam->retval = ntohl (mp->retval);
3076   vam->result_ready = 1;
3077 }
3078
3079 /* Format hex dump. */
3080 u8 *
3081 format_hex_bytes (u8 * s, va_list * va)
3082 {
3083   u8 *bytes = va_arg (*va, u8 *);
3084   int n_bytes = va_arg (*va, int);
3085   uword i;
3086
3087   /* Print short or long form depending on byte count. */
3088   uword short_form = n_bytes <= 32;
3089   uword indent = format_get_indent (s);
3090
3091   if (n_bytes == 0)
3092     return s;
3093
3094   for (i = 0; i < n_bytes; i++)
3095     {
3096       if (!short_form && (i % 32) == 0)
3097         s = format (s, "%08x: ", i);
3098       s = format (s, "%02x", bytes[i]);
3099       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3100         s = format (s, "\n%U", format_white_space, indent);
3101     }
3102
3103   return s;
3104 }
3105
3106 static void
3107 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3108                                             * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   i32 retval = ntohl (mp->retval);
3112   if (retval == 0)
3113     {
3114       fformat (vam->ofp, "classify table info :\n");
3115       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3116                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3117                ntohl (mp->miss_next_index));
3118       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3119                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3120                ntohl (mp->match_n_vectors));
3121       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3122                ntohl (mp->mask_length));
3123     }
3124   vam->retval = retval;
3125   vam->result_ready = 1;
3126 }
3127
3128 static void
3129   vl_api_classify_table_info_reply_t_handler_json
3130   (vl_api_classify_table_info_reply_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   vat_json_node_t node;
3134
3135   i32 retval = ntohl (mp->retval);
3136   if (retval == 0)
3137     {
3138       vat_json_init_object (&node);
3139
3140       vat_json_object_add_int (&node, "sessions",
3141                                ntohl (mp->active_sessions));
3142       vat_json_object_add_int (&node, "nexttbl",
3143                                ntohl (mp->next_table_index));
3144       vat_json_object_add_int (&node, "nextnode",
3145                                ntohl (mp->miss_next_index));
3146       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3147       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3148       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3149       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3150                       ntohl (mp->mask_length), 0);
3151       vat_json_object_add_string_copy (&node, "mask", s);
3152
3153       vat_json_print (vam->ofp, &node);
3154       vat_json_free (&node);
3155     }
3156   vam->retval = ntohl (mp->retval);
3157   vam->result_ready = 1;
3158 }
3159
3160 static void
3161 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3162                                            mp)
3163 {
3164   vat_main_t *vam = &vat_main;
3165
3166   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3167            ntohl (mp->hit_next_index), ntohl (mp->advance),
3168            ntohl (mp->opaque_index));
3169   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3170            ntohl (mp->match_length));
3171 }
3172
3173 static void
3174   vl_api_classify_session_details_t_handler_json
3175   (vl_api_classify_session_details_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t *node = NULL;
3179
3180   if (VAT_JSON_ARRAY != vam->json_tree.type)
3181     {
3182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3183       vat_json_init_array (&vam->json_tree);
3184     }
3185   node = vat_json_array_add (&vam->json_tree);
3186
3187   vat_json_init_object (node);
3188   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3189   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3190   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3191   u8 *s =
3192     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3193             0);
3194   vat_json_object_add_string_copy (node, "match", s);
3195 }
3196
3197 static void vl_api_pg_create_interface_reply_t_handler
3198   (vl_api_pg_create_interface_reply_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201
3202   vam->retval = ntohl (mp->retval);
3203   vam->result_ready = 1;
3204 }
3205
3206 static void vl_api_pg_create_interface_reply_t_handler_json
3207   (vl_api_pg_create_interface_reply_t * mp)
3208 {
3209   vat_main_t *vam = &vat_main;
3210   vat_json_node_t node;
3211
3212   i32 retval = ntohl (mp->retval);
3213   if (retval == 0)
3214     {
3215       vat_json_init_object (&node);
3216
3217       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3218
3219       vat_json_print (vam->ofp, &node);
3220       vat_json_free (&node);
3221     }
3222   vam->retval = ntohl (mp->retval);
3223   vam->result_ready = 1;
3224 }
3225
3226 static void vl_api_policer_classify_details_t_handler
3227   (vl_api_policer_classify_details_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230
3231   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3232            ntohl (mp->table_index));
3233 }
3234
3235 static void vl_api_policer_classify_details_t_handler_json
3236   (vl_api_policer_classify_details_t * mp)
3237 {
3238   vat_main_t *vam = &vat_main;
3239   vat_json_node_t *node;
3240
3241   if (VAT_JSON_ARRAY != vam->json_tree.type)
3242     {
3243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3244       vat_json_init_array (&vam->json_tree);
3245     }
3246   node = vat_json_array_add (&vam->json_tree);
3247
3248   vat_json_init_object (node);
3249   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3250   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3251 }
3252
3253 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3254   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3255 {
3256   vat_main_t *vam = &vat_main;
3257   i32 retval = ntohl (mp->retval);
3258   if (vam->async_mode)
3259     {
3260       vam->async_errors += (retval < 0);
3261     }
3262   else
3263     {
3264       vam->retval = retval;
3265       vam->sw_if_index = ntohl (mp->sw_if_index);
3266       vam->result_ready = 1;
3267     }
3268 }
3269
3270 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3271   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3272 {
3273   vat_main_t *vam = &vat_main;
3274   vat_json_node_t node;
3275
3276   vat_json_init_object (&node);
3277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3278   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3279
3280   vat_json_print (vam->ofp, &node);
3281   vat_json_free (&node);
3282
3283   vam->retval = ntohl (mp->retval);
3284   vam->result_ready = 1;
3285 }
3286
3287 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3288 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3289 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3290 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3291
3292 /*
3293  * Generate boilerplate reply handlers, which
3294  * dig the return value out of the xxx_reply_t API message,
3295  * stick it into vam->retval, and set vam->result_ready
3296  *
3297  * Could also do this by pointing N message decode slots at
3298  * a single function, but that could break in subtle ways.
3299  */
3300
3301 #define foreach_standard_reply_retval_handler           \
3302 _(sw_interface_set_flags_reply)                         \
3303 _(sw_interface_add_del_address_reply)                   \
3304 _(sw_interface_set_table_reply)                         \
3305 _(sw_interface_set_vpath_reply)                         \
3306 _(sw_interface_set_l2_bridge_reply)                     \
3307 _(bridge_domain_add_del_reply)                          \
3308 _(sw_interface_set_l2_xconnect_reply)                   \
3309 _(l2fib_add_del_reply)                                  \
3310 _(ip_add_del_route_reply)                               \
3311 _(proxy_arp_add_del_reply)                              \
3312 _(proxy_arp_intfc_enable_disable_reply)                 \
3313 _(mpls_add_del_encap_reply)                             \
3314 _(mpls_add_del_decap_reply)                             \
3315 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3316 _(sw_interface_set_unnumbered_reply)                    \
3317 _(ip_neighbor_add_del_reply)                            \
3318 _(reset_vrf_reply)                                      \
3319 _(oam_add_del_reply)                                    \
3320 _(reset_fib_reply)                                      \
3321 _(dhcp_proxy_config_reply)                              \
3322 _(dhcp_proxy_config_2_reply)                            \
3323 _(dhcp_proxy_set_vss_reply)                             \
3324 _(dhcp_client_config_reply)                             \
3325 _(set_ip_flow_hash_reply)                               \
3326 _(sw_interface_ip6_enable_disable_reply)                \
3327 _(sw_interface_ip6_set_link_local_address_reply)        \
3328 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3329 _(sw_interface_ip6nd_ra_config_reply)                   \
3330 _(set_arp_neighbor_limit_reply)                         \
3331 _(l2_patch_add_del_reply)                               \
3332 _(sr_tunnel_add_del_reply)                              \
3333 _(sr_policy_add_del_reply)                              \
3334 _(sr_multicast_map_add_del_reply)                       \
3335 _(classify_add_del_session_reply)                       \
3336 _(classify_set_interface_ip_table_reply)                \
3337 _(classify_set_interface_l2_tables_reply)               \
3338 _(l2tpv3_set_tunnel_cookies_reply)                      \
3339 _(l2tpv3_interface_enable_disable_reply)                \
3340 _(l2tpv3_set_lookup_key_reply)                          \
3341 _(l2_fib_clear_table_reply)                             \
3342 _(l2_interface_efp_filter_reply)                        \
3343 _(l2_interface_vlan_tag_rewrite_reply)                  \
3344 _(modify_vhost_user_if_reply)                           \
3345 _(delete_vhost_user_if_reply)                           \
3346 _(want_ip4_arp_events_reply)                            \
3347 _(input_acl_set_interface_reply)                        \
3348 _(ipsec_spd_add_del_reply)                              \
3349 _(ipsec_interface_add_del_spd_reply)                    \
3350 _(ipsec_spd_add_del_entry_reply)                        \
3351 _(ipsec_sad_add_del_entry_reply)                        \
3352 _(ipsec_sa_set_key_reply)                               \
3353 _(ikev2_profile_add_del_reply)                          \
3354 _(ikev2_profile_set_auth_reply)                         \
3355 _(ikev2_profile_set_id_reply)                           \
3356 _(ikev2_profile_set_ts_reply)                           \
3357 _(ikev2_set_local_key_reply)                            \
3358 _(delete_loopback_reply)                                \
3359 _(bd_ip_mac_add_del_reply)                              \
3360 _(map_del_domain_reply)                                 \
3361 _(map_add_del_rule_reply)                               \
3362 _(want_interface_events_reply)                          \
3363 _(want_stats_reply)                                     \
3364 _(cop_interface_enable_disable_reply)                   \
3365 _(cop_whitelist_enable_disable_reply)                   \
3366 _(sw_interface_clear_stats_reply)                       \
3367 _(trace_profile_add_reply)                              \
3368 _(trace_profile_apply_reply)                            \
3369 _(trace_profile_del_reply)                              \
3370 _(lisp_add_del_locator_reply)                           \
3371 _(lisp_add_del_local_eid_reply)                         \
3372 _(lisp_add_del_remote_mapping_reply)                    \
3373 _(lisp_add_del_adjacency_reply)                         \
3374 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3375 _(lisp_add_del_map_resolver_reply)                      \
3376 _(lisp_gpe_enable_disable_reply)                        \
3377 _(lisp_gpe_add_del_iface_reply)                         \
3378 _(lisp_enable_disable_reply)                            \
3379 _(lisp_pitr_set_locator_set_reply)                      \
3380 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3381 _(lisp_eid_table_add_del_map_reply)                     \
3382 _(vxlan_gpe_add_del_tunnel_reply)                       \
3383 _(af_packet_delete_reply)                               \
3384 _(policer_classify_set_interface_reply)                 \
3385 _(netmap_create_reply)                                  \
3386 _(netmap_delete_reply)                                  \
3387 _(ipfix_enable_reply)                                   \
3388 _(pg_capture_reply)                                     \
3389 _(pg_enable_disable_reply)                              \
3390 _(ip_source_and_port_range_check_add_del_reply)         \
3391 _(ip_source_and_port_range_check_interface_add_del_reply)
3392
3393 #define _(n)                                    \
3394     static void vl_api_##n##_t_handler          \
3395     (vl_api_##n##_t * mp)                       \
3396     {                                           \
3397         vat_main_t * vam = &vat_main;           \
3398         i32 retval = ntohl(mp->retval);         \
3399         if (vam->async_mode) {                  \
3400             vam->async_errors += (retval < 0);  \
3401         } else {                                \
3402             vam->retval = retval;               \
3403             vam->result_ready = 1;              \
3404         }                                       \
3405     }
3406 foreach_standard_reply_retval_handler;
3407 #undef _
3408
3409 #define _(n)                                    \
3410     static void vl_api_##n##_t_handler_json     \
3411     (vl_api_##n##_t * mp)                       \
3412     {                                           \
3413         vat_main_t * vam = &vat_main;           \
3414         vat_json_node_t node;                   \
3415         vat_json_init_object(&node);            \
3416         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3417         vat_json_print(vam->ofp, &node);        \
3418         vam->retval = ntohl(mp->retval);        \
3419         vam->result_ready = 1;                  \
3420     }
3421 foreach_standard_reply_retval_handler;
3422 #undef _
3423
3424 /*
3425  * Table of message reply handlers, must include boilerplate handlers
3426  * we just generated
3427  */
3428
3429 #define foreach_vpe_api_reply_msg                                       \
3430 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3431 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3432 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3433 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3434 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3435 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3436 _(CLI_REPLY, cli_reply)                                                 \
3437 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3438   sw_interface_add_del_address_reply)                                   \
3439 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3440 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3441 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3442   sw_interface_set_l2_xconnect_reply)                                   \
3443 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3444   sw_interface_set_l2_bridge_reply)                                     \
3445 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3446 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3447 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3448 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3449 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3450 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3451 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3452 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3453 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3454 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3455 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3456 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3457 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3458   proxy_arp_intfc_enable_disable_reply)                                 \
3459 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3460 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3461 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3462 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3463   mpls_ethernet_add_del_tunnel_reply)                                   \
3464 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3465   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3466 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3467   sw_interface_set_unnumbered_reply)                                    \
3468 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3469 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3470 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3471 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3472 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3473 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3474 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3475 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3476 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3477 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3478 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3479 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3480   sw_interface_ip6_enable_disable_reply)                                \
3481 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3482   sw_interface_ip6_set_link_local_address_reply)                        \
3483 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3484   sw_interface_ip6nd_ra_prefix_reply)                                   \
3485 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3486   sw_interface_ip6nd_ra_config_reply)                                   \
3487 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3488 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3489 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3490 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3491 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3492 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3493 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3494 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3495 classify_set_interface_ip_table_reply)                                  \
3496 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3497   classify_set_interface_l2_tables_reply)                               \
3498 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3499 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3500 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3501 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3502 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3503   l2tpv3_interface_enable_disable_reply)                                \
3504 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3505 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3506 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3507 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3508 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3509 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3510 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3511 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3512 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3513 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3514 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3515 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3516 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3517 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3518 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3519 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3520 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3521 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3522 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3523 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3524 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3525 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3526 _(IP_DETAILS, ip_details)                                               \
3527 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3528 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3529 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3530 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3531 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3532 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3533 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3534 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3535 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3536 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3537 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3538 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3539 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3540 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3541 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3542 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3543 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3544 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3545 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3546 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3547 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3548 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3549 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3550 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3551 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3552 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3553 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3554 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3555 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3556 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3557 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3558 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3559 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3560 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3561 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3562 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3563 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3564 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3565 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3566 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3567 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3568 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3569 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3570 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3571 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3572 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3573 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3574 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3575 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3576 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3577 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3578 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3579   lisp_add_del_map_request_itr_rlocs_reply)                             \
3580 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3581   lisp_get_map_request_itr_rlocs_reply)                                 \
3582 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3583 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3584 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3585 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3586 _(POLICER_DETAILS, policer_details)                                     \
3587 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3588 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3589 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3590 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3591 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3592 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3593 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3594 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3595 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3596 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3597 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3598 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3599 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3600 _(IPFIX_DETAILS, ipfix_details)                                         \
3601 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3602 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3603 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3604 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3605 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3606  ip_source_and_port_range_check_add_del_reply)                          \
3607 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3608  ip_source_and_port_range_check_interface_add_del_reply)                \
3609 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3610 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)
3611
3612 /* M: construct, but don't yet send a message */
3613
3614 #define M(T,t)                                  \
3615 do {                                            \
3616     vam->result_ready = 0;                      \
3617     mp = vl_msg_api_alloc(sizeof(*mp));         \
3618     memset (mp, 0, sizeof (*mp));               \
3619     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3620     mp->client_index = vam->my_client_index;    \
3621 } while(0);
3622
3623 #define M2(T,t,n)                               \
3624 do {                                            \
3625     vam->result_ready = 0;                      \
3626     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3627     memset (mp, 0, sizeof (*mp));               \
3628     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3629     mp->client_index = vam->my_client_index;    \
3630 } while(0);
3631
3632
3633 /* S: send a message */
3634 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3635
3636 /* W: wait for results, with timeout */
3637 #define W                                       \
3638 do {                                            \
3639     timeout = vat_time_now (vam) + 1.0;         \
3640                                                 \
3641     while (vat_time_now (vam) < timeout) {      \
3642         if (vam->result_ready == 1) {           \
3643             return (vam->retval);               \
3644         }                                       \
3645     }                                           \
3646     return -99;                                 \
3647 } while(0);
3648
3649 /* W2: wait for results, with timeout */
3650 #define W2(body)                                \
3651 do {                                            \
3652     timeout = vat_time_now (vam) + 1.0;         \
3653                                                 \
3654     while (vat_time_now (vam) < timeout) {      \
3655         if (vam->result_ready == 1) {           \
3656           (body);                               \
3657           return (vam->retval);                 \
3658         }                                       \
3659     }                                           \
3660     return -99;                                 \
3661 } while(0);
3662
3663 /* W_L: wait for results, with timeout */
3664 #define W_L(body)                               \
3665 do {                                            \
3666     timeout = vat_time_now (vam) + 1.0;         \
3667                                                 \
3668     while (vat_time_now (vam) < timeout) {      \
3669         if (vam->result_ready == 1) {           \
3670           (body);                               \
3671           return (vam->retval);                 \
3672         }                                       \
3673     }                                           \
3674     vam->noprint_msg = 0;     \
3675     return -99;                                 \
3676 } while(0);
3677
3678 typedef struct
3679 {
3680   u8 *name;
3681   u32 value;
3682 } name_sort_t;
3683
3684
3685 #define STR_VTR_OP_CASE(op)     \
3686     case L2_VTR_ ## op:         \
3687         return "" # op;
3688
3689 static const char *
3690 str_vtr_op (u32 vtr_op)
3691 {
3692   switch (vtr_op)
3693     {
3694       STR_VTR_OP_CASE (DISABLED);
3695       STR_VTR_OP_CASE (PUSH_1);
3696       STR_VTR_OP_CASE (PUSH_2);
3697       STR_VTR_OP_CASE (POP_1);
3698       STR_VTR_OP_CASE (POP_2);
3699       STR_VTR_OP_CASE (TRANSLATE_1_1);
3700       STR_VTR_OP_CASE (TRANSLATE_1_2);
3701       STR_VTR_OP_CASE (TRANSLATE_2_1);
3702       STR_VTR_OP_CASE (TRANSLATE_2_2);
3703     }
3704
3705   return "UNKNOWN";
3706 }
3707
3708 static int
3709 dump_sub_interface_table (vat_main_t * vam)
3710 {
3711   const sw_interface_subif_t *sub = NULL;
3712
3713   if (vam->json_output)
3714     {
3715       clib_warning
3716         ("JSON output supported only for VPE API calls and dump_stats_table");
3717       return -99;
3718     }
3719
3720   fformat (vam->ofp,
3721            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3722            "Interface", "sw_if_index",
3723            "sub id", "dot1ad", "tags", "outer id",
3724            "inner id", "exact", "default", "outer any", "inner any");
3725
3726   vec_foreach (sub, vam->sw_if_subif_table)
3727   {
3728     fformat (vam->ofp,
3729              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3730              sub->interface_name,
3731              sub->sw_if_index,
3732              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3733              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3734              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3735              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3736     if (sub->vtr_op != L2_VTR_DISABLED)
3737       {
3738         fformat (vam->ofp,
3739                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3740                  "tag1: %d tag2: %d ]\n",
3741                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3742                  sub->vtr_tag1, sub->vtr_tag2);
3743       }
3744   }
3745
3746   return 0;
3747 }
3748
3749 static int
3750 name_sort_cmp (void *a1, void *a2)
3751 {
3752   name_sort_t *n1 = a1;
3753   name_sort_t *n2 = a2;
3754
3755   return strcmp ((char *) n1->name, (char *) n2->name);
3756 }
3757
3758 static int
3759 dump_interface_table (vat_main_t * vam)
3760 {
3761   hash_pair_t *p;
3762   name_sort_t *nses = 0, *ns;
3763
3764   if (vam->json_output)
3765     {
3766       clib_warning
3767         ("JSON output supported only for VPE API calls and dump_stats_table");
3768       return -99;
3769     }
3770
3771   /* *INDENT-OFF* */
3772   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3773   ({
3774     vec_add2 (nses, ns, 1);
3775     ns->name = (u8 *)(p->key);
3776     ns->value = (u32) p->value[0];
3777   }));
3778   /* *INDENT-ON* */
3779
3780   vec_sort_with_function (nses, name_sort_cmp);
3781
3782   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3783   vec_foreach (ns, nses)
3784   {
3785     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3786   }
3787   vec_free (nses);
3788   return 0;
3789 }
3790
3791 static int
3792 dump_ip_table (vat_main_t * vam, int is_ipv6)
3793 {
3794   const ip_details_t *det = NULL;
3795   const ip_address_details_t *address = NULL;
3796   u32 i = ~0;
3797
3798   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3799
3800   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3801   {
3802     i++;
3803     if (!det->present)
3804       {
3805         continue;
3806       }
3807     fformat (vam->ofp, "%-12d\n", i);
3808     fformat (vam->ofp,
3809              "            %-30s%-13s\n", "Address", "Prefix length");
3810     if (!det->addr)
3811       {
3812         continue;
3813       }
3814     vec_foreach (address, det->addr)
3815     {
3816       fformat (vam->ofp,
3817                "            %-30U%-13d\n",
3818                is_ipv6 ? format_ip6_address : format_ip4_address,
3819                address->ip, address->prefix_length);
3820     }
3821   }
3822
3823   return 0;
3824 }
3825
3826 static int
3827 dump_ipv4_table (vat_main_t * vam)
3828 {
3829   if (vam->json_output)
3830     {
3831       clib_warning
3832         ("JSON output supported only for VPE API calls and dump_stats_table");
3833       return -99;
3834     }
3835
3836   return dump_ip_table (vam, 0);
3837 }
3838
3839 static int
3840 dump_ipv6_table (vat_main_t * vam)
3841 {
3842   if (vam->json_output)
3843     {
3844       clib_warning
3845         ("JSON output supported only for VPE API calls and dump_stats_table");
3846       return -99;
3847     }
3848
3849   return dump_ip_table (vam, 1);
3850 }
3851
3852 static char *
3853 counter_type_to_str (u8 counter_type, u8 is_combined)
3854 {
3855   if (!is_combined)
3856     {
3857       switch (counter_type)
3858         {
3859         case VNET_INTERFACE_COUNTER_DROP:
3860           return "drop";
3861         case VNET_INTERFACE_COUNTER_PUNT:
3862           return "punt";
3863         case VNET_INTERFACE_COUNTER_IP4:
3864           return "ip4";
3865         case VNET_INTERFACE_COUNTER_IP6:
3866           return "ip6";
3867         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3868           return "rx-no-buf";
3869         case VNET_INTERFACE_COUNTER_RX_MISS:
3870           return "rx-miss";
3871         case VNET_INTERFACE_COUNTER_RX_ERROR:
3872           return "rx-error";
3873         case VNET_INTERFACE_COUNTER_TX_ERROR:
3874           return "tx-error";
3875         default:
3876           return "INVALID-COUNTER-TYPE";
3877         }
3878     }
3879   else
3880     {
3881       switch (counter_type)
3882         {
3883         case VNET_INTERFACE_COUNTER_RX:
3884           return "rx";
3885         case VNET_INTERFACE_COUNTER_TX:
3886           return "tx";
3887         default:
3888           return "INVALID-COUNTER-TYPE";
3889         }
3890     }
3891 }
3892
3893 static int
3894 dump_stats_table (vat_main_t * vam)
3895 {
3896   vat_json_node_t node;
3897   vat_json_node_t *msg_array;
3898   vat_json_node_t *msg;
3899   vat_json_node_t *counter_array;
3900   vat_json_node_t *counter;
3901   interface_counter_t c;
3902   u64 packets;
3903   ip4_fib_counter_t *c4;
3904   ip6_fib_counter_t *c6;
3905   int i, j;
3906
3907   if (!vam->json_output)
3908     {
3909       clib_warning ("dump_stats_table supported only in JSON format");
3910       return -99;
3911     }
3912
3913   vat_json_init_object (&node);
3914
3915   /* interface counters */
3916   msg_array = vat_json_object_add (&node, "interface_counters");
3917   vat_json_init_array (msg_array);
3918   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3919     {
3920       msg = vat_json_array_add (msg_array);
3921       vat_json_init_object (msg);
3922       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3923                                        (u8 *) counter_type_to_str (i, 0));
3924       vat_json_object_add_int (msg, "is_combined", 0);
3925       counter_array = vat_json_object_add (msg, "data");
3926       vat_json_init_array (counter_array);
3927       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3928         {
3929           packets = vam->simple_interface_counters[i][j];
3930           vat_json_array_add_uint (counter_array, packets);
3931         }
3932     }
3933   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3934     {
3935       msg = vat_json_array_add (msg_array);
3936       vat_json_init_object (msg);
3937       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3938                                        (u8 *) counter_type_to_str (i, 1));
3939       vat_json_object_add_int (msg, "is_combined", 1);
3940       counter_array = vat_json_object_add (msg, "data");
3941       vat_json_init_array (counter_array);
3942       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3943         {
3944           c = vam->combined_interface_counters[i][j];
3945           counter = vat_json_array_add (counter_array);
3946           vat_json_init_object (counter);
3947           vat_json_object_add_uint (counter, "packets", c.packets);
3948           vat_json_object_add_uint (counter, "bytes", c.bytes);
3949         }
3950     }
3951
3952   /* ip4 fib counters */
3953   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3954   vat_json_init_array (msg_array);
3955   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3956     {
3957       msg = vat_json_array_add (msg_array);
3958       vat_json_init_object (msg);
3959       vat_json_object_add_uint (msg, "vrf_id",
3960                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3961       counter_array = vat_json_object_add (msg, "c");
3962       vat_json_init_array (counter_array);
3963       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3964         {
3965           counter = vat_json_array_add (counter_array);
3966           vat_json_init_object (counter);
3967           c4 = &vam->ip4_fib_counters[i][j];
3968           vat_json_object_add_ip4 (counter, "address", c4->address);
3969           vat_json_object_add_uint (counter, "address_length",
3970                                     c4->address_length);
3971           vat_json_object_add_uint (counter, "packets", c4->packets);
3972           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3973         }
3974     }
3975
3976   /* ip6 fib counters */
3977   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3978   vat_json_init_array (msg_array);
3979   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3980     {
3981       msg = vat_json_array_add (msg_array);
3982       vat_json_init_object (msg);
3983       vat_json_object_add_uint (msg, "vrf_id",
3984                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3985       counter_array = vat_json_object_add (msg, "c");
3986       vat_json_init_array (counter_array);
3987       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3988         {
3989           counter = vat_json_array_add (counter_array);
3990           vat_json_init_object (counter);
3991           c6 = &vam->ip6_fib_counters[i][j];
3992           vat_json_object_add_ip6 (counter, "address", c6->address);
3993           vat_json_object_add_uint (counter, "address_length",
3994                                     c6->address_length);
3995           vat_json_object_add_uint (counter, "packets", c6->packets);
3996           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3997         }
3998     }
3999
4000   vat_json_print (vam->ofp, &node);
4001   vat_json_free (&node);
4002
4003   return 0;
4004 }
4005
4006 int
4007 exec (vat_main_t * vam)
4008 {
4009   api_main_t *am = &api_main;
4010   vl_api_cli_request_t *mp;
4011   f64 timeout;
4012   void *oldheap;
4013   u8 *cmd = 0;
4014   unformat_input_t *i = vam->input;
4015
4016   if (vec_len (i->buffer) == 0)
4017     return -1;
4018
4019   if (vam->exec_mode == 0 && unformat (i, "mode"))
4020     {
4021       vam->exec_mode = 1;
4022       return 0;
4023     }
4024   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4025     {
4026       vam->exec_mode = 0;
4027       return 0;
4028     }
4029
4030
4031   M (CLI_REQUEST, cli_request);
4032
4033   /*
4034    * Copy cmd into shared memory.
4035    * In order for the CLI command to work, it
4036    * must be a vector ending in \n, not a C-string ending
4037    * in \n\0.
4038    */
4039   pthread_mutex_lock (&am->vlib_rp->mutex);
4040   oldheap = svm_push_data_heap (am->vlib_rp);
4041
4042   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4043   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4044
4045   svm_pop_heap (oldheap);
4046   pthread_mutex_unlock (&am->vlib_rp->mutex);
4047
4048   mp->cmd_in_shmem = (u64) cmd;
4049   S;
4050   timeout = vat_time_now (vam) + 10.0;
4051
4052   while (vat_time_now (vam) < timeout)
4053     {
4054       if (vam->result_ready == 1)
4055         {
4056           u8 *free_me;
4057           if (vam->shmem_result != NULL)
4058             fformat (vam->ofp, "%s", vam->shmem_result);
4059           pthread_mutex_lock (&am->vlib_rp->mutex);
4060           oldheap = svm_push_data_heap (am->vlib_rp);
4061
4062           free_me = (u8 *) vam->shmem_result;
4063           vec_free (free_me);
4064
4065           svm_pop_heap (oldheap);
4066           pthread_mutex_unlock (&am->vlib_rp->mutex);
4067           return 0;
4068         }
4069     }
4070   return -99;
4071 }
4072
4073 static int
4074 api_create_loopback (vat_main_t * vam)
4075 {
4076   unformat_input_t *i = vam->input;
4077   vl_api_create_loopback_t *mp;
4078   f64 timeout;
4079   u8 mac_address[6];
4080   u8 mac_set = 0;
4081
4082   memset (mac_address, 0, sizeof (mac_address));
4083
4084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4085     {
4086       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4087         mac_set = 1;
4088       else
4089         break;
4090     }
4091
4092   /* Construct the API message */
4093   M (CREATE_LOOPBACK, create_loopback);
4094   if (mac_set)
4095     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4096
4097   S;
4098   W;
4099 }
4100
4101 static int
4102 api_delete_loopback (vat_main_t * vam)
4103 {
4104   unformat_input_t *i = vam->input;
4105   vl_api_delete_loopback_t *mp;
4106   f64 timeout;
4107   u32 sw_if_index = ~0;
4108
4109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4110     {
4111       if (unformat (i, "sw_if_index %d", &sw_if_index))
4112         ;
4113       else
4114         break;
4115     }
4116
4117   if (sw_if_index == ~0)
4118     {
4119       errmsg ("missing sw_if_index\n");
4120       return -99;
4121     }
4122
4123   /* Construct the API message */
4124   M (DELETE_LOOPBACK, delete_loopback);
4125   mp->sw_if_index = ntohl (sw_if_index);
4126
4127   S;
4128   W;
4129 }
4130
4131 static int
4132 api_want_stats (vat_main_t * vam)
4133 {
4134   unformat_input_t *i = vam->input;
4135   vl_api_want_stats_t *mp;
4136   f64 timeout;
4137   int enable = -1;
4138
4139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4140     {
4141       if (unformat (i, "enable"))
4142         enable = 1;
4143       else if (unformat (i, "disable"))
4144         enable = 0;
4145       else
4146         break;
4147     }
4148
4149   if (enable == -1)
4150     {
4151       errmsg ("missing enable|disable\n");
4152       return -99;
4153     }
4154
4155   M (WANT_STATS, want_stats);
4156   mp->enable_disable = enable;
4157
4158   S;
4159   W;
4160 }
4161
4162 static int
4163 api_want_interface_events (vat_main_t * vam)
4164 {
4165   unformat_input_t *i = vam->input;
4166   vl_api_want_interface_events_t *mp;
4167   f64 timeout;
4168   int enable = -1;
4169
4170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4171     {
4172       if (unformat (i, "enable"))
4173         enable = 1;
4174       else if (unformat (i, "disable"))
4175         enable = 0;
4176       else
4177         break;
4178     }
4179
4180   if (enable == -1)
4181     {
4182       errmsg ("missing enable|disable\n");
4183       return -99;
4184     }
4185
4186   M (WANT_INTERFACE_EVENTS, want_interface_events);
4187   mp->enable_disable = enable;
4188
4189   vam->interface_event_display = enable;
4190
4191   S;
4192   W;
4193 }
4194
4195
4196 /* Note: non-static, called once to set up the initial intfc table */
4197 int
4198 api_sw_interface_dump (vat_main_t * vam)
4199 {
4200   vl_api_sw_interface_dump_t *mp;
4201   f64 timeout;
4202   hash_pair_t *p;
4203   name_sort_t *nses = 0, *ns;
4204   sw_interface_subif_t *sub = NULL;
4205
4206   /* Toss the old name table */
4207   /* *INDENT-OFF* */
4208   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4209   ({
4210     vec_add2 (nses, ns, 1);
4211     ns->name = (u8 *)(p->key);
4212     ns->value = (u32) p->value[0];
4213   }));
4214   /* *INDENT-ON* */
4215
4216   hash_free (vam->sw_if_index_by_interface_name);
4217
4218   vec_foreach (ns, nses) vec_free (ns->name);
4219
4220   vec_free (nses);
4221
4222   vec_foreach (sub, vam->sw_if_subif_table)
4223   {
4224     vec_free (sub->interface_name);
4225   }
4226   vec_free (vam->sw_if_subif_table);
4227
4228   /* recreate the interface name hash table */
4229   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4230
4231   /* Get list of ethernets */
4232   M (SW_INTERFACE_DUMP, sw_interface_dump);
4233   mp->name_filter_valid = 1;
4234   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4235   S;
4236
4237   /* and local / loopback interfaces */
4238   M (SW_INTERFACE_DUMP, sw_interface_dump);
4239   mp->name_filter_valid = 1;
4240   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4241   S;
4242
4243
4244   /* and vxlan-gpe tunnel interfaces */
4245   M (SW_INTERFACE_DUMP, sw_interface_dump);
4246   mp->name_filter_valid = 1;
4247   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4248            sizeof (mp->name_filter) - 1);
4249   S;
4250
4251   /* and vxlan tunnel interfaces */
4252   M (SW_INTERFACE_DUMP, sw_interface_dump);
4253   mp->name_filter_valid = 1;
4254   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4255   S;
4256
4257   /* and host (af_packet) interfaces */
4258   M (SW_INTERFACE_DUMP, sw_interface_dump);
4259   mp->name_filter_valid = 1;
4260   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4261   S;
4262
4263   /* and l2tpv3 tunnel interfaces */
4264   M (SW_INTERFACE_DUMP, sw_interface_dump);
4265   mp->name_filter_valid = 1;
4266   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4267            sizeof (mp->name_filter) - 1);
4268   S;
4269
4270   /* and GRE tunnel interfaces */
4271   M (SW_INTERFACE_DUMP, sw_interface_dump);
4272   mp->name_filter_valid = 1;
4273   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4274   S;
4275
4276   /* Use a control ping for synchronization */
4277   {
4278     vl_api_control_ping_t *mp;
4279     M (CONTROL_PING, control_ping);
4280     S;
4281   }
4282   W;
4283 }
4284
4285 static int
4286 api_sw_interface_set_flags (vat_main_t * vam)
4287 {
4288   unformat_input_t *i = vam->input;
4289   vl_api_sw_interface_set_flags_t *mp;
4290   f64 timeout;
4291   u32 sw_if_index;
4292   u8 sw_if_index_set = 0;
4293   u8 admin_up = 0, link_up = 0;
4294
4295   /* Parse args required to build the message */
4296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4297     {
4298       if (unformat (i, "admin-up"))
4299         admin_up = 1;
4300       else if (unformat (i, "admin-down"))
4301         admin_up = 0;
4302       else if (unformat (i, "link-up"))
4303         link_up = 1;
4304       else if (unformat (i, "link-down"))
4305         link_up = 0;
4306       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4307         sw_if_index_set = 1;
4308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4309         sw_if_index_set = 1;
4310       else
4311         break;
4312     }
4313
4314   if (sw_if_index_set == 0)
4315     {
4316       errmsg ("missing interface name or sw_if_index\n");
4317       return -99;
4318     }
4319
4320   /* Construct the API message */
4321   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4322   mp->sw_if_index = ntohl (sw_if_index);
4323   mp->admin_up_down = admin_up;
4324   mp->link_up_down = link_up;
4325
4326   /* send it... */
4327   S;
4328
4329   /* Wait for a reply, return the good/bad news... */
4330   W;
4331 }
4332
4333 static int
4334 api_sw_interface_clear_stats (vat_main_t * vam)
4335 {
4336   unformat_input_t *i = vam->input;
4337   vl_api_sw_interface_clear_stats_t *mp;
4338   f64 timeout;
4339   u32 sw_if_index;
4340   u8 sw_if_index_set = 0;
4341
4342   /* Parse args required to build the message */
4343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4344     {
4345       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4346         sw_if_index_set = 1;
4347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4348         sw_if_index_set = 1;
4349       else
4350         break;
4351     }
4352
4353   /* Construct the API message */
4354   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4355
4356   if (sw_if_index_set == 1)
4357     mp->sw_if_index = ntohl (sw_if_index);
4358   else
4359     mp->sw_if_index = ~0;
4360
4361   /* send it... */
4362   S;
4363
4364   /* Wait for a reply, return the good/bad news... */
4365   W;
4366 }
4367
4368 static int
4369 api_sw_interface_add_del_address (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_sw_interface_add_del_address_t *mp;
4373   f64 timeout;
4374   u32 sw_if_index;
4375   u8 sw_if_index_set = 0;
4376   u8 is_add = 1, del_all = 0;
4377   u32 address_length = 0;
4378   u8 v4_address_set = 0;
4379   u8 v6_address_set = 0;
4380   ip4_address_t v4address;
4381   ip6_address_t v6address;
4382
4383   /* Parse args required to build the message */
4384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4385     {
4386       if (unformat (i, "del-all"))
4387         del_all = 1;
4388       else if (unformat (i, "del"))
4389         is_add = 0;
4390       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4391         sw_if_index_set = 1;
4392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4393         sw_if_index_set = 1;
4394       else if (unformat (i, "%U/%d",
4395                          unformat_ip4_address, &v4address, &address_length))
4396         v4_address_set = 1;
4397       else if (unformat (i, "%U/%d",
4398                          unformat_ip6_address, &v6address, &address_length))
4399         v6_address_set = 1;
4400       else
4401         break;
4402     }
4403
4404   if (sw_if_index_set == 0)
4405     {
4406       errmsg ("missing interface name or sw_if_index\n");
4407       return -99;
4408     }
4409   if (v4_address_set && v6_address_set)
4410     {
4411       errmsg ("both v4 and v6 addresses set\n");
4412       return -99;
4413     }
4414   if (!v4_address_set && !v6_address_set && !del_all)
4415     {
4416       errmsg ("no addresses set\n");
4417       return -99;
4418     }
4419
4420   /* Construct the API message */
4421   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4422
4423   mp->sw_if_index = ntohl (sw_if_index);
4424   mp->is_add = is_add;
4425   mp->del_all = del_all;
4426   if (v6_address_set)
4427     {
4428       mp->is_ipv6 = 1;
4429       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4430     }
4431   else
4432     {
4433       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4434     }
4435   mp->address_length = address_length;
4436
4437   /* send it... */
4438   S;
4439
4440   /* Wait for a reply, return good/bad news  */
4441   W;
4442 }
4443
4444 static int
4445 api_sw_interface_set_table (vat_main_t * vam)
4446 {
4447   unformat_input_t *i = vam->input;
4448   vl_api_sw_interface_set_table_t *mp;
4449   f64 timeout;
4450   u32 sw_if_index, vrf_id = 0;
4451   u8 sw_if_index_set = 0;
4452   u8 is_ipv6 = 0;
4453
4454   /* Parse args required to build the message */
4455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4456     {
4457       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4458         sw_if_index_set = 1;
4459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4460         sw_if_index_set = 1;
4461       else if (unformat (i, "vrf %d", &vrf_id))
4462         ;
4463       else if (unformat (i, "ipv6"))
4464         is_ipv6 = 1;
4465       else
4466         break;
4467     }
4468
4469   if (sw_if_index_set == 0)
4470     {
4471       errmsg ("missing interface name or sw_if_index\n");
4472       return -99;
4473     }
4474
4475   /* Construct the API message */
4476   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4477
4478   mp->sw_if_index = ntohl (sw_if_index);
4479   mp->is_ipv6 = is_ipv6;
4480   mp->vrf_id = ntohl (vrf_id);
4481
4482   /* send it... */
4483   S;
4484
4485   /* Wait for a reply... */
4486   W;
4487 }
4488
4489 static int
4490 api_sw_interface_set_vpath (vat_main_t * vam)
4491 {
4492   unformat_input_t *i = vam->input;
4493   vl_api_sw_interface_set_vpath_t *mp;
4494   f64 timeout;
4495   u32 sw_if_index = 0;
4496   u8 sw_if_index_set = 0;
4497   u8 is_enable = 0;
4498
4499   /* Parse args required to build the message */
4500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4501     {
4502       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4503         sw_if_index_set = 1;
4504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4505         sw_if_index_set = 1;
4506       else if (unformat (i, "enable"))
4507         is_enable = 1;
4508       else if (unformat (i, "disable"))
4509         is_enable = 0;
4510       else
4511         break;
4512     }
4513
4514   if (sw_if_index_set == 0)
4515     {
4516       errmsg ("missing interface name or sw_if_index\n");
4517       return -99;
4518     }
4519
4520   /* Construct the API message */
4521   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4522
4523   mp->sw_if_index = ntohl (sw_if_index);
4524   mp->enable = is_enable;
4525
4526   /* send it... */
4527   S;
4528
4529   /* Wait for a reply... */
4530   W;
4531 }
4532
4533 static int
4534 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4535 {
4536   unformat_input_t *i = vam->input;
4537   vl_api_sw_interface_set_l2_xconnect_t *mp;
4538   f64 timeout;
4539   u32 rx_sw_if_index;
4540   u8 rx_sw_if_index_set = 0;
4541   u32 tx_sw_if_index;
4542   u8 tx_sw_if_index_set = 0;
4543   u8 enable = 1;
4544
4545   /* Parse args required to build the message */
4546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547     {
4548       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4549         rx_sw_if_index_set = 1;
4550       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4551         tx_sw_if_index_set = 1;
4552       else if (unformat (i, "rx"))
4553         {
4554           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4555             {
4556               if (unformat (i, "%U", unformat_sw_if_index, vam,
4557                             &rx_sw_if_index))
4558                 rx_sw_if_index_set = 1;
4559             }
4560           else
4561             break;
4562         }
4563       else if (unformat (i, "tx"))
4564         {
4565           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4566             {
4567               if (unformat (i, "%U", unformat_sw_if_index, vam,
4568                             &tx_sw_if_index))
4569                 tx_sw_if_index_set = 1;
4570             }
4571           else
4572             break;
4573         }
4574       else if (unformat (i, "enable"))
4575         enable = 1;
4576       else if (unformat (i, "disable"))
4577         enable = 0;
4578       else
4579         break;
4580     }
4581
4582   if (rx_sw_if_index_set == 0)
4583     {
4584       errmsg ("missing rx interface name or rx_sw_if_index\n");
4585       return -99;
4586     }
4587
4588   if (enable && (tx_sw_if_index_set == 0))
4589     {
4590       errmsg ("missing tx interface name or tx_sw_if_index\n");
4591       return -99;
4592     }
4593
4594   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4595
4596   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4597   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4598   mp->enable = enable;
4599
4600   S;
4601   W;
4602   /* NOTREACHED */
4603   return 0;
4604 }
4605
4606 static int
4607 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4608 {
4609   unformat_input_t *i = vam->input;
4610   vl_api_sw_interface_set_l2_bridge_t *mp;
4611   f64 timeout;
4612   u32 rx_sw_if_index;
4613   u8 rx_sw_if_index_set = 0;
4614   u32 bd_id;
4615   u8 bd_id_set = 0;
4616   u8 bvi = 0;
4617   u32 shg = 0;
4618   u8 enable = 1;
4619
4620   /* Parse args required to build the message */
4621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4622     {
4623       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4624         rx_sw_if_index_set = 1;
4625       else if (unformat (i, "bd_id %d", &bd_id))
4626         bd_id_set = 1;
4627       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4628         rx_sw_if_index_set = 1;
4629       else if (unformat (i, "shg %d", &shg))
4630         ;
4631       else if (unformat (i, "bvi"))
4632         bvi = 1;
4633       else if (unformat (i, "enable"))
4634         enable = 1;
4635       else if (unformat (i, "disable"))
4636         enable = 0;
4637       else
4638         break;
4639     }
4640
4641   if (rx_sw_if_index_set == 0)
4642     {
4643       errmsg ("missing rx interface name or sw_if_index\n");
4644       return -99;
4645     }
4646
4647   if (enable && (bd_id_set == 0))
4648     {
4649       errmsg ("missing bridge domain\n");
4650       return -99;
4651     }
4652
4653   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4654
4655   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4656   mp->bd_id = ntohl (bd_id);
4657   mp->shg = (u8) shg;
4658   mp->bvi = bvi;
4659   mp->enable = enable;
4660
4661   S;
4662   W;
4663   /* NOTREACHED */
4664   return 0;
4665 }
4666
4667 static int
4668 api_bridge_domain_dump (vat_main_t * vam)
4669 {
4670   unformat_input_t *i = vam->input;
4671   vl_api_bridge_domain_dump_t *mp;
4672   f64 timeout;
4673   u32 bd_id = ~0;
4674
4675   /* Parse args required to build the message */
4676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4677     {
4678       if (unformat (i, "bd_id %d", &bd_id))
4679         ;
4680       else
4681         break;
4682     }
4683
4684   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4685   mp->bd_id = ntohl (bd_id);
4686   S;
4687
4688   /* Use a control ping for synchronization */
4689   {
4690     vl_api_control_ping_t *mp;
4691     M (CONTROL_PING, control_ping);
4692     S;
4693   }
4694
4695   W;
4696   /* NOTREACHED */
4697   return 0;
4698 }
4699
4700 static int
4701 api_bridge_domain_add_del (vat_main_t * vam)
4702 {
4703   unformat_input_t *i = vam->input;
4704   vl_api_bridge_domain_add_del_t *mp;
4705   f64 timeout;
4706   u32 bd_id = ~0;
4707   u8 is_add = 1;
4708   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4709
4710   /* Parse args required to build the message */
4711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4712     {
4713       if (unformat (i, "bd_id %d", &bd_id))
4714         ;
4715       else if (unformat (i, "flood %d", &flood))
4716         ;
4717       else if (unformat (i, "uu-flood %d", &uu_flood))
4718         ;
4719       else if (unformat (i, "forward %d", &forward))
4720         ;
4721       else if (unformat (i, "learn %d", &learn))
4722         ;
4723       else if (unformat (i, "arp-term %d", &arp_term))
4724         ;
4725       else if (unformat (i, "del"))
4726         {
4727           is_add = 0;
4728           flood = uu_flood = forward = learn = 0;
4729         }
4730       else
4731         break;
4732     }
4733
4734   if (bd_id == ~0)
4735     {
4736       errmsg ("missing bridge domain\n");
4737       return -99;
4738     }
4739
4740   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4741
4742   mp->bd_id = ntohl (bd_id);
4743   mp->flood = flood;
4744   mp->uu_flood = uu_flood;
4745   mp->forward = forward;
4746   mp->learn = learn;
4747   mp->arp_term = arp_term;
4748   mp->is_add = is_add;
4749
4750   S;
4751   W;
4752   /* NOTREACHED */
4753   return 0;
4754 }
4755
4756 static int
4757 api_l2fib_add_del (vat_main_t * vam)
4758 {
4759   unformat_input_t *i = vam->input;
4760   vl_api_l2fib_add_del_t *mp;
4761   f64 timeout;
4762   u64 mac = 0;
4763   u8 mac_set = 0;
4764   u32 bd_id;
4765   u8 bd_id_set = 0;
4766   u32 sw_if_index;
4767   u8 sw_if_index_set = 0;
4768   u8 is_add = 1;
4769   u8 static_mac = 0;
4770   u8 filter_mac = 0;
4771   u8 bvi_mac = 0;
4772   int count = 1;
4773   f64 before = 0;
4774   int j;
4775
4776   /* Parse args required to build the message */
4777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4778     {
4779       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4780         mac_set = 1;
4781       else if (unformat (i, "bd_id %d", &bd_id))
4782         bd_id_set = 1;
4783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4784         sw_if_index_set = 1;
4785       else if (unformat (i, "sw_if"))
4786         {
4787           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4788             {
4789               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4790                 sw_if_index_set = 1;
4791             }
4792           else
4793             break;
4794         }
4795       else if (unformat (i, "static"))
4796         static_mac = 1;
4797       else if (unformat (i, "filter"))
4798         {
4799           filter_mac = 1;
4800           static_mac = 1;
4801         }
4802       else if (unformat (i, "bvi"))
4803         {
4804           bvi_mac = 1;
4805           static_mac = 1;
4806         }
4807       else if (unformat (i, "del"))
4808         is_add = 0;
4809       else if (unformat (i, "count %d", &count))
4810         ;
4811       else
4812         break;
4813     }
4814
4815   if (mac_set == 0)
4816     {
4817       errmsg ("missing mac address\n");
4818       return -99;
4819     }
4820
4821   if (bd_id_set == 0)
4822     {
4823       errmsg ("missing bridge domain\n");
4824       return -99;
4825     }
4826
4827   if (is_add && (sw_if_index_set == 0))
4828     {
4829       errmsg ("missing interface name or sw_if_index\n");
4830       return -99;
4831     }
4832
4833   if (count > 1)
4834     {
4835       /* Turn on async mode */
4836       vam->async_mode = 1;
4837       vam->async_errors = 0;
4838       before = vat_time_now (vam);
4839     }
4840
4841   for (j = 0; j < count; j++)
4842     {
4843       M (L2FIB_ADD_DEL, l2fib_add_del);
4844
4845       mp->mac = mac;
4846       mp->bd_id = ntohl (bd_id);
4847       mp->is_add = is_add;
4848
4849       if (is_add)
4850         {
4851           mp->sw_if_index = ntohl (sw_if_index);
4852           mp->static_mac = static_mac;
4853           mp->filter_mac = filter_mac;
4854           mp->bvi_mac = bvi_mac;
4855         }
4856       increment_mac_address (&mac);
4857       /* send it... */
4858       S;
4859     }
4860
4861   if (count > 1)
4862     {
4863       vl_api_control_ping_t *mp;
4864       f64 after;
4865
4866       /* Shut off async mode */
4867       vam->async_mode = 0;
4868
4869       M (CONTROL_PING, control_ping);
4870       S;
4871
4872       timeout = vat_time_now (vam) + 1.0;
4873       while (vat_time_now (vam) < timeout)
4874         if (vam->result_ready == 1)
4875           goto out;
4876       vam->retval = -99;
4877
4878     out:
4879       if (vam->retval == -99)
4880         errmsg ("timeout\n");
4881
4882       if (vam->async_errors > 0)
4883         {
4884           errmsg ("%d asynchronous errors\n", vam->async_errors);
4885           vam->retval = -98;
4886         }
4887       vam->async_errors = 0;
4888       after = vat_time_now (vam);
4889
4890       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4891                count, after - before, count / (after - before));
4892     }
4893   else
4894     {
4895       /* Wait for a reply... */
4896       W;
4897     }
4898   /* Return the good/bad news */
4899   return (vam->retval);
4900 }
4901
4902 static int
4903 api_l2_flags (vat_main_t * vam)
4904 {
4905   unformat_input_t *i = vam->input;
4906   vl_api_l2_flags_t *mp;
4907   f64 timeout;
4908   u32 sw_if_index;
4909   u32 feature_bitmap = 0;
4910   u8 sw_if_index_set = 0;
4911
4912   /* Parse args required to build the message */
4913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4914     {
4915       if (unformat (i, "sw_if_index %d", &sw_if_index))
4916         sw_if_index_set = 1;
4917       else if (unformat (i, "sw_if"))
4918         {
4919           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4920             {
4921               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4922                 sw_if_index_set = 1;
4923             }
4924           else
4925             break;
4926         }
4927       else if (unformat (i, "learn"))
4928         feature_bitmap |= L2INPUT_FEAT_LEARN;
4929       else if (unformat (i, "forward"))
4930         feature_bitmap |= L2INPUT_FEAT_FWD;
4931       else if (unformat (i, "flood"))
4932         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4933       else if (unformat (i, "uu-flood"))
4934         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4935       else
4936         break;
4937     }
4938
4939   if (sw_if_index_set == 0)
4940     {
4941       errmsg ("missing interface name or sw_if_index\n");
4942       return -99;
4943     }
4944
4945   M (L2_FLAGS, l2_flags);
4946
4947   mp->sw_if_index = ntohl (sw_if_index);
4948   mp->feature_bitmap = ntohl (feature_bitmap);
4949
4950   S;
4951   W;
4952   /* NOTREACHED */
4953   return 0;
4954 }
4955
4956 static int
4957 api_bridge_flags (vat_main_t * vam)
4958 {
4959   unformat_input_t *i = vam->input;
4960   vl_api_bridge_flags_t *mp;
4961   f64 timeout;
4962   u32 bd_id;
4963   u8 bd_id_set = 0;
4964   u8 is_set = 1;
4965   u32 flags = 0;
4966
4967   /* Parse args required to build the message */
4968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4969     {
4970       if (unformat (i, "bd_id %d", &bd_id))
4971         bd_id_set = 1;
4972       else if (unformat (i, "learn"))
4973         flags |= L2_LEARN;
4974       else if (unformat (i, "forward"))
4975         flags |= L2_FWD;
4976       else if (unformat (i, "flood"))
4977         flags |= L2_FLOOD;
4978       else if (unformat (i, "uu-flood"))
4979         flags |= L2_UU_FLOOD;
4980       else if (unformat (i, "arp-term"))
4981         flags |= L2_ARP_TERM;
4982       else if (unformat (i, "off"))
4983         is_set = 0;
4984       else if (unformat (i, "disable"))
4985         is_set = 0;
4986       else
4987         break;
4988     }
4989
4990   if (bd_id_set == 0)
4991     {
4992       errmsg ("missing bridge domain\n");
4993       return -99;
4994     }
4995
4996   M (BRIDGE_FLAGS, bridge_flags);
4997
4998   mp->bd_id = ntohl (bd_id);
4999   mp->feature_bitmap = ntohl (flags);
5000   mp->is_set = is_set;
5001
5002   S;
5003   W;
5004   /* NOTREACHED */
5005   return 0;
5006 }
5007
5008 static int
5009 api_bd_ip_mac_add_del (vat_main_t * vam)
5010 {
5011   unformat_input_t *i = vam->input;
5012   vl_api_bd_ip_mac_add_del_t *mp;
5013   f64 timeout;
5014   u32 bd_id;
5015   u8 is_ipv6 = 0;
5016   u8 is_add = 1;
5017   u8 bd_id_set = 0;
5018   u8 ip_set = 0;
5019   u8 mac_set = 0;
5020   ip4_address_t v4addr;
5021   ip6_address_t v6addr;
5022   u8 macaddr[6];
5023
5024
5025   /* Parse args required to build the message */
5026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5027     {
5028       if (unformat (i, "bd_id %d", &bd_id))
5029         {
5030           bd_id_set++;
5031         }
5032       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5033         {
5034           ip_set++;
5035         }
5036       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5037         {
5038           ip_set++;
5039           is_ipv6++;
5040         }
5041       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5042         {
5043           mac_set++;
5044         }
5045       else if (unformat (i, "del"))
5046         is_add = 0;
5047       else
5048         break;
5049     }
5050
5051   if (bd_id_set == 0)
5052     {
5053       errmsg ("missing bridge domain\n");
5054       return -99;
5055     }
5056   else if (ip_set == 0)
5057     {
5058       errmsg ("missing IP address\n");
5059       return -99;
5060     }
5061   else if (mac_set == 0)
5062     {
5063       errmsg ("missing MAC address\n");
5064       return -99;
5065     }
5066
5067   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5068
5069   mp->bd_id = ntohl (bd_id);
5070   mp->is_ipv6 = is_ipv6;
5071   mp->is_add = is_add;
5072   if (is_ipv6)
5073     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5074   else
5075     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5076   clib_memcpy (mp->mac_address, macaddr, 6);
5077   S;
5078   W;
5079   /* NOTREACHED */
5080   return 0;
5081 }
5082
5083 static int
5084 api_tap_connect (vat_main_t * vam)
5085 {
5086   unformat_input_t *i = vam->input;
5087   vl_api_tap_connect_t *mp;
5088   f64 timeout;
5089   u8 mac_address[6];
5090   u8 random_mac = 1;
5091   u8 name_set = 0;
5092   u8 *tap_name;
5093
5094   memset (mac_address, 0, sizeof (mac_address));
5095
5096   /* Parse args required to build the message */
5097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5098     {
5099       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5100         {
5101           random_mac = 0;
5102         }
5103       else if (unformat (i, "random-mac"))
5104         random_mac = 1;
5105       else if (unformat (i, "tapname %s", &tap_name))
5106         name_set = 1;
5107       else
5108         break;
5109     }
5110
5111   if (name_set == 0)
5112     {
5113       errmsg ("missing tap name\n");
5114       return -99;
5115     }
5116   if (vec_len (tap_name) > 63)
5117     {
5118       errmsg ("tap name too long\n");
5119     }
5120   vec_add1 (tap_name, 0);
5121
5122   /* Construct the API message */
5123   M (TAP_CONNECT, tap_connect);
5124
5125   mp->use_random_mac = random_mac;
5126   clib_memcpy (mp->mac_address, mac_address, 6);
5127   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5128   vec_free (tap_name);
5129
5130   /* send it... */
5131   S;
5132
5133   /* Wait for a reply... */
5134   W;
5135 }
5136
5137 static int
5138 api_tap_modify (vat_main_t * vam)
5139 {
5140   unformat_input_t *i = vam->input;
5141   vl_api_tap_modify_t *mp;
5142   f64 timeout;
5143   u8 mac_address[6];
5144   u8 random_mac = 1;
5145   u8 name_set = 0;
5146   u8 *tap_name;
5147   u32 sw_if_index = ~0;
5148   u8 sw_if_index_set = 0;
5149
5150   memset (mac_address, 0, sizeof (mac_address));
5151
5152   /* Parse args required to build the message */
5153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5154     {
5155       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5156         sw_if_index_set = 1;
5157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5158         sw_if_index_set = 1;
5159       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5160         {
5161           random_mac = 0;
5162         }
5163       else if (unformat (i, "random-mac"))
5164         random_mac = 1;
5165       else if (unformat (i, "tapname %s", &tap_name))
5166         name_set = 1;
5167       else
5168         break;
5169     }
5170
5171   if (sw_if_index_set == 0)
5172     {
5173       errmsg ("missing vpp interface name");
5174       return -99;
5175     }
5176   if (name_set == 0)
5177     {
5178       errmsg ("missing tap name\n");
5179       return -99;
5180     }
5181   if (vec_len (tap_name) > 63)
5182     {
5183       errmsg ("tap name too long\n");
5184     }
5185   vec_add1 (tap_name, 0);
5186
5187   /* Construct the API message */
5188   M (TAP_MODIFY, tap_modify);
5189
5190   mp->use_random_mac = random_mac;
5191   mp->sw_if_index = ntohl (sw_if_index);
5192   clib_memcpy (mp->mac_address, mac_address, 6);
5193   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5194   vec_free (tap_name);
5195
5196   /* send it... */
5197   S;
5198
5199   /* Wait for a reply... */
5200   W;
5201 }
5202
5203 static int
5204 api_tap_delete (vat_main_t * vam)
5205 {
5206   unformat_input_t *i = vam->input;
5207   vl_api_tap_delete_t *mp;
5208   f64 timeout;
5209   u32 sw_if_index = ~0;
5210   u8 sw_if_index_set = 0;
5211
5212   /* Parse args required to build the message */
5213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5214     {
5215       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5216         sw_if_index_set = 1;
5217       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5218         sw_if_index_set = 1;
5219       else
5220         break;
5221     }
5222
5223   if (sw_if_index_set == 0)
5224     {
5225       errmsg ("missing vpp interface name");
5226       return -99;
5227     }
5228
5229   /* Construct the API message */
5230   M (TAP_DELETE, tap_delete);
5231
5232   mp->sw_if_index = ntohl (sw_if_index);
5233
5234   /* send it... */
5235   S;
5236
5237   /* Wait for a reply... */
5238   W;
5239 }
5240
5241 static int
5242 api_ip_add_del_route (vat_main_t * vam)
5243 {
5244   unformat_input_t *i = vam->input;
5245   vl_api_ip_add_del_route_t *mp;
5246   f64 timeout;
5247   u32 sw_if_index = ~0, vrf_id = 0;
5248   u8 sw_if_index_set = 0;
5249   u8 is_ipv6 = 0;
5250   u8 is_local = 0, is_drop = 0;
5251   u8 create_vrf_if_needed = 0;
5252   u8 is_add = 1;
5253   u8 next_hop_weight = 1;
5254   u8 not_last = 0;
5255   u8 is_multipath = 0;
5256   u8 address_set = 0;
5257   u8 address_length_set = 0;
5258   u32 lookup_in_vrf = 0;
5259   u32 resolve_attempts = 0;
5260   u32 dst_address_length = 0;
5261   u8 next_hop_set = 0;
5262   ip4_address_t v4_dst_address, v4_next_hop_address;
5263   ip6_address_t v6_dst_address, v6_next_hop_address;
5264   int count = 1;
5265   int j;
5266   f64 before = 0;
5267   u32 random_add_del = 0;
5268   u32 *random_vector = 0;
5269   uword *random_hash;
5270   u32 random_seed = 0xdeaddabe;
5271   u32 classify_table_index = ~0;
5272   u8 is_classify = 0;
5273
5274   /* Parse args required to build the message */
5275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5276     {
5277       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5278         sw_if_index_set = 1;
5279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5280         sw_if_index_set = 1;
5281       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5282         {
5283           address_set = 1;
5284           is_ipv6 = 0;
5285         }
5286       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5287         {
5288           address_set = 1;
5289           is_ipv6 = 1;
5290         }
5291       else if (unformat (i, "/%d", &dst_address_length))
5292         {
5293           address_length_set = 1;
5294         }
5295
5296       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5297                                          &v4_next_hop_address))
5298         {
5299           next_hop_set = 1;
5300         }
5301       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5302                                          &v6_next_hop_address))
5303         {
5304           next_hop_set = 1;
5305         }
5306       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5307         ;
5308       else if (unformat (i, "weight %d", &next_hop_weight))
5309         ;
5310       else if (unformat (i, "drop"))
5311         {
5312           is_drop = 1;
5313         }
5314       else if (unformat (i, "local"))
5315         {
5316           is_local = 1;
5317         }
5318       else if (unformat (i, "classify %d", &classify_table_index))
5319         {
5320           is_classify = 1;
5321         }
5322       else if (unformat (i, "del"))
5323         is_add = 0;
5324       else if (unformat (i, "add"))
5325         is_add = 1;
5326       else if (unformat (i, "not-last"))
5327         not_last = 1;
5328       else if (unformat (i, "multipath"))
5329         is_multipath = 1;
5330       else if (unformat (i, "vrf %d", &vrf_id))
5331         ;
5332       else if (unformat (i, "create-vrf"))
5333         create_vrf_if_needed = 1;
5334       else if (unformat (i, "count %d", &count))
5335         ;
5336       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5337         ;
5338       else if (unformat (i, "random"))
5339         random_add_del = 1;
5340       else if (unformat (i, "seed %d", &random_seed))
5341         ;
5342       else
5343         {
5344           clib_warning ("parse error '%U'", format_unformat_error, i);
5345           return -99;
5346         }
5347     }
5348
5349   if (resolve_attempts > 0 && sw_if_index_set == 0)
5350     {
5351       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5352       return -99;
5353     }
5354
5355   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5356     {
5357       errmsg ("next hop / local / drop / classify not set\n");
5358       return -99;
5359     }
5360
5361   if (address_set == 0)
5362     {
5363       errmsg ("missing addresses\n");
5364       return -99;
5365     }
5366
5367   if (address_length_set == 0)
5368     {
5369       errmsg ("missing address length\n");
5370       return -99;
5371     }
5372
5373   /* Generate a pile of unique, random routes */
5374   if (random_add_del)
5375     {
5376       u32 this_random_address;
5377       random_hash = hash_create (count, sizeof (uword));
5378
5379       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5380       for (j = 0; j <= count; j++)
5381         {
5382           do
5383             {
5384               this_random_address = random_u32 (&random_seed);
5385               this_random_address =
5386                 clib_host_to_net_u32 (this_random_address);
5387             }
5388           while (hash_get (random_hash, this_random_address));
5389           vec_add1 (random_vector, this_random_address);
5390           hash_set (random_hash, this_random_address, 1);
5391         }
5392       hash_free (random_hash);
5393       v4_dst_address.as_u32 = random_vector[0];
5394     }
5395
5396   if (count > 1)
5397     {
5398       /* Turn on async mode */
5399       vam->async_mode = 1;
5400       vam->async_errors = 0;
5401       before = vat_time_now (vam);
5402     }
5403
5404   for (j = 0; j < count; j++)
5405     {
5406       /* Construct the API message */
5407       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5408
5409       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5410       mp->vrf_id = ntohl (vrf_id);
5411       if (resolve_attempts > 0)
5412         {
5413           mp->resolve_attempts = ntohl (resolve_attempts);
5414           mp->resolve_if_needed = 1;
5415         }
5416       mp->create_vrf_if_needed = create_vrf_if_needed;
5417
5418       mp->is_add = is_add;
5419       mp->is_drop = is_drop;
5420       mp->is_ipv6 = is_ipv6;
5421       mp->is_local = is_local;
5422       mp->is_classify = is_classify;
5423       mp->is_multipath = is_multipath;
5424       mp->not_last = not_last;
5425       mp->next_hop_weight = next_hop_weight;
5426       mp->dst_address_length = dst_address_length;
5427       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5428       mp->classify_table_index = ntohl (classify_table_index);
5429
5430       if (is_ipv6)
5431         {
5432           clib_memcpy (mp->dst_address, &v6_dst_address,
5433                        sizeof (v6_dst_address));
5434           if (next_hop_set)
5435             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5436                          sizeof (v6_next_hop_address));
5437           increment_v6_address (&v6_dst_address);
5438         }
5439       else
5440         {
5441           clib_memcpy (mp->dst_address, &v4_dst_address,
5442                        sizeof (v4_dst_address));
5443           if (next_hop_set)
5444             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5445                          sizeof (v4_next_hop_address));
5446           if (random_add_del)
5447             v4_dst_address.as_u32 = random_vector[j + 1];
5448           else
5449             increment_v4_address (&v4_dst_address);
5450         }
5451       /* send it... */
5452       S;
5453     }
5454
5455   /* When testing multiple add/del ops, use a control-ping to sync */
5456   if (count > 1)
5457     {
5458       vl_api_control_ping_t *mp;
5459       f64 after;
5460
5461       /* Shut off async mode */
5462       vam->async_mode = 0;
5463
5464       M (CONTROL_PING, control_ping);
5465       S;
5466
5467       timeout = vat_time_now (vam) + 1.0;
5468       while (vat_time_now (vam) < timeout)
5469         if (vam->result_ready == 1)
5470           goto out;
5471       vam->retval = -99;
5472
5473     out:
5474       if (vam->retval == -99)
5475         errmsg ("timeout\n");
5476
5477       if (vam->async_errors > 0)
5478         {
5479           errmsg ("%d asynchronous errors\n", vam->async_errors);
5480           vam->retval = -98;
5481         }
5482       vam->async_errors = 0;
5483       after = vat_time_now (vam);
5484
5485       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5486                count, after - before, count / (after - before));
5487     }
5488   else
5489     {
5490       /* Wait for a reply... */
5491       W;
5492     }
5493
5494   /* Return the good/bad news */
5495   return (vam->retval);
5496 }
5497
5498 static int
5499 api_proxy_arp_add_del (vat_main_t * vam)
5500 {
5501   unformat_input_t *i = vam->input;
5502   vl_api_proxy_arp_add_del_t *mp;
5503   f64 timeout;
5504   u32 vrf_id = 0;
5505   u8 is_add = 1;
5506   ip4_address_t lo, hi;
5507   u8 range_set = 0;
5508
5509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5510     {
5511       if (unformat (i, "vrf %d", &vrf_id))
5512         ;
5513       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5514                          unformat_ip4_address, &hi))
5515         range_set = 1;
5516       else if (unformat (i, "del"))
5517         is_add = 0;
5518       else
5519         {
5520           clib_warning ("parse error '%U'", format_unformat_error, i);
5521           return -99;
5522         }
5523     }
5524
5525   if (range_set == 0)
5526     {
5527       errmsg ("address range not set\n");
5528       return -99;
5529     }
5530
5531   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5532
5533   mp->vrf_id = ntohl (vrf_id);
5534   mp->is_add = is_add;
5535   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5536   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5537
5538   S;
5539   W;
5540   /* NOTREACHED */
5541   return 0;
5542 }
5543
5544 static int
5545 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5546 {
5547   unformat_input_t *i = vam->input;
5548   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5549   f64 timeout;
5550   u32 sw_if_index;
5551   u8 enable = 1;
5552   u8 sw_if_index_set = 0;
5553
5554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5555     {
5556       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5557         sw_if_index_set = 1;
5558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5559         sw_if_index_set = 1;
5560       else if (unformat (i, "enable"))
5561         enable = 1;
5562       else if (unformat (i, "disable"))
5563         enable = 0;
5564       else
5565         {
5566           clib_warning ("parse error '%U'", format_unformat_error, i);
5567           return -99;
5568         }
5569     }
5570
5571   if (sw_if_index_set == 0)
5572     {
5573       errmsg ("missing interface name or sw_if_index\n");
5574       return -99;
5575     }
5576
5577   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5578
5579   mp->sw_if_index = ntohl (sw_if_index);
5580   mp->enable_disable = enable;
5581
5582   S;
5583   W;
5584   /* NOTREACHED */
5585   return 0;
5586 }
5587
5588 static int
5589 api_mpls_add_del_decap (vat_main_t * vam)
5590 {
5591   unformat_input_t *i = vam->input;
5592   vl_api_mpls_add_del_decap_t *mp;
5593   f64 timeout;
5594   u32 rx_vrf_id = 0;
5595   u32 tx_vrf_id = 0;
5596   u32 label = 0;
5597   u8 is_add = 1;
5598   u8 s_bit = 1;
5599   u32 next_index = 1;
5600
5601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5602     {
5603       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5604         ;
5605       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5606         ;
5607       else if (unformat (i, "label %d", &label))
5608         ;
5609       else if (unformat (i, "next-index %d", &next_index))
5610         ;
5611       else if (unformat (i, "del"))
5612         is_add = 0;
5613       else if (unformat (i, "s-bit-clear"))
5614         s_bit = 0;
5615       else
5616         {
5617           clib_warning ("parse error '%U'", format_unformat_error, i);
5618           return -99;
5619         }
5620     }
5621
5622   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5623
5624   mp->rx_vrf_id = ntohl (rx_vrf_id);
5625   mp->tx_vrf_id = ntohl (tx_vrf_id);
5626   mp->label = ntohl (label);
5627   mp->next_index = ntohl (next_index);
5628   mp->s_bit = s_bit;
5629   mp->is_add = is_add;
5630
5631   S;
5632   W;
5633   /* NOTREACHED */
5634   return 0;
5635 }
5636
5637 static int
5638 api_mpls_add_del_encap (vat_main_t * vam)
5639 {
5640   unformat_input_t *i = vam->input;
5641   vl_api_mpls_add_del_encap_t *mp;
5642   f64 timeout;
5643   u32 vrf_id = 0;
5644   u32 *labels = 0;
5645   u32 label;
5646   ip4_address_t dst_address;
5647   u8 is_add = 1;
5648
5649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5650     {
5651       if (unformat (i, "vrf %d", &vrf_id))
5652         ;
5653       else if (unformat (i, "label %d", &label))
5654         vec_add1 (labels, ntohl (label));
5655       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5656         ;
5657       else if (unformat (i, "del"))
5658         is_add = 0;
5659       else
5660         {
5661           clib_warning ("parse error '%U'", format_unformat_error, i);
5662           return -99;
5663         }
5664     }
5665
5666   if (vec_len (labels) == 0)
5667     {
5668       errmsg ("missing encap label stack\n");
5669       return -99;
5670     }
5671
5672   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5673       sizeof (u32) * vec_len (labels));
5674
5675   mp->vrf_id = ntohl (vrf_id);
5676   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5677   mp->is_add = is_add;
5678   mp->nlabels = vec_len (labels);
5679   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5680
5681   vec_free (labels);
5682
5683   S;
5684   W;
5685   /* NOTREACHED */
5686   return 0;
5687 }
5688
5689 static int
5690 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5691 {
5692   unformat_input_t *i = vam->input;
5693   vl_api_mpls_gre_add_del_tunnel_t *mp;
5694   f64 timeout;
5695   u32 inner_vrf_id = 0;
5696   u32 outer_vrf_id = 0;
5697   ip4_address_t src_address;
5698   ip4_address_t dst_address;
5699   ip4_address_t intfc_address;
5700   u32 tmp;
5701   u8 intfc_address_length = 0;
5702   u8 is_add = 1;
5703   u8 l2_only = 0;
5704
5705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5706     {
5707       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5708         ;
5709       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5710         ;
5711       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5712         ;
5713       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5714         ;
5715       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5716                          &intfc_address, &tmp))
5717         intfc_address_length = tmp;
5718       else if (unformat (i, "l2-only"))
5719         l2_only = 1;
5720       else if (unformat (i, "del"))
5721         is_add = 0;
5722       else
5723         {
5724           clib_warning ("parse error '%U'", format_unformat_error, i);
5725           return -99;
5726         }
5727     }
5728
5729   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5730
5731   mp->inner_vrf_id = ntohl (inner_vrf_id);
5732   mp->outer_vrf_id = ntohl (outer_vrf_id);
5733   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5734   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5735   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5736   mp->intfc_address_length = intfc_address_length;
5737   mp->l2_only = l2_only;
5738   mp->is_add = is_add;
5739
5740   S;
5741   W;
5742   /* NOTREACHED */
5743   return 0;
5744 }
5745
5746 static int
5747 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5748 {
5749   unformat_input_t *i = vam->input;
5750   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5751   f64 timeout;
5752   u32 inner_vrf_id = 0;
5753   ip4_address_t intfc_address;
5754   u8 dst_mac_address[6];
5755   int dst_set = 1;
5756   u32 tmp;
5757   u8 intfc_address_length = 0;
5758   u8 is_add = 1;
5759   u8 l2_only = 0;
5760   u32 tx_sw_if_index;
5761   int tx_sw_if_index_set = 0;
5762
5763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5764     {
5765       if (unformat (i, "vrf %d", &inner_vrf_id))
5766         ;
5767       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5768                          &intfc_address, &tmp))
5769         intfc_address_length = tmp;
5770       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5771         tx_sw_if_index_set = 1;
5772       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5773         tx_sw_if_index_set = 1;
5774       else if (unformat (i, "dst %U", unformat_ethernet_address,
5775                          dst_mac_address))
5776         dst_set = 1;
5777       else if (unformat (i, "l2-only"))
5778         l2_only = 1;
5779       else if (unformat (i, "del"))
5780         is_add = 0;
5781       else
5782         {
5783           clib_warning ("parse error '%U'", format_unformat_error, i);
5784           return -99;
5785         }
5786     }
5787
5788   if (!dst_set)
5789     {
5790       errmsg ("dst (mac address) not set\n");
5791       return -99;
5792     }
5793   if (!tx_sw_if_index_set)
5794     {
5795       errmsg ("tx-intfc not set\n");
5796       return -99;
5797     }
5798
5799   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5800
5801   mp->vrf_id = ntohl (inner_vrf_id);
5802   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5803   mp->adj_address_length = intfc_address_length;
5804   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5805                sizeof (dst_mac_address));
5806   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5807   mp->l2_only = l2_only;
5808   mp->is_add = is_add;
5809
5810   S;
5811   W;
5812   /* NOTREACHED */
5813   return 0;
5814 }
5815
5816 static int
5817 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5818 {
5819   unformat_input_t *i = vam->input;
5820   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5821   f64 timeout;
5822   u32 inner_vrf_id = 0;
5823   u32 outer_vrf_id = 0;
5824   ip4_address_t adj_address;
5825   int adj_address_set = 0;
5826   ip4_address_t next_hop_address;
5827   int next_hop_address_set = 0;
5828   u32 tmp;
5829   u8 adj_address_length = 0;
5830   u8 l2_only = 0;
5831   u8 is_add = 1;
5832   u32 resolve_attempts = 5;
5833   u8 resolve_if_needed = 1;
5834
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5838         ;
5839       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5840         ;
5841       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5842                          &adj_address, &tmp))
5843         {
5844           adj_address_length = tmp;
5845           adj_address_set = 1;
5846         }
5847       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5848                          &next_hop_address))
5849         next_hop_address_set = 1;
5850       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5851         ;
5852       else if (unformat (i, "resolve-if-needed %d", &tmp))
5853         resolve_if_needed = tmp;
5854       else if (unformat (i, "l2-only"))
5855         l2_only = 1;
5856       else if (unformat (i, "del"))
5857         is_add = 0;
5858       else
5859         {
5860           clib_warning ("parse error '%U'", format_unformat_error, i);
5861           return -99;
5862         }
5863     }
5864
5865   if (!adj_address_set)
5866     {
5867       errmsg ("adjacency address/mask not set\n");
5868       return -99;
5869     }
5870   if (!next_hop_address_set)
5871     {
5872       errmsg ("ip4 next hop address (in outer fib) not set\n");
5873       return -99;
5874     }
5875
5876   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5877
5878   mp->inner_vrf_id = ntohl (inner_vrf_id);
5879   mp->outer_vrf_id = ntohl (outer_vrf_id);
5880   mp->resolve_attempts = ntohl (resolve_attempts);
5881   mp->resolve_if_needed = resolve_if_needed;
5882   mp->is_add = is_add;
5883   mp->l2_only = l2_only;
5884   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5885   mp->adj_address_length = adj_address_length;
5886   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5887                sizeof (next_hop_address));
5888
5889   S;
5890   W;
5891   /* NOTREACHED */
5892   return 0;
5893 }
5894
5895 static int
5896 api_sw_interface_set_unnumbered (vat_main_t * vam)
5897 {
5898   unformat_input_t *i = vam->input;
5899   vl_api_sw_interface_set_unnumbered_t *mp;
5900   f64 timeout;
5901   u32 sw_if_index;
5902   u32 unnum_sw_index = ~0;
5903   u8 is_add = 1;
5904   u8 sw_if_index_set = 0;
5905
5906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5907     {
5908       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5909         sw_if_index_set = 1;
5910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5911         sw_if_index_set = 1;
5912       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5913         ;
5914       else if (unformat (i, "del"))
5915         is_add = 0;
5916       else
5917         {
5918           clib_warning ("parse error '%U'", format_unformat_error, i);
5919           return -99;
5920         }
5921     }
5922
5923   if (sw_if_index_set == 0)
5924     {
5925       errmsg ("missing interface name or sw_if_index\n");
5926       return -99;
5927     }
5928
5929   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5930
5931   mp->sw_if_index = ntohl (sw_if_index);
5932   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5933   mp->is_add = is_add;
5934
5935   S;
5936   W;
5937   /* NOTREACHED */
5938   return 0;
5939 }
5940
5941 static int
5942 api_ip_neighbor_add_del (vat_main_t * vam)
5943 {
5944   unformat_input_t *i = vam->input;
5945   vl_api_ip_neighbor_add_del_t *mp;
5946   f64 timeout;
5947   u32 sw_if_index;
5948   u8 sw_if_index_set = 0;
5949   u32 vrf_id = 0;
5950   u8 is_add = 1;
5951   u8 is_static = 0;
5952   u8 mac_address[6];
5953   u8 mac_set = 0;
5954   u8 v4_address_set = 0;
5955   u8 v6_address_set = 0;
5956   ip4_address_t v4address;
5957   ip6_address_t v6address;
5958
5959   memset (mac_address, 0, sizeof (mac_address));
5960
5961   /* Parse args required to build the message */
5962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5963     {
5964       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5965         {
5966           mac_set = 1;
5967         }
5968       else if (unformat (i, "del"))
5969         is_add = 0;
5970       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5971         sw_if_index_set = 1;
5972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5973         sw_if_index_set = 1;
5974       else if (unformat (i, "is_static"))
5975         is_static = 1;
5976       else if (unformat (i, "vrf %d", &vrf_id))
5977         ;
5978       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5979         v4_address_set = 1;
5980       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5981         v6_address_set = 1;
5982       else
5983         {
5984           clib_warning ("parse error '%U'", format_unformat_error, i);
5985           return -99;
5986         }
5987     }
5988
5989   if (sw_if_index_set == 0)
5990     {
5991       errmsg ("missing interface name or sw_if_index\n");
5992       return -99;
5993     }
5994   if (v4_address_set && v6_address_set)
5995     {
5996       errmsg ("both v4 and v6 addresses set\n");
5997       return -99;
5998     }
5999   if (!v4_address_set && !v6_address_set)
6000     {
6001       errmsg ("no address set\n");
6002       return -99;
6003     }
6004
6005   /* Construct the API message */
6006   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6007
6008   mp->sw_if_index = ntohl (sw_if_index);
6009   mp->is_add = is_add;
6010   mp->vrf_id = ntohl (vrf_id);
6011   mp->is_static = is_static;
6012   if (mac_set)
6013     clib_memcpy (mp->mac_address, mac_address, 6);
6014   if (v6_address_set)
6015     {
6016       mp->is_ipv6 = 1;
6017       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6018     }
6019   else
6020     {
6021       /* mp->is_ipv6 = 0; via memset in M macro above */
6022       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6023     }
6024
6025   /* send it... */
6026   S;
6027
6028   /* Wait for a reply, return good/bad news  */
6029   W;
6030
6031   /* NOTREACHED */
6032   return 0;
6033 }
6034
6035 static int
6036 api_reset_vrf (vat_main_t * vam)
6037 {
6038   unformat_input_t *i = vam->input;
6039   vl_api_reset_vrf_t *mp;
6040   f64 timeout;
6041   u32 vrf_id = 0;
6042   u8 is_ipv6 = 0;
6043   u8 vrf_id_set = 0;
6044
6045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6046     {
6047       if (unformat (i, "vrf %d", &vrf_id))
6048         vrf_id_set = 1;
6049       else if (unformat (i, "ipv6"))
6050         is_ipv6 = 1;
6051       else
6052         {
6053           clib_warning ("parse error '%U'", format_unformat_error, i);
6054           return -99;
6055         }
6056     }
6057
6058   if (vrf_id_set == 0)
6059     {
6060       errmsg ("missing vrf id\n");
6061       return -99;
6062     }
6063
6064   M (RESET_VRF, reset_vrf);
6065
6066   mp->vrf_id = ntohl (vrf_id);
6067   mp->is_ipv6 = is_ipv6;
6068
6069   S;
6070   W;
6071   /* NOTREACHED */
6072   return 0;
6073 }
6074
6075 static int
6076 api_create_vlan_subif (vat_main_t * vam)
6077 {
6078   unformat_input_t *i = vam->input;
6079   vl_api_create_vlan_subif_t *mp;
6080   f64 timeout;
6081   u32 sw_if_index;
6082   u8 sw_if_index_set = 0;
6083   u32 vlan_id;
6084   u8 vlan_id_set = 0;
6085
6086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6087     {
6088       if (unformat (i, "sw_if_index %d", &sw_if_index))
6089         sw_if_index_set = 1;
6090       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6091         sw_if_index_set = 1;
6092       else if (unformat (i, "vlan %d", &vlan_id))
6093         vlan_id_set = 1;
6094       else
6095         {
6096           clib_warning ("parse error '%U'", format_unformat_error, i);
6097           return -99;
6098         }
6099     }
6100
6101   if (sw_if_index_set == 0)
6102     {
6103       errmsg ("missing interface name or sw_if_index\n");
6104       return -99;
6105     }
6106
6107   if (vlan_id_set == 0)
6108     {
6109       errmsg ("missing vlan_id\n");
6110       return -99;
6111     }
6112   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6113
6114   mp->sw_if_index = ntohl (sw_if_index);
6115   mp->vlan_id = ntohl (vlan_id);
6116
6117   S;
6118   W;
6119   /* NOTREACHED */
6120   return 0;
6121 }
6122
6123 #define foreach_create_subif_bit                \
6124 _(no_tags)                                      \
6125 _(one_tag)                                      \
6126 _(two_tags)                                     \
6127 _(dot1ad)                                       \
6128 _(exact_match)                                  \
6129 _(default_sub)                                  \
6130 _(outer_vlan_id_any)                            \
6131 _(inner_vlan_id_any)
6132
6133 static int
6134 api_create_subif (vat_main_t * vam)
6135 {
6136   unformat_input_t *i = vam->input;
6137   vl_api_create_subif_t *mp;
6138   f64 timeout;
6139   u32 sw_if_index;
6140   u8 sw_if_index_set = 0;
6141   u32 sub_id;
6142   u8 sub_id_set = 0;
6143   u32 no_tags = 0;
6144   u32 one_tag = 0;
6145   u32 two_tags = 0;
6146   u32 dot1ad = 0;
6147   u32 exact_match = 0;
6148   u32 default_sub = 0;
6149   u32 outer_vlan_id_any = 0;
6150   u32 inner_vlan_id_any = 0;
6151   u32 tmp;
6152   u16 outer_vlan_id = 0;
6153   u16 inner_vlan_id = 0;
6154
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "sw_if_index %d", &sw_if_index))
6158         sw_if_index_set = 1;
6159       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6160         sw_if_index_set = 1;
6161       else if (unformat (i, "sub_id %d", &sub_id))
6162         sub_id_set = 1;
6163       else if (unformat (i, "outer_vlan_id %d", &tmp))
6164         outer_vlan_id = tmp;
6165       else if (unformat (i, "inner_vlan_id %d", &tmp))
6166         inner_vlan_id = tmp;
6167
6168 #define _(a) else if (unformat (i, #a)) a = 1 ;
6169       foreach_create_subif_bit
6170 #undef _
6171         else
6172         {
6173           clib_warning ("parse error '%U'", format_unformat_error, i);
6174           return -99;
6175         }
6176     }
6177
6178   if (sw_if_index_set == 0)
6179     {
6180       errmsg ("missing interface name or sw_if_index\n");
6181       return -99;
6182     }
6183
6184   if (sub_id_set == 0)
6185     {
6186       errmsg ("missing sub_id\n");
6187       return -99;
6188     }
6189   M (CREATE_SUBIF, create_subif);
6190
6191   mp->sw_if_index = ntohl (sw_if_index);
6192   mp->sub_id = ntohl (sub_id);
6193
6194 #define _(a) mp->a = a;
6195   foreach_create_subif_bit;
6196 #undef _
6197
6198   mp->outer_vlan_id = ntohs (outer_vlan_id);
6199   mp->inner_vlan_id = ntohs (inner_vlan_id);
6200
6201   S;
6202   W;
6203   /* NOTREACHED */
6204   return 0;
6205 }
6206
6207 static int
6208 api_oam_add_del (vat_main_t * vam)
6209 {
6210   unformat_input_t *i = vam->input;
6211   vl_api_oam_add_del_t *mp;
6212   f64 timeout;
6213   u32 vrf_id = 0;
6214   u8 is_add = 1;
6215   ip4_address_t src, dst;
6216   u8 src_set = 0;
6217   u8 dst_set = 0;
6218
6219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6220     {
6221       if (unformat (i, "vrf %d", &vrf_id))
6222         ;
6223       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6224         src_set = 1;
6225       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6226         dst_set = 1;
6227       else if (unformat (i, "del"))
6228         is_add = 0;
6229       else
6230         {
6231           clib_warning ("parse error '%U'", format_unformat_error, i);
6232           return -99;
6233         }
6234     }
6235
6236   if (src_set == 0)
6237     {
6238       errmsg ("missing src addr\n");
6239       return -99;
6240     }
6241
6242   if (dst_set == 0)
6243     {
6244       errmsg ("missing dst addr\n");
6245       return -99;
6246     }
6247
6248   M (OAM_ADD_DEL, oam_add_del);
6249
6250   mp->vrf_id = ntohl (vrf_id);
6251   mp->is_add = is_add;
6252   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6253   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6254
6255   S;
6256   W;
6257   /* NOTREACHED */
6258   return 0;
6259 }
6260
6261 static int
6262 api_reset_fib (vat_main_t * vam)
6263 {
6264   unformat_input_t *i = vam->input;
6265   vl_api_reset_fib_t *mp;
6266   f64 timeout;
6267   u32 vrf_id = 0;
6268   u8 is_ipv6 = 0;
6269   u8 vrf_id_set = 0;
6270
6271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6272     {
6273       if (unformat (i, "vrf %d", &vrf_id))
6274         vrf_id_set = 1;
6275       else if (unformat (i, "ipv6"))
6276         is_ipv6 = 1;
6277       else
6278         {
6279           clib_warning ("parse error '%U'", format_unformat_error, i);
6280           return -99;
6281         }
6282     }
6283
6284   if (vrf_id_set == 0)
6285     {
6286       errmsg ("missing vrf id\n");
6287       return -99;
6288     }
6289
6290   M (RESET_FIB, reset_fib);
6291
6292   mp->vrf_id = ntohl (vrf_id);
6293   mp->is_ipv6 = is_ipv6;
6294
6295   S;
6296   W;
6297   /* NOTREACHED */
6298   return 0;
6299 }
6300
6301 static int
6302 api_dhcp_proxy_config (vat_main_t * vam)
6303 {
6304   unformat_input_t *i = vam->input;
6305   vl_api_dhcp_proxy_config_t *mp;
6306   f64 timeout;
6307   u32 vrf_id = 0;
6308   u8 is_add = 1;
6309   u8 insert_cid = 1;
6310   u8 v4_address_set = 0;
6311   u8 v6_address_set = 0;
6312   ip4_address_t v4address;
6313   ip6_address_t v6address;
6314   u8 v4_src_address_set = 0;
6315   u8 v6_src_address_set = 0;
6316   ip4_address_t v4srcaddress;
6317   ip6_address_t v6srcaddress;
6318
6319   /* Parse args required to build the message */
6320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6321     {
6322       if (unformat (i, "del"))
6323         is_add = 0;
6324       else if (unformat (i, "vrf %d", &vrf_id))
6325         ;
6326       else if (unformat (i, "insert-cid %d", &insert_cid))
6327         ;
6328       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6329         v4_address_set = 1;
6330       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6331         v6_address_set = 1;
6332       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6333         v4_src_address_set = 1;
6334       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6335         v6_src_address_set = 1;
6336       else
6337         break;
6338     }
6339
6340   if (v4_address_set && v6_address_set)
6341     {
6342       errmsg ("both v4 and v6 server addresses set\n");
6343       return -99;
6344     }
6345   if (!v4_address_set && !v6_address_set)
6346     {
6347       errmsg ("no server addresses set\n");
6348       return -99;
6349     }
6350
6351   if (v4_src_address_set && v6_src_address_set)
6352     {
6353       errmsg ("both v4 and v6  src addresses set\n");
6354       return -99;
6355     }
6356   if (!v4_src_address_set && !v6_src_address_set)
6357     {
6358       errmsg ("no src addresses set\n");
6359       return -99;
6360     }
6361
6362   if (!(v4_src_address_set && v4_address_set) &&
6363       !(v6_src_address_set && v6_address_set))
6364     {
6365       errmsg ("no matching server and src addresses set\n");
6366       return -99;
6367     }
6368
6369   /* Construct the API message */
6370   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6371
6372   mp->insert_circuit_id = insert_cid;
6373   mp->is_add = is_add;
6374   mp->vrf_id = ntohl (vrf_id);
6375   if (v6_address_set)
6376     {
6377       mp->is_ipv6 = 1;
6378       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6379       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6380     }
6381   else
6382     {
6383       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6384       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6385     }
6386
6387   /* send it... */
6388   S;
6389
6390   /* Wait for a reply, return good/bad news  */
6391   W;
6392   /* NOTREACHED */
6393   return 0;
6394 }
6395
6396 static int
6397 api_dhcp_proxy_config_2 (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_dhcp_proxy_config_2_t *mp;
6401   f64 timeout;
6402   u32 rx_vrf_id = 0;
6403   u32 server_vrf_id = 0;
6404   u8 is_add = 1;
6405   u8 insert_cid = 1;
6406   u8 v4_address_set = 0;
6407   u8 v6_address_set = 0;
6408   ip4_address_t v4address;
6409   ip6_address_t v6address;
6410   u8 v4_src_address_set = 0;
6411   u8 v6_src_address_set = 0;
6412   ip4_address_t v4srcaddress;
6413   ip6_address_t v6srcaddress;
6414
6415   /* Parse args required to build the message */
6416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6417     {
6418       if (unformat (i, "del"))
6419         is_add = 0;
6420       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6421         ;
6422       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6423         ;
6424       else if (unformat (i, "insert-cid %d", &insert_cid))
6425         ;
6426       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6427         v4_address_set = 1;
6428       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6429         v6_address_set = 1;
6430       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6431         v4_src_address_set = 1;
6432       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6433         v6_src_address_set = 1;
6434       else
6435         break;
6436     }
6437
6438   if (v4_address_set && v6_address_set)
6439     {
6440       errmsg ("both v4 and v6 server addresses set\n");
6441       return -99;
6442     }
6443   if (!v4_address_set && !v6_address_set)
6444     {
6445       errmsg ("no server addresses set\n");
6446       return -99;
6447     }
6448
6449   if (v4_src_address_set && v6_src_address_set)
6450     {
6451       errmsg ("both v4 and v6  src addresses set\n");
6452       return -99;
6453     }
6454   if (!v4_src_address_set && !v6_src_address_set)
6455     {
6456       errmsg ("no src addresses set\n");
6457       return -99;
6458     }
6459
6460   if (!(v4_src_address_set && v4_address_set) &&
6461       !(v6_src_address_set && v6_address_set))
6462     {
6463       errmsg ("no matching server and src addresses set\n");
6464       return -99;
6465     }
6466
6467   /* Construct the API message */
6468   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6469
6470   mp->insert_circuit_id = insert_cid;
6471   mp->is_add = is_add;
6472   mp->rx_vrf_id = ntohl (rx_vrf_id);
6473   mp->server_vrf_id = ntohl (server_vrf_id);
6474   if (v6_address_set)
6475     {
6476       mp->is_ipv6 = 1;
6477       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6478       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6479     }
6480   else
6481     {
6482       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6483       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6484     }
6485
6486   /* send it... */
6487   S;
6488
6489   /* Wait for a reply, return good/bad news  */
6490   W;
6491   /* NOTREACHED */
6492   return 0;
6493 }
6494
6495 static int
6496 api_dhcp_proxy_set_vss (vat_main_t * vam)
6497 {
6498   unformat_input_t *i = vam->input;
6499   vl_api_dhcp_proxy_set_vss_t *mp;
6500   f64 timeout;
6501   u8 is_ipv6 = 0;
6502   u8 is_add = 1;
6503   u32 tbl_id;
6504   u8 tbl_id_set = 0;
6505   u32 oui;
6506   u8 oui_set = 0;
6507   u32 fib_id;
6508   u8 fib_id_set = 0;
6509
6510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6511     {
6512       if (unformat (i, "tbl_id %d", &tbl_id))
6513         tbl_id_set = 1;
6514       if (unformat (i, "fib_id %d", &fib_id))
6515         fib_id_set = 1;
6516       if (unformat (i, "oui %d", &oui))
6517         oui_set = 1;
6518       else if (unformat (i, "ipv6"))
6519         is_ipv6 = 1;
6520       else if (unformat (i, "del"))
6521         is_add = 0;
6522       else
6523         {
6524           clib_warning ("parse error '%U'", format_unformat_error, i);
6525           return -99;
6526         }
6527     }
6528
6529   if (tbl_id_set == 0)
6530     {
6531       errmsg ("missing tbl id\n");
6532       return -99;
6533     }
6534
6535   if (fib_id_set == 0)
6536     {
6537       errmsg ("missing fib id\n");
6538       return -99;
6539     }
6540   if (oui_set == 0)
6541     {
6542       errmsg ("missing oui\n");
6543       return -99;
6544     }
6545
6546   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6547   mp->tbl_id = ntohl (tbl_id);
6548   mp->fib_id = ntohl (fib_id);
6549   mp->oui = ntohl (oui);
6550   mp->is_ipv6 = is_ipv6;
6551   mp->is_add = is_add;
6552
6553   S;
6554   W;
6555   /* NOTREACHED */
6556   return 0;
6557 }
6558
6559 static int
6560 api_dhcp_client_config (vat_main_t * vam)
6561 {
6562   unformat_input_t *i = vam->input;
6563   vl_api_dhcp_client_config_t *mp;
6564   f64 timeout;
6565   u32 sw_if_index;
6566   u8 sw_if_index_set = 0;
6567   u8 is_add = 1;
6568   u8 *hostname = 0;
6569   u8 disable_event = 0;
6570
6571   /* Parse args required to build the message */
6572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6573     {
6574       if (unformat (i, "del"))
6575         is_add = 0;
6576       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6577         sw_if_index_set = 1;
6578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6579         sw_if_index_set = 1;
6580       else if (unformat (i, "hostname %s", &hostname))
6581         ;
6582       else if (unformat (i, "disable_event"))
6583         disable_event = 1;
6584       else
6585         break;
6586     }
6587
6588   if (sw_if_index_set == 0)
6589     {
6590       errmsg ("missing interface name or sw_if_index\n");
6591       return -99;
6592     }
6593
6594   if (vec_len (hostname) > 63)
6595     {
6596       errmsg ("hostname too long\n");
6597     }
6598   vec_add1 (hostname, 0);
6599
6600   /* Construct the API message */
6601   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6602
6603   mp->sw_if_index = ntohl (sw_if_index);
6604   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6605   vec_free (hostname);
6606   mp->is_add = is_add;
6607   mp->want_dhcp_event = disable_event ? 0 : 1;
6608   mp->pid = getpid ();
6609
6610   /* send it... */
6611   S;
6612
6613   /* Wait for a reply, return good/bad news  */
6614   W;
6615   /* NOTREACHED */
6616   return 0;
6617 }
6618
6619 static int
6620 api_set_ip_flow_hash (vat_main_t * vam)
6621 {
6622   unformat_input_t *i = vam->input;
6623   vl_api_set_ip_flow_hash_t *mp;
6624   f64 timeout;
6625   u32 vrf_id = 0;
6626   u8 is_ipv6 = 0;
6627   u8 vrf_id_set = 0;
6628   u8 src = 0;
6629   u8 dst = 0;
6630   u8 sport = 0;
6631   u8 dport = 0;
6632   u8 proto = 0;
6633   u8 reverse = 0;
6634
6635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6636     {
6637       if (unformat (i, "vrf %d", &vrf_id))
6638         vrf_id_set = 1;
6639       else if (unformat (i, "ipv6"))
6640         is_ipv6 = 1;
6641       else if (unformat (i, "src"))
6642         src = 1;
6643       else if (unformat (i, "dst"))
6644         dst = 1;
6645       else if (unformat (i, "sport"))
6646         sport = 1;
6647       else if (unformat (i, "dport"))
6648         dport = 1;
6649       else if (unformat (i, "proto"))
6650         proto = 1;
6651       else if (unformat (i, "reverse"))
6652         reverse = 1;
6653
6654       else
6655         {
6656           clib_warning ("parse error '%U'", format_unformat_error, i);
6657           return -99;
6658         }
6659     }
6660
6661   if (vrf_id_set == 0)
6662     {
6663       errmsg ("missing vrf id\n");
6664       return -99;
6665     }
6666
6667   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6668   mp->src = src;
6669   mp->dst = dst;
6670   mp->sport = sport;
6671   mp->dport = dport;
6672   mp->proto = proto;
6673   mp->reverse = reverse;
6674   mp->vrf_id = ntohl (vrf_id);
6675   mp->is_ipv6 = is_ipv6;
6676
6677   S;
6678   W;
6679   /* NOTREACHED */
6680   return 0;
6681 }
6682
6683 static int
6684 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6685 {
6686   unformat_input_t *i = vam->input;
6687   vl_api_sw_interface_ip6_enable_disable_t *mp;
6688   f64 timeout;
6689   u32 sw_if_index;
6690   u8 sw_if_index_set = 0;
6691   u8 enable = 0;
6692
6693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6694     {
6695       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6696         sw_if_index_set = 1;
6697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6698         sw_if_index_set = 1;
6699       else if (unformat (i, "enable"))
6700         enable = 1;
6701       else if (unformat (i, "disable"))
6702         enable = 0;
6703       else
6704         {
6705           clib_warning ("parse error '%U'", format_unformat_error, i);
6706           return -99;
6707         }
6708     }
6709
6710   if (sw_if_index_set == 0)
6711     {
6712       errmsg ("missing interface name or sw_if_index\n");
6713       return -99;
6714     }
6715
6716   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6717
6718   mp->sw_if_index = ntohl (sw_if_index);
6719   mp->enable = enable;
6720
6721   S;
6722   W;
6723   /* NOTREACHED */
6724   return 0;
6725 }
6726
6727 static int
6728 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6729 {
6730   unformat_input_t *i = vam->input;
6731   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6732   f64 timeout;
6733   u32 sw_if_index;
6734   u8 sw_if_index_set = 0;
6735   u32 address_length = 0;
6736   u8 v6_address_set = 0;
6737   ip6_address_t v6address;
6738
6739   /* Parse args required to build the message */
6740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6741     {
6742       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6743         sw_if_index_set = 1;
6744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6745         sw_if_index_set = 1;
6746       else if (unformat (i, "%U/%d",
6747                          unformat_ip6_address, &v6address, &address_length))
6748         v6_address_set = 1;
6749       else
6750         break;
6751     }
6752
6753   if (sw_if_index_set == 0)
6754     {
6755       errmsg ("missing interface name or sw_if_index\n");
6756       return -99;
6757     }
6758   if (!v6_address_set)
6759     {
6760       errmsg ("no address set\n");
6761       return -99;
6762     }
6763
6764   /* Construct the API message */
6765   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6766      sw_interface_ip6_set_link_local_address);
6767
6768   mp->sw_if_index = ntohl (sw_if_index);
6769   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6770   mp->address_length = address_length;
6771
6772   /* send it... */
6773   S;
6774
6775   /* Wait for a reply, return good/bad news  */
6776   W;
6777
6778   /* NOTREACHED */
6779   return 0;
6780 }
6781
6782
6783 static int
6784 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6788   f64 timeout;
6789   u32 sw_if_index;
6790   u8 sw_if_index_set = 0;
6791   u32 address_length = 0;
6792   u8 v6_address_set = 0;
6793   ip6_address_t v6address;
6794   u8 use_default = 0;
6795   u8 no_advertise = 0;
6796   u8 off_link = 0;
6797   u8 no_autoconfig = 0;
6798   u8 no_onlink = 0;
6799   u8 is_no = 0;
6800   u32 val_lifetime = 0;
6801   u32 pref_lifetime = 0;
6802
6803   /* Parse args required to build the message */
6804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6805     {
6806       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6807         sw_if_index_set = 1;
6808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6809         sw_if_index_set = 1;
6810       else if (unformat (i, "%U/%d",
6811                          unformat_ip6_address, &v6address, &address_length))
6812         v6_address_set = 1;
6813       else if (unformat (i, "val_life %d", &val_lifetime))
6814         ;
6815       else if (unformat (i, "pref_life %d", &pref_lifetime))
6816         ;
6817       else if (unformat (i, "def"))
6818         use_default = 1;
6819       else if (unformat (i, "noadv"))
6820         no_advertise = 1;
6821       else if (unformat (i, "offl"))
6822         off_link = 1;
6823       else if (unformat (i, "noauto"))
6824         no_autoconfig = 1;
6825       else if (unformat (i, "nolink"))
6826         no_onlink = 1;
6827       else if (unformat (i, "isno"))
6828         is_no = 1;
6829       else
6830         {
6831           clib_warning ("parse error '%U'", format_unformat_error, i);
6832           return -99;
6833         }
6834     }
6835
6836   if (sw_if_index_set == 0)
6837     {
6838       errmsg ("missing interface name or sw_if_index\n");
6839       return -99;
6840     }
6841   if (!v6_address_set)
6842     {
6843       errmsg ("no address set\n");
6844       return -99;
6845     }
6846
6847   /* Construct the API message */
6848   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6849
6850   mp->sw_if_index = ntohl (sw_if_index);
6851   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6852   mp->address_length = address_length;
6853   mp->use_default = use_default;
6854   mp->no_advertise = no_advertise;
6855   mp->off_link = off_link;
6856   mp->no_autoconfig = no_autoconfig;
6857   mp->no_onlink = no_onlink;
6858   mp->is_no = is_no;
6859   mp->val_lifetime = ntohl (val_lifetime);
6860   mp->pref_lifetime = ntohl (pref_lifetime);
6861
6862   /* send it... */
6863   S;
6864
6865   /* Wait for a reply, return good/bad news  */
6866   W;
6867
6868   /* NOTREACHED */
6869   return 0;
6870 }
6871
6872 static int
6873 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6874 {
6875   unformat_input_t *i = vam->input;
6876   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6877   f64 timeout;
6878   u32 sw_if_index;
6879   u8 sw_if_index_set = 0;
6880   u8 suppress = 0;
6881   u8 managed = 0;
6882   u8 other = 0;
6883   u8 ll_option = 0;
6884   u8 send_unicast = 0;
6885   u8 cease = 0;
6886   u8 is_no = 0;
6887   u8 default_router = 0;
6888   u32 max_interval = 0;
6889   u32 min_interval = 0;
6890   u32 lifetime = 0;
6891   u32 initial_count = 0;
6892   u32 initial_interval = 0;
6893
6894
6895   /* Parse args required to build the message */
6896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6897     {
6898       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6899         sw_if_index_set = 1;
6900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6901         sw_if_index_set = 1;
6902       else if (unformat (i, "maxint %d", &max_interval))
6903         ;
6904       else if (unformat (i, "minint %d", &min_interval))
6905         ;
6906       else if (unformat (i, "life %d", &lifetime))
6907         ;
6908       else if (unformat (i, "count %d", &initial_count))
6909         ;
6910       else if (unformat (i, "interval %d", &initial_interval))
6911         ;
6912       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6913         suppress = 1;
6914       else if (unformat (i, "managed"))
6915         managed = 1;
6916       else if (unformat (i, "other"))
6917         other = 1;
6918       else if (unformat (i, "ll"))
6919         ll_option = 1;
6920       else if (unformat (i, "send"))
6921         send_unicast = 1;
6922       else if (unformat (i, "cease"))
6923         cease = 1;
6924       else if (unformat (i, "isno"))
6925         is_no = 1;
6926       else if (unformat (i, "def"))
6927         default_router = 1;
6928       else
6929         {
6930           clib_warning ("parse error '%U'", format_unformat_error, i);
6931           return -99;
6932         }
6933     }
6934
6935   if (sw_if_index_set == 0)
6936     {
6937       errmsg ("missing interface name or sw_if_index\n");
6938       return -99;
6939     }
6940
6941   /* Construct the API message */
6942   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6943
6944   mp->sw_if_index = ntohl (sw_if_index);
6945   mp->max_interval = ntohl (max_interval);
6946   mp->min_interval = ntohl (min_interval);
6947   mp->lifetime = ntohl (lifetime);
6948   mp->initial_count = ntohl (initial_count);
6949   mp->initial_interval = ntohl (initial_interval);
6950   mp->suppress = suppress;
6951   mp->managed = managed;
6952   mp->other = other;
6953   mp->ll_option = ll_option;
6954   mp->send_unicast = send_unicast;
6955   mp->cease = cease;
6956   mp->is_no = is_no;
6957   mp->default_router = default_router;
6958
6959   /* send it... */
6960   S;
6961
6962   /* Wait for a reply, return good/bad news  */
6963   W;
6964
6965   /* NOTREACHED */
6966   return 0;
6967 }
6968
6969 static int
6970 api_set_arp_neighbor_limit (vat_main_t * vam)
6971 {
6972   unformat_input_t *i = vam->input;
6973   vl_api_set_arp_neighbor_limit_t *mp;
6974   f64 timeout;
6975   u32 arp_nbr_limit;
6976   u8 limit_set = 0;
6977   u8 is_ipv6 = 0;
6978
6979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980     {
6981       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6982         limit_set = 1;
6983       else if (unformat (i, "ipv6"))
6984         is_ipv6 = 1;
6985       else
6986         {
6987           clib_warning ("parse error '%U'", format_unformat_error, i);
6988           return -99;
6989         }
6990     }
6991
6992   if (limit_set == 0)
6993     {
6994       errmsg ("missing limit value\n");
6995       return -99;
6996     }
6997
6998   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6999
7000   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7001   mp->is_ipv6 = is_ipv6;
7002
7003   S;
7004   W;
7005   /* NOTREACHED */
7006   return 0;
7007 }
7008
7009 static int
7010 api_l2_patch_add_del (vat_main_t * vam)
7011 {
7012   unformat_input_t *i = vam->input;
7013   vl_api_l2_patch_add_del_t *mp;
7014   f64 timeout;
7015   u32 rx_sw_if_index;
7016   u8 rx_sw_if_index_set = 0;
7017   u32 tx_sw_if_index;
7018   u8 tx_sw_if_index_set = 0;
7019   u8 is_add = 1;
7020
7021   /* Parse args required to build the message */
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7025         rx_sw_if_index_set = 1;
7026       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7027         tx_sw_if_index_set = 1;
7028       else if (unformat (i, "rx"))
7029         {
7030           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7031             {
7032               if (unformat (i, "%U", unformat_sw_if_index, vam,
7033                             &rx_sw_if_index))
7034                 rx_sw_if_index_set = 1;
7035             }
7036           else
7037             break;
7038         }
7039       else if (unformat (i, "tx"))
7040         {
7041           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7042             {
7043               if (unformat (i, "%U", unformat_sw_if_index, vam,
7044                             &tx_sw_if_index))
7045                 tx_sw_if_index_set = 1;
7046             }
7047           else
7048             break;
7049         }
7050       else if (unformat (i, "del"))
7051         is_add = 0;
7052       else
7053         break;
7054     }
7055
7056   if (rx_sw_if_index_set == 0)
7057     {
7058       errmsg ("missing rx interface name or rx_sw_if_index\n");
7059       return -99;
7060     }
7061
7062   if (tx_sw_if_index_set == 0)
7063     {
7064       errmsg ("missing tx interface name or tx_sw_if_index\n");
7065       return -99;
7066     }
7067
7068   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7069
7070   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7071   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7072   mp->is_add = is_add;
7073
7074   S;
7075   W;
7076   /* NOTREACHED */
7077   return 0;
7078 }
7079
7080 static int
7081 api_trace_profile_add (vat_main_t * vam)
7082 {
7083   unformat_input_t *input = vam->input;
7084   vl_api_trace_profile_add_t *mp;
7085   f64 timeout;
7086   u32 id = 0;
7087   u32 trace_option_elts = 0;
7088   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7089   int has_pow_option = 0;
7090   int has_ppc_option = 0;
7091
7092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7095                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7096                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7097                     &node_id, &app_data))
7098         ;
7099       else if (unformat (input, "pow"))
7100         has_pow_option = 1;
7101       else if (unformat (input, "ppc encap"))
7102         has_ppc_option = PPC_ENCAP;
7103       else if (unformat (input, "ppc decap"))
7104         has_ppc_option = PPC_DECAP;
7105       else if (unformat (input, "ppc none"))
7106         has_ppc_option = PPC_NONE;
7107       else
7108         break;
7109     }
7110   M (TRACE_PROFILE_ADD, trace_profile_add);
7111   mp->id = htons (id);
7112   mp->trace_type = trace_type;
7113   mp->trace_num_elt = trace_option_elts;
7114   mp->trace_ppc = has_ppc_option;
7115   mp->trace_app_data = htonl (app_data);
7116   mp->pow_enable = has_pow_option;
7117   mp->trace_tsp = trace_tsp;
7118   mp->node_id = htonl (node_id);
7119
7120   S;
7121   W;
7122
7123   return (0);
7124
7125 }
7126
7127 static int
7128 api_trace_profile_apply (vat_main_t * vam)
7129 {
7130   unformat_input_t *input = vam->input;
7131   vl_api_trace_profile_apply_t *mp;
7132   f64 timeout;
7133   ip6_address_t addr;
7134   u32 mask_width = ~0;
7135   int is_add = 0;
7136   int is_pop = 0;
7137   int is_none = 0;
7138   u32 vrf_id = 0;
7139   u32 id = 0;
7140
7141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7142     {
7143       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7144         ;
7145       else if (unformat (input, "id %d", &id))
7146         ;
7147       else if (unformat (input, "vrf-id %d", &vrf_id))
7148         ;
7149       else if (unformat (input, "add"))
7150         is_add = 1;
7151       else if (unformat (input, "pop"))
7152         is_pop = 1;
7153       else if (unformat (input, "none"))
7154         is_none = 1;
7155       else
7156         break;
7157     }
7158
7159   if ((is_add + is_pop + is_none) != 1)
7160     {
7161       errmsg ("One of (add, pop, none) required");
7162       return -99;
7163     }
7164   if (mask_width == ~0)
7165     {
7166       errmsg ("<address>/<mask-width> required");
7167       return -99;
7168     }
7169   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7170   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7171   mp->id = htons (id);
7172   mp->prefix_length = htonl (mask_width);
7173   mp->vrf_id = htonl (vrf_id);
7174   if (is_add)
7175     mp->trace_op = IOAM_HBYH_ADD;
7176   else if (is_pop)
7177     mp->trace_op = IOAM_HBYH_POP;
7178   else
7179     mp->trace_op = IOAM_HBYH_MOD;
7180
7181   if (is_none)
7182     mp->enable = 0;
7183   else
7184     mp->enable = 1;
7185
7186   S;
7187   W;
7188
7189   return 0;
7190 }
7191
7192 static int
7193 api_trace_profile_del (vat_main_t * vam)
7194 {
7195   vl_api_trace_profile_del_t *mp;
7196   f64 timeout;
7197
7198   M (TRACE_PROFILE_DEL, trace_profile_del);
7199   S;
7200   W;
7201   return 0;
7202 }
7203
7204 static int
7205 api_sr_tunnel_add_del (vat_main_t * vam)
7206 {
7207   unformat_input_t *i = vam->input;
7208   vl_api_sr_tunnel_add_del_t *mp;
7209   f64 timeout;
7210   int is_del = 0;
7211   int pl_index;
7212   ip6_address_t src_address;
7213   int src_address_set = 0;
7214   ip6_address_t dst_address;
7215   u32 dst_mask_width;
7216   int dst_address_set = 0;
7217   u16 flags = 0;
7218   u32 rx_table_id = 0;
7219   u32 tx_table_id = 0;
7220   ip6_address_t *segments = 0;
7221   ip6_address_t *this_seg;
7222   ip6_address_t *tags = 0;
7223   ip6_address_t *this_tag;
7224   ip6_address_t next_address, tag;
7225   u8 *name = 0;
7226   u8 *policy_name = 0;
7227
7228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7229     {
7230       if (unformat (i, "del"))
7231         is_del = 1;
7232       else if (unformat (i, "name %s", &name))
7233         ;
7234       else if (unformat (i, "policy %s", &policy_name))
7235         ;
7236       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7237         ;
7238       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7239         ;
7240       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7241         src_address_set = 1;
7242       else if (unformat (i, "dst %U/%d",
7243                          unformat_ip6_address, &dst_address, &dst_mask_width))
7244         dst_address_set = 1;
7245       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7246         {
7247           vec_add2 (segments, this_seg, 1);
7248           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7249                        sizeof (*this_seg));
7250         }
7251       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7252         {
7253           vec_add2 (tags, this_tag, 1);
7254           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7255         }
7256       else if (unformat (i, "clean"))
7257         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7258       else if (unformat (i, "protected"))
7259         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7260       else if (unformat (i, "InPE %d", &pl_index))
7261         {
7262           if (pl_index <= 0 || pl_index > 4)
7263             {
7264             pl_index_range_error:
7265               errmsg ("pl index %d out of range\n", pl_index);
7266               return -99;
7267             }
7268           flags |=
7269             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7270         }
7271       else if (unformat (i, "EgPE %d", &pl_index))
7272         {
7273           if (pl_index <= 0 || pl_index > 4)
7274             goto pl_index_range_error;
7275           flags |=
7276             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7277         }
7278       else if (unformat (i, "OrgSrc %d", &pl_index))
7279         {
7280           if (pl_index <= 0 || pl_index > 4)
7281             goto pl_index_range_error;
7282           flags |=
7283             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7284         }
7285       else
7286         break;
7287     }
7288
7289   if (!src_address_set)
7290     {
7291       errmsg ("src address required\n");
7292       return -99;
7293     }
7294
7295   if (!dst_address_set)
7296     {
7297       errmsg ("dst address required\n");
7298       return -99;
7299     }
7300
7301   if (!segments)
7302     {
7303       errmsg ("at least one sr segment required\n");
7304       return -99;
7305     }
7306
7307   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7308       vec_len (segments) * sizeof (ip6_address_t)
7309       + vec_len (tags) * sizeof (ip6_address_t));
7310
7311   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7312   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7313   mp->dst_mask_width = dst_mask_width;
7314   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7315   mp->n_segments = vec_len (segments);
7316   mp->n_tags = vec_len (tags);
7317   mp->is_add = is_del == 0;
7318   clib_memcpy (mp->segs_and_tags, segments,
7319                vec_len (segments) * sizeof (ip6_address_t));
7320   clib_memcpy (mp->segs_and_tags +
7321                vec_len (segments) * sizeof (ip6_address_t), tags,
7322                vec_len (tags) * sizeof (ip6_address_t));
7323
7324   mp->outer_vrf_id = ntohl (rx_table_id);
7325   mp->inner_vrf_id = ntohl (tx_table_id);
7326   memcpy (mp->name, name, vec_len (name));
7327   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7328
7329   vec_free (segments);
7330   vec_free (tags);
7331
7332   S;
7333   W;
7334   /* NOTREACHED */
7335 }
7336
7337 static int
7338 api_sr_policy_add_del (vat_main_t * vam)
7339 {
7340   unformat_input_t *input = vam->input;
7341   vl_api_sr_policy_add_del_t *mp;
7342   f64 timeout;
7343   int is_del = 0;
7344   u8 *name = 0;
7345   u8 *tunnel_name = 0;
7346   u8 **tunnel_names = 0;
7347
7348   int name_set = 0;
7349   int tunnel_set = 0;
7350   int j = 0;
7351   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7352   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7353
7354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (input, "del"))
7357         is_del = 1;
7358       else if (unformat (input, "name %s", &name))
7359         name_set = 1;
7360       else if (unformat (input, "tunnel %s", &tunnel_name))
7361         {
7362           if (tunnel_name)
7363             {
7364               vec_add1 (tunnel_names, tunnel_name);
7365               /* For serializer:
7366                  - length = #bytes to store in serial vector
7367                  - +1 = byte to store that length
7368                */
7369               tunnel_names_length += (vec_len (tunnel_name) + 1);
7370               tunnel_set = 1;
7371               tunnel_name = 0;
7372             }
7373         }
7374       else
7375         break;
7376     }
7377
7378   if (!name_set)
7379     {
7380       errmsg ("policy name required\n");
7381       return -99;
7382     }
7383
7384   if ((!tunnel_set) && (!is_del))
7385     {
7386       errmsg ("tunnel name required\n");
7387       return -99;
7388     }
7389
7390   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7391
7392
7393
7394   mp->is_add = !is_del;
7395
7396   memcpy (mp->name, name, vec_len (name));
7397   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7398   u8 *serial_orig = 0;
7399   vec_validate (serial_orig, tunnel_names_length);
7400   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7401   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7402
7403   for (j = 0; j < vec_len (tunnel_names); j++)
7404     {
7405       tun_name_len = vec_len (tunnel_names[j]);
7406       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7407       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7408       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7409       serial_orig += tun_name_len;      // Advance past the copy
7410     }
7411   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7412
7413   vec_free (tunnel_names);
7414   vec_free (tunnel_name);
7415
7416   S;
7417   W;
7418   /* NOTREACHED */
7419 }
7420
7421 static int
7422 api_sr_multicast_map_add_del (vat_main_t * vam)
7423 {
7424   unformat_input_t *input = vam->input;
7425   vl_api_sr_multicast_map_add_del_t *mp;
7426   f64 timeout;
7427   int is_del = 0;
7428   ip6_address_t multicast_address;
7429   u8 *policy_name = 0;
7430   int multicast_address_set = 0;
7431
7432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7433     {
7434       if (unformat (input, "del"))
7435         is_del = 1;
7436       else
7437         if (unformat
7438             (input, "address %U", unformat_ip6_address, &multicast_address))
7439         multicast_address_set = 1;
7440       else if (unformat (input, "sr-policy %s", &policy_name))
7441         ;
7442       else
7443         break;
7444     }
7445
7446   if (!is_del && !policy_name)
7447     {
7448       errmsg ("sr-policy name required\n");
7449       return -99;
7450     }
7451
7452
7453   if (!multicast_address_set)
7454     {
7455       errmsg ("address required\n");
7456       return -99;
7457     }
7458
7459   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7460
7461   mp->is_add = !is_del;
7462   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7463   clib_memcpy (mp->multicast_address, &multicast_address,
7464                sizeof (mp->multicast_address));
7465
7466
7467   vec_free (policy_name);
7468
7469   S;
7470   W;
7471   /* NOTREACHED */
7472 }
7473
7474
7475 #define foreach_ip4_proto_field                 \
7476 _(src_address)                                  \
7477 _(dst_address)                                  \
7478 _(tos)                                          \
7479 _(length)                                       \
7480 _(fragment_id)                                  \
7481 _(ttl)                                          \
7482 _(protocol)                                     \
7483 _(checksum)
7484
7485 uword
7486 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7487 {
7488   u8 **maskp = va_arg (*args, u8 **);
7489   u8 *mask = 0;
7490   u8 found_something = 0;
7491   ip4_header_t *ip;
7492
7493 #define _(a) u8 a=0;
7494   foreach_ip4_proto_field;
7495 #undef _
7496   u8 version = 0;
7497   u8 hdr_length = 0;
7498
7499
7500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7501     {
7502       if (unformat (input, "version"))
7503         version = 1;
7504       else if (unformat (input, "hdr_length"))
7505         hdr_length = 1;
7506       else if (unformat (input, "src"))
7507         src_address = 1;
7508       else if (unformat (input, "dst"))
7509         dst_address = 1;
7510       else if (unformat (input, "proto"))
7511         protocol = 1;
7512
7513 #define _(a) else if (unformat (input, #a)) a=1;
7514       foreach_ip4_proto_field
7515 #undef _
7516         else
7517         break;
7518     }
7519
7520 #define _(a) found_something += a;
7521   foreach_ip4_proto_field;
7522 #undef _
7523
7524   if (found_something == 0)
7525     return 0;
7526
7527   vec_validate (mask, sizeof (*ip) - 1);
7528
7529   ip = (ip4_header_t *) mask;
7530
7531 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7532   foreach_ip4_proto_field;
7533 #undef _
7534
7535   ip->ip_version_and_header_length = 0;
7536
7537   if (version)
7538     ip->ip_version_and_header_length |= 0xF0;
7539
7540   if (hdr_length)
7541     ip->ip_version_and_header_length |= 0x0F;
7542
7543   *maskp = mask;
7544   return 1;
7545 }
7546
7547 #define foreach_ip6_proto_field                 \
7548 _(src_address)                                  \
7549 _(dst_address)                                  \
7550 _(payload_length)                               \
7551 _(hop_limit)                                    \
7552 _(protocol)
7553
7554 uword
7555 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7556 {
7557   u8 **maskp = va_arg (*args, u8 **);
7558   u8 *mask = 0;
7559   u8 found_something = 0;
7560   ip6_header_t *ip;
7561   u32 ip_version_traffic_class_and_flow_label;
7562
7563 #define _(a) u8 a=0;
7564   foreach_ip6_proto_field;
7565 #undef _
7566   u8 version = 0;
7567   u8 traffic_class = 0;
7568   u8 flow_label = 0;
7569
7570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7571     {
7572       if (unformat (input, "version"))
7573         version = 1;
7574       else if (unformat (input, "traffic-class"))
7575         traffic_class = 1;
7576       else if (unformat (input, "flow-label"))
7577         flow_label = 1;
7578       else if (unformat (input, "src"))
7579         src_address = 1;
7580       else if (unformat (input, "dst"))
7581         dst_address = 1;
7582       else if (unformat (input, "proto"))
7583         protocol = 1;
7584
7585 #define _(a) else if (unformat (input, #a)) a=1;
7586       foreach_ip6_proto_field
7587 #undef _
7588         else
7589         break;
7590     }
7591
7592 #define _(a) found_something += a;
7593   foreach_ip6_proto_field;
7594 #undef _
7595
7596   if (found_something == 0)
7597     return 0;
7598
7599   vec_validate (mask, sizeof (*ip) - 1);
7600
7601   ip = (ip6_header_t *) mask;
7602
7603 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7604   foreach_ip6_proto_field;
7605 #undef _
7606
7607   ip_version_traffic_class_and_flow_label = 0;
7608
7609   if (version)
7610     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7611
7612   if (traffic_class)
7613     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7614
7615   if (flow_label)
7616     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7617
7618   ip->ip_version_traffic_class_and_flow_label =
7619     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7620
7621   *maskp = mask;
7622   return 1;
7623 }
7624
7625 uword
7626 unformat_l3_mask (unformat_input_t * input, va_list * args)
7627 {
7628   u8 **maskp = va_arg (*args, u8 **);
7629
7630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7631     {
7632       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7633         return 1;
7634       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7635         return 1;
7636       else
7637         break;
7638     }
7639   return 0;
7640 }
7641
7642 uword
7643 unformat_l2_mask (unformat_input_t * input, va_list * args)
7644 {
7645   u8 **maskp = va_arg (*args, u8 **);
7646   u8 *mask = 0;
7647   u8 src = 0;
7648   u8 dst = 0;
7649   u8 proto = 0;
7650   u8 tag1 = 0;
7651   u8 tag2 = 0;
7652   u8 ignore_tag1 = 0;
7653   u8 ignore_tag2 = 0;
7654   u8 cos1 = 0;
7655   u8 cos2 = 0;
7656   u8 dot1q = 0;
7657   u8 dot1ad = 0;
7658   int len = 14;
7659
7660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7661     {
7662       if (unformat (input, "src"))
7663         src = 1;
7664       else if (unformat (input, "dst"))
7665         dst = 1;
7666       else if (unformat (input, "proto"))
7667         proto = 1;
7668       else if (unformat (input, "tag1"))
7669         tag1 = 1;
7670       else if (unformat (input, "tag2"))
7671         tag2 = 1;
7672       else if (unformat (input, "ignore-tag1"))
7673         ignore_tag1 = 1;
7674       else if (unformat (input, "ignore-tag2"))
7675         ignore_tag2 = 1;
7676       else if (unformat (input, "cos1"))
7677         cos1 = 1;
7678       else if (unformat (input, "cos2"))
7679         cos2 = 1;
7680       else if (unformat (input, "dot1q"))
7681         dot1q = 1;
7682       else if (unformat (input, "dot1ad"))
7683         dot1ad = 1;
7684       else
7685         break;
7686     }
7687   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7688        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7689     return 0;
7690
7691   if (tag1 || ignore_tag1 || cos1 || dot1q)
7692     len = 18;
7693   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7694     len = 22;
7695
7696   vec_validate (mask, len - 1);
7697
7698   if (dst)
7699     memset (mask, 0xff, 6);
7700
7701   if (src)
7702     memset (mask + 6, 0xff, 6);
7703
7704   if (tag2 || dot1ad)
7705     {
7706       /* inner vlan tag */
7707       if (tag2)
7708         {
7709           mask[19] = 0xff;
7710           mask[18] = 0x0f;
7711         }
7712       if (cos2)
7713         mask[18] |= 0xe0;
7714       if (proto)
7715         mask[21] = mask[20] = 0xff;
7716       if (tag1)
7717         {
7718           mask[15] = 0xff;
7719           mask[14] = 0x0f;
7720         }
7721       if (cos1)
7722         mask[14] |= 0xe0;
7723       *maskp = mask;
7724       return 1;
7725     }
7726   if (tag1 | dot1q)
7727     {
7728       if (tag1)
7729         {
7730           mask[15] = 0xff;
7731           mask[14] = 0x0f;
7732         }
7733       if (cos1)
7734         mask[14] |= 0xe0;
7735       if (proto)
7736         mask[16] = mask[17] = 0xff;
7737
7738       *maskp = mask;
7739       return 1;
7740     }
7741   if (cos2)
7742     mask[18] |= 0xe0;
7743   if (cos1)
7744     mask[14] |= 0xe0;
7745   if (proto)
7746     mask[12] = mask[13] = 0xff;
7747
7748   *maskp = mask;
7749   return 1;
7750 }
7751
7752 uword
7753 unformat_classify_mask (unformat_input_t * input, va_list * args)
7754 {
7755   u8 **maskp = va_arg (*args, u8 **);
7756   u32 *skipp = va_arg (*args, u32 *);
7757   u32 *matchp = va_arg (*args, u32 *);
7758   u32 match;
7759   u8 *mask = 0;
7760   u8 *l2 = 0;
7761   u8 *l3 = 0;
7762   int i;
7763
7764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7765     {
7766       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7767         ;
7768       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7769         ;
7770       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7771         ;
7772       else
7773         break;
7774     }
7775
7776   if (mask || l2 || l3)
7777     {
7778       if (l2 || l3)
7779         {
7780           /* "With a free Ethernet header in every package" */
7781           if (l2 == 0)
7782             vec_validate (l2, 13);
7783           mask = l2;
7784           if (vec_len (l3))
7785             {
7786               vec_append (mask, l3);
7787               vec_free (l3);
7788             }
7789         }
7790
7791       /* Scan forward looking for the first significant mask octet */
7792       for (i = 0; i < vec_len (mask); i++)
7793         if (mask[i])
7794           break;
7795
7796       /* compute (skip, match) params */
7797       *skipp = i / sizeof (u32x4);
7798       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7799
7800       /* Pad mask to an even multiple of the vector size */
7801       while (vec_len (mask) % sizeof (u32x4))
7802         vec_add1 (mask, 0);
7803
7804       match = vec_len (mask) / sizeof (u32x4);
7805
7806       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7807         {
7808           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7809           if (*tmp || *(tmp + 1))
7810             break;
7811           match--;
7812         }
7813       if (match == 0)
7814         clib_warning ("BUG: match 0");
7815
7816       _vec_len (mask) = match * sizeof (u32x4);
7817
7818       *matchp = match;
7819       *maskp = mask;
7820
7821       return 1;
7822     }
7823
7824   return 0;
7825 }
7826
7827 #define foreach_l2_next                         \
7828 _(drop, DROP)                                   \
7829 _(ethernet, ETHERNET_INPUT)                     \
7830 _(ip4, IP4_INPUT)                               \
7831 _(ip6, IP6_INPUT)
7832
7833 uword
7834 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7835 {
7836   u32 *miss_next_indexp = va_arg (*args, u32 *);
7837   u32 next_index = 0;
7838   u32 tmp;
7839
7840 #define _(n,N) \
7841   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7842   foreach_l2_next;
7843 #undef _
7844
7845   if (unformat (input, "%d", &tmp))
7846     {
7847       next_index = tmp;
7848       goto out;
7849     }
7850
7851   return 0;
7852
7853 out:
7854   *miss_next_indexp = next_index;
7855   return 1;
7856 }
7857
7858 #define foreach_ip_next                         \
7859 _(miss, MISS)                                   \
7860 _(drop, DROP)                                   \
7861 _(local, LOCAL)                                 \
7862 _(rewrite, REWRITE)
7863
7864 uword
7865 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7866 {
7867   u32 *miss_next_indexp = va_arg (*args, u32 *);
7868   u32 next_index = 0;
7869   u32 tmp;
7870
7871 #define _(n,N) \
7872   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7873   foreach_ip_next;
7874 #undef _
7875
7876   if (unformat (input, "%d", &tmp))
7877     {
7878       next_index = tmp;
7879       goto out;
7880     }
7881
7882   return 0;
7883
7884 out:
7885   *miss_next_indexp = next_index;
7886   return 1;
7887 }
7888
7889 #define foreach_acl_next                        \
7890 _(deny, DENY)
7891
7892 uword
7893 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7894 {
7895   u32 *miss_next_indexp = va_arg (*args, u32 *);
7896   u32 next_index = 0;
7897   u32 tmp;
7898
7899 #define _(n,N) \
7900   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7901   foreach_acl_next;
7902 #undef _
7903
7904   if (unformat (input, "permit"))
7905     {
7906       next_index = ~0;
7907       goto out;
7908     }
7909   else if (unformat (input, "%d", &tmp))
7910     {
7911       next_index = tmp;
7912       goto out;
7913     }
7914
7915   return 0;
7916
7917 out:
7918   *miss_next_indexp = next_index;
7919   return 1;
7920 }
7921
7922 uword
7923 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7924 {
7925   u32 *r = va_arg (*args, u32 *);
7926
7927   if (unformat (input, "conform-color"))
7928     *r = POLICE_CONFORM;
7929   else if (unformat (input, "exceed-color"))
7930     *r = POLICE_EXCEED;
7931   else
7932     return 0;
7933
7934   return 1;
7935 }
7936
7937 static int
7938 api_classify_add_del_table (vat_main_t * vam)
7939 {
7940   unformat_input_t *i = vam->input;
7941   vl_api_classify_add_del_table_t *mp;
7942
7943   u32 nbuckets = 2;
7944   u32 skip = ~0;
7945   u32 match = ~0;
7946   int is_add = 1;
7947   u32 table_index = ~0;
7948   u32 next_table_index = ~0;
7949   u32 miss_next_index = ~0;
7950   u32 memory_size = 32 << 20;
7951   u8 *mask = 0;
7952   f64 timeout;
7953
7954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7955     {
7956       if (unformat (i, "del"))
7957         is_add = 0;
7958       else if (unformat (i, "buckets %d", &nbuckets))
7959         ;
7960       else if (unformat (i, "memory_size %d", &memory_size))
7961         ;
7962       else if (unformat (i, "skip %d", &skip))
7963         ;
7964       else if (unformat (i, "match %d", &match))
7965         ;
7966       else if (unformat (i, "table %d", &table_index))
7967         ;
7968       else if (unformat (i, "mask %U", unformat_classify_mask,
7969                          &mask, &skip, &match))
7970         ;
7971       else if (unformat (i, "next-table %d", &next_table_index))
7972         ;
7973       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7974                          &miss_next_index))
7975         ;
7976       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7977                          &miss_next_index))
7978         ;
7979       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7980                          &miss_next_index))
7981         ;
7982       else
7983         break;
7984     }
7985
7986   if (is_add && mask == 0)
7987     {
7988       errmsg ("Mask required\n");
7989       return -99;
7990     }
7991
7992   if (is_add && skip == ~0)
7993     {
7994       errmsg ("skip count required\n");
7995       return -99;
7996     }
7997
7998   if (is_add && match == ~0)
7999     {
8000       errmsg ("match count required\n");
8001       return -99;
8002     }
8003
8004   if (!is_add && table_index == ~0)
8005     {
8006       errmsg ("table index required for delete\n");
8007       return -99;
8008     }
8009
8010   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8011
8012   mp->is_add = is_add;
8013   mp->table_index = ntohl (table_index);
8014   mp->nbuckets = ntohl (nbuckets);
8015   mp->memory_size = ntohl (memory_size);
8016   mp->skip_n_vectors = ntohl (skip);
8017   mp->match_n_vectors = ntohl (match);
8018   mp->next_table_index = ntohl (next_table_index);
8019   mp->miss_next_index = ntohl (miss_next_index);
8020   clib_memcpy (mp->mask, mask, vec_len (mask));
8021
8022   vec_free (mask);
8023
8024   S;
8025   W;
8026   /* NOTREACHED */
8027 }
8028
8029 uword
8030 unformat_ip4_match (unformat_input_t * input, va_list * args)
8031 {
8032   u8 **matchp = va_arg (*args, u8 **);
8033   u8 *match = 0;
8034   ip4_header_t *ip;
8035   int version = 0;
8036   u32 version_val;
8037   int hdr_length = 0;
8038   u32 hdr_length_val;
8039   int src = 0, dst = 0;
8040   ip4_address_t src_val, dst_val;
8041   int proto = 0;
8042   u32 proto_val;
8043   int tos = 0;
8044   u32 tos_val;
8045   int length = 0;
8046   u32 length_val;
8047   int fragment_id = 0;
8048   u32 fragment_id_val;
8049   int ttl = 0;
8050   int ttl_val;
8051   int checksum = 0;
8052   u32 checksum_val;
8053
8054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8055     {
8056       if (unformat (input, "version %d", &version_val))
8057         version = 1;
8058       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8059         hdr_length = 1;
8060       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8061         src = 1;
8062       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8063         dst = 1;
8064       else if (unformat (input, "proto %d", &proto_val))
8065         proto = 1;
8066       else if (unformat (input, "tos %d", &tos_val))
8067         tos = 1;
8068       else if (unformat (input, "length %d", &length_val))
8069         length = 1;
8070       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8071         fragment_id = 1;
8072       else if (unformat (input, "ttl %d", &ttl_val))
8073         ttl = 1;
8074       else if (unformat (input, "checksum %d", &checksum_val))
8075         checksum = 1;
8076       else
8077         break;
8078     }
8079
8080   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8081       + ttl + checksum == 0)
8082     return 0;
8083
8084   /*
8085    * Aligned because we use the real comparison functions
8086    */
8087   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8088
8089   ip = (ip4_header_t *) match;
8090
8091   /* These are realistically matched in practice */
8092   if (src)
8093     ip->src_address.as_u32 = src_val.as_u32;
8094
8095   if (dst)
8096     ip->dst_address.as_u32 = dst_val.as_u32;
8097
8098   if (proto)
8099     ip->protocol = proto_val;
8100
8101
8102   /* These are not, but they're included for completeness */
8103   if (version)
8104     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8105
8106   if (hdr_length)
8107     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8108
8109   if (tos)
8110     ip->tos = tos_val;
8111
8112   if (length)
8113     ip->length = length_val;
8114
8115   if (ttl)
8116     ip->ttl = ttl_val;
8117
8118   if (checksum)
8119     ip->checksum = checksum_val;
8120
8121   *matchp = match;
8122   return 1;
8123 }
8124
8125 uword
8126 unformat_ip6_match (unformat_input_t * input, va_list * args)
8127 {
8128   u8 **matchp = va_arg (*args, u8 **);
8129   u8 *match = 0;
8130   ip6_header_t *ip;
8131   int version = 0;
8132   u32 version_val;
8133   u8 traffic_class = 0;
8134   u32 traffic_class_val = 0;
8135   u8 flow_label = 0;
8136   u8 flow_label_val;
8137   int src = 0, dst = 0;
8138   ip6_address_t src_val, dst_val;
8139   int proto = 0;
8140   u32 proto_val;
8141   int payload_length = 0;
8142   u32 payload_length_val;
8143   int hop_limit = 0;
8144   int hop_limit_val;
8145   u32 ip_version_traffic_class_and_flow_label;
8146
8147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8148     {
8149       if (unformat (input, "version %d", &version_val))
8150         version = 1;
8151       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8152         traffic_class = 1;
8153       else if (unformat (input, "flow_label %d", &flow_label_val))
8154         flow_label = 1;
8155       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8156         src = 1;
8157       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8158         dst = 1;
8159       else if (unformat (input, "proto %d", &proto_val))
8160         proto = 1;
8161       else if (unformat (input, "payload_length %d", &payload_length_val))
8162         payload_length = 1;
8163       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8164         hop_limit = 1;
8165       else
8166         break;
8167     }
8168
8169   if (version + traffic_class + flow_label + src + dst + proto +
8170       payload_length + hop_limit == 0)
8171     return 0;
8172
8173   /*
8174    * Aligned because we use the real comparison functions
8175    */
8176   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8177
8178   ip = (ip6_header_t *) match;
8179
8180   if (src)
8181     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8182
8183   if (dst)
8184     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8185
8186   if (proto)
8187     ip->protocol = proto_val;
8188
8189   ip_version_traffic_class_and_flow_label = 0;
8190
8191   if (version)
8192     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8193
8194   if (traffic_class)
8195     ip_version_traffic_class_and_flow_label |=
8196       (traffic_class_val & 0xFF) << 20;
8197
8198   if (flow_label)
8199     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8200
8201   ip->ip_version_traffic_class_and_flow_label =
8202     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8203
8204   if (payload_length)
8205     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8206
8207   if (hop_limit)
8208     ip->hop_limit = hop_limit_val;
8209
8210   *matchp = match;
8211   return 1;
8212 }
8213
8214 uword
8215 unformat_l3_match (unformat_input_t * input, va_list * args)
8216 {
8217   u8 **matchp = va_arg (*args, u8 **);
8218
8219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8220     {
8221       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8222         return 1;
8223       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8224         return 1;
8225       else
8226         break;
8227     }
8228   return 0;
8229 }
8230
8231 uword
8232 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8233 {
8234   u8 *tagp = va_arg (*args, u8 *);
8235   u32 tag;
8236
8237   if (unformat (input, "%d", &tag))
8238     {
8239       tagp[0] = (tag >> 8) & 0x0F;
8240       tagp[1] = tag & 0xFF;
8241       return 1;
8242     }
8243
8244   return 0;
8245 }
8246
8247 uword
8248 unformat_l2_match (unformat_input_t * input, va_list * args)
8249 {
8250   u8 **matchp = va_arg (*args, u8 **);
8251   u8 *match = 0;
8252   u8 src = 0;
8253   u8 src_val[6];
8254   u8 dst = 0;
8255   u8 dst_val[6];
8256   u8 proto = 0;
8257   u16 proto_val;
8258   u8 tag1 = 0;
8259   u8 tag1_val[2];
8260   u8 tag2 = 0;
8261   u8 tag2_val[2];
8262   int len = 14;
8263   u8 ignore_tag1 = 0;
8264   u8 ignore_tag2 = 0;
8265   u8 cos1 = 0;
8266   u8 cos2 = 0;
8267   u32 cos1_val = 0;
8268   u32 cos2_val = 0;
8269
8270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8273         src = 1;
8274       else
8275         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8276         dst = 1;
8277       else if (unformat (input, "proto %U",
8278                          unformat_ethernet_type_host_byte_order, &proto_val))
8279         proto = 1;
8280       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8281         tag1 = 1;
8282       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8283         tag2 = 1;
8284       else if (unformat (input, "ignore-tag1"))
8285         ignore_tag1 = 1;
8286       else if (unformat (input, "ignore-tag2"))
8287         ignore_tag2 = 1;
8288       else if (unformat (input, "cos1 %d", &cos1_val))
8289         cos1 = 1;
8290       else if (unformat (input, "cos2 %d", &cos2_val))
8291         cos2 = 1;
8292       else
8293         break;
8294     }
8295   if ((src + dst + proto + tag1 + tag2 +
8296        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8297     return 0;
8298
8299   if (tag1 || ignore_tag1 || cos1)
8300     len = 18;
8301   if (tag2 || ignore_tag2 || cos2)
8302     len = 22;
8303
8304   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8305
8306   if (dst)
8307     clib_memcpy (match, dst_val, 6);
8308
8309   if (src)
8310     clib_memcpy (match + 6, src_val, 6);
8311
8312   if (tag2)
8313     {
8314       /* inner vlan tag */
8315       match[19] = tag2_val[1];
8316       match[18] = tag2_val[0];
8317       if (cos2)
8318         match[18] |= (cos2_val & 0x7) << 5;
8319       if (proto)
8320         {
8321           match[21] = proto_val & 0xff;
8322           match[20] = proto_val >> 8;
8323         }
8324       if (tag1)
8325         {
8326           match[15] = tag1_val[1];
8327           match[14] = tag1_val[0];
8328         }
8329       if (cos1)
8330         match[14] |= (cos1_val & 0x7) << 5;
8331       *matchp = match;
8332       return 1;
8333     }
8334   if (tag1)
8335     {
8336       match[15] = tag1_val[1];
8337       match[14] = tag1_val[0];
8338       if (proto)
8339         {
8340           match[17] = proto_val & 0xff;
8341           match[16] = proto_val >> 8;
8342         }
8343       if (cos1)
8344         match[14] |= (cos1_val & 0x7) << 5;
8345
8346       *matchp = match;
8347       return 1;
8348     }
8349   if (cos2)
8350     match[18] |= (cos2_val & 0x7) << 5;
8351   if (cos1)
8352     match[14] |= (cos1_val & 0x7) << 5;
8353   if (proto)
8354     {
8355       match[13] = proto_val & 0xff;
8356       match[12] = proto_val >> 8;
8357     }
8358
8359   *matchp = match;
8360   return 1;
8361 }
8362
8363
8364 uword
8365 unformat_classify_match (unformat_input_t * input, va_list * args)
8366 {
8367   u8 **matchp = va_arg (*args, u8 **);
8368   u32 skip_n_vectors = va_arg (*args, u32);
8369   u32 match_n_vectors = va_arg (*args, u32);
8370
8371   u8 *match = 0;
8372   u8 *l2 = 0;
8373   u8 *l3 = 0;
8374
8375   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8376     {
8377       if (unformat (input, "hex %U", unformat_hex_string, &match))
8378         ;
8379       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8380         ;
8381       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8382         ;
8383       else
8384         break;
8385     }
8386
8387   if (match || l2 || l3)
8388     {
8389       if (l2 || l3)
8390         {
8391           /* "Win a free Ethernet header in every packet" */
8392           if (l2 == 0)
8393             vec_validate_aligned (l2, 13, sizeof (u32x4));
8394           match = l2;
8395           if (vec_len (l3))
8396             {
8397               vec_append_aligned (match, l3, sizeof (u32x4));
8398               vec_free (l3);
8399             }
8400         }
8401
8402       /* Make sure the vector is big enough even if key is all 0's */
8403       vec_validate_aligned
8404         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8405          sizeof (u32x4));
8406
8407       /* Set size, include skipped vectors */
8408       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8409
8410       *matchp = match;
8411
8412       return 1;
8413     }
8414
8415   return 0;
8416 }
8417
8418 static int
8419 api_classify_add_del_session (vat_main_t * vam)
8420 {
8421   unformat_input_t *i = vam->input;
8422   vl_api_classify_add_del_session_t *mp;
8423   int is_add = 1;
8424   u32 table_index = ~0;
8425   u32 hit_next_index = ~0;
8426   u32 opaque_index = ~0;
8427   u8 *match = 0;
8428   i32 advance = 0;
8429   f64 timeout;
8430   u32 skip_n_vectors = 0;
8431   u32 match_n_vectors = 0;
8432
8433   /*
8434    * Warning: you have to supply skip_n and match_n
8435    * because the API client cant simply look at the classify
8436    * table object.
8437    */
8438
8439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (i, "del"))
8442         is_add = 0;
8443       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8444                          &hit_next_index))
8445         ;
8446       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8447                          &hit_next_index))
8448         ;
8449       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8450                          &hit_next_index))
8451         ;
8452       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8453         ;
8454       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8455         ;
8456       else if (unformat (i, "opaque-index %d", &opaque_index))
8457         ;
8458       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8459         ;
8460       else if (unformat (i, "match_n %d", &match_n_vectors))
8461         ;
8462       else if (unformat (i, "match %U", unformat_classify_match,
8463                          &match, skip_n_vectors, match_n_vectors))
8464         ;
8465       else if (unformat (i, "advance %d", &advance))
8466         ;
8467       else if (unformat (i, "table-index %d", &table_index))
8468         ;
8469       else
8470         break;
8471     }
8472
8473   if (table_index == ~0)
8474     {
8475       errmsg ("Table index required\n");
8476       return -99;
8477     }
8478
8479   if (is_add && match == 0)
8480     {
8481       errmsg ("Match value required\n");
8482       return -99;
8483     }
8484
8485   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8486
8487   mp->is_add = is_add;
8488   mp->table_index = ntohl (table_index);
8489   mp->hit_next_index = ntohl (hit_next_index);
8490   mp->opaque_index = ntohl (opaque_index);
8491   mp->advance = ntohl (advance);
8492   clib_memcpy (mp->match, match, vec_len (match));
8493   vec_free (match);
8494
8495   S;
8496   W;
8497   /* NOTREACHED */
8498 }
8499
8500 static int
8501 api_classify_set_interface_ip_table (vat_main_t * vam)
8502 {
8503   unformat_input_t *i = vam->input;
8504   vl_api_classify_set_interface_ip_table_t *mp;
8505   f64 timeout;
8506   u32 sw_if_index;
8507   int sw_if_index_set;
8508   u32 table_index = ~0;
8509   u8 is_ipv6 = 0;
8510
8511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8512     {
8513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8514         sw_if_index_set = 1;
8515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8516         sw_if_index_set = 1;
8517       else if (unformat (i, "table %d", &table_index))
8518         ;
8519       else
8520         {
8521           clib_warning ("parse error '%U'", format_unformat_error, i);
8522           return -99;
8523         }
8524     }
8525
8526   if (sw_if_index_set == 0)
8527     {
8528       errmsg ("missing interface name or sw_if_index\n");
8529       return -99;
8530     }
8531
8532
8533   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8534
8535   mp->sw_if_index = ntohl (sw_if_index);
8536   mp->table_index = ntohl (table_index);
8537   mp->is_ipv6 = is_ipv6;
8538
8539   S;
8540   W;
8541   /* NOTREACHED */
8542   return 0;
8543 }
8544
8545 static int
8546 api_classify_set_interface_l2_tables (vat_main_t * vam)
8547 {
8548   unformat_input_t *i = vam->input;
8549   vl_api_classify_set_interface_l2_tables_t *mp;
8550   f64 timeout;
8551   u32 sw_if_index;
8552   int sw_if_index_set;
8553   u32 ip4_table_index = ~0;
8554   u32 ip6_table_index = ~0;
8555   u32 other_table_index = ~0;
8556
8557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8558     {
8559       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8560         sw_if_index_set = 1;
8561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8562         sw_if_index_set = 1;
8563       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8564         ;
8565       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8566         ;
8567       else if (unformat (i, "other-table %d", &other_table_index))
8568         ;
8569       else
8570         {
8571           clib_warning ("parse error '%U'", format_unformat_error, i);
8572           return -99;
8573         }
8574     }
8575
8576   if (sw_if_index_set == 0)
8577     {
8578       errmsg ("missing interface name or sw_if_index\n");
8579       return -99;
8580     }
8581
8582
8583   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8584
8585   mp->sw_if_index = ntohl (sw_if_index);
8586   mp->ip4_table_index = ntohl (ip4_table_index);
8587   mp->ip6_table_index = ntohl (ip6_table_index);
8588   mp->other_table_index = ntohl (other_table_index);
8589
8590
8591   S;
8592   W;
8593   /* NOTREACHED */
8594   return 0;
8595 }
8596
8597 static int
8598 api_ipfix_enable (vat_main_t * vam)
8599 {
8600   unformat_input_t *i = vam->input;
8601   vl_api_ipfix_enable_t *mp;
8602   ip4_address_t collector_address;
8603   u8 collector_address_set = 0;
8604   u32 collector_port = ~0;
8605   ip4_address_t src_address;
8606   u8 src_address_set = 0;
8607   u32 vrf_id = ~0;
8608   u32 path_mtu = ~0;
8609   u32 template_interval = ~0;
8610   f64 timeout;
8611
8612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8613     {
8614       if (unformat (i, "collector_address %U", unformat_ip4_address,
8615                     &collector_address))
8616         collector_address_set = 1;
8617       else if (unformat (i, "collector_port %d", &collector_port))
8618         ;
8619       else if (unformat (i, "src_address %U", unformat_ip4_address,
8620                          &src_address))
8621         src_address_set = 1;
8622       else if (unformat (i, "vrf_id %d", &vrf_id))
8623         ;
8624       else if (unformat (i, "path_mtu %d", &path_mtu))
8625         ;
8626       else if (unformat (i, "template_interval %d", &template_interval))
8627         ;
8628       else
8629         break;
8630     }
8631
8632   if (collector_address_set == 0)
8633     {
8634       errmsg ("collector_address required\n");
8635       return -99;
8636     }
8637
8638   if (src_address_set == 0)
8639     {
8640       errmsg ("src_address required\n");
8641       return -99;
8642     }
8643
8644   M (IPFIX_ENABLE, ipfix_enable);
8645
8646   memcpy (mp->collector_address, collector_address.data,
8647           sizeof (collector_address.data));
8648   mp->collector_port = htons ((u16) collector_port);
8649   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8650   mp->vrf_id = htonl (vrf_id);
8651   mp->path_mtu = htonl (path_mtu);
8652   mp->template_interval = htonl (template_interval);
8653
8654   S;
8655   W;
8656   /* NOTREACHED */
8657 }
8658
8659 static int
8660 api_get_node_index (vat_main_t * vam)
8661 {
8662   unformat_input_t *i = vam->input;
8663   vl_api_get_node_index_t *mp;
8664   f64 timeout;
8665   u8 *name = 0;
8666
8667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8668     {
8669       if (unformat (i, "node %s", &name))
8670         ;
8671       else
8672         break;
8673     }
8674   if (name == 0)
8675     {
8676       errmsg ("node name required\n");
8677       return -99;
8678     }
8679   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8680     {
8681       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8682       return -99;
8683     }
8684
8685   M (GET_NODE_INDEX, get_node_index);
8686   clib_memcpy (mp->node_name, name, vec_len (name));
8687   vec_free (name);
8688
8689   S;
8690   W;
8691   /* NOTREACHED */
8692   return 0;
8693 }
8694
8695 static int
8696 api_get_next_index (vat_main_t * vam)
8697 {
8698   unformat_input_t *i = vam->input;
8699   vl_api_get_next_index_t *mp;
8700   f64 timeout;
8701   u8 *node_name = 0, *next_node_name = 0;
8702
8703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8704     {
8705       if (unformat (i, "node-name %s", &node_name))
8706         ;
8707       else if (unformat (i, "next-node-name %s", &next_node_name))
8708         break;
8709     }
8710
8711   if (node_name == 0)
8712     {
8713       errmsg ("node name required\n");
8714       return -99;
8715     }
8716   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8717     {
8718       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8719       return -99;
8720     }
8721
8722   if (next_node_name == 0)
8723     {
8724       errmsg ("next node name required\n");
8725       return -99;
8726     }
8727   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8728     {
8729       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8730       return -99;
8731     }
8732
8733   M (GET_NEXT_INDEX, get_next_index);
8734   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8735   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8736   vec_free (node_name);
8737   vec_free (next_node_name);
8738
8739   S;
8740   W;
8741   /* NOTREACHED */
8742   return 0;
8743 }
8744
8745 static int
8746 api_add_node_next (vat_main_t * vam)
8747 {
8748   unformat_input_t *i = vam->input;
8749   vl_api_add_node_next_t *mp;
8750   f64 timeout;
8751   u8 *name = 0;
8752   u8 *next = 0;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "node %s", &name))
8757         ;
8758       else if (unformat (i, "next %s", &next))
8759         ;
8760       else
8761         break;
8762     }
8763   if (name == 0)
8764     {
8765       errmsg ("node name required\n");
8766       return -99;
8767     }
8768   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8769     {
8770       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8771       return -99;
8772     }
8773   if (next == 0)
8774     {
8775       errmsg ("next node required\n");
8776       return -99;
8777     }
8778   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8779     {
8780       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8781       return -99;
8782     }
8783
8784   M (ADD_NODE_NEXT, add_node_next);
8785   clib_memcpy (mp->node_name, name, vec_len (name));
8786   clib_memcpy (mp->next_name, next, vec_len (next));
8787   vec_free (name);
8788   vec_free (next);
8789
8790   S;
8791   W;
8792   /* NOTREACHED */
8793   return 0;
8794 }
8795
8796 static int
8797 api_l2tpv3_create_tunnel (vat_main_t * vam)
8798 {
8799   unformat_input_t *i = vam->input;
8800   ip6_address_t client_address, our_address;
8801   int client_address_set = 0;
8802   int our_address_set = 0;
8803   u32 local_session_id = 0;
8804   u32 remote_session_id = 0;
8805   u64 local_cookie = 0;
8806   u64 remote_cookie = 0;
8807   u8 l2_sublayer_present = 0;
8808   vl_api_l2tpv3_create_tunnel_t *mp;
8809   f64 timeout;
8810
8811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8812     {
8813       if (unformat (i, "client_address %U", unformat_ip6_address,
8814                     &client_address))
8815         client_address_set = 1;
8816       else if (unformat (i, "our_address %U", unformat_ip6_address,
8817                          &our_address))
8818         our_address_set = 1;
8819       else if (unformat (i, "local_session_id %d", &local_session_id))
8820         ;
8821       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8822         ;
8823       else if (unformat (i, "local_cookie %lld", &local_cookie))
8824         ;
8825       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8826         ;
8827       else if (unformat (i, "l2-sublayer-present"))
8828         l2_sublayer_present = 1;
8829       else
8830         break;
8831     }
8832
8833   if (client_address_set == 0)
8834     {
8835       errmsg ("client_address required\n");
8836       return -99;
8837     }
8838
8839   if (our_address_set == 0)
8840     {
8841       errmsg ("our_address required\n");
8842       return -99;
8843     }
8844
8845   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8846
8847   clib_memcpy (mp->client_address, client_address.as_u8,
8848                sizeof (mp->client_address));
8849
8850   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8851
8852   mp->local_session_id = ntohl (local_session_id);
8853   mp->remote_session_id = ntohl (remote_session_id);
8854   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8855   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8856   mp->l2_sublayer_present = l2_sublayer_present;
8857   mp->is_ipv6 = 1;
8858
8859   S;
8860   W;
8861   /* NOTREACHED */
8862   return 0;
8863 }
8864
8865 static int
8866 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8867 {
8868   unformat_input_t *i = vam->input;
8869   u32 sw_if_index;
8870   u8 sw_if_index_set = 0;
8871   u64 new_local_cookie = 0;
8872   u64 new_remote_cookie = 0;
8873   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8874   f64 timeout;
8875
8876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8877     {
8878       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8879         sw_if_index_set = 1;
8880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8881         sw_if_index_set = 1;
8882       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8883         ;
8884       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8885         ;
8886       else
8887         break;
8888     }
8889
8890   if (sw_if_index_set == 0)
8891     {
8892       errmsg ("missing interface name or sw_if_index\n");
8893       return -99;
8894     }
8895
8896   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8897
8898   mp->sw_if_index = ntohl (sw_if_index);
8899   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8900   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8901
8902   S;
8903   W;
8904   /* NOTREACHED */
8905   return 0;
8906 }
8907
8908 static int
8909 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8910 {
8911   unformat_input_t *i = vam->input;
8912   vl_api_l2tpv3_interface_enable_disable_t *mp;
8913   f64 timeout;
8914   u32 sw_if_index;
8915   u8 sw_if_index_set = 0;
8916   u8 enable_disable = 1;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8921         sw_if_index_set = 1;
8922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8923         sw_if_index_set = 1;
8924       else if (unformat (i, "enable"))
8925         enable_disable = 1;
8926       else if (unformat (i, "disable"))
8927         enable_disable = 0;
8928       else
8929         break;
8930     }
8931
8932   if (sw_if_index_set == 0)
8933     {
8934       errmsg ("missing interface name or sw_if_index\n");
8935       return -99;
8936     }
8937
8938   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8939
8940   mp->sw_if_index = ntohl (sw_if_index);
8941   mp->enable_disable = enable_disable;
8942
8943   S;
8944   W;
8945   /* NOTREACHED */
8946   return 0;
8947 }
8948
8949 static int
8950 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8951 {
8952   unformat_input_t *i = vam->input;
8953   vl_api_l2tpv3_set_lookup_key_t *mp;
8954   f64 timeout;
8955   u8 key = ~0;
8956
8957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8958     {
8959       if (unformat (i, "lookup_v6_src"))
8960         key = L2T_LOOKUP_SRC_ADDRESS;
8961       else if (unformat (i, "lookup_v6_dst"))
8962         key = L2T_LOOKUP_DST_ADDRESS;
8963       else if (unformat (i, "lookup_session_id"))
8964         key = L2T_LOOKUP_SESSION_ID;
8965       else
8966         break;
8967     }
8968
8969   if (key == (u8) ~ 0)
8970     {
8971       errmsg ("l2tp session lookup key unset\n");
8972       return -99;
8973     }
8974
8975   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8976
8977   mp->key = key;
8978
8979   S;
8980   W;
8981   /* NOTREACHED */
8982   return 0;
8983 }
8984
8985 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8986   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8987 {
8988   vat_main_t *vam = &vat_main;
8989
8990   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8991            format_ip6_address, mp->our_address,
8992            format_ip6_address, mp->client_address,
8993            clib_net_to_host_u32 (mp->sw_if_index));
8994
8995   fformat (vam->ofp,
8996            "   local cookies %016llx %016llx remote cookie %016llx\n",
8997            clib_net_to_host_u64 (mp->local_cookie[0]),
8998            clib_net_to_host_u64 (mp->local_cookie[1]),
8999            clib_net_to_host_u64 (mp->remote_cookie));
9000
9001   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9002            clib_net_to_host_u32 (mp->local_session_id),
9003            clib_net_to_host_u32 (mp->remote_session_id));
9004
9005   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9006            mp->l2_sublayer_present ? "preset" : "absent");
9007
9008 }
9009
9010 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9011   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9012 {
9013   vat_main_t *vam = &vat_main;
9014   vat_json_node_t *node = NULL;
9015   struct in6_addr addr;
9016
9017   if (VAT_JSON_ARRAY != vam->json_tree.type)
9018     {
9019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9020       vat_json_init_array (&vam->json_tree);
9021     }
9022   node = vat_json_array_add (&vam->json_tree);
9023
9024   vat_json_init_object (node);
9025
9026   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9027   vat_json_object_add_ip6 (node, "our_address", addr);
9028   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9029   vat_json_object_add_ip6 (node, "client_address", addr);
9030
9031   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9032   vat_json_init_array (lc);
9033   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9034   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9035   vat_json_object_add_uint (node, "remote_cookie",
9036                             clib_net_to_host_u64 (mp->remote_cookie));
9037
9038   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9039   vat_json_object_add_uint (node, "local_session_id",
9040                             clib_net_to_host_u32 (mp->local_session_id));
9041   vat_json_object_add_uint (node, "remote_session_id",
9042                             clib_net_to_host_u32 (mp->remote_session_id));
9043   vat_json_object_add_string_copy (node, "l2_sublayer",
9044                                    mp->l2_sublayer_present ? (u8 *) "present"
9045                                    : (u8 *) "absent");
9046 }
9047
9048 static int
9049 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9050 {
9051   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9052   f64 timeout;
9053
9054   /* Get list of l2tpv3-tunnel interfaces */
9055   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9056   S;
9057
9058   /* Use a control ping for synchronization */
9059   {
9060     vl_api_control_ping_t *mp;
9061     M (CONTROL_PING, control_ping);
9062     S;
9063   }
9064   W;
9065 }
9066
9067
9068 static void vl_api_sw_interface_tap_details_t_handler
9069   (vl_api_sw_interface_tap_details_t * mp)
9070 {
9071   vat_main_t *vam = &vat_main;
9072
9073   fformat (vam->ofp, "%-16s %d\n",
9074            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9075 }
9076
9077 static void vl_api_sw_interface_tap_details_t_handler_json
9078   (vl_api_sw_interface_tap_details_t * mp)
9079 {
9080   vat_main_t *vam = &vat_main;
9081   vat_json_node_t *node = NULL;
9082
9083   if (VAT_JSON_ARRAY != vam->json_tree.type)
9084     {
9085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9086       vat_json_init_array (&vam->json_tree);
9087     }
9088   node = vat_json_array_add (&vam->json_tree);
9089
9090   vat_json_init_object (node);
9091   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9092   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9093 }
9094
9095 static int
9096 api_sw_interface_tap_dump (vat_main_t * vam)
9097 {
9098   vl_api_sw_interface_tap_dump_t *mp;
9099   f64 timeout;
9100
9101   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9102   /* Get list of tap interfaces */
9103   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9104   S;
9105
9106   /* Use a control ping for synchronization */
9107   {
9108     vl_api_control_ping_t *mp;
9109     M (CONTROL_PING, control_ping);
9110     S;
9111   }
9112   W;
9113 }
9114
9115 static uword unformat_vxlan_decap_next
9116   (unformat_input_t * input, va_list * args)
9117 {
9118   u32 *result = va_arg (*args, u32 *);
9119   u32 tmp;
9120
9121   if (unformat (input, "drop"))
9122     *result = VXLAN_INPUT_NEXT_DROP;
9123   else if (unformat (input, "ip4"))
9124     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9125   else if (unformat (input, "ip6"))
9126     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9127   else if (unformat (input, "l2"))
9128     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9129   else if (unformat (input, "%d", &tmp))
9130     *result = tmp;
9131   else
9132     return 0;
9133   return 1;
9134 }
9135
9136 static int
9137 api_vxlan_add_del_tunnel (vat_main_t * vam)
9138 {
9139   unformat_input_t *line_input = vam->input;
9140   vl_api_vxlan_add_del_tunnel_t *mp;
9141   f64 timeout;
9142   ip4_address_t src4, dst4;
9143   ip6_address_t src6, dst6;
9144   u8 is_add = 1;
9145   u8 ipv4_set = 0, ipv6_set = 0;
9146   u8 src_set = 0;
9147   u8 dst_set = 0;
9148   u32 encap_vrf_id = 0;
9149   u32 decap_next_index = ~0;
9150   u32 vni = 0;
9151
9152   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9153     {
9154       if (unformat (line_input, "del"))
9155         is_add = 0;
9156       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9157         {
9158           ipv4_set = 1;
9159           src_set = 1;
9160         }
9161       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9162         {
9163           ipv4_set = 1;
9164           dst_set = 1;
9165         }
9166       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9167         {
9168           ipv6_set = 1;
9169           src_set = 1;
9170         }
9171       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9172         {
9173           ipv6_set = 1;
9174           dst_set = 1;
9175         }
9176       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9177         ;
9178       else if (unformat (line_input, "decap-next %U",
9179                          unformat_vxlan_decap_next, &decap_next_index))
9180         ;
9181       else if (unformat (line_input, "vni %d", &vni))
9182         ;
9183       else
9184         {
9185           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9186           return -99;
9187         }
9188     }
9189
9190   if (src_set == 0)
9191     {
9192       errmsg ("tunnel src address not specified\n");
9193       return -99;
9194     }
9195   if (dst_set == 0)
9196     {
9197       errmsg ("tunnel dst address not specified\n");
9198       return -99;
9199     }
9200
9201   if (ipv4_set && ipv6_set)
9202     {
9203       errmsg ("both IPv4 and IPv6 addresses specified");
9204       return -99;
9205     }
9206
9207   if ((vni == 0) || (vni >> 24))
9208     {
9209       errmsg ("vni not specified or out of range\n");
9210       return -99;
9211     }
9212
9213   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9214
9215   if (ipv6_set)
9216     {
9217       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9218       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9219     }
9220   else
9221     {
9222       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9223       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9224     }
9225   mp->encap_vrf_id = ntohl (encap_vrf_id);
9226   mp->decap_next_index = ntohl (decap_next_index);
9227   mp->vni = ntohl (vni);
9228   mp->is_add = is_add;
9229   mp->is_ipv6 = ipv6_set;
9230
9231   S;
9232   W;
9233   /* NOTREACHED */
9234   return 0;
9235 }
9236
9237 static void vl_api_vxlan_tunnel_details_t_handler
9238   (vl_api_vxlan_tunnel_details_t * mp)
9239 {
9240   vat_main_t *vam = &vat_main;
9241
9242   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9243            ntohl (mp->sw_if_index),
9244            format_ip46_address, &(mp->src_address[0]),
9245            IP46_TYPE_ANY,
9246            format_ip46_address, &(mp->dst_address[0]),
9247            IP46_TYPE_ANY,
9248            ntohl (mp->encap_vrf_id),
9249            ntohl (mp->decap_next_index), ntohl (mp->vni));
9250 }
9251
9252 static void vl_api_vxlan_tunnel_details_t_handler_json
9253   (vl_api_vxlan_tunnel_details_t * mp)
9254 {
9255   vat_main_t *vam = &vat_main;
9256   vat_json_node_t *node = NULL;
9257   struct in_addr ip4;
9258   struct in6_addr ip6;
9259
9260   if (VAT_JSON_ARRAY != vam->json_tree.type)
9261     {
9262       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9263       vat_json_init_array (&vam->json_tree);
9264     }
9265   node = vat_json_array_add (&vam->json_tree);
9266
9267   vat_json_init_object (node);
9268   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9269   if (mp->is_ipv6)
9270     {
9271       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9272       vat_json_object_add_ip6 (node, "src_address", ip6);
9273       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9274       vat_json_object_add_ip6 (node, "dst_address", ip6);
9275     }
9276   else
9277     {
9278       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9279       vat_json_object_add_ip4 (node, "src_address", ip4);
9280       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9281       vat_json_object_add_ip4 (node, "dst_address", ip4);
9282     }
9283   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9284   vat_json_object_add_uint (node, "decap_next_index",
9285                             ntohl (mp->decap_next_index));
9286   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9287   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9288 }
9289
9290 static int
9291 api_vxlan_tunnel_dump (vat_main_t * vam)
9292 {
9293   unformat_input_t *i = vam->input;
9294   vl_api_vxlan_tunnel_dump_t *mp;
9295   f64 timeout;
9296   u32 sw_if_index;
9297   u8 sw_if_index_set = 0;
9298
9299   /* Parse args required to build the message */
9300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9301     {
9302       if (unformat (i, "sw_if_index %d", &sw_if_index))
9303         sw_if_index_set = 1;
9304       else
9305         break;
9306     }
9307
9308   if (sw_if_index_set == 0)
9309     {
9310       sw_if_index = ~0;
9311     }
9312
9313   if (!vam->json_output)
9314     {
9315       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9316                "sw_if_index", "src_address", "dst_address",
9317                "encap_vrf_id", "decap_next_index", "vni");
9318     }
9319
9320   /* Get list of vxlan-tunnel interfaces */
9321   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9322
9323   mp->sw_if_index = htonl (sw_if_index);
9324
9325   S;
9326
9327   /* Use a control ping for synchronization */
9328   {
9329     vl_api_control_ping_t *mp;
9330     M (CONTROL_PING, control_ping);
9331     S;
9332   }
9333   W;
9334 }
9335
9336 static int
9337 api_gre_add_del_tunnel (vat_main_t * vam)
9338 {
9339   unformat_input_t *line_input = vam->input;
9340   vl_api_gre_add_del_tunnel_t *mp;
9341   f64 timeout;
9342   ip4_address_t src4, dst4;
9343   u8 is_add = 1;
9344   u8 src_set = 0;
9345   u8 dst_set = 0;
9346   u32 outer_fib_id = 0;
9347
9348   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9349     {
9350       if (unformat (line_input, "del"))
9351         is_add = 0;
9352       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9353         src_set = 1;
9354       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9355         dst_set = 1;
9356       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9357         ;
9358       else
9359         {
9360           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9361           return -99;
9362         }
9363     }
9364
9365   if (src_set == 0)
9366     {
9367       errmsg ("tunnel src address not specified\n");
9368       return -99;
9369     }
9370   if (dst_set == 0)
9371     {
9372       errmsg ("tunnel dst address not specified\n");
9373       return -99;
9374     }
9375
9376
9377   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9378
9379   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9380   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9381   mp->outer_fib_id = ntohl (outer_fib_id);
9382   mp->is_add = is_add;
9383
9384   S;
9385   W;
9386   /* NOTREACHED */
9387   return 0;
9388 }
9389
9390 static void vl_api_gre_tunnel_details_t_handler
9391   (vl_api_gre_tunnel_details_t * mp)
9392 {
9393   vat_main_t *vam = &vat_main;
9394
9395   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9396            ntohl (mp->sw_if_index),
9397            format_ip4_address, &mp->src_address,
9398            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9399 }
9400
9401 static void vl_api_gre_tunnel_details_t_handler_json
9402   (vl_api_gre_tunnel_details_t * mp)
9403 {
9404   vat_main_t *vam = &vat_main;
9405   vat_json_node_t *node = NULL;
9406   struct in_addr ip4;
9407
9408   if (VAT_JSON_ARRAY != vam->json_tree.type)
9409     {
9410       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9411       vat_json_init_array (&vam->json_tree);
9412     }
9413   node = vat_json_array_add (&vam->json_tree);
9414
9415   vat_json_init_object (node);
9416   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9417   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9418   vat_json_object_add_ip4 (node, "src_address", ip4);
9419   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9420   vat_json_object_add_ip4 (node, "dst_address", ip4);
9421   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9422 }
9423
9424 static int
9425 api_gre_tunnel_dump (vat_main_t * vam)
9426 {
9427   unformat_input_t *i = vam->input;
9428   vl_api_gre_tunnel_dump_t *mp;
9429   f64 timeout;
9430   u32 sw_if_index;
9431   u8 sw_if_index_set = 0;
9432
9433   /* Parse args required to build the message */
9434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9435     {
9436       if (unformat (i, "sw_if_index %d", &sw_if_index))
9437         sw_if_index_set = 1;
9438       else
9439         break;
9440     }
9441
9442   if (sw_if_index_set == 0)
9443     {
9444       sw_if_index = ~0;
9445     }
9446
9447   if (!vam->json_output)
9448     {
9449       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9450                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9451     }
9452
9453   /* Get list of gre-tunnel interfaces */
9454   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9455
9456   mp->sw_if_index = htonl (sw_if_index);
9457
9458   S;
9459
9460   /* Use a control ping for synchronization */
9461   {
9462     vl_api_control_ping_t *mp;
9463     M (CONTROL_PING, control_ping);
9464     S;
9465   }
9466   W;
9467 }
9468
9469 static int
9470 api_l2_fib_clear_table (vat_main_t * vam)
9471 {
9472 //  unformat_input_t * i = vam->input;
9473   vl_api_l2_fib_clear_table_t *mp;
9474   f64 timeout;
9475
9476   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9477
9478   S;
9479   W;
9480   /* NOTREACHED */
9481   return 0;
9482 }
9483
9484 static int
9485 api_l2_interface_efp_filter (vat_main_t * vam)
9486 {
9487   unformat_input_t *i = vam->input;
9488   vl_api_l2_interface_efp_filter_t *mp;
9489   f64 timeout;
9490   u32 sw_if_index;
9491   u8 enable = 1;
9492   u8 sw_if_index_set = 0;
9493
9494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9497         sw_if_index_set = 1;
9498       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9499         sw_if_index_set = 1;
9500       else if (unformat (i, "enable"))
9501         enable = 1;
9502       else if (unformat (i, "disable"))
9503         enable = 0;
9504       else
9505         {
9506           clib_warning ("parse error '%U'", format_unformat_error, i);
9507           return -99;
9508         }
9509     }
9510
9511   if (sw_if_index_set == 0)
9512     {
9513       errmsg ("missing sw_if_index\n");
9514       return -99;
9515     }
9516
9517   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9518
9519   mp->sw_if_index = ntohl (sw_if_index);
9520   mp->enable_disable = enable;
9521
9522   S;
9523   W;
9524   /* NOTREACHED */
9525   return 0;
9526 }
9527
9528 #define foreach_vtr_op                          \
9529 _("disable",  L2_VTR_DISABLED)                  \
9530 _("push-1",  L2_VTR_PUSH_1)                     \
9531 _("push-2",  L2_VTR_PUSH_2)                     \
9532 _("pop-1",  L2_VTR_POP_1)                       \
9533 _("pop-2",  L2_VTR_POP_2)                       \
9534 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9535 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9536 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9537 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9538
9539 static int
9540 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9544   f64 timeout;
9545   u32 sw_if_index;
9546   u8 sw_if_index_set = 0;
9547   u8 vtr_op_set = 0;
9548   u32 vtr_op = 0;
9549   u32 push_dot1q = 1;
9550   u32 tag1 = ~0;
9551   u32 tag2 = ~0;
9552
9553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9554     {
9555       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9556         sw_if_index_set = 1;
9557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9558         sw_if_index_set = 1;
9559       else if (unformat (i, "vtr_op %d", &vtr_op))
9560         vtr_op_set = 1;
9561 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9562       foreach_vtr_op
9563 #undef _
9564         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9565         ;
9566       else if (unformat (i, "tag1 %d", &tag1))
9567         ;
9568       else if (unformat (i, "tag2 %d", &tag2))
9569         ;
9570       else
9571         {
9572           clib_warning ("parse error '%U'", format_unformat_error, i);
9573           return -99;
9574         }
9575     }
9576
9577   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9578     {
9579       errmsg ("missing vtr operation or sw_if_index\n");
9580       return -99;
9581     }
9582
9583   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9584     mp->sw_if_index = ntohl (sw_if_index);
9585   mp->vtr_op = ntohl (vtr_op);
9586   mp->push_dot1q = ntohl (push_dot1q);
9587   mp->tag1 = ntohl (tag1);
9588   mp->tag2 = ntohl (tag2);
9589
9590   S;
9591   W;
9592   /* NOTREACHED */
9593   return 0;
9594 }
9595
9596 static int
9597 api_create_vhost_user_if (vat_main_t * vam)
9598 {
9599   unformat_input_t *i = vam->input;
9600   vl_api_create_vhost_user_if_t *mp;
9601   f64 timeout;
9602   u8 *file_name;
9603   u8 is_server = 0;
9604   u8 file_name_set = 0;
9605   u32 custom_dev_instance = ~0;
9606   u8 hwaddr[6];
9607   u8 use_custom_mac = 0;
9608
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "socket %s", &file_name))
9612         {
9613           file_name_set = 1;
9614         }
9615       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9616         ;
9617       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9618         use_custom_mac = 1;
9619       else if (unformat (i, "server"))
9620         is_server = 1;
9621       else
9622         break;
9623     }
9624
9625   if (file_name_set == 0)
9626     {
9627       errmsg ("missing socket file name\n");
9628       return -99;
9629     }
9630
9631   if (vec_len (file_name) > 255)
9632     {
9633       errmsg ("socket file name too long\n");
9634       return -99;
9635     }
9636   vec_add1 (file_name, 0);
9637
9638   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9639
9640   mp->is_server = is_server;
9641   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9642   vec_free (file_name);
9643   if (custom_dev_instance != ~0)
9644     {
9645       mp->renumber = 1;
9646       mp->custom_dev_instance = ntohl (custom_dev_instance);
9647     }
9648   mp->use_custom_mac = use_custom_mac;
9649   clib_memcpy (mp->mac_address, hwaddr, 6);
9650
9651   S;
9652   W;
9653   /* NOTREACHED */
9654   return 0;
9655 }
9656
9657 static int
9658 api_modify_vhost_user_if (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_modify_vhost_user_if_t *mp;
9662   f64 timeout;
9663   u8 *file_name;
9664   u8 is_server = 0;
9665   u8 file_name_set = 0;
9666   u32 custom_dev_instance = ~0;
9667   u8 sw_if_index_set = 0;
9668   u32 sw_if_index = (u32) ~ 0;
9669
9670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9671     {
9672       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9673         sw_if_index_set = 1;
9674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9675         sw_if_index_set = 1;
9676       else if (unformat (i, "socket %s", &file_name))
9677         {
9678           file_name_set = 1;
9679         }
9680       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9681         ;
9682       else if (unformat (i, "server"))
9683         is_server = 1;
9684       else
9685         break;
9686     }
9687
9688   if (sw_if_index_set == 0)
9689     {
9690       errmsg ("missing sw_if_index or interface name\n");
9691       return -99;
9692     }
9693
9694   if (file_name_set == 0)
9695     {
9696       errmsg ("missing socket file name\n");
9697       return -99;
9698     }
9699
9700   if (vec_len (file_name) > 255)
9701     {
9702       errmsg ("socket file name too long\n");
9703       return -99;
9704     }
9705   vec_add1 (file_name, 0);
9706
9707   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9708
9709   mp->sw_if_index = ntohl (sw_if_index);
9710   mp->is_server = is_server;
9711   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9712   vec_free (file_name);
9713   if (custom_dev_instance != ~0)
9714     {
9715       mp->renumber = 1;
9716       mp->custom_dev_instance = ntohl (custom_dev_instance);
9717     }
9718
9719   S;
9720   W;
9721   /* NOTREACHED */
9722   return 0;
9723 }
9724
9725 static int
9726 api_delete_vhost_user_if (vat_main_t * vam)
9727 {
9728   unformat_input_t *i = vam->input;
9729   vl_api_delete_vhost_user_if_t *mp;
9730   f64 timeout;
9731   u32 sw_if_index = ~0;
9732   u8 sw_if_index_set = 0;
9733
9734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9735     {
9736       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9737         sw_if_index_set = 1;
9738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9739         sw_if_index_set = 1;
9740       else
9741         break;
9742     }
9743
9744   if (sw_if_index_set == 0)
9745     {
9746       errmsg ("missing sw_if_index or interface name\n");
9747       return -99;
9748     }
9749
9750
9751   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9752
9753   mp->sw_if_index = ntohl (sw_if_index);
9754
9755   S;
9756   W;
9757   /* NOTREACHED */
9758   return 0;
9759 }
9760
9761 static void vl_api_sw_interface_vhost_user_details_t_handler
9762   (vl_api_sw_interface_vhost_user_details_t * mp)
9763 {
9764   vat_main_t *vam = &vat_main;
9765
9766   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9767            (char *) mp->interface_name,
9768            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9769            clib_net_to_host_u64 (mp->features), mp->is_server,
9770            ntohl (mp->num_regions), (char *) mp->sock_filename);
9771   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9772 }
9773
9774 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9775   (vl_api_sw_interface_vhost_user_details_t * mp)
9776 {
9777   vat_main_t *vam = &vat_main;
9778   vat_json_node_t *node = NULL;
9779
9780   if (VAT_JSON_ARRAY != vam->json_tree.type)
9781     {
9782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9783       vat_json_init_array (&vam->json_tree);
9784     }
9785   node = vat_json_array_add (&vam->json_tree);
9786
9787   vat_json_init_object (node);
9788   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9789   vat_json_object_add_string_copy (node, "interface_name",
9790                                    mp->interface_name);
9791   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9792                             ntohl (mp->virtio_net_hdr_sz));
9793   vat_json_object_add_uint (node, "features",
9794                             clib_net_to_host_u64 (mp->features));
9795   vat_json_object_add_uint (node, "is_server", mp->is_server);
9796   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9797   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9798   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9799 }
9800
9801 static int
9802 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9803 {
9804   vl_api_sw_interface_vhost_user_dump_t *mp;
9805   f64 timeout;
9806   fformat (vam->ofp,
9807            "Interface name           idx hdr_sz features server regions filename\n");
9808
9809   /* Get list of vhost-user interfaces */
9810   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9811   S;
9812
9813   /* Use a control ping for synchronization */
9814   {
9815     vl_api_control_ping_t *mp;
9816     M (CONTROL_PING, control_ping);
9817     S;
9818   }
9819   W;
9820 }
9821
9822 static int
9823 api_show_version (vat_main_t * vam)
9824 {
9825   vl_api_show_version_t *mp;
9826   f64 timeout;
9827
9828   M (SHOW_VERSION, show_version);
9829
9830   S;
9831   W;
9832   /* NOTREACHED */
9833   return 0;
9834 }
9835
9836
9837 static int
9838 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9839 {
9840   unformat_input_t *line_input = vam->input;
9841   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9842   f64 timeout;
9843   ip4_address_t local4, remote4;
9844   ip6_address_t local6, remote6;
9845   u8 is_add = 1;
9846   u8 ipv4_set = 0, ipv6_set = 0;
9847   u8 local_set = 0;
9848   u8 remote_set = 0;
9849   u32 encap_vrf_id = 0;
9850   u32 decap_vrf_id = 0;
9851   u8 protocol = ~0;
9852   u32 vni;
9853   u8 vni_set = 0;
9854
9855   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (line_input, "del"))
9858         is_add = 0;
9859       else if (unformat (line_input, "local %U",
9860                          unformat_ip4_address, &local4))
9861         {
9862           local_set = 1;
9863           ipv4_set = 1;
9864         }
9865       else if (unformat (line_input, "remote %U",
9866                          unformat_ip4_address, &remote4))
9867         {
9868           remote_set = 1;
9869           ipv4_set = 1;
9870         }
9871       else if (unformat (line_input, "local %U",
9872                          unformat_ip6_address, &local6))
9873         {
9874           local_set = 1;
9875           ipv6_set = 1;
9876         }
9877       else if (unformat (line_input, "remote %U",
9878                          unformat_ip6_address, &remote6))
9879         {
9880           remote_set = 1;
9881           ipv6_set = 1;
9882         }
9883       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9884         ;
9885       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9886         ;
9887       else if (unformat (line_input, "vni %d", &vni))
9888         vni_set = 1;
9889       else if (unformat (line_input, "next-ip4"))
9890         protocol = 1;
9891       else if (unformat (line_input, "next-ip6"))
9892         protocol = 2;
9893       else if (unformat (line_input, "next-ethernet"))
9894         protocol = 3;
9895       else if (unformat (line_input, "next-nsh"))
9896         protocol = 4;
9897       else
9898         {
9899           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9900           return -99;
9901         }
9902     }
9903
9904   if (local_set == 0)
9905     {
9906       errmsg ("tunnel local address not specified\n");
9907       return -99;
9908     }
9909   if (remote_set == 0)
9910     {
9911       errmsg ("tunnel remote address not specified\n");
9912       return -99;
9913     }
9914   if (ipv4_set && ipv6_set)
9915     {
9916       errmsg ("both IPv4 and IPv6 addresses specified");
9917       return -99;
9918     }
9919
9920   if (vni_set == 0)
9921     {
9922       errmsg ("vni not specified\n");
9923       return -99;
9924     }
9925
9926   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9927
9928
9929   if (ipv6_set)
9930     {
9931       clib_memcpy (&mp->local, &local6, sizeof (local6));
9932       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9933     }
9934   else
9935     {
9936       clib_memcpy (&mp->local, &local4, sizeof (local4));
9937       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9938     }
9939
9940   mp->encap_vrf_id = ntohl (encap_vrf_id);
9941   mp->decap_vrf_id = ntohl (decap_vrf_id);
9942   mp->protocol = ntohl (protocol);
9943   mp->vni = ntohl (vni);
9944   mp->is_add = is_add;
9945   mp->is_ipv6 = ipv6_set;
9946
9947   S;
9948   W;
9949   /* NOTREACHED */
9950   return 0;
9951 }
9952
9953 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9954   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9955 {
9956   vat_main_t *vam = &vat_main;
9957
9958   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9959            ntohl (mp->sw_if_index),
9960            format_ip46_address, &(mp->local[0]),
9961            format_ip46_address, &(mp->remote[0]),
9962            ntohl (mp->vni),
9963            ntohl (mp->protocol),
9964            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9965 }
9966
9967 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9968   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9969 {
9970   vat_main_t *vam = &vat_main;
9971   vat_json_node_t *node = NULL;
9972   struct in_addr ip4;
9973   struct in6_addr ip6;
9974
9975   if (VAT_JSON_ARRAY != vam->json_tree.type)
9976     {
9977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9978       vat_json_init_array (&vam->json_tree);
9979     }
9980   node = vat_json_array_add (&vam->json_tree);
9981
9982   vat_json_init_object (node);
9983   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9984   if (mp->is_ipv6)
9985     {
9986       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9987       vat_json_object_add_ip6 (node, "local", ip6);
9988       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9989       vat_json_object_add_ip6 (node, "remote", ip6);
9990     }
9991   else
9992     {
9993       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9994       vat_json_object_add_ip4 (node, "local", ip4);
9995       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9996       vat_json_object_add_ip4 (node, "remote", ip4);
9997     }
9998   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9999   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10000   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10001   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10002   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10003 }
10004
10005 static int
10006 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10007 {
10008   unformat_input_t *i = vam->input;
10009   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10010   f64 timeout;
10011   u32 sw_if_index;
10012   u8 sw_if_index_set = 0;
10013
10014   /* Parse args required to build the message */
10015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10016     {
10017       if (unformat (i, "sw_if_index %d", &sw_if_index))
10018         sw_if_index_set = 1;
10019       else
10020         break;
10021     }
10022
10023   if (sw_if_index_set == 0)
10024     {
10025       sw_if_index = ~0;
10026     }
10027
10028   if (!vam->json_output)
10029     {
10030       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10031                "sw_if_index", "local", "remote", "vni",
10032                "protocol", "encap_vrf_id", "decap_vrf_id");
10033     }
10034
10035   /* Get list of vxlan-tunnel interfaces */
10036   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10037
10038   mp->sw_if_index = htonl (sw_if_index);
10039
10040   S;
10041
10042   /* Use a control ping for synchronization */
10043   {
10044     vl_api_control_ping_t *mp;
10045     M (CONTROL_PING, control_ping);
10046     S;
10047   }
10048   W;
10049 }
10050
10051 u8 *
10052 format_l2_fib_mac_address (u8 * s, va_list * args)
10053 {
10054   u8 *a = va_arg (*args, u8 *);
10055
10056   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10057                  a[2], a[3], a[4], a[5], a[6], a[7]);
10058 }
10059
10060 static void vl_api_l2_fib_table_entry_t_handler
10061   (vl_api_l2_fib_table_entry_t * mp)
10062 {
10063   vat_main_t *vam = &vat_main;
10064
10065   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10066            "       %d       %d     %d\n",
10067            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10068            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10069            mp->bvi_mac);
10070 }
10071
10072 static void vl_api_l2_fib_table_entry_t_handler_json
10073   (vl_api_l2_fib_table_entry_t * mp)
10074 {
10075   vat_main_t *vam = &vat_main;
10076   vat_json_node_t *node = NULL;
10077
10078   if (VAT_JSON_ARRAY != vam->json_tree.type)
10079     {
10080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10081       vat_json_init_array (&vam->json_tree);
10082     }
10083   node = vat_json_array_add (&vam->json_tree);
10084
10085   vat_json_init_object (node);
10086   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10087   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10089   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10090   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10091   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10092 }
10093
10094 static int
10095 api_l2_fib_table_dump (vat_main_t * vam)
10096 {
10097   unformat_input_t *i = vam->input;
10098   vl_api_l2_fib_table_dump_t *mp;
10099   f64 timeout;
10100   u32 bd_id;
10101   u8 bd_id_set = 0;
10102
10103   /* Parse args required to build the message */
10104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10105     {
10106       if (unformat (i, "bd_id %d", &bd_id))
10107         bd_id_set = 1;
10108       else
10109         break;
10110     }
10111
10112   if (bd_id_set == 0)
10113     {
10114       errmsg ("missing bridge domain\n");
10115       return -99;
10116     }
10117
10118   fformat (vam->ofp,
10119            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10120
10121   /* Get list of l2 fib entries */
10122   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10123
10124   mp->bd_id = ntohl (bd_id);
10125   S;
10126
10127   /* Use a control ping for synchronization */
10128   {
10129     vl_api_control_ping_t *mp;
10130     M (CONTROL_PING, control_ping);
10131     S;
10132   }
10133   W;
10134 }
10135
10136
10137 static int
10138 api_interface_name_renumber (vat_main_t * vam)
10139 {
10140   unformat_input_t *line_input = vam->input;
10141   vl_api_interface_name_renumber_t *mp;
10142   u32 sw_if_index = ~0;
10143   f64 timeout;
10144   u32 new_show_dev_instance = ~0;
10145
10146   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10147     {
10148       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10149                     &sw_if_index))
10150         ;
10151       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10152         ;
10153       else if (unformat (line_input, "new_show_dev_instance %d",
10154                          &new_show_dev_instance))
10155         ;
10156       else
10157         break;
10158     }
10159
10160   if (sw_if_index == ~0)
10161     {
10162       errmsg ("missing interface name or sw_if_index\n");
10163       return -99;
10164     }
10165
10166   if (new_show_dev_instance == ~0)
10167     {
10168       errmsg ("missing new_show_dev_instance\n");
10169       return -99;
10170     }
10171
10172   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10173
10174   mp->sw_if_index = ntohl (sw_if_index);
10175   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10176
10177   S;
10178   W;
10179 }
10180
10181 static int
10182 api_want_ip4_arp_events (vat_main_t * vam)
10183 {
10184   unformat_input_t *line_input = vam->input;
10185   vl_api_want_ip4_arp_events_t *mp;
10186   f64 timeout;
10187   ip4_address_t address;
10188   int address_set = 0;
10189   u32 enable_disable = 1;
10190
10191   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10192     {
10193       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10194         address_set = 1;
10195       else if (unformat (line_input, "del"))
10196         enable_disable = 0;
10197       else
10198         break;
10199     }
10200
10201   if (address_set == 0)
10202     {
10203       errmsg ("missing addresses\n");
10204       return -99;
10205     }
10206
10207   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10208   mp->enable_disable = enable_disable;
10209   mp->pid = getpid ();
10210   mp->address = address.as_u32;
10211
10212   S;
10213   W;
10214 }
10215
10216 static int
10217 api_input_acl_set_interface (vat_main_t * vam)
10218 {
10219   unformat_input_t *i = vam->input;
10220   vl_api_input_acl_set_interface_t *mp;
10221   f64 timeout;
10222   u32 sw_if_index;
10223   int sw_if_index_set;
10224   u32 ip4_table_index = ~0;
10225   u32 ip6_table_index = ~0;
10226   u32 l2_table_index = ~0;
10227   u8 is_add = 1;
10228
10229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10230     {
10231       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10232         sw_if_index_set = 1;
10233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10234         sw_if_index_set = 1;
10235       else if (unformat (i, "del"))
10236         is_add = 0;
10237       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10238         ;
10239       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10240         ;
10241       else if (unformat (i, "l2-table %d", &l2_table_index))
10242         ;
10243       else
10244         {
10245           clib_warning ("parse error '%U'", format_unformat_error, i);
10246           return -99;
10247         }
10248     }
10249
10250   if (sw_if_index_set == 0)
10251     {
10252       errmsg ("missing interface name or sw_if_index\n");
10253       return -99;
10254     }
10255
10256   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10257
10258   mp->sw_if_index = ntohl (sw_if_index);
10259   mp->ip4_table_index = ntohl (ip4_table_index);
10260   mp->ip6_table_index = ntohl (ip6_table_index);
10261   mp->l2_table_index = ntohl (l2_table_index);
10262   mp->is_add = is_add;
10263
10264   S;
10265   W;
10266   /* NOTREACHED */
10267   return 0;
10268 }
10269
10270 static int
10271 api_ip_address_dump (vat_main_t * vam)
10272 {
10273   unformat_input_t *i = vam->input;
10274   vl_api_ip_address_dump_t *mp;
10275   u32 sw_if_index = ~0;
10276   u8 sw_if_index_set = 0;
10277   u8 ipv4_set = 0;
10278   u8 ipv6_set = 0;
10279   f64 timeout;
10280
10281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (i, "sw_if_index %d", &sw_if_index))
10284         sw_if_index_set = 1;
10285       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10286         sw_if_index_set = 1;
10287       else if (unformat (i, "ipv4"))
10288         ipv4_set = 1;
10289       else if (unformat (i, "ipv6"))
10290         ipv6_set = 1;
10291       else
10292         break;
10293     }
10294
10295   if (ipv4_set && ipv6_set)
10296     {
10297       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10298       return -99;
10299     }
10300
10301   if ((!ipv4_set) && (!ipv6_set))
10302     {
10303       errmsg ("no ipv4 nor ipv6 flag set\n");
10304       return -99;
10305     }
10306
10307   if (sw_if_index_set == 0)
10308     {
10309       errmsg ("missing interface name or sw_if_index\n");
10310       return -99;
10311     }
10312
10313   vam->current_sw_if_index = sw_if_index;
10314   vam->is_ipv6 = ipv6_set;
10315
10316   M (IP_ADDRESS_DUMP, ip_address_dump);
10317   mp->sw_if_index = ntohl (sw_if_index);
10318   mp->is_ipv6 = ipv6_set;
10319   S;
10320
10321   /* Use a control ping for synchronization */
10322   {
10323     vl_api_control_ping_t *mp;
10324     M (CONTROL_PING, control_ping);
10325     S;
10326   }
10327   W;
10328 }
10329
10330 static int
10331 api_ip_dump (vat_main_t * vam)
10332 {
10333   vl_api_ip_dump_t *mp;
10334   unformat_input_t *in = vam->input;
10335   int ipv4_set = 0;
10336   int ipv6_set = 0;
10337   int is_ipv6;
10338   f64 timeout;
10339   int i;
10340
10341   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10342     {
10343       if (unformat (in, "ipv4"))
10344         ipv4_set = 1;
10345       else if (unformat (in, "ipv6"))
10346         ipv6_set = 1;
10347       else
10348         break;
10349     }
10350
10351   if (ipv4_set && ipv6_set)
10352     {
10353       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10354       return -99;
10355     }
10356
10357   if ((!ipv4_set) && (!ipv6_set))
10358     {
10359       errmsg ("no ipv4 nor ipv6 flag set\n");
10360       return -99;
10361     }
10362
10363   is_ipv6 = ipv6_set;
10364   vam->is_ipv6 = is_ipv6;
10365
10366   /* free old data */
10367   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10368     {
10369       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10370     }
10371   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10372
10373   M (IP_DUMP, ip_dump);
10374   mp->is_ipv6 = ipv6_set;
10375   S;
10376
10377   /* Use a control ping for synchronization */
10378   {
10379     vl_api_control_ping_t *mp;
10380     M (CONTROL_PING, control_ping);
10381     S;
10382   }
10383   W;
10384 }
10385
10386 static int
10387 api_ipsec_spd_add_del (vat_main_t * vam)
10388 {
10389 #if DPDK > 0
10390   unformat_input_t *i = vam->input;
10391   vl_api_ipsec_spd_add_del_t *mp;
10392   f64 timeout;
10393   u32 spd_id = ~0;
10394   u8 is_add = 1;
10395
10396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10397     {
10398       if (unformat (i, "spd_id %d", &spd_id))
10399         ;
10400       else if (unformat (i, "del"))
10401         is_add = 0;
10402       else
10403         {
10404           clib_warning ("parse error '%U'", format_unformat_error, i);
10405           return -99;
10406         }
10407     }
10408   if (spd_id == ~0)
10409     {
10410       errmsg ("spd_id must be set\n");
10411       return -99;
10412     }
10413
10414   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10415
10416   mp->spd_id = ntohl (spd_id);
10417   mp->is_add = is_add;
10418
10419   S;
10420   W;
10421   /* NOTREACHED */
10422   return 0;
10423 #else
10424   clib_warning ("unsupported (no dpdk)");
10425   return -99;
10426 #endif
10427 }
10428
10429 static int
10430 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10431 {
10432 #if DPDK > 0
10433   unformat_input_t *i = vam->input;
10434   vl_api_ipsec_interface_add_del_spd_t *mp;
10435   f64 timeout;
10436   u32 sw_if_index;
10437   u8 sw_if_index_set = 0;
10438   u32 spd_id = (u32) ~ 0;
10439   u8 is_add = 1;
10440
10441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10442     {
10443       if (unformat (i, "del"))
10444         is_add = 0;
10445       else if (unformat (i, "spd_id %d", &spd_id))
10446         ;
10447       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10448         sw_if_index_set = 1;
10449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10450         sw_if_index_set = 1;
10451       else
10452         {
10453           clib_warning ("parse error '%U'", format_unformat_error, i);
10454           return -99;
10455         }
10456
10457     }
10458
10459   if (spd_id == (u32) ~ 0)
10460     {
10461       errmsg ("spd_id must be set\n");
10462       return -99;
10463     }
10464
10465   if (sw_if_index_set == 0)
10466     {
10467       errmsg ("missing interface name or sw_if_index\n");
10468       return -99;
10469     }
10470
10471   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10472
10473   mp->spd_id = ntohl (spd_id);
10474   mp->sw_if_index = ntohl (sw_if_index);
10475   mp->is_add = is_add;
10476
10477   S;
10478   W;
10479   /* NOTREACHED */
10480   return 0;
10481 #else
10482   clib_warning ("unsupported (no dpdk)");
10483   return -99;
10484 #endif
10485 }
10486
10487 static int
10488 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10489 {
10490 #if DPDK > 0
10491   unformat_input_t *i = vam->input;
10492   vl_api_ipsec_spd_add_del_entry_t *mp;
10493   f64 timeout;
10494   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10495   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10496   i32 priority = 0;
10497   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10498   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10499   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10500   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10501
10502   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10503   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10504   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10505   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10506   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10507   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10508
10509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10510     {
10511       if (unformat (i, "del"))
10512         is_add = 0;
10513       if (unformat (i, "outbound"))
10514         is_outbound = 1;
10515       if (unformat (i, "inbound"))
10516         is_outbound = 0;
10517       else if (unformat (i, "spd_id %d", &spd_id))
10518         ;
10519       else if (unformat (i, "sa_id %d", &sa_id))
10520         ;
10521       else if (unformat (i, "priority %d", &priority))
10522         ;
10523       else if (unformat (i, "protocol %d", &protocol))
10524         ;
10525       else if (unformat (i, "lport_start %d", &lport_start))
10526         ;
10527       else if (unformat (i, "lport_stop %d", &lport_stop))
10528         ;
10529       else if (unformat (i, "rport_start %d", &rport_start))
10530         ;
10531       else if (unformat (i, "rport_stop %d", &rport_stop))
10532         ;
10533       else
10534         if (unformat
10535             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10536         {
10537           is_ipv6 = 0;
10538           is_ip_any = 0;
10539         }
10540       else
10541         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10542         {
10543           is_ipv6 = 0;
10544           is_ip_any = 0;
10545         }
10546       else
10547         if (unformat
10548             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10549         {
10550           is_ipv6 = 0;
10551           is_ip_any = 0;
10552         }
10553       else
10554         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10555         {
10556           is_ipv6 = 0;
10557           is_ip_any = 0;
10558         }
10559       else
10560         if (unformat
10561             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10562         {
10563           is_ipv6 = 1;
10564           is_ip_any = 0;
10565         }
10566       else
10567         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10568         {
10569           is_ipv6 = 1;
10570           is_ip_any = 0;
10571         }
10572       else
10573         if (unformat
10574             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10575         {
10576           is_ipv6 = 1;
10577           is_ip_any = 0;
10578         }
10579       else
10580         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10581         {
10582           is_ipv6 = 1;
10583           is_ip_any = 0;
10584         }
10585       else
10586         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10587         {
10588           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10589             {
10590               clib_warning ("unsupported action: 'resolve'");
10591               return -99;
10592             }
10593         }
10594       else
10595         {
10596           clib_warning ("parse error '%U'", format_unformat_error, i);
10597           return -99;
10598         }
10599
10600     }
10601
10602   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10603
10604   mp->spd_id = ntohl (spd_id);
10605   mp->priority = ntohl (priority);
10606   mp->is_outbound = is_outbound;
10607
10608   mp->is_ipv6 = is_ipv6;
10609   if (is_ipv6 || is_ip_any)
10610     {
10611       clib_memcpy (mp->remote_address_start, &raddr6_start,
10612                    sizeof (ip6_address_t));
10613       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10614                    sizeof (ip6_address_t));
10615       clib_memcpy (mp->local_address_start, &laddr6_start,
10616                    sizeof (ip6_address_t));
10617       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10618                    sizeof (ip6_address_t));
10619     }
10620   else
10621     {
10622       clib_memcpy (mp->remote_address_start, &raddr4_start,
10623                    sizeof (ip4_address_t));
10624       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10625                    sizeof (ip4_address_t));
10626       clib_memcpy (mp->local_address_start, &laddr4_start,
10627                    sizeof (ip4_address_t));
10628       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10629                    sizeof (ip4_address_t));
10630     }
10631   mp->protocol = (u8) protocol;
10632   mp->local_port_start = ntohs ((u16) lport_start);
10633   mp->local_port_stop = ntohs ((u16) lport_stop);
10634   mp->remote_port_start = ntohs ((u16) rport_start);
10635   mp->remote_port_stop = ntohs ((u16) rport_stop);
10636   mp->policy = (u8) policy;
10637   mp->sa_id = ntohl (sa_id);
10638   mp->is_add = is_add;
10639   mp->is_ip_any = is_ip_any;
10640   S;
10641   W;
10642   /* NOTREACHED */
10643   return 0;
10644 #else
10645   clib_warning ("unsupported (no dpdk)");
10646   return -99;
10647 #endif
10648 }
10649
10650 static int
10651 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10652 {
10653 #if DPDK > 0
10654   unformat_input_t *i = vam->input;
10655   vl_api_ipsec_sad_add_del_entry_t *mp;
10656   f64 timeout;
10657   u32 sad_id = 0, spi = 0;
10658   u8 *ck = 0, *ik = 0;
10659   u8 is_add = 1;
10660
10661   u8 protocol = IPSEC_PROTOCOL_AH;
10662   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10663   u32 crypto_alg = 0, integ_alg = 0;
10664   ip4_address_t tun_src4;
10665   ip4_address_t tun_dst4;
10666   ip6_address_t tun_src6;
10667   ip6_address_t tun_dst6;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "del"))
10672         is_add = 0;
10673       else if (unformat (i, "sad_id %d", &sad_id))
10674         ;
10675       else if (unformat (i, "spi %d", &spi))
10676         ;
10677       else if (unformat (i, "esp"))
10678         protocol = IPSEC_PROTOCOL_ESP;
10679       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10680         {
10681           is_tunnel = 1;
10682           is_tunnel_ipv6 = 0;
10683         }
10684       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10685         {
10686           is_tunnel = 1;
10687           is_tunnel_ipv6 = 0;
10688         }
10689       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10690         {
10691           is_tunnel = 1;
10692           is_tunnel_ipv6 = 1;
10693         }
10694       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10695         {
10696           is_tunnel = 1;
10697           is_tunnel_ipv6 = 1;
10698         }
10699       else
10700         if (unformat
10701             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10702         {
10703           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10704               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10705             {
10706               clib_warning ("unsupported crypto-alg: '%U'",
10707                             format_ipsec_crypto_alg, crypto_alg);
10708               return -99;
10709             }
10710         }
10711       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10712         ;
10713       else
10714         if (unformat
10715             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10716         {
10717           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10718               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10719             {
10720               clib_warning ("unsupported integ-alg: '%U'",
10721                             format_ipsec_integ_alg, integ_alg);
10722               return -99;
10723             }
10724         }
10725       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10726         ;
10727       else
10728         {
10729           clib_warning ("parse error '%U'", format_unformat_error, i);
10730           return -99;
10731         }
10732
10733     }
10734
10735   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10736
10737   mp->sad_id = ntohl (sad_id);
10738   mp->is_add = is_add;
10739   mp->protocol = protocol;
10740   mp->spi = ntohl (spi);
10741   mp->is_tunnel = is_tunnel;
10742   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10743   mp->crypto_algorithm = crypto_alg;
10744   mp->integrity_algorithm = integ_alg;
10745   mp->crypto_key_length = vec_len (ck);
10746   mp->integrity_key_length = vec_len (ik);
10747
10748   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10749     mp->crypto_key_length = sizeof (mp->crypto_key);
10750
10751   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10752     mp->integrity_key_length = sizeof (mp->integrity_key);
10753
10754   if (ck)
10755     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10756   if (ik)
10757     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10758
10759   if (is_tunnel)
10760     {
10761       if (is_tunnel_ipv6)
10762         {
10763           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10764                        sizeof (ip6_address_t));
10765           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10766                        sizeof (ip6_address_t));
10767         }
10768       else
10769         {
10770           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10771                        sizeof (ip4_address_t));
10772           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10773                        sizeof (ip4_address_t));
10774         }
10775     }
10776
10777   S;
10778   W;
10779   /* NOTREACHED */
10780   return 0;
10781 #else
10782   clib_warning ("unsupported (no dpdk)");
10783   return -99;
10784 #endif
10785 }
10786
10787 static int
10788 api_ipsec_sa_set_key (vat_main_t * vam)
10789 {
10790 #if DPDK > 0
10791   unformat_input_t *i = vam->input;
10792   vl_api_ipsec_sa_set_key_t *mp;
10793   f64 timeout;
10794   u32 sa_id;
10795   u8 *ck = 0, *ik = 0;
10796
10797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10798     {
10799       if (unformat (i, "sa_id %d", &sa_id))
10800         ;
10801       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10802         ;
10803       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10804         ;
10805       else
10806         {
10807           clib_warning ("parse error '%U'", format_unformat_error, i);
10808           return -99;
10809         }
10810     }
10811
10812   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10813
10814   mp->sa_id = ntohl (sa_id);
10815   mp->crypto_key_length = vec_len (ck);
10816   mp->integrity_key_length = vec_len (ik);
10817
10818   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10819     mp->crypto_key_length = sizeof (mp->crypto_key);
10820
10821   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10822     mp->integrity_key_length = sizeof (mp->integrity_key);
10823
10824   if (ck)
10825     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10826   if (ik)
10827     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10828
10829   S;
10830   W;
10831   /* NOTREACHED */
10832   return 0;
10833 #else
10834   clib_warning ("unsupported (no dpdk)");
10835   return -99;
10836 #endif
10837 }
10838
10839 static int
10840 api_ikev2_profile_add_del (vat_main_t * vam)
10841 {
10842 #if DPDK > 0
10843   unformat_input_t *i = vam->input;
10844   vl_api_ikev2_profile_add_del_t *mp;
10845   f64 timeout;
10846   u8 is_add = 1;
10847   u8 *name = 0;
10848
10849   const char *valid_chars = "a-zA-Z0-9_";
10850
10851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10852     {
10853       if (unformat (i, "del"))
10854         is_add = 0;
10855       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10856         vec_add1 (name, 0);
10857       else
10858         {
10859           errmsg ("parse error '%U'", format_unformat_error, i);
10860           return -99;
10861         }
10862     }
10863
10864   if (!vec_len (name))
10865     {
10866       errmsg ("profile name must be specified");
10867       return -99;
10868     }
10869
10870   if (vec_len (name) > 64)
10871     {
10872       errmsg ("profile name too long");
10873       return -99;
10874     }
10875
10876   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10877
10878   clib_memcpy (mp->name, name, vec_len (name));
10879   mp->is_add = is_add;
10880   vec_free (name);
10881
10882   S;
10883   W;
10884   /* NOTREACHED */
10885   return 0;
10886 #else
10887   clib_warning ("unsupported (no dpdk)");
10888   return -99;
10889 #endif
10890 }
10891
10892 static int
10893 api_ikev2_profile_set_auth (vat_main_t * vam)
10894 {
10895 #if DPDK > 0
10896   unformat_input_t *i = vam->input;
10897   vl_api_ikev2_profile_set_auth_t *mp;
10898   f64 timeout;
10899   u8 *name = 0;
10900   u8 *data = 0;
10901   u32 auth_method = 0;
10902   u8 is_hex = 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, "name %U", unformat_token, valid_chars, &name))
10909         vec_add1 (name, 0);
10910       else if (unformat (i, "auth_method %U",
10911                          unformat_ikev2_auth_method, &auth_method))
10912         ;
10913       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10914         is_hex = 1;
10915       else if (unformat (i, "auth_data %v", &data))
10916         ;
10917       else
10918         {
10919           errmsg ("parse error '%U'", format_unformat_error, i);
10920           return -99;
10921         }
10922     }
10923
10924   if (!vec_len (name))
10925     {
10926       errmsg ("profile name must be specified");
10927       return -99;
10928     }
10929
10930   if (vec_len (name) > 64)
10931     {
10932       errmsg ("profile name too long");
10933       return -99;
10934     }
10935
10936   if (!vec_len (data))
10937     {
10938       errmsg ("auth_data must be specified");
10939       return -99;
10940     }
10941
10942   if (!auth_method)
10943     {
10944       errmsg ("auth_method must be specified");
10945       return -99;
10946     }
10947
10948   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10949
10950   mp->is_hex = is_hex;
10951   mp->auth_method = (u8) auth_method;
10952   mp->data_len = vec_len (data);
10953   clib_memcpy (mp->name, name, vec_len (name));
10954   clib_memcpy (mp->data, data, vec_len (data));
10955   vec_free (name);
10956   vec_free (data);
10957
10958   S;
10959   W;
10960   /* NOTREACHED */
10961   return 0;
10962 #else
10963   clib_warning ("unsupported (no dpdk)");
10964   return -99;
10965 #endif
10966 }
10967
10968 static int
10969 api_ikev2_profile_set_id (vat_main_t * vam)
10970 {
10971 #if DPDK > 0
10972   unformat_input_t *i = vam->input;
10973   vl_api_ikev2_profile_set_id_t *mp;
10974   f64 timeout;
10975   u8 *name = 0;
10976   u8 *data = 0;
10977   u8 is_local = 0;
10978   u32 id_type = 0;
10979   ip4_address_t ip4;
10980
10981   const char *valid_chars = "a-zA-Z0-9_";
10982
10983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10984     {
10985       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10986         vec_add1 (name, 0);
10987       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10988         ;
10989       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10990         {
10991           data = vec_new (u8, 4);
10992           clib_memcpy (data, ip4.as_u8, 4);
10993         }
10994       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10995         ;
10996       else if (unformat (i, "id_data %v", &data))
10997         ;
10998       else if (unformat (i, "local"))
10999         is_local = 1;
11000       else if (unformat (i, "remote"))
11001         is_local = 0;
11002       else
11003         {
11004           errmsg ("parse error '%U'", format_unformat_error, i);
11005           return -99;
11006         }
11007     }
11008
11009   if (!vec_len (name))
11010     {
11011       errmsg ("profile name must be specified");
11012       return -99;
11013     }
11014
11015   if (vec_len (name) > 64)
11016     {
11017       errmsg ("profile name too long");
11018       return -99;
11019     }
11020
11021   if (!vec_len (data))
11022     {
11023       errmsg ("id_data must be specified");
11024       return -99;
11025     }
11026
11027   if (!id_type)
11028     {
11029       errmsg ("id_type must be specified");
11030       return -99;
11031     }
11032
11033   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11034
11035   mp->is_local = is_local;
11036   mp->id_type = (u8) id_type;
11037   mp->data_len = vec_len (data);
11038   clib_memcpy (mp->name, name, vec_len (name));
11039   clib_memcpy (mp->data, data, vec_len (data));
11040   vec_free (name);
11041   vec_free (data);
11042
11043   S;
11044   W;
11045   /* NOTREACHED */
11046   return 0;
11047 #else
11048   clib_warning ("unsupported (no dpdk)");
11049   return -99;
11050 #endif
11051 }
11052
11053 static int
11054 api_ikev2_profile_set_ts (vat_main_t * vam)
11055 {
11056 #if DPDK > 0
11057   unformat_input_t *i = vam->input;
11058   vl_api_ikev2_profile_set_ts_t *mp;
11059   f64 timeout;
11060   u8 *name = 0;
11061   u8 is_local = 0;
11062   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11063   ip4_address_t start_addr, end_addr;
11064
11065   const char *valid_chars = "a-zA-Z0-9_";
11066
11067   start_addr.as_u32 = 0;
11068   end_addr.as_u32 = (u32) ~ 0;
11069
11070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11071     {
11072       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11073         vec_add1 (name, 0);
11074       else if (unformat (i, "protocol %d", &proto))
11075         ;
11076       else if (unformat (i, "start_port %d", &start_port))
11077         ;
11078       else if (unformat (i, "end_port %d", &end_port))
11079         ;
11080       else
11081         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11082         ;
11083       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11084         ;
11085       else if (unformat (i, "local"))
11086         is_local = 1;
11087       else if (unformat (i, "remote"))
11088         is_local = 0;
11089       else
11090         {
11091           errmsg ("parse error '%U'", format_unformat_error, i);
11092           return -99;
11093         }
11094     }
11095
11096   if (!vec_len (name))
11097     {
11098       errmsg ("profile name must be specified");
11099       return -99;
11100     }
11101
11102   if (vec_len (name) > 64)
11103     {
11104       errmsg ("profile name too long");
11105       return -99;
11106     }
11107
11108   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11109
11110   mp->is_local = is_local;
11111   mp->proto = (u8) proto;
11112   mp->start_port = (u16) start_port;
11113   mp->end_port = (u16) end_port;
11114   mp->start_addr = start_addr.as_u32;
11115   mp->end_addr = end_addr.as_u32;
11116   clib_memcpy (mp->name, name, vec_len (name));
11117   vec_free (name);
11118
11119   S;
11120   W;
11121   /* NOTREACHED */
11122   return 0;
11123 #else
11124   clib_warning ("unsupported (no dpdk)");
11125   return -99;
11126 #endif
11127 }
11128
11129 static int
11130 api_ikev2_set_local_key (vat_main_t * vam)
11131 {
11132 #if DPDK > 0
11133   unformat_input_t *i = vam->input;
11134   vl_api_ikev2_set_local_key_t *mp;
11135   f64 timeout;
11136   u8 *file = 0;
11137
11138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11139     {
11140       if (unformat (i, "file %v", &file))
11141         vec_add1 (file, 0);
11142       else
11143         {
11144           errmsg ("parse error '%U'", format_unformat_error, i);
11145           return -99;
11146         }
11147     }
11148
11149   if (!vec_len (file))
11150     {
11151       errmsg ("RSA key file must be specified");
11152       return -99;
11153     }
11154
11155   if (vec_len (file) > 256)
11156     {
11157       errmsg ("file name too long");
11158       return -99;
11159     }
11160
11161   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11162
11163   clib_memcpy (mp->key_file, file, vec_len (file));
11164   vec_free (file);
11165
11166   S;
11167   W;
11168   /* NOTREACHED */
11169   return 0;
11170 #else
11171   clib_warning ("unsupported (no dpdk)");
11172   return -99;
11173 #endif
11174 }
11175
11176 /*
11177  * MAP
11178  */
11179 static int
11180 api_map_add_domain (vat_main_t * vam)
11181 {
11182   unformat_input_t *i = vam->input;
11183   vl_api_map_add_domain_t *mp;
11184   f64 timeout;
11185
11186   ip4_address_t ip4_prefix;
11187   ip6_address_t ip6_prefix;
11188   ip6_address_t ip6_src;
11189   u32 num_m_args = 0;
11190   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11191     0, psid_length = 0;
11192   u8 is_translation = 0;
11193   u32 mtu = 0;
11194   u32 ip6_src_len = 128;
11195
11196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11197     {
11198       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11199                     &ip4_prefix, &ip4_prefix_len))
11200         num_m_args++;
11201       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11202                          &ip6_prefix, &ip6_prefix_len))
11203         num_m_args++;
11204       else
11205         if (unformat
11206             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11207              &ip6_src_len))
11208         num_m_args++;
11209       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11210         num_m_args++;
11211       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11212         num_m_args++;
11213       else if (unformat (i, "psid-offset %d", &psid_offset))
11214         num_m_args++;
11215       else if (unformat (i, "psid-len %d", &psid_length))
11216         num_m_args++;
11217       else if (unformat (i, "mtu %d", &mtu))
11218         num_m_args++;
11219       else if (unformat (i, "map-t"))
11220         is_translation = 1;
11221       else
11222         {
11223           clib_warning ("parse error '%U'", format_unformat_error, i);
11224           return -99;
11225         }
11226     }
11227
11228   if (num_m_args < 3)
11229     {
11230       errmsg ("mandatory argument(s) missing\n");
11231       return -99;
11232     }
11233
11234   /* Construct the API message */
11235   M (MAP_ADD_DOMAIN, map_add_domain);
11236
11237   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11238   mp->ip4_prefix_len = ip4_prefix_len;
11239
11240   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11241   mp->ip6_prefix_len = ip6_prefix_len;
11242
11243   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11244   mp->ip6_src_prefix_len = ip6_src_len;
11245
11246   mp->ea_bits_len = ea_bits_len;
11247   mp->psid_offset = psid_offset;
11248   mp->psid_length = psid_length;
11249   mp->is_translation = is_translation;
11250   mp->mtu = htons (mtu);
11251
11252   /* send it... */
11253   S;
11254
11255   /* Wait for a reply, return good/bad news  */
11256   W;
11257 }
11258
11259 static int
11260 api_map_del_domain (vat_main_t * vam)
11261 {
11262   unformat_input_t *i = vam->input;
11263   vl_api_map_del_domain_t *mp;
11264   f64 timeout;
11265
11266   u32 num_m_args = 0;
11267   u32 index;
11268
11269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11270     {
11271       if (unformat (i, "index %d", &index))
11272         num_m_args++;
11273       else
11274         {
11275           clib_warning ("parse error '%U'", format_unformat_error, i);
11276           return -99;
11277         }
11278     }
11279
11280   if (num_m_args != 1)
11281     {
11282       errmsg ("mandatory argument(s) missing\n");
11283       return -99;
11284     }
11285
11286   /* Construct the API message */
11287   M (MAP_DEL_DOMAIN, map_del_domain);
11288
11289   mp->index = ntohl (index);
11290
11291   /* send it... */
11292   S;
11293
11294   /* Wait for a reply, return good/bad news  */
11295   W;
11296 }
11297
11298 static int
11299 api_map_add_del_rule (vat_main_t * vam)
11300 {
11301   unformat_input_t *i = vam->input;
11302   vl_api_map_add_del_rule_t *mp;
11303   f64 timeout;
11304   u8 is_add = 1;
11305   ip6_address_t ip6_dst;
11306   u32 num_m_args = 0, index, psid = 0;
11307
11308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11309     {
11310       if (unformat (i, "index %d", &index))
11311         num_m_args++;
11312       else if (unformat (i, "psid %d", &psid))
11313         num_m_args++;
11314       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11315         num_m_args++;
11316       else if (unformat (i, "del"))
11317         {
11318           is_add = 0;
11319         }
11320       else
11321         {
11322           clib_warning ("parse error '%U'", format_unformat_error, i);
11323           return -99;
11324         }
11325     }
11326
11327   /* Construct the API message */
11328   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11329
11330   mp->index = ntohl (index);
11331   mp->is_add = is_add;
11332   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11333   mp->psid = ntohs (psid);
11334
11335   /* send it... */
11336   S;
11337
11338   /* Wait for a reply, return good/bad news  */
11339   W;
11340 }
11341
11342 static int
11343 api_map_domain_dump (vat_main_t * vam)
11344 {
11345   vl_api_map_domain_dump_t *mp;
11346   f64 timeout;
11347
11348   /* Construct the API message */
11349   M (MAP_DOMAIN_DUMP, map_domain_dump);
11350
11351   /* send it... */
11352   S;
11353
11354   /* Use a control ping for synchronization */
11355   {
11356     vl_api_control_ping_t *mp;
11357     M (CONTROL_PING, control_ping);
11358     S;
11359   }
11360   W;
11361 }
11362
11363 static int
11364 api_map_rule_dump (vat_main_t * vam)
11365 {
11366   unformat_input_t *i = vam->input;
11367   vl_api_map_rule_dump_t *mp;
11368   f64 timeout;
11369   u32 domain_index = ~0;
11370
11371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11372     {
11373       if (unformat (i, "index %u", &domain_index))
11374         ;
11375       else
11376         break;
11377     }
11378
11379   if (domain_index == ~0)
11380     {
11381       clib_warning ("parse error: domain index expected");
11382       return -99;
11383     }
11384
11385   /* Construct the API message */
11386   M (MAP_RULE_DUMP, map_rule_dump);
11387
11388   mp->domain_index = htonl (domain_index);
11389
11390   /* send it... */
11391   S;
11392
11393   /* Use a control ping for synchronization */
11394   {
11395     vl_api_control_ping_t *mp;
11396     M (CONTROL_PING, control_ping);
11397     S;
11398   }
11399   W;
11400 }
11401
11402 static void vl_api_map_add_domain_reply_t_handler
11403   (vl_api_map_add_domain_reply_t * mp)
11404 {
11405   vat_main_t *vam = &vat_main;
11406   i32 retval = ntohl (mp->retval);
11407
11408   if (vam->async_mode)
11409     {
11410       vam->async_errors += (retval < 0);
11411     }
11412   else
11413     {
11414       vam->retval = retval;
11415       vam->result_ready = 1;
11416     }
11417 }
11418
11419 static void vl_api_map_add_domain_reply_t_handler_json
11420   (vl_api_map_add_domain_reply_t * mp)
11421 {
11422   vat_main_t *vam = &vat_main;
11423   vat_json_node_t node;
11424
11425   vat_json_init_object (&node);
11426   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11427   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11428
11429   vat_json_print (vam->ofp, &node);
11430   vat_json_free (&node);
11431
11432   vam->retval = ntohl (mp->retval);
11433   vam->result_ready = 1;
11434 }
11435
11436 static int
11437 api_get_first_msg_id (vat_main_t * vam)
11438 {
11439   vl_api_get_first_msg_id_t *mp;
11440   f64 timeout;
11441   unformat_input_t *i = vam->input;
11442   u8 *name;
11443   u8 name_set = 0;
11444
11445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11446     {
11447       if (unformat (i, "client %s", &name))
11448         name_set = 1;
11449       else
11450         break;
11451     }
11452
11453   if (name_set == 0)
11454     {
11455       errmsg ("missing client name\n");
11456       return -99;
11457     }
11458   vec_add1 (name, 0);
11459
11460   if (vec_len (name) > 63)
11461     {
11462       errmsg ("client name too long\n");
11463       return -99;
11464     }
11465
11466   M (GET_FIRST_MSG_ID, get_first_msg_id);
11467   clib_memcpy (mp->name, name, vec_len (name));
11468   S;
11469   W;
11470   /* NOTREACHED */
11471   return 0;
11472 }
11473
11474 static int
11475 api_cop_interface_enable_disable (vat_main_t * vam)
11476 {
11477   unformat_input_t *line_input = vam->input;
11478   vl_api_cop_interface_enable_disable_t *mp;
11479   f64 timeout;
11480   u32 sw_if_index = ~0;
11481   u8 enable_disable = 1;
11482
11483   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (line_input, "disable"))
11486         enable_disable = 0;
11487       if (unformat (line_input, "enable"))
11488         enable_disable = 1;
11489       else if (unformat (line_input, "%U", unformat_sw_if_index,
11490                          vam, &sw_if_index))
11491         ;
11492       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11493         ;
11494       else
11495         break;
11496     }
11497
11498   if (sw_if_index == ~0)
11499     {
11500       errmsg ("missing interface name or sw_if_index\n");
11501       return -99;
11502     }
11503
11504   /* Construct the API message */
11505   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11506   mp->sw_if_index = ntohl (sw_if_index);
11507   mp->enable_disable = enable_disable;
11508
11509   /* send it... */
11510   S;
11511   /* Wait for the reply */
11512   W;
11513 }
11514
11515 static int
11516 api_cop_whitelist_enable_disable (vat_main_t * vam)
11517 {
11518   unformat_input_t *line_input = vam->input;
11519   vl_api_cop_whitelist_enable_disable_t *mp;
11520   f64 timeout;
11521   u32 sw_if_index = ~0;
11522   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11523   u32 fib_id = 0;
11524
11525   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11526     {
11527       if (unformat (line_input, "ip4"))
11528         ip4 = 1;
11529       else if (unformat (line_input, "ip6"))
11530         ip6 = 1;
11531       else if (unformat (line_input, "default"))
11532         default_cop = 1;
11533       else if (unformat (line_input, "%U", unformat_sw_if_index,
11534                          vam, &sw_if_index))
11535         ;
11536       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11537         ;
11538       else if (unformat (line_input, "fib-id %d", &fib_id))
11539         ;
11540       else
11541         break;
11542     }
11543
11544   if (sw_if_index == ~0)
11545     {
11546       errmsg ("missing interface name or sw_if_index\n");
11547       return -99;
11548     }
11549
11550   /* Construct the API message */
11551   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11552   mp->sw_if_index = ntohl (sw_if_index);
11553   mp->fib_id = ntohl (fib_id);
11554   mp->ip4 = ip4;
11555   mp->ip6 = ip6;
11556   mp->default_cop = default_cop;
11557
11558   /* send it... */
11559   S;
11560   /* Wait for the reply */
11561   W;
11562 }
11563
11564 static int
11565 api_get_node_graph (vat_main_t * vam)
11566 {
11567   vl_api_get_node_graph_t *mp;
11568   f64 timeout;
11569
11570   M (GET_NODE_GRAPH, get_node_graph);
11571
11572   /* send it... */
11573   S;
11574   /* Wait for the reply */
11575   W;
11576 }
11577
11578 /* *INDENT-OFF* */
11579 /** Used for parsing LISP eids */
11580 typedef CLIB_PACKED(struct{
11581   u8 addr[16];   /**< eid address */
11582   u32 len;       /**< prefix length if IP */
11583   u8 type;      /**< type of eid */
11584 }) lisp_eid_vat_t;
11585 /* *INDENT-ON* */
11586
11587 static uword
11588 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11589 {
11590   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11591
11592   memset (a, 0, sizeof (a[0]));
11593
11594   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11595     {
11596       a->type = 0;              /* ipv4 type */
11597     }
11598   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11599     {
11600       a->type = 1;              /* ipv6 type */
11601     }
11602   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11603     {
11604       a->type = 2;              /* mac type */
11605     }
11606   else
11607     {
11608       return 0;
11609     }
11610
11611   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11612     {
11613       return 0;
11614     }
11615
11616   return 1;
11617 }
11618
11619 static int
11620 lisp_eid_size_vat (u8 type)
11621 {
11622   switch (type)
11623     {
11624     case 0:
11625       return 4;
11626     case 1:
11627       return 16;
11628     case 2:
11629       return 6;
11630     }
11631   return 0;
11632 }
11633
11634 static void
11635 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11636 {
11637   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11638 }
11639
11640 /* *INDENT-OFF* */
11641 /** Used for transferring locators via VPP API */
11642 typedef CLIB_PACKED(struct
11643 {
11644   u32 sw_if_index; /**< locator sw_if_index */
11645   u8 priority; /**< locator priority */
11646   u8 weight;   /**< locator weight */
11647 }) ls_locator_t;
11648 /* *INDENT-ON* */
11649
11650 static int
11651 api_lisp_add_del_locator_set (vat_main_t * vam)
11652 {
11653   unformat_input_t *input = vam->input;
11654   vl_api_lisp_add_del_locator_set_t *mp;
11655   f64 timeout = ~0;
11656   u8 is_add = 1;
11657   u8 *locator_set_name = NULL;
11658   u8 locator_set_name_set = 0;
11659   ls_locator_t locator, *locators = 0;
11660   u32 sw_if_index, priority, weight;
11661
11662   /* Parse args required to build the message */
11663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11664     {
11665       if (unformat (input, "del"))
11666         {
11667           is_add = 0;
11668         }
11669       else if (unformat (input, "locator-set %s", &locator_set_name))
11670         {
11671           locator_set_name_set = 1;
11672         }
11673       else if (unformat (input, "sw_if_index %u p %u w %u",
11674                          &sw_if_index, &priority, &weight))
11675         {
11676           locator.sw_if_index = htonl (sw_if_index);
11677           locator.priority = priority;
11678           locator.weight = weight;
11679           vec_add1 (locators, locator);
11680         }
11681       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11682                          vam, &sw_if_index, &priority, &weight))
11683         {
11684           locator.sw_if_index = htonl (sw_if_index);
11685           locator.priority = priority;
11686           locator.weight = weight;
11687           vec_add1 (locators, locator);
11688         }
11689       else
11690         break;
11691     }
11692
11693   if (locator_set_name_set == 0)
11694     {
11695       errmsg ("missing locator-set name");
11696       vec_free (locators);
11697       return -99;
11698     }
11699
11700   if (vec_len (locator_set_name) > 64)
11701     {
11702       errmsg ("locator-set name too long\n");
11703       vec_free (locator_set_name);
11704       vec_free (locators);
11705       return -99;
11706     }
11707   vec_add1 (locator_set_name, 0);
11708
11709   /* Construct the API message */
11710   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11711
11712   mp->is_add = is_add;
11713   clib_memcpy (mp->locator_set_name, locator_set_name,
11714                vec_len (locator_set_name));
11715   vec_free (locator_set_name);
11716
11717   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11718   if (locators)
11719     clib_memcpy (mp->locators, locators,
11720                  (sizeof (ls_locator_t) * vec_len (locators)));
11721   vec_free (locators);
11722
11723   /* send it... */
11724   S;
11725
11726   /* Wait for a reply... */
11727   W;
11728
11729   /* NOTREACHED */
11730   return 0;
11731 }
11732
11733 static int
11734 api_lisp_add_del_locator (vat_main_t * vam)
11735 {
11736   unformat_input_t *input = vam->input;
11737   vl_api_lisp_add_del_locator_t *mp;
11738   f64 timeout = ~0;
11739   u32 tmp_if_index = ~0;
11740   u32 sw_if_index = ~0;
11741   u8 sw_if_index_set = 0;
11742   u8 sw_if_index_if_name_set = 0;
11743   u32 priority = ~0;
11744   u8 priority_set = 0;
11745   u32 weight = ~0;
11746   u8 weight_set = 0;
11747   u8 is_add = 1;
11748   u8 *locator_set_name = NULL;
11749   u8 locator_set_name_set = 0;
11750
11751   /* Parse args required to build the message */
11752   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11753     {
11754       if (unformat (input, "del"))
11755         {
11756           is_add = 0;
11757         }
11758       else if (unformat (input, "locator-set %s", &locator_set_name))
11759         {
11760           locator_set_name_set = 1;
11761         }
11762       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11763                          &tmp_if_index))
11764         {
11765           sw_if_index_if_name_set = 1;
11766           sw_if_index = tmp_if_index;
11767         }
11768       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11769         {
11770           sw_if_index_set = 1;
11771           sw_if_index = tmp_if_index;
11772         }
11773       else if (unformat (input, "p %d", &priority))
11774         {
11775           priority_set = 1;
11776         }
11777       else if (unformat (input, "w %d", &weight))
11778         {
11779           weight_set = 1;
11780         }
11781       else
11782         break;
11783     }
11784
11785   if (locator_set_name_set == 0)
11786     {
11787       errmsg ("missing locator-set name");
11788       return -99;
11789     }
11790
11791   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11792     {
11793       errmsg ("missing sw_if_index");
11794       vec_free (locator_set_name);
11795       return -99;
11796     }
11797
11798   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11799     {
11800       errmsg ("cannot use both params interface name and sw_if_index");
11801       vec_free (locator_set_name);
11802       return -99;
11803     }
11804
11805   if (priority_set == 0)
11806     {
11807       errmsg ("missing locator-set priority\n");
11808       vec_free (locator_set_name);
11809       return -99;
11810     }
11811
11812   if (weight_set == 0)
11813     {
11814       errmsg ("missing locator-set weight\n");
11815       vec_free (locator_set_name);
11816       return -99;
11817     }
11818
11819   if (vec_len (locator_set_name) > 64)
11820     {
11821       errmsg ("locator-set name too long\n");
11822       vec_free (locator_set_name);
11823       return -99;
11824     }
11825   vec_add1 (locator_set_name, 0);
11826
11827   /* Construct the API message */
11828   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11829
11830   mp->is_add = is_add;
11831   mp->sw_if_index = ntohl (sw_if_index);
11832   mp->priority = priority;
11833   mp->weight = weight;
11834   clib_memcpy (mp->locator_set_name, locator_set_name,
11835                vec_len (locator_set_name));
11836   vec_free (locator_set_name);
11837
11838   /* send it... */
11839   S;
11840
11841   /* Wait for a reply... */
11842   W;
11843
11844   /* NOTREACHED */
11845   return 0;
11846 }
11847
11848 static int
11849 api_lisp_add_del_local_eid (vat_main_t * vam)
11850 {
11851   unformat_input_t *input = vam->input;
11852   vl_api_lisp_add_del_local_eid_t *mp;
11853   f64 timeout = ~0;
11854   u8 is_add = 1;
11855   u8 eid_set = 0;
11856   lisp_eid_vat_t _eid, *eid = &_eid;
11857   u8 *locator_set_name = 0;
11858   u8 locator_set_name_set = 0;
11859   u32 vni = 0;
11860
11861   /* Parse args required to build the message */
11862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11863     {
11864       if (unformat (input, "del"))
11865         {
11866           is_add = 0;
11867         }
11868       else if (unformat (input, "vni %d", &vni))
11869         {
11870           ;
11871         }
11872       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11873         {
11874           eid_set = 1;
11875         }
11876       else if (unformat (input, "locator-set %s", &locator_set_name))
11877         {
11878           locator_set_name_set = 1;
11879         }
11880       else
11881         break;
11882     }
11883
11884   if (locator_set_name_set == 0)
11885     {
11886       errmsg ("missing locator-set name\n");
11887       return -99;
11888     }
11889
11890   if (0 == eid_set)
11891     {
11892       errmsg ("EID address not set!");
11893       vec_free (locator_set_name);
11894       return -99;
11895     }
11896
11897   if (vec_len (locator_set_name) > 64)
11898     {
11899       errmsg ("locator-set name too long\n");
11900       vec_free (locator_set_name);
11901       return -99;
11902     }
11903   vec_add1 (locator_set_name, 0);
11904
11905   /* Construct the API message */
11906   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11907
11908   mp->is_add = is_add;
11909   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11910   mp->eid_type = eid->type;
11911   mp->prefix_len = eid->len;
11912   mp->vni = clib_host_to_net_u32 (vni);
11913   clib_memcpy (mp->locator_set_name, locator_set_name,
11914                vec_len (locator_set_name));
11915
11916   vec_free (locator_set_name);
11917
11918   /* send it... */
11919   S;
11920
11921   /* Wait for a reply... */
11922   W;
11923
11924   /* NOTREACHED */
11925   return 0;
11926 }
11927
11928 /* *INDENT-OFF* */
11929 /** Used for transferring locators via VPP API */
11930 typedef CLIB_PACKED(struct
11931 {
11932   u8 is_ip4; /**< is locator an IPv4 address? */
11933   u8 priority; /**< locator priority */
11934   u8 weight;   /**< locator weight */
11935   u8 addr[16]; /**< IPv4/IPv6 address */
11936 }) rloc_t;
11937 /* *INDENT-ON* */
11938
11939 static int
11940 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11941 {
11942   unformat_input_t *input = vam->input;
11943   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11944   f64 timeout = ~0;
11945   u8 is_add = 1;
11946   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11947   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11948   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11949   u32 action = ~0, p, w;
11950   ip4_address_t rmt_rloc4, lcl_rloc4;
11951   ip6_address_t rmt_rloc6, lcl_rloc6;
11952   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11953
11954   memset (&rloc, 0, sizeof (rloc));
11955
11956   /* Parse args required to build the message */
11957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11958     {
11959       if (unformat (input, "del"))
11960         {
11961           is_add = 0;
11962         }
11963       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11964         {
11965           rmt_eid_set = 1;
11966         }
11967       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11968         {
11969           lcl_eid_set = 1;
11970         }
11971       else if (unformat (input, "p %d w %d", &p, &w))
11972         {
11973           if (!curr_rloc)
11974             {
11975               errmsg ("No RLOC configured for setting priority/weight!");
11976               return -99;
11977             }
11978           curr_rloc->priority = p;
11979           curr_rloc->weight = w;
11980         }
11981       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11982                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11983         {
11984           rloc.is_ip4 = 1;
11985
11986           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11987           rloc.priority = rloc.weight = 0;
11988           vec_add1 (lcl_locs, rloc);
11989
11990           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11991           vec_add1 (rmt_locs, rloc);
11992           /* priority and weight saved in rmt loc */
11993           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11994         }
11995       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11996                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11997         {
11998           rloc.is_ip4 = 0;
11999           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12000           rloc.priority = rloc.weight = 0;
12001           vec_add1 (lcl_locs, rloc);
12002
12003           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12004           vec_add1 (rmt_locs, rloc);
12005           /* priority and weight saved in rmt loc */
12006           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12007         }
12008       else if (unformat (input, "action %d", &action))
12009         {
12010           ;
12011         }
12012       else
12013         {
12014           clib_warning ("parse error '%U'", format_unformat_error, input);
12015           return -99;
12016         }
12017     }
12018
12019   if (!rmt_eid_set)
12020     {
12021       errmsg ("remote eid addresses not set\n");
12022       return -99;
12023     }
12024
12025   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12026     {
12027       errmsg ("eid types don't match\n");
12028       return -99;
12029     }
12030
12031   if (0 == rmt_locs && (u32) ~ 0 == action)
12032     {
12033       errmsg ("action not set for negative mapping\n");
12034       return -99;
12035     }
12036
12037   /* Construct the API message */
12038   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12039
12040   mp->is_add = is_add;
12041   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12042   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12043   mp->eid_type = rmt_eid->type;
12044   mp->rmt_len = rmt_eid->len;
12045   mp->lcl_len = lcl_eid->len;
12046   mp->action = action;
12047
12048   if (0 != rmt_locs && 0 != lcl_locs)
12049     {
12050       mp->loc_num = vec_len (rmt_locs);
12051       clib_memcpy (mp->lcl_locs, lcl_locs,
12052                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12053       clib_memcpy (mp->rmt_locs, rmt_locs,
12054                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12055     }
12056   vec_free (lcl_locs);
12057   vec_free (rmt_locs);
12058
12059   /* send it... */
12060   S;
12061
12062   /* Wait for a reply... */
12063   W;
12064
12065   /* NOTREACHED */
12066   return 0;
12067 }
12068
12069 static int
12070 api_lisp_add_del_map_resolver (vat_main_t * vam)
12071 {
12072   unformat_input_t *input = vam->input;
12073   vl_api_lisp_add_del_map_resolver_t *mp;
12074   f64 timeout = ~0;
12075   u8 is_add = 1;
12076   u8 ipv4_set = 0;
12077   u8 ipv6_set = 0;
12078   ip4_address_t ipv4;
12079   ip6_address_t ipv6;
12080
12081   /* Parse args required to build the message */
12082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12083     {
12084       if (unformat (input, "del"))
12085         {
12086           is_add = 0;
12087         }
12088       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12089         {
12090           ipv4_set = 1;
12091         }
12092       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12093         {
12094           ipv6_set = 1;
12095         }
12096       else
12097         break;
12098     }
12099
12100   if (ipv4_set && ipv6_set)
12101     {
12102       errmsg ("both eid v4 and v6 addresses set\n");
12103       return -99;
12104     }
12105
12106   if (!ipv4_set && !ipv6_set)
12107     {
12108       errmsg ("eid addresses not set\n");
12109       return -99;
12110     }
12111
12112   /* Construct the API message */
12113   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12114
12115   mp->is_add = is_add;
12116   if (ipv6_set)
12117     {
12118       mp->is_ipv6 = 1;
12119       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12120     }
12121   else
12122     {
12123       mp->is_ipv6 = 0;
12124       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12125     }
12126
12127   /* send it... */
12128   S;
12129
12130   /* Wait for a reply... */
12131   W;
12132
12133   /* NOTREACHED */
12134   return 0;
12135 }
12136
12137 static int
12138 api_lisp_gpe_enable_disable (vat_main_t * vam)
12139 {
12140   unformat_input_t *input = vam->input;
12141   vl_api_lisp_gpe_enable_disable_t *mp;
12142   f64 timeout = ~0;
12143   u8 is_set = 0;
12144   u8 is_en = 1;
12145
12146   /* Parse args required to build the message */
12147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12148     {
12149       if (unformat (input, "enable"))
12150         {
12151           is_set = 1;
12152           is_en = 1;
12153         }
12154       else if (unformat (input, "disable"))
12155         {
12156           is_set = 1;
12157           is_en = 0;
12158         }
12159       else
12160         break;
12161     }
12162
12163   if (is_set == 0)
12164     {
12165       errmsg ("Value not set\n");
12166       return -99;
12167     }
12168
12169   /* Construct the API message */
12170   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12171
12172   mp->is_en = is_en;
12173
12174   /* send it... */
12175   S;
12176
12177   /* Wait for a reply... */
12178   W;
12179
12180   /* NOTREACHED */
12181   return 0;
12182 }
12183
12184 static int
12185 api_lisp_enable_disable (vat_main_t * vam)
12186 {
12187   unformat_input_t *input = vam->input;
12188   vl_api_lisp_enable_disable_t *mp;
12189   f64 timeout = ~0;
12190   u8 is_set = 0;
12191   u8 is_en = 0;
12192
12193   /* Parse args required to build the message */
12194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12195     {
12196       if (unformat (input, "enable"))
12197         {
12198           is_set = 1;
12199           is_en = 1;
12200         }
12201       else if (unformat (input, "disable"))
12202         {
12203           is_set = 1;
12204         }
12205       else
12206         break;
12207     }
12208
12209   if (!is_set)
12210     {
12211       errmsg ("Value not set\n");
12212       return -99;
12213     }
12214
12215   /* Construct the API message */
12216   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12217
12218   mp->is_en = is_en;
12219
12220   /* send it... */
12221   S;
12222
12223   /* Wait for a reply... */
12224   W;
12225
12226   /* NOTREACHED */
12227   return 0;
12228 }
12229
12230 /**
12231  * Enable/disable LISP proxy ITR.
12232  *
12233  * @param vam vpp API test context
12234  * @return return code
12235  */
12236 static int
12237 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12238 {
12239   f64 timeout = ~0;
12240   u8 ls_name_set = 0;
12241   unformat_input_t *input = vam->input;
12242   vl_api_lisp_pitr_set_locator_set_t *mp;
12243   u8 is_add = 1;
12244   u8 *ls_name = 0;
12245
12246   /* Parse args required to build the message */
12247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12248     {
12249       if (unformat (input, "del"))
12250         is_add = 0;
12251       else if (unformat (input, "locator-set %s", &ls_name))
12252         ls_name_set = 1;
12253       else
12254         {
12255           errmsg ("parse error '%U'", format_unformat_error, input);
12256           return -99;
12257         }
12258     }
12259
12260   if (!ls_name_set)
12261     {
12262       errmsg ("locator-set name not set!");
12263       return -99;
12264     }
12265
12266   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12267
12268   mp->is_add = is_add;
12269   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12270   vec_free (ls_name);
12271
12272   /* send */
12273   S;
12274
12275   /* wait for reply */
12276   W;
12277
12278   /* notreached */
12279   return 0;
12280 }
12281
12282 static int
12283 api_show_lisp_pitr (vat_main_t * vam)
12284 {
12285   vl_api_show_lisp_pitr_t *mp;
12286   f64 timeout = ~0;
12287
12288   if (!vam->json_output)
12289     {
12290       fformat (vam->ofp, "%=20s\n", "lisp status:");
12291     }
12292
12293   M (SHOW_LISP_PITR, show_lisp_pitr);
12294   /* send it... */
12295   S;
12296
12297   /* Wait for a reply... */
12298   W;
12299
12300   /* NOTREACHED */
12301   return 0;
12302 }
12303
12304 /**
12305  * Add/delete mapping between vni and vrf
12306  */
12307 static int
12308 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12309 {
12310   f64 timeout = ~0;
12311   unformat_input_t *input = vam->input;
12312   vl_api_lisp_eid_table_add_del_map_t *mp;
12313   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12314   u32 vni, vrf, bd_index;
12315
12316   /* Parse args required to build the message */
12317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12318     {
12319       if (unformat (input, "del"))
12320         is_add = 0;
12321       else if (unformat (input, "vrf %d", &vrf))
12322         vrf_set = 1;
12323       else if (unformat (input, "bd_index %d", &bd_index))
12324         bd_index_set = 1;
12325       else if (unformat (input, "vni %d", &vni))
12326         vni_set = 1;
12327       else
12328         break;
12329     }
12330
12331   if (!vni_set || (!vrf_set && !bd_index_set))
12332     {
12333       errmsg ("missing arguments!");
12334       return -99;
12335     }
12336
12337   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12338
12339   mp->is_add = is_add;
12340   mp->vni = htonl (vni);
12341   mp->dp_table = htonl (vrf);
12342   mp->is_l2 = bd_index_set;
12343
12344   /* send */
12345   S;
12346
12347   /* wait for reply */
12348   W;
12349
12350   /* notreached */
12351   return 0;
12352 }
12353
12354 /**
12355  * Add/del remote mapping to/from LISP control plane
12356  *
12357  * @param vam vpp API test context
12358  * @return return code
12359  */
12360 static int
12361 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12362 {
12363   unformat_input_t *input = vam->input;
12364   vl_api_lisp_add_del_remote_mapping_t *mp;
12365   f64 timeout = ~0;
12366   u32 vni = 0;
12367   //TODO: seid need remove
12368   lisp_eid_vat_t _eid, *eid = &_eid;
12369   lisp_eid_vat_t _seid, *seid = &_seid;
12370   u8 is_add = 1, del_all = 0, eid_set = 0;
12371   u32 action = ~0, p, w;
12372   ip4_address_t rloc4;
12373   ip6_address_t rloc6;
12374   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12375
12376   memset (&rloc, 0, sizeof (rloc));
12377
12378   /* Parse args required to build the message */
12379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12380     {
12381       if (unformat (input, "del-all"))
12382         {
12383           del_all = 1;
12384         }
12385       else if (unformat (input, "del"))
12386         {
12387           is_add = 0;
12388         }
12389       else if (unformat (input, "add"))
12390         {
12391           is_add = 1;
12392         }
12393       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12394         {
12395           eid_set = 1;
12396         }
12397       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12398         {
12399           //TODO: Need remove, but first must be remove from CSIT test
12400         }
12401       else if (unformat (input, "vni %d", &vni))
12402         {
12403           ;
12404         }
12405       else if (unformat (input, "p %d w %d", &p, &w))
12406         {
12407           if (!curr_rloc)
12408             {
12409               errmsg ("No RLOC configured for setting priority/weight!");
12410               return -99;
12411             }
12412           curr_rloc->priority = p;
12413           curr_rloc->weight = w;
12414         }
12415       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12416         {
12417           rloc.is_ip4 = 1;
12418           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12419           vec_add1 (rlocs, rloc);
12420           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12421         }
12422       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12423         {
12424           rloc.is_ip4 = 0;
12425           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12426           vec_add1 (rlocs, rloc);
12427           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12428         }
12429       else if (unformat (input, "action %d", &action))
12430         {
12431           ;
12432         }
12433       else
12434         {
12435           clib_warning ("parse error '%U'", format_unformat_error, input);
12436           return -99;
12437         }
12438     }
12439
12440   if (0 == eid_set)
12441     {
12442       errmsg ("missing params!");
12443       return -99;
12444     }
12445
12446   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12447     {
12448       errmsg ("no action set for negative map-reply!");
12449       return -99;
12450     }
12451
12452   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12453   mp->is_add = is_add;
12454   mp->vni = htonl (vni);
12455   mp->action = (u8) action;
12456   mp->eid_len = eid->len;
12457   mp->del_all = del_all;
12458   mp->eid_type = eid->type;
12459   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12460
12461   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12462   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12463   vec_free (rlocs);
12464
12465   /* send it... */
12466   S;
12467
12468   /* Wait for a reply... */
12469   W;
12470
12471   /* NOTREACHED */
12472   return 0;
12473 }
12474
12475 /**
12476  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12477  * forwarding entries in data-plane accordingly.
12478  *
12479  * @param vam vpp API test context
12480  * @return return code
12481  */
12482 static int
12483 api_lisp_add_del_adjacency (vat_main_t * vam)
12484 {
12485   unformat_input_t *input = vam->input;
12486   vl_api_lisp_add_del_adjacency_t *mp;
12487   f64 timeout = ~0;
12488   u32 vni = 0;
12489   ip4_address_t seid4, deid4;
12490   ip6_address_t seid6, deid6;
12491   u8 deid_mac[6] = { 0 };
12492   u8 seid_mac[6] = { 0 };
12493   u8 deid_type, seid_type;
12494   u32 seid_len = 0, deid_len = 0, len;
12495   u8 is_add = 1;
12496
12497   seid_type = deid_type = (u8) ~ 0;
12498
12499   /* Parse args required to build the message */
12500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12501     {
12502       if (unformat (input, "del"))
12503         {
12504           is_add = 0;
12505         }
12506       else if (unformat (input, "add"))
12507         {
12508           is_add = 1;
12509         }
12510       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12511                          &deid4, &len))
12512         {
12513           deid_type = 0;        /* ipv4 */
12514           deid_len = len;
12515         }
12516       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12517                          &deid6, &len))
12518         {
12519           deid_type = 1;        /* ipv6 */
12520           deid_len = len;
12521         }
12522       else if (unformat (input, "deid %U", unformat_ethernet_address,
12523                          deid_mac))
12524         {
12525           deid_type = 2;        /* mac */
12526         }
12527       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12528                          &seid4, &len))
12529         {
12530           seid_type = 0;        /* ipv4 */
12531           seid_len = len;
12532         }
12533       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12534                          &seid6, &len))
12535         {
12536           seid_type = 1;        /* ipv6 */
12537           seid_len = len;
12538         }
12539       else if (unformat (input, "seid %U", unformat_ethernet_address,
12540                          seid_mac))
12541         {
12542           seid_type = 2;        /* mac */
12543         }
12544       else if (unformat (input, "vni %d", &vni))
12545         {
12546           ;
12547         }
12548       else
12549         {
12550           errmsg ("parse error '%U'", format_unformat_error, input);
12551           return -99;
12552         }
12553     }
12554
12555   if ((u8) ~ 0 == deid_type)
12556     {
12557       errmsg ("missing params!");
12558       return -99;
12559     }
12560
12561   if (seid_type != deid_type)
12562     {
12563       errmsg ("source and destination EIDs are of different types!");
12564       return -99;
12565     }
12566
12567   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12568   mp->is_add = is_add;
12569   mp->vni = htonl (vni);
12570   mp->seid_len = seid_len;
12571   mp->deid_len = deid_len;
12572   mp->eid_type = deid_type;
12573
12574   switch (mp->eid_type)
12575     {
12576     case 0:
12577       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12578       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12579       break;
12580     case 1:
12581       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12582       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12583       break;
12584     case 2:
12585       clib_memcpy (mp->seid, seid_mac, 6);
12586       clib_memcpy (mp->deid, deid_mac, 6);
12587       break;
12588     default:
12589       errmsg ("unknown EID type %d!", mp->eid_type);
12590       return 0;
12591     }
12592
12593   /* send it... */
12594   S;
12595
12596   /* Wait for a reply... */
12597   W;
12598
12599   /* NOTREACHED */
12600   return 0;
12601 }
12602
12603 static int
12604 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12605 {
12606   unformat_input_t *input = vam->input;
12607   vl_api_lisp_gpe_add_del_iface_t *mp;
12608   f64 timeout = ~0;
12609   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12610   u32 dp_table = 0, vni = 0;
12611
12612   /* Parse args required to build the message */
12613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12614     {
12615       if (unformat (input, "up"))
12616         {
12617           action_set = 1;
12618           is_add = 1;
12619         }
12620       else if (unformat (input, "down"))
12621         {
12622           action_set = 1;
12623           is_add = 0;
12624         }
12625       else if (unformat (input, "table_id %d", &dp_table))
12626         {
12627           dp_table_set = 1;
12628         }
12629       else if (unformat (input, "bd_id %d", &dp_table))
12630         {
12631           dp_table_set = 1;
12632           is_l2 = 1;
12633         }
12634       else if (unformat (input, "vni %d", &vni))
12635         {
12636           vni_set = 1;
12637         }
12638       else
12639         break;
12640     }
12641
12642   if (action_set == 0)
12643     {
12644       errmsg ("Action not set\n");
12645       return -99;
12646     }
12647   if (dp_table_set == 0 || vni_set == 0)
12648     {
12649       errmsg ("vni and dp_table must be set\n");
12650       return -99;
12651     }
12652
12653   /* Construct the API message */
12654   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12655
12656   mp->is_add = is_add;
12657   mp->dp_table = dp_table;
12658   mp->is_l2 = is_l2;
12659   mp->vni = vni;
12660
12661   /* send it... */
12662   S;
12663
12664   /* Wait for a reply... */
12665   W;
12666
12667   /* NOTREACHED */
12668   return 0;
12669 }
12670
12671 /**
12672  * Add/del map request itr rlocs from LISP control plane and updates
12673  *
12674  * @param vam vpp API test context
12675  * @return return code
12676  */
12677 static int
12678 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12679 {
12680   unformat_input_t *input = vam->input;
12681   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12682   f64 timeout = ~0;
12683   u8 *locator_set_name = 0;
12684   u8 locator_set_name_set = 0;
12685   u8 is_add = 1;
12686
12687   /* Parse args required to build the message */
12688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (input, "del"))
12691         {
12692           is_add = 0;
12693         }
12694       else if (unformat (input, "%_%v%_", &locator_set_name))
12695         {
12696           locator_set_name_set = 1;
12697         }
12698       else
12699         {
12700           clib_warning ("parse error '%U'", format_unformat_error, input);
12701           return -99;
12702         }
12703     }
12704
12705   if (is_add && !locator_set_name_set)
12706     {
12707       errmsg ("itr-rloc is not set!");
12708       return -99;
12709     }
12710
12711   if (is_add && vec_len (locator_set_name) > 64)
12712     {
12713       errmsg ("itr-rloc locator-set name too long\n");
12714       vec_free (locator_set_name);
12715       return -99;
12716     }
12717
12718   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12719   mp->is_add = is_add;
12720   if (is_add)
12721     {
12722       clib_memcpy (mp->locator_set_name, locator_set_name,
12723                    vec_len (locator_set_name));
12724     }
12725   else
12726     {
12727       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12728     }
12729   vec_free (locator_set_name);
12730
12731   /* send it... */
12732   S;
12733
12734   /* Wait for a reply... */
12735   W;
12736
12737   /* NOTREACHED */
12738   return 0;
12739 }
12740
12741 static int
12742 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12743                             u8 filter)
12744 {
12745   vl_api_lisp_locator_dump_t *mp;
12746   f64 timeout = ~0;
12747
12748   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12749
12750   mp->locator_set_index = htonl (locator_set_index);
12751   mp->filter = filter;
12752
12753   /* send it... */
12754   S;
12755
12756   /* Use a control ping for synchronization */
12757   {
12758     vl_api_noprint_control_ping_t *mp;
12759     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12760     S;
12761   }
12762   /* Wait for a reply... */
12763   W;
12764 }
12765
12766 static inline void
12767 clean_locator_set_message (vat_main_t * vam)
12768 {
12769   locator_set_msg_t *ls = 0;
12770
12771   vec_foreach (ls, vam->locator_set_msg)
12772   {
12773     vec_free (ls->locator_set_name);
12774   }
12775
12776   vec_free (vam->locator_set_msg);
12777 }
12778
12779 static int
12780 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12781 {
12782   locator_set_msg_t *ls;
12783   locator_msg_t *loc;
12784   u8 *tmp_str = 0;
12785   int i = 0, ret = 0;
12786
12787   vec_foreach (ls, vam->locator_set_msg)
12788   {
12789     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12790     if (ret)
12791       {
12792         vec_free (vam->locator_msg);
12793         clean_locator_set_message (vam);
12794         return ret;
12795       }
12796
12797     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12798                       ls->locator_set_index,
12799                       vec_len (vam->locator_msg) ? "" : "\n");
12800     i = 0;
12801     vec_foreach (loc, vam->locator_msg)
12802     {
12803       if (i)
12804         {
12805           tmp_str = format (tmp_str, "%=37s", " ");
12806         }
12807       if (loc->local)
12808         {
12809           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12810                             loc->sw_if_index, loc->priority, loc->weight);
12811         }
12812       else
12813         {
12814           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12815                             loc->is_ipv6 ? format_ip6_address :
12816                             format_ip4_address,
12817                             loc->ip_address, loc->priority, loc->weight);
12818         }
12819       i++;
12820     }
12821
12822     fformat (vam->ofp, "%s", tmp_str);
12823     vec_free (tmp_str);
12824     vec_free (vam->locator_msg);
12825   }
12826
12827   clean_locator_set_message (vam);
12828
12829   return ret;
12830 }
12831
12832 static int
12833 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12834 {
12835   locator_set_msg_t *ls;
12836   locator_msg_t *loc;
12837   vat_json_node_t *node = NULL;
12838   vat_json_node_t *locator_array;
12839   vat_json_node_t *locator;
12840   struct in6_addr ip6;
12841   struct in_addr ip4;
12842   int ret = 0;
12843
12844   if (!vec_len (vam->locator_set_msg))
12845     {
12846       /* just print [] */
12847       vat_json_init_array (&vam->json_tree);
12848       vat_json_print (vam->ofp, &vam->json_tree);
12849       vam->json_tree.type = VAT_JSON_NONE;
12850       return ret;
12851     }
12852
12853   if (VAT_JSON_ARRAY != vam->json_tree.type)
12854     {
12855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12856       vat_json_init_array (&vam->json_tree);
12857     }
12858
12859   vec_foreach (ls, vam->locator_set_msg)
12860   {
12861     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12862     if (ret)
12863       {
12864         vec_free (ls->locator_set_name);
12865         vec_free (vam->locator_msg);
12866         vec_free (vam->locator_set_msg);
12867         vat_json_free (&vam->json_tree);
12868         vam->json_tree.type = VAT_JSON_NONE;
12869         return ret;
12870       }
12871
12872     node = vat_json_array_add (&vam->json_tree);
12873     vat_json_init_object (node);
12874
12875     vat_json_object_add_uint (node, "locator-set-index",
12876                               ls->locator_set_index);
12877     vat_json_object_add_string_copy (node, "locator-set",
12878                                      ls->locator_set_name);
12879     locator_array = vat_json_object_add_list (node, "locator");
12880     vec_foreach (loc, vam->locator_msg)
12881     {
12882       locator = vat_json_array_add (locator_array);
12883       vat_json_init_object (locator);
12884       if (loc->local)
12885         {
12886           vat_json_object_add_uint (locator, "locator-index",
12887                                     loc->sw_if_index);
12888         }
12889       else
12890         {
12891           if (loc->is_ipv6)
12892             {
12893               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12894               vat_json_object_add_ip6 (locator, "locator", ip6);
12895             }
12896           else
12897             {
12898               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12899               vat_json_object_add_ip4 (locator, "locator", ip4);
12900             }
12901         }
12902       vat_json_object_add_uint (locator, "priority", loc->priority);
12903       vat_json_object_add_uint (locator, "weight", loc->weight);
12904     }
12905
12906     vec_free (ls->locator_set_name);
12907     vec_free (vam->locator_msg);
12908   }
12909
12910   vat_json_print (vam->ofp, &vam->json_tree);
12911   vat_json_free (&vam->json_tree);
12912   vam->json_tree.type = VAT_JSON_NONE;
12913
12914   vec_free (vam->locator_set_msg);
12915
12916   return ret;
12917 }
12918
12919 static int
12920 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12921                                 u32 * locator_set_index)
12922 {
12923   locator_set_msg_t *ls;
12924   int ret = 0;
12925
12926   *locator_set_index = ~0;
12927
12928   if (!vec_len (vam->locator_set_msg))
12929     {
12930       return ret;
12931     }
12932
12933   vec_foreach (ls, vam->locator_set_msg)
12934   {
12935     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12936       {
12937         *locator_set_index = ls->locator_set_index;
12938         vec_free (vam->locator_set_msg);
12939         return ret;
12940       }
12941   }
12942
12943   vec_free (vam->locator_set_msg);
12944
12945   return ret;
12946 }
12947
12948 static int
12949 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12950                        u32 * locator_set_index)
12951 {
12952   vl_api_lisp_locator_set_dump_t *mp;
12953   f64 timeout = ~0;
12954
12955   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12956   /* send it... */
12957   S;
12958
12959   /* Use a control ping for synchronization */
12960   {
12961     vl_api_noprint_control_ping_t *mp;
12962     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12963     S;
12964   }
12965
12966   vam->noprint_msg = 1;
12967   /* Wait for a reply... */
12968   /* *INDENT-OFF* */
12969   W_L
12970   ({
12971     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12972     vam->noprint_msg = 0;
12973   });
12974   /* *INDENT-ON* */
12975
12976   /* NOTREACHED */
12977   return 0;
12978 }
12979
12980 static inline int
12981 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12982                    u8 filter)
12983 {
12984   int ret = 0;
12985
12986   ASSERT (vam);
12987
12988   if (!vam->json_output)
12989     {
12990       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12991                "locator", "priority", "weight");
12992     }
12993
12994   if (locator_set)
12995     {
12996       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
12997     }
12998
12999   if (!ret && ~0 == locator_set_index)
13000     {
13001       return -99;
13002     }
13003
13004   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13005
13006   return ret;
13007 }
13008
13009 static int
13010 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13011 {
13012   vl_api_lisp_locator_set_dump_t *mp;
13013   f64 timeout = ~0;
13014
13015   if (!vam->json_output)
13016     {
13017       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13018                "locator-set", "locator-set-index", "locator", "priority",
13019                "weight");
13020     }
13021
13022   vam->noprint_msg = 1;
13023
13024   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13025
13026   mp->filter = filter;
13027
13028   /* send it... */
13029   S;
13030
13031   /* Use a control ping for synchronization */
13032   {
13033     vl_api_noprint_control_ping_t *mp;
13034     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13035     S;
13036   }
13037
13038   /* Wait for a reply... */
13039   /* *INDENT-OFF* */
13040   W_L
13041   ({
13042     if (vam->noprint_msg)
13043       {
13044         if (!vam->json_output)
13045           {
13046             print_locator_in_locator_set(vam, filter);
13047           }
13048         else
13049           {
13050             json_locator_in_locator_set(vam, filter);
13051           }
13052       }
13053     vam->noprint_msg = 0;
13054   });
13055   /* *INDENT-ON* */
13056
13057   /* NOTREACHED */
13058   return 0;
13059 }
13060
13061 static int
13062 api_lisp_locator_set_dump (vat_main_t * vam)
13063 {
13064   unformat_input_t *input = vam->input;
13065   vam->noprint_msg = 0;
13066   u32 locator_set_index = ~0;
13067   u8 locator_set_index_set = 0;
13068   u8 *locator_set = 0;
13069   u8 locator_set_set = 0;
13070   u8 filter = 0;
13071   int ret = 0;
13072
13073   /* Parse args required to build the message */
13074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13075     {
13076       if (unformat (input, "locator-set-index %u", &locator_set_index))
13077         {
13078           locator_set_index_set = 1;
13079         }
13080       else if (unformat (input, "locator-set %s", &locator_set))
13081         {
13082           locator_set_set = 1;
13083         }
13084       else if (unformat (input, "local"))
13085         {
13086           filter = 1;
13087         }
13088       else if (unformat (input, "remote"))
13089         {
13090           filter = 2;
13091         }
13092       else
13093         {
13094           break;
13095         }
13096     }
13097
13098   if (locator_set_index_set && locator_set_set)
13099     {
13100       errmsg ("use only input parameter!\n");
13101       return -99;
13102     }
13103
13104   if (locator_set_index_set || locator_set_set)
13105     {
13106       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13107     }
13108   else
13109     {
13110       ret = lisp_locator_set_dump (vam, filter);
13111     }
13112
13113   vec_free (locator_set);
13114
13115   return ret;
13116 }
13117
13118 static int
13119 api_lisp_eid_table_map_dump (vat_main_t * vam)
13120 {
13121   u8 is_l2 = 0;
13122   u8 mode_set = 0;
13123   unformat_input_t *input = vam->input;
13124   vl_api_lisp_eid_table_map_dump_t *mp;
13125   f64 timeout = ~0;
13126
13127   /* Parse args required to build the message */
13128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13129     {
13130       if (unformat (input, "l2"))
13131         {
13132           is_l2 = 1;
13133           mode_set = 1;
13134         }
13135       else if (unformat (input, "l3"))
13136         {
13137           is_l2 = 0;
13138           mode_set = 1;
13139         }
13140       else
13141         {
13142           errmsg ("parse error '%U'", format_unformat_error, input);
13143           return -99;
13144         }
13145     }
13146
13147   if (!mode_set)
13148     {
13149       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13150       return -99;
13151     }
13152
13153   if (!vam->json_output)
13154     {
13155       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13156     }
13157
13158   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13159   mp->is_l2 = is_l2;
13160
13161   /* send it... */
13162   S;
13163
13164   /* Use a control ping for synchronization */
13165   {
13166     vl_api_control_ping_t *mp;
13167     M (CONTROL_PING, control_ping);
13168     S;
13169   }
13170   /* Wait for a reply... */
13171   W;
13172
13173   /* NOTREACHED */
13174   return 0;
13175 }
13176
13177 static int
13178 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13179 {
13180   vl_api_lisp_eid_table_vni_dump_t *mp;
13181   f64 timeout = ~0;
13182
13183   if (!vam->json_output)
13184     {
13185       fformat (vam->ofp, "VNI\n");
13186     }
13187
13188   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13189
13190   /* send it... */
13191   S;
13192
13193   /* Use a control ping for synchronization */
13194   {
13195     vl_api_control_ping_t *mp;
13196     M (CONTROL_PING, control_ping);
13197     S;
13198   }
13199   /* Wait for a reply... */
13200   W;
13201
13202   /* NOTREACHED */
13203   return 0;
13204 }
13205
13206 static int
13207 get_locator_set (vat_main_t * vam)
13208 {
13209   vl_api_lisp_locator_set_dump_t *mp;
13210   f64 timeout = ~0;
13211
13212   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13213   /* send it... */
13214   S;
13215
13216   /* Use a control ping for synchronization */
13217   {
13218     vl_api_noprint_control_ping_t *mp;
13219     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13220     S;
13221   }
13222
13223   /* Wait for a reply... */
13224   W;
13225
13226   /* NOTREACHED */
13227   return 0;
13228 }
13229
13230 static inline u8 *
13231 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13232                           int *ret)
13233 {
13234   u8 *(*format_eid) (u8 *, va_list *) = 0;
13235
13236   ASSERT (vam != NULL);
13237   ASSERT (eid_table != NULL);
13238
13239   if (ret)
13240     {
13241       *ret = 0;
13242     }
13243
13244   switch (eid_table->eid_type)
13245     {
13246     case 0:
13247     case 1:
13248       format_eid = (eid_table->eid_type ? format_ip6_address :
13249                     format_ip4_address);
13250       str = format (0, "[%d] %U/%d",
13251                     clib_net_to_host_u32 (eid_table->vni),
13252                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13253       break;
13254     case 2:
13255       str = format (0, "[%d] %U",
13256                     clib_net_to_host_u32 (eid_table->vni),
13257                     format_ethernet_address, eid_table->eid);
13258       break;
13259     default:
13260       errmsg ("unknown EID type %d!", eid_table->eid_type);
13261       if (ret)
13262         {
13263           *ret = -99;
13264         }
13265       return 0;
13266     }
13267
13268   return str;
13269 }
13270
13271 static inline u8 *
13272 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13273                                   eid_table_t * eid_table)
13274 {
13275   locator_set_msg_t *ls = 0;
13276
13277   ASSERT (vam != NULL);
13278   ASSERT (eid_table != NULL);
13279
13280   if (eid_table->is_local)
13281     {
13282       vec_foreach (ls, vam->locator_set_msg)
13283       {
13284         if (ls->locator_set_index == eid_table->locator_set_index)
13285           {
13286             str = format (0, "local(%s)", ls->locator_set_name);
13287             return str;
13288           }
13289       }
13290
13291       str = format (0, "local(N/A)");
13292     }
13293   else
13294     {
13295       str = format (0, "remote");
13296     }
13297
13298   return str;
13299 }
13300
13301 static inline u8 *
13302 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13303                               eid_table_t * eid_table)
13304 {
13305   locator_msg_t *loc = 0;
13306   int first_line = 1;
13307
13308   ASSERT (vam != NULL);
13309   ASSERT (eid_table != NULL);
13310
13311   vec_foreach (loc, vam->locator_msg)
13312   {
13313     if (!first_line)
13314       {
13315         if (loc->local)
13316           {
13317             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13318           }
13319         else
13320           {
13321             str = format (str, "%=55s%-U\n", " ",
13322                           loc->is_ipv6 ? format_ip6_address :
13323                           format_ip4_address, loc->ip_address);
13324           }
13325
13326         continue;
13327       }
13328
13329     if (loc->local)
13330       {
13331         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13332                       eid_table->ttl, eid_table->authoritative);
13333       }
13334     else
13335       {
13336         str = format (str, "%-30U%-20u%-u\n",
13337                       loc->is_ipv6 ? format_ip6_address :
13338                       format_ip4_address,
13339                       loc->ip_address, eid_table->ttl,
13340                       eid_table->authoritative);
13341       }
13342     first_line = 0;
13343   }
13344
13345   return str;
13346 }
13347
13348 static int
13349 print_lisp_eid_table_dump (vat_main_t * vam)
13350 {
13351   eid_table_t *eid_table = 0;
13352   u8 *tmp_str = 0, *tmp_str2 = 0;
13353   int ret = 0;
13354
13355   ASSERT (vam != NULL);
13356
13357   ret = get_locator_set (vam);
13358   if (ret)
13359     {
13360       vec_free (vam->eid_tables);
13361       return ret;
13362     }
13363
13364   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13365            "ttl", "authoritative");
13366
13367   vec_foreach (eid_table, vam->eid_tables)
13368   {
13369     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13370     if (ret)
13371       {
13372         vec_free (vam->locator_msg);
13373         clean_locator_set_message (vam);
13374         vec_free (vam->eid_tables);
13375         return ret;
13376       }
13377
13378     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13379     if (ret)
13380       {
13381         vec_free (vam->locator_msg);
13382         clean_locator_set_message (vam);
13383         vec_free (vam->eid_tables);
13384         return ret;
13385       }
13386
13387     tmp_str = format (0, "%-35s", tmp_str2);
13388     vec_free (tmp_str2);
13389
13390     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13391     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13392     vec_free (tmp_str2);
13393
13394     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13395     tmp_str = format (tmp_str, "%-s", tmp_str2);
13396     vec_free (tmp_str2);
13397
13398     fformat (vam->ofp, "%s", tmp_str);
13399     vec_free (tmp_str);
13400     vec_free (vam->locator_msg);
13401   }
13402
13403   clean_locator_set_message (vam);
13404   vec_free (vam->eid_tables);
13405
13406   return ret;
13407 }
13408
13409 static inline void
13410 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13411                                 eid_table_t * eid_table)
13412 {
13413   locator_set_msg_t *ls = 0;
13414   u8 *s = 0;
13415
13416   ASSERT (vam != NULL);
13417   ASSERT (node != NULL);
13418   ASSERT (eid_table != NULL);
13419
13420   if (eid_table->is_local)
13421     {
13422       vec_foreach (ls, vam->locator_set_msg)
13423       {
13424         if (ls->locator_set_index == eid_table->locator_set_index)
13425           {
13426             vat_json_object_add_string_copy (node, "locator-set",
13427                                              ls->locator_set_name);
13428             return;
13429           }
13430       }
13431
13432       s = format (0, "N/A");
13433       vec_add1 (s, 0);
13434       vat_json_object_add_string_copy (node, "locator-set", s);
13435       vec_free (s);
13436     }
13437   else
13438     {
13439       s = format (0, "remote");
13440       vec_add1 (s, 0);
13441       vat_json_object_add_string_copy (node, "locator-set", s);
13442       vec_free (s);
13443     }
13444 }
13445
13446 static inline int
13447 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13448                         eid_table_t * eid_table)
13449 {
13450   u8 *s = 0;
13451   struct in6_addr ip6;
13452   struct in_addr ip4;
13453
13454   ASSERT (vam != NULL);
13455   ASSERT (node != NULL);
13456   ASSERT (eid_table != NULL);
13457
13458   switch (eid_table->eid_type)
13459     {
13460     case 0:
13461       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13462       vat_json_object_add_ip4 (node, "eid", ip4);
13463       vat_json_object_add_uint (node, "eid-prefix-len",
13464                                 eid_table->eid_prefix_len);
13465       break;
13466     case 1:
13467       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13468       vat_json_object_add_ip6 (node, "eid", ip6);
13469       vat_json_object_add_uint (node, "eid-prefix-len",
13470                                 eid_table->eid_prefix_len);
13471       break;
13472     case 2:
13473       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13474       vec_add1 (s, 0);
13475       vat_json_object_add_string_copy (node, "eid", s);
13476       vec_free (s);
13477       break;
13478     default:
13479       errmsg ("unknown EID type %d!", eid_table->eid_type);
13480       return -99;
13481     }
13482
13483   return 0;
13484 }
13485
13486 static inline void
13487 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13488                             eid_table_t * eid_table)
13489 {
13490   locator_msg_t *loc = 0;
13491   vat_json_node_t *locator_array = 0;
13492   vat_json_node_t *locator = 0;
13493   struct in6_addr ip6;
13494   struct in_addr ip4;
13495
13496   ASSERT (vam != NULL);
13497   ASSERT (node != NULL);
13498   ASSERT (eid_table != NULL);
13499
13500   locator_array = vat_json_object_add_list (node, "locator");
13501   vec_foreach (loc, vam->locator_msg)
13502   {
13503     locator = vat_json_array_add (locator_array);
13504     vat_json_init_object (locator);
13505     if (loc->local)
13506       {
13507         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13508       }
13509     else
13510       {
13511         if (loc->is_ipv6)
13512           {
13513             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13514             vat_json_object_add_ip6 (locator, "locator", ip6);
13515           }
13516         else
13517           {
13518             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13519             vat_json_object_add_ip4 (locator, "locator", ip4);
13520           }
13521       }
13522   }
13523 }
13524
13525 static int
13526 json_lisp_eid_table_dump (vat_main_t * vam)
13527 {
13528   eid_table_t *eid_table;
13529   vat_json_node_t *node = 0;
13530   int ret = 0;
13531
13532   ASSERT (vam != NULL);
13533
13534   ret = get_locator_set (vam);
13535   if (ret)
13536     {
13537       vec_free (vam->eid_tables);
13538       return ret;
13539     }
13540
13541   if (!vec_len (vam->eid_tables))
13542     {
13543       /* just print [] */
13544       vat_json_init_array (&vam->json_tree);
13545       vat_json_print (vam->ofp, &vam->json_tree);
13546       vam->json_tree.type = VAT_JSON_NONE;
13547       return ret;
13548     }
13549
13550   if (VAT_JSON_ARRAY != vam->json_tree.type)
13551     {
13552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13553       vat_json_init_array (&vam->json_tree);
13554     }
13555
13556   vec_foreach (eid_table, vam->eid_tables)
13557   {
13558     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13559     if (ret)
13560       {
13561         vec_free (vam->locator_msg);
13562         vec_free (vam->eid_tables);
13563         clean_locator_set_message (vam);
13564         vat_json_free (&vam->json_tree);
13565         vam->json_tree.type = VAT_JSON_NONE;
13566         return ret;
13567       }
13568
13569     node = vat_json_array_add (&vam->json_tree);
13570     vat_json_init_object (node);
13571
13572     vat_json_object_add_uint (node, "vni", eid_table->vni);
13573
13574     json_locator_set_for_eid_table (vam, node, eid_table);
13575     ret = json_eid_for_eid_table (vam, node, eid_table);
13576     if (ret)
13577       {
13578         vec_free (vam->locator_msg);
13579         vec_free (vam->eid_tables);
13580         clean_locator_set_message (vam);
13581         vat_json_free (&vam->json_tree);
13582         vam->json_tree.type = VAT_JSON_NONE;
13583         return ret;
13584       }
13585
13586     json_locator_for_eid_table (vam, node, eid_table);
13587
13588     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13589     vat_json_object_add_uint (node, "authoritative",
13590                               eid_table->authoritative);
13591
13592     vec_free (vam->locator_msg);
13593   }
13594
13595   vat_json_print (vam->ofp, &vam->json_tree);
13596   vat_json_free (&vam->json_tree);
13597   vam->json_tree.type = VAT_JSON_NONE;
13598
13599   clean_locator_set_message (vam);
13600   vec_free (vam->eid_tables);
13601
13602   return ret;
13603 }
13604
13605 static int
13606 api_lisp_eid_table_dump (vat_main_t * vam)
13607 {
13608   unformat_input_t *i = vam->input;
13609   vl_api_lisp_eid_table_dump_t *mp;
13610   f64 timeout = ~0;
13611   struct in_addr ip4;
13612   struct in6_addr ip6;
13613   u8 mac[6];
13614   u8 eid_type = ~0, eid_set = 0;
13615   u32 prefix_length = ~0, t, vni = 0;
13616   u8 filter = 0;
13617
13618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13619     {
13620       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13621         {
13622           eid_set = 1;
13623           eid_type = 0;
13624           prefix_length = t;
13625         }
13626       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13627         {
13628           eid_set = 1;
13629           eid_type = 1;
13630           prefix_length = t;
13631         }
13632       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13633         {
13634           eid_set = 1;
13635           eid_type = 2;
13636         }
13637       else if (unformat (i, "vni %d", &t))
13638         {
13639           vni = t;
13640         }
13641       else if (unformat (i, "local"))
13642         {
13643           filter = 1;
13644         }
13645       else if (unformat (i, "remote"))
13646         {
13647           filter = 2;
13648         }
13649       else
13650         {
13651           errmsg ("parse error '%U'", format_unformat_error, i);
13652           return -99;
13653         }
13654     }
13655
13656   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13657
13658   mp->filter = filter;
13659   if (eid_set)
13660     {
13661       mp->eid_set = 1;
13662       mp->vni = htonl (vni);
13663       mp->eid_type = eid_type;
13664       switch (eid_type)
13665         {
13666         case 0:
13667           mp->prefix_length = prefix_length;
13668           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13669           break;
13670         case 1:
13671           mp->prefix_length = prefix_length;
13672           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13673           break;
13674         case 2:
13675           clib_memcpy (mp->eid, mac, sizeof (mac));
13676           break;
13677         default:
13678           errmsg ("unknown EID type %d!", eid_type);
13679           return -99;
13680         }
13681     }
13682
13683   vam->noprint_msg = 1;
13684
13685   /* send it... */
13686   S;
13687
13688   /* Use a control ping for synchronization */
13689   {
13690     vl_api_noprint_control_ping_t *mp;
13691     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13692     S;
13693   }
13694
13695   /* Wait for a reply... */
13696   /* *INDENT-OFF* */
13697   W_L
13698   ({
13699     if (vam->noprint_msg)
13700       {
13701         if (!vam->json_output)
13702           {
13703             vam->retval = print_lisp_eid_table_dump(vam);
13704           }
13705         else
13706           {
13707             vam->retval = json_lisp_eid_table_dump(vam);
13708           }
13709       }
13710     vam->noprint_msg = 0;
13711   });
13712   /* *INDENT-ON* */
13713
13714   /* NOTREACHED */
13715   return 0;
13716 }
13717
13718 static int
13719 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13720 {
13721   vl_api_lisp_gpe_tunnel_dump_t *mp;
13722   f64 timeout = ~0;
13723
13724   if (!vam->json_output)
13725     {
13726       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13727                "%=16s%=16s%=16s%=16s%=16s\n",
13728                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13729                "Decap next", "Lisp version", "Flags", "Next protocol",
13730                "ver_res", "res", "iid");
13731     }
13732
13733   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13734   /* send it... */
13735   S;
13736
13737   /* Use a control ping for synchronization */
13738   {
13739     vl_api_control_ping_t *mp;
13740     M (CONTROL_PING, control_ping);
13741     S;
13742   }
13743   /* Wait for a reply... */
13744   W;
13745
13746   /* NOTREACHED */
13747   return 0;
13748 }
13749
13750 static int
13751 api_lisp_map_resolver_dump (vat_main_t * vam)
13752 {
13753   vl_api_lisp_map_resolver_dump_t *mp;
13754   f64 timeout = ~0;
13755
13756   if (!vam->json_output)
13757     {
13758       fformat (vam->ofp, "%=20s\n", "Map resolver");
13759     }
13760
13761   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13762   /* send it... */
13763   S;
13764
13765   /* Use a control ping for synchronization */
13766   {
13767     vl_api_control_ping_t *mp;
13768     M (CONTROL_PING, control_ping);
13769     S;
13770   }
13771   /* Wait for a reply... */
13772   W;
13773
13774   /* NOTREACHED */
13775   return 0;
13776 }
13777
13778 static int
13779 api_show_lisp_status (vat_main_t * vam)
13780 {
13781   vl_api_show_lisp_status_t *mp;
13782   f64 timeout = ~0;
13783
13784   if (!vam->json_output)
13785     {
13786       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13787     }
13788
13789   M (SHOW_LISP_STATUS, show_lisp_status);
13790   /* send it... */
13791   S;
13792   /* Wait for a reply... */
13793   W;
13794
13795   /* NOTREACHED */
13796   return 0;
13797 }
13798
13799 static int
13800 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13801 {
13802   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13803   f64 timeout = ~0;
13804
13805   if (!vam->json_output)
13806     {
13807       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13808     }
13809
13810   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13811   /* send it... */
13812   S;
13813   /* Wait for a reply... */
13814   W;
13815
13816   /* NOTREACHED */
13817   return 0;
13818 }
13819
13820 static int
13821 api_af_packet_create (vat_main_t * vam)
13822 {
13823   unformat_input_t *i = vam->input;
13824   vl_api_af_packet_create_t *mp;
13825   f64 timeout;
13826   u8 *host_if_name = 0;
13827   u8 hw_addr[6];
13828   u8 random_hw_addr = 1;
13829
13830   memset (hw_addr, 0, sizeof (hw_addr));
13831
13832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13833     {
13834       if (unformat (i, "name %s", &host_if_name))
13835         vec_add1 (host_if_name, 0);
13836       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13837         random_hw_addr = 0;
13838       else
13839         break;
13840     }
13841
13842   if (!vec_len (host_if_name))
13843     {
13844       errmsg ("host-interface name must be specified");
13845       return -99;
13846     }
13847
13848   if (vec_len (host_if_name) > 64)
13849     {
13850       errmsg ("host-interface name too long");
13851       return -99;
13852     }
13853
13854   M (AF_PACKET_CREATE, af_packet_create);
13855
13856   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13857   clib_memcpy (mp->hw_addr, hw_addr, 6);
13858   mp->use_random_hw_addr = random_hw_addr;
13859   vec_free (host_if_name);
13860
13861   S;
13862   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13863   /* NOTREACHED */
13864   return 0;
13865 }
13866
13867 static int
13868 api_af_packet_delete (vat_main_t * vam)
13869 {
13870   unformat_input_t *i = vam->input;
13871   vl_api_af_packet_delete_t *mp;
13872   f64 timeout;
13873   u8 *host_if_name = 0;
13874
13875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13876     {
13877       if (unformat (i, "name %s", &host_if_name))
13878         vec_add1 (host_if_name, 0);
13879       else
13880         break;
13881     }
13882
13883   if (!vec_len (host_if_name))
13884     {
13885       errmsg ("host-interface name must be specified");
13886       return -99;
13887     }
13888
13889   if (vec_len (host_if_name) > 64)
13890     {
13891       errmsg ("host-interface name too long");
13892       return -99;
13893     }
13894
13895   M (AF_PACKET_DELETE, af_packet_delete);
13896
13897   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13898   vec_free (host_if_name);
13899
13900   S;
13901   W;
13902   /* NOTREACHED */
13903   return 0;
13904 }
13905
13906 static int
13907 api_policer_add_del (vat_main_t * vam)
13908 {
13909   unformat_input_t *i = vam->input;
13910   vl_api_policer_add_del_t *mp;
13911   f64 timeout;
13912   u8 is_add = 1;
13913   u8 *name = 0;
13914   u32 cir = 0;
13915   u32 eir = 0;
13916   u64 cb = 0;
13917   u64 eb = 0;
13918   u8 rate_type = 0;
13919   u8 round_type = 0;
13920   u8 type = 0;
13921   u8 color_aware = 0;
13922   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13923
13924   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13925   conform_action.dscp = 0;
13926   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13927   exceed_action.dscp = 0;
13928   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13929   violate_action.dscp = 0;
13930
13931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13932     {
13933       if (unformat (i, "del"))
13934         is_add = 0;
13935       else if (unformat (i, "name %s", &name))
13936         vec_add1 (name, 0);
13937       else if (unformat (i, "cir %u", &cir))
13938         ;
13939       else if (unformat (i, "eir %u", &eir))
13940         ;
13941       else if (unformat (i, "cb %u", &cb))
13942         ;
13943       else if (unformat (i, "eb %u", &eb))
13944         ;
13945       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13946                          &rate_type))
13947         ;
13948       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13949                          &round_type))
13950         ;
13951       else if (unformat (i, "type %U", unformat_policer_type, &type))
13952         ;
13953       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13954                          &conform_action))
13955         ;
13956       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13957                          &exceed_action))
13958         ;
13959       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13960                          &violate_action))
13961         ;
13962       else if (unformat (i, "color-aware"))
13963         color_aware = 1;
13964       else
13965         break;
13966     }
13967
13968   if (!vec_len (name))
13969     {
13970       errmsg ("policer name must be specified");
13971       return -99;
13972     }
13973
13974   if (vec_len (name) > 64)
13975     {
13976       errmsg ("policer name too long");
13977       return -99;
13978     }
13979
13980   M (POLICER_ADD_DEL, policer_add_del);
13981
13982   clib_memcpy (mp->name, name, vec_len (name));
13983   vec_free (name);
13984   mp->is_add = is_add;
13985   mp->cir = cir;
13986   mp->eir = eir;
13987   mp->cb = cb;
13988   mp->eb = eb;
13989   mp->rate_type = rate_type;
13990   mp->round_type = round_type;
13991   mp->type = type;
13992   mp->conform_action_type = conform_action.action_type;
13993   mp->conform_dscp = conform_action.dscp;
13994   mp->exceed_action_type = exceed_action.action_type;
13995   mp->exceed_dscp = exceed_action.dscp;
13996   mp->violate_action_type = violate_action.action_type;
13997   mp->violate_dscp = violate_action.dscp;
13998   mp->color_aware = color_aware;
13999
14000   S;
14001   W;
14002   /* NOTREACHED */
14003   return 0;
14004 }
14005
14006 static int
14007 api_policer_dump (vat_main_t * vam)
14008 {
14009   unformat_input_t *i = vam->input;
14010   vl_api_policer_dump_t *mp;
14011   f64 timeout = ~0;
14012   u8 *match_name = 0;
14013   u8 match_name_valid = 0;
14014
14015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14016     {
14017       if (unformat (i, "name %s", &match_name))
14018         {
14019           vec_add1 (match_name, 0);
14020           match_name_valid = 1;
14021         }
14022       else
14023         break;
14024     }
14025
14026   M (POLICER_DUMP, policer_dump);
14027   mp->match_name_valid = match_name_valid;
14028   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14029   vec_free (match_name);
14030   /* send it... */
14031   S;
14032
14033   /* Use a control ping for synchronization */
14034   {
14035     vl_api_control_ping_t *mp;
14036     M (CONTROL_PING, control_ping);
14037     S;
14038   }
14039   /* Wait for a reply... */
14040   W;
14041
14042   /* NOTREACHED */
14043   return 0;
14044 }
14045
14046 static int
14047 api_policer_classify_set_interface (vat_main_t * vam)
14048 {
14049   unformat_input_t *i = vam->input;
14050   vl_api_policer_classify_set_interface_t *mp;
14051   f64 timeout;
14052   u32 sw_if_index;
14053   int sw_if_index_set;
14054   u32 ip4_table_index = ~0;
14055   u32 ip6_table_index = ~0;
14056   u32 l2_table_index = ~0;
14057   u8 is_add = 1;
14058
14059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14060     {
14061       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14062         sw_if_index_set = 1;
14063       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14064         sw_if_index_set = 1;
14065       else if (unformat (i, "del"))
14066         is_add = 0;
14067       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14068         ;
14069       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14070         ;
14071       else if (unformat (i, "l2-table %d", &l2_table_index))
14072         ;
14073       else
14074         {
14075           clib_warning ("parse error '%U'", format_unformat_error, i);
14076           return -99;
14077         }
14078     }
14079
14080   if (sw_if_index_set == 0)
14081     {
14082       errmsg ("missing interface name or sw_if_index\n");
14083       return -99;
14084     }
14085
14086   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14087
14088   mp->sw_if_index = ntohl (sw_if_index);
14089   mp->ip4_table_index = ntohl (ip4_table_index);
14090   mp->ip6_table_index = ntohl (ip6_table_index);
14091   mp->l2_table_index = ntohl (l2_table_index);
14092   mp->is_add = is_add;
14093
14094   S;
14095   W;
14096   /* NOTREACHED */
14097   return 0;
14098 }
14099
14100 static int
14101 api_policer_classify_dump (vat_main_t * vam)
14102 {
14103   unformat_input_t *i = vam->input;
14104   vl_api_policer_classify_dump_t *mp;
14105   f64 timeout = ~0;
14106   u8 type = POLICER_CLASSIFY_N_TABLES;
14107
14108   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14109     ;
14110   else
14111     {
14112       errmsg ("classify table type must be specified\n");
14113       return -99;
14114     }
14115
14116   if (!vam->json_output)
14117     {
14118       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14119     }
14120
14121   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14122   mp->type = type;
14123   /* send it... */
14124   S;
14125
14126   /* Use a control ping for synchronization */
14127   {
14128     vl_api_control_ping_t *mp;
14129     M (CONTROL_PING, control_ping);
14130     S;
14131   }
14132   /* Wait for a reply... */
14133   W;
14134
14135   /* NOTREACHED */
14136   return 0;
14137 }
14138
14139 static int
14140 api_netmap_create (vat_main_t * vam)
14141 {
14142   unformat_input_t *i = vam->input;
14143   vl_api_netmap_create_t *mp;
14144   f64 timeout;
14145   u8 *if_name = 0;
14146   u8 hw_addr[6];
14147   u8 random_hw_addr = 1;
14148   u8 is_pipe = 0;
14149   u8 is_master = 0;
14150
14151   memset (hw_addr, 0, sizeof (hw_addr));
14152
14153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14154     {
14155       if (unformat (i, "name %s", &if_name))
14156         vec_add1 (if_name, 0);
14157       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14158         random_hw_addr = 0;
14159       else if (unformat (i, "pipe"))
14160         is_pipe = 1;
14161       else if (unformat (i, "master"))
14162         is_master = 1;
14163       else if (unformat (i, "slave"))
14164         is_master = 0;
14165       else
14166         break;
14167     }
14168
14169   if (!vec_len (if_name))
14170     {
14171       errmsg ("interface name must be specified");
14172       return -99;
14173     }
14174
14175   if (vec_len (if_name) > 64)
14176     {
14177       errmsg ("interface name too long");
14178       return -99;
14179     }
14180
14181   M (NETMAP_CREATE, netmap_create);
14182
14183   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14184   clib_memcpy (mp->hw_addr, hw_addr, 6);
14185   mp->use_random_hw_addr = random_hw_addr;
14186   mp->is_pipe = is_pipe;
14187   mp->is_master = is_master;
14188   vec_free (if_name);
14189
14190   S;
14191   W;
14192   /* NOTREACHED */
14193   return 0;
14194 }
14195
14196 static int
14197 api_netmap_delete (vat_main_t * vam)
14198 {
14199   unformat_input_t *i = vam->input;
14200   vl_api_netmap_delete_t *mp;
14201   f64 timeout;
14202   u8 *if_name = 0;
14203
14204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14205     {
14206       if (unformat (i, "name %s", &if_name))
14207         vec_add1 (if_name, 0);
14208       else
14209         break;
14210     }
14211
14212   if (!vec_len (if_name))
14213     {
14214       errmsg ("interface name must be specified");
14215       return -99;
14216     }
14217
14218   if (vec_len (if_name) > 64)
14219     {
14220       errmsg ("interface name too long");
14221       return -99;
14222     }
14223
14224   M (NETMAP_DELETE, netmap_delete);
14225
14226   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14227   vec_free (if_name);
14228
14229   S;
14230   W;
14231   /* NOTREACHED */
14232   return 0;
14233 }
14234
14235 static void vl_api_mpls_gre_tunnel_details_t_handler
14236   (vl_api_mpls_gre_tunnel_details_t * mp)
14237 {
14238   vat_main_t *vam = &vat_main;
14239   i32 i;
14240   i32 len = ntohl (mp->nlabels);
14241
14242   if (mp->l2_only == 0)
14243     {
14244       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14245                ntohl (mp->tunnel_index),
14246                format_ip4_address, &mp->tunnel_src,
14247                format_ip4_address, &mp->tunnel_dst,
14248                format_ip4_address, &mp->intfc_address,
14249                ntohl (mp->mask_width));
14250       for (i = 0; i < len; i++)
14251         {
14252           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14253         }
14254       fformat (vam->ofp, "\n");
14255       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14256                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14257     }
14258   else
14259     {
14260       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14261                ntohl (mp->tunnel_index),
14262                format_ip4_address, &mp->tunnel_src,
14263                format_ip4_address, &mp->tunnel_dst,
14264                format_ip4_address, &mp->intfc_address);
14265       for (i = 0; i < len; i++)
14266         {
14267           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14268         }
14269       fformat (vam->ofp, "\n");
14270       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14271                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14272     }
14273 }
14274
14275 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14276   (vl_api_mpls_gre_tunnel_details_t * mp)
14277 {
14278   vat_main_t *vam = &vat_main;
14279   vat_json_node_t *node = NULL;
14280   struct in_addr ip4;
14281   i32 i;
14282   i32 len = ntohl (mp->nlabels);
14283
14284   if (VAT_JSON_ARRAY != vam->json_tree.type)
14285     {
14286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14287       vat_json_init_array (&vam->json_tree);
14288     }
14289   node = vat_json_array_add (&vam->json_tree);
14290
14291   vat_json_init_object (node);
14292   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14293   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14294   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14295   vat_json_object_add_uint (node, "inner_fib_index",
14296                             ntohl (mp->inner_fib_index));
14297   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14298   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14299   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14300   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14301   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14302   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14303   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14304   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14305   vat_json_object_add_uint (node, "outer_fib_index",
14306                             ntohl (mp->outer_fib_index));
14307   vat_json_object_add_uint (node, "label_count", len);
14308   for (i = 0; i < len; i++)
14309     {
14310       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14311     }
14312 }
14313
14314 static int
14315 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14316 {
14317   vl_api_mpls_gre_tunnel_dump_t *mp;
14318   f64 timeout;
14319   i32 index = -1;
14320
14321   /* Parse args required to build the message */
14322   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14323     {
14324       if (!unformat (vam->input, "tunnel_index %d", &index))
14325         {
14326           index = -1;
14327           break;
14328         }
14329     }
14330
14331   fformat (vam->ofp, "  tunnel_index %d\n", index);
14332
14333   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14334   mp->tunnel_index = htonl (index);
14335   S;
14336
14337   /* Use a control ping for synchronization */
14338   {
14339     vl_api_control_ping_t *mp;
14340     M (CONTROL_PING, control_ping);
14341     S;
14342   }
14343   W;
14344 }
14345
14346 static void vl_api_mpls_eth_tunnel_details_t_handler
14347   (vl_api_mpls_eth_tunnel_details_t * mp)
14348 {
14349   vat_main_t *vam = &vat_main;
14350   i32 i;
14351   i32 len = ntohl (mp->nlabels);
14352
14353   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14354            ntohl (mp->tunnel_index),
14355            format_ethernet_address, &mp->tunnel_dst_mac,
14356            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14357   for (i = 0; i < len; i++)
14358     {
14359       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14360     }
14361   fformat (vam->ofp, "\n");
14362   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14363            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14364 }
14365
14366 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14367   (vl_api_mpls_eth_tunnel_details_t * mp)
14368 {
14369   vat_main_t *vam = &vat_main;
14370   vat_json_node_t *node = NULL;
14371   struct in_addr ip4;
14372   i32 i;
14373   i32 len = ntohl (mp->nlabels);
14374
14375   if (VAT_JSON_ARRAY != vam->json_tree.type)
14376     {
14377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14378       vat_json_init_array (&vam->json_tree);
14379     }
14380   node = vat_json_array_add (&vam->json_tree);
14381
14382   vat_json_init_object (node);
14383   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14384   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14385   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14386   vat_json_object_add_uint (node, "inner_fib_index",
14387                             ntohl (mp->inner_fib_index));
14388   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14389   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14390   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14391   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14392   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14393                                    format (0, "%U", format_ethernet_address,
14394                                            &mp->tunnel_dst_mac));
14395   vat_json_object_add_uint (node, "tx_sw_if_index",
14396                             ntohl (mp->tx_sw_if_index));
14397   vat_json_object_add_uint (node, "label_count", len);
14398   for (i = 0; i < len; i++)
14399     {
14400       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14401     }
14402 }
14403
14404 static int
14405 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14406 {
14407   vl_api_mpls_eth_tunnel_dump_t *mp;
14408   f64 timeout;
14409   i32 index = -1;
14410
14411   /* Parse args required to build the message */
14412   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14413     {
14414       if (!unformat (vam->input, "tunnel_index %d", &index))
14415         {
14416           index = -1;
14417           break;
14418         }
14419     }
14420
14421   fformat (vam->ofp, "  tunnel_index %d\n", index);
14422
14423   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14424   mp->tunnel_index = htonl (index);
14425   S;
14426
14427   /* Use a control ping for synchronization */
14428   {
14429     vl_api_control_ping_t *mp;
14430     M (CONTROL_PING, control_ping);
14431     S;
14432   }
14433   W;
14434 }
14435
14436 static void vl_api_mpls_fib_encap_details_t_handler
14437   (vl_api_mpls_fib_encap_details_t * mp)
14438 {
14439   vat_main_t *vam = &vat_main;
14440   i32 i;
14441   i32 len = ntohl (mp->nlabels);
14442
14443   fformat (vam->ofp, "table %d, dest %U, label ",
14444            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14445   for (i = 0; i < len; i++)
14446     {
14447       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14448     }
14449   fformat (vam->ofp, "\n");
14450 }
14451
14452 static void vl_api_mpls_fib_encap_details_t_handler_json
14453   (vl_api_mpls_fib_encap_details_t * mp)
14454 {
14455   vat_main_t *vam = &vat_main;
14456   vat_json_node_t *node = NULL;
14457   i32 i;
14458   i32 len = ntohl (mp->nlabels);
14459   struct in_addr ip4;
14460
14461   if (VAT_JSON_ARRAY != vam->json_tree.type)
14462     {
14463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14464       vat_json_init_array (&vam->json_tree);
14465     }
14466   node = vat_json_array_add (&vam->json_tree);
14467
14468   vat_json_init_object (node);
14469   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14470   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14471   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14472   vat_json_object_add_ip4 (node, "dest", ip4);
14473   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14474   vat_json_object_add_uint (node, "label_count", len);
14475   for (i = 0; i < len; i++)
14476     {
14477       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14478     }
14479 }
14480
14481 static int
14482 api_mpls_fib_encap_dump (vat_main_t * vam)
14483 {
14484   vl_api_mpls_fib_encap_dump_t *mp;
14485   f64 timeout;
14486
14487   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14488   S;
14489
14490   /* Use a control ping for synchronization */
14491   {
14492     vl_api_control_ping_t *mp;
14493     M (CONTROL_PING, control_ping);
14494     S;
14495   }
14496   W;
14497 }
14498
14499 static void vl_api_mpls_fib_decap_details_t_handler
14500   (vl_api_mpls_fib_decap_details_t * mp)
14501 {
14502   vat_main_t *vam = &vat_main;
14503
14504   fformat (vam->ofp,
14505            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14506            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14507            ntohl (mp->label), ntohl (mp->s_bit));
14508 }
14509
14510 static void vl_api_mpls_fib_decap_details_t_handler_json
14511   (vl_api_mpls_fib_decap_details_t * mp)
14512 {
14513   vat_main_t *vam = &vat_main;
14514   vat_json_node_t *node = NULL;
14515   struct in_addr ip4;
14516
14517   if (VAT_JSON_ARRAY != vam->json_tree.type)
14518     {
14519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14520       vat_json_init_array (&vam->json_tree);
14521     }
14522   node = vat_json_array_add (&vam->json_tree);
14523
14524   vat_json_init_object (node);
14525   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14526   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14527   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14528   vat_json_object_add_ip4 (node, "dest", ip4);
14529   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14530   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14531   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14532   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14533   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14534 }
14535
14536 static int
14537 api_mpls_fib_decap_dump (vat_main_t * vam)
14538 {
14539   vl_api_mpls_fib_decap_dump_t *mp;
14540   f64 timeout;
14541
14542   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14543   S;
14544
14545   /* Use a control ping for synchronization */
14546   {
14547     vl_api_control_ping_t *mp;
14548     M (CONTROL_PING, control_ping);
14549     S;
14550   }
14551   W;
14552 }
14553
14554 int
14555 api_classify_table_ids (vat_main_t * vam)
14556 {
14557   vl_api_classify_table_ids_t *mp;
14558   f64 timeout;
14559
14560   /* Construct the API message */
14561   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14562   mp->context = 0;
14563
14564   S;
14565   W;
14566   /* NOTREACHED */
14567   return 0;
14568 }
14569
14570 int
14571 api_classify_table_by_interface (vat_main_t * vam)
14572 {
14573   unformat_input_t *input = vam->input;
14574   vl_api_classify_table_by_interface_t *mp;
14575   f64 timeout;
14576
14577   u32 sw_if_index = ~0;
14578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14579     {
14580       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14581         ;
14582       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14583         ;
14584       else
14585         break;
14586     }
14587   if (sw_if_index == ~0)
14588     {
14589       errmsg ("missing interface name or sw_if_index\n");
14590       return -99;
14591     }
14592
14593   /* Construct the API message */
14594   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14595   mp->context = 0;
14596   mp->sw_if_index = ntohl (sw_if_index);
14597
14598   S;
14599   W;
14600   /* NOTREACHED */
14601   return 0;
14602 }
14603
14604 int
14605 api_classify_table_info (vat_main_t * vam)
14606 {
14607   unformat_input_t *input = vam->input;
14608   vl_api_classify_table_info_t *mp;
14609   f64 timeout;
14610
14611   u32 table_id = ~0;
14612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14613     {
14614       if (unformat (input, "table_id %d", &table_id))
14615         ;
14616       else
14617         break;
14618     }
14619   if (table_id == ~0)
14620     {
14621       errmsg ("missing table id\n");
14622       return -99;
14623     }
14624
14625   /* Construct the API message */
14626   M (CLASSIFY_TABLE_INFO, classify_table_info);
14627   mp->context = 0;
14628   mp->table_id = ntohl (table_id);
14629
14630   S;
14631   W;
14632   /* NOTREACHED */
14633   return 0;
14634 }
14635
14636 int
14637 api_classify_session_dump (vat_main_t * vam)
14638 {
14639   unformat_input_t *input = vam->input;
14640   vl_api_classify_session_dump_t *mp;
14641   f64 timeout;
14642
14643   u32 table_id = ~0;
14644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14645     {
14646       if (unformat (input, "table_id %d", &table_id))
14647         ;
14648       else
14649         break;
14650     }
14651   if (table_id == ~0)
14652     {
14653       errmsg ("missing table id\n");
14654       return -99;
14655     }
14656
14657   /* Construct the API message */
14658   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14659   mp->context = 0;
14660   mp->table_id = ntohl (table_id);
14661   S;
14662
14663   /* Use a control ping for synchronization */
14664   {
14665     vl_api_control_ping_t *mp;
14666     M (CONTROL_PING, control_ping);
14667     S;
14668   }
14669   W;
14670   /* NOTREACHED */
14671   return 0;
14672 }
14673
14674 static void
14675 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14676 {
14677   vat_main_t *vam = &vat_main;
14678
14679   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14680            "src_address %U, fib_index %u, path_mtu %u, "
14681            "template_interval %u\n",
14682            format_ip4_address, mp->collector_address,
14683            ntohs (mp->collector_port),
14684            format_ip4_address, mp->src_address,
14685            ntohl (mp->fib_index),
14686            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14687
14688   vam->retval = 0;
14689   vam->result_ready = 1;
14690 }
14691
14692 static void
14693 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14694 {
14695   vat_main_t *vam = &vat_main;
14696   vat_json_node_t node;
14697   struct in_addr collector_address;
14698   struct in_addr src_address;
14699
14700   vat_json_init_object (&node);
14701   clib_memcpy (&collector_address, &mp->collector_address,
14702                sizeof (collector_address));
14703   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14704   vat_json_object_add_uint (&node, "collector_port",
14705                             ntohs (mp->collector_port));
14706   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14707   vat_json_object_add_ip4 (&node, "src_address", src_address);
14708   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14709   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14710   vat_json_object_add_uint (&node, "template_interval",
14711                             ntohl (mp->template_interval));
14712
14713   vat_json_print (vam->ofp, &node);
14714   vat_json_free (&node);
14715   vam->retval = 0;
14716   vam->result_ready = 1;
14717 }
14718
14719 int
14720 api_ipfix_dump (vat_main_t * vam)
14721 {
14722   vl_api_ipfix_dump_t *mp;
14723   f64 timeout;
14724
14725   /* Construct the API message */
14726   M (IPFIX_DUMP, ipfix_dump);
14727   mp->context = 0;
14728
14729   S;
14730   W;
14731   /* NOTREACHED */
14732   return 0;
14733 }
14734
14735 int
14736 api_pg_create_interface (vat_main_t * vam)
14737 {
14738   unformat_input_t *input = vam->input;
14739   vl_api_pg_create_interface_t *mp;
14740   f64 timeout;
14741
14742   u32 if_id = ~0;
14743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14744     {
14745       if (unformat (input, "if_id %d", &if_id))
14746         ;
14747       else
14748         break;
14749     }
14750   if (if_id == ~0)
14751     {
14752       errmsg ("missing pg interface index\n");
14753       return -99;
14754     }
14755
14756   /* Construct the API message */
14757   M (PG_CREATE_INTERFACE, pg_create_interface);
14758   mp->context = 0;
14759   mp->interface_id = ntohl (if_id);
14760
14761   S;
14762   W;
14763   /* NOTREACHED */
14764   return 0;
14765 }
14766
14767 int
14768 api_pg_capture (vat_main_t * vam)
14769 {
14770   unformat_input_t *input = vam->input;
14771   vl_api_pg_capture_t *mp;
14772   f64 timeout;
14773
14774   u32 if_id = ~0;
14775   u8 enable = 1;
14776   u32 count = 1;
14777   u8 pcap_file_set = 0;
14778   u8 *pcap_file = 0;
14779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14780     {
14781       if (unformat (input, "if_id %d", &if_id))
14782         ;
14783       else if (unformat (input, "pcap %s", &pcap_file))
14784         pcap_file_set = 1;
14785       else if (unformat (input, "count %d", &count))
14786         ;
14787       else if (unformat (input, "disable"))
14788         enable = 0;
14789       else
14790         break;
14791     }
14792   if (if_id == ~0)
14793     {
14794       errmsg ("missing pg interface index\n");
14795       return -99;
14796     }
14797   if (pcap_file_set > 0)
14798     {
14799       if (vec_len (pcap_file) > 255)
14800         {
14801           errmsg ("pcap file name is too long\n");
14802           return -99;
14803         }
14804     }
14805
14806   u32 name_len = vec_len (pcap_file);
14807   /* Construct the API message */
14808   M (PG_CAPTURE, pg_capture);
14809   mp->context = 0;
14810   mp->interface_id = ntohl (if_id);
14811   mp->is_enabled = enable;
14812   mp->count = ntohl (count);
14813   mp->pcap_name_length = ntohl (name_len);
14814   if (pcap_file_set != 0)
14815     {
14816       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14817     }
14818   vec_free (pcap_file);
14819
14820   S;
14821   W;
14822   /* NOTREACHED */
14823   return 0;
14824 }
14825
14826 int
14827 api_pg_enable_disable (vat_main_t * vam)
14828 {
14829   unformat_input_t *input = vam->input;
14830   vl_api_pg_enable_disable_t *mp;
14831   f64 timeout;
14832
14833   u8 enable = 1;
14834   u8 stream_name_set = 0;
14835   u8 *stream_name = 0;
14836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14837     {
14838       if (unformat (input, "stream %s", &stream_name))
14839         stream_name_set = 1;
14840       else if (unformat (input, "disable"))
14841         enable = 0;
14842       else
14843         break;
14844     }
14845
14846   if (stream_name_set > 0)
14847     {
14848       if (vec_len (stream_name) > 255)
14849         {
14850           errmsg ("stream name too long\n");
14851           return -99;
14852         }
14853     }
14854
14855   u32 name_len = vec_len (stream_name);
14856   /* Construct the API message */
14857   M (PG_ENABLE_DISABLE, pg_enable_disable);
14858   mp->context = 0;
14859   mp->is_enabled = enable;
14860   if (stream_name_set != 0)
14861     {
14862       mp->stream_name_length = ntohl (name_len);
14863       clib_memcpy (mp->stream_name, stream_name, name_len);
14864     }
14865   vec_free (stream_name);
14866
14867   S;
14868   W;
14869   /* NOTREACHED */
14870   return 0;
14871 }
14872
14873 int
14874 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14875 {
14876   unformat_input_t *input = vam->input;
14877   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14878   f64 timeout;
14879
14880   u16 *low_ports = 0;
14881   u16 *high_ports = 0;
14882   u16 this_low;
14883   u16 this_hi;
14884   ip4_address_t ip4_addr;
14885   ip6_address_t ip6_addr;
14886   u32 length;
14887   u32 tmp, tmp2;
14888   u8 prefix_set = 0;
14889   u32 vrf_id = ~0;
14890   u8 is_add = 1;
14891   u8 is_ipv6 = 0;
14892
14893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14894     {
14895       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14896         {
14897           prefix_set = 1;
14898         }
14899       else
14900         if (unformat
14901             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14902         {
14903           prefix_set = 1;
14904           is_ipv6 = 1;
14905         }
14906       else if (unformat (input, "vrf %d", &vrf_id))
14907         ;
14908       else if (unformat (input, "del"))
14909         is_add = 0;
14910       else if (unformat (input, "port %d", &tmp))
14911         {
14912           if (tmp == 0 || tmp > 65535)
14913             {
14914               errmsg ("port %d out of range", tmp);
14915               return -99;
14916             }
14917           this_low = tmp;
14918           this_hi = this_low + 1;
14919           vec_add1 (low_ports, this_low);
14920           vec_add1 (high_ports, this_hi);
14921         }
14922       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14923         {
14924           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14925             {
14926               errmsg ("incorrect range parameters\n");
14927               return -99;
14928             }
14929           this_low = tmp;
14930           /* Note: in debug CLI +1 is added to high before
14931              passing to real fn that does "the work"
14932              (ip_source_and_port_range_check_add_del).
14933              This fn is a wrapper around the binary API fn a
14934              control plane will call, which expects this increment
14935              to have occurred. Hence letting the binary API control
14936              plane fn do the increment for consistency between VAT
14937              and other control planes.
14938            */
14939           this_hi = tmp2;
14940           vec_add1 (low_ports, this_low);
14941           vec_add1 (high_ports, this_hi);
14942         }
14943       else
14944         break;
14945     }
14946
14947   if (prefix_set == 0)
14948     {
14949       errmsg ("<address>/<mask> not specified\n");
14950       return -99;
14951     }
14952
14953   if (vrf_id == ~0)
14954     {
14955       errmsg ("VRF ID required, not specified\n");
14956       return -99;
14957     }
14958
14959   if (vrf_id == 0)
14960     {
14961       errmsg
14962         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14963       return -99;
14964     }
14965
14966   if (vec_len (low_ports) == 0)
14967     {
14968       errmsg ("At least one port or port range required\n");
14969       return -99;
14970     }
14971
14972   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14973      ip_source_and_port_range_check_add_del);
14974
14975   mp->is_add = is_add;
14976
14977   if (is_ipv6)
14978     {
14979       mp->is_ipv6 = 1;
14980       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14981     }
14982   else
14983     {
14984       mp->is_ipv6 = 0;
14985       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14986     }
14987
14988   mp->mask_length = length;
14989   mp->number_of_ranges = vec_len (low_ports);
14990
14991   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14992   vec_free (low_ports);
14993
14994   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14995   vec_free (high_ports);
14996
14997   mp->vrf_id = ntohl (vrf_id);
14998
14999   S;
15000   W;
15001   /* NOTREACHED */
15002   return 0;
15003 }
15004
15005 int
15006 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15007 {
15008   unformat_input_t *input = vam->input;
15009   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15010   f64 timeout;
15011   u32 sw_if_index = ~0;
15012   int vrf_set = 0;
15013   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15014   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15015   u8 is_add = 1;
15016
15017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15018     {
15019       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15020         ;
15021       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15022         ;
15023       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15024         vrf_set = 1;
15025       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15026         vrf_set = 1;
15027       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15028         vrf_set = 1;
15029       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15030         vrf_set = 1;
15031       else if (unformat (input, "del"))
15032         is_add = 0;
15033       else
15034         break;
15035     }
15036
15037   if (sw_if_index == ~0)
15038     {
15039       errmsg ("Interface required but not specified\n");
15040       return -99;
15041     }
15042
15043   if (vrf_set == 0)
15044     {
15045       errmsg ("VRF ID required but not specified\n");
15046       return -99;
15047     }
15048
15049   if (tcp_out_vrf_id == 0
15050       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15051     {
15052       errmsg
15053         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15054       return -99;
15055     }
15056
15057   /* Construct the API message */
15058   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15059      ip_source_and_port_range_check_interface_add_del);
15060
15061   mp->sw_if_index = ntohl (sw_if_index);
15062   mp->is_add = is_add;
15063   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15064   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15065   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15066   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15067
15068   /* send it... */
15069   S;
15070
15071   /* Wait for a reply... */
15072   W;
15073 }
15074
15075 static int
15076 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15077 {
15078   unformat_input_t *i = vam->input;
15079   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15080   f64 timeout;
15081   u32 local_sa_id = 0;
15082   u32 remote_sa_id = 0;
15083   ip4_address_t src_address;
15084   ip4_address_t dst_address;
15085   u8 is_add = 1;
15086
15087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15088     {
15089       if (unformat (i, "local_sa %d", &local_sa_id))
15090         ;
15091       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15092         ;
15093       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15094         ;
15095       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15096         ;
15097       else if (unformat (i, "del"))
15098         is_add = 0;
15099       else
15100         {
15101           clib_warning ("parse error '%U'", format_unformat_error, i);
15102           return -99;
15103         }
15104     }
15105
15106   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15107
15108   mp->local_sa_id = ntohl (local_sa_id);
15109   mp->remote_sa_id = ntohl (remote_sa_id);
15110   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15111   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15112   mp->is_add = is_add;
15113
15114   S;
15115   W;
15116   /* NOTREACHED */
15117   return 0;
15118 }
15119
15120 static void vl_api_ipsec_gre_tunnel_details_t_handler
15121   (vl_api_ipsec_gre_tunnel_details_t * mp)
15122 {
15123   vat_main_t *vam = &vat_main;
15124
15125   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15126            ntohl (mp->sw_if_index),
15127            format_ip4_address, &mp->src_address,
15128            format_ip4_address, &mp->dst_address,
15129            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15130 }
15131
15132 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15133   (vl_api_ipsec_gre_tunnel_details_t * mp)
15134 {
15135   vat_main_t *vam = &vat_main;
15136   vat_json_node_t *node = NULL;
15137   struct in_addr ip4;
15138
15139   if (VAT_JSON_ARRAY != vam->json_tree.type)
15140     {
15141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15142       vat_json_init_array (&vam->json_tree);
15143     }
15144   node = vat_json_array_add (&vam->json_tree);
15145
15146   vat_json_init_object (node);
15147   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15148   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15149   vat_json_object_add_ip4 (node, "src_address", ip4);
15150   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15151   vat_json_object_add_ip4 (node, "dst_address", ip4);
15152   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15153   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15154 }
15155
15156 static int
15157 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15158 {
15159   unformat_input_t *i = vam->input;
15160   vl_api_ipsec_gre_tunnel_dump_t *mp;
15161   f64 timeout;
15162   u32 sw_if_index;
15163   u8 sw_if_index_set = 0;
15164
15165   /* Parse args required to build the message */
15166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15167     {
15168       if (unformat (i, "sw_if_index %d", &sw_if_index))
15169         sw_if_index_set = 1;
15170       else
15171         break;
15172     }
15173
15174   if (sw_if_index_set == 0)
15175     {
15176       sw_if_index = ~0;
15177     }
15178
15179   if (!vam->json_output)
15180     {
15181       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15182                "sw_if_index", "src_address", "dst_address",
15183                "local_sa_id", "remote_sa_id");
15184     }
15185
15186   /* Get list of gre-tunnel interfaces */
15187   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15188
15189   mp->sw_if_index = htonl (sw_if_index);
15190
15191   S;
15192
15193   /* Use a control ping for synchronization */
15194   {
15195     vl_api_control_ping_t *mp;
15196     M (CONTROL_PING, control_ping);
15197     S;
15198   }
15199   W;
15200 }
15201
15202 static int
15203 q_or_quit (vat_main_t * vam)
15204 {
15205   longjmp (vam->jump_buf, 1);
15206   return 0;                     /* not so much */
15207 }
15208
15209 static int
15210 q (vat_main_t * vam)
15211 {
15212   return q_or_quit (vam);
15213 }
15214
15215 static int
15216 quit (vat_main_t * vam)
15217 {
15218   return q_or_quit (vam);
15219 }
15220
15221 static int
15222 comment (vat_main_t * vam)
15223 {
15224   return 0;
15225 }
15226
15227 static int
15228 cmd_cmp (void *a1, void *a2)
15229 {
15230   u8 **c1 = a1;
15231   u8 **c2 = a2;
15232
15233   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15234 }
15235
15236 static int
15237 help (vat_main_t * vam)
15238 {
15239   u8 **cmds = 0;
15240   u8 *name = 0;
15241   hash_pair_t *p;
15242   unformat_input_t *i = vam->input;
15243   int j;
15244
15245   if (unformat (i, "%s", &name))
15246     {
15247       uword *hs;
15248
15249       vec_add1 (name, 0);
15250
15251       hs = hash_get_mem (vam->help_by_name, name);
15252       if (hs)
15253         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15254       else
15255         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15256       vec_free (name);
15257       return 0;
15258     }
15259
15260   fformat (vam->ofp, "Help is available for the following:\n");
15261
15262     /* *INDENT-OFF* */
15263     hash_foreach_pair (p, vam->function_by_name,
15264     ({
15265       vec_add1 (cmds, (u8 *)(p->key));
15266     }));
15267     /* *INDENT-ON* */
15268
15269   vec_sort_with_function (cmds, cmd_cmp);
15270
15271   for (j = 0; j < vec_len (cmds); j++)
15272     fformat (vam->ofp, "%s\n", cmds[j]);
15273
15274   vec_free (cmds);
15275   return 0;
15276 }
15277
15278 static int
15279 set (vat_main_t * vam)
15280 {
15281   u8 *name = 0, *value = 0;
15282   unformat_input_t *i = vam->input;
15283
15284   if (unformat (i, "%s", &name))
15285     {
15286       /* The input buffer is a vector, not a string. */
15287       value = vec_dup (i->buffer);
15288       vec_delete (value, i->index, 0);
15289       /* Almost certainly has a trailing newline */
15290       if (value[vec_len (value) - 1] == '\n')
15291         value[vec_len (value) - 1] = 0;
15292       /* Make sure it's a proper string, one way or the other */
15293       vec_add1 (value, 0);
15294       (void) clib_macro_set_value (&vam->macro_main,
15295                                    (char *) name, (char *) value);
15296     }
15297   else
15298     errmsg ("usage: set <name> <value>\n");
15299
15300   vec_free (name);
15301   vec_free (value);
15302   return 0;
15303 }
15304
15305 static int
15306 unset (vat_main_t * vam)
15307 {
15308   u8 *name = 0;
15309
15310   if (unformat (vam->input, "%s", &name))
15311     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15312       errmsg ("unset: %s wasn't set\n", name);
15313   vec_free (name);
15314   return 0;
15315 }
15316
15317 typedef struct
15318 {
15319   u8 *name;
15320   u8 *value;
15321 } macro_sort_t;
15322
15323
15324 static int
15325 macro_sort_cmp (void *a1, void *a2)
15326 {
15327   macro_sort_t *s1 = a1;
15328   macro_sort_t *s2 = a2;
15329
15330   return strcmp ((char *) (s1->name), (char *) (s2->name));
15331 }
15332
15333 static int
15334 dump_macro_table (vat_main_t * vam)
15335 {
15336   macro_sort_t *sort_me = 0, *sm;
15337   int i;
15338   hash_pair_t *p;
15339
15340     /* *INDENT-OFF* */
15341     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15342     ({
15343       vec_add2 (sort_me, sm, 1);
15344       sm->name = (u8 *)(p->key);
15345       sm->value = (u8 *) (p->value[0]);
15346     }));
15347     /* *INDENT-ON* */
15348
15349   vec_sort_with_function (sort_me, macro_sort_cmp);
15350
15351   if (vec_len (sort_me))
15352     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15353   else
15354     fformat (vam->ofp, "The macro table is empty...\n");
15355
15356   for (i = 0; i < vec_len (sort_me); i++)
15357     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15358   return 0;
15359 }
15360
15361 static int
15362 dump_node_table (vat_main_t * vam)
15363 {
15364   int i, j;
15365   vlib_node_t *node, *next_node;
15366
15367   if (vec_len (vam->graph_nodes) == 0)
15368     {
15369       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15370       return 0;
15371     }
15372
15373   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15374     {
15375       node = vam->graph_nodes[i];
15376       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15377       for (j = 0; j < vec_len (node->next_nodes); j++)
15378         {
15379           if (node->next_nodes[j] != ~0)
15380             {
15381               next_node = vam->graph_nodes[node->next_nodes[j]];
15382               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15383             }
15384         }
15385     }
15386   return 0;
15387 }
15388
15389 static int
15390 search_node_table (vat_main_t * vam)
15391 {
15392   unformat_input_t *line_input = vam->input;
15393   u8 *node_to_find;
15394   int j;
15395   vlib_node_t *node, *next_node;
15396   uword *p;
15397
15398   if (vam->graph_node_index_by_name == 0)
15399     {
15400       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15401       return 0;
15402     }
15403
15404   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15405     {
15406       if (unformat (line_input, "%s", &node_to_find))
15407         {
15408           vec_add1 (node_to_find, 0);
15409           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15410           if (p == 0)
15411             {
15412               fformat (vam->ofp, "%s not found...\n", node_to_find);
15413               goto out;
15414             }
15415           node = vam->graph_nodes[p[0]];
15416           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15417           for (j = 0; j < vec_len (node->next_nodes); j++)
15418             {
15419               if (node->next_nodes[j] != ~0)
15420                 {
15421                   next_node = vam->graph_nodes[node->next_nodes[j]];
15422                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15423                 }
15424             }
15425         }
15426
15427       else
15428         {
15429           clib_warning ("parse error '%U'", format_unformat_error,
15430                         line_input);
15431           return -99;
15432         }
15433
15434     out:
15435       vec_free (node_to_find);
15436
15437     }
15438
15439   return 0;
15440 }
15441
15442
15443 static int
15444 script (vat_main_t * vam)
15445 {
15446   u8 *s = 0;
15447   char *save_current_file;
15448   unformat_input_t save_input;
15449   jmp_buf save_jump_buf;
15450   u32 save_line_number;
15451
15452   FILE *new_fp, *save_ifp;
15453
15454   if (unformat (vam->input, "%s", &s))
15455     {
15456       new_fp = fopen ((char *) s, "r");
15457       if (new_fp == 0)
15458         {
15459           errmsg ("Couldn't open script file %s\n", s);
15460           vec_free (s);
15461           return -99;
15462         }
15463     }
15464   else
15465     {
15466       errmsg ("Missing script name\n");
15467       return -99;
15468     }
15469
15470   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15471   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15472   save_ifp = vam->ifp;
15473   save_line_number = vam->input_line_number;
15474   save_current_file = (char *) vam->current_file;
15475
15476   vam->input_line_number = 0;
15477   vam->ifp = new_fp;
15478   vam->current_file = s;
15479   do_one_file (vam);
15480
15481   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15482   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15483   vam->ifp = save_ifp;
15484   vam->input_line_number = save_line_number;
15485   vam->current_file = (u8 *) save_current_file;
15486   vec_free (s);
15487
15488   return 0;
15489 }
15490
15491 static int
15492 echo (vat_main_t * vam)
15493 {
15494   fformat (vam->ofp, "%v", vam->input->buffer);
15495   return 0;
15496 }
15497
15498 /* List of API message constructors, CLI names map to api_xxx */
15499 #define foreach_vpe_api_msg                                             \
15500 _(create_loopback,"[mac <mac-addr>]")                                   \
15501 _(sw_interface_dump,"")                                                 \
15502 _(sw_interface_set_flags,                                               \
15503   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15504 _(sw_interface_add_del_address,                                         \
15505   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15506 _(sw_interface_set_table,                                               \
15507   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15508 _(sw_interface_set_vpath,                                               \
15509   "<intfc> | sw_if_index <id> enable | disable")                        \
15510 _(sw_interface_set_l2_xconnect,                                         \
15511   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15512   "enable | disable")                                                   \
15513 _(sw_interface_set_l2_bridge,                                           \
15514   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15515   "[shg <split-horizon-group>] [bvi]\n"                                 \
15516   "enable | disable")                                                   \
15517 _(bridge_domain_add_del,                                                \
15518   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15519 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15520 _(l2fib_add_del,                                                        \
15521   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15522 _(l2_flags,                                                             \
15523   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15524 _(bridge_flags,                                                         \
15525   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15526 _(tap_connect,                                                          \
15527   "tapname <name> mac <mac-addr> | random-mac")                         \
15528 _(tap_modify,                                                           \
15529   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15530 _(tap_delete,                                                           \
15531   "<vpp-if-name> | sw_if_index <id>")                                   \
15532 _(sw_interface_tap_dump, "")                                            \
15533 _(ip_add_del_route,                                                     \
15534   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15535   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15536   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15537   "[multipath] [count <n>]")                                            \
15538 _(proxy_arp_add_del,                                                    \
15539   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15540 _(proxy_arp_intfc_enable_disable,                                       \
15541   "<intfc> | sw_if_index <id> enable | disable")                        \
15542 _(mpls_add_del_encap,                                                   \
15543   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15544 _(mpls_add_del_decap,                                                   \
15545   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15546 _(mpls_gre_add_del_tunnel,                                              \
15547   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15548   "adj <ip4-address>/<mask-width> [del]")                               \
15549 _(sw_interface_set_unnumbered,                                          \
15550   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15551 _(ip_neighbor_add_del,                                                  \
15552   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15553   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15554 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15555 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15556 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15557   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15558   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15559   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15560 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15561 _(reset_fib, "vrf <n> [ipv6]")                                          \
15562 _(dhcp_proxy_config,                                                    \
15563   "svr <v46-address> src <v46-address>\n"                               \
15564    "insert-cid <n> [del]")                                              \
15565 _(dhcp_proxy_config_2,                                                  \
15566   "svr <v46-address> src <v46-address>\n"                               \
15567    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15568 _(dhcp_proxy_set_vss,                                                   \
15569   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15570 _(dhcp_client_config,                                                   \
15571   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15572 _(set_ip_flow_hash,                                                     \
15573   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15574 _(sw_interface_ip6_enable_disable,                                      \
15575   "<intfc> | sw_if_index <id> enable | disable")                        \
15576 _(sw_interface_ip6_set_link_local_address,                              \
15577   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15578 _(sw_interface_ip6nd_ra_prefix,                                         \
15579   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15580   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15581   "[nolink] [isno]")                                                    \
15582 _(sw_interface_ip6nd_ra_config,                                         \
15583   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15584   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15585   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15586 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15587 _(l2_patch_add_del,                                                     \
15588   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15589   "enable | disable")                                                   \
15590 _(mpls_ethernet_add_del_tunnel,                                         \
15591   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15592   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15593 _(mpls_ethernet_add_del_tunnel_2,                                       \
15594   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15595   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15596 _(sr_tunnel_add_del,                                                    \
15597   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15598   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15599   "[policy <policy_name>]")                                             \
15600 _(sr_policy_add_del,                                                    \
15601   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15602 _(sr_multicast_map_add_del,                                             \
15603   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15604 _(classify_add_del_table,                                               \
15605   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15606   "[del] mask <mask-value>\n"                                           \
15607   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15608 _(classify_add_del_session,                                             \
15609   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15610   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15611   "  [l3 [ip4|ip6]]")                                                   \
15612 _(classify_set_interface_ip_table,                                      \
15613   "<intfc> | sw_if_index <nn> table <nn>")                              \
15614 _(classify_set_interface_l2_tables,                                     \
15615   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15616   "  [other-table <nn>]")                                               \
15617 _(get_node_index, "node <node-name")                                    \
15618 _(add_node_next, "node <node-name> next <next-node-name>")              \
15619 _(l2tpv3_create_tunnel,                                                 \
15620   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15621   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15622   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15623 _(l2tpv3_set_tunnel_cookies,                                            \
15624   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15625   "[new_remote_cookie <nn>]\n")                                         \
15626 _(l2tpv3_interface_enable_disable,                                      \
15627   "<intfc> | sw_if_index <nn> enable | disable")                        \
15628 _(l2tpv3_set_lookup_key,                                                \
15629   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15630 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15631 _(vxlan_add_del_tunnel,                                                 \
15632   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15633   " [decap-next l2|ip4|ip6] [del]")                                     \
15634 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15635 _(gre_add_del_tunnel,                                                   \
15636   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15637 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15638 _(l2_fib_clear_table, "")                                               \
15639 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15640 _(l2_interface_vlan_tag_rewrite,                                        \
15641   "<intfc> | sw_if_index <nn> \n"                                       \
15642   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15643   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15644 _(create_vhost_user_if,                                                 \
15645         "socket <filename> [server] [renumber <dev_instance>] "         \
15646         "[mac <mac_address>]")                                          \
15647 _(modify_vhost_user_if,                                                 \
15648         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15649         "[server] [renumber <dev_instance>]")                           \
15650 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15651 _(sw_interface_vhost_user_dump, "")                                     \
15652 _(show_version, "")                                                     \
15653 _(vxlan_gpe_add_del_tunnel,                                             \
15654   "local <addr> remote <addr> vni <nn>\n"                               \
15655     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15656   "[next-ethernet] [next-nsh]\n")                                       \
15657 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15658 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15659 _(interface_name_renumber,                                              \
15660   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15661 _(input_acl_set_interface,                                              \
15662   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15663   "  [l2-table <nn>] [del]")                                            \
15664 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15665 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15666 _(ip_dump, "ipv4 | ipv6")                                               \
15667 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15668 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15669   "  spid_id <n> ")                                                     \
15670 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15671   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15672   "  integ_alg <alg> integ_key <hex>")                                  \
15673 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15674   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15675   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15676   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15677 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15678 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15679 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15680   "(auth_data 0x<data> | auth_data <data>)")                            \
15681 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15682   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15683 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15684   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15685   "(local|remote)")                                                     \
15686 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15687 _(delete_loopback,"sw_if_index <nn>")                                   \
15688 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15689 _(map_add_domain,                                                       \
15690   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15691   "ip6-src <ip6addr> "                                                  \
15692   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15693 _(map_del_domain, "index <n>")                                          \
15694 _(map_add_del_rule,                                                     \
15695   "index <n> psid <n> dst <ip6addr> [del]")                             \
15696 _(map_domain_dump, "")                                                  \
15697 _(map_rule_dump, "index <map-domain>")                                  \
15698 _(want_interface_events,  "enable|disable")                             \
15699 _(want_stats,"enable|disable")                                          \
15700 _(get_first_msg_id, "client <name>")                                    \
15701 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15702 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15703   "fib-id <nn> [ip4][ip6][default]")                                    \
15704 _(get_node_graph, " ")                                                  \
15705 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15706 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15707   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15708   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15709 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15710   " vrf_id <nn>  add | pop | none")                                     \
15711 _(trace_profile_del, "")                                                \
15712 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15713                             " sw_if_index <sw_if_index> p <priority> "  \
15714                             "w <weight>] [del]")                        \
15715 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15716                         "iface <intf> | sw_if_index <sw_if_index> "     \
15717                         "p <priority> w <weight> [del]")                \
15718 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15719                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15720                           "locator-set <locator_name> [del]")           \
15721 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15722   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15723 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15724 _(lisp_gpe_enable_disable, "enable|disable")                            \
15725 _(lisp_enable_disable, "enable|disable")                                \
15726 _(lisp_gpe_add_del_iface, "up|down")                                    \
15727 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15728                                "rloc <locator> p <prio> "               \
15729                                "w <weight> [rloc <loc> ... ] "          \
15730                                "action <action> [del-all]")             \
15731 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15732                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15733                           "[rloc <loc> ... ] action <action>")          \
15734 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15735 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15736 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15737 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15738                          "locator-set <loc-set-name>] [local | remote]")\
15739 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15740                        "[local] | [remote]")                            \
15741 _(lisp_eid_table_vni_dump, "")                                          \
15742 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15743 _(lisp_gpe_tunnel_dump, "")                                             \
15744 _(lisp_map_resolver_dump, "")                                           \
15745 _(show_lisp_status, "")                                                 \
15746 _(lisp_get_map_request_itr_rlocs, "")                                   \
15747 _(show_lisp_pitr, "")                                                   \
15748 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15749 _(af_packet_delete, "name <host interface name>")                       \
15750 _(policer_add_del, "name <policer name> <params> [del]")                \
15751 _(policer_dump, "[name <policer name>]")                                \
15752 _(policer_classify_set_interface,                                       \
15753   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15754   "  [l2-table <nn>] [del]")                                            \
15755 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15756 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15757     "[master|slave]")                                                   \
15758 _(netmap_delete, "name <interface name>")                               \
15759 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15760 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15761 _(mpls_fib_encap_dump, "")                                              \
15762 _(mpls_fib_decap_dump, "")                                              \
15763 _(classify_table_ids, "")                                               \
15764 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15765 _(classify_table_info, "table_id <nn>")                                 \
15766 _(classify_session_dump, "table_id <nn>")                               \
15767 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15768                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15769                 "[template_interval <nn>]")                             \
15770 _(ipfix_dump, "")                                                       \
15771 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15772 _(pg_create_interface, "if_id <nn>")                                    \
15773 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15774 _(pg_enable_disable, "[stream <id>] disable")                           \
15775 _(ip_source_and_port_range_check_add_del,                               \
15776   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15777 _(ip_source_and_port_range_check_interface_add_del,                     \
15778   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15779   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15780 _(ipsec_gre_add_del_tunnel,                                             \
15781   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15782 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")
15783
15784 /* List of command functions, CLI names map directly to functions */
15785 #define foreach_cli_function                                    \
15786 _(comment, "usage: comment <ignore-rest-of-line>")              \
15787 _(dump_interface_table, "usage: dump_interface_table")          \
15788 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15789 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15790 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15791 _(dump_stats_table, "usage: dump_stats_table")                  \
15792 _(dump_macro_table, "usage: dump_macro_table ")                 \
15793 _(dump_node_table, "usage: dump_node_table")                    \
15794 _(echo, "usage: echo <message>")                                \
15795 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15796 _(help, "usage: help")                                          \
15797 _(q, "usage: quit")                                             \
15798 _(quit, "usage: quit")                                          \
15799 _(search_node_table, "usage: search_node_table <name>...")      \
15800 _(set, "usage: set <variable-name> <value>")                    \
15801 _(script, "usage: script <file-name>")                          \
15802 _(unset, "usage: unset <variable-name>")
15803
15804 #define _(N,n)                                  \
15805     static void vl_api_##n##_t_handler_uni      \
15806     (vl_api_##n##_t * mp)                       \
15807     {                                           \
15808         vat_main_t * vam = &vat_main;           \
15809         if (vam->json_output) {                 \
15810             vl_api_##n##_t_handler_json(mp);    \
15811         } else {                                \
15812             vl_api_##n##_t_handler(mp);         \
15813         }                                       \
15814     }
15815 foreach_vpe_api_reply_msg;
15816 #undef _
15817
15818 void
15819 vat_api_hookup (vat_main_t * vam)
15820 {
15821 #define _(N,n)                                                  \
15822     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15823                            vl_api_##n##_t_handler_uni,          \
15824                            vl_noop_handler,                     \
15825                            vl_api_##n##_t_endian,               \
15826                            vl_api_##n##_t_print,                \
15827                            sizeof(vl_api_##n##_t), 1);
15828   foreach_vpe_api_reply_msg;
15829 #undef _
15830
15831   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15832
15833   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15834
15835   vam->function_by_name = hash_create_string (0, sizeof (uword));
15836
15837   vam->help_by_name = hash_create_string (0, sizeof (uword));
15838
15839   /* API messages we can send */
15840 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15841   foreach_vpe_api_msg;
15842 #undef _
15843
15844   /* Help strings */
15845 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15846   foreach_vpe_api_msg;
15847 #undef _
15848
15849   /* CLI functions */
15850 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15851   foreach_cli_function;
15852 #undef _
15853
15854   /* Help strings */
15855 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15856   foreach_cli_function;
15857 #undef _
15858 }
15859
15860 #undef vl_api_version
15861 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15862 #include <vpp-api/vpe.api.h>
15863 #undef vl_api_version
15864
15865 void
15866 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15867 {
15868   /*
15869    * Send the main API signature in slot 0. This bit of code must
15870    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15871    */
15872   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15873 }
15874
15875 /*
15876  * fd.io coding-style-patch-verification: ON
15877  *
15878  * Local Variables:
15879  * eval: (c-set-style "gnu")
15880  * End:
15881  */