VPP-240: delete subinterface
[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 add_lisp_eid_table_entry (vat_main_t * vam,
2365                           vl_api_lisp_eid_table_details_t * mp)
2366 {
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 = clib_net_to_host_u32 (mp->locator_set_index);
2372   eid_table.eid_type = mp->eid_type;
2373   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2374   eid_table.eid_prefix_len = mp->eid_prefix_len;
2375   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2376   eid_table.action = mp->action;
2377   eid_table.authoritative = mp->authoritative;
2378   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2379   vec_add1 (vam->eid_tables, eid_table);
2380 }
2381
2382 static void
2383 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   add_lisp_eid_table_entry (vam, mp);
2387 }
2388
2389 static void
2390 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2391                                               * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   add_lisp_eid_table_entry (vam, mp);
2395 }
2396
2397 static void
2398   vl_api_lisp_eid_table_map_details_t_handler
2399   (vl_api_lisp_eid_table_map_details_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402
2403   u8 *line = format (0, "%=10d%=10d",
2404                      clib_net_to_host_u32 (mp->vni),
2405                      clib_net_to_host_u32 (mp->dp_table));
2406   fformat (vam->ofp, "%v\n", line);
2407   vec_free (line);
2408 }
2409
2410 static void
2411   vl_api_lisp_eid_table_map_details_t_handler_json
2412   (vl_api_lisp_eid_table_map_details_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   vat_json_node_t *node = NULL;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422   node = vat_json_array_add (&vam->json_tree);
2423   vat_json_init_object (node);
2424   vat_json_object_add_uint (node, "dp_table",
2425                             clib_net_to_host_u32 (mp->dp_table));
2426   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2427 }
2428
2429 static void
2430   vl_api_lisp_eid_table_vni_details_t_handler
2431   (vl_api_lisp_eid_table_vni_details_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434
2435   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2436   fformat (vam->ofp, "%v\n", line);
2437   vec_free (line);
2438 }
2439
2440 static void
2441   vl_api_lisp_eid_table_vni_details_t_handler_json
2442   (vl_api_lisp_eid_table_vni_details_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t *node = NULL;
2446
2447   if (VAT_JSON_ARRAY != vam->json_tree.type)
2448     {
2449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2450       vat_json_init_array (&vam->json_tree);
2451     }
2452   node = vat_json_array_add (&vam->json_tree);
2453   vat_json_init_object (node);
2454   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2455 }
2456
2457 static u8 *
2458 format_decap_next (u8 * s, va_list * args)
2459 {
2460   u32 next_index = va_arg (*args, u32);
2461
2462   switch (next_index)
2463     {
2464     case LISP_GPE_INPUT_NEXT_DROP:
2465       return format (s, "drop");
2466     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2467       return format (s, "ip4");
2468     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2469       return format (s, "ip6");
2470     default:
2471       return format (s, "unknown %d", next_index);
2472     }
2473   return s;
2474 }
2475
2476 static void
2477 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2478                                           mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   u8 *iid_str;
2482   u8 *flag_str = NULL;
2483
2484   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2485
2486 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2487   foreach_lisp_gpe_flag_bit;
2488 #undef _
2489
2490   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2491            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2492            mp->tunnels,
2493            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2494            mp->source_ip,
2495            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2496            mp->destination_ip,
2497            ntohl (mp->encap_fib_id),
2498            ntohl (mp->decap_fib_id),
2499            format_decap_next, ntohl (mp->dcap_next),
2500            mp->ver_res >> 6,
2501            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2502
2503   vec_free (iid_str);
2504 }
2505
2506 static void
2507   vl_api_lisp_gpe_tunnel_details_t_handler_json
2508   (vl_api_lisp_gpe_tunnel_details_t * mp)
2509 {
2510   vat_main_t *vam = &vat_main;
2511   vat_json_node_t *node = NULL;
2512   struct in6_addr ip6;
2513   struct in_addr ip4;
2514   u8 *next_decap_str;
2515
2516   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2517
2518   if (VAT_JSON_ARRAY != vam->json_tree.type)
2519     {
2520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2521       vat_json_init_array (&vam->json_tree);
2522     }
2523   node = vat_json_array_add (&vam->json_tree);
2524
2525   vat_json_init_object (node);
2526   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2527   if (mp->is_ipv6)
2528     {
2529       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2530       vat_json_object_add_ip6 (node, "source address", ip6);
2531       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2532       vat_json_object_add_ip6 (node, "destination address", ip6);
2533     }
2534   else
2535     {
2536       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2537       vat_json_object_add_ip4 (node, "source address", ip4);
2538       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2539       vat_json_object_add_ip4 (node, "destination address", ip4);
2540     }
2541   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2542   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2543   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2544   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2545   vat_json_object_add_uint (node, "flags", mp->flags);
2546   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2547   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2548   vat_json_object_add_uint (node, "res", mp->res);
2549   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2550
2551   vec_free (next_decap_str);
2552 }
2553
2554 static void
2555 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2556                                             * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559
2560   fformat (vam->ofp, "%=20U\n",
2561            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2562            mp->ip_address);
2563 }
2564
2565 static void
2566   vl_api_lisp_map_resolver_details_t_handler_json
2567   (vl_api_lisp_map_resolver_details_t * mp)
2568 {
2569   vat_main_t *vam = &vat_main;
2570   vat_json_node_t *node = NULL;
2571   struct in6_addr ip6;
2572   struct in_addr ip4;
2573
2574   if (VAT_JSON_ARRAY != vam->json_tree.type)
2575     {
2576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2577       vat_json_init_array (&vam->json_tree);
2578     }
2579   node = vat_json_array_add (&vam->json_tree);
2580
2581   vat_json_init_object (node);
2582   if (mp->is_ipv6)
2583     {
2584       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2585       vat_json_object_add_ip6 (node, "map resolver", ip6);
2586     }
2587   else
2588     {
2589       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2590       vat_json_object_add_ip4 (node, "map resolver", ip4);
2591     }
2592 }
2593
2594 static void
2595   vl_api_show_lisp_status_reply_t_handler
2596   (vl_api_show_lisp_status_reply_t * mp)
2597 {
2598   vat_main_t *vam = &vat_main;
2599   i32 retval = ntohl (mp->retval);
2600
2601   if (0 <= retval)
2602     {
2603       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2604                mp->feature_status ? "enabled" : "disabled",
2605                mp->gpe_status ? "enabled" : "disabled");
2606     }
2607
2608   vam->retval = retval;
2609   vam->result_ready = 1;
2610 }
2611
2612 static void
2613   vl_api_show_lisp_status_reply_t_handler_json
2614   (vl_api_show_lisp_status_reply_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   vat_json_node_t node;
2618   u8 *gpe_status = NULL;
2619   u8 *feature_status = NULL;
2620
2621   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2622   feature_status = format (0, "%s",
2623                            mp->feature_status ? "enabled" : "disabled");
2624   vec_add1 (gpe_status, 0);
2625   vec_add1 (feature_status, 0);
2626
2627   vat_json_init_object (&node);
2628   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2629   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2630
2631   vec_free (gpe_status);
2632   vec_free (feature_status);
2633
2634   vat_json_print (vam->ofp, &node);
2635   vat_json_free (&node);
2636
2637   vam->retval = ntohl (mp->retval);
2638   vam->result_ready = 1;
2639 }
2640
2641 static void
2642   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2643   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2644 {
2645   vat_main_t *vam = &vat_main;
2646   i32 retval = ntohl (mp->retval);
2647
2648   if (retval >= 0)
2649     {
2650       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2659   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t *node = NULL;
2663
2664   if (VAT_JSON_ARRAY != vam->json_tree.type)
2665     {
2666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2667       vat_json_init_array (&vam->json_tree);
2668     }
2669   node = vat_json_array_add (&vam->json_tree);
2670
2671   vat_json_init_object (node);
2672   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2673
2674   vat_json_print (vam->ofp, node);
2675   vat_json_free (node);
2676
2677   vam->retval = ntohl (mp->retval);
2678   vam->result_ready = 1;
2679 }
2680
2681 static void
2682 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2683 {
2684   vat_main_t *vam = &vat_main;
2685   i32 retval = ntohl (mp->retval);
2686
2687   if (0 <= retval)
2688     {
2689       fformat (vam->ofp, "%-20s%-16s\n",
2690                mp->status ? "enabled" : "disabled",
2691                mp->status ? (char *) mp->locator_set_name : "");
2692     }
2693
2694   vam->retval = retval;
2695   vam->result_ready = 1;
2696 }
2697
2698 static void
2699 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2700                                             mp)
2701 {
2702   vat_main_t *vam = &vat_main;
2703   vat_json_node_t node;
2704   u8 *status = 0;
2705
2706   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2707   vec_add1 (status, 0);
2708
2709   vat_json_init_object (&node);
2710   vat_json_object_add_string_copy (&node, "status", status);
2711   if (mp->status)
2712     {
2713       vat_json_object_add_string_copy (&node, "locator_set",
2714                                        mp->locator_set_name);
2715     }
2716
2717   vec_free (status);
2718
2719   vat_json_print (vam->ofp, &node);
2720   vat_json_free (&node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static u8 *
2727 format_policer_type (u8 * s, va_list * va)
2728 {
2729   u32 i = va_arg (*va, u32);
2730
2731   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2732     s = format (s, "1r2c");
2733   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2734     s = format (s, "1r3c");
2735   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2736     s = format (s, "2r3c-2698");
2737   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2738     s = format (s, "2r3c-4115");
2739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2740     s = format (s, "2r3c-mef5cf1");
2741   else
2742     s = format (s, "ILLEGAL");
2743   return s;
2744 }
2745
2746 static u8 *
2747 format_policer_rate_type (u8 * s, va_list * va)
2748 {
2749   u32 i = va_arg (*va, u32);
2750
2751   if (i == SSE2_QOS_RATE_KBPS)
2752     s = format (s, "kbps");
2753   else if (i == SSE2_QOS_RATE_PPS)
2754     s = format (s, "pps");
2755   else
2756     s = format (s, "ILLEGAL");
2757   return s;
2758 }
2759
2760 static u8 *
2761 format_policer_round_type (u8 * s, va_list * va)
2762 {
2763   u32 i = va_arg (*va, u32);
2764
2765   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2766     s = format (s, "closest");
2767   else if (i == SSE2_QOS_ROUND_TO_UP)
2768     s = format (s, "up");
2769   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2770     s = format (s, "down");
2771   else
2772     s = format (s, "ILLEGAL");
2773   return s;
2774 }
2775
2776 static u8 *
2777 format_policer_action_type (u8 * s, va_list * va)
2778 {
2779   u32 i = va_arg (*va, u32);
2780
2781   if (i == SSE2_QOS_ACTION_DROP)
2782     s = format (s, "drop");
2783   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2784     s = format (s, "transmit");
2785   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2786     s = format (s, "mark-and-transmit");
2787   else
2788     s = format (s, "ILLEGAL");
2789   return s;
2790 }
2791
2792 static u8 *
2793 format_dscp (u8 * s, va_list * va)
2794 {
2795   u32 i = va_arg (*va, u32);
2796   char *t = 0;
2797
2798   switch (i)
2799     {
2800 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2801       foreach_vnet_dscp
2802 #undef _
2803     default:
2804       return format (s, "ILLEGAL");
2805     }
2806   s = format (s, "%s", t);
2807   return s;
2808 }
2809
2810 static void
2811 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2815
2816   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2817     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2818   else
2819     conform_dscp_str = format (0, "");
2820
2821   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2822     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2823   else
2824     exceed_dscp_str = format (0, "");
2825
2826   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2827     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2828   else
2829     violate_dscp_str = format (0, "");
2830
2831   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2832            "rate type %U, round type %U, %s rate, %s color-aware, "
2833            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2834            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2835            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2836            mp->name,
2837            format_policer_type, mp->type,
2838            ntohl (mp->cir),
2839            ntohl (mp->eir),
2840            clib_net_to_host_u64 (mp->cb),
2841            clib_net_to_host_u64 (mp->eb),
2842            format_policer_rate_type, mp->rate_type,
2843            format_policer_round_type, mp->round_type,
2844            mp->single_rate ? "single" : "dual",
2845            mp->color_aware ? "is" : "not",
2846            ntohl (mp->cir_tokens_per_period),
2847            ntohl (mp->pir_tokens_per_period),
2848            ntohl (mp->scale),
2849            ntohl (mp->current_limit),
2850            ntohl (mp->current_bucket),
2851            ntohl (mp->extended_limit),
2852            ntohl (mp->extended_bucket),
2853            clib_net_to_host_u64 (mp->last_update_time),
2854            format_policer_action_type, mp->conform_action_type,
2855            conform_dscp_str,
2856            format_policer_action_type, mp->exceed_action_type,
2857            exceed_dscp_str,
2858            format_policer_action_type, mp->violate_action_type,
2859            violate_dscp_str);
2860
2861   vec_free (conform_dscp_str);
2862   vec_free (exceed_dscp_str);
2863   vec_free (violate_dscp_str);
2864 }
2865
2866 static void vl_api_policer_details_t_handler_json
2867   (vl_api_policer_details_t * mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   vat_json_node_t *node;
2871   u8 *rate_type_str, *round_type_str, *type_str;
2872   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2873
2874   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2875   round_type_str =
2876     format (0, "%U", format_policer_round_type, mp->round_type);
2877   type_str = format (0, "%U", format_policer_type, mp->type);
2878   conform_action_str = format (0, "%U", format_policer_action_type,
2879                                mp->conform_action_type);
2880   exceed_action_str = format (0, "%U", format_policer_action_type,
2881                               mp->exceed_action_type);
2882   violate_action_str = format (0, "%U", format_policer_action_type,
2883                                mp->violate_action_type);
2884
2885   if (VAT_JSON_ARRAY != vam->json_tree.type)
2886     {
2887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2888       vat_json_init_array (&vam->json_tree);
2889     }
2890   node = vat_json_array_add (&vam->json_tree);
2891
2892   vat_json_init_object (node);
2893   vat_json_object_add_string_copy (node, "name", mp->name);
2894   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2895   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2896   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2897   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2898   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2899   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2900   vat_json_object_add_string_copy (node, "type", type_str);
2901   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2902   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2903   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2904   vat_json_object_add_uint (node, "cir_tokens_per_period",
2905                             ntohl (mp->cir_tokens_per_period));
2906   vat_json_object_add_uint (node, "eir_tokens_per_period",
2907                             ntohl (mp->pir_tokens_per_period));
2908   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2909   vat_json_object_add_uint (node, "current_bucket",
2910                             ntohl (mp->current_bucket));
2911   vat_json_object_add_uint (node, "extended_limit",
2912                             ntohl (mp->extended_limit));
2913   vat_json_object_add_uint (node, "extended_bucket",
2914                             ntohl (mp->extended_bucket));
2915   vat_json_object_add_uint (node, "last_update_time",
2916                             ntohl (mp->last_update_time));
2917   vat_json_object_add_string_copy (node, "conform_action",
2918                                    conform_action_str);
2919   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2920     {
2921       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2922       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2923       vec_free (dscp_str);
2924     }
2925   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2926   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2927     {
2928       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2929       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2930       vec_free (dscp_str);
2931     }
2932   vat_json_object_add_string_copy (node, "violate_action",
2933                                    violate_action_str);
2934   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2935     {
2936       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2937       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2938       vec_free (dscp_str);
2939     }
2940
2941   vec_free (rate_type_str);
2942   vec_free (round_type_str);
2943   vec_free (type_str);
2944   vec_free (conform_action_str);
2945   vec_free (exceed_action_str);
2946   vec_free (violate_action_str);
2947 }
2948
2949 static void
2950 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2951                                            mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   int i, count = ntohl (mp->count);
2955
2956   if (count > 0)
2957     fformat (vam->ofp, "classify table ids (%d) : ", count);
2958   for (i = 0; i < count; i++)
2959     {
2960       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2961       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2962     }
2963   vam->retval = ntohl (mp->retval);
2964   vam->result_ready = 1;
2965 }
2966
2967 static void
2968   vl_api_classify_table_ids_reply_t_handler_json
2969   (vl_api_classify_table_ids_reply_t * mp)
2970 {
2971   vat_main_t *vam = &vat_main;
2972   int i, count = ntohl (mp->count);
2973
2974   if (count > 0)
2975     {
2976       vat_json_node_t node;
2977
2978       vat_json_init_object (&node);
2979       for (i = 0; i < count; i++)
2980         {
2981           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2982         }
2983       vat_json_print (vam->ofp, &node);
2984       vat_json_free (&node);
2985     }
2986   vam->retval = ntohl (mp->retval);
2987   vam->result_ready = 1;
2988 }
2989
2990 static void
2991   vl_api_classify_table_by_interface_reply_t_handler
2992   (vl_api_classify_table_by_interface_reply_t * mp)
2993 {
2994   vat_main_t *vam = &vat_main;
2995   u32 table_id;
2996
2997   table_id = ntohl (mp->l2_table_id);
2998   if (table_id != ~0)
2999     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3000   else
3001     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3002   table_id = ntohl (mp->ip4_table_id);
3003   if (table_id != ~0)
3004     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3005   else
3006     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3007   table_id = ntohl (mp->ip6_table_id);
3008   if (table_id != ~0)
3009     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3010   else
3011     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3012   vam->retval = ntohl (mp->retval);
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_classify_table_by_interface_reply_t_handler_json
3018   (vl_api_classify_table_by_interface_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t node;
3022
3023   vat_json_init_object (&node);
3024
3025   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3026   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3027   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3028
3029   vat_json_print (vam->ofp, &node);
3030   vat_json_free (&node);
3031
3032   vam->retval = ntohl (mp->retval);
3033   vam->result_ready = 1;
3034 }
3035
3036 static void vl_api_policer_add_del_reply_t_handler
3037   (vl_api_policer_add_del_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   i32 retval = ntohl (mp->retval);
3041   if (vam->async_mode)
3042     {
3043       vam->async_errors += (retval < 0);
3044     }
3045   else
3046     {
3047       vam->retval = retval;
3048       vam->result_ready = 1;
3049       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3050         /*
3051          * Note: this is just barely thread-safe, depends on
3052          * the main thread spinning waiting for an answer...
3053          */
3054         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3055     }
3056 }
3057
3058 static void vl_api_policer_add_del_reply_t_handler_json
3059   (vl_api_policer_add_del_reply_t * mp)
3060 {
3061   vat_main_t *vam = &vat_main;
3062   vat_json_node_t node;
3063
3064   vat_json_init_object (&node);
3065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3066   vat_json_object_add_uint (&node, "policer_index",
3067                             ntohl (mp->policer_index));
3068
3069   vat_json_print (vam->ofp, &node);
3070   vat_json_free (&node);
3071
3072   vam->retval = ntohl (mp->retval);
3073   vam->result_ready = 1;
3074 }
3075
3076 /* Format hex dump. */
3077 u8 *
3078 format_hex_bytes (u8 * s, va_list * va)
3079 {
3080   u8 *bytes = va_arg (*va, u8 *);
3081   int n_bytes = va_arg (*va, int);
3082   uword i;
3083
3084   /* Print short or long form depending on byte count. */
3085   uword short_form = n_bytes <= 32;
3086   uword indent = format_get_indent (s);
3087
3088   if (n_bytes == 0)
3089     return s;
3090
3091   for (i = 0; i < n_bytes; i++)
3092     {
3093       if (!short_form && (i % 32) == 0)
3094         s = format (s, "%08x: ", i);
3095       s = format (s, "%02x", bytes[i]);
3096       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3097         s = format (s, "\n%U", format_white_space, indent);
3098     }
3099
3100   return s;
3101 }
3102
3103 static void
3104 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3105                                             * mp)
3106 {
3107   vat_main_t *vam = &vat_main;
3108   i32 retval = ntohl (mp->retval);
3109   if (retval == 0)
3110     {
3111       fformat (vam->ofp, "classify table info :\n");
3112       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3113                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3114                ntohl (mp->miss_next_index));
3115       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3116                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3117                ntohl (mp->match_n_vectors));
3118       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3119                ntohl (mp->mask_length));
3120     }
3121   vam->retval = retval;
3122   vam->result_ready = 1;
3123 }
3124
3125 static void
3126   vl_api_classify_table_info_reply_t_handler_json
3127   (vl_api_classify_table_info_reply_t * mp)
3128 {
3129   vat_main_t *vam = &vat_main;
3130   vat_json_node_t node;
3131
3132   i32 retval = ntohl (mp->retval);
3133   if (retval == 0)
3134     {
3135       vat_json_init_object (&node);
3136
3137       vat_json_object_add_int (&node, "sessions",
3138                                ntohl (mp->active_sessions));
3139       vat_json_object_add_int (&node, "nexttbl",
3140                                ntohl (mp->next_table_index));
3141       vat_json_object_add_int (&node, "nextnode",
3142                                ntohl (mp->miss_next_index));
3143       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3144       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3145       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3146       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3147                       ntohl (mp->mask_length), 0);
3148       vat_json_object_add_string_copy (&node, "mask", s);
3149
3150       vat_json_print (vam->ofp, &node);
3151       vat_json_free (&node);
3152     }
3153   vam->retval = ntohl (mp->retval);
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3159                                            mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162
3163   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3164            ntohl (mp->hit_next_index), ntohl (mp->advance),
3165            ntohl (mp->opaque_index));
3166   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3167            ntohl (mp->match_length));
3168 }
3169
3170 static void
3171   vl_api_classify_session_details_t_handler_json
3172   (vl_api_classify_session_details_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t *node = NULL;
3176
3177   if (VAT_JSON_ARRAY != vam->json_tree.type)
3178     {
3179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3180       vat_json_init_array (&vam->json_tree);
3181     }
3182   node = vat_json_array_add (&vam->json_tree);
3183
3184   vat_json_init_object (node);
3185   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3186   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3187   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3188   u8 *s =
3189     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3190             0);
3191   vat_json_object_add_string_copy (node, "match", s);
3192 }
3193
3194 static void vl_api_pg_create_interface_reply_t_handler
3195   (vl_api_pg_create_interface_reply_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198
3199   vam->retval = ntohl (mp->retval);
3200   vam->result_ready = 1;
3201 }
3202
3203 static void vl_api_pg_create_interface_reply_t_handler_json
3204   (vl_api_pg_create_interface_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   i32 retval = ntohl (mp->retval);
3210   if (retval == 0)
3211     {
3212       vat_json_init_object (&node);
3213
3214       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3215
3216       vat_json_print (vam->ofp, &node);
3217       vat_json_free (&node);
3218     }
3219   vam->retval = ntohl (mp->retval);
3220   vam->result_ready = 1;
3221 }
3222
3223 static void vl_api_policer_classify_details_t_handler
3224   (vl_api_policer_classify_details_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227
3228   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3229            ntohl (mp->table_index));
3230 }
3231
3232 static void vl_api_policer_classify_details_t_handler_json
3233   (vl_api_policer_classify_details_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t *node;
3237
3238   if (VAT_JSON_ARRAY != vam->json_tree.type)
3239     {
3240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3241       vat_json_init_array (&vam->json_tree);
3242     }
3243   node = vat_json_array_add (&vam->json_tree);
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3247   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3248 }
3249
3250 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3251   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   i32 retval = ntohl (mp->retval);
3255   if (vam->async_mode)
3256     {
3257       vam->async_errors += (retval < 0);
3258     }
3259   else
3260     {
3261       vam->retval = retval;
3262       vam->sw_if_index = ntohl (mp->sw_if_index);
3263       vam->result_ready = 1;
3264     }
3265 }
3266
3267 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3268   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271   vat_json_node_t node;
3272
3273   vat_json_init_object (&node);
3274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3275   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3276
3277   vat_json_print (vam->ofp, &node);
3278   vat_json_free (&node);
3279
3280   vam->retval = ntohl (mp->retval);
3281   vam->result_ready = 1;
3282 }
3283
3284 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3285 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3286 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3287 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3288
3289 /*
3290  * Generate boilerplate reply handlers, which
3291  * dig the return value out of the xxx_reply_t API message,
3292  * stick it into vam->retval, and set vam->result_ready
3293  *
3294  * Could also do this by pointing N message decode slots at
3295  * a single function, but that could break in subtle ways.
3296  */
3297
3298 #define foreach_standard_reply_retval_handler           \
3299 _(sw_interface_set_flags_reply)                         \
3300 _(sw_interface_add_del_address_reply)                   \
3301 _(sw_interface_set_table_reply)                         \
3302 _(sw_interface_set_vpath_reply)                         \
3303 _(sw_interface_set_l2_bridge_reply)                     \
3304 _(bridge_domain_add_del_reply)                          \
3305 _(sw_interface_set_l2_xconnect_reply)                   \
3306 _(l2fib_add_del_reply)                                  \
3307 _(ip_add_del_route_reply)                               \
3308 _(proxy_arp_add_del_reply)                              \
3309 _(proxy_arp_intfc_enable_disable_reply)                 \
3310 _(mpls_add_del_encap_reply)                             \
3311 _(mpls_add_del_decap_reply)                             \
3312 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3313 _(sw_interface_set_unnumbered_reply)                    \
3314 _(ip_neighbor_add_del_reply)                            \
3315 _(reset_vrf_reply)                                      \
3316 _(oam_add_del_reply)                                    \
3317 _(reset_fib_reply)                                      \
3318 _(dhcp_proxy_config_reply)                              \
3319 _(dhcp_proxy_config_2_reply)                            \
3320 _(dhcp_proxy_set_vss_reply)                             \
3321 _(dhcp_client_config_reply)                             \
3322 _(set_ip_flow_hash_reply)                               \
3323 _(sw_interface_ip6_enable_disable_reply)                \
3324 _(sw_interface_ip6_set_link_local_address_reply)        \
3325 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3326 _(sw_interface_ip6nd_ra_config_reply)                   \
3327 _(set_arp_neighbor_limit_reply)                         \
3328 _(l2_patch_add_del_reply)                               \
3329 _(sr_tunnel_add_del_reply)                              \
3330 _(sr_policy_add_del_reply)                              \
3331 _(sr_multicast_map_add_del_reply)                       \
3332 _(classify_add_del_session_reply)                       \
3333 _(classify_set_interface_ip_table_reply)                \
3334 _(classify_set_interface_l2_tables_reply)               \
3335 _(l2tpv3_set_tunnel_cookies_reply)                      \
3336 _(l2tpv3_interface_enable_disable_reply)                \
3337 _(l2tpv3_set_lookup_key_reply)                          \
3338 _(l2_fib_clear_table_reply)                             \
3339 _(l2_interface_efp_filter_reply)                        \
3340 _(l2_interface_vlan_tag_rewrite_reply)                  \
3341 _(modify_vhost_user_if_reply)                           \
3342 _(delete_vhost_user_if_reply)                           \
3343 _(want_ip4_arp_events_reply)                            \
3344 _(input_acl_set_interface_reply)                        \
3345 _(ipsec_spd_add_del_reply)                              \
3346 _(ipsec_interface_add_del_spd_reply)                    \
3347 _(ipsec_spd_add_del_entry_reply)                        \
3348 _(ipsec_sad_add_del_entry_reply)                        \
3349 _(ipsec_sa_set_key_reply)                               \
3350 _(ikev2_profile_add_del_reply)                          \
3351 _(ikev2_profile_set_auth_reply)                         \
3352 _(ikev2_profile_set_id_reply)                           \
3353 _(ikev2_profile_set_ts_reply)                           \
3354 _(ikev2_set_local_key_reply)                            \
3355 _(delete_loopback_reply)                                \
3356 _(bd_ip_mac_add_del_reply)                              \
3357 _(map_del_domain_reply)                                 \
3358 _(map_add_del_rule_reply)                               \
3359 _(want_interface_events_reply)                          \
3360 _(want_stats_reply)                                     \
3361 _(cop_interface_enable_disable_reply)                   \
3362 _(cop_whitelist_enable_disable_reply)                   \
3363 _(sw_interface_clear_stats_reply)                       \
3364 _(trace_profile_add_reply)                              \
3365 _(trace_profile_apply_reply)                            \
3366 _(trace_profile_del_reply)                              \
3367 _(lisp_add_del_locator_reply)                           \
3368 _(lisp_add_del_local_eid_reply)                         \
3369 _(lisp_add_del_remote_mapping_reply)                    \
3370 _(lisp_add_del_adjacency_reply)                         \
3371 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3372 _(lisp_add_del_map_resolver_reply)                      \
3373 _(lisp_gpe_enable_disable_reply)                        \
3374 _(lisp_gpe_add_del_iface_reply)                         \
3375 _(lisp_enable_disable_reply)                            \
3376 _(lisp_pitr_set_locator_set_reply)                      \
3377 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3378 _(lisp_eid_table_add_del_map_reply)                     \
3379 _(vxlan_gpe_add_del_tunnel_reply)                       \
3380 _(af_packet_delete_reply)                               \
3381 _(policer_classify_set_interface_reply)                 \
3382 _(netmap_create_reply)                                  \
3383 _(netmap_delete_reply)                                  \
3384 _(ipfix_enable_reply)                                   \
3385 _(pg_capture_reply)                                     \
3386 _(pg_enable_disable_reply)                              \
3387 _(ip_source_and_port_range_check_add_del_reply)         \
3388 _(ip_source_and_port_range_check_interface_add_del_reply)\
3389 _(delete_subif_reply)
3390
3391 #define _(n)                                    \
3392     static void vl_api_##n##_t_handler          \
3393     (vl_api_##n##_t * mp)                       \
3394     {                                           \
3395         vat_main_t * vam = &vat_main;           \
3396         i32 retval = ntohl(mp->retval);         \
3397         if (vam->async_mode) {                  \
3398             vam->async_errors += (retval < 0);  \
3399         } else {                                \
3400             vam->retval = retval;               \
3401             vam->result_ready = 1;              \
3402         }                                       \
3403     }
3404 foreach_standard_reply_retval_handler;
3405 #undef _
3406
3407 #define _(n)                                    \
3408     static void vl_api_##n##_t_handler_json     \
3409     (vl_api_##n##_t * mp)                       \
3410     {                                           \
3411         vat_main_t * vam = &vat_main;           \
3412         vat_json_node_t node;                   \
3413         vat_json_init_object(&node);            \
3414         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3415         vat_json_print(vam->ofp, &node);        \
3416         vam->retval = ntohl(mp->retval);        \
3417         vam->result_ready = 1;                  \
3418     }
3419 foreach_standard_reply_retval_handler;
3420 #undef _
3421
3422 /*
3423  * Table of message reply handlers, must include boilerplate handlers
3424  * we just generated
3425  */
3426
3427 #define foreach_vpe_api_reply_msg                                       \
3428 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3429 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3430 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3431 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3432 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3433 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3434 _(CLI_REPLY, cli_reply)                                                 \
3435 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3436   sw_interface_add_del_address_reply)                                   \
3437 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3438 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3439 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3440   sw_interface_set_l2_xconnect_reply)                                   \
3441 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3442   sw_interface_set_l2_bridge_reply)                                     \
3443 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3444 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3445 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3446 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3447 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3448 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3449 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3450 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3451 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3452 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3453 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3454 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3455 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3456   proxy_arp_intfc_enable_disable_reply)                                 \
3457 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3458 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3459 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3460 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3461   mpls_ethernet_add_del_tunnel_reply)                                   \
3462 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3463   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3464 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3465   sw_interface_set_unnumbered_reply)                                    \
3466 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3467 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3468 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3469 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3470 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3471 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3472 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3473 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3474 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3475 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3476 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3477 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3478   sw_interface_ip6_enable_disable_reply)                                \
3479 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3480   sw_interface_ip6_set_link_local_address_reply)                        \
3481 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3482   sw_interface_ip6nd_ra_prefix_reply)                                   \
3483 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3484   sw_interface_ip6nd_ra_config_reply)                                   \
3485 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3486 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3487 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3488 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3489 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3490 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3491 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3492 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3493 classify_set_interface_ip_table_reply)                                  \
3494 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3495   classify_set_interface_l2_tables_reply)                               \
3496 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3497 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3498 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3499 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3500 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3501   l2tpv3_interface_enable_disable_reply)                                \
3502 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3503 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3504 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3505 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3506 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3507 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3508 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3509 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3510 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3511 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3512 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3513 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3514 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3515 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3516 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3517 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3518 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3519 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3520 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3521 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3522 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3523 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3524 _(IP_DETAILS, ip_details)                                               \
3525 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3526 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3527 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3528 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3529 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3530 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3531 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3532 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3533 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3534 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3535 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3536 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3537 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3538 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3539 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3540 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3541 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3542 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3543 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3544 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3545 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3546 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3547 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3548 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3549 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3550 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3551 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3552 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3553 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3554 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3555 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3556 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3557 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3558 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3559 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3560 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3561 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3562 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3563 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3564 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3565 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3566 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3567 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3568 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3569 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3570 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3571 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3572 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3573 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3574 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3575 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3576 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3577   lisp_add_del_map_request_itr_rlocs_reply)                             \
3578 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3579   lisp_get_map_request_itr_rlocs_reply)                                 \
3580 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3581 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3582 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3583 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3584 _(POLICER_DETAILS, policer_details)                                     \
3585 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3586 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3587 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3588 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3589 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3590 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3591 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3592 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3593 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3594 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3595 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3596 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3597 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3598 _(IPFIX_DETAILS, ipfix_details)                                         \
3599 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3600 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3601 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3602 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3603 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3604  ip_source_and_port_range_check_add_del_reply)                          \
3605 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3606  ip_source_and_port_range_check_interface_add_del_reply)                \
3607 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3608 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3609 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3610
3611 /* M: construct, but don't yet send a message */
3612
3613 #define M(T,t)                                  \
3614 do {                                            \
3615     vam->result_ready = 0;                      \
3616     mp = vl_msg_api_alloc(sizeof(*mp));         \
3617     memset (mp, 0, sizeof (*mp));               \
3618     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3619     mp->client_index = vam->my_client_index;    \
3620 } while(0);
3621
3622 #define M2(T,t,n)                               \
3623 do {                                            \
3624     vam->result_ready = 0;                      \
3625     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3626     memset (mp, 0, sizeof (*mp));               \
3627     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3628     mp->client_index = vam->my_client_index;    \
3629 } while(0);
3630
3631
3632 /* S: send a message */
3633 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3634
3635 /* W: wait for results, with timeout */
3636 #define W                                       \
3637 do {                                            \
3638     timeout = vat_time_now (vam) + 1.0;         \
3639                                                 \
3640     while (vat_time_now (vam) < timeout) {      \
3641         if (vam->result_ready == 1) {           \
3642             return (vam->retval);               \
3643         }                                       \
3644     }                                           \
3645     return -99;                                 \
3646 } while(0);
3647
3648 /* W2: wait for results, with timeout */
3649 #define W2(body)                                \
3650 do {                                            \
3651     timeout = vat_time_now (vam) + 1.0;         \
3652                                                 \
3653     while (vat_time_now (vam) < timeout) {      \
3654         if (vam->result_ready == 1) {           \
3655           (body);                               \
3656           return (vam->retval);                 \
3657         }                                       \
3658     }                                           \
3659     return -99;                                 \
3660 } while(0);
3661
3662 /* W_L: wait for results, with timeout */
3663 #define W_L(body)                               \
3664 do {                                            \
3665     timeout = vat_time_now (vam) + 1.0;         \
3666                                                 \
3667     while (vat_time_now (vam) < timeout) {      \
3668         if (vam->result_ready == 1) {           \
3669           (body);                               \
3670           return (vam->retval);                 \
3671         }                                       \
3672     }                                           \
3673     vam->noprint_msg = 0;     \
3674     return -99;                                 \
3675 } while(0);
3676
3677 typedef struct
3678 {
3679   u8 *name;
3680   u32 value;
3681 } name_sort_t;
3682
3683
3684 #define STR_VTR_OP_CASE(op)     \
3685     case L2_VTR_ ## op:         \
3686         return "" # op;
3687
3688 static const char *
3689 str_vtr_op (u32 vtr_op)
3690 {
3691   switch (vtr_op)
3692     {
3693       STR_VTR_OP_CASE (DISABLED);
3694       STR_VTR_OP_CASE (PUSH_1);
3695       STR_VTR_OP_CASE (PUSH_2);
3696       STR_VTR_OP_CASE (POP_1);
3697       STR_VTR_OP_CASE (POP_2);
3698       STR_VTR_OP_CASE (TRANSLATE_1_1);
3699       STR_VTR_OP_CASE (TRANSLATE_1_2);
3700       STR_VTR_OP_CASE (TRANSLATE_2_1);
3701       STR_VTR_OP_CASE (TRANSLATE_2_2);
3702     }
3703
3704   return "UNKNOWN";
3705 }
3706
3707 static int
3708 dump_sub_interface_table (vat_main_t * vam)
3709 {
3710   const sw_interface_subif_t *sub = NULL;
3711
3712   if (vam->json_output)
3713     {
3714       clib_warning
3715         ("JSON output supported only for VPE API calls and dump_stats_table");
3716       return -99;
3717     }
3718
3719   fformat (vam->ofp,
3720            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3721            "Interface", "sw_if_index",
3722            "sub id", "dot1ad", "tags", "outer id",
3723            "inner id", "exact", "default", "outer any", "inner any");
3724
3725   vec_foreach (sub, vam->sw_if_subif_table)
3726   {
3727     fformat (vam->ofp,
3728              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3729              sub->interface_name,
3730              sub->sw_if_index,
3731              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3732              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3733              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3734              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3735     if (sub->vtr_op != L2_VTR_DISABLED)
3736       {
3737         fformat (vam->ofp,
3738                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3739                  "tag1: %d tag2: %d ]\n",
3740                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3741                  sub->vtr_tag1, sub->vtr_tag2);
3742       }
3743   }
3744
3745   return 0;
3746 }
3747
3748 static int
3749 name_sort_cmp (void *a1, void *a2)
3750 {
3751   name_sort_t *n1 = a1;
3752   name_sort_t *n2 = a2;
3753
3754   return strcmp ((char *) n1->name, (char *) n2->name);
3755 }
3756
3757 static int
3758 dump_interface_table (vat_main_t * vam)
3759 {
3760   hash_pair_t *p;
3761   name_sort_t *nses = 0, *ns;
3762
3763   if (vam->json_output)
3764     {
3765       clib_warning
3766         ("JSON output supported only for VPE API calls and dump_stats_table");
3767       return -99;
3768     }
3769
3770   /* *INDENT-OFF* */
3771   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3772   ({
3773     vec_add2 (nses, ns, 1);
3774     ns->name = (u8 *)(p->key);
3775     ns->value = (u32) p->value[0];
3776   }));
3777   /* *INDENT-ON* */
3778
3779   vec_sort_with_function (nses, name_sort_cmp);
3780
3781   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3782   vec_foreach (ns, nses)
3783   {
3784     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3785   }
3786   vec_free (nses);
3787   return 0;
3788 }
3789
3790 static int
3791 dump_ip_table (vat_main_t * vam, int is_ipv6)
3792 {
3793   const ip_details_t *det = NULL;
3794   const ip_address_details_t *address = NULL;
3795   u32 i = ~0;
3796
3797   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3798
3799   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3800   {
3801     i++;
3802     if (!det->present)
3803       {
3804         continue;
3805       }
3806     fformat (vam->ofp, "%-12d\n", i);
3807     fformat (vam->ofp,
3808              "            %-30s%-13s\n", "Address", "Prefix length");
3809     if (!det->addr)
3810       {
3811         continue;
3812       }
3813     vec_foreach (address, det->addr)
3814     {
3815       fformat (vam->ofp,
3816                "            %-30U%-13d\n",
3817                is_ipv6 ? format_ip6_address : format_ip4_address,
3818                address->ip, address->prefix_length);
3819     }
3820   }
3821
3822   return 0;
3823 }
3824
3825 static int
3826 dump_ipv4_table (vat_main_t * vam)
3827 {
3828   if (vam->json_output)
3829     {
3830       clib_warning
3831         ("JSON output supported only for VPE API calls and dump_stats_table");
3832       return -99;
3833     }
3834
3835   return dump_ip_table (vam, 0);
3836 }
3837
3838 static int
3839 dump_ipv6_table (vat_main_t * vam)
3840 {
3841   if (vam->json_output)
3842     {
3843       clib_warning
3844         ("JSON output supported only for VPE API calls and dump_stats_table");
3845       return -99;
3846     }
3847
3848   return dump_ip_table (vam, 1);
3849 }
3850
3851 static char *
3852 counter_type_to_str (u8 counter_type, u8 is_combined)
3853 {
3854   if (!is_combined)
3855     {
3856       switch (counter_type)
3857         {
3858         case VNET_INTERFACE_COUNTER_DROP:
3859           return "drop";
3860         case VNET_INTERFACE_COUNTER_PUNT:
3861           return "punt";
3862         case VNET_INTERFACE_COUNTER_IP4:
3863           return "ip4";
3864         case VNET_INTERFACE_COUNTER_IP6:
3865           return "ip6";
3866         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3867           return "rx-no-buf";
3868         case VNET_INTERFACE_COUNTER_RX_MISS:
3869           return "rx-miss";
3870         case VNET_INTERFACE_COUNTER_RX_ERROR:
3871           return "rx-error";
3872         case VNET_INTERFACE_COUNTER_TX_ERROR:
3873           return "tx-error";
3874         default:
3875           return "INVALID-COUNTER-TYPE";
3876         }
3877     }
3878   else
3879     {
3880       switch (counter_type)
3881         {
3882         case VNET_INTERFACE_COUNTER_RX:
3883           return "rx";
3884         case VNET_INTERFACE_COUNTER_TX:
3885           return "tx";
3886         default:
3887           return "INVALID-COUNTER-TYPE";
3888         }
3889     }
3890 }
3891
3892 static int
3893 dump_stats_table (vat_main_t * vam)
3894 {
3895   vat_json_node_t node;
3896   vat_json_node_t *msg_array;
3897   vat_json_node_t *msg;
3898   vat_json_node_t *counter_array;
3899   vat_json_node_t *counter;
3900   interface_counter_t c;
3901   u64 packets;
3902   ip4_fib_counter_t *c4;
3903   ip6_fib_counter_t *c6;
3904   int i, j;
3905
3906   if (!vam->json_output)
3907     {
3908       clib_warning ("dump_stats_table supported only in JSON format");
3909       return -99;
3910     }
3911
3912   vat_json_init_object (&node);
3913
3914   /* interface counters */
3915   msg_array = vat_json_object_add (&node, "interface_counters");
3916   vat_json_init_array (msg_array);
3917   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3918     {
3919       msg = vat_json_array_add (msg_array);
3920       vat_json_init_object (msg);
3921       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3922                                        (u8 *) counter_type_to_str (i, 0));
3923       vat_json_object_add_int (msg, "is_combined", 0);
3924       counter_array = vat_json_object_add (msg, "data");
3925       vat_json_init_array (counter_array);
3926       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3927         {
3928           packets = vam->simple_interface_counters[i][j];
3929           vat_json_array_add_uint (counter_array, packets);
3930         }
3931     }
3932   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3933     {
3934       msg = vat_json_array_add (msg_array);
3935       vat_json_init_object (msg);
3936       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3937                                        (u8 *) counter_type_to_str (i, 1));
3938       vat_json_object_add_int (msg, "is_combined", 1);
3939       counter_array = vat_json_object_add (msg, "data");
3940       vat_json_init_array (counter_array);
3941       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3942         {
3943           c = vam->combined_interface_counters[i][j];
3944           counter = vat_json_array_add (counter_array);
3945           vat_json_init_object (counter);
3946           vat_json_object_add_uint (counter, "packets", c.packets);
3947           vat_json_object_add_uint (counter, "bytes", c.bytes);
3948         }
3949     }
3950
3951   /* ip4 fib counters */
3952   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3953   vat_json_init_array (msg_array);
3954   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3955     {
3956       msg = vat_json_array_add (msg_array);
3957       vat_json_init_object (msg);
3958       vat_json_object_add_uint (msg, "vrf_id",
3959                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3960       counter_array = vat_json_object_add (msg, "c");
3961       vat_json_init_array (counter_array);
3962       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3963         {
3964           counter = vat_json_array_add (counter_array);
3965           vat_json_init_object (counter);
3966           c4 = &vam->ip4_fib_counters[i][j];
3967           vat_json_object_add_ip4 (counter, "address", c4->address);
3968           vat_json_object_add_uint (counter, "address_length",
3969                                     c4->address_length);
3970           vat_json_object_add_uint (counter, "packets", c4->packets);
3971           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3972         }
3973     }
3974
3975   /* ip6 fib counters */
3976   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3977   vat_json_init_array (msg_array);
3978   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3979     {
3980       msg = vat_json_array_add (msg_array);
3981       vat_json_init_object (msg);
3982       vat_json_object_add_uint (msg, "vrf_id",
3983                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3984       counter_array = vat_json_object_add (msg, "c");
3985       vat_json_init_array (counter_array);
3986       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3987         {
3988           counter = vat_json_array_add (counter_array);
3989           vat_json_init_object (counter);
3990           c6 = &vam->ip6_fib_counters[i][j];
3991           vat_json_object_add_ip6 (counter, "address", c6->address);
3992           vat_json_object_add_uint (counter, "address_length",
3993                                     c6->address_length);
3994           vat_json_object_add_uint (counter, "packets", c6->packets);
3995           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3996         }
3997     }
3998
3999   vat_json_print (vam->ofp, &node);
4000   vat_json_free (&node);
4001
4002   return 0;
4003 }
4004
4005 int
4006 exec (vat_main_t * vam)
4007 {
4008   api_main_t *am = &api_main;
4009   vl_api_cli_request_t *mp;
4010   f64 timeout;
4011   void *oldheap;
4012   u8 *cmd = 0;
4013   unformat_input_t *i = vam->input;
4014
4015   if (vec_len (i->buffer) == 0)
4016     return -1;
4017
4018   if (vam->exec_mode == 0 && unformat (i, "mode"))
4019     {
4020       vam->exec_mode = 1;
4021       return 0;
4022     }
4023   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4024     {
4025       vam->exec_mode = 0;
4026       return 0;
4027     }
4028
4029
4030   M (CLI_REQUEST, cli_request);
4031
4032   /*
4033    * Copy cmd into shared memory.
4034    * In order for the CLI command to work, it
4035    * must be a vector ending in \n, not a C-string ending
4036    * in \n\0.
4037    */
4038   pthread_mutex_lock (&am->vlib_rp->mutex);
4039   oldheap = svm_push_data_heap (am->vlib_rp);
4040
4041   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4042   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4043
4044   svm_pop_heap (oldheap);
4045   pthread_mutex_unlock (&am->vlib_rp->mutex);
4046
4047   mp->cmd_in_shmem = (u64) cmd;
4048   S;
4049   timeout = vat_time_now (vam) + 10.0;
4050
4051   while (vat_time_now (vam) < timeout)
4052     {
4053       if (vam->result_ready == 1)
4054         {
4055           u8 *free_me;
4056           if (vam->shmem_result != NULL)
4057             fformat (vam->ofp, "%s", vam->shmem_result);
4058           pthread_mutex_lock (&am->vlib_rp->mutex);
4059           oldheap = svm_push_data_heap (am->vlib_rp);
4060
4061           free_me = (u8 *) vam->shmem_result;
4062           vec_free (free_me);
4063
4064           svm_pop_heap (oldheap);
4065           pthread_mutex_unlock (&am->vlib_rp->mutex);
4066           return 0;
4067         }
4068     }
4069   return -99;
4070 }
4071
4072 static int
4073 api_create_loopback (vat_main_t * vam)
4074 {
4075   unformat_input_t *i = vam->input;
4076   vl_api_create_loopback_t *mp;
4077   f64 timeout;
4078   u8 mac_address[6];
4079   u8 mac_set = 0;
4080
4081   memset (mac_address, 0, sizeof (mac_address));
4082
4083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4084     {
4085       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4086         mac_set = 1;
4087       else
4088         break;
4089     }
4090
4091   /* Construct the API message */
4092   M (CREATE_LOOPBACK, create_loopback);
4093   if (mac_set)
4094     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4095
4096   S;
4097   W;
4098 }
4099
4100 static int
4101 api_delete_loopback (vat_main_t * vam)
4102 {
4103   unformat_input_t *i = vam->input;
4104   vl_api_delete_loopback_t *mp;
4105   f64 timeout;
4106   u32 sw_if_index = ~0;
4107
4108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4109     {
4110       if (unformat (i, "sw_if_index %d", &sw_if_index))
4111         ;
4112       else
4113         break;
4114     }
4115
4116   if (sw_if_index == ~0)
4117     {
4118       errmsg ("missing sw_if_index\n");
4119       return -99;
4120     }
4121
4122   /* Construct the API message */
4123   M (DELETE_LOOPBACK, delete_loopback);
4124   mp->sw_if_index = ntohl (sw_if_index);
4125
4126   S;
4127   W;
4128 }
4129
4130 static int
4131 api_want_stats (vat_main_t * vam)
4132 {
4133   unformat_input_t *i = vam->input;
4134   vl_api_want_stats_t *mp;
4135   f64 timeout;
4136   int enable = -1;
4137
4138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4139     {
4140       if (unformat (i, "enable"))
4141         enable = 1;
4142       else if (unformat (i, "disable"))
4143         enable = 0;
4144       else
4145         break;
4146     }
4147
4148   if (enable == -1)
4149     {
4150       errmsg ("missing enable|disable\n");
4151       return -99;
4152     }
4153
4154   M (WANT_STATS, want_stats);
4155   mp->enable_disable = enable;
4156
4157   S;
4158   W;
4159 }
4160
4161 static int
4162 api_want_interface_events (vat_main_t * vam)
4163 {
4164   unformat_input_t *i = vam->input;
4165   vl_api_want_interface_events_t *mp;
4166   f64 timeout;
4167   int enable = -1;
4168
4169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4170     {
4171       if (unformat (i, "enable"))
4172         enable = 1;
4173       else if (unformat (i, "disable"))
4174         enable = 0;
4175       else
4176         break;
4177     }
4178
4179   if (enable == -1)
4180     {
4181       errmsg ("missing enable|disable\n");
4182       return -99;
4183     }
4184
4185   M (WANT_INTERFACE_EVENTS, want_interface_events);
4186   mp->enable_disable = enable;
4187
4188   vam->interface_event_display = enable;
4189
4190   S;
4191   W;
4192 }
4193
4194
4195 /* Note: non-static, called once to set up the initial intfc table */
4196 int
4197 api_sw_interface_dump (vat_main_t * vam)
4198 {
4199   vl_api_sw_interface_dump_t *mp;
4200   f64 timeout;
4201   hash_pair_t *p;
4202   name_sort_t *nses = 0, *ns;
4203   sw_interface_subif_t *sub = NULL;
4204
4205   /* Toss the old name table */
4206   /* *INDENT-OFF* */
4207   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4208   ({
4209     vec_add2 (nses, ns, 1);
4210     ns->name = (u8 *)(p->key);
4211     ns->value = (u32) p->value[0];
4212   }));
4213   /* *INDENT-ON* */
4214
4215   hash_free (vam->sw_if_index_by_interface_name);
4216
4217   vec_foreach (ns, nses) vec_free (ns->name);
4218
4219   vec_free (nses);
4220
4221   vec_foreach (sub, vam->sw_if_subif_table)
4222   {
4223     vec_free (sub->interface_name);
4224   }
4225   vec_free (vam->sw_if_subif_table);
4226
4227   /* recreate the interface name hash table */
4228   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4229
4230   /* Get list of ethernets */
4231   M (SW_INTERFACE_DUMP, sw_interface_dump);
4232   mp->name_filter_valid = 1;
4233   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4234   S;
4235
4236   /* and local / loopback interfaces */
4237   M (SW_INTERFACE_DUMP, sw_interface_dump);
4238   mp->name_filter_valid = 1;
4239   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4240   S;
4241
4242
4243   /* and vxlan-gpe tunnel interfaces */
4244   M (SW_INTERFACE_DUMP, sw_interface_dump);
4245   mp->name_filter_valid = 1;
4246   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4247            sizeof (mp->name_filter) - 1);
4248   S;
4249
4250   /* and vxlan tunnel interfaces */
4251   M (SW_INTERFACE_DUMP, sw_interface_dump);
4252   mp->name_filter_valid = 1;
4253   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4254   S;
4255
4256   /* and host (af_packet) interfaces */
4257   M (SW_INTERFACE_DUMP, sw_interface_dump);
4258   mp->name_filter_valid = 1;
4259   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4260   S;
4261
4262   /* and l2tpv3 tunnel interfaces */
4263   M (SW_INTERFACE_DUMP, sw_interface_dump);
4264   mp->name_filter_valid = 1;
4265   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4266            sizeof (mp->name_filter) - 1);
4267   S;
4268
4269   /* and GRE tunnel interfaces */
4270   M (SW_INTERFACE_DUMP, sw_interface_dump);
4271   mp->name_filter_valid = 1;
4272   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4273   S;
4274
4275   /* Use a control ping for synchronization */
4276   {
4277     vl_api_control_ping_t *mp;
4278     M (CONTROL_PING, control_ping);
4279     S;
4280   }
4281   W;
4282 }
4283
4284 static int
4285 api_sw_interface_set_flags (vat_main_t * vam)
4286 {
4287   unformat_input_t *i = vam->input;
4288   vl_api_sw_interface_set_flags_t *mp;
4289   f64 timeout;
4290   u32 sw_if_index;
4291   u8 sw_if_index_set = 0;
4292   u8 admin_up = 0, link_up = 0;
4293
4294   /* Parse args required to build the message */
4295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4296     {
4297       if (unformat (i, "admin-up"))
4298         admin_up = 1;
4299       else if (unformat (i, "admin-down"))
4300         admin_up = 0;
4301       else if (unformat (i, "link-up"))
4302         link_up = 1;
4303       else if (unformat (i, "link-down"))
4304         link_up = 0;
4305       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4306         sw_if_index_set = 1;
4307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4308         sw_if_index_set = 1;
4309       else
4310         break;
4311     }
4312
4313   if (sw_if_index_set == 0)
4314     {
4315       errmsg ("missing interface name or sw_if_index\n");
4316       return -99;
4317     }
4318
4319   /* Construct the API message */
4320   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4321   mp->sw_if_index = ntohl (sw_if_index);
4322   mp->admin_up_down = admin_up;
4323   mp->link_up_down = link_up;
4324
4325   /* send it... */
4326   S;
4327
4328   /* Wait for a reply, return the good/bad news... */
4329   W;
4330 }
4331
4332 static int
4333 api_sw_interface_clear_stats (vat_main_t * vam)
4334 {
4335   unformat_input_t *i = vam->input;
4336   vl_api_sw_interface_clear_stats_t *mp;
4337   f64 timeout;
4338   u32 sw_if_index;
4339   u8 sw_if_index_set = 0;
4340
4341   /* Parse args required to build the message */
4342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4343     {
4344       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4345         sw_if_index_set = 1;
4346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4347         sw_if_index_set = 1;
4348       else
4349         break;
4350     }
4351
4352   /* Construct the API message */
4353   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4354
4355   if (sw_if_index_set == 1)
4356     mp->sw_if_index = ntohl (sw_if_index);
4357   else
4358     mp->sw_if_index = ~0;
4359
4360   /* send it... */
4361   S;
4362
4363   /* Wait for a reply, return the good/bad news... */
4364   W;
4365 }
4366
4367 static int
4368 api_sw_interface_add_del_address (vat_main_t * vam)
4369 {
4370   unformat_input_t *i = vam->input;
4371   vl_api_sw_interface_add_del_address_t *mp;
4372   f64 timeout;
4373   u32 sw_if_index;
4374   u8 sw_if_index_set = 0;
4375   u8 is_add = 1, del_all = 0;
4376   u32 address_length = 0;
4377   u8 v4_address_set = 0;
4378   u8 v6_address_set = 0;
4379   ip4_address_t v4address;
4380   ip6_address_t v6address;
4381
4382   /* Parse args required to build the message */
4383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4384     {
4385       if (unformat (i, "del-all"))
4386         del_all = 1;
4387       else if (unformat (i, "del"))
4388         is_add = 0;
4389       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4390         sw_if_index_set = 1;
4391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4392         sw_if_index_set = 1;
4393       else if (unformat (i, "%U/%d",
4394                          unformat_ip4_address, &v4address, &address_length))
4395         v4_address_set = 1;
4396       else if (unformat (i, "%U/%d",
4397                          unformat_ip6_address, &v6address, &address_length))
4398         v6_address_set = 1;
4399       else
4400         break;
4401     }
4402
4403   if (sw_if_index_set == 0)
4404     {
4405       errmsg ("missing interface name or sw_if_index\n");
4406       return -99;
4407     }
4408   if (v4_address_set && v6_address_set)
4409     {
4410       errmsg ("both v4 and v6 addresses set\n");
4411       return -99;
4412     }
4413   if (!v4_address_set && !v6_address_set && !del_all)
4414     {
4415       errmsg ("no addresses set\n");
4416       return -99;
4417     }
4418
4419   /* Construct the API message */
4420   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4421
4422   mp->sw_if_index = ntohl (sw_if_index);
4423   mp->is_add = is_add;
4424   mp->del_all = del_all;
4425   if (v6_address_set)
4426     {
4427       mp->is_ipv6 = 1;
4428       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4429     }
4430   else
4431     {
4432       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4433     }
4434   mp->address_length = address_length;
4435
4436   /* send it... */
4437   S;
4438
4439   /* Wait for a reply, return good/bad news  */
4440   W;
4441 }
4442
4443 static int
4444 api_sw_interface_set_table (vat_main_t * vam)
4445 {
4446   unformat_input_t *i = vam->input;
4447   vl_api_sw_interface_set_table_t *mp;
4448   f64 timeout;
4449   u32 sw_if_index, vrf_id = 0;
4450   u8 sw_if_index_set = 0;
4451   u8 is_ipv6 = 0;
4452
4453   /* Parse args required to build the message */
4454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4455     {
4456       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4457         sw_if_index_set = 1;
4458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4459         sw_if_index_set = 1;
4460       else if (unformat (i, "vrf %d", &vrf_id))
4461         ;
4462       else if (unformat (i, "ipv6"))
4463         is_ipv6 = 1;
4464       else
4465         break;
4466     }
4467
4468   if (sw_if_index_set == 0)
4469     {
4470       errmsg ("missing interface name or sw_if_index\n");
4471       return -99;
4472     }
4473
4474   /* Construct the API message */
4475   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4476
4477   mp->sw_if_index = ntohl (sw_if_index);
4478   mp->is_ipv6 = is_ipv6;
4479   mp->vrf_id = ntohl (vrf_id);
4480
4481   /* send it... */
4482   S;
4483
4484   /* Wait for a reply... */
4485   W;
4486 }
4487
4488 static int
4489 api_sw_interface_set_vpath (vat_main_t * vam)
4490 {
4491   unformat_input_t *i = vam->input;
4492   vl_api_sw_interface_set_vpath_t *mp;
4493   f64 timeout;
4494   u32 sw_if_index = 0;
4495   u8 sw_if_index_set = 0;
4496   u8 is_enable = 0;
4497
4498   /* Parse args required to build the message */
4499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4500     {
4501       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4502         sw_if_index_set = 1;
4503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4504         sw_if_index_set = 1;
4505       else if (unformat (i, "enable"))
4506         is_enable = 1;
4507       else if (unformat (i, "disable"))
4508         is_enable = 0;
4509       else
4510         break;
4511     }
4512
4513   if (sw_if_index_set == 0)
4514     {
4515       errmsg ("missing interface name or sw_if_index\n");
4516       return -99;
4517     }
4518
4519   /* Construct the API message */
4520   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4521
4522   mp->sw_if_index = ntohl (sw_if_index);
4523   mp->enable = is_enable;
4524
4525   /* send it... */
4526   S;
4527
4528   /* Wait for a reply... */
4529   W;
4530 }
4531
4532 static int
4533 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4534 {
4535   unformat_input_t *i = vam->input;
4536   vl_api_sw_interface_set_l2_xconnect_t *mp;
4537   f64 timeout;
4538   u32 rx_sw_if_index;
4539   u8 rx_sw_if_index_set = 0;
4540   u32 tx_sw_if_index;
4541   u8 tx_sw_if_index_set = 0;
4542   u8 enable = 1;
4543
4544   /* Parse args required to build the message */
4545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4546     {
4547       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4548         rx_sw_if_index_set = 1;
4549       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4550         tx_sw_if_index_set = 1;
4551       else if (unformat (i, "rx"))
4552         {
4553           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4554             {
4555               if (unformat (i, "%U", unformat_sw_if_index, vam,
4556                             &rx_sw_if_index))
4557                 rx_sw_if_index_set = 1;
4558             }
4559           else
4560             break;
4561         }
4562       else if (unformat (i, "tx"))
4563         {
4564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4565             {
4566               if (unformat (i, "%U", unformat_sw_if_index, vam,
4567                             &tx_sw_if_index))
4568                 tx_sw_if_index_set = 1;
4569             }
4570           else
4571             break;
4572         }
4573       else if (unformat (i, "enable"))
4574         enable = 1;
4575       else if (unformat (i, "disable"))
4576         enable = 0;
4577       else
4578         break;
4579     }
4580
4581   if (rx_sw_if_index_set == 0)
4582     {
4583       errmsg ("missing rx interface name or rx_sw_if_index\n");
4584       return -99;
4585     }
4586
4587   if (enable && (tx_sw_if_index_set == 0))
4588     {
4589       errmsg ("missing tx interface name or tx_sw_if_index\n");
4590       return -99;
4591     }
4592
4593   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4594
4595   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4596   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4597   mp->enable = enable;
4598
4599   S;
4600   W;
4601   /* NOTREACHED */
4602   return 0;
4603 }
4604
4605 static int
4606 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4607 {
4608   unformat_input_t *i = vam->input;
4609   vl_api_sw_interface_set_l2_bridge_t *mp;
4610   f64 timeout;
4611   u32 rx_sw_if_index;
4612   u8 rx_sw_if_index_set = 0;
4613   u32 bd_id;
4614   u8 bd_id_set = 0;
4615   u8 bvi = 0;
4616   u32 shg = 0;
4617   u8 enable = 1;
4618
4619   /* Parse args required to build the message */
4620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4621     {
4622       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4623         rx_sw_if_index_set = 1;
4624       else if (unformat (i, "bd_id %d", &bd_id))
4625         bd_id_set = 1;
4626       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4627         rx_sw_if_index_set = 1;
4628       else if (unformat (i, "shg %d", &shg))
4629         ;
4630       else if (unformat (i, "bvi"))
4631         bvi = 1;
4632       else if (unformat (i, "enable"))
4633         enable = 1;
4634       else if (unformat (i, "disable"))
4635         enable = 0;
4636       else
4637         break;
4638     }
4639
4640   if (rx_sw_if_index_set == 0)
4641     {
4642       errmsg ("missing rx interface name or sw_if_index\n");
4643       return -99;
4644     }
4645
4646   if (enable && (bd_id_set == 0))
4647     {
4648       errmsg ("missing bridge domain\n");
4649       return -99;
4650     }
4651
4652   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4653
4654   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4655   mp->bd_id = ntohl (bd_id);
4656   mp->shg = (u8) shg;
4657   mp->bvi = bvi;
4658   mp->enable = enable;
4659
4660   S;
4661   W;
4662   /* NOTREACHED */
4663   return 0;
4664 }
4665
4666 static int
4667 api_bridge_domain_dump (vat_main_t * vam)
4668 {
4669   unformat_input_t *i = vam->input;
4670   vl_api_bridge_domain_dump_t *mp;
4671   f64 timeout;
4672   u32 bd_id = ~0;
4673
4674   /* Parse args required to build the message */
4675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4676     {
4677       if (unformat (i, "bd_id %d", &bd_id))
4678         ;
4679       else
4680         break;
4681     }
4682
4683   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4684   mp->bd_id = ntohl (bd_id);
4685   S;
4686
4687   /* Use a control ping for synchronization */
4688   {
4689     vl_api_control_ping_t *mp;
4690     M (CONTROL_PING, control_ping);
4691     S;
4692   }
4693
4694   W;
4695   /* NOTREACHED */
4696   return 0;
4697 }
4698
4699 static int
4700 api_bridge_domain_add_del (vat_main_t * vam)
4701 {
4702   unformat_input_t *i = vam->input;
4703   vl_api_bridge_domain_add_del_t *mp;
4704   f64 timeout;
4705   u32 bd_id = ~0;
4706   u8 is_add = 1;
4707   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4708
4709   /* Parse args required to build the message */
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "bd_id %d", &bd_id))
4713         ;
4714       else if (unformat (i, "flood %d", &flood))
4715         ;
4716       else if (unformat (i, "uu-flood %d", &uu_flood))
4717         ;
4718       else if (unformat (i, "forward %d", &forward))
4719         ;
4720       else if (unformat (i, "learn %d", &learn))
4721         ;
4722       else if (unformat (i, "arp-term %d", &arp_term))
4723         ;
4724       else if (unformat (i, "del"))
4725         {
4726           is_add = 0;
4727           flood = uu_flood = forward = learn = 0;
4728         }
4729       else
4730         break;
4731     }
4732
4733   if (bd_id == ~0)
4734     {
4735       errmsg ("missing bridge domain\n");
4736       return -99;
4737     }
4738
4739   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4740
4741   mp->bd_id = ntohl (bd_id);
4742   mp->flood = flood;
4743   mp->uu_flood = uu_flood;
4744   mp->forward = forward;
4745   mp->learn = learn;
4746   mp->arp_term = arp_term;
4747   mp->is_add = is_add;
4748
4749   S;
4750   W;
4751   /* NOTREACHED */
4752   return 0;
4753 }
4754
4755 static int
4756 api_l2fib_add_del (vat_main_t * vam)
4757 {
4758   unformat_input_t *i = vam->input;
4759   vl_api_l2fib_add_del_t *mp;
4760   f64 timeout;
4761   u64 mac = 0;
4762   u8 mac_set = 0;
4763   u32 bd_id;
4764   u8 bd_id_set = 0;
4765   u32 sw_if_index;
4766   u8 sw_if_index_set = 0;
4767   u8 is_add = 1;
4768   u8 static_mac = 0;
4769   u8 filter_mac = 0;
4770   u8 bvi_mac = 0;
4771   int count = 1;
4772   f64 before = 0;
4773   int j;
4774
4775   /* Parse args required to build the message */
4776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4777     {
4778       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4779         mac_set = 1;
4780       else if (unformat (i, "bd_id %d", &bd_id))
4781         bd_id_set = 1;
4782       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "sw_if"))
4785         {
4786           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787             {
4788               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4789                 sw_if_index_set = 1;
4790             }
4791           else
4792             break;
4793         }
4794       else if (unformat (i, "static"))
4795         static_mac = 1;
4796       else if (unformat (i, "filter"))
4797         {
4798           filter_mac = 1;
4799           static_mac = 1;
4800         }
4801       else if (unformat (i, "bvi"))
4802         {
4803           bvi_mac = 1;
4804           static_mac = 1;
4805         }
4806       else if (unformat (i, "del"))
4807         is_add = 0;
4808       else if (unformat (i, "count %d", &count))
4809         ;
4810       else
4811         break;
4812     }
4813
4814   if (mac_set == 0)
4815     {
4816       errmsg ("missing mac address\n");
4817       return -99;
4818     }
4819
4820   if (bd_id_set == 0)
4821     {
4822       errmsg ("missing bridge domain\n");
4823       return -99;
4824     }
4825
4826   if (is_add && (sw_if_index_set == 0))
4827     {
4828       errmsg ("missing interface name or sw_if_index\n");
4829       return -99;
4830     }
4831
4832   if (count > 1)
4833     {
4834       /* Turn on async mode */
4835       vam->async_mode = 1;
4836       vam->async_errors = 0;
4837       before = vat_time_now (vam);
4838     }
4839
4840   for (j = 0; j < count; j++)
4841     {
4842       M (L2FIB_ADD_DEL, l2fib_add_del);
4843
4844       mp->mac = mac;
4845       mp->bd_id = ntohl (bd_id);
4846       mp->is_add = is_add;
4847
4848       if (is_add)
4849         {
4850           mp->sw_if_index = ntohl (sw_if_index);
4851           mp->static_mac = static_mac;
4852           mp->filter_mac = filter_mac;
4853           mp->bvi_mac = bvi_mac;
4854         }
4855       increment_mac_address (&mac);
4856       /* send it... */
4857       S;
4858     }
4859
4860   if (count > 1)
4861     {
4862       vl_api_control_ping_t *mp;
4863       f64 after;
4864
4865       /* Shut off async mode */
4866       vam->async_mode = 0;
4867
4868       M (CONTROL_PING, control_ping);
4869       S;
4870
4871       timeout = vat_time_now (vam) + 1.0;
4872       while (vat_time_now (vam) < timeout)
4873         if (vam->result_ready == 1)
4874           goto out;
4875       vam->retval = -99;
4876
4877     out:
4878       if (vam->retval == -99)
4879         errmsg ("timeout\n");
4880
4881       if (vam->async_errors > 0)
4882         {
4883           errmsg ("%d asynchronous errors\n", vam->async_errors);
4884           vam->retval = -98;
4885         }
4886       vam->async_errors = 0;
4887       after = vat_time_now (vam);
4888
4889       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4890                count, after - before, count / (after - before));
4891     }
4892   else
4893     {
4894       /* Wait for a reply... */
4895       W;
4896     }
4897   /* Return the good/bad news */
4898   return (vam->retval);
4899 }
4900
4901 static int
4902 api_l2_flags (vat_main_t * vam)
4903 {
4904   unformat_input_t *i = vam->input;
4905   vl_api_l2_flags_t *mp;
4906   f64 timeout;
4907   u32 sw_if_index;
4908   u32 feature_bitmap = 0;
4909   u8 sw_if_index_set = 0;
4910
4911   /* Parse args required to build the message */
4912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4913     {
4914       if (unformat (i, "sw_if_index %d", &sw_if_index))
4915         sw_if_index_set = 1;
4916       else if (unformat (i, "sw_if"))
4917         {
4918           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4919             {
4920               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4921                 sw_if_index_set = 1;
4922             }
4923           else
4924             break;
4925         }
4926       else if (unformat (i, "learn"))
4927         feature_bitmap |= L2INPUT_FEAT_LEARN;
4928       else if (unformat (i, "forward"))
4929         feature_bitmap |= L2INPUT_FEAT_FWD;
4930       else if (unformat (i, "flood"))
4931         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4932       else if (unformat (i, "uu-flood"))
4933         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4934       else
4935         break;
4936     }
4937
4938   if (sw_if_index_set == 0)
4939     {
4940       errmsg ("missing interface name or sw_if_index\n");
4941       return -99;
4942     }
4943
4944   M (L2_FLAGS, l2_flags);
4945
4946   mp->sw_if_index = ntohl (sw_if_index);
4947   mp->feature_bitmap = ntohl (feature_bitmap);
4948
4949   S;
4950   W;
4951   /* NOTREACHED */
4952   return 0;
4953 }
4954
4955 static int
4956 api_bridge_flags (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_bridge_flags_t *mp;
4960   f64 timeout;
4961   u32 bd_id;
4962   u8 bd_id_set = 0;
4963   u8 is_set = 1;
4964   u32 flags = 0;
4965
4966   /* Parse args required to build the message */
4967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4968     {
4969       if (unformat (i, "bd_id %d", &bd_id))
4970         bd_id_set = 1;
4971       else if (unformat (i, "learn"))
4972         flags |= L2_LEARN;
4973       else if (unformat (i, "forward"))
4974         flags |= L2_FWD;
4975       else if (unformat (i, "flood"))
4976         flags |= L2_FLOOD;
4977       else if (unformat (i, "uu-flood"))
4978         flags |= L2_UU_FLOOD;
4979       else if (unformat (i, "arp-term"))
4980         flags |= L2_ARP_TERM;
4981       else if (unformat (i, "off"))
4982         is_set = 0;
4983       else if (unformat (i, "disable"))
4984         is_set = 0;
4985       else
4986         break;
4987     }
4988
4989   if (bd_id_set == 0)
4990     {
4991       errmsg ("missing bridge domain\n");
4992       return -99;
4993     }
4994
4995   M (BRIDGE_FLAGS, bridge_flags);
4996
4997   mp->bd_id = ntohl (bd_id);
4998   mp->feature_bitmap = ntohl (flags);
4999   mp->is_set = is_set;
5000
5001   S;
5002   W;
5003   /* NOTREACHED */
5004   return 0;
5005 }
5006
5007 static int
5008 api_bd_ip_mac_add_del (vat_main_t * vam)
5009 {
5010   unformat_input_t *i = vam->input;
5011   vl_api_bd_ip_mac_add_del_t *mp;
5012   f64 timeout;
5013   u32 bd_id;
5014   u8 is_ipv6 = 0;
5015   u8 is_add = 1;
5016   u8 bd_id_set = 0;
5017   u8 ip_set = 0;
5018   u8 mac_set = 0;
5019   ip4_address_t v4addr;
5020   ip6_address_t v6addr;
5021   u8 macaddr[6];
5022
5023
5024   /* Parse args required to build the message */
5025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5026     {
5027       if (unformat (i, "bd_id %d", &bd_id))
5028         {
5029           bd_id_set++;
5030         }
5031       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5032         {
5033           ip_set++;
5034         }
5035       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5036         {
5037           ip_set++;
5038           is_ipv6++;
5039         }
5040       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5041         {
5042           mac_set++;
5043         }
5044       else if (unformat (i, "del"))
5045         is_add = 0;
5046       else
5047         break;
5048     }
5049
5050   if (bd_id_set == 0)
5051     {
5052       errmsg ("missing bridge domain\n");
5053       return -99;
5054     }
5055   else if (ip_set == 0)
5056     {
5057       errmsg ("missing IP address\n");
5058       return -99;
5059     }
5060   else if (mac_set == 0)
5061     {
5062       errmsg ("missing MAC address\n");
5063       return -99;
5064     }
5065
5066   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5067
5068   mp->bd_id = ntohl (bd_id);
5069   mp->is_ipv6 = is_ipv6;
5070   mp->is_add = is_add;
5071   if (is_ipv6)
5072     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5073   else
5074     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5075   clib_memcpy (mp->mac_address, macaddr, 6);
5076   S;
5077   W;
5078   /* NOTREACHED */
5079   return 0;
5080 }
5081
5082 static int
5083 api_tap_connect (vat_main_t * vam)
5084 {
5085   unformat_input_t *i = vam->input;
5086   vl_api_tap_connect_t *mp;
5087   f64 timeout;
5088   u8 mac_address[6];
5089   u8 random_mac = 1;
5090   u8 name_set = 0;
5091   u8 *tap_name;
5092
5093   memset (mac_address, 0, sizeof (mac_address));
5094
5095   /* Parse args required to build the message */
5096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5097     {
5098       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5099         {
5100           random_mac = 0;
5101         }
5102       else if (unformat (i, "random-mac"))
5103         random_mac = 1;
5104       else if (unformat (i, "tapname %s", &tap_name))
5105         name_set = 1;
5106       else
5107         break;
5108     }
5109
5110   if (name_set == 0)
5111     {
5112       errmsg ("missing tap name\n");
5113       return -99;
5114     }
5115   if (vec_len (tap_name) > 63)
5116     {
5117       errmsg ("tap name too long\n");
5118     }
5119   vec_add1 (tap_name, 0);
5120
5121   /* Construct the API message */
5122   M (TAP_CONNECT, tap_connect);
5123
5124   mp->use_random_mac = random_mac;
5125   clib_memcpy (mp->mac_address, mac_address, 6);
5126   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5127   vec_free (tap_name);
5128
5129   /* send it... */
5130   S;
5131
5132   /* Wait for a reply... */
5133   W;
5134 }
5135
5136 static int
5137 api_tap_modify (vat_main_t * vam)
5138 {
5139   unformat_input_t *i = vam->input;
5140   vl_api_tap_modify_t *mp;
5141   f64 timeout;
5142   u8 mac_address[6];
5143   u8 random_mac = 1;
5144   u8 name_set = 0;
5145   u8 *tap_name;
5146   u32 sw_if_index = ~0;
5147   u8 sw_if_index_set = 0;
5148
5149   memset (mac_address, 0, sizeof (mac_address));
5150
5151   /* Parse args required to build the message */
5152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5153     {
5154       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5155         sw_if_index_set = 1;
5156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5157         sw_if_index_set = 1;
5158       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5159         {
5160           random_mac = 0;
5161         }
5162       else if (unformat (i, "random-mac"))
5163         random_mac = 1;
5164       else if (unformat (i, "tapname %s", &tap_name))
5165         name_set = 1;
5166       else
5167         break;
5168     }
5169
5170   if (sw_if_index_set == 0)
5171     {
5172       errmsg ("missing vpp interface name");
5173       return -99;
5174     }
5175   if (name_set == 0)
5176     {
5177       errmsg ("missing tap name\n");
5178       return -99;
5179     }
5180   if (vec_len (tap_name) > 63)
5181     {
5182       errmsg ("tap name too long\n");
5183     }
5184   vec_add1 (tap_name, 0);
5185
5186   /* Construct the API message */
5187   M (TAP_MODIFY, tap_modify);
5188
5189   mp->use_random_mac = random_mac;
5190   mp->sw_if_index = ntohl (sw_if_index);
5191   clib_memcpy (mp->mac_address, mac_address, 6);
5192   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5193   vec_free (tap_name);
5194
5195   /* send it... */
5196   S;
5197
5198   /* Wait for a reply... */
5199   W;
5200 }
5201
5202 static int
5203 api_tap_delete (vat_main_t * vam)
5204 {
5205   unformat_input_t *i = vam->input;
5206   vl_api_tap_delete_t *mp;
5207   f64 timeout;
5208   u32 sw_if_index = ~0;
5209   u8 sw_if_index_set = 0;
5210
5211   /* Parse args required to build the message */
5212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5213     {
5214       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5215         sw_if_index_set = 1;
5216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5217         sw_if_index_set = 1;
5218       else
5219         break;
5220     }
5221
5222   if (sw_if_index_set == 0)
5223     {
5224       errmsg ("missing vpp interface name");
5225       return -99;
5226     }
5227
5228   /* Construct the API message */
5229   M (TAP_DELETE, tap_delete);
5230
5231   mp->sw_if_index = ntohl (sw_if_index);
5232
5233   /* send it... */
5234   S;
5235
5236   /* Wait for a reply... */
5237   W;
5238 }
5239
5240 static int
5241 api_ip_add_del_route (vat_main_t * vam)
5242 {
5243   unformat_input_t *i = vam->input;
5244   vl_api_ip_add_del_route_t *mp;
5245   f64 timeout;
5246   u32 sw_if_index = ~0, vrf_id = 0;
5247   u8 sw_if_index_set = 0;
5248   u8 is_ipv6 = 0;
5249   u8 is_local = 0, is_drop = 0;
5250   u8 create_vrf_if_needed = 0;
5251   u8 is_add = 1;
5252   u8 next_hop_weight = 1;
5253   u8 not_last = 0;
5254   u8 is_multipath = 0;
5255   u8 address_set = 0;
5256   u8 address_length_set = 0;
5257   u32 lookup_in_vrf = 0;
5258   u32 resolve_attempts = 0;
5259   u32 dst_address_length = 0;
5260   u8 next_hop_set = 0;
5261   ip4_address_t v4_dst_address, v4_next_hop_address;
5262   ip6_address_t v6_dst_address, v6_next_hop_address;
5263   int count = 1;
5264   int j;
5265   f64 before = 0;
5266   u32 random_add_del = 0;
5267   u32 *random_vector = 0;
5268   uword *random_hash;
5269   u32 random_seed = 0xdeaddabe;
5270   u32 classify_table_index = ~0;
5271   u8 is_classify = 0;
5272
5273   /* Parse args required to build the message */
5274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275     {
5276       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5277         sw_if_index_set = 1;
5278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5279         sw_if_index_set = 1;
5280       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5281         {
5282           address_set = 1;
5283           is_ipv6 = 0;
5284         }
5285       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5286         {
5287           address_set = 1;
5288           is_ipv6 = 1;
5289         }
5290       else if (unformat (i, "/%d", &dst_address_length))
5291         {
5292           address_length_set = 1;
5293         }
5294
5295       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5296                                          &v4_next_hop_address))
5297         {
5298           next_hop_set = 1;
5299         }
5300       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5301                                          &v6_next_hop_address))
5302         {
5303           next_hop_set = 1;
5304         }
5305       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5306         ;
5307       else if (unformat (i, "weight %d", &next_hop_weight))
5308         ;
5309       else if (unformat (i, "drop"))
5310         {
5311           is_drop = 1;
5312         }
5313       else if (unformat (i, "local"))
5314         {
5315           is_local = 1;
5316         }
5317       else if (unformat (i, "classify %d", &classify_table_index))
5318         {
5319           is_classify = 1;
5320         }
5321       else if (unformat (i, "del"))
5322         is_add = 0;
5323       else if (unformat (i, "add"))
5324         is_add = 1;
5325       else if (unformat (i, "not-last"))
5326         not_last = 1;
5327       else if (unformat (i, "multipath"))
5328         is_multipath = 1;
5329       else if (unformat (i, "vrf %d", &vrf_id))
5330         ;
5331       else if (unformat (i, "create-vrf"))
5332         create_vrf_if_needed = 1;
5333       else if (unformat (i, "count %d", &count))
5334         ;
5335       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5336         ;
5337       else if (unformat (i, "random"))
5338         random_add_del = 1;
5339       else if (unformat (i, "seed %d", &random_seed))
5340         ;
5341       else
5342         {
5343           clib_warning ("parse error '%U'", format_unformat_error, i);
5344           return -99;
5345         }
5346     }
5347
5348   if (resolve_attempts > 0 && sw_if_index_set == 0)
5349     {
5350       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5351       return -99;
5352     }
5353
5354   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5355     {
5356       errmsg ("next hop / local / drop / classify not set\n");
5357       return -99;
5358     }
5359
5360   if (address_set == 0)
5361     {
5362       errmsg ("missing addresses\n");
5363       return -99;
5364     }
5365
5366   if (address_length_set == 0)
5367     {
5368       errmsg ("missing address length\n");
5369       return -99;
5370     }
5371
5372   /* Generate a pile of unique, random routes */
5373   if (random_add_del)
5374     {
5375       u32 this_random_address;
5376       random_hash = hash_create (count, sizeof (uword));
5377
5378       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5379       for (j = 0; j <= count; j++)
5380         {
5381           do
5382             {
5383               this_random_address = random_u32 (&random_seed);
5384               this_random_address =
5385                 clib_host_to_net_u32 (this_random_address);
5386             }
5387           while (hash_get (random_hash, this_random_address));
5388           vec_add1 (random_vector, this_random_address);
5389           hash_set (random_hash, this_random_address, 1);
5390         }
5391       hash_free (random_hash);
5392       v4_dst_address.as_u32 = random_vector[0];
5393     }
5394
5395   if (count > 1)
5396     {
5397       /* Turn on async mode */
5398       vam->async_mode = 1;
5399       vam->async_errors = 0;
5400       before = vat_time_now (vam);
5401     }
5402
5403   for (j = 0; j < count; j++)
5404     {
5405       /* Construct the API message */
5406       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5407
5408       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5409       mp->vrf_id = ntohl (vrf_id);
5410       if (resolve_attempts > 0)
5411         {
5412           mp->resolve_attempts = ntohl (resolve_attempts);
5413           mp->resolve_if_needed = 1;
5414         }
5415       mp->create_vrf_if_needed = create_vrf_if_needed;
5416
5417       mp->is_add = is_add;
5418       mp->is_drop = is_drop;
5419       mp->is_ipv6 = is_ipv6;
5420       mp->is_local = is_local;
5421       mp->is_classify = is_classify;
5422       mp->is_multipath = is_multipath;
5423       mp->not_last = not_last;
5424       mp->next_hop_weight = next_hop_weight;
5425       mp->dst_address_length = dst_address_length;
5426       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5427       mp->classify_table_index = ntohl (classify_table_index);
5428
5429       if (is_ipv6)
5430         {
5431           clib_memcpy (mp->dst_address, &v6_dst_address,
5432                        sizeof (v6_dst_address));
5433           if (next_hop_set)
5434             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5435                          sizeof (v6_next_hop_address));
5436           increment_v6_address (&v6_dst_address);
5437         }
5438       else
5439         {
5440           clib_memcpy (mp->dst_address, &v4_dst_address,
5441                        sizeof (v4_dst_address));
5442           if (next_hop_set)
5443             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5444                          sizeof (v4_next_hop_address));
5445           if (random_add_del)
5446             v4_dst_address.as_u32 = random_vector[j + 1];
5447           else
5448             increment_v4_address (&v4_dst_address);
5449         }
5450       /* send it... */
5451       S;
5452     }
5453
5454   /* When testing multiple add/del ops, use a control-ping to sync */
5455   if (count > 1)
5456     {
5457       vl_api_control_ping_t *mp;
5458       f64 after;
5459
5460       /* Shut off async mode */
5461       vam->async_mode = 0;
5462
5463       M (CONTROL_PING, control_ping);
5464       S;
5465
5466       timeout = vat_time_now (vam) + 1.0;
5467       while (vat_time_now (vam) < timeout)
5468         if (vam->result_ready == 1)
5469           goto out;
5470       vam->retval = -99;
5471
5472     out:
5473       if (vam->retval == -99)
5474         errmsg ("timeout\n");
5475
5476       if (vam->async_errors > 0)
5477         {
5478           errmsg ("%d asynchronous errors\n", vam->async_errors);
5479           vam->retval = -98;
5480         }
5481       vam->async_errors = 0;
5482       after = vat_time_now (vam);
5483
5484       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5485                count, after - before, count / (after - before));
5486     }
5487   else
5488     {
5489       /* Wait for a reply... */
5490       W;
5491     }
5492
5493   /* Return the good/bad news */
5494   return (vam->retval);
5495 }
5496
5497 static int
5498 api_proxy_arp_add_del (vat_main_t * vam)
5499 {
5500   unformat_input_t *i = vam->input;
5501   vl_api_proxy_arp_add_del_t *mp;
5502   f64 timeout;
5503   u32 vrf_id = 0;
5504   u8 is_add = 1;
5505   ip4_address_t lo, hi;
5506   u8 range_set = 0;
5507
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "vrf %d", &vrf_id))
5511         ;
5512       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5513                          unformat_ip4_address, &hi))
5514         range_set = 1;
5515       else if (unformat (i, "del"))
5516         is_add = 0;
5517       else
5518         {
5519           clib_warning ("parse error '%U'", format_unformat_error, i);
5520           return -99;
5521         }
5522     }
5523
5524   if (range_set == 0)
5525     {
5526       errmsg ("address range not set\n");
5527       return -99;
5528     }
5529
5530   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5531
5532   mp->vrf_id = ntohl (vrf_id);
5533   mp->is_add = is_add;
5534   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5535   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5536
5537   S;
5538   W;
5539   /* NOTREACHED */
5540   return 0;
5541 }
5542
5543 static int
5544 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5545 {
5546   unformat_input_t *i = vam->input;
5547   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5548   f64 timeout;
5549   u32 sw_if_index;
5550   u8 enable = 1;
5551   u8 sw_if_index_set = 0;
5552
5553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5554     {
5555       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5556         sw_if_index_set = 1;
5557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5558         sw_if_index_set = 1;
5559       else if (unformat (i, "enable"))
5560         enable = 1;
5561       else if (unformat (i, "disable"))
5562         enable = 0;
5563       else
5564         {
5565           clib_warning ("parse error '%U'", format_unformat_error, i);
5566           return -99;
5567         }
5568     }
5569
5570   if (sw_if_index_set == 0)
5571     {
5572       errmsg ("missing interface name or sw_if_index\n");
5573       return -99;
5574     }
5575
5576   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5577
5578   mp->sw_if_index = ntohl (sw_if_index);
5579   mp->enable_disable = enable;
5580
5581   S;
5582   W;
5583   /* NOTREACHED */
5584   return 0;
5585 }
5586
5587 static int
5588 api_mpls_add_del_decap (vat_main_t * vam)
5589 {
5590   unformat_input_t *i = vam->input;
5591   vl_api_mpls_add_del_decap_t *mp;
5592   f64 timeout;
5593   u32 rx_vrf_id = 0;
5594   u32 tx_vrf_id = 0;
5595   u32 label = 0;
5596   u8 is_add = 1;
5597   u8 s_bit = 1;
5598   u32 next_index = 1;
5599
5600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5601     {
5602       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5603         ;
5604       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5605         ;
5606       else if (unformat (i, "label %d", &label))
5607         ;
5608       else if (unformat (i, "next-index %d", &next_index))
5609         ;
5610       else if (unformat (i, "del"))
5611         is_add = 0;
5612       else if (unformat (i, "s-bit-clear"))
5613         s_bit = 0;
5614       else
5615         {
5616           clib_warning ("parse error '%U'", format_unformat_error, i);
5617           return -99;
5618         }
5619     }
5620
5621   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5622
5623   mp->rx_vrf_id = ntohl (rx_vrf_id);
5624   mp->tx_vrf_id = ntohl (tx_vrf_id);
5625   mp->label = ntohl (label);
5626   mp->next_index = ntohl (next_index);
5627   mp->s_bit = s_bit;
5628   mp->is_add = is_add;
5629
5630   S;
5631   W;
5632   /* NOTREACHED */
5633   return 0;
5634 }
5635
5636 static int
5637 api_mpls_add_del_encap (vat_main_t * vam)
5638 {
5639   unformat_input_t *i = vam->input;
5640   vl_api_mpls_add_del_encap_t *mp;
5641   f64 timeout;
5642   u32 vrf_id = 0;
5643   u32 *labels = 0;
5644   u32 label;
5645   ip4_address_t dst_address;
5646   u8 is_add = 1;
5647
5648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649     {
5650       if (unformat (i, "vrf %d", &vrf_id))
5651         ;
5652       else if (unformat (i, "label %d", &label))
5653         vec_add1 (labels, ntohl (label));
5654       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5655         ;
5656       else if (unformat (i, "del"))
5657         is_add = 0;
5658       else
5659         {
5660           clib_warning ("parse error '%U'", format_unformat_error, i);
5661           return -99;
5662         }
5663     }
5664
5665   if (vec_len (labels) == 0)
5666     {
5667       errmsg ("missing encap label stack\n");
5668       return -99;
5669     }
5670
5671   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5672       sizeof (u32) * vec_len (labels));
5673
5674   mp->vrf_id = ntohl (vrf_id);
5675   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5676   mp->is_add = is_add;
5677   mp->nlabels = vec_len (labels);
5678   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5679
5680   vec_free (labels);
5681
5682   S;
5683   W;
5684   /* NOTREACHED */
5685   return 0;
5686 }
5687
5688 static int
5689 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5690 {
5691   unformat_input_t *i = vam->input;
5692   vl_api_mpls_gre_add_del_tunnel_t *mp;
5693   f64 timeout;
5694   u32 inner_vrf_id = 0;
5695   u32 outer_vrf_id = 0;
5696   ip4_address_t src_address;
5697   ip4_address_t dst_address;
5698   ip4_address_t intfc_address;
5699   u32 tmp;
5700   u8 intfc_address_length = 0;
5701   u8 is_add = 1;
5702   u8 l2_only = 0;
5703
5704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5705     {
5706       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5707         ;
5708       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5709         ;
5710       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5711         ;
5712       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5713         ;
5714       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5715                          &intfc_address, &tmp))
5716         intfc_address_length = tmp;
5717       else if (unformat (i, "l2-only"))
5718         l2_only = 1;
5719       else if (unformat (i, "del"))
5720         is_add = 0;
5721       else
5722         {
5723           clib_warning ("parse error '%U'", format_unformat_error, i);
5724           return -99;
5725         }
5726     }
5727
5728   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5729
5730   mp->inner_vrf_id = ntohl (inner_vrf_id);
5731   mp->outer_vrf_id = ntohl (outer_vrf_id);
5732   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5733   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5734   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5735   mp->intfc_address_length = intfc_address_length;
5736   mp->l2_only = l2_only;
5737   mp->is_add = is_add;
5738
5739   S;
5740   W;
5741   /* NOTREACHED */
5742   return 0;
5743 }
5744
5745 static int
5746 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5747 {
5748   unformat_input_t *i = vam->input;
5749   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5750   f64 timeout;
5751   u32 inner_vrf_id = 0;
5752   ip4_address_t intfc_address;
5753   u8 dst_mac_address[6];
5754   int dst_set = 1;
5755   u32 tmp;
5756   u8 intfc_address_length = 0;
5757   u8 is_add = 1;
5758   u8 l2_only = 0;
5759   u32 tx_sw_if_index;
5760   int tx_sw_if_index_set = 0;
5761
5762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5763     {
5764       if (unformat (i, "vrf %d", &inner_vrf_id))
5765         ;
5766       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5767                          &intfc_address, &tmp))
5768         intfc_address_length = tmp;
5769       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5770         tx_sw_if_index_set = 1;
5771       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5772         tx_sw_if_index_set = 1;
5773       else if (unformat (i, "dst %U", unformat_ethernet_address,
5774                          dst_mac_address))
5775         dst_set = 1;
5776       else if (unformat (i, "l2-only"))
5777         l2_only = 1;
5778       else if (unformat (i, "del"))
5779         is_add = 0;
5780       else
5781         {
5782           clib_warning ("parse error '%U'", format_unformat_error, i);
5783           return -99;
5784         }
5785     }
5786
5787   if (!dst_set)
5788     {
5789       errmsg ("dst (mac address) not set\n");
5790       return -99;
5791     }
5792   if (!tx_sw_if_index_set)
5793     {
5794       errmsg ("tx-intfc not set\n");
5795       return -99;
5796     }
5797
5798   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5799
5800   mp->vrf_id = ntohl (inner_vrf_id);
5801   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5802   mp->adj_address_length = intfc_address_length;
5803   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5804                sizeof (dst_mac_address));
5805   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5806   mp->l2_only = l2_only;
5807   mp->is_add = is_add;
5808
5809   S;
5810   W;
5811   /* NOTREACHED */
5812   return 0;
5813 }
5814
5815 static int
5816 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5817 {
5818   unformat_input_t *i = vam->input;
5819   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5820   f64 timeout;
5821   u32 inner_vrf_id = 0;
5822   u32 outer_vrf_id = 0;
5823   ip4_address_t adj_address;
5824   int adj_address_set = 0;
5825   ip4_address_t next_hop_address;
5826   int next_hop_address_set = 0;
5827   u32 tmp;
5828   u8 adj_address_length = 0;
5829   u8 l2_only = 0;
5830   u8 is_add = 1;
5831   u32 resolve_attempts = 5;
5832   u8 resolve_if_needed = 1;
5833
5834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5835     {
5836       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5837         ;
5838       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5839         ;
5840       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5841                          &adj_address, &tmp))
5842         {
5843           adj_address_length = tmp;
5844           adj_address_set = 1;
5845         }
5846       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5847                          &next_hop_address))
5848         next_hop_address_set = 1;
5849       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5850         ;
5851       else if (unformat (i, "resolve-if-needed %d", &tmp))
5852         resolve_if_needed = tmp;
5853       else if (unformat (i, "l2-only"))
5854         l2_only = 1;
5855       else if (unformat (i, "del"))
5856         is_add = 0;
5857       else
5858         {
5859           clib_warning ("parse error '%U'", format_unformat_error, i);
5860           return -99;
5861         }
5862     }
5863
5864   if (!adj_address_set)
5865     {
5866       errmsg ("adjacency address/mask not set\n");
5867       return -99;
5868     }
5869   if (!next_hop_address_set)
5870     {
5871       errmsg ("ip4 next hop address (in outer fib) not set\n");
5872       return -99;
5873     }
5874
5875   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5876
5877   mp->inner_vrf_id = ntohl (inner_vrf_id);
5878   mp->outer_vrf_id = ntohl (outer_vrf_id);
5879   mp->resolve_attempts = ntohl (resolve_attempts);
5880   mp->resolve_if_needed = resolve_if_needed;
5881   mp->is_add = is_add;
5882   mp->l2_only = l2_only;
5883   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5884   mp->adj_address_length = adj_address_length;
5885   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5886                sizeof (next_hop_address));
5887
5888   S;
5889   W;
5890   /* NOTREACHED */
5891   return 0;
5892 }
5893
5894 static int
5895 api_sw_interface_set_unnumbered (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_unnumbered_t *mp;
5899   f64 timeout;
5900   u32 sw_if_index;
5901   u32 unnum_sw_index = ~0;
5902   u8 is_add = 1;
5903   u8 sw_if_index_set = 0;
5904
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5910         sw_if_index_set = 1;
5911       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5912         ;
5913       else if (unformat (i, "del"))
5914         is_add = 0;
5915       else
5916         {
5917           clib_warning ("parse error '%U'", format_unformat_error, i);
5918           return -99;
5919         }
5920     }
5921
5922   if (sw_if_index_set == 0)
5923     {
5924       errmsg ("missing interface name or sw_if_index\n");
5925       return -99;
5926     }
5927
5928   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5929
5930   mp->sw_if_index = ntohl (sw_if_index);
5931   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5932   mp->is_add = is_add;
5933
5934   S;
5935   W;
5936   /* NOTREACHED */
5937   return 0;
5938 }
5939
5940 static int
5941 api_ip_neighbor_add_del (vat_main_t * vam)
5942 {
5943   unformat_input_t *i = vam->input;
5944   vl_api_ip_neighbor_add_del_t *mp;
5945   f64 timeout;
5946   u32 sw_if_index;
5947   u8 sw_if_index_set = 0;
5948   u32 vrf_id = 0;
5949   u8 is_add = 1;
5950   u8 is_static = 0;
5951   u8 mac_address[6];
5952   u8 mac_set = 0;
5953   u8 v4_address_set = 0;
5954   u8 v6_address_set = 0;
5955   ip4_address_t v4address;
5956   ip6_address_t v6address;
5957
5958   memset (mac_address, 0, sizeof (mac_address));
5959
5960   /* Parse args required to build the message */
5961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5962     {
5963       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5964         {
5965           mac_set = 1;
5966         }
5967       else if (unformat (i, "del"))
5968         is_add = 0;
5969       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5970         sw_if_index_set = 1;
5971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5972         sw_if_index_set = 1;
5973       else if (unformat (i, "is_static"))
5974         is_static = 1;
5975       else if (unformat (i, "vrf %d", &vrf_id))
5976         ;
5977       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5978         v4_address_set = 1;
5979       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5980         v6_address_set = 1;
5981       else
5982         {
5983           clib_warning ("parse error '%U'", format_unformat_error, i);
5984           return -99;
5985         }
5986     }
5987
5988   if (sw_if_index_set == 0)
5989     {
5990       errmsg ("missing interface name or sw_if_index\n");
5991       return -99;
5992     }
5993   if (v4_address_set && v6_address_set)
5994     {
5995       errmsg ("both v4 and v6 addresses set\n");
5996       return -99;
5997     }
5998   if (!v4_address_set && !v6_address_set)
5999     {
6000       errmsg ("no address set\n");
6001       return -99;
6002     }
6003
6004   /* Construct the API message */
6005   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6006
6007   mp->sw_if_index = ntohl (sw_if_index);
6008   mp->is_add = is_add;
6009   mp->vrf_id = ntohl (vrf_id);
6010   mp->is_static = is_static;
6011   if (mac_set)
6012     clib_memcpy (mp->mac_address, mac_address, 6);
6013   if (v6_address_set)
6014     {
6015       mp->is_ipv6 = 1;
6016       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6017     }
6018   else
6019     {
6020       /* mp->is_ipv6 = 0; via memset in M macro above */
6021       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6022     }
6023
6024   /* send it... */
6025   S;
6026
6027   /* Wait for a reply, return good/bad news  */
6028   W;
6029
6030   /* NOTREACHED */
6031   return 0;
6032 }
6033
6034 static int
6035 api_reset_vrf (vat_main_t * vam)
6036 {
6037   unformat_input_t *i = vam->input;
6038   vl_api_reset_vrf_t *mp;
6039   f64 timeout;
6040   u32 vrf_id = 0;
6041   u8 is_ipv6 = 0;
6042   u8 vrf_id_set = 0;
6043
6044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6045     {
6046       if (unformat (i, "vrf %d", &vrf_id))
6047         vrf_id_set = 1;
6048       else if (unformat (i, "ipv6"))
6049         is_ipv6 = 1;
6050       else
6051         {
6052           clib_warning ("parse error '%U'", format_unformat_error, i);
6053           return -99;
6054         }
6055     }
6056
6057   if (vrf_id_set == 0)
6058     {
6059       errmsg ("missing vrf id\n");
6060       return -99;
6061     }
6062
6063   M (RESET_VRF, reset_vrf);
6064
6065   mp->vrf_id = ntohl (vrf_id);
6066   mp->is_ipv6 = is_ipv6;
6067
6068   S;
6069   W;
6070   /* NOTREACHED */
6071   return 0;
6072 }
6073
6074 static int
6075 api_create_vlan_subif (vat_main_t * vam)
6076 {
6077   unformat_input_t *i = vam->input;
6078   vl_api_create_vlan_subif_t *mp;
6079   f64 timeout;
6080   u32 sw_if_index;
6081   u8 sw_if_index_set = 0;
6082   u32 vlan_id;
6083   u8 vlan_id_set = 0;
6084
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "sw_if_index %d", &sw_if_index))
6088         sw_if_index_set = 1;
6089       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6090         sw_if_index_set = 1;
6091       else if (unformat (i, "vlan %d", &vlan_id))
6092         vlan_id_set = 1;
6093       else
6094         {
6095           clib_warning ("parse error '%U'", format_unformat_error, i);
6096           return -99;
6097         }
6098     }
6099
6100   if (sw_if_index_set == 0)
6101     {
6102       errmsg ("missing interface name or sw_if_index\n");
6103       return -99;
6104     }
6105
6106   if (vlan_id_set == 0)
6107     {
6108       errmsg ("missing vlan_id\n");
6109       return -99;
6110     }
6111   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6112
6113   mp->sw_if_index = ntohl (sw_if_index);
6114   mp->vlan_id = ntohl (vlan_id);
6115
6116   S;
6117   W;
6118   /* NOTREACHED */
6119   return 0;
6120 }
6121
6122 #define foreach_create_subif_bit                \
6123 _(no_tags)                                      \
6124 _(one_tag)                                      \
6125 _(two_tags)                                     \
6126 _(dot1ad)                                       \
6127 _(exact_match)                                  \
6128 _(default_sub)                                  \
6129 _(outer_vlan_id_any)                            \
6130 _(inner_vlan_id_any)
6131
6132 static int
6133 api_create_subif (vat_main_t * vam)
6134 {
6135   unformat_input_t *i = vam->input;
6136   vl_api_create_subif_t *mp;
6137   f64 timeout;
6138   u32 sw_if_index;
6139   u8 sw_if_index_set = 0;
6140   u32 sub_id;
6141   u8 sub_id_set = 0;
6142   u32 no_tags = 0;
6143   u32 one_tag = 0;
6144   u32 two_tags = 0;
6145   u32 dot1ad = 0;
6146   u32 exact_match = 0;
6147   u32 default_sub = 0;
6148   u32 outer_vlan_id_any = 0;
6149   u32 inner_vlan_id_any = 0;
6150   u32 tmp;
6151   u16 outer_vlan_id = 0;
6152   u16 inner_vlan_id = 0;
6153
6154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6155     {
6156       if (unformat (i, "sw_if_index %d", &sw_if_index))
6157         sw_if_index_set = 1;
6158       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6159         sw_if_index_set = 1;
6160       else if (unformat (i, "sub_id %d", &sub_id))
6161         sub_id_set = 1;
6162       else if (unformat (i, "outer_vlan_id %d", &tmp))
6163         outer_vlan_id = tmp;
6164       else if (unformat (i, "inner_vlan_id %d", &tmp))
6165         inner_vlan_id = tmp;
6166
6167 #define _(a) else if (unformat (i, #a)) a = 1 ;
6168       foreach_create_subif_bit
6169 #undef _
6170         else
6171         {
6172           clib_warning ("parse error '%U'", format_unformat_error, i);
6173           return -99;
6174         }
6175     }
6176
6177   if (sw_if_index_set == 0)
6178     {
6179       errmsg ("missing interface name or sw_if_index\n");
6180       return -99;
6181     }
6182
6183   if (sub_id_set == 0)
6184     {
6185       errmsg ("missing sub_id\n");
6186       return -99;
6187     }
6188   M (CREATE_SUBIF, create_subif);
6189
6190   mp->sw_if_index = ntohl (sw_if_index);
6191   mp->sub_id = ntohl (sub_id);
6192
6193 #define _(a) mp->a = a;
6194   foreach_create_subif_bit;
6195 #undef _
6196
6197   mp->outer_vlan_id = ntohs (outer_vlan_id);
6198   mp->inner_vlan_id = ntohs (inner_vlan_id);
6199
6200   S;
6201   W;
6202   /* NOTREACHED */
6203   return 0;
6204 }
6205
6206 static int
6207 api_oam_add_del (vat_main_t * vam)
6208 {
6209   unformat_input_t *i = vam->input;
6210   vl_api_oam_add_del_t *mp;
6211   f64 timeout;
6212   u32 vrf_id = 0;
6213   u8 is_add = 1;
6214   ip4_address_t src, dst;
6215   u8 src_set = 0;
6216   u8 dst_set = 0;
6217
6218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219     {
6220       if (unformat (i, "vrf %d", &vrf_id))
6221         ;
6222       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6223         src_set = 1;
6224       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6225         dst_set = 1;
6226       else if (unformat (i, "del"))
6227         is_add = 0;
6228       else
6229         {
6230           clib_warning ("parse error '%U'", format_unformat_error, i);
6231           return -99;
6232         }
6233     }
6234
6235   if (src_set == 0)
6236     {
6237       errmsg ("missing src addr\n");
6238       return -99;
6239     }
6240
6241   if (dst_set == 0)
6242     {
6243       errmsg ("missing dst addr\n");
6244       return -99;
6245     }
6246
6247   M (OAM_ADD_DEL, oam_add_del);
6248
6249   mp->vrf_id = ntohl (vrf_id);
6250   mp->is_add = is_add;
6251   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6252   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6253
6254   S;
6255   W;
6256   /* NOTREACHED */
6257   return 0;
6258 }
6259
6260 static int
6261 api_reset_fib (vat_main_t * vam)
6262 {
6263   unformat_input_t *i = vam->input;
6264   vl_api_reset_fib_t *mp;
6265   f64 timeout;
6266   u32 vrf_id = 0;
6267   u8 is_ipv6 = 0;
6268   u8 vrf_id_set = 0;
6269
6270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6271     {
6272       if (unformat (i, "vrf %d", &vrf_id))
6273         vrf_id_set = 1;
6274       else if (unformat (i, "ipv6"))
6275         is_ipv6 = 1;
6276       else
6277         {
6278           clib_warning ("parse error '%U'", format_unformat_error, i);
6279           return -99;
6280         }
6281     }
6282
6283   if (vrf_id_set == 0)
6284     {
6285       errmsg ("missing vrf id\n");
6286       return -99;
6287     }
6288
6289   M (RESET_FIB, reset_fib);
6290
6291   mp->vrf_id = ntohl (vrf_id);
6292   mp->is_ipv6 = is_ipv6;
6293
6294   S;
6295   W;
6296   /* NOTREACHED */
6297   return 0;
6298 }
6299
6300 static int
6301 api_dhcp_proxy_config (vat_main_t * vam)
6302 {
6303   unformat_input_t *i = vam->input;
6304   vl_api_dhcp_proxy_config_t *mp;
6305   f64 timeout;
6306   u32 vrf_id = 0;
6307   u8 is_add = 1;
6308   u8 insert_cid = 1;
6309   u8 v4_address_set = 0;
6310   u8 v6_address_set = 0;
6311   ip4_address_t v4address;
6312   ip6_address_t v6address;
6313   u8 v4_src_address_set = 0;
6314   u8 v6_src_address_set = 0;
6315   ip4_address_t v4srcaddress;
6316   ip6_address_t v6srcaddress;
6317
6318   /* Parse args required to build the message */
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "del"))
6322         is_add = 0;
6323       else if (unformat (i, "vrf %d", &vrf_id))
6324         ;
6325       else if (unformat (i, "insert-cid %d", &insert_cid))
6326         ;
6327       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6328         v4_address_set = 1;
6329       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6330         v6_address_set = 1;
6331       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6332         v4_src_address_set = 1;
6333       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6334         v6_src_address_set = 1;
6335       else
6336         break;
6337     }
6338
6339   if (v4_address_set && v6_address_set)
6340     {
6341       errmsg ("both v4 and v6 server addresses set\n");
6342       return -99;
6343     }
6344   if (!v4_address_set && !v6_address_set)
6345     {
6346       errmsg ("no server addresses set\n");
6347       return -99;
6348     }
6349
6350   if (v4_src_address_set && v6_src_address_set)
6351     {
6352       errmsg ("both v4 and v6  src addresses set\n");
6353       return -99;
6354     }
6355   if (!v4_src_address_set && !v6_src_address_set)
6356     {
6357       errmsg ("no src addresses set\n");
6358       return -99;
6359     }
6360
6361   if (!(v4_src_address_set && v4_address_set) &&
6362       !(v6_src_address_set && v6_address_set))
6363     {
6364       errmsg ("no matching server and src addresses set\n");
6365       return -99;
6366     }
6367
6368   /* Construct the API message */
6369   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6370
6371   mp->insert_circuit_id = insert_cid;
6372   mp->is_add = is_add;
6373   mp->vrf_id = ntohl (vrf_id);
6374   if (v6_address_set)
6375     {
6376       mp->is_ipv6 = 1;
6377       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6378       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6379     }
6380   else
6381     {
6382       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6383       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6384     }
6385
6386   /* send it... */
6387   S;
6388
6389   /* Wait for a reply, return good/bad news  */
6390   W;
6391   /* NOTREACHED */
6392   return 0;
6393 }
6394
6395 static int
6396 api_dhcp_proxy_config_2 (vat_main_t * vam)
6397 {
6398   unformat_input_t *i = vam->input;
6399   vl_api_dhcp_proxy_config_2_t *mp;
6400   f64 timeout;
6401   u32 rx_vrf_id = 0;
6402   u32 server_vrf_id = 0;
6403   u8 is_add = 1;
6404   u8 insert_cid = 1;
6405   u8 v4_address_set = 0;
6406   u8 v6_address_set = 0;
6407   ip4_address_t v4address;
6408   ip6_address_t v6address;
6409   u8 v4_src_address_set = 0;
6410   u8 v6_src_address_set = 0;
6411   ip4_address_t v4srcaddress;
6412   ip6_address_t v6srcaddress;
6413
6414   /* Parse args required to build the message */
6415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6416     {
6417       if (unformat (i, "del"))
6418         is_add = 0;
6419       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6420         ;
6421       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6422         ;
6423       else if (unformat (i, "insert-cid %d", &insert_cid))
6424         ;
6425       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6426         v4_address_set = 1;
6427       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6428         v6_address_set = 1;
6429       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6430         v4_src_address_set = 1;
6431       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6432         v6_src_address_set = 1;
6433       else
6434         break;
6435     }
6436
6437   if (v4_address_set && v6_address_set)
6438     {
6439       errmsg ("both v4 and v6 server addresses set\n");
6440       return -99;
6441     }
6442   if (!v4_address_set && !v6_address_set)
6443     {
6444       errmsg ("no server addresses set\n");
6445       return -99;
6446     }
6447
6448   if (v4_src_address_set && v6_src_address_set)
6449     {
6450       errmsg ("both v4 and v6  src addresses set\n");
6451       return -99;
6452     }
6453   if (!v4_src_address_set && !v6_src_address_set)
6454     {
6455       errmsg ("no src addresses set\n");
6456       return -99;
6457     }
6458
6459   if (!(v4_src_address_set && v4_address_set) &&
6460       !(v6_src_address_set && v6_address_set))
6461     {
6462       errmsg ("no matching server and src addresses set\n");
6463       return -99;
6464     }
6465
6466   /* Construct the API message */
6467   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6468
6469   mp->insert_circuit_id = insert_cid;
6470   mp->is_add = is_add;
6471   mp->rx_vrf_id = ntohl (rx_vrf_id);
6472   mp->server_vrf_id = ntohl (server_vrf_id);
6473   if (v6_address_set)
6474     {
6475       mp->is_ipv6 = 1;
6476       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6477       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6478     }
6479   else
6480     {
6481       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6482       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6483     }
6484
6485   /* send it... */
6486   S;
6487
6488   /* Wait for a reply, return good/bad news  */
6489   W;
6490   /* NOTREACHED */
6491   return 0;
6492 }
6493
6494 static int
6495 api_dhcp_proxy_set_vss (vat_main_t * vam)
6496 {
6497   unformat_input_t *i = vam->input;
6498   vl_api_dhcp_proxy_set_vss_t *mp;
6499   f64 timeout;
6500   u8 is_ipv6 = 0;
6501   u8 is_add = 1;
6502   u32 tbl_id;
6503   u8 tbl_id_set = 0;
6504   u32 oui;
6505   u8 oui_set = 0;
6506   u32 fib_id;
6507   u8 fib_id_set = 0;
6508
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "tbl_id %d", &tbl_id))
6512         tbl_id_set = 1;
6513       if (unformat (i, "fib_id %d", &fib_id))
6514         fib_id_set = 1;
6515       if (unformat (i, "oui %d", &oui))
6516         oui_set = 1;
6517       else if (unformat (i, "ipv6"))
6518         is_ipv6 = 1;
6519       else if (unformat (i, "del"))
6520         is_add = 0;
6521       else
6522         {
6523           clib_warning ("parse error '%U'", format_unformat_error, i);
6524           return -99;
6525         }
6526     }
6527
6528   if (tbl_id_set == 0)
6529     {
6530       errmsg ("missing tbl id\n");
6531       return -99;
6532     }
6533
6534   if (fib_id_set == 0)
6535     {
6536       errmsg ("missing fib id\n");
6537       return -99;
6538     }
6539   if (oui_set == 0)
6540     {
6541       errmsg ("missing oui\n");
6542       return -99;
6543     }
6544
6545   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6546   mp->tbl_id = ntohl (tbl_id);
6547   mp->fib_id = ntohl (fib_id);
6548   mp->oui = ntohl (oui);
6549   mp->is_ipv6 = is_ipv6;
6550   mp->is_add = is_add;
6551
6552   S;
6553   W;
6554   /* NOTREACHED */
6555   return 0;
6556 }
6557
6558 static int
6559 api_dhcp_client_config (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_dhcp_client_config_t *mp;
6563   f64 timeout;
6564   u32 sw_if_index;
6565   u8 sw_if_index_set = 0;
6566   u8 is_add = 1;
6567   u8 *hostname = 0;
6568   u8 disable_event = 0;
6569
6570   /* Parse args required to build the message */
6571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572     {
6573       if (unformat (i, "del"))
6574         is_add = 0;
6575       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6576         sw_if_index_set = 1;
6577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6578         sw_if_index_set = 1;
6579       else if (unformat (i, "hostname %s", &hostname))
6580         ;
6581       else if (unformat (i, "disable_event"))
6582         disable_event = 1;
6583       else
6584         break;
6585     }
6586
6587   if (sw_if_index_set == 0)
6588     {
6589       errmsg ("missing interface name or sw_if_index\n");
6590       return -99;
6591     }
6592
6593   if (vec_len (hostname) > 63)
6594     {
6595       errmsg ("hostname too long\n");
6596     }
6597   vec_add1 (hostname, 0);
6598
6599   /* Construct the API message */
6600   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6601
6602   mp->sw_if_index = ntohl (sw_if_index);
6603   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6604   vec_free (hostname);
6605   mp->is_add = is_add;
6606   mp->want_dhcp_event = disable_event ? 0 : 1;
6607   mp->pid = getpid ();
6608
6609   /* send it... */
6610   S;
6611
6612   /* Wait for a reply, return good/bad news  */
6613   W;
6614   /* NOTREACHED */
6615   return 0;
6616 }
6617
6618 static int
6619 api_set_ip_flow_hash (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_set_ip_flow_hash_t *mp;
6623   f64 timeout;
6624   u32 vrf_id = 0;
6625   u8 is_ipv6 = 0;
6626   u8 vrf_id_set = 0;
6627   u8 src = 0;
6628   u8 dst = 0;
6629   u8 sport = 0;
6630   u8 dport = 0;
6631   u8 proto = 0;
6632   u8 reverse = 0;
6633
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "vrf %d", &vrf_id))
6637         vrf_id_set = 1;
6638       else if (unformat (i, "ipv6"))
6639         is_ipv6 = 1;
6640       else if (unformat (i, "src"))
6641         src = 1;
6642       else if (unformat (i, "dst"))
6643         dst = 1;
6644       else if (unformat (i, "sport"))
6645         sport = 1;
6646       else if (unformat (i, "dport"))
6647         dport = 1;
6648       else if (unformat (i, "proto"))
6649         proto = 1;
6650       else if (unformat (i, "reverse"))
6651         reverse = 1;
6652
6653       else
6654         {
6655           clib_warning ("parse error '%U'", format_unformat_error, i);
6656           return -99;
6657         }
6658     }
6659
6660   if (vrf_id_set == 0)
6661     {
6662       errmsg ("missing vrf id\n");
6663       return -99;
6664     }
6665
6666   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6667   mp->src = src;
6668   mp->dst = dst;
6669   mp->sport = sport;
6670   mp->dport = dport;
6671   mp->proto = proto;
6672   mp->reverse = reverse;
6673   mp->vrf_id = ntohl (vrf_id);
6674   mp->is_ipv6 = is_ipv6;
6675
6676   S;
6677   W;
6678   /* NOTREACHED */
6679   return 0;
6680 }
6681
6682 static int
6683 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6684 {
6685   unformat_input_t *i = vam->input;
6686   vl_api_sw_interface_ip6_enable_disable_t *mp;
6687   f64 timeout;
6688   u32 sw_if_index;
6689   u8 sw_if_index_set = 0;
6690   u8 enable = 0;
6691
6692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6693     {
6694       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6695         sw_if_index_set = 1;
6696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6697         sw_if_index_set = 1;
6698       else if (unformat (i, "enable"))
6699         enable = 1;
6700       else if (unformat (i, "disable"))
6701         enable = 0;
6702       else
6703         {
6704           clib_warning ("parse error '%U'", format_unformat_error, i);
6705           return -99;
6706         }
6707     }
6708
6709   if (sw_if_index_set == 0)
6710     {
6711       errmsg ("missing interface name or sw_if_index\n");
6712       return -99;
6713     }
6714
6715   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6716
6717   mp->sw_if_index = ntohl (sw_if_index);
6718   mp->enable = enable;
6719
6720   S;
6721   W;
6722   /* NOTREACHED */
6723   return 0;
6724 }
6725
6726 static int
6727 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6728 {
6729   unformat_input_t *i = vam->input;
6730   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6731   f64 timeout;
6732   u32 sw_if_index;
6733   u8 sw_if_index_set = 0;
6734   u32 address_length = 0;
6735   u8 v6_address_set = 0;
6736   ip6_address_t v6address;
6737
6738   /* Parse args required to build the message */
6739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6740     {
6741       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6742         sw_if_index_set = 1;
6743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6744         sw_if_index_set = 1;
6745       else if (unformat (i, "%U/%d",
6746                          unformat_ip6_address, &v6address, &address_length))
6747         v6_address_set = 1;
6748       else
6749         break;
6750     }
6751
6752   if (sw_if_index_set == 0)
6753     {
6754       errmsg ("missing interface name or sw_if_index\n");
6755       return -99;
6756     }
6757   if (!v6_address_set)
6758     {
6759       errmsg ("no address set\n");
6760       return -99;
6761     }
6762
6763   /* Construct the API message */
6764   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6765      sw_interface_ip6_set_link_local_address);
6766
6767   mp->sw_if_index = ntohl (sw_if_index);
6768   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6769   mp->address_length = address_length;
6770
6771   /* send it... */
6772   S;
6773
6774   /* Wait for a reply, return good/bad news  */
6775   W;
6776
6777   /* NOTREACHED */
6778   return 0;
6779 }
6780
6781
6782 static int
6783 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6787   f64 timeout;
6788   u32 sw_if_index;
6789   u8 sw_if_index_set = 0;
6790   u32 address_length = 0;
6791   u8 v6_address_set = 0;
6792   ip6_address_t v6address;
6793   u8 use_default = 0;
6794   u8 no_advertise = 0;
6795   u8 off_link = 0;
6796   u8 no_autoconfig = 0;
6797   u8 no_onlink = 0;
6798   u8 is_no = 0;
6799   u32 val_lifetime = 0;
6800   u32 pref_lifetime = 0;
6801
6802   /* Parse args required to build the message */
6803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6804     {
6805       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6806         sw_if_index_set = 1;
6807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6808         sw_if_index_set = 1;
6809       else if (unformat (i, "%U/%d",
6810                          unformat_ip6_address, &v6address, &address_length))
6811         v6_address_set = 1;
6812       else if (unformat (i, "val_life %d", &val_lifetime))
6813         ;
6814       else if (unformat (i, "pref_life %d", &pref_lifetime))
6815         ;
6816       else if (unformat (i, "def"))
6817         use_default = 1;
6818       else if (unformat (i, "noadv"))
6819         no_advertise = 1;
6820       else if (unformat (i, "offl"))
6821         off_link = 1;
6822       else if (unformat (i, "noauto"))
6823         no_autoconfig = 1;
6824       else if (unformat (i, "nolink"))
6825         no_onlink = 1;
6826       else if (unformat (i, "isno"))
6827         is_no = 1;
6828       else
6829         {
6830           clib_warning ("parse error '%U'", format_unformat_error, i);
6831           return -99;
6832         }
6833     }
6834
6835   if (sw_if_index_set == 0)
6836     {
6837       errmsg ("missing interface name or sw_if_index\n");
6838       return -99;
6839     }
6840   if (!v6_address_set)
6841     {
6842       errmsg ("no address set\n");
6843       return -99;
6844     }
6845
6846   /* Construct the API message */
6847   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6848
6849   mp->sw_if_index = ntohl (sw_if_index);
6850   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6851   mp->address_length = address_length;
6852   mp->use_default = use_default;
6853   mp->no_advertise = no_advertise;
6854   mp->off_link = off_link;
6855   mp->no_autoconfig = no_autoconfig;
6856   mp->no_onlink = no_onlink;
6857   mp->is_no = is_no;
6858   mp->val_lifetime = ntohl (val_lifetime);
6859   mp->pref_lifetime = ntohl (pref_lifetime);
6860
6861   /* send it... */
6862   S;
6863
6864   /* Wait for a reply, return good/bad news  */
6865   W;
6866
6867   /* NOTREACHED */
6868   return 0;
6869 }
6870
6871 static int
6872 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6876   f64 timeout;
6877   u32 sw_if_index;
6878   u8 sw_if_index_set = 0;
6879   u8 suppress = 0;
6880   u8 managed = 0;
6881   u8 other = 0;
6882   u8 ll_option = 0;
6883   u8 send_unicast = 0;
6884   u8 cease = 0;
6885   u8 is_no = 0;
6886   u8 default_router = 0;
6887   u32 max_interval = 0;
6888   u32 min_interval = 0;
6889   u32 lifetime = 0;
6890   u32 initial_count = 0;
6891   u32 initial_interval = 0;
6892
6893
6894   /* Parse args required to build the message */
6895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896     {
6897       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6900         sw_if_index_set = 1;
6901       else if (unformat (i, "maxint %d", &max_interval))
6902         ;
6903       else if (unformat (i, "minint %d", &min_interval))
6904         ;
6905       else if (unformat (i, "life %d", &lifetime))
6906         ;
6907       else if (unformat (i, "count %d", &initial_count))
6908         ;
6909       else if (unformat (i, "interval %d", &initial_interval))
6910         ;
6911       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6912         suppress = 1;
6913       else if (unformat (i, "managed"))
6914         managed = 1;
6915       else if (unformat (i, "other"))
6916         other = 1;
6917       else if (unformat (i, "ll"))
6918         ll_option = 1;
6919       else if (unformat (i, "send"))
6920         send_unicast = 1;
6921       else if (unformat (i, "cease"))
6922         cease = 1;
6923       else if (unformat (i, "isno"))
6924         is_no = 1;
6925       else if (unformat (i, "def"))
6926         default_router = 1;
6927       else
6928         {
6929           clib_warning ("parse error '%U'", format_unformat_error, i);
6930           return -99;
6931         }
6932     }
6933
6934   if (sw_if_index_set == 0)
6935     {
6936       errmsg ("missing interface name or sw_if_index\n");
6937       return -99;
6938     }
6939
6940   /* Construct the API message */
6941   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6942
6943   mp->sw_if_index = ntohl (sw_if_index);
6944   mp->max_interval = ntohl (max_interval);
6945   mp->min_interval = ntohl (min_interval);
6946   mp->lifetime = ntohl (lifetime);
6947   mp->initial_count = ntohl (initial_count);
6948   mp->initial_interval = ntohl (initial_interval);
6949   mp->suppress = suppress;
6950   mp->managed = managed;
6951   mp->other = other;
6952   mp->ll_option = ll_option;
6953   mp->send_unicast = send_unicast;
6954   mp->cease = cease;
6955   mp->is_no = is_no;
6956   mp->default_router = default_router;
6957
6958   /* send it... */
6959   S;
6960
6961   /* Wait for a reply, return good/bad news  */
6962   W;
6963
6964   /* NOTREACHED */
6965   return 0;
6966 }
6967
6968 static int
6969 api_set_arp_neighbor_limit (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_set_arp_neighbor_limit_t *mp;
6973   f64 timeout;
6974   u32 arp_nbr_limit;
6975   u8 limit_set = 0;
6976   u8 is_ipv6 = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6981         limit_set = 1;
6982       else if (unformat (i, "ipv6"))
6983         is_ipv6 = 1;
6984       else
6985         {
6986           clib_warning ("parse error '%U'", format_unformat_error, i);
6987           return -99;
6988         }
6989     }
6990
6991   if (limit_set == 0)
6992     {
6993       errmsg ("missing limit value\n");
6994       return -99;
6995     }
6996
6997   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6998
6999   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S;
7003   W;
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_l2_patch_add_del (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_l2_patch_add_del_t *mp;
7013   f64 timeout;
7014   u32 rx_sw_if_index;
7015   u8 rx_sw_if_index_set = 0;
7016   u32 tx_sw_if_index;
7017   u8 tx_sw_if_index_set = 0;
7018   u8 is_add = 1;
7019
7020   /* Parse args required to build the message */
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7024         rx_sw_if_index_set = 1;
7025       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7026         tx_sw_if_index_set = 1;
7027       else if (unformat (i, "rx"))
7028         {
7029           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7030             {
7031               if (unformat (i, "%U", unformat_sw_if_index, vam,
7032                             &rx_sw_if_index))
7033                 rx_sw_if_index_set = 1;
7034             }
7035           else
7036             break;
7037         }
7038       else if (unformat (i, "tx"))
7039         {
7040           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041             {
7042               if (unformat (i, "%U", unformat_sw_if_index, vam,
7043                             &tx_sw_if_index))
7044                 tx_sw_if_index_set = 1;
7045             }
7046           else
7047             break;
7048         }
7049       else if (unformat (i, "del"))
7050         is_add = 0;
7051       else
7052         break;
7053     }
7054
7055   if (rx_sw_if_index_set == 0)
7056     {
7057       errmsg ("missing rx interface name or rx_sw_if_index\n");
7058       return -99;
7059     }
7060
7061   if (tx_sw_if_index_set == 0)
7062     {
7063       errmsg ("missing tx interface name or tx_sw_if_index\n");
7064       return -99;
7065     }
7066
7067   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7068
7069   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7070   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7071   mp->is_add = is_add;
7072
7073   S;
7074   W;
7075   /* NOTREACHED */
7076   return 0;
7077 }
7078
7079 static int
7080 api_trace_profile_add (vat_main_t * vam)
7081 {
7082   unformat_input_t *input = vam->input;
7083   vl_api_trace_profile_add_t *mp;
7084   f64 timeout;
7085   u32 id = 0;
7086   u32 trace_option_elts = 0;
7087   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7088   int has_pow_option = 0;
7089   int has_ppc_option = 0;
7090
7091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7094                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7095                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7096                     &node_id, &app_data))
7097         ;
7098       else if (unformat (input, "pow"))
7099         has_pow_option = 1;
7100       else if (unformat (input, "ppc encap"))
7101         has_ppc_option = PPC_ENCAP;
7102       else if (unformat (input, "ppc decap"))
7103         has_ppc_option = PPC_DECAP;
7104       else if (unformat (input, "ppc none"))
7105         has_ppc_option = PPC_NONE;
7106       else
7107         break;
7108     }
7109   M (TRACE_PROFILE_ADD, trace_profile_add);
7110   mp->id = htons (id);
7111   mp->trace_type = trace_type;
7112   mp->trace_num_elt = trace_option_elts;
7113   mp->trace_ppc = has_ppc_option;
7114   mp->trace_app_data = htonl (app_data);
7115   mp->pow_enable = has_pow_option;
7116   mp->trace_tsp = trace_tsp;
7117   mp->node_id = htonl (node_id);
7118
7119   S;
7120   W;
7121
7122   return (0);
7123
7124 }
7125
7126 static int
7127 api_trace_profile_apply (vat_main_t * vam)
7128 {
7129   unformat_input_t *input = vam->input;
7130   vl_api_trace_profile_apply_t *mp;
7131   f64 timeout;
7132   ip6_address_t addr;
7133   u32 mask_width = ~0;
7134   int is_add = 0;
7135   int is_pop = 0;
7136   int is_none = 0;
7137   u32 vrf_id = 0;
7138   u32 id = 0;
7139
7140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7141     {
7142       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7143         ;
7144       else if (unformat (input, "id %d", &id))
7145         ;
7146       else if (unformat (input, "vrf-id %d", &vrf_id))
7147         ;
7148       else if (unformat (input, "add"))
7149         is_add = 1;
7150       else if (unformat (input, "pop"))
7151         is_pop = 1;
7152       else if (unformat (input, "none"))
7153         is_none = 1;
7154       else
7155         break;
7156     }
7157
7158   if ((is_add + is_pop + is_none) != 1)
7159     {
7160       errmsg ("One of (add, pop, none) required");
7161       return -99;
7162     }
7163   if (mask_width == ~0)
7164     {
7165       errmsg ("<address>/<mask-width> required");
7166       return -99;
7167     }
7168   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7169   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7170   mp->id = htons (id);
7171   mp->prefix_length = htonl (mask_width);
7172   mp->vrf_id = htonl (vrf_id);
7173   if (is_add)
7174     mp->trace_op = IOAM_HBYH_ADD;
7175   else if (is_pop)
7176     mp->trace_op = IOAM_HBYH_POP;
7177   else
7178     mp->trace_op = IOAM_HBYH_MOD;
7179
7180   if (is_none)
7181     mp->enable = 0;
7182   else
7183     mp->enable = 1;
7184
7185   S;
7186   W;
7187
7188   return 0;
7189 }
7190
7191 static int
7192 api_trace_profile_del (vat_main_t * vam)
7193 {
7194   vl_api_trace_profile_del_t *mp;
7195   f64 timeout;
7196
7197   M (TRACE_PROFILE_DEL, trace_profile_del);
7198   S;
7199   W;
7200   return 0;
7201 }
7202
7203 static int
7204 api_sr_tunnel_add_del (vat_main_t * vam)
7205 {
7206   unformat_input_t *i = vam->input;
7207   vl_api_sr_tunnel_add_del_t *mp;
7208   f64 timeout;
7209   int is_del = 0;
7210   int pl_index;
7211   ip6_address_t src_address;
7212   int src_address_set = 0;
7213   ip6_address_t dst_address;
7214   u32 dst_mask_width;
7215   int dst_address_set = 0;
7216   u16 flags = 0;
7217   u32 rx_table_id = 0;
7218   u32 tx_table_id = 0;
7219   ip6_address_t *segments = 0;
7220   ip6_address_t *this_seg;
7221   ip6_address_t *tags = 0;
7222   ip6_address_t *this_tag;
7223   ip6_address_t next_address, tag;
7224   u8 *name = 0;
7225   u8 *policy_name = 0;
7226
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "del"))
7230         is_del = 1;
7231       else if (unformat (i, "name %s", &name))
7232         ;
7233       else if (unformat (i, "policy %s", &policy_name))
7234         ;
7235       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7236         ;
7237       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7238         ;
7239       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7240         src_address_set = 1;
7241       else if (unformat (i, "dst %U/%d",
7242                          unformat_ip6_address, &dst_address, &dst_mask_width))
7243         dst_address_set = 1;
7244       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7245         {
7246           vec_add2 (segments, this_seg, 1);
7247           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7248                        sizeof (*this_seg));
7249         }
7250       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7251         {
7252           vec_add2 (tags, this_tag, 1);
7253           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7254         }
7255       else if (unformat (i, "clean"))
7256         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7257       else if (unformat (i, "protected"))
7258         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7259       else if (unformat (i, "InPE %d", &pl_index))
7260         {
7261           if (pl_index <= 0 || pl_index > 4)
7262             {
7263             pl_index_range_error:
7264               errmsg ("pl index %d out of range\n", pl_index);
7265               return -99;
7266             }
7267           flags |=
7268             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7269         }
7270       else if (unformat (i, "EgPE %d", &pl_index))
7271         {
7272           if (pl_index <= 0 || pl_index > 4)
7273             goto pl_index_range_error;
7274           flags |=
7275             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7276         }
7277       else if (unformat (i, "OrgSrc %d", &pl_index))
7278         {
7279           if (pl_index <= 0 || pl_index > 4)
7280             goto pl_index_range_error;
7281           flags |=
7282             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7283         }
7284       else
7285         break;
7286     }
7287
7288   if (!src_address_set)
7289     {
7290       errmsg ("src address required\n");
7291       return -99;
7292     }
7293
7294   if (!dst_address_set)
7295     {
7296       errmsg ("dst address required\n");
7297       return -99;
7298     }
7299
7300   if (!segments)
7301     {
7302       errmsg ("at least one sr segment required\n");
7303       return -99;
7304     }
7305
7306   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7307       vec_len (segments) * sizeof (ip6_address_t)
7308       + vec_len (tags) * sizeof (ip6_address_t));
7309
7310   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7311   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7312   mp->dst_mask_width = dst_mask_width;
7313   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7314   mp->n_segments = vec_len (segments);
7315   mp->n_tags = vec_len (tags);
7316   mp->is_add = is_del == 0;
7317   clib_memcpy (mp->segs_and_tags, segments,
7318                vec_len (segments) * sizeof (ip6_address_t));
7319   clib_memcpy (mp->segs_and_tags +
7320                vec_len (segments) * sizeof (ip6_address_t), tags,
7321                vec_len (tags) * sizeof (ip6_address_t));
7322
7323   mp->outer_vrf_id = ntohl (rx_table_id);
7324   mp->inner_vrf_id = ntohl (tx_table_id);
7325   memcpy (mp->name, name, vec_len (name));
7326   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7327
7328   vec_free (segments);
7329   vec_free (tags);
7330
7331   S;
7332   W;
7333   /* NOTREACHED */
7334 }
7335
7336 static int
7337 api_sr_policy_add_del (vat_main_t * vam)
7338 {
7339   unformat_input_t *input = vam->input;
7340   vl_api_sr_policy_add_del_t *mp;
7341   f64 timeout;
7342   int is_del = 0;
7343   u8 *name = 0;
7344   u8 *tunnel_name = 0;
7345   u8 **tunnel_names = 0;
7346
7347   int name_set = 0;
7348   int tunnel_set = 0;
7349   int j = 0;
7350   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7351   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7352
7353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7354     {
7355       if (unformat (input, "del"))
7356         is_del = 1;
7357       else if (unformat (input, "name %s", &name))
7358         name_set = 1;
7359       else if (unformat (input, "tunnel %s", &tunnel_name))
7360         {
7361           if (tunnel_name)
7362             {
7363               vec_add1 (tunnel_names, tunnel_name);
7364               /* For serializer:
7365                  - length = #bytes to store in serial vector
7366                  - +1 = byte to store that length
7367                */
7368               tunnel_names_length += (vec_len (tunnel_name) + 1);
7369               tunnel_set = 1;
7370               tunnel_name = 0;
7371             }
7372         }
7373       else
7374         break;
7375     }
7376
7377   if (!name_set)
7378     {
7379       errmsg ("policy name required\n");
7380       return -99;
7381     }
7382
7383   if ((!tunnel_set) && (!is_del))
7384     {
7385       errmsg ("tunnel name required\n");
7386       return -99;
7387     }
7388
7389   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7390
7391
7392
7393   mp->is_add = !is_del;
7394
7395   memcpy (mp->name, name, vec_len (name));
7396   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7397   u8 *serial_orig = 0;
7398   vec_validate (serial_orig, tunnel_names_length);
7399   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7400   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7401
7402   for (j = 0; j < vec_len (tunnel_names); j++)
7403     {
7404       tun_name_len = vec_len (tunnel_names[j]);
7405       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7406       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7407       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7408       serial_orig += tun_name_len;      // Advance past the copy
7409     }
7410   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7411
7412   vec_free (tunnel_names);
7413   vec_free (tunnel_name);
7414
7415   S;
7416   W;
7417   /* NOTREACHED */
7418 }
7419
7420 static int
7421 api_sr_multicast_map_add_del (vat_main_t * vam)
7422 {
7423   unformat_input_t *input = vam->input;
7424   vl_api_sr_multicast_map_add_del_t *mp;
7425   f64 timeout;
7426   int is_del = 0;
7427   ip6_address_t multicast_address;
7428   u8 *policy_name = 0;
7429   int multicast_address_set = 0;
7430
7431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (input, "del"))
7434         is_del = 1;
7435       else
7436         if (unformat
7437             (input, "address %U", unformat_ip6_address, &multicast_address))
7438         multicast_address_set = 1;
7439       else if (unformat (input, "sr-policy %s", &policy_name))
7440         ;
7441       else
7442         break;
7443     }
7444
7445   if (!is_del && !policy_name)
7446     {
7447       errmsg ("sr-policy name required\n");
7448       return -99;
7449     }
7450
7451
7452   if (!multicast_address_set)
7453     {
7454       errmsg ("address required\n");
7455       return -99;
7456     }
7457
7458   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7459
7460   mp->is_add = !is_del;
7461   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7462   clib_memcpy (mp->multicast_address, &multicast_address,
7463                sizeof (mp->multicast_address));
7464
7465
7466   vec_free (policy_name);
7467
7468   S;
7469   W;
7470   /* NOTREACHED */
7471 }
7472
7473
7474 #define foreach_ip4_proto_field                 \
7475 _(src_address)                                  \
7476 _(dst_address)                                  \
7477 _(tos)                                          \
7478 _(length)                                       \
7479 _(fragment_id)                                  \
7480 _(ttl)                                          \
7481 _(protocol)                                     \
7482 _(checksum)
7483
7484 uword
7485 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7486 {
7487   u8 **maskp = va_arg (*args, u8 **);
7488   u8 *mask = 0;
7489   u8 found_something = 0;
7490   ip4_header_t *ip;
7491
7492 #define _(a) u8 a=0;
7493   foreach_ip4_proto_field;
7494 #undef _
7495   u8 version = 0;
7496   u8 hdr_length = 0;
7497
7498
7499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (input, "version"))
7502         version = 1;
7503       else if (unformat (input, "hdr_length"))
7504         hdr_length = 1;
7505       else if (unformat (input, "src"))
7506         src_address = 1;
7507       else if (unformat (input, "dst"))
7508         dst_address = 1;
7509       else if (unformat (input, "proto"))
7510         protocol = 1;
7511
7512 #define _(a) else if (unformat (input, #a)) a=1;
7513       foreach_ip4_proto_field
7514 #undef _
7515         else
7516         break;
7517     }
7518
7519 #define _(a) found_something += a;
7520   foreach_ip4_proto_field;
7521 #undef _
7522
7523   if (found_something == 0)
7524     return 0;
7525
7526   vec_validate (mask, sizeof (*ip) - 1);
7527
7528   ip = (ip4_header_t *) mask;
7529
7530 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7531   foreach_ip4_proto_field;
7532 #undef _
7533
7534   ip->ip_version_and_header_length = 0;
7535
7536   if (version)
7537     ip->ip_version_and_header_length |= 0xF0;
7538
7539   if (hdr_length)
7540     ip->ip_version_and_header_length |= 0x0F;
7541
7542   *maskp = mask;
7543   return 1;
7544 }
7545
7546 #define foreach_ip6_proto_field                 \
7547 _(src_address)                                  \
7548 _(dst_address)                                  \
7549 _(payload_length)                               \
7550 _(hop_limit)                                    \
7551 _(protocol)
7552
7553 uword
7554 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7555 {
7556   u8 **maskp = va_arg (*args, u8 **);
7557   u8 *mask = 0;
7558   u8 found_something = 0;
7559   ip6_header_t *ip;
7560   u32 ip_version_traffic_class_and_flow_label;
7561
7562 #define _(a) u8 a=0;
7563   foreach_ip6_proto_field;
7564 #undef _
7565   u8 version = 0;
7566   u8 traffic_class = 0;
7567   u8 flow_label = 0;
7568
7569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (unformat (input, "version"))
7572         version = 1;
7573       else if (unformat (input, "traffic-class"))
7574         traffic_class = 1;
7575       else if (unformat (input, "flow-label"))
7576         flow_label = 1;
7577       else if (unformat (input, "src"))
7578         src_address = 1;
7579       else if (unformat (input, "dst"))
7580         dst_address = 1;
7581       else if (unformat (input, "proto"))
7582         protocol = 1;
7583
7584 #define _(a) else if (unformat (input, #a)) a=1;
7585       foreach_ip6_proto_field
7586 #undef _
7587         else
7588         break;
7589     }
7590
7591 #define _(a) found_something += a;
7592   foreach_ip6_proto_field;
7593 #undef _
7594
7595   if (found_something == 0)
7596     return 0;
7597
7598   vec_validate (mask, sizeof (*ip) - 1);
7599
7600   ip = (ip6_header_t *) mask;
7601
7602 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7603   foreach_ip6_proto_field;
7604 #undef _
7605
7606   ip_version_traffic_class_and_flow_label = 0;
7607
7608   if (version)
7609     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7610
7611   if (traffic_class)
7612     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7613
7614   if (flow_label)
7615     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7616
7617   ip->ip_version_traffic_class_and_flow_label =
7618     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7619
7620   *maskp = mask;
7621   return 1;
7622 }
7623
7624 uword
7625 unformat_l3_mask (unformat_input_t * input, va_list * args)
7626 {
7627   u8 **maskp = va_arg (*args, u8 **);
7628
7629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7630     {
7631       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7632         return 1;
7633       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7634         return 1;
7635       else
7636         break;
7637     }
7638   return 0;
7639 }
7640
7641 uword
7642 unformat_l2_mask (unformat_input_t * input, va_list * args)
7643 {
7644   u8 **maskp = va_arg (*args, u8 **);
7645   u8 *mask = 0;
7646   u8 src = 0;
7647   u8 dst = 0;
7648   u8 proto = 0;
7649   u8 tag1 = 0;
7650   u8 tag2 = 0;
7651   u8 ignore_tag1 = 0;
7652   u8 ignore_tag2 = 0;
7653   u8 cos1 = 0;
7654   u8 cos2 = 0;
7655   u8 dot1q = 0;
7656   u8 dot1ad = 0;
7657   int len = 14;
7658
7659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7660     {
7661       if (unformat (input, "src"))
7662         src = 1;
7663       else if (unformat (input, "dst"))
7664         dst = 1;
7665       else if (unformat (input, "proto"))
7666         proto = 1;
7667       else if (unformat (input, "tag1"))
7668         tag1 = 1;
7669       else if (unformat (input, "tag2"))
7670         tag2 = 1;
7671       else if (unformat (input, "ignore-tag1"))
7672         ignore_tag1 = 1;
7673       else if (unformat (input, "ignore-tag2"))
7674         ignore_tag2 = 1;
7675       else if (unformat (input, "cos1"))
7676         cos1 = 1;
7677       else if (unformat (input, "cos2"))
7678         cos2 = 1;
7679       else if (unformat (input, "dot1q"))
7680         dot1q = 1;
7681       else if (unformat (input, "dot1ad"))
7682         dot1ad = 1;
7683       else
7684         break;
7685     }
7686   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7687        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7688     return 0;
7689
7690   if (tag1 || ignore_tag1 || cos1 || dot1q)
7691     len = 18;
7692   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7693     len = 22;
7694
7695   vec_validate (mask, len - 1);
7696
7697   if (dst)
7698     memset (mask, 0xff, 6);
7699
7700   if (src)
7701     memset (mask + 6, 0xff, 6);
7702
7703   if (tag2 || dot1ad)
7704     {
7705       /* inner vlan tag */
7706       if (tag2)
7707         {
7708           mask[19] = 0xff;
7709           mask[18] = 0x0f;
7710         }
7711       if (cos2)
7712         mask[18] |= 0xe0;
7713       if (proto)
7714         mask[21] = mask[20] = 0xff;
7715       if (tag1)
7716         {
7717           mask[15] = 0xff;
7718           mask[14] = 0x0f;
7719         }
7720       if (cos1)
7721         mask[14] |= 0xe0;
7722       *maskp = mask;
7723       return 1;
7724     }
7725   if (tag1 | dot1q)
7726     {
7727       if (tag1)
7728         {
7729           mask[15] = 0xff;
7730           mask[14] = 0x0f;
7731         }
7732       if (cos1)
7733         mask[14] |= 0xe0;
7734       if (proto)
7735         mask[16] = mask[17] = 0xff;
7736
7737       *maskp = mask;
7738       return 1;
7739     }
7740   if (cos2)
7741     mask[18] |= 0xe0;
7742   if (cos1)
7743     mask[14] |= 0xe0;
7744   if (proto)
7745     mask[12] = mask[13] = 0xff;
7746
7747   *maskp = mask;
7748   return 1;
7749 }
7750
7751 uword
7752 unformat_classify_mask (unformat_input_t * input, va_list * args)
7753 {
7754   u8 **maskp = va_arg (*args, u8 **);
7755   u32 *skipp = va_arg (*args, u32 *);
7756   u32 *matchp = va_arg (*args, u32 *);
7757   u32 match;
7758   u8 *mask = 0;
7759   u8 *l2 = 0;
7760   u8 *l3 = 0;
7761   int i;
7762
7763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7764     {
7765       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7766         ;
7767       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7768         ;
7769       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7770         ;
7771       else
7772         break;
7773     }
7774
7775   if (mask || l2 || l3)
7776     {
7777       if (l2 || l3)
7778         {
7779           /* "With a free Ethernet header in every package" */
7780           if (l2 == 0)
7781             vec_validate (l2, 13);
7782           mask = l2;
7783           if (vec_len (l3))
7784             {
7785               vec_append (mask, l3);
7786               vec_free (l3);
7787             }
7788         }
7789
7790       /* Scan forward looking for the first significant mask octet */
7791       for (i = 0; i < vec_len (mask); i++)
7792         if (mask[i])
7793           break;
7794
7795       /* compute (skip, match) params */
7796       *skipp = i / sizeof (u32x4);
7797       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7798
7799       /* Pad mask to an even multiple of the vector size */
7800       while (vec_len (mask) % sizeof (u32x4))
7801         vec_add1 (mask, 0);
7802
7803       match = vec_len (mask) / sizeof (u32x4);
7804
7805       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7806         {
7807           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7808           if (*tmp || *(tmp + 1))
7809             break;
7810           match--;
7811         }
7812       if (match == 0)
7813         clib_warning ("BUG: match 0");
7814
7815       _vec_len (mask) = match * sizeof (u32x4);
7816
7817       *matchp = match;
7818       *maskp = mask;
7819
7820       return 1;
7821     }
7822
7823   return 0;
7824 }
7825
7826 #define foreach_l2_next                         \
7827 _(drop, DROP)                                   \
7828 _(ethernet, ETHERNET_INPUT)                     \
7829 _(ip4, IP4_INPUT)                               \
7830 _(ip6, IP6_INPUT)
7831
7832 uword
7833 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7834 {
7835   u32 *miss_next_indexp = va_arg (*args, u32 *);
7836   u32 next_index = 0;
7837   u32 tmp;
7838
7839 #define _(n,N) \
7840   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7841   foreach_l2_next;
7842 #undef _
7843
7844   if (unformat (input, "%d", &tmp))
7845     {
7846       next_index = tmp;
7847       goto out;
7848     }
7849
7850   return 0;
7851
7852 out:
7853   *miss_next_indexp = next_index;
7854   return 1;
7855 }
7856
7857 #define foreach_ip_next                         \
7858 _(miss, MISS)                                   \
7859 _(drop, DROP)                                   \
7860 _(local, LOCAL)                                 \
7861 _(rewrite, REWRITE)
7862
7863 uword
7864 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7865 {
7866   u32 *miss_next_indexp = va_arg (*args, u32 *);
7867   u32 next_index = 0;
7868   u32 tmp;
7869
7870 #define _(n,N) \
7871   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7872   foreach_ip_next;
7873 #undef _
7874
7875   if (unformat (input, "%d", &tmp))
7876     {
7877       next_index = tmp;
7878       goto out;
7879     }
7880
7881   return 0;
7882
7883 out:
7884   *miss_next_indexp = next_index;
7885   return 1;
7886 }
7887
7888 #define foreach_acl_next                        \
7889 _(deny, DENY)
7890
7891 uword
7892 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7893 {
7894   u32 *miss_next_indexp = va_arg (*args, u32 *);
7895   u32 next_index = 0;
7896   u32 tmp;
7897
7898 #define _(n,N) \
7899   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7900   foreach_acl_next;
7901 #undef _
7902
7903   if (unformat (input, "permit"))
7904     {
7905       next_index = ~0;
7906       goto out;
7907     }
7908   else if (unformat (input, "%d", &tmp))
7909     {
7910       next_index = tmp;
7911       goto out;
7912     }
7913
7914   return 0;
7915
7916 out:
7917   *miss_next_indexp = next_index;
7918   return 1;
7919 }
7920
7921 uword
7922 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7923 {
7924   u32 *r = va_arg (*args, u32 *);
7925
7926   if (unformat (input, "conform-color"))
7927     *r = POLICE_CONFORM;
7928   else if (unformat (input, "exceed-color"))
7929     *r = POLICE_EXCEED;
7930   else
7931     return 0;
7932
7933   return 1;
7934 }
7935
7936 static int
7937 api_classify_add_del_table (vat_main_t * vam)
7938 {
7939   unformat_input_t *i = vam->input;
7940   vl_api_classify_add_del_table_t *mp;
7941
7942   u32 nbuckets = 2;
7943   u32 skip = ~0;
7944   u32 match = ~0;
7945   int is_add = 1;
7946   u32 table_index = ~0;
7947   u32 next_table_index = ~0;
7948   u32 miss_next_index = ~0;
7949   u32 memory_size = 32 << 20;
7950   u8 *mask = 0;
7951   f64 timeout;
7952
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "del"))
7956         is_add = 0;
7957       else if (unformat (i, "buckets %d", &nbuckets))
7958         ;
7959       else if (unformat (i, "memory_size %d", &memory_size))
7960         ;
7961       else if (unformat (i, "skip %d", &skip))
7962         ;
7963       else if (unformat (i, "match %d", &match))
7964         ;
7965       else if (unformat (i, "table %d", &table_index))
7966         ;
7967       else if (unformat (i, "mask %U", unformat_classify_mask,
7968                          &mask, &skip, &match))
7969         ;
7970       else if (unformat (i, "next-table %d", &next_table_index))
7971         ;
7972       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7973                          &miss_next_index))
7974         ;
7975       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7976                          &miss_next_index))
7977         ;
7978       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7979                          &miss_next_index))
7980         ;
7981       else
7982         break;
7983     }
7984
7985   if (is_add && mask == 0)
7986     {
7987       errmsg ("Mask required\n");
7988       return -99;
7989     }
7990
7991   if (is_add && skip == ~0)
7992     {
7993       errmsg ("skip count required\n");
7994       return -99;
7995     }
7996
7997   if (is_add && match == ~0)
7998     {
7999       errmsg ("match count required\n");
8000       return -99;
8001     }
8002
8003   if (!is_add && table_index == ~0)
8004     {
8005       errmsg ("table index required for delete\n");
8006       return -99;
8007     }
8008
8009   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8010
8011   mp->is_add = is_add;
8012   mp->table_index = ntohl (table_index);
8013   mp->nbuckets = ntohl (nbuckets);
8014   mp->memory_size = ntohl (memory_size);
8015   mp->skip_n_vectors = ntohl (skip);
8016   mp->match_n_vectors = ntohl (match);
8017   mp->next_table_index = ntohl (next_table_index);
8018   mp->miss_next_index = ntohl (miss_next_index);
8019   clib_memcpy (mp->mask, mask, vec_len (mask));
8020
8021   vec_free (mask);
8022
8023   S;
8024   W;
8025   /* NOTREACHED */
8026 }
8027
8028 uword
8029 unformat_ip4_match (unformat_input_t * input, va_list * args)
8030 {
8031   u8 **matchp = va_arg (*args, u8 **);
8032   u8 *match = 0;
8033   ip4_header_t *ip;
8034   int version = 0;
8035   u32 version_val;
8036   int hdr_length = 0;
8037   u32 hdr_length_val;
8038   int src = 0, dst = 0;
8039   ip4_address_t src_val, dst_val;
8040   int proto = 0;
8041   u32 proto_val;
8042   int tos = 0;
8043   u32 tos_val;
8044   int length = 0;
8045   u32 length_val;
8046   int fragment_id = 0;
8047   u32 fragment_id_val;
8048   int ttl = 0;
8049   int ttl_val;
8050   int checksum = 0;
8051   u32 checksum_val;
8052
8053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (input, "version %d", &version_val))
8056         version = 1;
8057       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8058         hdr_length = 1;
8059       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8060         src = 1;
8061       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8062         dst = 1;
8063       else if (unformat (input, "proto %d", &proto_val))
8064         proto = 1;
8065       else if (unformat (input, "tos %d", &tos_val))
8066         tos = 1;
8067       else if (unformat (input, "length %d", &length_val))
8068         length = 1;
8069       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8070         fragment_id = 1;
8071       else if (unformat (input, "ttl %d", &ttl_val))
8072         ttl = 1;
8073       else if (unformat (input, "checksum %d", &checksum_val))
8074         checksum = 1;
8075       else
8076         break;
8077     }
8078
8079   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8080       + ttl + checksum == 0)
8081     return 0;
8082
8083   /*
8084    * Aligned because we use the real comparison functions
8085    */
8086   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8087
8088   ip = (ip4_header_t *) match;
8089
8090   /* These are realistically matched in practice */
8091   if (src)
8092     ip->src_address.as_u32 = src_val.as_u32;
8093
8094   if (dst)
8095     ip->dst_address.as_u32 = dst_val.as_u32;
8096
8097   if (proto)
8098     ip->protocol = proto_val;
8099
8100
8101   /* These are not, but they're included for completeness */
8102   if (version)
8103     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8104
8105   if (hdr_length)
8106     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8107
8108   if (tos)
8109     ip->tos = tos_val;
8110
8111   if (length)
8112     ip->length = length_val;
8113
8114   if (ttl)
8115     ip->ttl = ttl_val;
8116
8117   if (checksum)
8118     ip->checksum = checksum_val;
8119
8120   *matchp = match;
8121   return 1;
8122 }
8123
8124 uword
8125 unformat_ip6_match (unformat_input_t * input, va_list * args)
8126 {
8127   u8 **matchp = va_arg (*args, u8 **);
8128   u8 *match = 0;
8129   ip6_header_t *ip;
8130   int version = 0;
8131   u32 version_val;
8132   u8 traffic_class = 0;
8133   u32 traffic_class_val = 0;
8134   u8 flow_label = 0;
8135   u8 flow_label_val;
8136   int src = 0, dst = 0;
8137   ip6_address_t src_val, dst_val;
8138   int proto = 0;
8139   u32 proto_val;
8140   int payload_length = 0;
8141   u32 payload_length_val;
8142   int hop_limit = 0;
8143   int hop_limit_val;
8144   u32 ip_version_traffic_class_and_flow_label;
8145
8146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8147     {
8148       if (unformat (input, "version %d", &version_val))
8149         version = 1;
8150       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8151         traffic_class = 1;
8152       else if (unformat (input, "flow_label %d", &flow_label_val))
8153         flow_label = 1;
8154       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8155         src = 1;
8156       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8157         dst = 1;
8158       else if (unformat (input, "proto %d", &proto_val))
8159         proto = 1;
8160       else if (unformat (input, "payload_length %d", &payload_length_val))
8161         payload_length = 1;
8162       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8163         hop_limit = 1;
8164       else
8165         break;
8166     }
8167
8168   if (version + traffic_class + flow_label + src + dst + proto +
8169       payload_length + hop_limit == 0)
8170     return 0;
8171
8172   /*
8173    * Aligned because we use the real comparison functions
8174    */
8175   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8176
8177   ip = (ip6_header_t *) match;
8178
8179   if (src)
8180     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8181
8182   if (dst)
8183     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8184
8185   if (proto)
8186     ip->protocol = proto_val;
8187
8188   ip_version_traffic_class_and_flow_label = 0;
8189
8190   if (version)
8191     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8192
8193   if (traffic_class)
8194     ip_version_traffic_class_and_flow_label |=
8195       (traffic_class_val & 0xFF) << 20;
8196
8197   if (flow_label)
8198     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8199
8200   ip->ip_version_traffic_class_and_flow_label =
8201     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8202
8203   if (payload_length)
8204     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8205
8206   if (hop_limit)
8207     ip->hop_limit = hop_limit_val;
8208
8209   *matchp = match;
8210   return 1;
8211 }
8212
8213 uword
8214 unformat_l3_match (unformat_input_t * input, va_list * args)
8215 {
8216   u8 **matchp = va_arg (*args, u8 **);
8217
8218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8219     {
8220       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8221         return 1;
8222       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8223         return 1;
8224       else
8225         break;
8226     }
8227   return 0;
8228 }
8229
8230 uword
8231 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8232 {
8233   u8 *tagp = va_arg (*args, u8 *);
8234   u32 tag;
8235
8236   if (unformat (input, "%d", &tag))
8237     {
8238       tagp[0] = (tag >> 8) & 0x0F;
8239       tagp[1] = tag & 0xFF;
8240       return 1;
8241     }
8242
8243   return 0;
8244 }
8245
8246 uword
8247 unformat_l2_match (unformat_input_t * input, va_list * args)
8248 {
8249   u8 **matchp = va_arg (*args, u8 **);
8250   u8 *match = 0;
8251   u8 src = 0;
8252   u8 src_val[6];
8253   u8 dst = 0;
8254   u8 dst_val[6];
8255   u8 proto = 0;
8256   u16 proto_val;
8257   u8 tag1 = 0;
8258   u8 tag1_val[2];
8259   u8 tag2 = 0;
8260   u8 tag2_val[2];
8261   int len = 14;
8262   u8 ignore_tag1 = 0;
8263   u8 ignore_tag2 = 0;
8264   u8 cos1 = 0;
8265   u8 cos2 = 0;
8266   u32 cos1_val = 0;
8267   u32 cos2_val = 0;
8268
8269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8270     {
8271       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8272         src = 1;
8273       else
8274         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8275         dst = 1;
8276       else if (unformat (input, "proto %U",
8277                          unformat_ethernet_type_host_byte_order, &proto_val))
8278         proto = 1;
8279       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8280         tag1 = 1;
8281       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8282         tag2 = 1;
8283       else if (unformat (input, "ignore-tag1"))
8284         ignore_tag1 = 1;
8285       else if (unformat (input, "ignore-tag2"))
8286         ignore_tag2 = 1;
8287       else if (unformat (input, "cos1 %d", &cos1_val))
8288         cos1 = 1;
8289       else if (unformat (input, "cos2 %d", &cos2_val))
8290         cos2 = 1;
8291       else
8292         break;
8293     }
8294   if ((src + dst + proto + tag1 + tag2 +
8295        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8296     return 0;
8297
8298   if (tag1 || ignore_tag1 || cos1)
8299     len = 18;
8300   if (tag2 || ignore_tag2 || cos2)
8301     len = 22;
8302
8303   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8304
8305   if (dst)
8306     clib_memcpy (match, dst_val, 6);
8307
8308   if (src)
8309     clib_memcpy (match + 6, src_val, 6);
8310
8311   if (tag2)
8312     {
8313       /* inner vlan tag */
8314       match[19] = tag2_val[1];
8315       match[18] = tag2_val[0];
8316       if (cos2)
8317         match[18] |= (cos2_val & 0x7) << 5;
8318       if (proto)
8319         {
8320           match[21] = proto_val & 0xff;
8321           match[20] = proto_val >> 8;
8322         }
8323       if (tag1)
8324         {
8325           match[15] = tag1_val[1];
8326           match[14] = tag1_val[0];
8327         }
8328       if (cos1)
8329         match[14] |= (cos1_val & 0x7) << 5;
8330       *matchp = match;
8331       return 1;
8332     }
8333   if (tag1)
8334     {
8335       match[15] = tag1_val[1];
8336       match[14] = tag1_val[0];
8337       if (proto)
8338         {
8339           match[17] = proto_val & 0xff;
8340           match[16] = proto_val >> 8;
8341         }
8342       if (cos1)
8343         match[14] |= (cos1_val & 0x7) << 5;
8344
8345       *matchp = match;
8346       return 1;
8347     }
8348   if (cos2)
8349     match[18] |= (cos2_val & 0x7) << 5;
8350   if (cos1)
8351     match[14] |= (cos1_val & 0x7) << 5;
8352   if (proto)
8353     {
8354       match[13] = proto_val & 0xff;
8355       match[12] = proto_val >> 8;
8356     }
8357
8358   *matchp = match;
8359   return 1;
8360 }
8361
8362
8363 uword
8364 unformat_classify_match (unformat_input_t * input, va_list * args)
8365 {
8366   u8 **matchp = va_arg (*args, u8 **);
8367   u32 skip_n_vectors = va_arg (*args, u32);
8368   u32 match_n_vectors = va_arg (*args, u32);
8369
8370   u8 *match = 0;
8371   u8 *l2 = 0;
8372   u8 *l3 = 0;
8373
8374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8375     {
8376       if (unformat (input, "hex %U", unformat_hex_string, &match))
8377         ;
8378       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8379         ;
8380       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8381         ;
8382       else
8383         break;
8384     }
8385
8386   if (match || l2 || l3)
8387     {
8388       if (l2 || l3)
8389         {
8390           /* "Win a free Ethernet header in every packet" */
8391           if (l2 == 0)
8392             vec_validate_aligned (l2, 13, sizeof (u32x4));
8393           match = l2;
8394           if (vec_len (l3))
8395             {
8396               vec_append_aligned (match, l3, sizeof (u32x4));
8397               vec_free (l3);
8398             }
8399         }
8400
8401       /* Make sure the vector is big enough even if key is all 0's */
8402       vec_validate_aligned
8403         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8404          sizeof (u32x4));
8405
8406       /* Set size, include skipped vectors */
8407       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8408
8409       *matchp = match;
8410
8411       return 1;
8412     }
8413
8414   return 0;
8415 }
8416
8417 static int
8418 api_classify_add_del_session (vat_main_t * vam)
8419 {
8420   unformat_input_t *i = vam->input;
8421   vl_api_classify_add_del_session_t *mp;
8422   int is_add = 1;
8423   u32 table_index = ~0;
8424   u32 hit_next_index = ~0;
8425   u32 opaque_index = ~0;
8426   u8 *match = 0;
8427   i32 advance = 0;
8428   f64 timeout;
8429   u32 skip_n_vectors = 0;
8430   u32 match_n_vectors = 0;
8431
8432   /*
8433    * Warning: you have to supply skip_n and match_n
8434    * because the API client cant simply look at the classify
8435    * table object.
8436    */
8437
8438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8439     {
8440       if (unformat (i, "del"))
8441         is_add = 0;
8442       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8443                          &hit_next_index))
8444         ;
8445       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8446                          &hit_next_index))
8447         ;
8448       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8449                          &hit_next_index))
8450         ;
8451       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8452         ;
8453       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8454         ;
8455       else if (unformat (i, "opaque-index %d", &opaque_index))
8456         ;
8457       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8458         ;
8459       else if (unformat (i, "match_n %d", &match_n_vectors))
8460         ;
8461       else if (unformat (i, "match %U", unformat_classify_match,
8462                          &match, skip_n_vectors, match_n_vectors))
8463         ;
8464       else if (unformat (i, "advance %d", &advance))
8465         ;
8466       else if (unformat (i, "table-index %d", &table_index))
8467         ;
8468       else
8469         break;
8470     }
8471
8472   if (table_index == ~0)
8473     {
8474       errmsg ("Table index required\n");
8475       return -99;
8476     }
8477
8478   if (is_add && match == 0)
8479     {
8480       errmsg ("Match value required\n");
8481       return -99;
8482     }
8483
8484   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8485
8486   mp->is_add = is_add;
8487   mp->table_index = ntohl (table_index);
8488   mp->hit_next_index = ntohl (hit_next_index);
8489   mp->opaque_index = ntohl (opaque_index);
8490   mp->advance = ntohl (advance);
8491   clib_memcpy (mp->match, match, vec_len (match));
8492   vec_free (match);
8493
8494   S;
8495   W;
8496   /* NOTREACHED */
8497 }
8498
8499 static int
8500 api_classify_set_interface_ip_table (vat_main_t * vam)
8501 {
8502   unformat_input_t *i = vam->input;
8503   vl_api_classify_set_interface_ip_table_t *mp;
8504   f64 timeout;
8505   u32 sw_if_index;
8506   int sw_if_index_set;
8507   u32 table_index = ~0;
8508   u8 is_ipv6 = 0;
8509
8510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8511     {
8512       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8513         sw_if_index_set = 1;
8514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8515         sw_if_index_set = 1;
8516       else if (unformat (i, "table %d", &table_index))
8517         ;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (sw_if_index_set == 0)
8526     {
8527       errmsg ("missing interface name or sw_if_index\n");
8528       return -99;
8529     }
8530
8531
8532   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8533
8534   mp->sw_if_index = ntohl (sw_if_index);
8535   mp->table_index = ntohl (table_index);
8536   mp->is_ipv6 = is_ipv6;
8537
8538   S;
8539   W;
8540   /* NOTREACHED */
8541   return 0;
8542 }
8543
8544 static int
8545 api_classify_set_interface_l2_tables (vat_main_t * vam)
8546 {
8547   unformat_input_t *i = vam->input;
8548   vl_api_classify_set_interface_l2_tables_t *mp;
8549   f64 timeout;
8550   u32 sw_if_index;
8551   int sw_if_index_set;
8552   u32 ip4_table_index = ~0;
8553   u32 ip6_table_index = ~0;
8554   u32 other_table_index = ~0;
8555
8556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8559         sw_if_index_set = 1;
8560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8561         sw_if_index_set = 1;
8562       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8563         ;
8564       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8565         ;
8566       else if (unformat (i, "other-table %d", &other_table_index))
8567         ;
8568       else
8569         {
8570           clib_warning ("parse error '%U'", format_unformat_error, i);
8571           return -99;
8572         }
8573     }
8574
8575   if (sw_if_index_set == 0)
8576     {
8577       errmsg ("missing interface name or sw_if_index\n");
8578       return -99;
8579     }
8580
8581
8582   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8583
8584   mp->sw_if_index = ntohl (sw_if_index);
8585   mp->ip4_table_index = ntohl (ip4_table_index);
8586   mp->ip6_table_index = ntohl (ip6_table_index);
8587   mp->other_table_index = ntohl (other_table_index);
8588
8589
8590   S;
8591   W;
8592   /* NOTREACHED */
8593   return 0;
8594 }
8595
8596 static int
8597 api_ipfix_enable (vat_main_t * vam)
8598 {
8599   unformat_input_t *i = vam->input;
8600   vl_api_ipfix_enable_t *mp;
8601   ip4_address_t collector_address;
8602   u8 collector_address_set = 0;
8603   u32 collector_port = ~0;
8604   ip4_address_t src_address;
8605   u8 src_address_set = 0;
8606   u32 vrf_id = ~0;
8607   u32 path_mtu = ~0;
8608   u32 template_interval = ~0;
8609   f64 timeout;
8610
8611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8612     {
8613       if (unformat (i, "collector_address %U", unformat_ip4_address,
8614                     &collector_address))
8615         collector_address_set = 1;
8616       else if (unformat (i, "collector_port %d", &collector_port))
8617         ;
8618       else if (unformat (i, "src_address %U", unformat_ip4_address,
8619                          &src_address))
8620         src_address_set = 1;
8621       else if (unformat (i, "vrf_id %d", &vrf_id))
8622         ;
8623       else if (unformat (i, "path_mtu %d", &path_mtu))
8624         ;
8625       else if (unformat (i, "template_interval %d", &template_interval))
8626         ;
8627       else
8628         break;
8629     }
8630
8631   if (collector_address_set == 0)
8632     {
8633       errmsg ("collector_address required\n");
8634       return -99;
8635     }
8636
8637   if (src_address_set == 0)
8638     {
8639       errmsg ("src_address required\n");
8640       return -99;
8641     }
8642
8643   M (IPFIX_ENABLE, ipfix_enable);
8644
8645   memcpy (mp->collector_address, collector_address.data,
8646           sizeof (collector_address.data));
8647   mp->collector_port = htons ((u16) collector_port);
8648   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8649   mp->vrf_id = htonl (vrf_id);
8650   mp->path_mtu = htonl (path_mtu);
8651   mp->template_interval = htonl (template_interval);
8652
8653   S;
8654   W;
8655   /* NOTREACHED */
8656 }
8657
8658 static int
8659 api_get_node_index (vat_main_t * vam)
8660 {
8661   unformat_input_t *i = vam->input;
8662   vl_api_get_node_index_t *mp;
8663   f64 timeout;
8664   u8 *name = 0;
8665
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "node %s", &name))
8669         ;
8670       else
8671         break;
8672     }
8673   if (name == 0)
8674     {
8675       errmsg ("node name required\n");
8676       return -99;
8677     }
8678   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8679     {
8680       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8681       return -99;
8682     }
8683
8684   M (GET_NODE_INDEX, get_node_index);
8685   clib_memcpy (mp->node_name, name, vec_len (name));
8686   vec_free (name);
8687
8688   S;
8689   W;
8690   /* NOTREACHED */
8691   return 0;
8692 }
8693
8694 static int
8695 api_get_next_index (vat_main_t * vam)
8696 {
8697   unformat_input_t *i = vam->input;
8698   vl_api_get_next_index_t *mp;
8699   f64 timeout;
8700   u8 *node_name = 0, *next_node_name = 0;
8701
8702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (i, "node-name %s", &node_name))
8705         ;
8706       else if (unformat (i, "next-node-name %s", &next_node_name))
8707         break;
8708     }
8709
8710   if (node_name == 0)
8711     {
8712       errmsg ("node name required\n");
8713       return -99;
8714     }
8715   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8716     {
8717       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8718       return -99;
8719     }
8720
8721   if (next_node_name == 0)
8722     {
8723       errmsg ("next node name required\n");
8724       return -99;
8725     }
8726   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8727     {
8728       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8729       return -99;
8730     }
8731
8732   M (GET_NEXT_INDEX, get_next_index);
8733   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8734   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8735   vec_free (node_name);
8736   vec_free (next_node_name);
8737
8738   S;
8739   W;
8740   /* NOTREACHED */
8741   return 0;
8742 }
8743
8744 static int
8745 api_add_node_next (vat_main_t * vam)
8746 {
8747   unformat_input_t *i = vam->input;
8748   vl_api_add_node_next_t *mp;
8749   f64 timeout;
8750   u8 *name = 0;
8751   u8 *next = 0;
8752
8753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8754     {
8755       if (unformat (i, "node %s", &name))
8756         ;
8757       else if (unformat (i, "next %s", &next))
8758         ;
8759       else
8760         break;
8761     }
8762   if (name == 0)
8763     {
8764       errmsg ("node name required\n");
8765       return -99;
8766     }
8767   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8768     {
8769       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8770       return -99;
8771     }
8772   if (next == 0)
8773     {
8774       errmsg ("next node required\n");
8775       return -99;
8776     }
8777   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8778     {
8779       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8780       return -99;
8781     }
8782
8783   M (ADD_NODE_NEXT, add_node_next);
8784   clib_memcpy (mp->node_name, name, vec_len (name));
8785   clib_memcpy (mp->next_name, next, vec_len (next));
8786   vec_free (name);
8787   vec_free (next);
8788
8789   S;
8790   W;
8791   /* NOTREACHED */
8792   return 0;
8793 }
8794
8795 static int
8796 api_l2tpv3_create_tunnel (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   ip6_address_t client_address, our_address;
8800   int client_address_set = 0;
8801   int our_address_set = 0;
8802   u32 local_session_id = 0;
8803   u32 remote_session_id = 0;
8804   u64 local_cookie = 0;
8805   u64 remote_cookie = 0;
8806   u8 l2_sublayer_present = 0;
8807   vl_api_l2tpv3_create_tunnel_t *mp;
8808   f64 timeout;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "client_address %U", unformat_ip6_address,
8813                     &client_address))
8814         client_address_set = 1;
8815       else if (unformat (i, "our_address %U", unformat_ip6_address,
8816                          &our_address))
8817         our_address_set = 1;
8818       else if (unformat (i, "local_session_id %d", &local_session_id))
8819         ;
8820       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8821         ;
8822       else if (unformat (i, "local_cookie %lld", &local_cookie))
8823         ;
8824       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8825         ;
8826       else if (unformat (i, "l2-sublayer-present"))
8827         l2_sublayer_present = 1;
8828       else
8829         break;
8830     }
8831
8832   if (client_address_set == 0)
8833     {
8834       errmsg ("client_address required\n");
8835       return -99;
8836     }
8837
8838   if (our_address_set == 0)
8839     {
8840       errmsg ("our_address required\n");
8841       return -99;
8842     }
8843
8844   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8845
8846   clib_memcpy (mp->client_address, client_address.as_u8,
8847                sizeof (mp->client_address));
8848
8849   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8850
8851   mp->local_session_id = ntohl (local_session_id);
8852   mp->remote_session_id = ntohl (remote_session_id);
8853   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8854   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8855   mp->l2_sublayer_present = l2_sublayer_present;
8856   mp->is_ipv6 = 1;
8857
8858   S;
8859   W;
8860   /* NOTREACHED */
8861   return 0;
8862 }
8863
8864 static int
8865 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8866 {
8867   unformat_input_t *i = vam->input;
8868   u32 sw_if_index;
8869   u8 sw_if_index_set = 0;
8870   u64 new_local_cookie = 0;
8871   u64 new_remote_cookie = 0;
8872   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8873   f64 timeout;
8874
8875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8876     {
8877       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8878         sw_if_index_set = 1;
8879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8880         sw_if_index_set = 1;
8881       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8882         ;
8883       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8884         ;
8885       else
8886         break;
8887     }
8888
8889   if (sw_if_index_set == 0)
8890     {
8891       errmsg ("missing interface name or sw_if_index\n");
8892       return -99;
8893     }
8894
8895   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8896
8897   mp->sw_if_index = ntohl (sw_if_index);
8898   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8899   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8900
8901   S;
8902   W;
8903   /* NOTREACHED */
8904   return 0;
8905 }
8906
8907 static int
8908 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_l2tpv3_interface_enable_disable_t *mp;
8912   f64 timeout;
8913   u32 sw_if_index;
8914   u8 sw_if_index_set = 0;
8915   u8 enable_disable = 1;
8916
8917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8918     {
8919       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8920         sw_if_index_set = 1;
8921       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8922         sw_if_index_set = 1;
8923       else if (unformat (i, "enable"))
8924         enable_disable = 1;
8925       else if (unformat (i, "disable"))
8926         enable_disable = 0;
8927       else
8928         break;
8929     }
8930
8931   if (sw_if_index_set == 0)
8932     {
8933       errmsg ("missing interface name or sw_if_index\n");
8934       return -99;
8935     }
8936
8937   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8938
8939   mp->sw_if_index = ntohl (sw_if_index);
8940   mp->enable_disable = enable_disable;
8941
8942   S;
8943   W;
8944   /* NOTREACHED */
8945   return 0;
8946 }
8947
8948 static int
8949 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_l2tpv3_set_lookup_key_t *mp;
8953   f64 timeout;
8954   u8 key = ~0;
8955
8956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8957     {
8958       if (unformat (i, "lookup_v6_src"))
8959         key = L2T_LOOKUP_SRC_ADDRESS;
8960       else if (unformat (i, "lookup_v6_dst"))
8961         key = L2T_LOOKUP_DST_ADDRESS;
8962       else if (unformat (i, "lookup_session_id"))
8963         key = L2T_LOOKUP_SESSION_ID;
8964       else
8965         break;
8966     }
8967
8968   if (key == (u8) ~ 0)
8969     {
8970       errmsg ("l2tp session lookup key unset\n");
8971       return -99;
8972     }
8973
8974   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8975
8976   mp->key = key;
8977
8978   S;
8979   W;
8980   /* NOTREACHED */
8981   return 0;
8982 }
8983
8984 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8985   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8986 {
8987   vat_main_t *vam = &vat_main;
8988
8989   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8990            format_ip6_address, mp->our_address,
8991            format_ip6_address, mp->client_address,
8992            clib_net_to_host_u32 (mp->sw_if_index));
8993
8994   fformat (vam->ofp,
8995            "   local cookies %016llx %016llx remote cookie %016llx\n",
8996            clib_net_to_host_u64 (mp->local_cookie[0]),
8997            clib_net_to_host_u64 (mp->local_cookie[1]),
8998            clib_net_to_host_u64 (mp->remote_cookie));
8999
9000   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9001            clib_net_to_host_u32 (mp->local_session_id),
9002            clib_net_to_host_u32 (mp->remote_session_id));
9003
9004   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9005            mp->l2_sublayer_present ? "preset" : "absent");
9006
9007 }
9008
9009 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9010   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9011 {
9012   vat_main_t *vam = &vat_main;
9013   vat_json_node_t *node = NULL;
9014   struct in6_addr addr;
9015
9016   if (VAT_JSON_ARRAY != vam->json_tree.type)
9017     {
9018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9019       vat_json_init_array (&vam->json_tree);
9020     }
9021   node = vat_json_array_add (&vam->json_tree);
9022
9023   vat_json_init_object (node);
9024
9025   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9026   vat_json_object_add_ip6 (node, "our_address", addr);
9027   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9028   vat_json_object_add_ip6 (node, "client_address", addr);
9029
9030   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9031   vat_json_init_array (lc);
9032   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9033   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9034   vat_json_object_add_uint (node, "remote_cookie",
9035                             clib_net_to_host_u64 (mp->remote_cookie));
9036
9037   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9038   vat_json_object_add_uint (node, "local_session_id",
9039                             clib_net_to_host_u32 (mp->local_session_id));
9040   vat_json_object_add_uint (node, "remote_session_id",
9041                             clib_net_to_host_u32 (mp->remote_session_id));
9042   vat_json_object_add_string_copy (node, "l2_sublayer",
9043                                    mp->l2_sublayer_present ? (u8 *) "present"
9044                                    : (u8 *) "absent");
9045 }
9046
9047 static int
9048 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9049 {
9050   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9051   f64 timeout;
9052
9053   /* Get list of l2tpv3-tunnel interfaces */
9054   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9055   S;
9056
9057   /* Use a control ping for synchronization */
9058   {
9059     vl_api_control_ping_t *mp;
9060     M (CONTROL_PING, control_ping);
9061     S;
9062   }
9063   W;
9064 }
9065
9066
9067 static void vl_api_sw_interface_tap_details_t_handler
9068   (vl_api_sw_interface_tap_details_t * mp)
9069 {
9070   vat_main_t *vam = &vat_main;
9071
9072   fformat (vam->ofp, "%-16s %d\n",
9073            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9074 }
9075
9076 static void vl_api_sw_interface_tap_details_t_handler_json
9077   (vl_api_sw_interface_tap_details_t * mp)
9078 {
9079   vat_main_t *vam = &vat_main;
9080   vat_json_node_t *node = NULL;
9081
9082   if (VAT_JSON_ARRAY != vam->json_tree.type)
9083     {
9084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9085       vat_json_init_array (&vam->json_tree);
9086     }
9087   node = vat_json_array_add (&vam->json_tree);
9088
9089   vat_json_init_object (node);
9090   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9091   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9092 }
9093
9094 static int
9095 api_sw_interface_tap_dump (vat_main_t * vam)
9096 {
9097   vl_api_sw_interface_tap_dump_t *mp;
9098   f64 timeout;
9099
9100   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9101   /* Get list of tap interfaces */
9102   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9103   S;
9104
9105   /* Use a control ping for synchronization */
9106   {
9107     vl_api_control_ping_t *mp;
9108     M (CONTROL_PING, control_ping);
9109     S;
9110   }
9111   W;
9112 }
9113
9114 static uword unformat_vxlan_decap_next
9115   (unformat_input_t * input, va_list * args)
9116 {
9117   u32 *result = va_arg (*args, u32 *);
9118   u32 tmp;
9119
9120   if (unformat (input, "drop"))
9121     *result = VXLAN_INPUT_NEXT_DROP;
9122   else if (unformat (input, "ip4"))
9123     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9124   else if (unformat (input, "ip6"))
9125     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9126   else if (unformat (input, "l2"))
9127     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9128   else if (unformat (input, "%d", &tmp))
9129     *result = tmp;
9130   else
9131     return 0;
9132   return 1;
9133 }
9134
9135 static int
9136 api_vxlan_add_del_tunnel (vat_main_t * vam)
9137 {
9138   unformat_input_t *line_input = vam->input;
9139   vl_api_vxlan_add_del_tunnel_t *mp;
9140   f64 timeout;
9141   ip4_address_t src4, dst4;
9142   ip6_address_t src6, dst6;
9143   u8 is_add = 1;
9144   u8 ipv4_set = 0, ipv6_set = 0;
9145   u8 src_set = 0;
9146   u8 dst_set = 0;
9147   u32 encap_vrf_id = 0;
9148   u32 decap_next_index = ~0;
9149   u32 vni = 0;
9150
9151   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9152     {
9153       if (unformat (line_input, "del"))
9154         is_add = 0;
9155       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9156         {
9157           ipv4_set = 1;
9158           src_set = 1;
9159         }
9160       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9161         {
9162           ipv4_set = 1;
9163           dst_set = 1;
9164         }
9165       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9166         {
9167           ipv6_set = 1;
9168           src_set = 1;
9169         }
9170       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9171         {
9172           ipv6_set = 1;
9173           dst_set = 1;
9174         }
9175       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9176         ;
9177       else if (unformat (line_input, "decap-next %U",
9178                          unformat_vxlan_decap_next, &decap_next_index))
9179         ;
9180       else if (unformat (line_input, "vni %d", &vni))
9181         ;
9182       else
9183         {
9184           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9185           return -99;
9186         }
9187     }
9188
9189   if (src_set == 0)
9190     {
9191       errmsg ("tunnel src address not specified\n");
9192       return -99;
9193     }
9194   if (dst_set == 0)
9195     {
9196       errmsg ("tunnel dst address not specified\n");
9197       return -99;
9198     }
9199
9200   if (ipv4_set && ipv6_set)
9201     {
9202       errmsg ("both IPv4 and IPv6 addresses specified");
9203       return -99;
9204     }
9205
9206   if ((vni == 0) || (vni >> 24))
9207     {
9208       errmsg ("vni not specified or out of range\n");
9209       return -99;
9210     }
9211
9212   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9213
9214   if (ipv6_set)
9215     {
9216       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9217       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9218     }
9219   else
9220     {
9221       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9222       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9223     }
9224   mp->encap_vrf_id = ntohl (encap_vrf_id);
9225   mp->decap_next_index = ntohl (decap_next_index);
9226   mp->vni = ntohl (vni);
9227   mp->is_add = is_add;
9228   mp->is_ipv6 = ipv6_set;
9229
9230   S;
9231   W;
9232   /* NOTREACHED */
9233   return 0;
9234 }
9235
9236 static void vl_api_vxlan_tunnel_details_t_handler
9237   (vl_api_vxlan_tunnel_details_t * mp)
9238 {
9239   vat_main_t *vam = &vat_main;
9240
9241   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9242            ntohl (mp->sw_if_index),
9243            format_ip46_address, &(mp->src_address[0]),
9244            IP46_TYPE_ANY,
9245            format_ip46_address, &(mp->dst_address[0]),
9246            IP46_TYPE_ANY,
9247            ntohl (mp->encap_vrf_id),
9248            ntohl (mp->decap_next_index), ntohl (mp->vni));
9249 }
9250
9251 static void vl_api_vxlan_tunnel_details_t_handler_json
9252   (vl_api_vxlan_tunnel_details_t * mp)
9253 {
9254   vat_main_t *vam = &vat_main;
9255   vat_json_node_t *node = NULL;
9256   struct in_addr ip4;
9257   struct in6_addr ip6;
9258
9259   if (VAT_JSON_ARRAY != vam->json_tree.type)
9260     {
9261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9262       vat_json_init_array (&vam->json_tree);
9263     }
9264   node = vat_json_array_add (&vam->json_tree);
9265
9266   vat_json_init_object (node);
9267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9268   if (mp->is_ipv6)
9269     {
9270       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9271       vat_json_object_add_ip6 (node, "src_address", ip6);
9272       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9273       vat_json_object_add_ip6 (node, "dst_address", ip6);
9274     }
9275   else
9276     {
9277       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9278       vat_json_object_add_ip4 (node, "src_address", ip4);
9279       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9280       vat_json_object_add_ip4 (node, "dst_address", ip4);
9281     }
9282   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9283   vat_json_object_add_uint (node, "decap_next_index",
9284                             ntohl (mp->decap_next_index));
9285   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9286   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9287 }
9288
9289 static int
9290 api_vxlan_tunnel_dump (vat_main_t * vam)
9291 {
9292   unformat_input_t *i = vam->input;
9293   vl_api_vxlan_tunnel_dump_t *mp;
9294   f64 timeout;
9295   u32 sw_if_index;
9296   u8 sw_if_index_set = 0;
9297
9298   /* Parse args required to build the message */
9299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9300     {
9301       if (unformat (i, "sw_if_index %d", &sw_if_index))
9302         sw_if_index_set = 1;
9303       else
9304         break;
9305     }
9306
9307   if (sw_if_index_set == 0)
9308     {
9309       sw_if_index = ~0;
9310     }
9311
9312   if (!vam->json_output)
9313     {
9314       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9315                "sw_if_index", "src_address", "dst_address",
9316                "encap_vrf_id", "decap_next_index", "vni");
9317     }
9318
9319   /* Get list of vxlan-tunnel interfaces */
9320   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9321
9322   mp->sw_if_index = htonl (sw_if_index);
9323
9324   S;
9325
9326   /* Use a control ping for synchronization */
9327   {
9328     vl_api_control_ping_t *mp;
9329     M (CONTROL_PING, control_ping);
9330     S;
9331   }
9332   W;
9333 }
9334
9335 static int
9336 api_gre_add_del_tunnel (vat_main_t * vam)
9337 {
9338   unformat_input_t *line_input = vam->input;
9339   vl_api_gre_add_del_tunnel_t *mp;
9340   f64 timeout;
9341   ip4_address_t src4, dst4;
9342   u8 is_add = 1;
9343   u8 src_set = 0;
9344   u8 dst_set = 0;
9345   u32 outer_fib_id = 0;
9346
9347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9348     {
9349       if (unformat (line_input, "del"))
9350         is_add = 0;
9351       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9352         src_set = 1;
9353       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9354         dst_set = 1;
9355       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9356         ;
9357       else
9358         {
9359           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9360           return -99;
9361         }
9362     }
9363
9364   if (src_set == 0)
9365     {
9366       errmsg ("tunnel src address not specified\n");
9367       return -99;
9368     }
9369   if (dst_set == 0)
9370     {
9371       errmsg ("tunnel dst address not specified\n");
9372       return -99;
9373     }
9374
9375
9376   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9377
9378   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9379   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9380   mp->outer_fib_id = ntohl (outer_fib_id);
9381   mp->is_add = is_add;
9382
9383   S;
9384   W;
9385   /* NOTREACHED */
9386   return 0;
9387 }
9388
9389 static void vl_api_gre_tunnel_details_t_handler
9390   (vl_api_gre_tunnel_details_t * mp)
9391 {
9392   vat_main_t *vam = &vat_main;
9393
9394   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9395            ntohl (mp->sw_if_index),
9396            format_ip4_address, &mp->src_address,
9397            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9398 }
9399
9400 static void vl_api_gre_tunnel_details_t_handler_json
9401   (vl_api_gre_tunnel_details_t * mp)
9402 {
9403   vat_main_t *vam = &vat_main;
9404   vat_json_node_t *node = NULL;
9405   struct in_addr ip4;
9406
9407   if (VAT_JSON_ARRAY != vam->json_tree.type)
9408     {
9409       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9410       vat_json_init_array (&vam->json_tree);
9411     }
9412   node = vat_json_array_add (&vam->json_tree);
9413
9414   vat_json_init_object (node);
9415   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9416   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9417   vat_json_object_add_ip4 (node, "src_address", ip4);
9418   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9419   vat_json_object_add_ip4 (node, "dst_address", ip4);
9420   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9421 }
9422
9423 static int
9424 api_gre_tunnel_dump (vat_main_t * vam)
9425 {
9426   unformat_input_t *i = vam->input;
9427   vl_api_gre_tunnel_dump_t *mp;
9428   f64 timeout;
9429   u32 sw_if_index;
9430   u8 sw_if_index_set = 0;
9431
9432   /* Parse args required to build the message */
9433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (i, "sw_if_index %d", &sw_if_index))
9436         sw_if_index_set = 1;
9437       else
9438         break;
9439     }
9440
9441   if (sw_if_index_set == 0)
9442     {
9443       sw_if_index = ~0;
9444     }
9445
9446   if (!vam->json_output)
9447     {
9448       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9449                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9450     }
9451
9452   /* Get list of gre-tunnel interfaces */
9453   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9454
9455   mp->sw_if_index = htonl (sw_if_index);
9456
9457   S;
9458
9459   /* Use a control ping for synchronization */
9460   {
9461     vl_api_control_ping_t *mp;
9462     M (CONTROL_PING, control_ping);
9463     S;
9464   }
9465   W;
9466 }
9467
9468 static int
9469 api_l2_fib_clear_table (vat_main_t * vam)
9470 {
9471 //  unformat_input_t * i = vam->input;
9472   vl_api_l2_fib_clear_table_t *mp;
9473   f64 timeout;
9474
9475   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9476
9477   S;
9478   W;
9479   /* NOTREACHED */
9480   return 0;
9481 }
9482
9483 static int
9484 api_l2_interface_efp_filter (vat_main_t * vam)
9485 {
9486   unformat_input_t *i = vam->input;
9487   vl_api_l2_interface_efp_filter_t *mp;
9488   f64 timeout;
9489   u32 sw_if_index;
9490   u8 enable = 1;
9491   u8 sw_if_index_set = 0;
9492
9493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9494     {
9495       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9496         sw_if_index_set = 1;
9497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9498         sw_if_index_set = 1;
9499       else if (unformat (i, "enable"))
9500         enable = 1;
9501       else if (unformat (i, "disable"))
9502         enable = 0;
9503       else
9504         {
9505           clib_warning ("parse error '%U'", format_unformat_error, i);
9506           return -99;
9507         }
9508     }
9509
9510   if (sw_if_index_set == 0)
9511     {
9512       errmsg ("missing sw_if_index\n");
9513       return -99;
9514     }
9515
9516   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9517
9518   mp->sw_if_index = ntohl (sw_if_index);
9519   mp->enable_disable = enable;
9520
9521   S;
9522   W;
9523   /* NOTREACHED */
9524   return 0;
9525 }
9526
9527 #define foreach_vtr_op                          \
9528 _("disable",  L2_VTR_DISABLED)                  \
9529 _("push-1",  L2_VTR_PUSH_1)                     \
9530 _("push-2",  L2_VTR_PUSH_2)                     \
9531 _("pop-1",  L2_VTR_POP_1)                       \
9532 _("pop-2",  L2_VTR_POP_2)                       \
9533 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9534 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9535 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9536 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9537
9538 static int
9539 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9540 {
9541   unformat_input_t *i = vam->input;
9542   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9543   f64 timeout;
9544   u32 sw_if_index;
9545   u8 sw_if_index_set = 0;
9546   u8 vtr_op_set = 0;
9547   u32 vtr_op = 0;
9548   u32 push_dot1q = 1;
9549   u32 tag1 = ~0;
9550   u32 tag2 = ~0;
9551
9552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9553     {
9554       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "vtr_op %d", &vtr_op))
9559         vtr_op_set = 1;
9560 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9561       foreach_vtr_op
9562 #undef _
9563         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9564         ;
9565       else if (unformat (i, "tag1 %d", &tag1))
9566         ;
9567       else if (unformat (i, "tag2 %d", &tag2))
9568         ;
9569       else
9570         {
9571           clib_warning ("parse error '%U'", format_unformat_error, i);
9572           return -99;
9573         }
9574     }
9575
9576   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9577     {
9578       errmsg ("missing vtr operation or sw_if_index\n");
9579       return -99;
9580     }
9581
9582   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9583     mp->sw_if_index = ntohl (sw_if_index);
9584   mp->vtr_op = ntohl (vtr_op);
9585   mp->push_dot1q = ntohl (push_dot1q);
9586   mp->tag1 = ntohl (tag1);
9587   mp->tag2 = ntohl (tag2);
9588
9589   S;
9590   W;
9591   /* NOTREACHED */
9592   return 0;
9593 }
9594
9595 static int
9596 api_create_vhost_user_if (vat_main_t * vam)
9597 {
9598   unformat_input_t *i = vam->input;
9599   vl_api_create_vhost_user_if_t *mp;
9600   f64 timeout;
9601   u8 *file_name;
9602   u8 is_server = 0;
9603   u8 file_name_set = 0;
9604   u32 custom_dev_instance = ~0;
9605   u8 hwaddr[6];
9606   u8 use_custom_mac = 0;
9607
9608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9609     {
9610       if (unformat (i, "socket %s", &file_name))
9611         {
9612           file_name_set = 1;
9613         }
9614       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9615         ;
9616       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9617         use_custom_mac = 1;
9618       else if (unformat (i, "server"))
9619         is_server = 1;
9620       else
9621         break;
9622     }
9623
9624   if (file_name_set == 0)
9625     {
9626       errmsg ("missing socket file name\n");
9627       return -99;
9628     }
9629
9630   if (vec_len (file_name) > 255)
9631     {
9632       errmsg ("socket file name too long\n");
9633       return -99;
9634     }
9635   vec_add1 (file_name, 0);
9636
9637   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9638
9639   mp->is_server = is_server;
9640   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9641   vec_free (file_name);
9642   if (custom_dev_instance != ~0)
9643     {
9644       mp->renumber = 1;
9645       mp->custom_dev_instance = ntohl (custom_dev_instance);
9646     }
9647   mp->use_custom_mac = use_custom_mac;
9648   clib_memcpy (mp->mac_address, hwaddr, 6);
9649
9650   S;
9651   W;
9652   /* NOTREACHED */
9653   return 0;
9654 }
9655
9656 static int
9657 api_modify_vhost_user_if (vat_main_t * vam)
9658 {
9659   unformat_input_t *i = vam->input;
9660   vl_api_modify_vhost_user_if_t *mp;
9661   f64 timeout;
9662   u8 *file_name;
9663   u8 is_server = 0;
9664   u8 file_name_set = 0;
9665   u32 custom_dev_instance = ~0;
9666   u8 sw_if_index_set = 0;
9667   u32 sw_if_index = (u32) ~ 0;
9668
9669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9670     {
9671       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9672         sw_if_index_set = 1;
9673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9674         sw_if_index_set = 1;
9675       else if (unformat (i, "socket %s", &file_name))
9676         {
9677           file_name_set = 1;
9678         }
9679       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9680         ;
9681       else if (unformat (i, "server"))
9682         is_server = 1;
9683       else
9684         break;
9685     }
9686
9687   if (sw_if_index_set == 0)
9688     {
9689       errmsg ("missing sw_if_index or interface name\n");
9690       return -99;
9691     }
9692
9693   if (file_name_set == 0)
9694     {
9695       errmsg ("missing socket file name\n");
9696       return -99;
9697     }
9698
9699   if (vec_len (file_name) > 255)
9700     {
9701       errmsg ("socket file name too long\n");
9702       return -99;
9703     }
9704   vec_add1 (file_name, 0);
9705
9706   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9707
9708   mp->sw_if_index = ntohl (sw_if_index);
9709   mp->is_server = is_server;
9710   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9711   vec_free (file_name);
9712   if (custom_dev_instance != ~0)
9713     {
9714       mp->renumber = 1;
9715       mp->custom_dev_instance = ntohl (custom_dev_instance);
9716     }
9717
9718   S;
9719   W;
9720   /* NOTREACHED */
9721   return 0;
9722 }
9723
9724 static int
9725 api_delete_vhost_user_if (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_delete_vhost_user_if_t *mp;
9729   f64 timeout;
9730   u32 sw_if_index = ~0;
9731   u8 sw_if_index_set = 0;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9736         sw_if_index_set = 1;
9737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9738         sw_if_index_set = 1;
9739       else
9740         break;
9741     }
9742
9743   if (sw_if_index_set == 0)
9744     {
9745       errmsg ("missing sw_if_index or interface name\n");
9746       return -99;
9747     }
9748
9749
9750   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9751
9752   mp->sw_if_index = ntohl (sw_if_index);
9753
9754   S;
9755   W;
9756   /* NOTREACHED */
9757   return 0;
9758 }
9759
9760 static void vl_api_sw_interface_vhost_user_details_t_handler
9761   (vl_api_sw_interface_vhost_user_details_t * mp)
9762 {
9763   vat_main_t *vam = &vat_main;
9764
9765   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9766            (char *) mp->interface_name,
9767            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9768            clib_net_to_host_u64 (mp->features), mp->is_server,
9769            ntohl (mp->num_regions), (char *) mp->sock_filename);
9770   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9771 }
9772
9773 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9774   (vl_api_sw_interface_vhost_user_details_t * mp)
9775 {
9776   vat_main_t *vam = &vat_main;
9777   vat_json_node_t *node = NULL;
9778
9779   if (VAT_JSON_ARRAY != vam->json_tree.type)
9780     {
9781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9782       vat_json_init_array (&vam->json_tree);
9783     }
9784   node = vat_json_array_add (&vam->json_tree);
9785
9786   vat_json_init_object (node);
9787   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9788   vat_json_object_add_string_copy (node, "interface_name",
9789                                    mp->interface_name);
9790   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9791                             ntohl (mp->virtio_net_hdr_sz));
9792   vat_json_object_add_uint (node, "features",
9793                             clib_net_to_host_u64 (mp->features));
9794   vat_json_object_add_uint (node, "is_server", mp->is_server);
9795   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9796   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9797   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9798 }
9799
9800 static int
9801 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9802 {
9803   vl_api_sw_interface_vhost_user_dump_t *mp;
9804   f64 timeout;
9805   fformat (vam->ofp,
9806            "Interface name           idx hdr_sz features server regions filename\n");
9807
9808   /* Get list of vhost-user interfaces */
9809   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9810   S;
9811
9812   /* Use a control ping for synchronization */
9813   {
9814     vl_api_control_ping_t *mp;
9815     M (CONTROL_PING, control_ping);
9816     S;
9817   }
9818   W;
9819 }
9820
9821 static int
9822 api_show_version (vat_main_t * vam)
9823 {
9824   vl_api_show_version_t *mp;
9825   f64 timeout;
9826
9827   M (SHOW_VERSION, show_version);
9828
9829   S;
9830   W;
9831   /* NOTREACHED */
9832   return 0;
9833 }
9834
9835
9836 static int
9837 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9838 {
9839   unformat_input_t *line_input = vam->input;
9840   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9841   f64 timeout;
9842   ip4_address_t local4, remote4;
9843   ip6_address_t local6, remote6;
9844   u8 is_add = 1;
9845   u8 ipv4_set = 0, ipv6_set = 0;
9846   u8 local_set = 0;
9847   u8 remote_set = 0;
9848   u32 encap_vrf_id = 0;
9849   u32 decap_vrf_id = 0;
9850   u8 protocol = ~0;
9851   u32 vni;
9852   u8 vni_set = 0;
9853
9854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9855     {
9856       if (unformat (line_input, "del"))
9857         is_add = 0;
9858       else if (unformat (line_input, "local %U",
9859                          unformat_ip4_address, &local4))
9860         {
9861           local_set = 1;
9862           ipv4_set = 1;
9863         }
9864       else if (unformat (line_input, "remote %U",
9865                          unformat_ip4_address, &remote4))
9866         {
9867           remote_set = 1;
9868           ipv4_set = 1;
9869         }
9870       else if (unformat (line_input, "local %U",
9871                          unformat_ip6_address, &local6))
9872         {
9873           local_set = 1;
9874           ipv6_set = 1;
9875         }
9876       else if (unformat (line_input, "remote %U",
9877                          unformat_ip6_address, &remote6))
9878         {
9879           remote_set = 1;
9880           ipv6_set = 1;
9881         }
9882       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9883         ;
9884       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9885         ;
9886       else if (unformat (line_input, "vni %d", &vni))
9887         vni_set = 1;
9888       else if (unformat (line_input, "next-ip4"))
9889         protocol = 1;
9890       else if (unformat (line_input, "next-ip6"))
9891         protocol = 2;
9892       else if (unformat (line_input, "next-ethernet"))
9893         protocol = 3;
9894       else if (unformat (line_input, "next-nsh"))
9895         protocol = 4;
9896       else
9897         {
9898           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9899           return -99;
9900         }
9901     }
9902
9903   if (local_set == 0)
9904     {
9905       errmsg ("tunnel local address not specified\n");
9906       return -99;
9907     }
9908   if (remote_set == 0)
9909     {
9910       errmsg ("tunnel remote address not specified\n");
9911       return -99;
9912     }
9913   if (ipv4_set && ipv6_set)
9914     {
9915       errmsg ("both IPv4 and IPv6 addresses specified");
9916       return -99;
9917     }
9918
9919   if (vni_set == 0)
9920     {
9921       errmsg ("vni not specified\n");
9922       return -99;
9923     }
9924
9925   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9926
9927
9928   if (ipv6_set)
9929     {
9930       clib_memcpy (&mp->local, &local6, sizeof (local6));
9931       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9932     }
9933   else
9934     {
9935       clib_memcpy (&mp->local, &local4, sizeof (local4));
9936       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9937     }
9938
9939   mp->encap_vrf_id = ntohl (encap_vrf_id);
9940   mp->decap_vrf_id = ntohl (decap_vrf_id);
9941   mp->protocol = ntohl (protocol);
9942   mp->vni = ntohl (vni);
9943   mp->is_add = is_add;
9944   mp->is_ipv6 = ipv6_set;
9945
9946   S;
9947   W;
9948   /* NOTREACHED */
9949   return 0;
9950 }
9951
9952 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9953   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9954 {
9955   vat_main_t *vam = &vat_main;
9956
9957   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9958            ntohl (mp->sw_if_index),
9959            format_ip46_address, &(mp->local[0]),
9960            format_ip46_address, &(mp->remote[0]),
9961            ntohl (mp->vni),
9962            ntohl (mp->protocol),
9963            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9964 }
9965
9966 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9967   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9968 {
9969   vat_main_t *vam = &vat_main;
9970   vat_json_node_t *node = NULL;
9971   struct in_addr ip4;
9972   struct in6_addr ip6;
9973
9974   if (VAT_JSON_ARRAY != vam->json_tree.type)
9975     {
9976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9977       vat_json_init_array (&vam->json_tree);
9978     }
9979   node = vat_json_array_add (&vam->json_tree);
9980
9981   vat_json_init_object (node);
9982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9983   if (mp->is_ipv6)
9984     {
9985       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9986       vat_json_object_add_ip6 (node, "local", ip6);
9987       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9988       vat_json_object_add_ip6 (node, "remote", ip6);
9989     }
9990   else
9991     {
9992       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9993       vat_json_object_add_ip4 (node, "local", ip4);
9994       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9995       vat_json_object_add_ip4 (node, "remote", ip4);
9996     }
9997   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9998   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9999   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10000   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10001   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10002 }
10003
10004 static int
10005 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10006 {
10007   unformat_input_t *i = vam->input;
10008   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10009   f64 timeout;
10010   u32 sw_if_index;
10011   u8 sw_if_index_set = 0;
10012
10013   /* Parse args required to build the message */
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "sw_if_index %d", &sw_if_index))
10017         sw_if_index_set = 1;
10018       else
10019         break;
10020     }
10021
10022   if (sw_if_index_set == 0)
10023     {
10024       sw_if_index = ~0;
10025     }
10026
10027   if (!vam->json_output)
10028     {
10029       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10030                "sw_if_index", "local", "remote", "vni",
10031                "protocol", "encap_vrf_id", "decap_vrf_id");
10032     }
10033
10034   /* Get list of vxlan-tunnel interfaces */
10035   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10036
10037   mp->sw_if_index = htonl (sw_if_index);
10038
10039   S;
10040
10041   /* Use a control ping for synchronization */
10042   {
10043     vl_api_control_ping_t *mp;
10044     M (CONTROL_PING, control_ping);
10045     S;
10046   }
10047   W;
10048 }
10049
10050 u8 *
10051 format_l2_fib_mac_address (u8 * s, va_list * args)
10052 {
10053   u8 *a = va_arg (*args, u8 *);
10054
10055   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10056                  a[2], a[3], a[4], a[5], a[6], a[7]);
10057 }
10058
10059 static void vl_api_l2_fib_table_entry_t_handler
10060   (vl_api_l2_fib_table_entry_t * mp)
10061 {
10062   vat_main_t *vam = &vat_main;
10063
10064   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10065            "       %d       %d     %d\n",
10066            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10067            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10068            mp->bvi_mac);
10069 }
10070
10071 static void vl_api_l2_fib_table_entry_t_handler_json
10072   (vl_api_l2_fib_table_entry_t * mp)
10073 {
10074   vat_main_t *vam = &vat_main;
10075   vat_json_node_t *node = NULL;
10076
10077   if (VAT_JSON_ARRAY != vam->json_tree.type)
10078     {
10079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10080       vat_json_init_array (&vam->json_tree);
10081     }
10082   node = vat_json_array_add (&vam->json_tree);
10083
10084   vat_json_init_object (node);
10085   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10086   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10088   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10089   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10090   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10091 }
10092
10093 static int
10094 api_l2_fib_table_dump (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_l2_fib_table_dump_t *mp;
10098   f64 timeout;
10099   u32 bd_id;
10100   u8 bd_id_set = 0;
10101
10102   /* Parse args required to build the message */
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "bd_id %d", &bd_id))
10106         bd_id_set = 1;
10107       else
10108         break;
10109     }
10110
10111   if (bd_id_set == 0)
10112     {
10113       errmsg ("missing bridge domain\n");
10114       return -99;
10115     }
10116
10117   fformat (vam->ofp,
10118            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10119
10120   /* Get list of l2 fib entries */
10121   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10122
10123   mp->bd_id = ntohl (bd_id);
10124   S;
10125
10126   /* Use a control ping for synchronization */
10127   {
10128     vl_api_control_ping_t *mp;
10129     M (CONTROL_PING, control_ping);
10130     S;
10131   }
10132   W;
10133 }
10134
10135
10136 static int
10137 api_interface_name_renumber (vat_main_t * vam)
10138 {
10139   unformat_input_t *line_input = vam->input;
10140   vl_api_interface_name_renumber_t *mp;
10141   u32 sw_if_index = ~0;
10142   f64 timeout;
10143   u32 new_show_dev_instance = ~0;
10144
10145   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10148                     &sw_if_index))
10149         ;
10150       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10151         ;
10152       else if (unformat (line_input, "new_show_dev_instance %d",
10153                          &new_show_dev_instance))
10154         ;
10155       else
10156         break;
10157     }
10158
10159   if (sw_if_index == ~0)
10160     {
10161       errmsg ("missing interface name or sw_if_index\n");
10162       return -99;
10163     }
10164
10165   if (new_show_dev_instance == ~0)
10166     {
10167       errmsg ("missing new_show_dev_instance\n");
10168       return -99;
10169     }
10170
10171   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10172
10173   mp->sw_if_index = ntohl (sw_if_index);
10174   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10175
10176   S;
10177   W;
10178 }
10179
10180 static int
10181 api_want_ip4_arp_events (vat_main_t * vam)
10182 {
10183   unformat_input_t *line_input = vam->input;
10184   vl_api_want_ip4_arp_events_t *mp;
10185   f64 timeout;
10186   ip4_address_t address;
10187   int address_set = 0;
10188   u32 enable_disable = 1;
10189
10190   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10191     {
10192       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10193         address_set = 1;
10194       else if (unformat (line_input, "del"))
10195         enable_disable = 0;
10196       else
10197         break;
10198     }
10199
10200   if (address_set == 0)
10201     {
10202       errmsg ("missing addresses\n");
10203       return -99;
10204     }
10205
10206   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10207   mp->enable_disable = enable_disable;
10208   mp->pid = getpid ();
10209   mp->address = address.as_u32;
10210
10211   S;
10212   W;
10213 }
10214
10215 static int
10216 api_input_acl_set_interface (vat_main_t * vam)
10217 {
10218   unformat_input_t *i = vam->input;
10219   vl_api_input_acl_set_interface_t *mp;
10220   f64 timeout;
10221   u32 sw_if_index;
10222   int sw_if_index_set;
10223   u32 ip4_table_index = ~0;
10224   u32 ip6_table_index = ~0;
10225   u32 l2_table_index = ~0;
10226   u8 is_add = 1;
10227
10228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10229     {
10230       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10231         sw_if_index_set = 1;
10232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10233         sw_if_index_set = 1;
10234       else if (unformat (i, "del"))
10235         is_add = 0;
10236       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10237         ;
10238       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10239         ;
10240       else if (unformat (i, "l2-table %d", &l2_table_index))
10241         ;
10242       else
10243         {
10244           clib_warning ("parse error '%U'", format_unformat_error, i);
10245           return -99;
10246         }
10247     }
10248
10249   if (sw_if_index_set == 0)
10250     {
10251       errmsg ("missing interface name or sw_if_index\n");
10252       return -99;
10253     }
10254
10255   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10256
10257   mp->sw_if_index = ntohl (sw_if_index);
10258   mp->ip4_table_index = ntohl (ip4_table_index);
10259   mp->ip6_table_index = ntohl (ip6_table_index);
10260   mp->l2_table_index = ntohl (l2_table_index);
10261   mp->is_add = is_add;
10262
10263   S;
10264   W;
10265   /* NOTREACHED */
10266   return 0;
10267 }
10268
10269 static int
10270 api_ip_address_dump (vat_main_t * vam)
10271 {
10272   unformat_input_t *i = vam->input;
10273   vl_api_ip_address_dump_t *mp;
10274   u32 sw_if_index = ~0;
10275   u8 sw_if_index_set = 0;
10276   u8 ipv4_set = 0;
10277   u8 ipv6_set = 0;
10278   f64 timeout;
10279
10280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10281     {
10282       if (unformat (i, "sw_if_index %d", &sw_if_index))
10283         sw_if_index_set = 1;
10284       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10285         sw_if_index_set = 1;
10286       else if (unformat (i, "ipv4"))
10287         ipv4_set = 1;
10288       else if (unformat (i, "ipv6"))
10289         ipv6_set = 1;
10290       else
10291         break;
10292     }
10293
10294   if (ipv4_set && ipv6_set)
10295     {
10296       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10297       return -99;
10298     }
10299
10300   if ((!ipv4_set) && (!ipv6_set))
10301     {
10302       errmsg ("no ipv4 nor ipv6 flag set\n");
10303       return -99;
10304     }
10305
10306   if (sw_if_index_set == 0)
10307     {
10308       errmsg ("missing interface name or sw_if_index\n");
10309       return -99;
10310     }
10311
10312   vam->current_sw_if_index = sw_if_index;
10313   vam->is_ipv6 = ipv6_set;
10314
10315   M (IP_ADDRESS_DUMP, ip_address_dump);
10316   mp->sw_if_index = ntohl (sw_if_index);
10317   mp->is_ipv6 = ipv6_set;
10318   S;
10319
10320   /* Use a control ping for synchronization */
10321   {
10322     vl_api_control_ping_t *mp;
10323     M (CONTROL_PING, control_ping);
10324     S;
10325   }
10326   W;
10327 }
10328
10329 static int
10330 api_ip_dump (vat_main_t * vam)
10331 {
10332   vl_api_ip_dump_t *mp;
10333   unformat_input_t *in = vam->input;
10334   int ipv4_set = 0;
10335   int ipv6_set = 0;
10336   int is_ipv6;
10337   f64 timeout;
10338   int i;
10339
10340   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10341     {
10342       if (unformat (in, "ipv4"))
10343         ipv4_set = 1;
10344       else if (unformat (in, "ipv6"))
10345         ipv6_set = 1;
10346       else
10347         break;
10348     }
10349
10350   if (ipv4_set && ipv6_set)
10351     {
10352       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10353       return -99;
10354     }
10355
10356   if ((!ipv4_set) && (!ipv6_set))
10357     {
10358       errmsg ("no ipv4 nor ipv6 flag set\n");
10359       return -99;
10360     }
10361
10362   is_ipv6 = ipv6_set;
10363   vam->is_ipv6 = is_ipv6;
10364
10365   /* free old data */
10366   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10367     {
10368       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10369     }
10370   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10371
10372   M (IP_DUMP, ip_dump);
10373   mp->is_ipv6 = ipv6_set;
10374   S;
10375
10376   /* Use a control ping for synchronization */
10377   {
10378     vl_api_control_ping_t *mp;
10379     M (CONTROL_PING, control_ping);
10380     S;
10381   }
10382   W;
10383 }
10384
10385 static int
10386 api_ipsec_spd_add_del (vat_main_t * vam)
10387 {
10388 #if DPDK > 0
10389   unformat_input_t *i = vam->input;
10390   vl_api_ipsec_spd_add_del_t *mp;
10391   f64 timeout;
10392   u32 spd_id = ~0;
10393   u8 is_add = 1;
10394
10395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10396     {
10397       if (unformat (i, "spd_id %d", &spd_id))
10398         ;
10399       else if (unformat (i, "del"))
10400         is_add = 0;
10401       else
10402         {
10403           clib_warning ("parse error '%U'", format_unformat_error, i);
10404           return -99;
10405         }
10406     }
10407   if (spd_id == ~0)
10408     {
10409       errmsg ("spd_id must be set\n");
10410       return -99;
10411     }
10412
10413   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10414
10415   mp->spd_id = ntohl (spd_id);
10416   mp->is_add = is_add;
10417
10418   S;
10419   W;
10420   /* NOTREACHED */
10421   return 0;
10422 #else
10423   clib_warning ("unsupported (no dpdk)");
10424   return -99;
10425 #endif
10426 }
10427
10428 static int
10429 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10430 {
10431 #if DPDK > 0
10432   unformat_input_t *i = vam->input;
10433   vl_api_ipsec_interface_add_del_spd_t *mp;
10434   f64 timeout;
10435   u32 sw_if_index;
10436   u8 sw_if_index_set = 0;
10437   u32 spd_id = (u32) ~ 0;
10438   u8 is_add = 1;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "del"))
10443         is_add = 0;
10444       else if (unformat (i, "spd_id %d", &spd_id))
10445         ;
10446       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10447         sw_if_index_set = 1;
10448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10449         sw_if_index_set = 1;
10450       else
10451         {
10452           clib_warning ("parse error '%U'", format_unformat_error, i);
10453           return -99;
10454         }
10455
10456     }
10457
10458   if (spd_id == (u32) ~ 0)
10459     {
10460       errmsg ("spd_id must be set\n");
10461       return -99;
10462     }
10463
10464   if (sw_if_index_set == 0)
10465     {
10466       errmsg ("missing interface name or sw_if_index\n");
10467       return -99;
10468     }
10469
10470   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10471
10472   mp->spd_id = ntohl (spd_id);
10473   mp->sw_if_index = ntohl (sw_if_index);
10474   mp->is_add = is_add;
10475
10476   S;
10477   W;
10478   /* NOTREACHED */
10479   return 0;
10480 #else
10481   clib_warning ("unsupported (no dpdk)");
10482   return -99;
10483 #endif
10484 }
10485
10486 static int
10487 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10488 {
10489 #if DPDK > 0
10490   unformat_input_t *i = vam->input;
10491   vl_api_ipsec_spd_add_del_entry_t *mp;
10492   f64 timeout;
10493   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10494   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10495   i32 priority = 0;
10496   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10497   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10498   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10499   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10500
10501   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10502   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10503   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10504   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10505   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10506   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "del"))
10511         is_add = 0;
10512       if (unformat (i, "outbound"))
10513         is_outbound = 1;
10514       if (unformat (i, "inbound"))
10515         is_outbound = 0;
10516       else if (unformat (i, "spd_id %d", &spd_id))
10517         ;
10518       else if (unformat (i, "sa_id %d", &sa_id))
10519         ;
10520       else if (unformat (i, "priority %d", &priority))
10521         ;
10522       else if (unformat (i, "protocol %d", &protocol))
10523         ;
10524       else if (unformat (i, "lport_start %d", &lport_start))
10525         ;
10526       else if (unformat (i, "lport_stop %d", &lport_stop))
10527         ;
10528       else if (unformat (i, "rport_start %d", &rport_start))
10529         ;
10530       else if (unformat (i, "rport_stop %d", &rport_stop))
10531         ;
10532       else
10533         if (unformat
10534             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10535         {
10536           is_ipv6 = 0;
10537           is_ip_any = 0;
10538         }
10539       else
10540         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10541         {
10542           is_ipv6 = 0;
10543           is_ip_any = 0;
10544         }
10545       else
10546         if (unformat
10547             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10548         {
10549           is_ipv6 = 0;
10550           is_ip_any = 0;
10551         }
10552       else
10553         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10554         {
10555           is_ipv6 = 0;
10556           is_ip_any = 0;
10557         }
10558       else
10559         if (unformat
10560             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10561         {
10562           is_ipv6 = 1;
10563           is_ip_any = 0;
10564         }
10565       else
10566         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10567         {
10568           is_ipv6 = 1;
10569           is_ip_any = 0;
10570         }
10571       else
10572         if (unformat
10573             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10574         {
10575           is_ipv6 = 1;
10576           is_ip_any = 0;
10577         }
10578       else
10579         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10580         {
10581           is_ipv6 = 1;
10582           is_ip_any = 0;
10583         }
10584       else
10585         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10586         {
10587           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10588             {
10589               clib_warning ("unsupported action: 'resolve'");
10590               return -99;
10591             }
10592         }
10593       else
10594         {
10595           clib_warning ("parse error '%U'", format_unformat_error, i);
10596           return -99;
10597         }
10598
10599     }
10600
10601   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10602
10603   mp->spd_id = ntohl (spd_id);
10604   mp->priority = ntohl (priority);
10605   mp->is_outbound = is_outbound;
10606
10607   mp->is_ipv6 = is_ipv6;
10608   if (is_ipv6 || is_ip_any)
10609     {
10610       clib_memcpy (mp->remote_address_start, &raddr6_start,
10611                    sizeof (ip6_address_t));
10612       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10613                    sizeof (ip6_address_t));
10614       clib_memcpy (mp->local_address_start, &laddr6_start,
10615                    sizeof (ip6_address_t));
10616       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10617                    sizeof (ip6_address_t));
10618     }
10619   else
10620     {
10621       clib_memcpy (mp->remote_address_start, &raddr4_start,
10622                    sizeof (ip4_address_t));
10623       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10624                    sizeof (ip4_address_t));
10625       clib_memcpy (mp->local_address_start, &laddr4_start,
10626                    sizeof (ip4_address_t));
10627       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10628                    sizeof (ip4_address_t));
10629     }
10630   mp->protocol = (u8) protocol;
10631   mp->local_port_start = ntohs ((u16) lport_start);
10632   mp->local_port_stop = ntohs ((u16) lport_stop);
10633   mp->remote_port_start = ntohs ((u16) rport_start);
10634   mp->remote_port_stop = ntohs ((u16) rport_stop);
10635   mp->policy = (u8) policy;
10636   mp->sa_id = ntohl (sa_id);
10637   mp->is_add = is_add;
10638   mp->is_ip_any = is_ip_any;
10639   S;
10640   W;
10641   /* NOTREACHED */
10642   return 0;
10643 #else
10644   clib_warning ("unsupported (no dpdk)");
10645   return -99;
10646 #endif
10647 }
10648
10649 static int
10650 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10651 {
10652 #if DPDK > 0
10653   unformat_input_t *i = vam->input;
10654   vl_api_ipsec_sad_add_del_entry_t *mp;
10655   f64 timeout;
10656   u32 sad_id = 0, spi = 0;
10657   u8 *ck = 0, *ik = 0;
10658   u8 is_add = 1;
10659
10660   u8 protocol = IPSEC_PROTOCOL_AH;
10661   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10662   u32 crypto_alg = 0, integ_alg = 0;
10663   ip4_address_t tun_src4;
10664   ip4_address_t tun_dst4;
10665   ip6_address_t tun_src6;
10666   ip6_address_t tun_dst6;
10667
10668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10669     {
10670       if (unformat (i, "del"))
10671         is_add = 0;
10672       else if (unformat (i, "sad_id %d", &sad_id))
10673         ;
10674       else if (unformat (i, "spi %d", &spi))
10675         ;
10676       else if (unformat (i, "esp"))
10677         protocol = IPSEC_PROTOCOL_ESP;
10678       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10679         {
10680           is_tunnel = 1;
10681           is_tunnel_ipv6 = 0;
10682         }
10683       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10684         {
10685           is_tunnel = 1;
10686           is_tunnel_ipv6 = 0;
10687         }
10688       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10689         {
10690           is_tunnel = 1;
10691           is_tunnel_ipv6 = 1;
10692         }
10693       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10694         {
10695           is_tunnel = 1;
10696           is_tunnel_ipv6 = 1;
10697         }
10698       else
10699         if (unformat
10700             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10701         {
10702           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10703               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10704             {
10705               clib_warning ("unsupported crypto-alg: '%U'",
10706                             format_ipsec_crypto_alg, crypto_alg);
10707               return -99;
10708             }
10709         }
10710       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10711         ;
10712       else
10713         if (unformat
10714             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10715         {
10716           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10717               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10718             {
10719               clib_warning ("unsupported integ-alg: '%U'",
10720                             format_ipsec_integ_alg, integ_alg);
10721               return -99;
10722             }
10723         }
10724       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10725         ;
10726       else
10727         {
10728           clib_warning ("parse error '%U'", format_unformat_error, i);
10729           return -99;
10730         }
10731
10732     }
10733
10734   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10735
10736   mp->sad_id = ntohl (sad_id);
10737   mp->is_add = is_add;
10738   mp->protocol = protocol;
10739   mp->spi = ntohl (spi);
10740   mp->is_tunnel = is_tunnel;
10741   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10742   mp->crypto_algorithm = crypto_alg;
10743   mp->integrity_algorithm = integ_alg;
10744   mp->crypto_key_length = vec_len (ck);
10745   mp->integrity_key_length = vec_len (ik);
10746
10747   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10748     mp->crypto_key_length = sizeof (mp->crypto_key);
10749
10750   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10751     mp->integrity_key_length = sizeof (mp->integrity_key);
10752
10753   if (ck)
10754     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10755   if (ik)
10756     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10757
10758   if (is_tunnel)
10759     {
10760       if (is_tunnel_ipv6)
10761         {
10762           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10763                        sizeof (ip6_address_t));
10764           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10765                        sizeof (ip6_address_t));
10766         }
10767       else
10768         {
10769           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10770                        sizeof (ip4_address_t));
10771           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10772                        sizeof (ip4_address_t));
10773         }
10774     }
10775
10776   S;
10777   W;
10778   /* NOTREACHED */
10779   return 0;
10780 #else
10781   clib_warning ("unsupported (no dpdk)");
10782   return -99;
10783 #endif
10784 }
10785
10786 static int
10787 api_ipsec_sa_set_key (vat_main_t * vam)
10788 {
10789 #if DPDK > 0
10790   unformat_input_t *i = vam->input;
10791   vl_api_ipsec_sa_set_key_t *mp;
10792   f64 timeout;
10793   u32 sa_id;
10794   u8 *ck = 0, *ik = 0;
10795
10796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (i, "sa_id %d", &sa_id))
10799         ;
10800       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10801         ;
10802       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10803         ;
10804       else
10805         {
10806           clib_warning ("parse error '%U'", format_unformat_error, i);
10807           return -99;
10808         }
10809     }
10810
10811   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10812
10813   mp->sa_id = ntohl (sa_id);
10814   mp->crypto_key_length = vec_len (ck);
10815   mp->integrity_key_length = vec_len (ik);
10816
10817   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10818     mp->crypto_key_length = sizeof (mp->crypto_key);
10819
10820   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10821     mp->integrity_key_length = sizeof (mp->integrity_key);
10822
10823   if (ck)
10824     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10825   if (ik)
10826     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10827
10828   S;
10829   W;
10830   /* NOTREACHED */
10831   return 0;
10832 #else
10833   clib_warning ("unsupported (no dpdk)");
10834   return -99;
10835 #endif
10836 }
10837
10838 static int
10839 api_ikev2_profile_add_del (vat_main_t * vam)
10840 {
10841 #if DPDK > 0
10842   unformat_input_t *i = vam->input;
10843   vl_api_ikev2_profile_add_del_t *mp;
10844   f64 timeout;
10845   u8 is_add = 1;
10846   u8 *name = 0;
10847
10848   const char *valid_chars = "a-zA-Z0-9_";
10849
10850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (i, "del"))
10853         is_add = 0;
10854       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10855         vec_add1 (name, 0);
10856       else
10857         {
10858           errmsg ("parse error '%U'", format_unformat_error, i);
10859           return -99;
10860         }
10861     }
10862
10863   if (!vec_len (name))
10864     {
10865       errmsg ("profile name must be specified");
10866       return -99;
10867     }
10868
10869   if (vec_len (name) > 64)
10870     {
10871       errmsg ("profile name too long");
10872       return -99;
10873     }
10874
10875   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10876
10877   clib_memcpy (mp->name, name, vec_len (name));
10878   mp->is_add = is_add;
10879   vec_free (name);
10880
10881   S;
10882   W;
10883   /* NOTREACHED */
10884   return 0;
10885 #else
10886   clib_warning ("unsupported (no dpdk)");
10887   return -99;
10888 #endif
10889 }
10890
10891 static int
10892 api_ikev2_profile_set_auth (vat_main_t * vam)
10893 {
10894 #if DPDK > 0
10895   unformat_input_t *i = vam->input;
10896   vl_api_ikev2_profile_set_auth_t *mp;
10897   f64 timeout;
10898   u8 *name = 0;
10899   u8 *data = 0;
10900   u32 auth_method = 0;
10901   u8 is_hex = 0;
10902
10903   const char *valid_chars = "a-zA-Z0-9_";
10904
10905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906     {
10907       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10908         vec_add1 (name, 0);
10909       else if (unformat (i, "auth_method %U",
10910                          unformat_ikev2_auth_method, &auth_method))
10911         ;
10912       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10913         is_hex = 1;
10914       else if (unformat (i, "auth_data %v", &data))
10915         ;
10916       else
10917         {
10918           errmsg ("parse error '%U'", format_unformat_error, i);
10919           return -99;
10920         }
10921     }
10922
10923   if (!vec_len (name))
10924     {
10925       errmsg ("profile name must be specified");
10926       return -99;
10927     }
10928
10929   if (vec_len (name) > 64)
10930     {
10931       errmsg ("profile name too long");
10932       return -99;
10933     }
10934
10935   if (!vec_len (data))
10936     {
10937       errmsg ("auth_data must be specified");
10938       return -99;
10939     }
10940
10941   if (!auth_method)
10942     {
10943       errmsg ("auth_method must be specified");
10944       return -99;
10945     }
10946
10947   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10948
10949   mp->is_hex = is_hex;
10950   mp->auth_method = (u8) auth_method;
10951   mp->data_len = vec_len (data);
10952   clib_memcpy (mp->name, name, vec_len (name));
10953   clib_memcpy (mp->data, data, vec_len (data));
10954   vec_free (name);
10955   vec_free (data);
10956
10957   S;
10958   W;
10959   /* NOTREACHED */
10960   return 0;
10961 #else
10962   clib_warning ("unsupported (no dpdk)");
10963   return -99;
10964 #endif
10965 }
10966
10967 static int
10968 api_ikev2_profile_set_id (vat_main_t * vam)
10969 {
10970 #if DPDK > 0
10971   unformat_input_t *i = vam->input;
10972   vl_api_ikev2_profile_set_id_t *mp;
10973   f64 timeout;
10974   u8 *name = 0;
10975   u8 *data = 0;
10976   u8 is_local = 0;
10977   u32 id_type = 0;
10978   ip4_address_t ip4;
10979
10980   const char *valid_chars = "a-zA-Z0-9_";
10981
10982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10985         vec_add1 (name, 0);
10986       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10987         ;
10988       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10989         {
10990           data = vec_new (u8, 4);
10991           clib_memcpy (data, ip4.as_u8, 4);
10992         }
10993       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10994         ;
10995       else if (unformat (i, "id_data %v", &data))
10996         ;
10997       else if (unformat (i, "local"))
10998         is_local = 1;
10999       else if (unformat (i, "remote"))
11000         is_local = 0;
11001       else
11002         {
11003           errmsg ("parse error '%U'", format_unformat_error, i);
11004           return -99;
11005         }
11006     }
11007
11008   if (!vec_len (name))
11009     {
11010       errmsg ("profile name must be specified");
11011       return -99;
11012     }
11013
11014   if (vec_len (name) > 64)
11015     {
11016       errmsg ("profile name too long");
11017       return -99;
11018     }
11019
11020   if (!vec_len (data))
11021     {
11022       errmsg ("id_data must be specified");
11023       return -99;
11024     }
11025
11026   if (!id_type)
11027     {
11028       errmsg ("id_type must be specified");
11029       return -99;
11030     }
11031
11032   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11033
11034   mp->is_local = is_local;
11035   mp->id_type = (u8) id_type;
11036   mp->data_len = vec_len (data);
11037   clib_memcpy (mp->name, name, vec_len (name));
11038   clib_memcpy (mp->data, data, vec_len (data));
11039   vec_free (name);
11040   vec_free (data);
11041
11042   S;
11043   W;
11044   /* NOTREACHED */
11045   return 0;
11046 #else
11047   clib_warning ("unsupported (no dpdk)");
11048   return -99;
11049 #endif
11050 }
11051
11052 static int
11053 api_ikev2_profile_set_ts (vat_main_t * vam)
11054 {
11055 #if DPDK > 0
11056   unformat_input_t *i = vam->input;
11057   vl_api_ikev2_profile_set_ts_t *mp;
11058   f64 timeout;
11059   u8 *name = 0;
11060   u8 is_local = 0;
11061   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11062   ip4_address_t start_addr, end_addr;
11063
11064   const char *valid_chars = "a-zA-Z0-9_";
11065
11066   start_addr.as_u32 = 0;
11067   end_addr.as_u32 = (u32) ~ 0;
11068
11069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11070     {
11071       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11072         vec_add1 (name, 0);
11073       else if (unformat (i, "protocol %d", &proto))
11074         ;
11075       else if (unformat (i, "start_port %d", &start_port))
11076         ;
11077       else if (unformat (i, "end_port %d", &end_port))
11078         ;
11079       else
11080         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11081         ;
11082       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11083         ;
11084       else if (unformat (i, "local"))
11085         is_local = 1;
11086       else if (unformat (i, "remote"))
11087         is_local = 0;
11088       else
11089         {
11090           errmsg ("parse error '%U'", format_unformat_error, i);
11091           return -99;
11092         }
11093     }
11094
11095   if (!vec_len (name))
11096     {
11097       errmsg ("profile name must be specified");
11098       return -99;
11099     }
11100
11101   if (vec_len (name) > 64)
11102     {
11103       errmsg ("profile name too long");
11104       return -99;
11105     }
11106
11107   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11108
11109   mp->is_local = is_local;
11110   mp->proto = (u8) proto;
11111   mp->start_port = (u16) start_port;
11112   mp->end_port = (u16) end_port;
11113   mp->start_addr = start_addr.as_u32;
11114   mp->end_addr = end_addr.as_u32;
11115   clib_memcpy (mp->name, name, vec_len (name));
11116   vec_free (name);
11117
11118   S;
11119   W;
11120   /* NOTREACHED */
11121   return 0;
11122 #else
11123   clib_warning ("unsupported (no dpdk)");
11124   return -99;
11125 #endif
11126 }
11127
11128 static int
11129 api_ikev2_set_local_key (vat_main_t * vam)
11130 {
11131 #if DPDK > 0
11132   unformat_input_t *i = vam->input;
11133   vl_api_ikev2_set_local_key_t *mp;
11134   f64 timeout;
11135   u8 *file = 0;
11136
11137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11138     {
11139       if (unformat (i, "file %v", &file))
11140         vec_add1 (file, 0);
11141       else
11142         {
11143           errmsg ("parse error '%U'", format_unformat_error, i);
11144           return -99;
11145         }
11146     }
11147
11148   if (!vec_len (file))
11149     {
11150       errmsg ("RSA key file must be specified");
11151       return -99;
11152     }
11153
11154   if (vec_len (file) > 256)
11155     {
11156       errmsg ("file name too long");
11157       return -99;
11158     }
11159
11160   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11161
11162   clib_memcpy (mp->key_file, file, vec_len (file));
11163   vec_free (file);
11164
11165   S;
11166   W;
11167   /* NOTREACHED */
11168   return 0;
11169 #else
11170   clib_warning ("unsupported (no dpdk)");
11171   return -99;
11172 #endif
11173 }
11174
11175 /*
11176  * MAP
11177  */
11178 static int
11179 api_map_add_domain (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_map_add_domain_t *mp;
11183   f64 timeout;
11184
11185   ip4_address_t ip4_prefix;
11186   ip6_address_t ip6_prefix;
11187   ip6_address_t ip6_src;
11188   u32 num_m_args = 0;
11189   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11190     0, psid_length = 0;
11191   u8 is_translation = 0;
11192   u32 mtu = 0;
11193   u32 ip6_src_len = 128;
11194
11195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11196     {
11197       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11198                     &ip4_prefix, &ip4_prefix_len))
11199         num_m_args++;
11200       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11201                          &ip6_prefix, &ip6_prefix_len))
11202         num_m_args++;
11203       else
11204         if (unformat
11205             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11206              &ip6_src_len))
11207         num_m_args++;
11208       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11209         num_m_args++;
11210       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11211         num_m_args++;
11212       else if (unformat (i, "psid-offset %d", &psid_offset))
11213         num_m_args++;
11214       else if (unformat (i, "psid-len %d", &psid_length))
11215         num_m_args++;
11216       else if (unformat (i, "mtu %d", &mtu))
11217         num_m_args++;
11218       else if (unformat (i, "map-t"))
11219         is_translation = 1;
11220       else
11221         {
11222           clib_warning ("parse error '%U'", format_unformat_error, i);
11223           return -99;
11224         }
11225     }
11226
11227   if (num_m_args < 3)
11228     {
11229       errmsg ("mandatory argument(s) missing\n");
11230       return -99;
11231     }
11232
11233   /* Construct the API message */
11234   M (MAP_ADD_DOMAIN, map_add_domain);
11235
11236   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11237   mp->ip4_prefix_len = ip4_prefix_len;
11238
11239   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11240   mp->ip6_prefix_len = ip6_prefix_len;
11241
11242   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11243   mp->ip6_src_prefix_len = ip6_src_len;
11244
11245   mp->ea_bits_len = ea_bits_len;
11246   mp->psid_offset = psid_offset;
11247   mp->psid_length = psid_length;
11248   mp->is_translation = is_translation;
11249   mp->mtu = htons (mtu);
11250
11251   /* send it... */
11252   S;
11253
11254   /* Wait for a reply, return good/bad news  */
11255   W;
11256 }
11257
11258 static int
11259 api_map_del_domain (vat_main_t * vam)
11260 {
11261   unformat_input_t *i = vam->input;
11262   vl_api_map_del_domain_t *mp;
11263   f64 timeout;
11264
11265   u32 num_m_args = 0;
11266   u32 index;
11267
11268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11269     {
11270       if (unformat (i, "index %d", &index))
11271         num_m_args++;
11272       else
11273         {
11274           clib_warning ("parse error '%U'", format_unformat_error, i);
11275           return -99;
11276         }
11277     }
11278
11279   if (num_m_args != 1)
11280     {
11281       errmsg ("mandatory argument(s) missing\n");
11282       return -99;
11283     }
11284
11285   /* Construct the API message */
11286   M (MAP_DEL_DOMAIN, map_del_domain);
11287
11288   mp->index = ntohl (index);
11289
11290   /* send it... */
11291   S;
11292
11293   /* Wait for a reply, return good/bad news  */
11294   W;
11295 }
11296
11297 static int
11298 api_map_add_del_rule (vat_main_t * vam)
11299 {
11300   unformat_input_t *i = vam->input;
11301   vl_api_map_add_del_rule_t *mp;
11302   f64 timeout;
11303   u8 is_add = 1;
11304   ip6_address_t ip6_dst;
11305   u32 num_m_args = 0, index, psid = 0;
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "index %d", &index))
11310         num_m_args++;
11311       else if (unformat (i, "psid %d", &psid))
11312         num_m_args++;
11313       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11314         num_m_args++;
11315       else if (unformat (i, "del"))
11316         {
11317           is_add = 0;
11318         }
11319       else
11320         {
11321           clib_warning ("parse error '%U'", format_unformat_error, i);
11322           return -99;
11323         }
11324     }
11325
11326   /* Construct the API message */
11327   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11328
11329   mp->index = ntohl (index);
11330   mp->is_add = is_add;
11331   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11332   mp->psid = ntohs (psid);
11333
11334   /* send it... */
11335   S;
11336
11337   /* Wait for a reply, return good/bad news  */
11338   W;
11339 }
11340
11341 static int
11342 api_map_domain_dump (vat_main_t * vam)
11343 {
11344   vl_api_map_domain_dump_t *mp;
11345   f64 timeout;
11346
11347   /* Construct the API message */
11348   M (MAP_DOMAIN_DUMP, map_domain_dump);
11349
11350   /* send it... */
11351   S;
11352
11353   /* Use a control ping for synchronization */
11354   {
11355     vl_api_control_ping_t *mp;
11356     M (CONTROL_PING, control_ping);
11357     S;
11358   }
11359   W;
11360 }
11361
11362 static int
11363 api_map_rule_dump (vat_main_t * vam)
11364 {
11365   unformat_input_t *i = vam->input;
11366   vl_api_map_rule_dump_t *mp;
11367   f64 timeout;
11368   u32 domain_index = ~0;
11369
11370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (i, "index %u", &domain_index))
11373         ;
11374       else
11375         break;
11376     }
11377
11378   if (domain_index == ~0)
11379     {
11380       clib_warning ("parse error: domain index expected");
11381       return -99;
11382     }
11383
11384   /* Construct the API message */
11385   M (MAP_RULE_DUMP, map_rule_dump);
11386
11387   mp->domain_index = htonl (domain_index);
11388
11389   /* send it... */
11390   S;
11391
11392   /* Use a control ping for synchronization */
11393   {
11394     vl_api_control_ping_t *mp;
11395     M (CONTROL_PING, control_ping);
11396     S;
11397   }
11398   W;
11399 }
11400
11401 static void vl_api_map_add_domain_reply_t_handler
11402   (vl_api_map_add_domain_reply_t * mp)
11403 {
11404   vat_main_t *vam = &vat_main;
11405   i32 retval = ntohl (mp->retval);
11406
11407   if (vam->async_mode)
11408     {
11409       vam->async_errors += (retval < 0);
11410     }
11411   else
11412     {
11413       vam->retval = retval;
11414       vam->result_ready = 1;
11415     }
11416 }
11417
11418 static void vl_api_map_add_domain_reply_t_handler_json
11419   (vl_api_map_add_domain_reply_t * mp)
11420 {
11421   vat_main_t *vam = &vat_main;
11422   vat_json_node_t node;
11423
11424   vat_json_init_object (&node);
11425   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11426   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11427
11428   vat_json_print (vam->ofp, &node);
11429   vat_json_free (&node);
11430
11431   vam->retval = ntohl (mp->retval);
11432   vam->result_ready = 1;
11433 }
11434
11435 static int
11436 api_get_first_msg_id (vat_main_t * vam)
11437 {
11438   vl_api_get_first_msg_id_t *mp;
11439   f64 timeout;
11440   unformat_input_t *i = vam->input;
11441   u8 *name;
11442   u8 name_set = 0;
11443
11444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (i, "client %s", &name))
11447         name_set = 1;
11448       else
11449         break;
11450     }
11451
11452   if (name_set == 0)
11453     {
11454       errmsg ("missing client name\n");
11455       return -99;
11456     }
11457   vec_add1 (name, 0);
11458
11459   if (vec_len (name) > 63)
11460     {
11461       errmsg ("client name too long\n");
11462       return -99;
11463     }
11464
11465   M (GET_FIRST_MSG_ID, get_first_msg_id);
11466   clib_memcpy (mp->name, name, vec_len (name));
11467   S;
11468   W;
11469   /* NOTREACHED */
11470   return 0;
11471 }
11472
11473 static int
11474 api_cop_interface_enable_disable (vat_main_t * vam)
11475 {
11476   unformat_input_t *line_input = vam->input;
11477   vl_api_cop_interface_enable_disable_t *mp;
11478   f64 timeout;
11479   u32 sw_if_index = ~0;
11480   u8 enable_disable = 1;
11481
11482   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (line_input, "disable"))
11485         enable_disable = 0;
11486       if (unformat (line_input, "enable"))
11487         enable_disable = 1;
11488       else if (unformat (line_input, "%U", unformat_sw_if_index,
11489                          vam, &sw_if_index))
11490         ;
11491       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11492         ;
11493       else
11494         break;
11495     }
11496
11497   if (sw_if_index == ~0)
11498     {
11499       errmsg ("missing interface name or sw_if_index\n");
11500       return -99;
11501     }
11502
11503   /* Construct the API message */
11504   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11505   mp->sw_if_index = ntohl (sw_if_index);
11506   mp->enable_disable = enable_disable;
11507
11508   /* send it... */
11509   S;
11510   /* Wait for the reply */
11511   W;
11512 }
11513
11514 static int
11515 api_cop_whitelist_enable_disable (vat_main_t * vam)
11516 {
11517   unformat_input_t *line_input = vam->input;
11518   vl_api_cop_whitelist_enable_disable_t *mp;
11519   f64 timeout;
11520   u32 sw_if_index = ~0;
11521   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11522   u32 fib_id = 0;
11523
11524   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11525     {
11526       if (unformat (line_input, "ip4"))
11527         ip4 = 1;
11528       else if (unformat (line_input, "ip6"))
11529         ip6 = 1;
11530       else if (unformat (line_input, "default"))
11531         default_cop = 1;
11532       else if (unformat (line_input, "%U", unformat_sw_if_index,
11533                          vam, &sw_if_index))
11534         ;
11535       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11536         ;
11537       else if (unformat (line_input, "fib-id %d", &fib_id))
11538         ;
11539       else
11540         break;
11541     }
11542
11543   if (sw_if_index == ~0)
11544     {
11545       errmsg ("missing interface name or sw_if_index\n");
11546       return -99;
11547     }
11548
11549   /* Construct the API message */
11550   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11551   mp->sw_if_index = ntohl (sw_if_index);
11552   mp->fib_id = ntohl (fib_id);
11553   mp->ip4 = ip4;
11554   mp->ip6 = ip6;
11555   mp->default_cop = default_cop;
11556
11557   /* send it... */
11558   S;
11559   /* Wait for the reply */
11560   W;
11561 }
11562
11563 static int
11564 api_get_node_graph (vat_main_t * vam)
11565 {
11566   vl_api_get_node_graph_t *mp;
11567   f64 timeout;
11568
11569   M (GET_NODE_GRAPH, get_node_graph);
11570
11571   /* send it... */
11572   S;
11573   /* Wait for the reply */
11574   W;
11575 }
11576
11577 /* *INDENT-OFF* */
11578 /** Used for parsing LISP eids */
11579 typedef CLIB_PACKED(struct{
11580   u8 addr[16];   /**< eid address */
11581   u32 len;       /**< prefix length if IP */
11582   u8 type;      /**< type of eid */
11583 }) lisp_eid_vat_t;
11584 /* *INDENT-ON* */
11585
11586 static uword
11587 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11588 {
11589   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11590
11591   memset (a, 0, sizeof (a[0]));
11592
11593   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11594     {
11595       a->type = 0;              /* ipv4 type */
11596     }
11597   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11598     {
11599       a->type = 1;              /* ipv6 type */
11600     }
11601   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11602     {
11603       a->type = 2;              /* mac type */
11604     }
11605   else
11606     {
11607       return 0;
11608     }
11609
11610   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11611     {
11612       return 0;
11613     }
11614
11615   return 1;
11616 }
11617
11618 static int
11619 lisp_eid_size_vat (u8 type)
11620 {
11621   switch (type)
11622     {
11623     case 0:
11624       return 4;
11625     case 1:
11626       return 16;
11627     case 2:
11628       return 6;
11629     }
11630   return 0;
11631 }
11632
11633 static void
11634 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11635 {
11636   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11637 }
11638
11639 /* *INDENT-OFF* */
11640 /** Used for transferring locators via VPP API */
11641 typedef CLIB_PACKED(struct
11642 {
11643   u32 sw_if_index; /**< locator sw_if_index */
11644   u8 priority; /**< locator priority */
11645   u8 weight;   /**< locator weight */
11646 }) ls_locator_t;
11647 /* *INDENT-ON* */
11648
11649 static int
11650 api_lisp_add_del_locator_set (vat_main_t * vam)
11651 {
11652   unformat_input_t *input = vam->input;
11653   vl_api_lisp_add_del_locator_set_t *mp;
11654   f64 timeout = ~0;
11655   u8 is_add = 1;
11656   u8 *locator_set_name = NULL;
11657   u8 locator_set_name_set = 0;
11658   ls_locator_t locator, *locators = 0;
11659   u32 sw_if_index, priority, weight;
11660
11661   /* Parse args required to build the message */
11662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11663     {
11664       if (unformat (input, "del"))
11665         {
11666           is_add = 0;
11667         }
11668       else if (unformat (input, "locator-set %s", &locator_set_name))
11669         {
11670           locator_set_name_set = 1;
11671         }
11672       else if (unformat (input, "sw_if_index %u p %u w %u",
11673                          &sw_if_index, &priority, &weight))
11674         {
11675           locator.sw_if_index = htonl (sw_if_index);
11676           locator.priority = priority;
11677           locator.weight = weight;
11678           vec_add1 (locators, locator);
11679         }
11680       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11681                          vam, &sw_if_index, &priority, &weight))
11682         {
11683           locator.sw_if_index = htonl (sw_if_index);
11684           locator.priority = priority;
11685           locator.weight = weight;
11686           vec_add1 (locators, locator);
11687         }
11688       else
11689         break;
11690     }
11691
11692   if (locator_set_name_set == 0)
11693     {
11694       errmsg ("missing locator-set name");
11695       vec_free (locators);
11696       return -99;
11697     }
11698
11699   if (vec_len (locator_set_name) > 64)
11700     {
11701       errmsg ("locator-set name too long\n");
11702       vec_free (locator_set_name);
11703       vec_free (locators);
11704       return -99;
11705     }
11706   vec_add1 (locator_set_name, 0);
11707
11708   /* Construct the API message */
11709   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11710
11711   mp->is_add = is_add;
11712   clib_memcpy (mp->locator_set_name, locator_set_name,
11713                vec_len (locator_set_name));
11714   vec_free (locator_set_name);
11715
11716   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11717   if (locators)
11718     clib_memcpy (mp->locators, locators,
11719                  (sizeof (ls_locator_t) * vec_len (locators)));
11720   vec_free (locators);
11721
11722   /* send it... */
11723   S;
11724
11725   /* Wait for a reply... */
11726   W;
11727
11728   /* NOTREACHED */
11729   return 0;
11730 }
11731
11732 static int
11733 api_lisp_add_del_locator (vat_main_t * vam)
11734 {
11735   unformat_input_t *input = vam->input;
11736   vl_api_lisp_add_del_locator_t *mp;
11737   f64 timeout = ~0;
11738   u32 tmp_if_index = ~0;
11739   u32 sw_if_index = ~0;
11740   u8 sw_if_index_set = 0;
11741   u8 sw_if_index_if_name_set = 0;
11742   u32 priority = ~0;
11743   u8 priority_set = 0;
11744   u32 weight = ~0;
11745   u8 weight_set = 0;
11746   u8 is_add = 1;
11747   u8 *locator_set_name = NULL;
11748   u8 locator_set_name_set = 0;
11749
11750   /* Parse args required to build the message */
11751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11752     {
11753       if (unformat (input, "del"))
11754         {
11755           is_add = 0;
11756         }
11757       else if (unformat (input, "locator-set %s", &locator_set_name))
11758         {
11759           locator_set_name_set = 1;
11760         }
11761       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11762                          &tmp_if_index))
11763         {
11764           sw_if_index_if_name_set = 1;
11765           sw_if_index = tmp_if_index;
11766         }
11767       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11768         {
11769           sw_if_index_set = 1;
11770           sw_if_index = tmp_if_index;
11771         }
11772       else if (unformat (input, "p %d", &priority))
11773         {
11774           priority_set = 1;
11775         }
11776       else if (unformat (input, "w %d", &weight))
11777         {
11778           weight_set = 1;
11779         }
11780       else
11781         break;
11782     }
11783
11784   if (locator_set_name_set == 0)
11785     {
11786       errmsg ("missing locator-set name");
11787       return -99;
11788     }
11789
11790   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11791     {
11792       errmsg ("missing sw_if_index");
11793       vec_free (locator_set_name);
11794       return -99;
11795     }
11796
11797   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11798     {
11799       errmsg ("cannot use both params interface name and sw_if_index");
11800       vec_free (locator_set_name);
11801       return -99;
11802     }
11803
11804   if (priority_set == 0)
11805     {
11806       errmsg ("missing locator-set priority\n");
11807       vec_free (locator_set_name);
11808       return -99;
11809     }
11810
11811   if (weight_set == 0)
11812     {
11813       errmsg ("missing locator-set weight\n");
11814       vec_free (locator_set_name);
11815       return -99;
11816     }
11817
11818   if (vec_len (locator_set_name) > 64)
11819     {
11820       errmsg ("locator-set name too long\n");
11821       vec_free (locator_set_name);
11822       return -99;
11823     }
11824   vec_add1 (locator_set_name, 0);
11825
11826   /* Construct the API message */
11827   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11828
11829   mp->is_add = is_add;
11830   mp->sw_if_index = ntohl (sw_if_index);
11831   mp->priority = priority;
11832   mp->weight = weight;
11833   clib_memcpy (mp->locator_set_name, locator_set_name,
11834                vec_len (locator_set_name));
11835   vec_free (locator_set_name);
11836
11837   /* send it... */
11838   S;
11839
11840   /* Wait for a reply... */
11841   W;
11842
11843   /* NOTREACHED */
11844   return 0;
11845 }
11846
11847 static int
11848 api_lisp_add_del_local_eid (vat_main_t * vam)
11849 {
11850   unformat_input_t *input = vam->input;
11851   vl_api_lisp_add_del_local_eid_t *mp;
11852   f64 timeout = ~0;
11853   u8 is_add = 1;
11854   u8 eid_set = 0;
11855   lisp_eid_vat_t _eid, *eid = &_eid;
11856   u8 *locator_set_name = 0;
11857   u8 locator_set_name_set = 0;
11858   u32 vni = 0;
11859
11860   /* Parse args required to build the message */
11861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11862     {
11863       if (unformat (input, "del"))
11864         {
11865           is_add = 0;
11866         }
11867       else if (unformat (input, "vni %d", &vni))
11868         {
11869           ;
11870         }
11871       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11872         {
11873           eid_set = 1;
11874         }
11875       else if (unformat (input, "locator-set %s", &locator_set_name))
11876         {
11877           locator_set_name_set = 1;
11878         }
11879       else
11880         break;
11881     }
11882
11883   if (locator_set_name_set == 0)
11884     {
11885       errmsg ("missing locator-set name\n");
11886       return -99;
11887     }
11888
11889   if (0 == eid_set)
11890     {
11891       errmsg ("EID address not set!");
11892       vec_free (locator_set_name);
11893       return -99;
11894     }
11895
11896   if (vec_len (locator_set_name) > 64)
11897     {
11898       errmsg ("locator-set name too long\n");
11899       vec_free (locator_set_name);
11900       return -99;
11901     }
11902   vec_add1 (locator_set_name, 0);
11903
11904   /* Construct the API message */
11905   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11906
11907   mp->is_add = is_add;
11908   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11909   mp->eid_type = eid->type;
11910   mp->prefix_len = eid->len;
11911   mp->vni = clib_host_to_net_u32 (vni);
11912   clib_memcpy (mp->locator_set_name, locator_set_name,
11913                vec_len (locator_set_name));
11914
11915   vec_free (locator_set_name);
11916
11917   /* send it... */
11918   S;
11919
11920   /* Wait for a reply... */
11921   W;
11922
11923   /* NOTREACHED */
11924   return 0;
11925 }
11926
11927 /* *INDENT-OFF* */
11928 /** Used for transferring locators via VPP API */
11929 typedef CLIB_PACKED(struct
11930 {
11931   u8 is_ip4; /**< is locator an IPv4 address? */
11932   u8 priority; /**< locator priority */
11933   u8 weight;   /**< locator weight */
11934   u8 addr[16]; /**< IPv4/IPv6 address */
11935 }) rloc_t;
11936 /* *INDENT-ON* */
11937
11938 static int
11939 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11940 {
11941   unformat_input_t *input = vam->input;
11942   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11943   f64 timeout = ~0;
11944   u8 is_add = 1;
11945   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11946   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11947   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11948   u32 action = ~0, p, w;
11949   ip4_address_t rmt_rloc4, lcl_rloc4;
11950   ip6_address_t rmt_rloc6, lcl_rloc6;
11951   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11952
11953   memset (&rloc, 0, sizeof (rloc));
11954
11955   /* Parse args required to build the message */
11956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11957     {
11958       if (unformat (input, "del"))
11959         {
11960           is_add = 0;
11961         }
11962       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11963         {
11964           rmt_eid_set = 1;
11965         }
11966       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11967         {
11968           lcl_eid_set = 1;
11969         }
11970       else if (unformat (input, "p %d w %d", &p, &w))
11971         {
11972           if (!curr_rloc)
11973             {
11974               errmsg ("No RLOC configured for setting priority/weight!");
11975               return -99;
11976             }
11977           curr_rloc->priority = p;
11978           curr_rloc->weight = w;
11979         }
11980       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11981                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11982         {
11983           rloc.is_ip4 = 1;
11984
11985           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11986           rloc.priority = rloc.weight = 0;
11987           vec_add1 (lcl_locs, rloc);
11988
11989           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11990           vec_add1 (rmt_locs, rloc);
11991           /* priority and weight saved in rmt loc */
11992           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11993         }
11994       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11995                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11996         {
11997           rloc.is_ip4 = 0;
11998           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11999           rloc.priority = rloc.weight = 0;
12000           vec_add1 (lcl_locs, rloc);
12001
12002           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12003           vec_add1 (rmt_locs, rloc);
12004           /* priority and weight saved in rmt loc */
12005           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12006         }
12007       else if (unformat (input, "action %d", &action))
12008         {
12009           ;
12010         }
12011       else
12012         {
12013           clib_warning ("parse error '%U'", format_unformat_error, input);
12014           return -99;
12015         }
12016     }
12017
12018   if (!rmt_eid_set)
12019     {
12020       errmsg ("remote eid addresses not set\n");
12021       return -99;
12022     }
12023
12024   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12025     {
12026       errmsg ("eid types don't match\n");
12027       return -99;
12028     }
12029
12030   if (0 == rmt_locs && (u32) ~ 0 == action)
12031     {
12032       errmsg ("action not set for negative mapping\n");
12033       return -99;
12034     }
12035
12036   /* Construct the API message */
12037   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12038
12039   mp->is_add = is_add;
12040   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12041   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12042   mp->eid_type = rmt_eid->type;
12043   mp->rmt_len = rmt_eid->len;
12044   mp->lcl_len = lcl_eid->len;
12045   mp->action = action;
12046
12047   if (0 != rmt_locs && 0 != lcl_locs)
12048     {
12049       mp->loc_num = vec_len (rmt_locs);
12050       clib_memcpy (mp->lcl_locs, lcl_locs,
12051                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12052       clib_memcpy (mp->rmt_locs, rmt_locs,
12053                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12054     }
12055   vec_free (lcl_locs);
12056   vec_free (rmt_locs);
12057
12058   /* send it... */
12059   S;
12060
12061   /* Wait for a reply... */
12062   W;
12063
12064   /* NOTREACHED */
12065   return 0;
12066 }
12067
12068 static int
12069 api_lisp_add_del_map_resolver (vat_main_t * vam)
12070 {
12071   unformat_input_t *input = vam->input;
12072   vl_api_lisp_add_del_map_resolver_t *mp;
12073   f64 timeout = ~0;
12074   u8 is_add = 1;
12075   u8 ipv4_set = 0;
12076   u8 ipv6_set = 0;
12077   ip4_address_t ipv4;
12078   ip6_address_t ipv6;
12079
12080   /* Parse args required to build the message */
12081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (input, "del"))
12084         {
12085           is_add = 0;
12086         }
12087       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12088         {
12089           ipv4_set = 1;
12090         }
12091       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12092         {
12093           ipv6_set = 1;
12094         }
12095       else
12096         break;
12097     }
12098
12099   if (ipv4_set && ipv6_set)
12100     {
12101       errmsg ("both eid v4 and v6 addresses set\n");
12102       return -99;
12103     }
12104
12105   if (!ipv4_set && !ipv6_set)
12106     {
12107       errmsg ("eid addresses not set\n");
12108       return -99;
12109     }
12110
12111   /* Construct the API message */
12112   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12113
12114   mp->is_add = is_add;
12115   if (ipv6_set)
12116     {
12117       mp->is_ipv6 = 1;
12118       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12119     }
12120   else
12121     {
12122       mp->is_ipv6 = 0;
12123       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12124     }
12125
12126   /* send it... */
12127   S;
12128
12129   /* Wait for a reply... */
12130   W;
12131
12132   /* NOTREACHED */
12133   return 0;
12134 }
12135
12136 static int
12137 api_lisp_gpe_enable_disable (vat_main_t * vam)
12138 {
12139   unformat_input_t *input = vam->input;
12140   vl_api_lisp_gpe_enable_disable_t *mp;
12141   f64 timeout = ~0;
12142   u8 is_set = 0;
12143   u8 is_en = 1;
12144
12145   /* Parse args required to build the message */
12146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12147     {
12148       if (unformat (input, "enable"))
12149         {
12150           is_set = 1;
12151           is_en = 1;
12152         }
12153       else if (unformat (input, "disable"))
12154         {
12155           is_set = 1;
12156           is_en = 0;
12157         }
12158       else
12159         break;
12160     }
12161
12162   if (is_set == 0)
12163     {
12164       errmsg ("Value not set\n");
12165       return -99;
12166     }
12167
12168   /* Construct the API message */
12169   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12170
12171   mp->is_en = is_en;
12172
12173   /* send it... */
12174   S;
12175
12176   /* Wait for a reply... */
12177   W;
12178
12179   /* NOTREACHED */
12180   return 0;
12181 }
12182
12183 static int
12184 api_lisp_enable_disable (vat_main_t * vam)
12185 {
12186   unformat_input_t *input = vam->input;
12187   vl_api_lisp_enable_disable_t *mp;
12188   f64 timeout = ~0;
12189   u8 is_set = 0;
12190   u8 is_en = 0;
12191
12192   /* Parse args required to build the message */
12193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12194     {
12195       if (unformat (input, "enable"))
12196         {
12197           is_set = 1;
12198           is_en = 1;
12199         }
12200       else if (unformat (input, "disable"))
12201         {
12202           is_set = 1;
12203         }
12204       else
12205         break;
12206     }
12207
12208   if (!is_set)
12209     {
12210       errmsg ("Value not set\n");
12211       return -99;
12212     }
12213
12214   /* Construct the API message */
12215   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12216
12217   mp->is_en = is_en;
12218
12219   /* send it... */
12220   S;
12221
12222   /* Wait for a reply... */
12223   W;
12224
12225   /* NOTREACHED */
12226   return 0;
12227 }
12228
12229 /**
12230  * Enable/disable LISP proxy ITR.
12231  *
12232  * @param vam vpp API test context
12233  * @return return code
12234  */
12235 static int
12236 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12237 {
12238   f64 timeout = ~0;
12239   u8 ls_name_set = 0;
12240   unformat_input_t *input = vam->input;
12241   vl_api_lisp_pitr_set_locator_set_t *mp;
12242   u8 is_add = 1;
12243   u8 *ls_name = 0;
12244
12245   /* Parse args required to build the message */
12246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (input, "del"))
12249         is_add = 0;
12250       else if (unformat (input, "locator-set %s", &ls_name))
12251         ls_name_set = 1;
12252       else
12253         {
12254           errmsg ("parse error '%U'", format_unformat_error, input);
12255           return -99;
12256         }
12257     }
12258
12259   if (!ls_name_set)
12260     {
12261       errmsg ("locator-set name not set!");
12262       return -99;
12263     }
12264
12265   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12266
12267   mp->is_add = is_add;
12268   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12269   vec_free (ls_name);
12270
12271   /* send */
12272   S;
12273
12274   /* wait for reply */
12275   W;
12276
12277   /* notreached */
12278   return 0;
12279 }
12280
12281 static int
12282 api_show_lisp_pitr (vat_main_t * vam)
12283 {
12284   vl_api_show_lisp_pitr_t *mp;
12285   f64 timeout = ~0;
12286
12287   if (!vam->json_output)
12288     {
12289       fformat (vam->ofp, "%=20s\n", "lisp status:");
12290     }
12291
12292   M (SHOW_LISP_PITR, show_lisp_pitr);
12293   /* send it... */
12294   S;
12295
12296   /* Wait for a reply... */
12297   W;
12298
12299   /* NOTREACHED */
12300   return 0;
12301 }
12302
12303 /**
12304  * Add/delete mapping between vni and vrf
12305  */
12306 static int
12307 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12308 {
12309   f64 timeout = ~0;
12310   unformat_input_t *input = vam->input;
12311   vl_api_lisp_eid_table_add_del_map_t *mp;
12312   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12313   u32 vni, vrf, bd_index;
12314
12315   /* Parse args required to build the message */
12316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12317     {
12318       if (unformat (input, "del"))
12319         is_add = 0;
12320       else if (unformat (input, "vrf %d", &vrf))
12321         vrf_set = 1;
12322       else if (unformat (input, "bd_index %d", &bd_index))
12323         bd_index_set = 1;
12324       else if (unformat (input, "vni %d", &vni))
12325         vni_set = 1;
12326       else
12327         break;
12328     }
12329
12330   if (!vni_set || (!vrf_set && !bd_index_set))
12331     {
12332       errmsg ("missing arguments!");
12333       return -99;
12334     }
12335
12336   if (vrf_set && bd_index_set)
12337     {
12338       errmsg ("error: both vrf and bd entered!");
12339       return -99;
12340     }
12341
12342   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12343
12344   mp->is_add = is_add;
12345   mp->vni = htonl (vni);
12346   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12347   mp->is_l2 = bd_index_set;
12348
12349   /* send */
12350   S;
12351
12352   /* wait for reply */
12353   W;
12354
12355   /* notreached */
12356   return 0;
12357 }
12358
12359 /**
12360  * Add/del remote mapping to/from LISP control plane
12361  *
12362  * @param vam vpp API test context
12363  * @return return code
12364  */
12365 static int
12366 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12367 {
12368   unformat_input_t *input = vam->input;
12369   vl_api_lisp_add_del_remote_mapping_t *mp;
12370   f64 timeout = ~0;
12371   u32 vni = 0;
12372   //TODO: seid need remove
12373   lisp_eid_vat_t _eid, *eid = &_eid;
12374   lisp_eid_vat_t _seid, *seid = &_seid;
12375   u8 is_add = 1, del_all = 0, eid_set = 0;
12376   u32 action = ~0, p, w;
12377   ip4_address_t rloc4;
12378   ip6_address_t rloc6;
12379   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12380
12381   memset (&rloc, 0, sizeof (rloc));
12382
12383   /* Parse args required to build the message */
12384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12385     {
12386       if (unformat (input, "del-all"))
12387         {
12388           del_all = 1;
12389         }
12390       else if (unformat (input, "del"))
12391         {
12392           is_add = 0;
12393         }
12394       else if (unformat (input, "add"))
12395         {
12396           is_add = 1;
12397         }
12398       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12399         {
12400           eid_set = 1;
12401         }
12402       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12403         {
12404           //TODO: Need remove, but first must be remove from CSIT test
12405         }
12406       else if (unformat (input, "vni %d", &vni))
12407         {
12408           ;
12409         }
12410       else if (unformat (input, "p %d w %d", &p, &w))
12411         {
12412           if (!curr_rloc)
12413             {
12414               errmsg ("No RLOC configured for setting priority/weight!");
12415               return -99;
12416             }
12417           curr_rloc->priority = p;
12418           curr_rloc->weight = w;
12419         }
12420       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12421         {
12422           rloc.is_ip4 = 1;
12423           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12424           vec_add1 (rlocs, rloc);
12425           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12426         }
12427       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12428         {
12429           rloc.is_ip4 = 0;
12430           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12431           vec_add1 (rlocs, rloc);
12432           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12433         }
12434       else if (unformat (input, "action %d", &action))
12435         {
12436           ;
12437         }
12438       else
12439         {
12440           clib_warning ("parse error '%U'", format_unformat_error, input);
12441           return -99;
12442         }
12443     }
12444
12445   if (0 == eid_set)
12446     {
12447       errmsg ("missing params!");
12448       return -99;
12449     }
12450
12451   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12452     {
12453       errmsg ("no action set for negative map-reply!");
12454       return -99;
12455     }
12456
12457   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12458   mp->is_add = is_add;
12459   mp->vni = htonl (vni);
12460   mp->action = (u8) action;
12461   mp->eid_len = eid->len;
12462   mp->del_all = del_all;
12463   mp->eid_type = eid->type;
12464   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12465
12466   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12467   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12468   vec_free (rlocs);
12469
12470   /* send it... */
12471   S;
12472
12473   /* Wait for a reply... */
12474   W;
12475
12476   /* NOTREACHED */
12477   return 0;
12478 }
12479
12480 /**
12481  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12482  * forwarding entries in data-plane accordingly.
12483  *
12484  * @param vam vpp API test context
12485  * @return return code
12486  */
12487 static int
12488 api_lisp_add_del_adjacency (vat_main_t * vam)
12489 {
12490   unformat_input_t *input = vam->input;
12491   vl_api_lisp_add_del_adjacency_t *mp;
12492   f64 timeout = ~0;
12493   u32 vni = 0;
12494   ip4_address_t seid4, deid4;
12495   ip6_address_t seid6, deid6;
12496   u8 deid_mac[6] = { 0 };
12497   u8 seid_mac[6] = { 0 };
12498   u8 deid_type, seid_type;
12499   u32 seid_len = 0, deid_len = 0, len;
12500   u8 is_add = 1;
12501
12502   seid_type = deid_type = (u8) ~ 0;
12503
12504   /* Parse args required to build the message */
12505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12506     {
12507       if (unformat (input, "del"))
12508         {
12509           is_add = 0;
12510         }
12511       else if (unformat (input, "add"))
12512         {
12513           is_add = 1;
12514         }
12515       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12516                          &deid4, &len))
12517         {
12518           deid_type = 0;        /* ipv4 */
12519           deid_len = len;
12520         }
12521       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12522                          &deid6, &len))
12523         {
12524           deid_type = 1;        /* ipv6 */
12525           deid_len = len;
12526         }
12527       else if (unformat (input, "deid %U", unformat_ethernet_address,
12528                          deid_mac))
12529         {
12530           deid_type = 2;        /* mac */
12531         }
12532       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12533                          &seid4, &len))
12534         {
12535           seid_type = 0;        /* ipv4 */
12536           seid_len = len;
12537         }
12538       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12539                          &seid6, &len))
12540         {
12541           seid_type = 1;        /* ipv6 */
12542           seid_len = len;
12543         }
12544       else if (unformat (input, "seid %U", unformat_ethernet_address,
12545                          seid_mac))
12546         {
12547           seid_type = 2;        /* mac */
12548         }
12549       else if (unformat (input, "vni %d", &vni))
12550         {
12551           ;
12552         }
12553       else
12554         {
12555           errmsg ("parse error '%U'", format_unformat_error, input);
12556           return -99;
12557         }
12558     }
12559
12560   if ((u8) ~ 0 == deid_type)
12561     {
12562       errmsg ("missing params!");
12563       return -99;
12564     }
12565
12566   if (seid_type != deid_type)
12567     {
12568       errmsg ("source and destination EIDs are of different types!");
12569       return -99;
12570     }
12571
12572   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12573   mp->is_add = is_add;
12574   mp->vni = htonl (vni);
12575   mp->seid_len = seid_len;
12576   mp->deid_len = deid_len;
12577   mp->eid_type = deid_type;
12578
12579   switch (mp->eid_type)
12580     {
12581     case 0:
12582       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12583       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12584       break;
12585     case 1:
12586       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12587       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12588       break;
12589     case 2:
12590       clib_memcpy (mp->seid, seid_mac, 6);
12591       clib_memcpy (mp->deid, deid_mac, 6);
12592       break;
12593     default:
12594       errmsg ("unknown EID type %d!", mp->eid_type);
12595       return 0;
12596     }
12597
12598   /* send it... */
12599   S;
12600
12601   /* Wait for a reply... */
12602   W;
12603
12604   /* NOTREACHED */
12605   return 0;
12606 }
12607
12608 static int
12609 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12610 {
12611   unformat_input_t *input = vam->input;
12612   vl_api_lisp_gpe_add_del_iface_t *mp;
12613   f64 timeout = ~0;
12614   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12615   u32 dp_table = 0, vni = 0;
12616
12617   /* Parse args required to build the message */
12618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12619     {
12620       if (unformat (input, "up"))
12621         {
12622           action_set = 1;
12623           is_add = 1;
12624         }
12625       else if (unformat (input, "down"))
12626         {
12627           action_set = 1;
12628           is_add = 0;
12629         }
12630       else if (unformat (input, "table_id %d", &dp_table))
12631         {
12632           dp_table_set = 1;
12633         }
12634       else if (unformat (input, "bd_id %d", &dp_table))
12635         {
12636           dp_table_set = 1;
12637           is_l2 = 1;
12638         }
12639       else if (unformat (input, "vni %d", &vni))
12640         {
12641           vni_set = 1;
12642         }
12643       else
12644         break;
12645     }
12646
12647   if (action_set == 0)
12648     {
12649       errmsg ("Action not set\n");
12650       return -99;
12651     }
12652   if (dp_table_set == 0 || vni_set == 0)
12653     {
12654       errmsg ("vni and dp_table must be set\n");
12655       return -99;
12656     }
12657
12658   /* Construct the API message */
12659   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12660
12661   mp->is_add = is_add;
12662   mp->dp_table = dp_table;
12663   mp->is_l2 = is_l2;
12664   mp->vni = vni;
12665
12666   /* send it... */
12667   S;
12668
12669   /* Wait for a reply... */
12670   W;
12671
12672   /* NOTREACHED */
12673   return 0;
12674 }
12675
12676 /**
12677  * Add/del map request itr rlocs from LISP control plane and updates
12678  *
12679  * @param vam vpp API test context
12680  * @return return code
12681  */
12682 static int
12683 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12684 {
12685   unformat_input_t *input = vam->input;
12686   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12687   f64 timeout = ~0;
12688   u8 *locator_set_name = 0;
12689   u8 locator_set_name_set = 0;
12690   u8 is_add = 1;
12691
12692   /* Parse args required to build the message */
12693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12694     {
12695       if (unformat (input, "del"))
12696         {
12697           is_add = 0;
12698         }
12699       else if (unformat (input, "%_%v%_", &locator_set_name))
12700         {
12701           locator_set_name_set = 1;
12702         }
12703       else
12704         {
12705           clib_warning ("parse error '%U'", format_unformat_error, input);
12706           return -99;
12707         }
12708     }
12709
12710   if (is_add && !locator_set_name_set)
12711     {
12712       errmsg ("itr-rloc is not set!");
12713       return -99;
12714     }
12715
12716   if (is_add && vec_len (locator_set_name) > 64)
12717     {
12718       errmsg ("itr-rloc locator-set name too long\n");
12719       vec_free (locator_set_name);
12720       return -99;
12721     }
12722
12723   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12724   mp->is_add = is_add;
12725   if (is_add)
12726     {
12727       clib_memcpy (mp->locator_set_name, locator_set_name,
12728                    vec_len (locator_set_name));
12729     }
12730   else
12731     {
12732       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12733     }
12734   vec_free (locator_set_name);
12735
12736   /* send it... */
12737   S;
12738
12739   /* Wait for a reply... */
12740   W;
12741
12742   /* NOTREACHED */
12743   return 0;
12744 }
12745
12746 static int
12747 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12748                             u8 filter)
12749 {
12750   vl_api_lisp_locator_dump_t *mp;
12751   f64 timeout = ~0;
12752
12753   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12754
12755   mp->locator_set_index = htonl (locator_set_index);
12756   mp->filter = filter;
12757
12758   /* send it... */
12759   S;
12760
12761   /* Use a control ping for synchronization */
12762   {
12763     vl_api_noprint_control_ping_t *mp;
12764     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12765     S;
12766   }
12767   /* Wait for a reply... */
12768   W;
12769 }
12770
12771 static inline void
12772 clean_locator_set_message (vat_main_t * vam)
12773 {
12774   locator_set_msg_t *ls = 0;
12775
12776   vec_foreach (ls, vam->locator_set_msg)
12777   {
12778     vec_free (ls->locator_set_name);
12779   }
12780
12781   vec_free (vam->locator_set_msg);
12782 }
12783
12784 static int
12785 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12786 {
12787   locator_set_msg_t *ls;
12788   locator_msg_t *loc;
12789   u8 *tmp_str = 0;
12790   int i = 0, ret = 0;
12791
12792   vec_foreach (ls, vam->locator_set_msg)
12793   {
12794     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12795     if (ret)
12796       {
12797         vec_free (vam->locator_msg);
12798         clean_locator_set_message (vam);
12799         return ret;
12800       }
12801
12802     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12803                       ls->locator_set_index,
12804                       vec_len (vam->locator_msg) ? "" : "\n");
12805     i = 0;
12806     vec_foreach (loc, vam->locator_msg)
12807     {
12808       if (i)
12809         {
12810           tmp_str = format (tmp_str, "%=37s", " ");
12811         }
12812       if (loc->local)
12813         {
12814           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12815                             loc->sw_if_index, loc->priority, loc->weight);
12816         }
12817       else
12818         {
12819           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12820                             loc->is_ipv6 ? format_ip6_address :
12821                             format_ip4_address,
12822                             loc->ip_address, loc->priority, loc->weight);
12823         }
12824       i++;
12825     }
12826
12827     fformat (vam->ofp, "%s", tmp_str);
12828     vec_free (tmp_str);
12829     vec_free (vam->locator_msg);
12830   }
12831
12832   clean_locator_set_message (vam);
12833
12834   return ret;
12835 }
12836
12837 static int
12838 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12839 {
12840   locator_set_msg_t *ls;
12841   locator_msg_t *loc;
12842   vat_json_node_t *node = NULL;
12843   vat_json_node_t *locator_array;
12844   vat_json_node_t *locator;
12845   struct in6_addr ip6;
12846   struct in_addr ip4;
12847   int ret = 0;
12848
12849   if (!vec_len (vam->locator_set_msg))
12850     {
12851       /* just print [] */
12852       vat_json_init_array (&vam->json_tree);
12853       vat_json_print (vam->ofp, &vam->json_tree);
12854       vam->json_tree.type = VAT_JSON_NONE;
12855       return ret;
12856     }
12857
12858   if (VAT_JSON_ARRAY != vam->json_tree.type)
12859     {
12860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12861       vat_json_init_array (&vam->json_tree);
12862     }
12863
12864   vec_foreach (ls, vam->locator_set_msg)
12865   {
12866     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12867     if (ret)
12868       {
12869         vec_free (ls->locator_set_name);
12870         vec_free (vam->locator_msg);
12871         vec_free (vam->locator_set_msg);
12872         vat_json_free (&vam->json_tree);
12873         vam->json_tree.type = VAT_JSON_NONE;
12874         return ret;
12875       }
12876
12877     node = vat_json_array_add (&vam->json_tree);
12878     vat_json_init_object (node);
12879
12880     vat_json_object_add_uint (node, "locator-set-index",
12881                               ls->locator_set_index);
12882     vat_json_object_add_string_copy (node, "locator-set",
12883                                      ls->locator_set_name);
12884     locator_array = vat_json_object_add_list (node, "locator");
12885     vec_foreach (loc, vam->locator_msg)
12886     {
12887       locator = vat_json_array_add (locator_array);
12888       vat_json_init_object (locator);
12889       if (loc->local)
12890         {
12891           vat_json_object_add_uint (locator, "locator-index",
12892                                     loc->sw_if_index);
12893         }
12894       else
12895         {
12896           if (loc->is_ipv6)
12897             {
12898               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12899               vat_json_object_add_ip6 (locator, "locator", ip6);
12900             }
12901           else
12902             {
12903               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12904               vat_json_object_add_ip4 (locator, "locator", ip4);
12905             }
12906         }
12907       vat_json_object_add_uint (locator, "priority", loc->priority);
12908       vat_json_object_add_uint (locator, "weight", loc->weight);
12909     }
12910
12911     vec_free (ls->locator_set_name);
12912     vec_free (vam->locator_msg);
12913   }
12914
12915   vat_json_print (vam->ofp, &vam->json_tree);
12916   vat_json_free (&vam->json_tree);
12917   vam->json_tree.type = VAT_JSON_NONE;
12918
12919   vec_free (vam->locator_set_msg);
12920
12921   return ret;
12922 }
12923
12924 static int
12925 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12926                                 u32 * locator_set_index)
12927 {
12928   locator_set_msg_t *ls;
12929   int ret = 0;
12930
12931   *locator_set_index = ~0;
12932
12933   if (!vec_len (vam->locator_set_msg))
12934     {
12935       return ret;
12936     }
12937
12938   vec_foreach (ls, vam->locator_set_msg)
12939   {
12940     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12941       {
12942         *locator_set_index = ls->locator_set_index;
12943         vec_free (vam->locator_set_msg);
12944         return ret;
12945       }
12946   }
12947
12948   vec_free (vam->locator_set_msg);
12949
12950   return ret;
12951 }
12952
12953 static int
12954 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12955                        u32 * locator_set_index)
12956 {
12957   vl_api_lisp_locator_set_dump_t *mp;
12958   f64 timeout = ~0;
12959
12960   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12961   /* send it... */
12962   S;
12963
12964   /* Use a control ping for synchronization */
12965   {
12966     vl_api_noprint_control_ping_t *mp;
12967     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12968     S;
12969   }
12970
12971   vam->noprint_msg = 1;
12972   /* Wait for a reply... */
12973   /* *INDENT-OFF* */
12974   W_L
12975   ({
12976     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12977     vam->noprint_msg = 0;
12978   });
12979   /* *INDENT-ON* */
12980
12981   /* NOTREACHED */
12982   return 0;
12983 }
12984
12985 static inline int
12986 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12987                    u8 filter)
12988 {
12989   int ret = 0;
12990
12991   ASSERT (vam);
12992
12993   if (!vam->json_output)
12994     {
12995       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12996                "locator", "priority", "weight");
12997     }
12998
12999   if (locator_set)
13000     {
13001       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13002     }
13003
13004   if (!ret && ~0 == locator_set_index)
13005     {
13006       return -99;
13007     }
13008
13009   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13010
13011   return ret;
13012 }
13013
13014 static int
13015 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13016 {
13017   vl_api_lisp_locator_set_dump_t *mp;
13018   f64 timeout = ~0;
13019
13020   if (!vam->json_output)
13021     {
13022       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13023                "locator-set", "locator-set-index", "locator", "priority",
13024                "weight");
13025     }
13026
13027   vam->noprint_msg = 1;
13028
13029   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13030
13031   mp->filter = filter;
13032
13033   /* send it... */
13034   S;
13035
13036   /* Use a control ping for synchronization */
13037   {
13038     vl_api_noprint_control_ping_t *mp;
13039     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13040     S;
13041   }
13042
13043   /* Wait for a reply... */
13044   /* *INDENT-OFF* */
13045   W_L
13046   ({
13047     if (vam->noprint_msg)
13048       {
13049         if (!vam->json_output)
13050           {
13051             print_locator_in_locator_set(vam, filter);
13052           }
13053         else
13054           {
13055             json_locator_in_locator_set(vam, filter);
13056           }
13057       }
13058     vam->noprint_msg = 0;
13059   });
13060   /* *INDENT-ON* */
13061
13062   /* NOTREACHED */
13063   return 0;
13064 }
13065
13066 static int
13067 api_lisp_locator_set_dump (vat_main_t * vam)
13068 {
13069   unformat_input_t *input = vam->input;
13070   vam->noprint_msg = 0;
13071   u32 locator_set_index = ~0;
13072   u8 locator_set_index_set = 0;
13073   u8 *locator_set = 0;
13074   u8 locator_set_set = 0;
13075   u8 filter = 0;
13076   int ret = 0;
13077
13078   /* Parse args required to build the message */
13079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13080     {
13081       if (unformat (input, "locator-set-index %u", &locator_set_index))
13082         {
13083           locator_set_index_set = 1;
13084         }
13085       else if (unformat (input, "locator-set %s", &locator_set))
13086         {
13087           locator_set_set = 1;
13088         }
13089       else if (unformat (input, "local"))
13090         {
13091           filter = 1;
13092         }
13093       else if (unformat (input, "remote"))
13094         {
13095           filter = 2;
13096         }
13097       else
13098         {
13099           break;
13100         }
13101     }
13102
13103   if (locator_set_index_set && locator_set_set)
13104     {
13105       errmsg ("use only input parameter!\n");
13106       return -99;
13107     }
13108
13109   if (locator_set_index_set || locator_set_set)
13110     {
13111       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13112     }
13113   else
13114     {
13115       ret = lisp_locator_set_dump (vam, filter);
13116     }
13117
13118   vec_free (locator_set);
13119
13120   return ret;
13121 }
13122
13123 static int
13124 api_lisp_eid_table_map_dump (vat_main_t * vam)
13125 {
13126   u8 is_l2 = 0;
13127   u8 mode_set = 0;
13128   unformat_input_t *input = vam->input;
13129   vl_api_lisp_eid_table_map_dump_t *mp;
13130   f64 timeout = ~0;
13131
13132   /* Parse args required to build the message */
13133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13134     {
13135       if (unformat (input, "l2"))
13136         {
13137           is_l2 = 1;
13138           mode_set = 1;
13139         }
13140       else if (unformat (input, "l3"))
13141         {
13142           is_l2 = 0;
13143           mode_set = 1;
13144         }
13145       else
13146         {
13147           errmsg ("parse error '%U'", format_unformat_error, input);
13148           return -99;
13149         }
13150     }
13151
13152   if (!mode_set)
13153     {
13154       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13155       return -99;
13156     }
13157
13158   if (!vam->json_output)
13159     {
13160       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13161     }
13162
13163   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13164   mp->is_l2 = is_l2;
13165
13166   /* send it... */
13167   S;
13168
13169   /* Use a control ping for synchronization */
13170   {
13171     vl_api_control_ping_t *mp;
13172     M (CONTROL_PING, control_ping);
13173     S;
13174   }
13175   /* Wait for a reply... */
13176   W;
13177
13178   /* NOTREACHED */
13179   return 0;
13180 }
13181
13182 static int
13183 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13184 {
13185   vl_api_lisp_eid_table_vni_dump_t *mp;
13186   f64 timeout = ~0;
13187
13188   if (!vam->json_output)
13189     {
13190       fformat (vam->ofp, "VNI\n");
13191     }
13192
13193   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13194
13195   /* send it... */
13196   S;
13197
13198   /* Use a control ping for synchronization */
13199   {
13200     vl_api_control_ping_t *mp;
13201     M (CONTROL_PING, control_ping);
13202     S;
13203   }
13204   /* Wait for a reply... */
13205   W;
13206
13207   /* NOTREACHED */
13208   return 0;
13209 }
13210
13211 static int
13212 get_locator_set (vat_main_t * vam)
13213 {
13214   vl_api_lisp_locator_set_dump_t *mp;
13215   f64 timeout = ~0;
13216
13217   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13218   /* send it... */
13219   S;
13220
13221   /* Use a control ping for synchronization */
13222   {
13223     vl_api_noprint_control_ping_t *mp;
13224     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13225     S;
13226   }
13227
13228   /* Wait for a reply... */
13229   W;
13230
13231   /* NOTREACHED */
13232   return 0;
13233 }
13234
13235 static inline u8 *
13236 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13237                           int *ret)
13238 {
13239   u8 *(*format_eid) (u8 *, va_list *) = 0;
13240
13241   ASSERT (vam != NULL);
13242   ASSERT (eid_table != NULL);
13243
13244   if (ret)
13245     {
13246       *ret = 0;
13247     }
13248
13249   switch (eid_table->eid_type)
13250     {
13251     case 0:
13252     case 1:
13253       format_eid = (eid_table->eid_type ? format_ip6_address :
13254                     format_ip4_address);
13255       str = format (0, "[%d] %U/%d", eid_table->vni,
13256                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13257       break;
13258     case 2:
13259       str = format (0, "[%d] %U", eid_table->vni,
13260                     format_ethernet_address, eid_table->eid);
13261       break;
13262     default:
13263       errmsg ("unknown EID type %d!", eid_table->eid_type);
13264       if (ret)
13265         {
13266           *ret = -99;
13267         }
13268       return 0;
13269     }
13270
13271   return str;
13272 }
13273
13274 static inline u8 *
13275 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13276                                   eid_table_t * eid_table)
13277 {
13278   locator_set_msg_t *ls = 0;
13279
13280   ASSERT (vam != NULL);
13281   ASSERT (eid_table != NULL);
13282
13283   if (eid_table->is_local)
13284     {
13285       vec_foreach (ls, vam->locator_set_msg)
13286       {
13287         if (ls->locator_set_index == eid_table->locator_set_index)
13288           {
13289             str = format (0, "local(%s)", ls->locator_set_name);
13290             return str;
13291           }
13292       }
13293
13294       str = format (0, "local(N/A)");
13295     }
13296   else
13297     {
13298       str = format (0, "remote");
13299     }
13300
13301   return str;
13302 }
13303
13304 static inline u8 *
13305 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13306                               eid_table_t * eid_table)
13307 {
13308   locator_msg_t *loc = 0;
13309   int first_line = 1;
13310
13311   ASSERT (vam != NULL);
13312   ASSERT (eid_table != NULL);
13313
13314   if (~0 == eid_table->locator_set_index)
13315     {
13316       return format (0, "action: %d\n", eid_table->action);
13317     }
13318
13319   vec_foreach (loc, vam->locator_msg)
13320   {
13321     if (!first_line)
13322       {
13323         if (loc->local)
13324           {
13325             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13326           }
13327         else
13328           {
13329             str = format (str, "%=55s%-U\n", " ",
13330                           loc->is_ipv6 ? format_ip6_address :
13331                           format_ip4_address, loc->ip_address);
13332           }
13333
13334         continue;
13335       }
13336
13337     if (loc->local)
13338       {
13339         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13340                       eid_table->ttl, eid_table->authoritative);
13341       }
13342     else
13343       {
13344         str = format (str, "%-30U%-20u%-u\n",
13345                       loc->is_ipv6 ? format_ip6_address :
13346                       format_ip4_address,
13347                       loc->ip_address, eid_table->ttl,
13348                       eid_table->authoritative);
13349       }
13350     first_line = 0;
13351   }
13352
13353   return str;
13354 }
13355
13356 static int
13357 print_lisp_eid_table_dump (vat_main_t * vam)
13358 {
13359   eid_table_t *eid_table = 0;
13360   u8 *tmp_str = 0, *tmp_str2 = 0;
13361   int ret = 0;
13362
13363   ASSERT (vam != NULL);
13364
13365   ret = get_locator_set (vam);
13366   if (ret)
13367     {
13368       vec_free (vam->eid_tables);
13369       return ret;
13370     }
13371
13372   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13373            "ttl", "authoritative");
13374
13375   vec_foreach (eid_table, vam->eid_tables)
13376   {
13377     if (~0 != eid_table->locator_set_index)
13378       {
13379         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13380                                           0);
13381         if (ret)
13382           {
13383             vec_free (vam->locator_msg);
13384             clean_locator_set_message (vam);
13385             vec_free (vam->eid_tables);
13386             return ret;
13387           }
13388       }
13389
13390     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13391     if (ret)
13392       {
13393         vec_free (vam->locator_msg);
13394         clean_locator_set_message (vam);
13395         vec_free (vam->eid_tables);
13396         return ret;
13397       }
13398
13399     tmp_str = format (0, "%-35s", tmp_str2);
13400     vec_free (tmp_str2);
13401
13402     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13403     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13404     vec_free (tmp_str2);
13405
13406     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13407     tmp_str = format (tmp_str, "%-s", tmp_str2);
13408     vec_free (tmp_str2);
13409
13410     fformat (vam->ofp, "%s", tmp_str);
13411     vec_free (tmp_str);
13412     vec_free (vam->locator_msg);
13413   }
13414
13415   clean_locator_set_message (vam);
13416   vec_free (vam->eid_tables);
13417
13418   return ret;
13419 }
13420
13421 static inline void
13422 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13423                                 eid_table_t * eid_table)
13424 {
13425   locator_set_msg_t *ls = 0;
13426   u8 *s = 0;
13427
13428   ASSERT (vam != NULL);
13429   ASSERT (node != NULL);
13430   ASSERT (eid_table != NULL);
13431
13432   if (eid_table->is_local)
13433     {
13434       vec_foreach (ls, vam->locator_set_msg)
13435       {
13436         if (ls->locator_set_index == eid_table->locator_set_index)
13437           {
13438             vat_json_object_add_string_copy (node, "locator-set",
13439                                              ls->locator_set_name);
13440             return;
13441           }
13442       }
13443
13444       s = format (0, "N/A");
13445       vec_add1 (s, 0);
13446       vat_json_object_add_string_copy (node, "locator-set", s);
13447       vec_free (s);
13448     }
13449   else
13450     {
13451       s = format (0, "remote");
13452       vec_add1 (s, 0);
13453       vat_json_object_add_string_copy (node, "locator-set", s);
13454       vec_free (s);
13455     }
13456 }
13457
13458 static inline int
13459 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13460                         eid_table_t * eid_table)
13461 {
13462   u8 *s = 0;
13463   struct in6_addr ip6;
13464   struct in_addr ip4;
13465
13466   ASSERT (vam != NULL);
13467   ASSERT (node != NULL);
13468   ASSERT (eid_table != NULL);
13469
13470   switch (eid_table->eid_type)
13471     {
13472     case 0:
13473       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13474       vat_json_object_add_ip4 (node, "eid", ip4);
13475       vat_json_object_add_uint (node, "eid-prefix-len",
13476                                 eid_table->eid_prefix_len);
13477       break;
13478     case 1:
13479       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13480       vat_json_object_add_ip6 (node, "eid", ip6);
13481       vat_json_object_add_uint (node, "eid-prefix-len",
13482                                 eid_table->eid_prefix_len);
13483       break;
13484     case 2:
13485       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13486       vec_add1 (s, 0);
13487       vat_json_object_add_string_copy (node, "eid", s);
13488       vec_free (s);
13489       break;
13490     default:
13491       errmsg ("unknown EID type %d!", eid_table->eid_type);
13492       return -99;
13493     }
13494
13495   return 0;
13496 }
13497
13498 static inline void
13499 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13500                             eid_table_t * eid_table)
13501 {
13502   locator_msg_t *loc = 0;
13503   vat_json_node_t *locator_array = 0;
13504   vat_json_node_t *locator = 0;
13505   struct in6_addr ip6;
13506   struct in_addr ip4;
13507
13508   ASSERT (vam != NULL);
13509   ASSERT (node != NULL);
13510   ASSERT (eid_table != NULL);
13511
13512   locator_array = vat_json_object_add_list (node, "locator");
13513   vec_foreach (loc, vam->locator_msg)
13514   {
13515     locator = vat_json_array_add (locator_array);
13516     vat_json_init_object (locator);
13517     if (loc->local)
13518       {
13519         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13520       }
13521     else
13522       {
13523         if (loc->is_ipv6)
13524           {
13525             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13526             vat_json_object_add_ip6 (locator, "locator", ip6);
13527           }
13528         else
13529           {
13530             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13531             vat_json_object_add_ip4 (locator, "locator", ip4);
13532           }
13533       }
13534   }
13535 }
13536
13537 static int
13538 json_lisp_eid_table_dump (vat_main_t * vam)
13539 {
13540   eid_table_t *eid_table;
13541   vat_json_node_t *node = 0;
13542   int ret = 0;
13543
13544   ASSERT (vam != NULL);
13545
13546   ret = get_locator_set (vam);
13547   if (ret)
13548     {
13549       vec_free (vam->eid_tables);
13550       return ret;
13551     }
13552
13553   if (!vec_len (vam->eid_tables))
13554     {
13555       /* just print [] */
13556       vat_json_init_array (&vam->json_tree);
13557       vat_json_print (vam->ofp, &vam->json_tree);
13558       vam->json_tree.type = VAT_JSON_NONE;
13559       return ret;
13560     }
13561
13562   if (VAT_JSON_ARRAY != vam->json_tree.type)
13563     {
13564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13565       vat_json_init_array (&vam->json_tree);
13566     }
13567
13568   vec_foreach (eid_table, vam->eid_tables)
13569   {
13570     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13571     if (ret)
13572       {
13573         vec_free (vam->locator_msg);
13574         vec_free (vam->eid_tables);
13575         clean_locator_set_message (vam);
13576         vat_json_free (&vam->json_tree);
13577         vam->json_tree.type = VAT_JSON_NONE;
13578         return ret;
13579       }
13580
13581     node = vat_json_array_add (&vam->json_tree);
13582     vat_json_init_object (node);
13583
13584     vat_json_object_add_uint (node, "vni", eid_table->vni);
13585
13586     json_locator_set_for_eid_table (vam, node, eid_table);
13587     ret = json_eid_for_eid_table (vam, node, eid_table);
13588     if (ret)
13589       {
13590         vec_free (vam->locator_msg);
13591         vec_free (vam->eid_tables);
13592         clean_locator_set_message (vam);
13593         vat_json_free (&vam->json_tree);
13594         vam->json_tree.type = VAT_JSON_NONE;
13595         return ret;
13596       }
13597
13598     json_locator_for_eid_table (vam, node, eid_table);
13599
13600     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13601     vat_json_object_add_uint (node, "authoritative",
13602                               eid_table->authoritative);
13603
13604     vec_free (vam->locator_msg);
13605   }
13606
13607   vat_json_print (vam->ofp, &vam->json_tree);
13608   vat_json_free (&vam->json_tree);
13609   vam->json_tree.type = VAT_JSON_NONE;
13610
13611   clean_locator_set_message (vam);
13612   vec_free (vam->eid_tables);
13613
13614   return ret;
13615 }
13616
13617 static int
13618 api_lisp_eid_table_dump (vat_main_t * vam)
13619 {
13620   unformat_input_t *i = vam->input;
13621   vl_api_lisp_eid_table_dump_t *mp;
13622   f64 timeout = ~0;
13623   struct in_addr ip4;
13624   struct in6_addr ip6;
13625   u8 mac[6];
13626   u8 eid_type = ~0, eid_set = 0;
13627   u32 prefix_length = ~0, t, vni = 0;
13628   u8 filter = 0;
13629
13630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13631     {
13632       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13633         {
13634           eid_set = 1;
13635           eid_type = 0;
13636           prefix_length = t;
13637         }
13638       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13639         {
13640           eid_set = 1;
13641           eid_type = 1;
13642           prefix_length = t;
13643         }
13644       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13645         {
13646           eid_set = 1;
13647           eid_type = 2;
13648         }
13649       else if (unformat (i, "vni %d", &t))
13650         {
13651           vni = t;
13652         }
13653       else if (unformat (i, "local"))
13654         {
13655           filter = 1;
13656         }
13657       else if (unformat (i, "remote"))
13658         {
13659           filter = 2;
13660         }
13661       else
13662         {
13663           errmsg ("parse error '%U'", format_unformat_error, i);
13664           return -99;
13665         }
13666     }
13667
13668   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13669
13670   mp->filter = filter;
13671   if (eid_set)
13672     {
13673       mp->eid_set = 1;
13674       mp->vni = htonl (vni);
13675       mp->eid_type = eid_type;
13676       switch (eid_type)
13677         {
13678         case 0:
13679           mp->prefix_length = prefix_length;
13680           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13681           break;
13682         case 1:
13683           mp->prefix_length = prefix_length;
13684           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13685           break;
13686         case 2:
13687           clib_memcpy (mp->eid, mac, sizeof (mac));
13688           break;
13689         default:
13690           errmsg ("unknown EID type %d!", eid_type);
13691           return -99;
13692         }
13693     }
13694
13695   vam->noprint_msg = 1;
13696
13697   /* send it... */
13698   S;
13699
13700   /* Use a control ping for synchronization */
13701   {
13702     vl_api_noprint_control_ping_t *mp;
13703     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13704     S;
13705   }
13706
13707   /* Wait for a reply... */
13708   /* *INDENT-OFF* */
13709   W_L
13710   ({
13711     if (vam->noprint_msg)
13712       {
13713         if (!vam->json_output)
13714           {
13715             vam->retval = print_lisp_eid_table_dump(vam);
13716           }
13717         else
13718           {
13719             vam->retval = json_lisp_eid_table_dump(vam);
13720           }
13721       }
13722     vam->noprint_msg = 0;
13723   });
13724   /* *INDENT-ON* */
13725
13726   /* NOTREACHED */
13727   return 0;
13728 }
13729
13730 static int
13731 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13732 {
13733   vl_api_lisp_gpe_tunnel_dump_t *mp;
13734   f64 timeout = ~0;
13735
13736   if (!vam->json_output)
13737     {
13738       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13739                "%=16s%=16s%=16s%=16s%=16s\n",
13740                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13741                "Decap next", "Lisp version", "Flags", "Next protocol",
13742                "ver_res", "res", "iid");
13743     }
13744
13745   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13746   /* send it... */
13747   S;
13748
13749   /* Use a control ping for synchronization */
13750   {
13751     vl_api_control_ping_t *mp;
13752     M (CONTROL_PING, control_ping);
13753     S;
13754   }
13755   /* Wait for a reply... */
13756   W;
13757
13758   /* NOTREACHED */
13759   return 0;
13760 }
13761
13762 static int
13763 api_lisp_map_resolver_dump (vat_main_t * vam)
13764 {
13765   vl_api_lisp_map_resolver_dump_t *mp;
13766   f64 timeout = ~0;
13767
13768   if (!vam->json_output)
13769     {
13770       fformat (vam->ofp, "%=20s\n", "Map resolver");
13771     }
13772
13773   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13774   /* send it... */
13775   S;
13776
13777   /* Use a control ping for synchronization */
13778   {
13779     vl_api_control_ping_t *mp;
13780     M (CONTROL_PING, control_ping);
13781     S;
13782   }
13783   /* Wait for a reply... */
13784   W;
13785
13786   /* NOTREACHED */
13787   return 0;
13788 }
13789
13790 static int
13791 api_show_lisp_status (vat_main_t * vam)
13792 {
13793   vl_api_show_lisp_status_t *mp;
13794   f64 timeout = ~0;
13795
13796   if (!vam->json_output)
13797     {
13798       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13799     }
13800
13801   M (SHOW_LISP_STATUS, show_lisp_status);
13802   /* send it... */
13803   S;
13804   /* Wait for a reply... */
13805   W;
13806
13807   /* NOTREACHED */
13808   return 0;
13809 }
13810
13811 static int
13812 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13813 {
13814   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13815   f64 timeout = ~0;
13816
13817   if (!vam->json_output)
13818     {
13819       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13820     }
13821
13822   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13823   /* send it... */
13824   S;
13825   /* Wait for a reply... */
13826   W;
13827
13828   /* NOTREACHED */
13829   return 0;
13830 }
13831
13832 static int
13833 api_af_packet_create (vat_main_t * vam)
13834 {
13835   unformat_input_t *i = vam->input;
13836   vl_api_af_packet_create_t *mp;
13837   f64 timeout;
13838   u8 *host_if_name = 0;
13839   u8 hw_addr[6];
13840   u8 random_hw_addr = 1;
13841
13842   memset (hw_addr, 0, sizeof (hw_addr));
13843
13844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (i, "name %s", &host_if_name))
13847         vec_add1 (host_if_name, 0);
13848       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13849         random_hw_addr = 0;
13850       else
13851         break;
13852     }
13853
13854   if (!vec_len (host_if_name))
13855     {
13856       errmsg ("host-interface name must be specified");
13857       return -99;
13858     }
13859
13860   if (vec_len (host_if_name) > 64)
13861     {
13862       errmsg ("host-interface name too long");
13863       return -99;
13864     }
13865
13866   M (AF_PACKET_CREATE, af_packet_create);
13867
13868   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13869   clib_memcpy (mp->hw_addr, hw_addr, 6);
13870   mp->use_random_hw_addr = random_hw_addr;
13871   vec_free (host_if_name);
13872
13873   S;
13874   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13875   /* NOTREACHED */
13876   return 0;
13877 }
13878
13879 static int
13880 api_af_packet_delete (vat_main_t * vam)
13881 {
13882   unformat_input_t *i = vam->input;
13883   vl_api_af_packet_delete_t *mp;
13884   f64 timeout;
13885   u8 *host_if_name = 0;
13886
13887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13888     {
13889       if (unformat (i, "name %s", &host_if_name))
13890         vec_add1 (host_if_name, 0);
13891       else
13892         break;
13893     }
13894
13895   if (!vec_len (host_if_name))
13896     {
13897       errmsg ("host-interface name must be specified");
13898       return -99;
13899     }
13900
13901   if (vec_len (host_if_name) > 64)
13902     {
13903       errmsg ("host-interface name too long");
13904       return -99;
13905     }
13906
13907   M (AF_PACKET_DELETE, af_packet_delete);
13908
13909   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13910   vec_free (host_if_name);
13911
13912   S;
13913   W;
13914   /* NOTREACHED */
13915   return 0;
13916 }
13917
13918 static int
13919 api_policer_add_del (vat_main_t * vam)
13920 {
13921   unformat_input_t *i = vam->input;
13922   vl_api_policer_add_del_t *mp;
13923   f64 timeout;
13924   u8 is_add = 1;
13925   u8 *name = 0;
13926   u32 cir = 0;
13927   u32 eir = 0;
13928   u64 cb = 0;
13929   u64 eb = 0;
13930   u8 rate_type = 0;
13931   u8 round_type = 0;
13932   u8 type = 0;
13933   u8 color_aware = 0;
13934   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13935
13936   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13937   conform_action.dscp = 0;
13938   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13939   exceed_action.dscp = 0;
13940   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13941   violate_action.dscp = 0;
13942
13943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13944     {
13945       if (unformat (i, "del"))
13946         is_add = 0;
13947       else if (unformat (i, "name %s", &name))
13948         vec_add1 (name, 0);
13949       else if (unformat (i, "cir %u", &cir))
13950         ;
13951       else if (unformat (i, "eir %u", &eir))
13952         ;
13953       else if (unformat (i, "cb %u", &cb))
13954         ;
13955       else if (unformat (i, "eb %u", &eb))
13956         ;
13957       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13958                          &rate_type))
13959         ;
13960       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13961                          &round_type))
13962         ;
13963       else if (unformat (i, "type %U", unformat_policer_type, &type))
13964         ;
13965       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13966                          &conform_action))
13967         ;
13968       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13969                          &exceed_action))
13970         ;
13971       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13972                          &violate_action))
13973         ;
13974       else if (unformat (i, "color-aware"))
13975         color_aware = 1;
13976       else
13977         break;
13978     }
13979
13980   if (!vec_len (name))
13981     {
13982       errmsg ("policer name must be specified");
13983       return -99;
13984     }
13985
13986   if (vec_len (name) > 64)
13987     {
13988       errmsg ("policer name too long");
13989       return -99;
13990     }
13991
13992   M (POLICER_ADD_DEL, policer_add_del);
13993
13994   clib_memcpy (mp->name, name, vec_len (name));
13995   vec_free (name);
13996   mp->is_add = is_add;
13997   mp->cir = cir;
13998   mp->eir = eir;
13999   mp->cb = cb;
14000   mp->eb = eb;
14001   mp->rate_type = rate_type;
14002   mp->round_type = round_type;
14003   mp->type = type;
14004   mp->conform_action_type = conform_action.action_type;
14005   mp->conform_dscp = conform_action.dscp;
14006   mp->exceed_action_type = exceed_action.action_type;
14007   mp->exceed_dscp = exceed_action.dscp;
14008   mp->violate_action_type = violate_action.action_type;
14009   mp->violate_dscp = violate_action.dscp;
14010   mp->color_aware = color_aware;
14011
14012   S;
14013   W;
14014   /* NOTREACHED */
14015   return 0;
14016 }
14017
14018 static int
14019 api_policer_dump (vat_main_t * vam)
14020 {
14021   unformat_input_t *i = vam->input;
14022   vl_api_policer_dump_t *mp;
14023   f64 timeout = ~0;
14024   u8 *match_name = 0;
14025   u8 match_name_valid = 0;
14026
14027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14028     {
14029       if (unformat (i, "name %s", &match_name))
14030         {
14031           vec_add1 (match_name, 0);
14032           match_name_valid = 1;
14033         }
14034       else
14035         break;
14036     }
14037
14038   M (POLICER_DUMP, policer_dump);
14039   mp->match_name_valid = match_name_valid;
14040   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14041   vec_free (match_name);
14042   /* send it... */
14043   S;
14044
14045   /* Use a control ping for synchronization */
14046   {
14047     vl_api_control_ping_t *mp;
14048     M (CONTROL_PING, control_ping);
14049     S;
14050   }
14051   /* Wait for a reply... */
14052   W;
14053
14054   /* NOTREACHED */
14055   return 0;
14056 }
14057
14058 static int
14059 api_policer_classify_set_interface (vat_main_t * vam)
14060 {
14061   unformat_input_t *i = vam->input;
14062   vl_api_policer_classify_set_interface_t *mp;
14063   f64 timeout;
14064   u32 sw_if_index;
14065   int sw_if_index_set;
14066   u32 ip4_table_index = ~0;
14067   u32 ip6_table_index = ~0;
14068   u32 l2_table_index = ~0;
14069   u8 is_add = 1;
14070
14071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14072     {
14073       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14074         sw_if_index_set = 1;
14075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14076         sw_if_index_set = 1;
14077       else if (unformat (i, "del"))
14078         is_add = 0;
14079       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14080         ;
14081       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14082         ;
14083       else if (unformat (i, "l2-table %d", &l2_table_index))
14084         ;
14085       else
14086         {
14087           clib_warning ("parse error '%U'", format_unformat_error, i);
14088           return -99;
14089         }
14090     }
14091
14092   if (sw_if_index_set == 0)
14093     {
14094       errmsg ("missing interface name or sw_if_index\n");
14095       return -99;
14096     }
14097
14098   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14099
14100   mp->sw_if_index = ntohl (sw_if_index);
14101   mp->ip4_table_index = ntohl (ip4_table_index);
14102   mp->ip6_table_index = ntohl (ip6_table_index);
14103   mp->l2_table_index = ntohl (l2_table_index);
14104   mp->is_add = is_add;
14105
14106   S;
14107   W;
14108   /* NOTREACHED */
14109   return 0;
14110 }
14111
14112 static int
14113 api_policer_classify_dump (vat_main_t * vam)
14114 {
14115   unformat_input_t *i = vam->input;
14116   vl_api_policer_classify_dump_t *mp;
14117   f64 timeout = ~0;
14118   u8 type = POLICER_CLASSIFY_N_TABLES;
14119
14120   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14121     ;
14122   else
14123     {
14124       errmsg ("classify table type must be specified\n");
14125       return -99;
14126     }
14127
14128   if (!vam->json_output)
14129     {
14130       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14131     }
14132
14133   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14134   mp->type = type;
14135   /* send it... */
14136   S;
14137
14138   /* Use a control ping for synchronization */
14139   {
14140     vl_api_control_ping_t *mp;
14141     M (CONTROL_PING, control_ping);
14142     S;
14143   }
14144   /* Wait for a reply... */
14145   W;
14146
14147   /* NOTREACHED */
14148   return 0;
14149 }
14150
14151 static int
14152 api_netmap_create (vat_main_t * vam)
14153 {
14154   unformat_input_t *i = vam->input;
14155   vl_api_netmap_create_t *mp;
14156   f64 timeout;
14157   u8 *if_name = 0;
14158   u8 hw_addr[6];
14159   u8 random_hw_addr = 1;
14160   u8 is_pipe = 0;
14161   u8 is_master = 0;
14162
14163   memset (hw_addr, 0, sizeof (hw_addr));
14164
14165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14166     {
14167       if (unformat (i, "name %s", &if_name))
14168         vec_add1 (if_name, 0);
14169       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14170         random_hw_addr = 0;
14171       else if (unformat (i, "pipe"))
14172         is_pipe = 1;
14173       else if (unformat (i, "master"))
14174         is_master = 1;
14175       else if (unformat (i, "slave"))
14176         is_master = 0;
14177       else
14178         break;
14179     }
14180
14181   if (!vec_len (if_name))
14182     {
14183       errmsg ("interface name must be specified");
14184       return -99;
14185     }
14186
14187   if (vec_len (if_name) > 64)
14188     {
14189       errmsg ("interface name too long");
14190       return -99;
14191     }
14192
14193   M (NETMAP_CREATE, netmap_create);
14194
14195   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14196   clib_memcpy (mp->hw_addr, hw_addr, 6);
14197   mp->use_random_hw_addr = random_hw_addr;
14198   mp->is_pipe = is_pipe;
14199   mp->is_master = is_master;
14200   vec_free (if_name);
14201
14202   S;
14203   W;
14204   /* NOTREACHED */
14205   return 0;
14206 }
14207
14208 static int
14209 api_netmap_delete (vat_main_t * vam)
14210 {
14211   unformat_input_t *i = vam->input;
14212   vl_api_netmap_delete_t *mp;
14213   f64 timeout;
14214   u8 *if_name = 0;
14215
14216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14217     {
14218       if (unformat (i, "name %s", &if_name))
14219         vec_add1 (if_name, 0);
14220       else
14221         break;
14222     }
14223
14224   if (!vec_len (if_name))
14225     {
14226       errmsg ("interface name must be specified");
14227       return -99;
14228     }
14229
14230   if (vec_len (if_name) > 64)
14231     {
14232       errmsg ("interface name too long");
14233       return -99;
14234     }
14235
14236   M (NETMAP_DELETE, netmap_delete);
14237
14238   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14239   vec_free (if_name);
14240
14241   S;
14242   W;
14243   /* NOTREACHED */
14244   return 0;
14245 }
14246
14247 static void vl_api_mpls_gre_tunnel_details_t_handler
14248   (vl_api_mpls_gre_tunnel_details_t * mp)
14249 {
14250   vat_main_t *vam = &vat_main;
14251   i32 i;
14252   i32 len = ntohl (mp->nlabels);
14253
14254   if (mp->l2_only == 0)
14255     {
14256       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14257                ntohl (mp->tunnel_index),
14258                format_ip4_address, &mp->tunnel_src,
14259                format_ip4_address, &mp->tunnel_dst,
14260                format_ip4_address, &mp->intfc_address,
14261                ntohl (mp->mask_width));
14262       for (i = 0; i < len; i++)
14263         {
14264           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14265         }
14266       fformat (vam->ofp, "\n");
14267       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14268                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14269     }
14270   else
14271     {
14272       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14273                ntohl (mp->tunnel_index),
14274                format_ip4_address, &mp->tunnel_src,
14275                format_ip4_address, &mp->tunnel_dst,
14276                format_ip4_address, &mp->intfc_address);
14277       for (i = 0; i < len; i++)
14278         {
14279           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14280         }
14281       fformat (vam->ofp, "\n");
14282       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14283                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14284     }
14285 }
14286
14287 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14288   (vl_api_mpls_gre_tunnel_details_t * mp)
14289 {
14290   vat_main_t *vam = &vat_main;
14291   vat_json_node_t *node = NULL;
14292   struct in_addr ip4;
14293   i32 i;
14294   i32 len = ntohl (mp->nlabels);
14295
14296   if (VAT_JSON_ARRAY != vam->json_tree.type)
14297     {
14298       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14299       vat_json_init_array (&vam->json_tree);
14300     }
14301   node = vat_json_array_add (&vam->json_tree);
14302
14303   vat_json_init_object (node);
14304   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14305   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14306   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14307   vat_json_object_add_uint (node, "inner_fib_index",
14308                             ntohl (mp->inner_fib_index));
14309   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14310   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14311   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14312   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14313   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14314   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14315   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14316   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14317   vat_json_object_add_uint (node, "outer_fib_index",
14318                             ntohl (mp->outer_fib_index));
14319   vat_json_object_add_uint (node, "label_count", len);
14320   for (i = 0; i < len; i++)
14321     {
14322       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14323     }
14324 }
14325
14326 static int
14327 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14328 {
14329   vl_api_mpls_gre_tunnel_dump_t *mp;
14330   f64 timeout;
14331   i32 index = -1;
14332
14333   /* Parse args required to build the message */
14334   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14335     {
14336       if (!unformat (vam->input, "tunnel_index %d", &index))
14337         {
14338           index = -1;
14339           break;
14340         }
14341     }
14342
14343   fformat (vam->ofp, "  tunnel_index %d\n", index);
14344
14345   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14346   mp->tunnel_index = htonl (index);
14347   S;
14348
14349   /* Use a control ping for synchronization */
14350   {
14351     vl_api_control_ping_t *mp;
14352     M (CONTROL_PING, control_ping);
14353     S;
14354   }
14355   W;
14356 }
14357
14358 static void vl_api_mpls_eth_tunnel_details_t_handler
14359   (vl_api_mpls_eth_tunnel_details_t * mp)
14360 {
14361   vat_main_t *vam = &vat_main;
14362   i32 i;
14363   i32 len = ntohl (mp->nlabels);
14364
14365   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14366            ntohl (mp->tunnel_index),
14367            format_ethernet_address, &mp->tunnel_dst_mac,
14368            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14369   for (i = 0; i < len; i++)
14370     {
14371       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14372     }
14373   fformat (vam->ofp, "\n");
14374   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14375            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14376 }
14377
14378 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14379   (vl_api_mpls_eth_tunnel_details_t * mp)
14380 {
14381   vat_main_t *vam = &vat_main;
14382   vat_json_node_t *node = NULL;
14383   struct in_addr ip4;
14384   i32 i;
14385   i32 len = ntohl (mp->nlabels);
14386
14387   if (VAT_JSON_ARRAY != vam->json_tree.type)
14388     {
14389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14390       vat_json_init_array (&vam->json_tree);
14391     }
14392   node = vat_json_array_add (&vam->json_tree);
14393
14394   vat_json_init_object (node);
14395   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14396   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14397   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14398   vat_json_object_add_uint (node, "inner_fib_index",
14399                             ntohl (mp->inner_fib_index));
14400   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14401   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14402   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14403   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14404   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14405                                    format (0, "%U", format_ethernet_address,
14406                                            &mp->tunnel_dst_mac));
14407   vat_json_object_add_uint (node, "tx_sw_if_index",
14408                             ntohl (mp->tx_sw_if_index));
14409   vat_json_object_add_uint (node, "label_count", len);
14410   for (i = 0; i < len; i++)
14411     {
14412       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14413     }
14414 }
14415
14416 static int
14417 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14418 {
14419   vl_api_mpls_eth_tunnel_dump_t *mp;
14420   f64 timeout;
14421   i32 index = -1;
14422
14423   /* Parse args required to build the message */
14424   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14425     {
14426       if (!unformat (vam->input, "tunnel_index %d", &index))
14427         {
14428           index = -1;
14429           break;
14430         }
14431     }
14432
14433   fformat (vam->ofp, "  tunnel_index %d\n", index);
14434
14435   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14436   mp->tunnel_index = htonl (index);
14437   S;
14438
14439   /* Use a control ping for synchronization */
14440   {
14441     vl_api_control_ping_t *mp;
14442     M (CONTROL_PING, control_ping);
14443     S;
14444   }
14445   W;
14446 }
14447
14448 static void vl_api_mpls_fib_encap_details_t_handler
14449   (vl_api_mpls_fib_encap_details_t * mp)
14450 {
14451   vat_main_t *vam = &vat_main;
14452   i32 i;
14453   i32 len = ntohl (mp->nlabels);
14454
14455   fformat (vam->ofp, "table %d, dest %U, label ",
14456            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14457   for (i = 0; i < len; i++)
14458     {
14459       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14460     }
14461   fformat (vam->ofp, "\n");
14462 }
14463
14464 static void vl_api_mpls_fib_encap_details_t_handler_json
14465   (vl_api_mpls_fib_encap_details_t * mp)
14466 {
14467   vat_main_t *vam = &vat_main;
14468   vat_json_node_t *node = NULL;
14469   i32 i;
14470   i32 len = ntohl (mp->nlabels);
14471   struct in_addr ip4;
14472
14473   if (VAT_JSON_ARRAY != vam->json_tree.type)
14474     {
14475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14476       vat_json_init_array (&vam->json_tree);
14477     }
14478   node = vat_json_array_add (&vam->json_tree);
14479
14480   vat_json_init_object (node);
14481   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14482   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14483   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14484   vat_json_object_add_ip4 (node, "dest", ip4);
14485   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14486   vat_json_object_add_uint (node, "label_count", len);
14487   for (i = 0; i < len; i++)
14488     {
14489       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14490     }
14491 }
14492
14493 static int
14494 api_mpls_fib_encap_dump (vat_main_t * vam)
14495 {
14496   vl_api_mpls_fib_encap_dump_t *mp;
14497   f64 timeout;
14498
14499   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14500   S;
14501
14502   /* Use a control ping for synchronization */
14503   {
14504     vl_api_control_ping_t *mp;
14505     M (CONTROL_PING, control_ping);
14506     S;
14507   }
14508   W;
14509 }
14510
14511 static void vl_api_mpls_fib_decap_details_t_handler
14512   (vl_api_mpls_fib_decap_details_t * mp)
14513 {
14514   vat_main_t *vam = &vat_main;
14515
14516   fformat (vam->ofp,
14517            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14518            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14519            ntohl (mp->label), ntohl (mp->s_bit));
14520 }
14521
14522 static void vl_api_mpls_fib_decap_details_t_handler_json
14523   (vl_api_mpls_fib_decap_details_t * mp)
14524 {
14525   vat_main_t *vam = &vat_main;
14526   vat_json_node_t *node = NULL;
14527   struct in_addr ip4;
14528
14529   if (VAT_JSON_ARRAY != vam->json_tree.type)
14530     {
14531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14532       vat_json_init_array (&vam->json_tree);
14533     }
14534   node = vat_json_array_add (&vam->json_tree);
14535
14536   vat_json_init_object (node);
14537   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14538   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14539   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14540   vat_json_object_add_ip4 (node, "dest", ip4);
14541   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14542   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14543   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14544   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14545   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14546 }
14547
14548 static int
14549 api_mpls_fib_decap_dump (vat_main_t * vam)
14550 {
14551   vl_api_mpls_fib_decap_dump_t *mp;
14552   f64 timeout;
14553
14554   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14555   S;
14556
14557   /* Use a control ping for synchronization */
14558   {
14559     vl_api_control_ping_t *mp;
14560     M (CONTROL_PING, control_ping);
14561     S;
14562   }
14563   W;
14564 }
14565
14566 int
14567 api_classify_table_ids (vat_main_t * vam)
14568 {
14569   vl_api_classify_table_ids_t *mp;
14570   f64 timeout;
14571
14572   /* Construct the API message */
14573   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14574   mp->context = 0;
14575
14576   S;
14577   W;
14578   /* NOTREACHED */
14579   return 0;
14580 }
14581
14582 int
14583 api_classify_table_by_interface (vat_main_t * vam)
14584 {
14585   unformat_input_t *input = vam->input;
14586   vl_api_classify_table_by_interface_t *mp;
14587   f64 timeout;
14588
14589   u32 sw_if_index = ~0;
14590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14593         ;
14594       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14595         ;
14596       else
14597         break;
14598     }
14599   if (sw_if_index == ~0)
14600     {
14601       errmsg ("missing interface name or sw_if_index\n");
14602       return -99;
14603     }
14604
14605   /* Construct the API message */
14606   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14607   mp->context = 0;
14608   mp->sw_if_index = ntohl (sw_if_index);
14609
14610   S;
14611   W;
14612   /* NOTREACHED */
14613   return 0;
14614 }
14615
14616 int
14617 api_classify_table_info (vat_main_t * vam)
14618 {
14619   unformat_input_t *input = vam->input;
14620   vl_api_classify_table_info_t *mp;
14621   f64 timeout;
14622
14623   u32 table_id = ~0;
14624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (input, "table_id %d", &table_id))
14627         ;
14628       else
14629         break;
14630     }
14631   if (table_id == ~0)
14632     {
14633       errmsg ("missing table id\n");
14634       return -99;
14635     }
14636
14637   /* Construct the API message */
14638   M (CLASSIFY_TABLE_INFO, classify_table_info);
14639   mp->context = 0;
14640   mp->table_id = ntohl (table_id);
14641
14642   S;
14643   W;
14644   /* NOTREACHED */
14645   return 0;
14646 }
14647
14648 int
14649 api_classify_session_dump (vat_main_t * vam)
14650 {
14651   unformat_input_t *input = vam->input;
14652   vl_api_classify_session_dump_t *mp;
14653   f64 timeout;
14654
14655   u32 table_id = ~0;
14656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14657     {
14658       if (unformat (input, "table_id %d", &table_id))
14659         ;
14660       else
14661         break;
14662     }
14663   if (table_id == ~0)
14664     {
14665       errmsg ("missing table id\n");
14666       return -99;
14667     }
14668
14669   /* Construct the API message */
14670   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14671   mp->context = 0;
14672   mp->table_id = ntohl (table_id);
14673   S;
14674
14675   /* Use a control ping for synchronization */
14676   {
14677     vl_api_control_ping_t *mp;
14678     M (CONTROL_PING, control_ping);
14679     S;
14680   }
14681   W;
14682   /* NOTREACHED */
14683   return 0;
14684 }
14685
14686 static void
14687 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14688 {
14689   vat_main_t *vam = &vat_main;
14690
14691   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14692            "src_address %U, fib_index %u, path_mtu %u, "
14693            "template_interval %u\n",
14694            format_ip4_address, mp->collector_address,
14695            ntohs (mp->collector_port),
14696            format_ip4_address, mp->src_address,
14697            ntohl (mp->fib_index),
14698            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14699
14700   vam->retval = 0;
14701   vam->result_ready = 1;
14702 }
14703
14704 static void
14705 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14706 {
14707   vat_main_t *vam = &vat_main;
14708   vat_json_node_t node;
14709   struct in_addr collector_address;
14710   struct in_addr src_address;
14711
14712   vat_json_init_object (&node);
14713   clib_memcpy (&collector_address, &mp->collector_address,
14714                sizeof (collector_address));
14715   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14716   vat_json_object_add_uint (&node, "collector_port",
14717                             ntohs (mp->collector_port));
14718   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14719   vat_json_object_add_ip4 (&node, "src_address", src_address);
14720   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14721   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14722   vat_json_object_add_uint (&node, "template_interval",
14723                             ntohl (mp->template_interval));
14724
14725   vat_json_print (vam->ofp, &node);
14726   vat_json_free (&node);
14727   vam->retval = 0;
14728   vam->result_ready = 1;
14729 }
14730
14731 int
14732 api_ipfix_dump (vat_main_t * vam)
14733 {
14734   vl_api_ipfix_dump_t *mp;
14735   f64 timeout;
14736
14737   /* Construct the API message */
14738   M (IPFIX_DUMP, ipfix_dump);
14739   mp->context = 0;
14740
14741   S;
14742   W;
14743   /* NOTREACHED */
14744   return 0;
14745 }
14746
14747 int
14748 api_pg_create_interface (vat_main_t * vam)
14749 {
14750   unformat_input_t *input = vam->input;
14751   vl_api_pg_create_interface_t *mp;
14752   f64 timeout;
14753
14754   u32 if_id = ~0;
14755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14756     {
14757       if (unformat (input, "if_id %d", &if_id))
14758         ;
14759       else
14760         break;
14761     }
14762   if (if_id == ~0)
14763     {
14764       errmsg ("missing pg interface index\n");
14765       return -99;
14766     }
14767
14768   /* Construct the API message */
14769   M (PG_CREATE_INTERFACE, pg_create_interface);
14770   mp->context = 0;
14771   mp->interface_id = ntohl (if_id);
14772
14773   S;
14774   W;
14775   /* NOTREACHED */
14776   return 0;
14777 }
14778
14779 int
14780 api_pg_capture (vat_main_t * vam)
14781 {
14782   unformat_input_t *input = vam->input;
14783   vl_api_pg_capture_t *mp;
14784   f64 timeout;
14785
14786   u32 if_id = ~0;
14787   u8 enable = 1;
14788   u32 count = 1;
14789   u8 pcap_file_set = 0;
14790   u8 *pcap_file = 0;
14791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14792     {
14793       if (unformat (input, "if_id %d", &if_id))
14794         ;
14795       else if (unformat (input, "pcap %s", &pcap_file))
14796         pcap_file_set = 1;
14797       else if (unformat (input, "count %d", &count))
14798         ;
14799       else if (unformat (input, "disable"))
14800         enable = 0;
14801       else
14802         break;
14803     }
14804   if (if_id == ~0)
14805     {
14806       errmsg ("missing pg interface index\n");
14807       return -99;
14808     }
14809   if (pcap_file_set > 0)
14810     {
14811       if (vec_len (pcap_file) > 255)
14812         {
14813           errmsg ("pcap file name is too long\n");
14814           return -99;
14815         }
14816     }
14817
14818   u32 name_len = vec_len (pcap_file);
14819   /* Construct the API message */
14820   M (PG_CAPTURE, pg_capture);
14821   mp->context = 0;
14822   mp->interface_id = ntohl (if_id);
14823   mp->is_enabled = enable;
14824   mp->count = ntohl (count);
14825   mp->pcap_name_length = ntohl (name_len);
14826   if (pcap_file_set != 0)
14827     {
14828       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14829     }
14830   vec_free (pcap_file);
14831
14832   S;
14833   W;
14834   /* NOTREACHED */
14835   return 0;
14836 }
14837
14838 int
14839 api_pg_enable_disable (vat_main_t * vam)
14840 {
14841   unformat_input_t *input = vam->input;
14842   vl_api_pg_enable_disable_t *mp;
14843   f64 timeout;
14844
14845   u8 enable = 1;
14846   u8 stream_name_set = 0;
14847   u8 *stream_name = 0;
14848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14849     {
14850       if (unformat (input, "stream %s", &stream_name))
14851         stream_name_set = 1;
14852       else if (unformat (input, "disable"))
14853         enable = 0;
14854       else
14855         break;
14856     }
14857
14858   if (stream_name_set > 0)
14859     {
14860       if (vec_len (stream_name) > 255)
14861         {
14862           errmsg ("stream name too long\n");
14863           return -99;
14864         }
14865     }
14866
14867   u32 name_len = vec_len (stream_name);
14868   /* Construct the API message */
14869   M (PG_ENABLE_DISABLE, pg_enable_disable);
14870   mp->context = 0;
14871   mp->is_enabled = enable;
14872   if (stream_name_set != 0)
14873     {
14874       mp->stream_name_length = ntohl (name_len);
14875       clib_memcpy (mp->stream_name, stream_name, name_len);
14876     }
14877   vec_free (stream_name);
14878
14879   S;
14880   W;
14881   /* NOTREACHED */
14882   return 0;
14883 }
14884
14885 int
14886 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14887 {
14888   unformat_input_t *input = vam->input;
14889   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14890   f64 timeout;
14891
14892   u16 *low_ports = 0;
14893   u16 *high_ports = 0;
14894   u16 this_low;
14895   u16 this_hi;
14896   ip4_address_t ip4_addr;
14897   ip6_address_t ip6_addr;
14898   u32 length;
14899   u32 tmp, tmp2;
14900   u8 prefix_set = 0;
14901   u32 vrf_id = ~0;
14902   u8 is_add = 1;
14903   u8 is_ipv6 = 0;
14904
14905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14908         {
14909           prefix_set = 1;
14910         }
14911       else
14912         if (unformat
14913             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14914         {
14915           prefix_set = 1;
14916           is_ipv6 = 1;
14917         }
14918       else if (unformat (input, "vrf %d", &vrf_id))
14919         ;
14920       else if (unformat (input, "del"))
14921         is_add = 0;
14922       else if (unformat (input, "port %d", &tmp))
14923         {
14924           if (tmp == 0 || tmp > 65535)
14925             {
14926               errmsg ("port %d out of range", tmp);
14927               return -99;
14928             }
14929           this_low = tmp;
14930           this_hi = this_low + 1;
14931           vec_add1 (low_ports, this_low);
14932           vec_add1 (high_ports, this_hi);
14933         }
14934       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14935         {
14936           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14937             {
14938               errmsg ("incorrect range parameters\n");
14939               return -99;
14940             }
14941           this_low = tmp;
14942           /* Note: in debug CLI +1 is added to high before
14943              passing to real fn that does "the work"
14944              (ip_source_and_port_range_check_add_del).
14945              This fn is a wrapper around the binary API fn a
14946              control plane will call, which expects this increment
14947              to have occurred. Hence letting the binary API control
14948              plane fn do the increment for consistency between VAT
14949              and other control planes.
14950            */
14951           this_hi = tmp2;
14952           vec_add1 (low_ports, this_low);
14953           vec_add1 (high_ports, this_hi);
14954         }
14955       else
14956         break;
14957     }
14958
14959   if (prefix_set == 0)
14960     {
14961       errmsg ("<address>/<mask> not specified\n");
14962       return -99;
14963     }
14964
14965   if (vrf_id == ~0)
14966     {
14967       errmsg ("VRF ID required, not specified\n");
14968       return -99;
14969     }
14970
14971   if (vrf_id == 0)
14972     {
14973       errmsg
14974         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14975       return -99;
14976     }
14977
14978   if (vec_len (low_ports) == 0)
14979     {
14980       errmsg ("At least one port or port range required\n");
14981       return -99;
14982     }
14983
14984   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14985      ip_source_and_port_range_check_add_del);
14986
14987   mp->is_add = is_add;
14988
14989   if (is_ipv6)
14990     {
14991       mp->is_ipv6 = 1;
14992       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14993     }
14994   else
14995     {
14996       mp->is_ipv6 = 0;
14997       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14998     }
14999
15000   mp->mask_length = length;
15001   mp->number_of_ranges = vec_len (low_ports);
15002
15003   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15004   vec_free (low_ports);
15005
15006   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15007   vec_free (high_ports);
15008
15009   mp->vrf_id = ntohl (vrf_id);
15010
15011   S;
15012   W;
15013   /* NOTREACHED */
15014   return 0;
15015 }
15016
15017 int
15018 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15019 {
15020   unformat_input_t *input = vam->input;
15021   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15022   f64 timeout;
15023   u32 sw_if_index = ~0;
15024   int vrf_set = 0;
15025   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15026   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15027   u8 is_add = 1;
15028
15029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15030     {
15031       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15032         ;
15033       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15034         ;
15035       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15036         vrf_set = 1;
15037       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15038         vrf_set = 1;
15039       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15040         vrf_set = 1;
15041       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15042         vrf_set = 1;
15043       else if (unformat (input, "del"))
15044         is_add = 0;
15045       else
15046         break;
15047     }
15048
15049   if (sw_if_index == ~0)
15050     {
15051       errmsg ("Interface required but not specified\n");
15052       return -99;
15053     }
15054
15055   if (vrf_set == 0)
15056     {
15057       errmsg ("VRF ID required but not specified\n");
15058       return -99;
15059     }
15060
15061   if (tcp_out_vrf_id == 0
15062       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15063     {
15064       errmsg
15065         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15066       return -99;
15067     }
15068
15069   /* Construct the API message */
15070   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15071      ip_source_and_port_range_check_interface_add_del);
15072
15073   mp->sw_if_index = ntohl (sw_if_index);
15074   mp->is_add = is_add;
15075   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15076   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15077   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15078   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15079
15080   /* send it... */
15081   S;
15082
15083   /* Wait for a reply... */
15084   W;
15085 }
15086
15087 static int
15088 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15089 {
15090   unformat_input_t *i = vam->input;
15091   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15092   f64 timeout;
15093   u32 local_sa_id = 0;
15094   u32 remote_sa_id = 0;
15095   ip4_address_t src_address;
15096   ip4_address_t dst_address;
15097   u8 is_add = 1;
15098
15099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15100     {
15101       if (unformat (i, "local_sa %d", &local_sa_id))
15102         ;
15103       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15104         ;
15105       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15106         ;
15107       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15108         ;
15109       else if (unformat (i, "del"))
15110         is_add = 0;
15111       else
15112         {
15113           clib_warning ("parse error '%U'", format_unformat_error, i);
15114           return -99;
15115         }
15116     }
15117
15118   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15119
15120   mp->local_sa_id = ntohl (local_sa_id);
15121   mp->remote_sa_id = ntohl (remote_sa_id);
15122   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15123   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15124   mp->is_add = is_add;
15125
15126   S;
15127   W;
15128   /* NOTREACHED */
15129   return 0;
15130 }
15131
15132 static void vl_api_ipsec_gre_tunnel_details_t_handler
15133   (vl_api_ipsec_gre_tunnel_details_t * mp)
15134 {
15135   vat_main_t *vam = &vat_main;
15136
15137   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15138            ntohl (mp->sw_if_index),
15139            format_ip4_address, &mp->src_address,
15140            format_ip4_address, &mp->dst_address,
15141            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15142 }
15143
15144 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15145   (vl_api_ipsec_gre_tunnel_details_t * mp)
15146 {
15147   vat_main_t *vam = &vat_main;
15148   vat_json_node_t *node = NULL;
15149   struct in_addr ip4;
15150
15151   if (VAT_JSON_ARRAY != vam->json_tree.type)
15152     {
15153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15154       vat_json_init_array (&vam->json_tree);
15155     }
15156   node = vat_json_array_add (&vam->json_tree);
15157
15158   vat_json_init_object (node);
15159   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15160   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15161   vat_json_object_add_ip4 (node, "src_address", ip4);
15162   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15163   vat_json_object_add_ip4 (node, "dst_address", ip4);
15164   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15165   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15166 }
15167
15168 static int
15169 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15170 {
15171   unformat_input_t *i = vam->input;
15172   vl_api_ipsec_gre_tunnel_dump_t *mp;
15173   f64 timeout;
15174   u32 sw_if_index;
15175   u8 sw_if_index_set = 0;
15176
15177   /* Parse args required to build the message */
15178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15179     {
15180       if (unformat (i, "sw_if_index %d", &sw_if_index))
15181         sw_if_index_set = 1;
15182       else
15183         break;
15184     }
15185
15186   if (sw_if_index_set == 0)
15187     {
15188       sw_if_index = ~0;
15189     }
15190
15191   if (!vam->json_output)
15192     {
15193       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15194                "sw_if_index", "src_address", "dst_address",
15195                "local_sa_id", "remote_sa_id");
15196     }
15197
15198   /* Get list of gre-tunnel interfaces */
15199   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15200
15201   mp->sw_if_index = htonl (sw_if_index);
15202
15203   S;
15204
15205   /* Use a control ping for synchronization */
15206   {
15207     vl_api_control_ping_t *mp;
15208     M (CONTROL_PING, control_ping);
15209     S;
15210   }
15211   W;
15212 }
15213
15214 static int
15215 api_delete_subif (vat_main_t * vam)
15216 {
15217   unformat_input_t *i = vam->input;
15218   vl_api_delete_subif_t *mp;
15219   f64 timeout;
15220   u32 sw_if_index = ~0;
15221
15222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15223     {
15224       if (unformat (i, "sw_if_index %d", &sw_if_index))
15225         ;
15226       else
15227         break;
15228     }
15229
15230   if (sw_if_index == ~0)
15231     {
15232       errmsg ("missing sw_if_index\n");
15233       return -99;
15234     }
15235
15236   /* Construct the API message */
15237   M (DELETE_SUBIF, delete_subif);
15238   mp->sw_if_index = ntohl (sw_if_index);
15239
15240   S;
15241   W;
15242 }
15243
15244 static int
15245 q_or_quit (vat_main_t * vam)
15246 {
15247   longjmp (vam->jump_buf, 1);
15248   return 0;                     /* not so much */
15249 }
15250
15251 static int
15252 q (vat_main_t * vam)
15253 {
15254   return q_or_quit (vam);
15255 }
15256
15257 static int
15258 quit (vat_main_t * vam)
15259 {
15260   return q_or_quit (vam);
15261 }
15262
15263 static int
15264 comment (vat_main_t * vam)
15265 {
15266   return 0;
15267 }
15268
15269 static int
15270 cmd_cmp (void *a1, void *a2)
15271 {
15272   u8 **c1 = a1;
15273   u8 **c2 = a2;
15274
15275   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15276 }
15277
15278 static int
15279 help (vat_main_t * vam)
15280 {
15281   u8 **cmds = 0;
15282   u8 *name = 0;
15283   hash_pair_t *p;
15284   unformat_input_t *i = vam->input;
15285   int j;
15286
15287   if (unformat (i, "%s", &name))
15288     {
15289       uword *hs;
15290
15291       vec_add1 (name, 0);
15292
15293       hs = hash_get_mem (vam->help_by_name, name);
15294       if (hs)
15295         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15296       else
15297         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15298       vec_free (name);
15299       return 0;
15300     }
15301
15302   fformat (vam->ofp, "Help is available for the following:\n");
15303
15304     /* *INDENT-OFF* */
15305     hash_foreach_pair (p, vam->function_by_name,
15306     ({
15307       vec_add1 (cmds, (u8 *)(p->key));
15308     }));
15309     /* *INDENT-ON* */
15310
15311   vec_sort_with_function (cmds, cmd_cmp);
15312
15313   for (j = 0; j < vec_len (cmds); j++)
15314     fformat (vam->ofp, "%s\n", cmds[j]);
15315
15316   vec_free (cmds);
15317   return 0;
15318 }
15319
15320 static int
15321 set (vat_main_t * vam)
15322 {
15323   u8 *name = 0, *value = 0;
15324   unformat_input_t *i = vam->input;
15325
15326   if (unformat (i, "%s", &name))
15327     {
15328       /* The input buffer is a vector, not a string. */
15329       value = vec_dup (i->buffer);
15330       vec_delete (value, i->index, 0);
15331       /* Almost certainly has a trailing newline */
15332       if (value[vec_len (value) - 1] == '\n')
15333         value[vec_len (value) - 1] = 0;
15334       /* Make sure it's a proper string, one way or the other */
15335       vec_add1 (value, 0);
15336       (void) clib_macro_set_value (&vam->macro_main,
15337                                    (char *) name, (char *) value);
15338     }
15339   else
15340     errmsg ("usage: set <name> <value>\n");
15341
15342   vec_free (name);
15343   vec_free (value);
15344   return 0;
15345 }
15346
15347 static int
15348 unset (vat_main_t * vam)
15349 {
15350   u8 *name = 0;
15351
15352   if (unformat (vam->input, "%s", &name))
15353     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15354       errmsg ("unset: %s wasn't set\n", name);
15355   vec_free (name);
15356   return 0;
15357 }
15358
15359 typedef struct
15360 {
15361   u8 *name;
15362   u8 *value;
15363 } macro_sort_t;
15364
15365
15366 static int
15367 macro_sort_cmp (void *a1, void *a2)
15368 {
15369   macro_sort_t *s1 = a1;
15370   macro_sort_t *s2 = a2;
15371
15372   return strcmp ((char *) (s1->name), (char *) (s2->name));
15373 }
15374
15375 static int
15376 dump_macro_table (vat_main_t * vam)
15377 {
15378   macro_sort_t *sort_me = 0, *sm;
15379   int i;
15380   hash_pair_t *p;
15381
15382     /* *INDENT-OFF* */
15383     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15384     ({
15385       vec_add2 (sort_me, sm, 1);
15386       sm->name = (u8 *)(p->key);
15387       sm->value = (u8 *) (p->value[0]);
15388     }));
15389     /* *INDENT-ON* */
15390
15391   vec_sort_with_function (sort_me, macro_sort_cmp);
15392
15393   if (vec_len (sort_me))
15394     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15395   else
15396     fformat (vam->ofp, "The macro table is empty...\n");
15397
15398   for (i = 0; i < vec_len (sort_me); i++)
15399     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15400   return 0;
15401 }
15402
15403 static int
15404 dump_node_table (vat_main_t * vam)
15405 {
15406   int i, j;
15407   vlib_node_t *node, *next_node;
15408
15409   if (vec_len (vam->graph_nodes) == 0)
15410     {
15411       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15412       return 0;
15413     }
15414
15415   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15416     {
15417       node = vam->graph_nodes[i];
15418       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15419       for (j = 0; j < vec_len (node->next_nodes); j++)
15420         {
15421           if (node->next_nodes[j] != ~0)
15422             {
15423               next_node = vam->graph_nodes[node->next_nodes[j]];
15424               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15425             }
15426         }
15427     }
15428   return 0;
15429 }
15430
15431 static int
15432 search_node_table (vat_main_t * vam)
15433 {
15434   unformat_input_t *line_input = vam->input;
15435   u8 *node_to_find;
15436   int j;
15437   vlib_node_t *node, *next_node;
15438   uword *p;
15439
15440   if (vam->graph_node_index_by_name == 0)
15441     {
15442       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15443       return 0;
15444     }
15445
15446   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15447     {
15448       if (unformat (line_input, "%s", &node_to_find))
15449         {
15450           vec_add1 (node_to_find, 0);
15451           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15452           if (p == 0)
15453             {
15454               fformat (vam->ofp, "%s not found...\n", node_to_find);
15455               goto out;
15456             }
15457           node = vam->graph_nodes[p[0]];
15458           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15459           for (j = 0; j < vec_len (node->next_nodes); j++)
15460             {
15461               if (node->next_nodes[j] != ~0)
15462                 {
15463                   next_node = vam->graph_nodes[node->next_nodes[j]];
15464                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15465                 }
15466             }
15467         }
15468
15469       else
15470         {
15471           clib_warning ("parse error '%U'", format_unformat_error,
15472                         line_input);
15473           return -99;
15474         }
15475
15476     out:
15477       vec_free (node_to_find);
15478
15479     }
15480
15481   return 0;
15482 }
15483
15484
15485 static int
15486 script (vat_main_t * vam)
15487 {
15488   u8 *s = 0;
15489   char *save_current_file;
15490   unformat_input_t save_input;
15491   jmp_buf save_jump_buf;
15492   u32 save_line_number;
15493
15494   FILE *new_fp, *save_ifp;
15495
15496   if (unformat (vam->input, "%s", &s))
15497     {
15498       new_fp = fopen ((char *) s, "r");
15499       if (new_fp == 0)
15500         {
15501           errmsg ("Couldn't open script file %s\n", s);
15502           vec_free (s);
15503           return -99;
15504         }
15505     }
15506   else
15507     {
15508       errmsg ("Missing script name\n");
15509       return -99;
15510     }
15511
15512   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15513   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15514   save_ifp = vam->ifp;
15515   save_line_number = vam->input_line_number;
15516   save_current_file = (char *) vam->current_file;
15517
15518   vam->input_line_number = 0;
15519   vam->ifp = new_fp;
15520   vam->current_file = s;
15521   do_one_file (vam);
15522
15523   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15524   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15525   vam->ifp = save_ifp;
15526   vam->input_line_number = save_line_number;
15527   vam->current_file = (u8 *) save_current_file;
15528   vec_free (s);
15529
15530   return 0;
15531 }
15532
15533 static int
15534 echo (vat_main_t * vam)
15535 {
15536   fformat (vam->ofp, "%v", vam->input->buffer);
15537   return 0;
15538 }
15539
15540 /* List of API message constructors, CLI names map to api_xxx */
15541 #define foreach_vpe_api_msg                                             \
15542 _(create_loopback,"[mac <mac-addr>]")                                   \
15543 _(sw_interface_dump,"")                                                 \
15544 _(sw_interface_set_flags,                                               \
15545   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15546 _(sw_interface_add_del_address,                                         \
15547   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15548 _(sw_interface_set_table,                                               \
15549   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15550 _(sw_interface_set_vpath,                                               \
15551   "<intfc> | sw_if_index <id> enable | disable")                        \
15552 _(sw_interface_set_l2_xconnect,                                         \
15553   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15554   "enable | disable")                                                   \
15555 _(sw_interface_set_l2_bridge,                                           \
15556   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15557   "[shg <split-horizon-group>] [bvi]\n"                                 \
15558   "enable | disable")                                                   \
15559 _(bridge_domain_add_del,                                                \
15560   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15561 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15562 _(l2fib_add_del,                                                        \
15563   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15564 _(l2_flags,                                                             \
15565   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15566 _(bridge_flags,                                                         \
15567   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15568 _(tap_connect,                                                          \
15569   "tapname <name> mac <mac-addr> | random-mac")                         \
15570 _(tap_modify,                                                           \
15571   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15572 _(tap_delete,                                                           \
15573   "<vpp-if-name> | sw_if_index <id>")                                   \
15574 _(sw_interface_tap_dump, "")                                            \
15575 _(ip_add_del_route,                                                     \
15576   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15577   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15578   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15579   "[multipath] [count <n>]")                                            \
15580 _(proxy_arp_add_del,                                                    \
15581   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15582 _(proxy_arp_intfc_enable_disable,                                       \
15583   "<intfc> | sw_if_index <id> enable | disable")                        \
15584 _(mpls_add_del_encap,                                                   \
15585   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15586 _(mpls_add_del_decap,                                                   \
15587   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15588 _(mpls_gre_add_del_tunnel,                                              \
15589   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15590   "adj <ip4-address>/<mask-width> [del]")                               \
15591 _(sw_interface_set_unnumbered,                                          \
15592   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15593 _(ip_neighbor_add_del,                                                  \
15594   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15595   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15596 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15597 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15598 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15599   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15600   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15601   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15602 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15603 _(reset_fib, "vrf <n> [ipv6]")                                          \
15604 _(dhcp_proxy_config,                                                    \
15605   "svr <v46-address> src <v46-address>\n"                               \
15606    "insert-cid <n> [del]")                                              \
15607 _(dhcp_proxy_config_2,                                                  \
15608   "svr <v46-address> src <v46-address>\n"                               \
15609    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15610 _(dhcp_proxy_set_vss,                                                   \
15611   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15612 _(dhcp_client_config,                                                   \
15613   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15614 _(set_ip_flow_hash,                                                     \
15615   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15616 _(sw_interface_ip6_enable_disable,                                      \
15617   "<intfc> | sw_if_index <id> enable | disable")                        \
15618 _(sw_interface_ip6_set_link_local_address,                              \
15619   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15620 _(sw_interface_ip6nd_ra_prefix,                                         \
15621   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15622   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15623   "[nolink] [isno]")                                                    \
15624 _(sw_interface_ip6nd_ra_config,                                         \
15625   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15626   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15627   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15628 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15629 _(l2_patch_add_del,                                                     \
15630   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15631   "enable | disable")                                                   \
15632 _(mpls_ethernet_add_del_tunnel,                                         \
15633   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15634   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15635 _(mpls_ethernet_add_del_tunnel_2,                                       \
15636   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15637   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15638 _(sr_tunnel_add_del,                                                    \
15639   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15640   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15641   "[policy <policy_name>]")                                             \
15642 _(sr_policy_add_del,                                                    \
15643   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15644 _(sr_multicast_map_add_del,                                             \
15645   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15646 _(classify_add_del_table,                                               \
15647   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15648   "[del] mask <mask-value>\n"                                           \
15649   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15650 _(classify_add_del_session,                                             \
15651   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15652   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15653   "  [l3 [ip4|ip6]]")                                                   \
15654 _(classify_set_interface_ip_table,                                      \
15655   "<intfc> | sw_if_index <nn> table <nn>")                              \
15656 _(classify_set_interface_l2_tables,                                     \
15657   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15658   "  [other-table <nn>]")                                               \
15659 _(get_node_index, "node <node-name")                                    \
15660 _(add_node_next, "node <node-name> next <next-node-name>")              \
15661 _(l2tpv3_create_tunnel,                                                 \
15662   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15663   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15664   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15665 _(l2tpv3_set_tunnel_cookies,                                            \
15666   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15667   "[new_remote_cookie <nn>]\n")                                         \
15668 _(l2tpv3_interface_enable_disable,                                      \
15669   "<intfc> | sw_if_index <nn> enable | disable")                        \
15670 _(l2tpv3_set_lookup_key,                                                \
15671   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15672 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15673 _(vxlan_add_del_tunnel,                                                 \
15674   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15675   " [decap-next l2|ip4|ip6] [del]")                                     \
15676 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15677 _(gre_add_del_tunnel,                                                   \
15678   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15679 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15680 _(l2_fib_clear_table, "")                                               \
15681 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15682 _(l2_interface_vlan_tag_rewrite,                                        \
15683   "<intfc> | sw_if_index <nn> \n"                                       \
15684   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15685   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15686 _(create_vhost_user_if,                                                 \
15687         "socket <filename> [server] [renumber <dev_instance>] "         \
15688         "[mac <mac_address>]")                                          \
15689 _(modify_vhost_user_if,                                                 \
15690         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15691         "[server] [renumber <dev_instance>]")                           \
15692 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15693 _(sw_interface_vhost_user_dump, "")                                     \
15694 _(show_version, "")                                                     \
15695 _(vxlan_gpe_add_del_tunnel,                                             \
15696   "local <addr> remote <addr> vni <nn>\n"                               \
15697     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15698   "[next-ethernet] [next-nsh]\n")                                       \
15699 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15700 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15701 _(interface_name_renumber,                                              \
15702   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15703 _(input_acl_set_interface,                                              \
15704   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15705   "  [l2-table <nn>] [del]")                                            \
15706 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15707 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15708 _(ip_dump, "ipv4 | ipv6")                                               \
15709 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15710 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15711   "  spid_id <n> ")                                                     \
15712 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15713   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15714   "  integ_alg <alg> integ_key <hex>")                                  \
15715 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15716   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15717   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15718   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15719 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15720 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15721 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15722   "(auth_data 0x<data> | auth_data <data>)")                            \
15723 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15724   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15725 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15726   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15727   "(local|remote)")                                                     \
15728 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15729 _(delete_loopback,"sw_if_index <nn>")                                   \
15730 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15731 _(map_add_domain,                                                       \
15732   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15733   "ip6-src <ip6addr> "                                                  \
15734   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15735 _(map_del_domain, "index <n>")                                          \
15736 _(map_add_del_rule,                                                     \
15737   "index <n> psid <n> dst <ip6addr> [del]")                             \
15738 _(map_domain_dump, "")                                                  \
15739 _(map_rule_dump, "index <map-domain>")                                  \
15740 _(want_interface_events,  "enable|disable")                             \
15741 _(want_stats,"enable|disable")                                          \
15742 _(get_first_msg_id, "client <name>")                                    \
15743 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15744 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15745   "fib-id <nn> [ip4][ip6][default]")                                    \
15746 _(get_node_graph, " ")                                                  \
15747 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15748 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15749   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15750   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15751 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15752   " vrf_id <nn>  add | pop | none")                                     \
15753 _(trace_profile_del, "")                                                \
15754 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15755                             " sw_if_index <sw_if_index> p <priority> "  \
15756                             "w <weight>] [del]")                        \
15757 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15758                         "iface <intf> | sw_if_index <sw_if_index> "     \
15759                         "p <priority> w <weight> [del]")                \
15760 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15761                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15762                           "locator-set <locator_name> [del]")           \
15763 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15764   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15765 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15766 _(lisp_gpe_enable_disable, "enable|disable")                            \
15767 _(lisp_enable_disable, "enable|disable")                                \
15768 _(lisp_gpe_add_del_iface, "up|down")                                    \
15769 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15770                                "rloc <locator> p <prio> "               \
15771                                "w <weight> [rloc <loc> ... ] "          \
15772                                "action <action> [del-all]")             \
15773 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15774                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15775                           "[rloc <loc> ... ] action <action>")          \
15776 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15777 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15778 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15779 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15780                          "locator-set <loc-set-name>] [local | remote]")\
15781 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15782                        "[local] | [remote]")                            \
15783 _(lisp_eid_table_vni_dump, "")                                          \
15784 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15785 _(lisp_gpe_tunnel_dump, "")                                             \
15786 _(lisp_map_resolver_dump, "")                                           \
15787 _(show_lisp_status, "")                                                 \
15788 _(lisp_get_map_request_itr_rlocs, "")                                   \
15789 _(show_lisp_pitr, "")                                                   \
15790 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15791 _(af_packet_delete, "name <host interface name>")                       \
15792 _(policer_add_del, "name <policer name> <params> [del]")                \
15793 _(policer_dump, "[name <policer name>]")                                \
15794 _(policer_classify_set_interface,                                       \
15795   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15796   "  [l2-table <nn>] [del]")                                            \
15797 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15798 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15799     "[master|slave]")                                                   \
15800 _(netmap_delete, "name <interface name>")                               \
15801 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15802 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15803 _(mpls_fib_encap_dump, "")                                              \
15804 _(mpls_fib_decap_dump, "")                                              \
15805 _(classify_table_ids, "")                                               \
15806 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15807 _(classify_table_info, "table_id <nn>")                                 \
15808 _(classify_session_dump, "table_id <nn>")                               \
15809 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15810                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15811                 "[template_interval <nn>]")                             \
15812 _(ipfix_dump, "")                                                       \
15813 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15814 _(pg_create_interface, "if_id <nn>")                                    \
15815 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15816 _(pg_enable_disable, "[stream <id>] disable")                           \
15817 _(ip_source_and_port_range_check_add_del,                               \
15818   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15819 _(ip_source_and_port_range_check_interface_add_del,                     \
15820   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15821   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15822 _(ipsec_gre_add_del_tunnel,                                             \
15823   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15824 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15825 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15826
15827 /* List of command functions, CLI names map directly to functions */
15828 #define foreach_cli_function                                    \
15829 _(comment, "usage: comment <ignore-rest-of-line>")              \
15830 _(dump_interface_table, "usage: dump_interface_table")          \
15831 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15832 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15833 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15834 _(dump_stats_table, "usage: dump_stats_table")                  \
15835 _(dump_macro_table, "usage: dump_macro_table ")                 \
15836 _(dump_node_table, "usage: dump_node_table")                    \
15837 _(echo, "usage: echo <message>")                                \
15838 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15839 _(help, "usage: help")                                          \
15840 _(q, "usage: quit")                                             \
15841 _(quit, "usage: quit")                                          \
15842 _(search_node_table, "usage: search_node_table <name>...")      \
15843 _(set, "usage: set <variable-name> <value>")                    \
15844 _(script, "usage: script <file-name>")                          \
15845 _(unset, "usage: unset <variable-name>")
15846
15847 #define _(N,n)                                  \
15848     static void vl_api_##n##_t_handler_uni      \
15849     (vl_api_##n##_t * mp)                       \
15850     {                                           \
15851         vat_main_t * vam = &vat_main;           \
15852         if (vam->json_output) {                 \
15853             vl_api_##n##_t_handler_json(mp);    \
15854         } else {                                \
15855             vl_api_##n##_t_handler(mp);         \
15856         }                                       \
15857     }
15858 foreach_vpe_api_reply_msg;
15859 #undef _
15860
15861 void
15862 vat_api_hookup (vat_main_t * vam)
15863 {
15864 #define _(N,n)                                                  \
15865     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15866                            vl_api_##n##_t_handler_uni,          \
15867                            vl_noop_handler,                     \
15868                            vl_api_##n##_t_endian,               \
15869                            vl_api_##n##_t_print,                \
15870                            sizeof(vl_api_##n##_t), 1);
15871   foreach_vpe_api_reply_msg;
15872 #undef _
15873
15874   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15875
15876   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15877
15878   vam->function_by_name = hash_create_string (0, sizeof (uword));
15879
15880   vam->help_by_name = hash_create_string (0, sizeof (uword));
15881
15882   /* API messages we can send */
15883 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15884   foreach_vpe_api_msg;
15885 #undef _
15886
15887   /* Help strings */
15888 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15889   foreach_vpe_api_msg;
15890 #undef _
15891
15892   /* CLI functions */
15893 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15894   foreach_cli_function;
15895 #undef _
15896
15897   /* Help strings */
15898 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15899   foreach_cli_function;
15900 #undef _
15901 }
15902
15903 #undef vl_api_version
15904 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15905 #include <vpp-api/vpe.api.h>
15906 #undef vl_api_version
15907
15908 void
15909 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15910 {
15911   /*
15912    * Send the main API signature in slot 0. This bit of code must
15913    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15914    */
15915   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15916 }
15917
15918 /*
15919  * fd.io coding-style-patch-verification: ON
15920  *
15921  * Local Variables:
15922  * eval: (c-set-style "gnu")
15923  * End:
15924  */