12e8a9565aa2307b83ddcc363c37cb256652175c
[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/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1155           mp->mac_ip ? "mac/ip binding" : "address resolution",
1156           format_ip4_address, &mp->address,
1157           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1158 }
1159
1160 static void
1161 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1162 {
1163   /* JSON output not supported */
1164 }
1165
1166 static void
1167 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1171           mp->mac_ip ? "mac/ip binding" : "address resolution",
1172           format_ip6_address, mp->address,
1173           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1174 }
1175
1176 static void
1177 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1178 {
1179   /* JSON output not supported */
1180 }
1181
1182 /*
1183  * Special-case: build the bridge domain table, maintain
1184  * the next bd id vbl.
1185  */
1186 static void vl_api_bridge_domain_details_t_handler
1187   (vl_api_bridge_domain_details_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1191
1192   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1193            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1194
1195   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1196            ntohl (mp->bd_id), mp->learn, mp->forward,
1197            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1198
1199   if (n_sw_ifs)
1200     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1201              "Interface Name");
1202 }
1203
1204 static void vl_api_bridge_domain_details_t_handler_json
1205   (vl_api_bridge_domain_details_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t *node, *array = NULL;
1209
1210   if (VAT_JSON_ARRAY != vam->json_tree.type)
1211     {
1212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1213       vat_json_init_array (&vam->json_tree);
1214     }
1215   node = vat_json_array_add (&vam->json_tree);
1216
1217   vat_json_init_object (node);
1218   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1219   vat_json_object_add_uint (node, "flood", mp->flood);
1220   vat_json_object_add_uint (node, "forward", mp->forward);
1221   vat_json_object_add_uint (node, "learn", mp->learn);
1222   vat_json_object_add_uint (node, "bvi_sw_if_index",
1223                             ntohl (mp->bvi_sw_if_index));
1224   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1225   array = vat_json_object_add (node, "sw_if");
1226   vat_json_init_array (array);
1227 }
1228
1229 /*
1230  * Special-case: build the bridge domain sw if table.
1231  */
1232 static void vl_api_bridge_domain_sw_if_details_t_handler
1233   (vl_api_bridge_domain_sw_if_details_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   hash_pair_t *p;
1237   u8 *sw_if_name = 0;
1238   u32 sw_if_index;
1239
1240   sw_if_index = ntohl (mp->sw_if_index);
1241   /* *INDENT-OFF* */
1242   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1243   ({
1244     if ((u32) p->value[0] == sw_if_index)
1245       {
1246         sw_if_name = (u8 *)(p->key);
1247         break;
1248       }
1249   }));
1250   /* *INDENT-ON* */
1251
1252   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1253            mp->shg, sw_if_name ? (char *) sw_if_name :
1254            "sw_if_index not found!");
1255 }
1256
1257 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1258   (vl_api_bridge_domain_sw_if_details_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t *node = NULL;
1262   uword last_index = 0;
1263
1264   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1265   ASSERT (vec_len (vam->json_tree.array) >= 1);
1266   last_index = vec_len (vam->json_tree.array) - 1;
1267   node = &vam->json_tree.array[last_index];
1268   node = vat_json_object_get_element (node, "sw_if");
1269   ASSERT (NULL != node);
1270   node = vat_json_array_add (node);
1271
1272   vat_json_init_object (node);
1273   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1275   vat_json_object_add_uint (node, "shg", mp->shg);
1276 }
1277
1278 static void vl_api_control_ping_reply_t_handler
1279   (vl_api_control_ping_reply_t * mp)
1280 {
1281   vat_main_t *vam = &vat_main;
1282   i32 retval = ntohl (mp->retval);
1283   if (vam->async_mode)
1284     {
1285       vam->async_errors += (retval < 0);
1286     }
1287   else
1288     {
1289       vam->retval = retval;
1290       vam->result_ready = 1;
1291     }
1292 }
1293
1294 static void vl_api_control_ping_reply_t_handler_json
1295   (vl_api_control_ping_reply_t * mp)
1296 {
1297   vat_main_t *vam = &vat_main;
1298   i32 retval = ntohl (mp->retval);
1299
1300   if (VAT_JSON_NONE != vam->json_tree.type)
1301     {
1302       vat_json_print (vam->ofp, &vam->json_tree);
1303       vat_json_free (&vam->json_tree);
1304       vam->json_tree.type = VAT_JSON_NONE;
1305     }
1306   else
1307     {
1308       /* just print [] */
1309       vat_json_init_array (&vam->json_tree);
1310       vat_json_print (vam->ofp, &vam->json_tree);
1311       vam->json_tree.type = VAT_JSON_NONE;
1312     }
1313
1314   vam->retval = retval;
1315   vam->result_ready = 1;
1316 }
1317
1318 static void
1319 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1320 {
1321   vat_main_t *vam = &vat_main;
1322   i32 retval = ntohl (mp->retval);
1323   if (vam->async_mode)
1324     {
1325       vam->async_errors += (retval < 0);
1326     }
1327   else
1328     {
1329       vam->retval = retval;
1330       vam->result_ready = 1;
1331     }
1332 }
1333
1334 static void vl_api_l2_flags_reply_t_handler_json
1335   (vl_api_l2_flags_reply_t * mp)
1336 {
1337   vat_main_t *vam = &vat_main;
1338   vat_json_node_t node;
1339
1340   vat_json_init_object (&node);
1341   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1342   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1343                             ntohl (mp->resulting_feature_bitmap));
1344
1345   vat_json_print (vam->ofp, &node);
1346   vat_json_free (&node);
1347
1348   vam->retval = ntohl (mp->retval);
1349   vam->result_ready = 1;
1350 }
1351
1352 static void vl_api_bridge_flags_reply_t_handler
1353   (vl_api_bridge_flags_reply_t * mp)
1354 {
1355   vat_main_t *vam = &vat_main;
1356   i32 retval = ntohl (mp->retval);
1357   if (vam->async_mode)
1358     {
1359       vam->async_errors += (retval < 0);
1360     }
1361   else
1362     {
1363       vam->retval = retval;
1364       vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_bridge_flags_reply_t_handler_json
1369   (vl_api_bridge_flags_reply_t * mp)
1370 {
1371   vat_main_t *vam = &vat_main;
1372   vat_json_node_t node;
1373
1374   vat_json_init_object (&node);
1375   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1376   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1377                             ntohl (mp->resulting_feature_bitmap));
1378
1379   vat_json_print (vam->ofp, &node);
1380   vat_json_free (&node);
1381
1382   vam->retval = ntohl (mp->retval);
1383   vam->result_ready = 1;
1384 }
1385
1386 static void vl_api_tap_connect_reply_t_handler
1387   (vl_api_tap_connect_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->sw_if_index = ntohl (mp->sw_if_index);
1399       vam->result_ready = 1;
1400     }
1401
1402 }
1403
1404 static void vl_api_tap_connect_reply_t_handler_json
1405   (vl_api_tap_connect_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409
1410   vat_json_init_object (&node);
1411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1413
1414   vat_json_print (vam->ofp, &node);
1415   vat_json_free (&node);
1416
1417   vam->retval = ntohl (mp->retval);
1418   vam->result_ready = 1;
1419
1420 }
1421
1422 static void
1423 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1424 {
1425   vat_main_t *vam = &vat_main;
1426   i32 retval = ntohl (mp->retval);
1427   if (vam->async_mode)
1428     {
1429       vam->async_errors += (retval < 0);
1430     }
1431   else
1432     {
1433       vam->retval = retval;
1434       vam->sw_if_index = ntohl (mp->sw_if_index);
1435       vam->result_ready = 1;
1436     }
1437 }
1438
1439 static void vl_api_tap_modify_reply_t_handler_json
1440   (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   vat_json_node_t node;
1444
1445   vat_json_init_object (&node);
1446   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1447   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1448
1449   vat_json_print (vam->ofp, &node);
1450   vat_json_free (&node);
1451
1452   vam->retval = ntohl (mp->retval);
1453   vam->result_ready = 1;
1454 }
1455
1456 static void
1457 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   i32 retval = ntohl (mp->retval);
1461   if (vam->async_mode)
1462     {
1463       vam->async_errors += (retval < 0);
1464     }
1465   else
1466     {
1467       vam->retval = retval;
1468       vam->result_ready = 1;
1469     }
1470 }
1471
1472 static void vl_api_tap_delete_reply_t_handler_json
1473   (vl_api_tap_delete_reply_t * mp)
1474 {
1475   vat_main_t *vam = &vat_main;
1476   vat_json_node_t node;
1477
1478   vat_json_init_object (&node);
1479   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1480
1481   vat_json_print (vam->ofp, &node);
1482   vat_json_free (&node);
1483
1484   vam->retval = ntohl (mp->retval);
1485   vam->result_ready = 1;
1486 }
1487
1488 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1489   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1490 {
1491   vat_main_t *vam = &vat_main;
1492   i32 retval = ntohl (mp->retval);
1493   if (vam->async_mode)
1494     {
1495       vam->async_errors += (retval < 0);
1496     }
1497   else
1498     {
1499       vam->retval = retval;
1500       vam->result_ready = 1;
1501     }
1502 }
1503
1504 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1505   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1506 {
1507   vat_main_t *vam = &vat_main;
1508   vat_json_node_t node;
1509
1510   vat_json_init_object (&node);
1511   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1512   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1513                             ntohl (mp->tunnel_sw_if_index));
1514
1515   vat_json_print (vam->ofp, &node);
1516   vat_json_free (&node);
1517
1518   vam->retval = ntohl (mp->retval);
1519   vam->result_ready = 1;
1520 }
1521
1522 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1523   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1524 {
1525   vat_main_t *vam = &vat_main;
1526   i32 retval = ntohl (mp->retval);
1527   if (vam->async_mode)
1528     {
1529       vam->async_errors += (retval < 0);
1530     }
1531   else
1532     {
1533       vam->retval = retval;
1534       vam->sw_if_index = ntohl (mp->sw_if_index);
1535       vam->result_ready = 1;
1536     }
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   vat_json_node_t node;
1544
1545   vat_json_init_object (&node);
1546   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1547   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1548
1549   vat_json_print (vam->ofp, &node);
1550   vat_json_free (&node);
1551
1552   vam->retval = ntohl (mp->retval);
1553   vam->result_ready = 1;
1554 }
1555
1556
1557 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1558   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1559 {
1560   vat_main_t *vam = &vat_main;
1561   i32 retval = ntohl (mp->retval);
1562   if (vam->async_mode)
1563     {
1564       vam->async_errors += (retval < 0);
1565     }
1566   else
1567     {
1568       vam->retval = retval;
1569       vam->result_ready = 1;
1570     }
1571 }
1572
1573 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1574   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1575 {
1576   vat_main_t *vam = &vat_main;
1577   vat_json_node_t node;
1578
1579   vat_json_init_object (&node);
1580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1581   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1582
1583   vat_json_print (vam->ofp, &node);
1584   vat_json_free (&node);
1585
1586   vam->retval = ntohl (mp->retval);
1587   vam->result_ready = 1;
1588 }
1589
1590 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1591   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   i32 retval = ntohl (mp->retval);
1595   if (vam->async_mode)
1596     {
1597       vam->async_errors += (retval < 0);
1598     }
1599   else
1600     {
1601       vam->retval = retval;
1602       vam->sw_if_index = ntohl (mp->sw_if_index);
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1616
1617   vat_json_print (vam->ofp, &node);
1618   vat_json_free (&node);
1619
1620   vam->retval = ntohl (mp->retval);
1621   vam->result_ready = 1;
1622 }
1623
1624 static void vl_api_gre_add_del_tunnel_reply_t_handler
1625   (vl_api_gre_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->sw_if_index = ntohl (mp->sw_if_index);
1637       vam->result_ready = 1;
1638     }
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   vat_json_node_t node;
1646
1647   vat_json_init_object (&node);
1648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1649   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1650
1651   vat_json_print (vam->ofp, &node);
1652   vat_json_free (&node);
1653
1654   vam->retval = ntohl (mp->retval);
1655   vam->result_ready = 1;
1656 }
1657
1658 static void vl_api_create_vhost_user_if_reply_t_handler
1659   (vl_api_create_vhost_user_if_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   i32 retval = ntohl (mp->retval);
1663   if (vam->async_mode)
1664     {
1665       vam->async_errors += (retval < 0);
1666     }
1667   else
1668     {
1669       vam->retval = retval;
1670       vam->sw_if_index = ntohl (mp->sw_if_index);
1671       vam->result_ready = 1;
1672     }
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler_json
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   vat_json_node_t node;
1680
1681   vat_json_init_object (&node);
1682   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1683   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1684
1685   vat_json_print (vam->ofp, &node);
1686   vat_json_free (&node);
1687
1688   vam->retval = ntohl (mp->retval);
1689   vam->result_ready = 1;
1690 }
1691
1692 static void vl_api_ip_address_details_t_handler
1693   (vl_api_ip_address_details_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   static ip_address_details_t empty_ip_address_details = { {0} };
1697   ip_address_details_t *address = NULL;
1698   ip_details_t *current_ip_details = NULL;
1699   ip_details_t *details = NULL;
1700
1701   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1702
1703   if (!details || vam->current_sw_if_index >= vec_len (details)
1704       || !details[vam->current_sw_if_index].present)
1705     {
1706       errmsg ("ip address details arrived but not stored\n");
1707       errmsg ("ip_dump should be called first\n");
1708       return;
1709     }
1710
1711   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1712
1713 #define addresses (current_ip_details->addr)
1714
1715   vec_validate_init_empty (addresses, vec_len (addresses),
1716                            empty_ip_address_details);
1717
1718   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1719
1720   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1721   address->prefix_length = mp->prefix_length;
1722 #undef addresses
1723 }
1724
1725 static void vl_api_ip_address_details_t_handler_json
1726   (vl_api_ip_address_details_t * mp)
1727 {
1728   vat_main_t *vam = &vat_main;
1729   vat_json_node_t *node = NULL;
1730   struct in6_addr ip6;
1731   struct in_addr ip4;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   node = vat_json_array_add (&vam->json_tree);
1739
1740   vat_json_init_object (node);
1741   if (vam->is_ipv6)
1742     {
1743       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1744       vat_json_object_add_ip6 (node, "ip", ip6);
1745     }
1746   else
1747     {
1748       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1749       vat_json_object_add_ip4 (node, "ip", ip4);
1750     }
1751   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1752 }
1753
1754 static void
1755 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1756 {
1757   vat_main_t *vam = &vat_main;
1758   static ip_details_t empty_ip_details = { 0 };
1759   ip_details_t *ip = NULL;
1760   u32 sw_if_index = ~0;
1761
1762   sw_if_index = ntohl (mp->sw_if_index);
1763
1764   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1765                            sw_if_index, empty_ip_details);
1766
1767   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1768                          sw_if_index);
1769
1770   ip->present = 1;
1771 }
1772
1773 static void
1774 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1775 {
1776   vat_main_t *vam = &vat_main;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   vat_json_array_add_uint (&vam->json_tree,
1784                            clib_net_to_host_u32 (mp->sw_if_index));
1785 }
1786
1787 static void vl_api_map_domain_details_t_handler_json
1788   (vl_api_map_domain_details_t * mp)
1789 {
1790   vat_json_node_t *node = NULL;
1791   vat_main_t *vam = &vat_main;
1792   struct in6_addr ip6;
1793   struct in_addr ip4;
1794
1795   if (VAT_JSON_ARRAY != vam->json_tree.type)
1796     {
1797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1798       vat_json_init_array (&vam->json_tree);
1799     }
1800
1801   node = vat_json_array_add (&vam->json_tree);
1802   vat_json_init_object (node);
1803
1804   vat_json_object_add_uint (node, "domain_index",
1805                             clib_net_to_host_u32 (mp->domain_index));
1806   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1807   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1808   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1809   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1810   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1811   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1812   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1813   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1814   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1815   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1816   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1817   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1818   vat_json_object_add_uint (node, "flags", mp->flags);
1819   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1820   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1821 }
1822
1823 static void vl_api_map_domain_details_t_handler
1824   (vl_api_map_domain_details_t * mp)
1825 {
1826   vat_main_t *vam = &vat_main;
1827
1828   if (mp->is_translation)
1829     {
1830       fformat (vam->ofp,
1831                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1832                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1833                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1834                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1835                clib_net_to_host_u32 (mp->domain_index));
1836     }
1837   else
1838     {
1839       fformat (vam->ofp,
1840                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1841                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1842                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1843                format_ip6_address, mp->ip6_src,
1844                clib_net_to_host_u32 (mp->domain_index));
1845     }
1846   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1847            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1848            mp->is_translation ? "map-t" : "");
1849 }
1850
1851 static void vl_api_map_rule_details_t_handler_json
1852   (vl_api_map_rule_details_t * mp)
1853 {
1854   struct in6_addr ip6;
1855   vat_json_node_t *node = NULL;
1856   vat_main_t *vam = &vat_main;
1857
1858   if (VAT_JSON_ARRAY != vam->json_tree.type)
1859     {
1860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1861       vat_json_init_array (&vam->json_tree);
1862     }
1863
1864   node = vat_json_array_add (&vam->json_tree);
1865   vat_json_init_object (node);
1866
1867   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1868   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1869   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1870 }
1871
1872 static void
1873 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1877            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1878 }
1879
1880 static void
1881 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1885           "router_addr %U host_mac %U\n",
1886           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1887           format_ip4_address, &mp->host_address,
1888           format_ip4_address, &mp->router_address,
1889           format_ethernet_address, mp->host_mac);
1890 }
1891
1892 static void vl_api_dhcp_compl_event_t_handler_json
1893   (vl_api_dhcp_compl_event_t * mp)
1894 {
1895   /* JSON output not supported */
1896 }
1897
1898 static void
1899 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1900                               u32 counter)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   static u64 default_counter = 0;
1904
1905   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1906                            NULL);
1907   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1908                            sw_if_index, default_counter);
1909   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1910 }
1911
1912 static void
1913 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1914                                 interface_counter_t counter)
1915 {
1916   vat_main_t *vam = &vat_main;
1917   static interface_counter_t default_counter = { 0, };
1918
1919   vec_validate_init_empty (vam->combined_interface_counters,
1920                            vnet_counter_type, NULL);
1921   vec_validate_init_empty (vam->combined_interface_counters
1922                            [vnet_counter_type], sw_if_index, default_counter);
1923   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   /* not supported */
1930 }
1931
1932 static void vl_api_vnet_interface_counters_t_handler_json
1933   (vl_api_vnet_interface_counters_t * mp)
1934 {
1935   interface_counter_t counter;
1936   vlib_counter_t *v;
1937   u64 *v_packets;
1938   u64 packets;
1939   u32 count;
1940   u32 first_sw_if_index;
1941   int i;
1942
1943   count = ntohl (mp->count);
1944   first_sw_if_index = ntohl (mp->first_sw_if_index);
1945
1946   if (!mp->is_combined)
1947     {
1948       v_packets = (u64 *) & mp->data;
1949       for (i = 0; i < count; i++)
1950         {
1951           packets =
1952             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1953           set_simple_interface_counter (mp->vnet_counter_type,
1954                                         first_sw_if_index + i, packets);
1955           v_packets++;
1956         }
1957     }
1958   else
1959     {
1960       v = (vlib_counter_t *) & mp->data;
1961       for (i = 0; i < count; i++)
1962         {
1963           counter.packets =
1964             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1965           counter.bytes =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1967           set_combined_interface_counter (mp->vnet_counter_type,
1968                                           first_sw_if_index + i, counter);
1969           v++;
1970         }
1971     }
1972 }
1973
1974 static u32
1975 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   u32 i;
1979
1980   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1981     {
1982       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1983         {
1984           return i;
1985         }
1986     }
1987   return ~0;
1988 }
1989
1990 static u32
1991 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   u32 i;
1995
1996   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1997     {
1998       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1999         {
2000           return i;
2001         }
2002     }
2003   return ~0;
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2013   (vl_api_vnet_ip4_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip4_fib_counter_t *v;
2017   ip4_fib_counter_t *counter;
2018   struct in_addr ip4;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip4_fib_counters, vrf_index);
2032       vam->ip4_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip4_fib_counters[vrf_index]);
2036   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2041       counter = &vam->ip4_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2043       counter->address = ip4;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_vnet_ip6_fib_counters_t_handler
2052   (vl_api_vnet_ip6_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2058   (vl_api_vnet_ip6_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip6_fib_counter_t *v;
2062   ip6_fib_counter_t *counter;
2063   struct in6_addr ip6;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip6_fib_counters, vrf_index);
2077       vam->ip6_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip6_fib_counters[vrf_index]);
2081   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2086       counter = &vam->ip6_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2088       counter->address = ip6;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_get_first_msg_id_reply_t_handler
2097   (vl_api_get_first_msg_id_reply_t * mp)
2098 {
2099   vat_main_t *vam = &vat_main;
2100   i32 retval = ntohl (mp->retval);
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111   if (retval >= 0)
2112     {
2113       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2114     }
2115 }
2116
2117 static void vl_api_get_first_msg_id_reply_t_handler_json
2118   (vl_api_get_first_msg_id_reply_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t node;
2122
2123   vat_json_init_object (&node);
2124   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2125   vat_json_object_add_uint (&node, "first_msg_id",
2126                             (uint) ntohs (mp->first_msg_id));
2127
2128   vat_json_print (vam->ofp, &node);
2129   vat_json_free (&node);
2130
2131   vam->retval = ntohl (mp->retval);
2132   vam->result_ready = 1;
2133 }
2134
2135 static void vl_api_get_node_graph_reply_t_handler
2136   (vl_api_get_node_graph_reply_t * mp)
2137 {
2138   vat_main_t *vam = &vat_main;
2139   api_main_t *am = &api_main;
2140   i32 retval = ntohl (mp->retval);
2141   u8 *pvt_copy, *reply;
2142   void *oldheap;
2143   vlib_node_t *node;
2144   int i;
2145
2146   if (vam->async_mode)
2147     {
2148       vam->async_errors += (retval < 0);
2149     }
2150   else
2151     {
2152       vam->retval = retval;
2153       vam->result_ready = 1;
2154     }
2155
2156   /* "Should never happen..." */
2157   if (retval != 0)
2158     return;
2159
2160   reply = (u8 *) (mp->reply_in_shmem);
2161   pvt_copy = vec_dup (reply);
2162
2163   /* Toss the shared-memory original... */
2164   pthread_mutex_lock (&am->vlib_rp->mutex);
2165   oldheap = svm_push_data_heap (am->vlib_rp);
2166
2167   vec_free (reply);
2168
2169   svm_pop_heap (oldheap);
2170   pthread_mutex_unlock (&am->vlib_rp->mutex);
2171
2172   if (vam->graph_nodes)
2173     {
2174       hash_free (vam->graph_node_index_by_name);
2175
2176       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2177         {
2178           node = vam->graph_nodes[i];
2179           vec_free (node->name);
2180           vec_free (node->next_nodes);
2181           vec_free (node);
2182         }
2183       vec_free (vam->graph_nodes);
2184     }
2185
2186   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2187   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2188   vec_free (pvt_copy);
2189
2190   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2191     {
2192       node = vam->graph_nodes[i];
2193       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2194     }
2195 }
2196
2197 static void vl_api_get_node_graph_reply_t_handler_json
2198   (vl_api_get_node_graph_reply_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   api_main_t *am = &api_main;
2202   void *oldheap;
2203   vat_json_node_t node;
2204   u8 *reply;
2205
2206   /* $$$$ make this real? */
2207   vat_json_init_object (&node);
2208   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2209   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2210
2211   reply = (u8 *) (mp->reply_in_shmem);
2212
2213   /* Toss the shared-memory original... */
2214   pthread_mutex_lock (&am->vlib_rp->mutex);
2215   oldheap = svm_push_data_heap (am->vlib_rp);
2216
2217   vec_free (reply);
2218
2219   svm_pop_heap (oldheap);
2220   pthread_mutex_unlock (&am->vlib_rp->mutex);
2221
2222   vat_json_print (vam->ofp, &node);
2223   vat_json_free (&node);
2224
2225   vam->retval = ntohl (mp->retval);
2226   vam->result_ready = 1;
2227 }
2228
2229 static void
2230 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2231 {
2232   vat_main_t *vam = &vat_main;
2233   u8 *s = 0;
2234
2235   if (mp->local)
2236     {
2237       s = format (s, "%=16d%=16d%=16d\n",
2238                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2239     }
2240   else
2241     {
2242       s = format (s, "%=16U%=16d%=16d\n",
2243                   mp->is_ipv6 ? format_ip6_address :
2244                   format_ip4_address,
2245                   mp->ip_address, mp->priority, mp->weight);
2246     }
2247
2248   fformat (vam->ofp, "%v", s);
2249   vec_free (s);
2250 }
2251
2252 static void
2253 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2254                                             mp)
2255 {
2256   vat_main_t *vam = &vat_main;
2257   vat_json_node_t *node = NULL;
2258   struct in6_addr ip6;
2259   struct in_addr ip4;
2260
2261   if (VAT_JSON_ARRAY != vam->json_tree.type)
2262     {
2263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2264       vat_json_init_array (&vam->json_tree);
2265     }
2266   node = vat_json_array_add (&vam->json_tree);
2267   vat_json_init_object (node);
2268
2269   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2270   vat_json_object_add_uint (node, "priority", mp->priority);
2271   vat_json_object_add_uint (node, "weight", mp->weight);
2272
2273   if (mp->local)
2274     vat_json_object_add_uint (node, "sw_if_index",
2275                               clib_net_to_host_u32 (mp->sw_if_index));
2276   else
2277     {
2278       if (mp->is_ipv6)
2279         {
2280           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2281           vat_json_object_add_ip6 (node, "address", ip6);
2282         }
2283       else
2284         {
2285           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2286           vat_json_object_add_ip4 (node, "address", ip4);
2287         }
2288     }
2289 }
2290
2291 static void
2292 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2293                                            mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299
2300   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2301            ls_name);
2302   vec_free (ls_name);
2303 }
2304
2305 static void
2306   vl_api_lisp_locator_set_details_t_handler_json
2307   (vl_api_lisp_locator_set_details_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   vat_json_node_t *node = 0;
2311   u8 *ls_name = 0;
2312
2313   ls_name = format (0, "%s", mp->ls_name);
2314   vec_add1 (ls_name, 0);
2315
2316   if (VAT_JSON_ARRAY != vam->json_tree.type)
2317     {
2318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2319       vat_json_init_array (&vam->json_tree);
2320     }
2321   node = vat_json_array_add (&vam->json_tree);
2322
2323   vat_json_init_object (node);
2324   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2325   vat_json_object_add_uint (node, "ls_index",
2326                             clib_net_to_host_u32 (mp->ls_index));
2327   vec_free (ls_name);
2328 }
2329
2330 static u8 *
2331 format_lisp_flat_eid (u8 * s, va_list * args)
2332 {
2333   u32 type = va_arg (*args, u32);
2334   u8 *eid = va_arg (*args, u8 *);
2335   u32 eid_len = va_arg (*args, u32);
2336
2337   switch (type)
2338     {
2339     case 0:
2340       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2341     case 1:
2342       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2343     case 2:
2344       return format (s, "%U", format_ethernet_address, eid);
2345     }
2346   return 0;
2347 }
2348
2349 static u8 *
2350 format_lisp_eid_vat (u8 * s, va_list * args)
2351 {
2352   u32 type = va_arg (*args, u32);
2353   u8 *eid = va_arg (*args, u8 *);
2354   u32 eid_len = va_arg (*args, u32);
2355   u8 *seid = va_arg (*args, u8 *);
2356   u32 seid_len = va_arg (*args, u32);
2357   u32 is_src_dst = va_arg (*args, u32);
2358
2359   if (is_src_dst)
2360     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2361
2362   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2363
2364   return s;
2365 }
2366
2367 static void
2368 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   u8 *s = 0, *eid = 0;
2372
2373   if (~0 == mp->locator_set_index)
2374     s = format (0, "action: %d", mp->action);
2375   else
2376     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2377
2378   eid = format (0, "%U", format_lisp_eid_vat,
2379                 mp->eid_type,
2380                 mp->eid,
2381                 mp->eid_prefix_len,
2382                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2383   vec_add1 (eid, 0);
2384
2385   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2386            clib_net_to_host_u32 (mp->vni),
2387            eid,
2388            mp->is_local ? "local" : "remote",
2389            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2390   vec_free (s);
2391   vec_free (eid);
2392 }
2393
2394 static void
2395 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2396                                               * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   vat_json_node_t *node = 0;
2400   u8 *eid = 0;
2401
2402   if (VAT_JSON_ARRAY != vam->json_tree.type)
2403     {
2404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2405       vat_json_init_array (&vam->json_tree);
2406     }
2407   node = vat_json_array_add (&vam->json_tree);
2408
2409   vat_json_init_object (node);
2410   if (~0 == mp->locator_set_index)
2411     vat_json_object_add_uint (node, "action", mp->action);
2412   else
2413     vat_json_object_add_uint (node, "locator_set_index",
2414                               clib_net_to_host_u32 (mp->locator_set_index));
2415
2416   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2417   eid = format (0, "%U", format_lisp_eid_vat,
2418                 mp->eid_type,
2419                 mp->eid,
2420                 mp->eid_prefix_len,
2421                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2422   vec_add1 (eid, 0);
2423   vat_json_object_add_string_copy (node, "eid", eid);
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2426   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2427   vec_free (eid);
2428 }
2429
2430 static void
2431   vl_api_lisp_eid_table_map_details_t_handler
2432   (vl_api_lisp_eid_table_map_details_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435
2436   u8 *line = format (0, "%=10d%=10d",
2437                      clib_net_to_host_u32 (mp->vni),
2438                      clib_net_to_host_u32 (mp->dp_table));
2439   fformat (vam->ofp, "%v\n", line);
2440   vec_free (line);
2441 }
2442
2443 static void
2444   vl_api_lisp_eid_table_map_details_t_handler_json
2445   (vl_api_lisp_eid_table_map_details_t * mp)
2446 {
2447   vat_main_t *vam = &vat_main;
2448   vat_json_node_t *node = NULL;
2449
2450   if (VAT_JSON_ARRAY != vam->json_tree.type)
2451     {
2452       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2453       vat_json_init_array (&vam->json_tree);
2454     }
2455   node = vat_json_array_add (&vam->json_tree);
2456   vat_json_init_object (node);
2457   vat_json_object_add_uint (node, "dp_table",
2458                             clib_net_to_host_u32 (mp->dp_table));
2459   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2460 }
2461
2462 static void
2463   vl_api_lisp_eid_table_vni_details_t_handler
2464   (vl_api_lisp_eid_table_vni_details_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467
2468   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2469   fformat (vam->ofp, "%v\n", line);
2470   vec_free (line);
2471 }
2472
2473 static void
2474   vl_api_lisp_eid_table_vni_details_t_handler_json
2475   (vl_api_lisp_eid_table_vni_details_t * mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   vat_json_node_t *node = NULL;
2479
2480   if (VAT_JSON_ARRAY != vam->json_tree.type)
2481     {
2482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2483       vat_json_init_array (&vam->json_tree);
2484     }
2485   node = vat_json_array_add (&vam->json_tree);
2486   vat_json_init_object (node);
2487   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2488 }
2489
2490 static u8 *
2491 format_decap_next (u8 * s, va_list * args)
2492 {
2493   u32 next_index = va_arg (*args, u32);
2494
2495   switch (next_index)
2496     {
2497     case LISP_GPE_INPUT_NEXT_DROP:
2498       return format (s, "drop");
2499     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2500       return format (s, "ip4");
2501     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2502       return format (s, "ip6");
2503     default:
2504       return format (s, "unknown %d", next_index);
2505     }
2506   return s;
2507 }
2508
2509 static void
2510 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2511                                           mp)
2512 {
2513   vat_main_t *vam = &vat_main;
2514   u8 *iid_str;
2515   u8 *flag_str = NULL;
2516
2517   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2518
2519 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2520   foreach_lisp_gpe_flag_bit;
2521 #undef _
2522
2523   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2524            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2525            mp->tunnels,
2526            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2527            mp->source_ip,
2528            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2529            mp->destination_ip,
2530            ntohl (mp->encap_fib_id),
2531            ntohl (mp->decap_fib_id),
2532            format_decap_next, ntohl (mp->dcap_next),
2533            mp->ver_res >> 6,
2534            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2535
2536   vec_free (iid_str);
2537 }
2538
2539 static void
2540   vl_api_lisp_gpe_tunnel_details_t_handler_json
2541   (vl_api_lisp_gpe_tunnel_details_t * mp)
2542 {
2543   vat_main_t *vam = &vat_main;
2544   vat_json_node_t *node = NULL;
2545   struct in6_addr ip6;
2546   struct in_addr ip4;
2547   u8 *next_decap_str;
2548
2549   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557
2558   vat_json_init_object (node);
2559   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2560   if (mp->is_ipv6)
2561     {
2562       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2563       vat_json_object_add_ip6 (node, "source address", ip6);
2564       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2565       vat_json_object_add_ip6 (node, "destination address", ip6);
2566     }
2567   else
2568     {
2569       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2570       vat_json_object_add_ip4 (node, "source address", ip4);
2571       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2572       vat_json_object_add_ip4 (node, "destination address", ip4);
2573     }
2574   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2575   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2576   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2577   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2578   vat_json_object_add_uint (node, "flags", mp->flags);
2579   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2580   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2581   vat_json_object_add_uint (node, "res", mp->res);
2582   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2583
2584   vec_free (next_decap_str);
2585 }
2586
2587 static void
2588 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2589                                             * mp)
2590 {
2591   vat_main_t *vam = &vat_main;
2592
2593   fformat (vam->ofp, "%=20U\n",
2594            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2595            mp->ip_address);
2596 }
2597
2598 static void
2599   vl_api_lisp_map_resolver_details_t_handler_json
2600   (vl_api_lisp_map_resolver_details_t * mp)
2601 {
2602   vat_main_t *vam = &vat_main;
2603   vat_json_node_t *node = NULL;
2604   struct in6_addr ip6;
2605   struct in_addr ip4;
2606
2607   if (VAT_JSON_ARRAY != vam->json_tree.type)
2608     {
2609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2610       vat_json_init_array (&vam->json_tree);
2611     }
2612   node = vat_json_array_add (&vam->json_tree);
2613
2614   vat_json_init_object (node);
2615   if (mp->is_ipv6)
2616     {
2617       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2618       vat_json_object_add_ip6 (node, "map resolver", ip6);
2619     }
2620   else
2621     {
2622       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2623       vat_json_object_add_ip4 (node, "map resolver", ip4);
2624     }
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   i32 retval = ntohl (mp->retval);
2633
2634   if (0 <= retval)
2635     {
2636       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2637                mp->feature_status ? "enabled" : "disabled",
2638                mp->gpe_status ? "enabled" : "disabled");
2639     }
2640
2641   vam->retval = retval;
2642   vam->result_ready = 1;
2643 }
2644
2645 static void
2646   vl_api_show_lisp_status_reply_t_handler_json
2647   (vl_api_show_lisp_status_reply_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650   vat_json_node_t node;
2651   u8 *gpe_status = NULL;
2652   u8 *feature_status = NULL;
2653
2654   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2655   feature_status = format (0, "%s",
2656                            mp->feature_status ? "enabled" : "disabled");
2657   vec_add1 (gpe_status, 0);
2658   vec_add1 (feature_status, 0);
2659
2660   vat_json_init_object (&node);
2661   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2662   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2663
2664   vec_free (gpe_status);
2665   vec_free (feature_status);
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void
2675   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2676   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   i32 retval = ntohl (mp->retval);
2680
2681   if (retval >= 0)
2682     {
2683       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2684     }
2685
2686   vam->retval = retval;
2687   vam->result_ready = 1;
2688 }
2689
2690 static void
2691   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2692   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t *node = NULL;
2696
2697   if (VAT_JSON_ARRAY != vam->json_tree.type)
2698     {
2699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2700       vat_json_init_array (&vam->json_tree);
2701     }
2702   node = vat_json_array_add (&vam->json_tree);
2703
2704   vat_json_init_object (node);
2705   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2706
2707   vat_json_print (vam->ofp, node);
2708   vat_json_free (node);
2709
2710   vam->retval = ntohl (mp->retval);
2711   vam->result_ready = 1;
2712 }
2713
2714 static u8 *
2715 format_lisp_map_request_mode (u8 * s, va_list * args)
2716 {
2717   u32 mode = va_arg (*args, u32);
2718
2719   switch (mode)
2720     {
2721     case 0:
2722       return format (0, "dst-only");
2723     case 1:
2724       return format (0, "src-dst");
2725     }
2726   return 0;
2727 }
2728
2729 static void
2730   vl_api_show_lisp_map_request_mode_reply_t_handler
2731   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2732 {
2733   vat_main_t *vam = &vat_main;
2734   i32 retval = ntohl (mp->retval);
2735
2736   if (0 <= retval)
2737     {
2738       u32 mode = mp->mode;
2739       fformat (vam->ofp, "map_request_mode: %U\n",
2740                format_lisp_map_request_mode, mode);
2741     }
2742
2743   vam->retval = retval;
2744   vam->result_ready = 1;
2745 }
2746
2747 static void
2748   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2749   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   vat_json_node_t node;
2753   u8 *s = 0;
2754   u32 mode;
2755
2756   mode = mp->mode;
2757   s = format (0, "%U", format_lisp_map_request_mode, mode);
2758   vec_add1 (s, 0);
2759
2760   vat_json_init_object (&node);
2761   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2762   vat_json_print (vam->ofp, &node);
2763   vat_json_free (&node);
2764
2765   vec_free (s);
2766   vam->retval = ntohl (mp->retval);
2767   vam->result_ready = 1;
2768 }
2769
2770 static void
2771 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   i32 retval = ntohl (mp->retval);
2775
2776   if (0 <= retval)
2777     {
2778       fformat (vam->ofp, "%-20s%-16s\n",
2779                mp->status ? "enabled" : "disabled",
2780                mp->status ? (char *) mp->locator_set_name : "");
2781     }
2782
2783   vam->retval = retval;
2784   vam->result_ready = 1;
2785 }
2786
2787 static void
2788 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2789                                             mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   vat_json_node_t node;
2793   u8 *status = 0;
2794
2795   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2796   vec_add1 (status, 0);
2797
2798   vat_json_init_object (&node);
2799   vat_json_object_add_string_copy (&node, "status", status);
2800   if (mp->status)
2801     {
2802       vat_json_object_add_string_copy (&node, "locator_set",
2803                                        mp->locator_set_name);
2804     }
2805
2806   vec_free (status);
2807
2808   vat_json_print (vam->ofp, &node);
2809   vat_json_free (&node);
2810
2811   vam->retval = ntohl (mp->retval);
2812   vam->result_ready = 1;
2813 }
2814
2815 static u8 *
2816 format_policer_type (u8 * s, va_list * va)
2817 {
2818   u32 i = va_arg (*va, u32);
2819
2820   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2821     s = format (s, "1r2c");
2822   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2823     s = format (s, "1r3c");
2824   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2825     s = format (s, "2r3c-2698");
2826   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2827     s = format (s, "2r3c-4115");
2828   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2829     s = format (s, "2r3c-mef5cf1");
2830   else
2831     s = format (s, "ILLEGAL");
2832   return s;
2833 }
2834
2835 static u8 *
2836 format_policer_rate_type (u8 * s, va_list * va)
2837 {
2838   u32 i = va_arg (*va, u32);
2839
2840   if (i == SSE2_QOS_RATE_KBPS)
2841     s = format (s, "kbps");
2842   else if (i == SSE2_QOS_RATE_PPS)
2843     s = format (s, "pps");
2844   else
2845     s = format (s, "ILLEGAL");
2846   return s;
2847 }
2848
2849 static u8 *
2850 format_policer_round_type (u8 * s, va_list * va)
2851 {
2852   u32 i = va_arg (*va, u32);
2853
2854   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2855     s = format (s, "closest");
2856   else if (i == SSE2_QOS_ROUND_TO_UP)
2857     s = format (s, "up");
2858   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2859     s = format (s, "down");
2860   else
2861     s = format (s, "ILLEGAL");
2862   return s;
2863 }
2864
2865 static u8 *
2866 format_policer_action_type (u8 * s, va_list * va)
2867 {
2868   u32 i = va_arg (*va, u32);
2869
2870   if (i == SSE2_QOS_ACTION_DROP)
2871     s = format (s, "drop");
2872   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2873     s = format (s, "transmit");
2874   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2875     s = format (s, "mark-and-transmit");
2876   else
2877     s = format (s, "ILLEGAL");
2878   return s;
2879 }
2880
2881 static u8 *
2882 format_dscp (u8 * s, va_list * va)
2883 {
2884   u32 i = va_arg (*va, u32);
2885   char *t = 0;
2886
2887   switch (i)
2888     {
2889 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2890       foreach_vnet_dscp
2891 #undef _
2892     default:
2893       return format (s, "ILLEGAL");
2894     }
2895   s = format (s, "%s", t);
2896   return s;
2897 }
2898
2899 static void
2900 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2901 {
2902   vat_main_t *vam = &vat_main;
2903   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2904
2905   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2906     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2907   else
2908     conform_dscp_str = format (0, "");
2909
2910   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2911     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2912   else
2913     exceed_dscp_str = format (0, "");
2914
2915   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2916     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2917   else
2918     violate_dscp_str = format (0, "");
2919
2920   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2921            "rate type %U, round type %U, %s rate, %s color-aware, "
2922            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2923            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2924            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2925            mp->name,
2926            format_policer_type, mp->type,
2927            ntohl (mp->cir),
2928            ntohl (mp->eir),
2929            clib_net_to_host_u64 (mp->cb),
2930            clib_net_to_host_u64 (mp->eb),
2931            format_policer_rate_type, mp->rate_type,
2932            format_policer_round_type, mp->round_type,
2933            mp->single_rate ? "single" : "dual",
2934            mp->color_aware ? "is" : "not",
2935            ntohl (mp->cir_tokens_per_period),
2936            ntohl (mp->pir_tokens_per_period),
2937            ntohl (mp->scale),
2938            ntohl (mp->current_limit),
2939            ntohl (mp->current_bucket),
2940            ntohl (mp->extended_limit),
2941            ntohl (mp->extended_bucket),
2942            clib_net_to_host_u64 (mp->last_update_time),
2943            format_policer_action_type, mp->conform_action_type,
2944            conform_dscp_str,
2945            format_policer_action_type, mp->exceed_action_type,
2946            exceed_dscp_str,
2947            format_policer_action_type, mp->violate_action_type,
2948            violate_dscp_str);
2949
2950   vec_free (conform_dscp_str);
2951   vec_free (exceed_dscp_str);
2952   vec_free (violate_dscp_str);
2953 }
2954
2955 static void vl_api_policer_details_t_handler_json
2956   (vl_api_policer_details_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   vat_json_node_t *node;
2960   u8 *rate_type_str, *round_type_str, *type_str;
2961   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2962
2963   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2964   round_type_str =
2965     format (0, "%U", format_policer_round_type, mp->round_type);
2966   type_str = format (0, "%U", format_policer_type, mp->type);
2967   conform_action_str = format (0, "%U", format_policer_action_type,
2968                                mp->conform_action_type);
2969   exceed_action_str = format (0, "%U", format_policer_action_type,
2970                               mp->exceed_action_type);
2971   violate_action_str = format (0, "%U", format_policer_action_type,
2972                                mp->violate_action_type);
2973
2974   if (VAT_JSON_ARRAY != vam->json_tree.type)
2975     {
2976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2977       vat_json_init_array (&vam->json_tree);
2978     }
2979   node = vat_json_array_add (&vam->json_tree);
2980
2981   vat_json_init_object (node);
2982   vat_json_object_add_string_copy (node, "name", mp->name);
2983   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2984   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2985   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2986   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2987   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2988   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2989   vat_json_object_add_string_copy (node, "type", type_str);
2990   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2991   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2992   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2993   vat_json_object_add_uint (node, "cir_tokens_per_period",
2994                             ntohl (mp->cir_tokens_per_period));
2995   vat_json_object_add_uint (node, "eir_tokens_per_period",
2996                             ntohl (mp->pir_tokens_per_period));
2997   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2998   vat_json_object_add_uint (node, "current_bucket",
2999                             ntohl (mp->current_bucket));
3000   vat_json_object_add_uint (node, "extended_limit",
3001                             ntohl (mp->extended_limit));
3002   vat_json_object_add_uint (node, "extended_bucket",
3003                             ntohl (mp->extended_bucket));
3004   vat_json_object_add_uint (node, "last_update_time",
3005                             ntohl (mp->last_update_time));
3006   vat_json_object_add_string_copy (node, "conform_action",
3007                                    conform_action_str);
3008   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3009     {
3010       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3011       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3012       vec_free (dscp_str);
3013     }
3014   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3015   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3016     {
3017       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3018       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3019       vec_free (dscp_str);
3020     }
3021   vat_json_object_add_string_copy (node, "violate_action",
3022                                    violate_action_str);
3023   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3024     {
3025       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3026       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3027       vec_free (dscp_str);
3028     }
3029
3030   vec_free (rate_type_str);
3031   vec_free (round_type_str);
3032   vec_free (type_str);
3033   vec_free (conform_action_str);
3034   vec_free (exceed_action_str);
3035   vec_free (violate_action_str);
3036 }
3037
3038 static void
3039 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3040                                            mp)
3041 {
3042   vat_main_t *vam = &vat_main;
3043   int i, count = ntohl (mp->count);
3044
3045   if (count > 0)
3046     fformat (vam->ofp, "classify table ids (%d) : ", count);
3047   for (i = 0; i < count; i++)
3048     {
3049       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3050       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3051     }
3052   vam->retval = ntohl (mp->retval);
3053   vam->result_ready = 1;
3054 }
3055
3056 static void
3057   vl_api_classify_table_ids_reply_t_handler_json
3058   (vl_api_classify_table_ids_reply_t * mp)
3059 {
3060   vat_main_t *vam = &vat_main;
3061   int i, count = ntohl (mp->count);
3062
3063   if (count > 0)
3064     {
3065       vat_json_node_t node;
3066
3067       vat_json_init_object (&node);
3068       for (i = 0; i < count; i++)
3069         {
3070           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3071         }
3072       vat_json_print (vam->ofp, &node);
3073       vat_json_free (&node);
3074     }
3075   vam->retval = ntohl (mp->retval);
3076   vam->result_ready = 1;
3077 }
3078
3079 static void
3080   vl_api_classify_table_by_interface_reply_t_handler
3081   (vl_api_classify_table_by_interface_reply_t * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   u32 table_id;
3085
3086   table_id = ntohl (mp->l2_table_id);
3087   if (table_id != ~0)
3088     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3089   else
3090     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3091   table_id = ntohl (mp->ip4_table_id);
3092   if (table_id != ~0)
3093     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3094   else
3095     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3096   table_id = ntohl (mp->ip6_table_id);
3097   if (table_id != ~0)
3098     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3099   else
3100     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3101   vam->retval = ntohl (mp->retval);
3102   vam->result_ready = 1;
3103 }
3104
3105 static void
3106   vl_api_classify_table_by_interface_reply_t_handler_json
3107   (vl_api_classify_table_by_interface_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t node;
3111
3112   vat_json_init_object (&node);
3113
3114   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3115   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3116   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3117
3118   vat_json_print (vam->ofp, &node);
3119   vat_json_free (&node);
3120
3121   vam->retval = ntohl (mp->retval);
3122   vam->result_ready = 1;
3123 }
3124
3125 static void vl_api_policer_add_del_reply_t_handler
3126   (vl_api_policer_add_del_reply_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   i32 retval = ntohl (mp->retval);
3130   if (vam->async_mode)
3131     {
3132       vam->async_errors += (retval < 0);
3133     }
3134   else
3135     {
3136       vam->retval = retval;
3137       vam->result_ready = 1;
3138       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3139         /*
3140          * Note: this is just barely thread-safe, depends on
3141          * the main thread spinning waiting for an answer...
3142          */
3143         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3144     }
3145 }
3146
3147 static void vl_api_policer_add_del_reply_t_handler_json
3148   (vl_api_policer_add_del_reply_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t node;
3152
3153   vat_json_init_object (&node);
3154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3155   vat_json_object_add_uint (&node, "policer_index",
3156                             ntohl (mp->policer_index));
3157
3158   vat_json_print (vam->ofp, &node);
3159   vat_json_free (&node);
3160
3161   vam->retval = ntohl (mp->retval);
3162   vam->result_ready = 1;
3163 }
3164
3165 /* Format hex dump. */
3166 u8 *
3167 format_hex_bytes (u8 * s, va_list * va)
3168 {
3169   u8 *bytes = va_arg (*va, u8 *);
3170   int n_bytes = va_arg (*va, int);
3171   uword i;
3172
3173   /* Print short or long form depending on byte count. */
3174   uword short_form = n_bytes <= 32;
3175   uword indent = format_get_indent (s);
3176
3177   if (n_bytes == 0)
3178     return s;
3179
3180   for (i = 0; i < n_bytes; i++)
3181     {
3182       if (!short_form && (i % 32) == 0)
3183         s = format (s, "%08x: ", i);
3184       s = format (s, "%02x", bytes[i]);
3185       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3186         s = format (s, "\n%U", format_white_space, indent);
3187     }
3188
3189   return s;
3190 }
3191
3192 static void
3193 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3194                                             * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   i32 retval = ntohl (mp->retval);
3198   if (retval == 0)
3199     {
3200       fformat (vam->ofp, "classify table info :\n");
3201       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3202                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3203                ntohl (mp->miss_next_index));
3204       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3205                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3206                ntohl (mp->match_n_vectors));
3207       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3208                ntohl (mp->mask_length));
3209     }
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_classify_table_info_reply_t_handler_json
3216   (vl_api_classify_table_info_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220
3221   i32 retval = ntohl (mp->retval);
3222   if (retval == 0)
3223     {
3224       vat_json_init_object (&node);
3225
3226       vat_json_object_add_int (&node, "sessions",
3227                                ntohl (mp->active_sessions));
3228       vat_json_object_add_int (&node, "nexttbl",
3229                                ntohl (mp->next_table_index));
3230       vat_json_object_add_int (&node, "nextnode",
3231                                ntohl (mp->miss_next_index));
3232       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3233       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3234       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3235       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3236                       ntohl (mp->mask_length), 0);
3237       vat_json_object_add_string_copy (&node, "mask", s);
3238
3239       vat_json_print (vam->ofp, &node);
3240       vat_json_free (&node);
3241     }
3242   vam->retval = ntohl (mp->retval);
3243   vam->result_ready = 1;
3244 }
3245
3246 static void
3247 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3248                                            mp)
3249 {
3250   vat_main_t *vam = &vat_main;
3251
3252   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3253            ntohl (mp->hit_next_index), ntohl (mp->advance),
3254            ntohl (mp->opaque_index));
3255   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3256            ntohl (mp->match_length));
3257 }
3258
3259 static void
3260   vl_api_classify_session_details_t_handler_json
3261   (vl_api_classify_session_details_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t *node = NULL;
3265
3266   if (VAT_JSON_ARRAY != vam->json_tree.type)
3267     {
3268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3269       vat_json_init_array (&vam->json_tree);
3270     }
3271   node = vat_json_array_add (&vam->json_tree);
3272
3273   vat_json_init_object (node);
3274   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3275   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3276   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3277   u8 *s =
3278     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3279             0);
3280   vat_json_object_add_string_copy (node, "match", s);
3281 }
3282
3283 static void vl_api_pg_create_interface_reply_t_handler
3284   (vl_api_pg_create_interface_reply_t * mp)
3285 {
3286   vat_main_t *vam = &vat_main;
3287
3288   vam->retval = ntohl (mp->retval);
3289   vam->result_ready = 1;
3290 }
3291
3292 static void vl_api_pg_create_interface_reply_t_handler_json
3293   (vl_api_pg_create_interface_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   vat_json_node_t node;
3297
3298   i32 retval = ntohl (mp->retval);
3299   if (retval == 0)
3300     {
3301       vat_json_init_object (&node);
3302
3303       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3304
3305       vat_json_print (vam->ofp, &node);
3306       vat_json_free (&node);
3307     }
3308   vam->retval = ntohl (mp->retval);
3309   vam->result_ready = 1;
3310 }
3311
3312 static void vl_api_policer_classify_details_t_handler
3313   (vl_api_policer_classify_details_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316
3317   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3318            ntohl (mp->table_index));
3319 }
3320
3321 static void vl_api_policer_classify_details_t_handler_json
3322   (vl_api_policer_classify_details_t * mp)
3323 {
3324   vat_main_t *vam = &vat_main;
3325   vat_json_node_t *node;
3326
3327   if (VAT_JSON_ARRAY != vam->json_tree.type)
3328     {
3329       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3330       vat_json_init_array (&vam->json_tree);
3331     }
3332   node = vat_json_array_add (&vam->json_tree);
3333
3334   vat_json_init_object (node);
3335   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3336   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3337 }
3338
3339 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3340   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (vam->async_mode)
3345     {
3346       vam->async_errors += (retval < 0);
3347     }
3348   else
3349     {
3350       vam->retval = retval;
3351       vam->sw_if_index = ntohl (mp->sw_if_index);
3352       vam->result_ready = 1;
3353     }
3354 }
3355
3356 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3357   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3358 {
3359   vat_main_t *vam = &vat_main;
3360   vat_json_node_t node;
3361
3362   vat_json_init_object (&node);
3363   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3364   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3365
3366   vat_json_print (vam->ofp, &node);
3367   vat_json_free (&node);
3368
3369   vam->retval = ntohl (mp->retval);
3370   vam->result_ready = 1;
3371 }
3372
3373 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3374 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3375 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3376 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3377
3378 /*
3379  * Generate boilerplate reply handlers, which
3380  * dig the return value out of the xxx_reply_t API message,
3381  * stick it into vam->retval, and set vam->result_ready
3382  *
3383  * Could also do this by pointing N message decode slots at
3384  * a single function, but that could break in subtle ways.
3385  */
3386
3387 #define foreach_standard_reply_retval_handler           \
3388 _(sw_interface_set_flags_reply)                         \
3389 _(sw_interface_add_del_address_reply)                   \
3390 _(sw_interface_set_table_reply)                         \
3391 _(sw_interface_set_vpath_reply)                         \
3392 _(sw_interface_set_l2_bridge_reply)                     \
3393 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3394 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3395 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3396 _(bridge_domain_add_del_reply)                          \
3397 _(sw_interface_set_l2_xconnect_reply)                   \
3398 _(l2fib_add_del_reply)                                  \
3399 _(ip_add_del_route_reply)                               \
3400 _(proxy_arp_add_del_reply)                              \
3401 _(proxy_arp_intfc_enable_disable_reply)                 \
3402 _(mpls_add_del_encap_reply)                             \
3403 _(mpls_add_del_decap_reply)                             \
3404 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3405 _(sw_interface_set_unnumbered_reply)                    \
3406 _(ip_neighbor_add_del_reply)                            \
3407 _(reset_vrf_reply)                                      \
3408 _(oam_add_del_reply)                                    \
3409 _(reset_fib_reply)                                      \
3410 _(dhcp_proxy_config_reply)                              \
3411 _(dhcp_proxy_config_2_reply)                            \
3412 _(dhcp_proxy_set_vss_reply)                             \
3413 _(dhcp_client_config_reply)                             \
3414 _(set_ip_flow_hash_reply)                               \
3415 _(sw_interface_ip6_enable_disable_reply)                \
3416 _(sw_interface_ip6_set_link_local_address_reply)        \
3417 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3418 _(sw_interface_ip6nd_ra_config_reply)                   \
3419 _(set_arp_neighbor_limit_reply)                         \
3420 _(l2_patch_add_del_reply)                               \
3421 _(sr_tunnel_add_del_reply)                              \
3422 _(sr_policy_add_del_reply)                              \
3423 _(sr_multicast_map_add_del_reply)                       \
3424 _(classify_add_del_session_reply)                       \
3425 _(classify_set_interface_ip_table_reply)                \
3426 _(classify_set_interface_l2_tables_reply)               \
3427 _(l2tpv3_set_tunnel_cookies_reply)                      \
3428 _(l2tpv3_interface_enable_disable_reply)                \
3429 _(l2tpv3_set_lookup_key_reply)                          \
3430 _(l2_fib_clear_table_reply)                             \
3431 _(l2_interface_efp_filter_reply)                        \
3432 _(l2_interface_vlan_tag_rewrite_reply)                  \
3433 _(modify_vhost_user_if_reply)                           \
3434 _(delete_vhost_user_if_reply)                           \
3435 _(want_ip4_arp_events_reply)                            \
3436 _(want_ip6_nd_events_reply)                             \
3437 _(input_acl_set_interface_reply)                        \
3438 _(ipsec_spd_add_del_reply)                              \
3439 _(ipsec_interface_add_del_spd_reply)                    \
3440 _(ipsec_spd_add_del_entry_reply)                        \
3441 _(ipsec_sad_add_del_entry_reply)                        \
3442 _(ipsec_sa_set_key_reply)                               \
3443 _(ikev2_profile_add_del_reply)                          \
3444 _(ikev2_profile_set_auth_reply)                         \
3445 _(ikev2_profile_set_id_reply)                           \
3446 _(ikev2_profile_set_ts_reply)                           \
3447 _(ikev2_set_local_key_reply)                            \
3448 _(delete_loopback_reply)                                \
3449 _(bd_ip_mac_add_del_reply)                              \
3450 _(map_del_domain_reply)                                 \
3451 _(map_add_del_rule_reply)                               \
3452 _(want_interface_events_reply)                          \
3453 _(want_stats_reply)                                     \
3454 _(cop_interface_enable_disable_reply)                   \
3455 _(cop_whitelist_enable_disable_reply)                   \
3456 _(sw_interface_clear_stats_reply)                       \
3457 _(ioam_enable_reply)                              \
3458 _(ioam_disable_reply)                              \
3459 _(lisp_add_del_locator_reply)                           \
3460 _(lisp_add_del_local_eid_reply)                         \
3461 _(lisp_add_del_remote_mapping_reply)                    \
3462 _(lisp_add_del_adjacency_reply)                         \
3463 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3464 _(lisp_add_del_map_resolver_reply)                      \
3465 _(lisp_gpe_enable_disable_reply)                        \
3466 _(lisp_gpe_add_del_iface_reply)                         \
3467 _(lisp_enable_disable_reply)                            \
3468 _(lisp_pitr_set_locator_set_reply)                      \
3469 _(lisp_map_request_mode_reply)                          \
3470 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3471 _(lisp_eid_table_add_del_map_reply)                     \
3472 _(vxlan_gpe_add_del_tunnel_reply)                       \
3473 _(af_packet_delete_reply)                               \
3474 _(policer_classify_set_interface_reply)                 \
3475 _(netmap_create_reply)                                  \
3476 _(netmap_delete_reply)                                  \
3477 _(set_ipfix_exporter_reply)                             \
3478 _(set_ipfix_classify_stream_reply)                      \
3479 _(ipfix_classify_table_add_del_reply)                   \
3480 _(pg_capture_reply)                                     \
3481 _(pg_enable_disable_reply)                              \
3482 _(ip_source_and_port_range_check_add_del_reply)         \
3483 _(ip_source_and_port_range_check_interface_add_del_reply)\
3484 _(delete_subif_reply)
3485
3486 #define _(n)                                    \
3487     static void vl_api_##n##_t_handler          \
3488     (vl_api_##n##_t * mp)                       \
3489     {                                           \
3490         vat_main_t * vam = &vat_main;           \
3491         i32 retval = ntohl(mp->retval);         \
3492         if (vam->async_mode) {                  \
3493             vam->async_errors += (retval < 0);  \
3494         } else {                                \
3495             vam->retval = retval;               \
3496             vam->result_ready = 1;              \
3497         }                                       \
3498     }
3499 foreach_standard_reply_retval_handler;
3500 #undef _
3501
3502 #define _(n)                                    \
3503     static void vl_api_##n##_t_handler_json     \
3504     (vl_api_##n##_t * mp)                       \
3505     {                                           \
3506         vat_main_t * vam = &vat_main;           \
3507         vat_json_node_t node;                   \
3508         vat_json_init_object(&node);            \
3509         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3510         vat_json_print(vam->ofp, &node);        \
3511         vam->retval = ntohl(mp->retval);        \
3512         vam->result_ready = 1;                  \
3513     }
3514 foreach_standard_reply_retval_handler;
3515 #undef _
3516
3517 /*
3518  * Table of message reply handlers, must include boilerplate handlers
3519  * we just generated
3520  */
3521
3522 #define foreach_vpe_api_reply_msg                                       \
3523 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3524 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3525 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3526 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3527 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3528 _(CLI_REPLY, cli_reply)                                                 \
3529 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3530 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3531   sw_interface_add_del_address_reply)                                   \
3532 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3533 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3534 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3535   sw_interface_set_l2_xconnect_reply)                                   \
3536 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3537   sw_interface_set_l2_bridge_reply)                                     \
3538 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3539   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3540 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3541   sw_interface_set_dpdk_hqos_subport_reply)                             \
3542 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3543   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3544 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3545 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3546 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3547 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3548 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3549 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3550 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3551 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3552 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3553 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3554 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3555 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3556 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3557   proxy_arp_intfc_enable_disable_reply)                                 \
3558 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3559 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3560 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3561 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3562   mpls_ethernet_add_del_tunnel_reply)                                   \
3563 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3564   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3565 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3566   sw_interface_set_unnumbered_reply)                                    \
3567 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3568 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3569 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3570 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3571 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3572 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3573 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3574 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3575 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3576 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3577 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3578 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3579   sw_interface_ip6_enable_disable_reply)                                \
3580 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3581   sw_interface_ip6_set_link_local_address_reply)                        \
3582 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3583   sw_interface_ip6nd_ra_prefix_reply)                                   \
3584 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3585   sw_interface_ip6nd_ra_config_reply)                                   \
3586 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3587 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3588 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3589 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3590 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3591 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3592 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3593 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3594 classify_set_interface_ip_table_reply)                                  \
3595 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3596   classify_set_interface_l2_tables_reply)                               \
3597 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3598 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3599 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3600 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3601 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3602   l2tpv3_interface_enable_disable_reply)                                \
3603 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3604 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3605 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3606 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3607 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3608 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3609 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3610 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3611 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3612 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3613 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3614 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3615 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3616 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3617 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3618 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3619 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3620 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3621 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3622 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3623 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3624 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3625 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3626 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3627 _(IP_DETAILS, ip_details)                                               \
3628 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3629 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3630 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3631 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3632 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3633 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3634 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3635 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3636 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3637 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3638 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3639 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3640 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3641 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3642 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3643 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3644 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3645 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3646 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3647 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3648 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3649 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3650 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3651 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3652 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3653 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3654 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3655 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3656 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3657 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3658 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3659 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3660 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3661 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3662 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3663 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3664 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3665 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3666 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3667 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3668 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3669 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3670 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3671 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3672 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3673 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3674 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3675 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3676 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3677 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3678 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3679 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3680   lisp_add_del_map_request_itr_rlocs_reply)                             \
3681 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3682   lisp_get_map_request_itr_rlocs_reply)                                 \
3683 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3684 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3685 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3686 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3687 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3688 _(POLICER_DETAILS, policer_details)                                     \
3689 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3690 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3691 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3692 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3693 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3694 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3695 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3696 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3697 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3698 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3699 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3700 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3701 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3702 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3703 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3704 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3705 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3706 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3707 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3708 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3709 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3710 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3711 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3712  ip_source_and_port_range_check_add_del_reply)                          \
3713 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3714  ip_source_and_port_range_check_interface_add_del_reply)                \
3715 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3716 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3717 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3718
3719 /* M: construct, but don't yet send a message */
3720
3721 #define M(T,t)                                  \
3722 do {                                            \
3723     vam->result_ready = 0;                      \
3724     mp = vl_msg_api_alloc(sizeof(*mp));         \
3725     memset (mp, 0, sizeof (*mp));               \
3726     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3727     mp->client_index = vam->my_client_index;    \
3728 } while(0);
3729
3730 #define M2(T,t,n)                               \
3731 do {                                            \
3732     vam->result_ready = 0;                      \
3733     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3734     memset (mp, 0, sizeof (*mp));               \
3735     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3736     mp->client_index = vam->my_client_index;    \
3737 } while(0);
3738
3739
3740 /* S: send a message */
3741 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3742
3743 /* W: wait for results, with timeout */
3744 #define W                                       \
3745 do {                                            \
3746     timeout = vat_time_now (vam) + 1.0;         \
3747                                                 \
3748     while (vat_time_now (vam) < timeout) {      \
3749         if (vam->result_ready == 1) {           \
3750             return (vam->retval);               \
3751         }                                       \
3752     }                                           \
3753     return -99;                                 \
3754 } while(0);
3755
3756 /* W2: wait for results, with timeout */
3757 #define W2(body)                                \
3758 do {                                            \
3759     timeout = vat_time_now (vam) + 1.0;         \
3760                                                 \
3761     while (vat_time_now (vam) < timeout) {      \
3762         if (vam->result_ready == 1) {           \
3763           (body);                               \
3764           return (vam->retval);                 \
3765         }                                       \
3766     }                                           \
3767     return -99;                                 \
3768 } while(0);
3769
3770 typedef struct
3771 {
3772   u8 *name;
3773   u32 value;
3774 } name_sort_t;
3775
3776
3777 #define STR_VTR_OP_CASE(op)     \
3778     case L2_VTR_ ## op:         \
3779         return "" # op;
3780
3781 static const char *
3782 str_vtr_op (u32 vtr_op)
3783 {
3784   switch (vtr_op)
3785     {
3786       STR_VTR_OP_CASE (DISABLED);
3787       STR_VTR_OP_CASE (PUSH_1);
3788       STR_VTR_OP_CASE (PUSH_2);
3789       STR_VTR_OP_CASE (POP_1);
3790       STR_VTR_OP_CASE (POP_2);
3791       STR_VTR_OP_CASE (TRANSLATE_1_1);
3792       STR_VTR_OP_CASE (TRANSLATE_1_2);
3793       STR_VTR_OP_CASE (TRANSLATE_2_1);
3794       STR_VTR_OP_CASE (TRANSLATE_2_2);
3795     }
3796
3797   return "UNKNOWN";
3798 }
3799
3800 static int
3801 dump_sub_interface_table (vat_main_t * vam)
3802 {
3803   const sw_interface_subif_t *sub = NULL;
3804
3805   if (vam->json_output)
3806     {
3807       clib_warning
3808         ("JSON output supported only for VPE API calls and dump_stats_table");
3809       return -99;
3810     }
3811
3812   fformat (vam->ofp,
3813            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3814            "Interface", "sw_if_index",
3815            "sub id", "dot1ad", "tags", "outer id",
3816            "inner id", "exact", "default", "outer any", "inner any");
3817
3818   vec_foreach (sub, vam->sw_if_subif_table)
3819   {
3820     fformat (vam->ofp,
3821              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3822              sub->interface_name,
3823              sub->sw_if_index,
3824              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3825              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3826              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3827              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3828     if (sub->vtr_op != L2_VTR_DISABLED)
3829       {
3830         fformat (vam->ofp,
3831                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3832                  "tag1: %d tag2: %d ]\n",
3833                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3834                  sub->vtr_tag1, sub->vtr_tag2);
3835       }
3836   }
3837
3838   return 0;
3839 }
3840
3841 static int
3842 name_sort_cmp (void *a1, void *a2)
3843 {
3844   name_sort_t *n1 = a1;
3845   name_sort_t *n2 = a2;
3846
3847   return strcmp ((char *) n1->name, (char *) n2->name);
3848 }
3849
3850 static int
3851 dump_interface_table (vat_main_t * vam)
3852 {
3853   hash_pair_t *p;
3854   name_sort_t *nses = 0, *ns;
3855
3856   if (vam->json_output)
3857     {
3858       clib_warning
3859         ("JSON output supported only for VPE API calls and dump_stats_table");
3860       return -99;
3861     }
3862
3863   /* *INDENT-OFF* */
3864   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3865   ({
3866     vec_add2 (nses, ns, 1);
3867     ns->name = (u8 *)(p->key);
3868     ns->value = (u32) p->value[0];
3869   }));
3870   /* *INDENT-ON* */
3871
3872   vec_sort_with_function (nses, name_sort_cmp);
3873
3874   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3875   vec_foreach (ns, nses)
3876   {
3877     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3878   }
3879   vec_free (nses);
3880   return 0;
3881 }
3882
3883 static int
3884 dump_ip_table (vat_main_t * vam, int is_ipv6)
3885 {
3886   const ip_details_t *det = NULL;
3887   const ip_address_details_t *address = NULL;
3888   u32 i = ~0;
3889
3890   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3891
3892   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3893   {
3894     i++;
3895     if (!det->present)
3896       {
3897         continue;
3898       }
3899     fformat (vam->ofp, "%-12d\n", i);
3900     fformat (vam->ofp,
3901              "            %-30s%-13s\n", "Address", "Prefix length");
3902     if (!det->addr)
3903       {
3904         continue;
3905       }
3906     vec_foreach (address, det->addr)
3907     {
3908       fformat (vam->ofp,
3909                "            %-30U%-13d\n",
3910                is_ipv6 ? format_ip6_address : format_ip4_address,
3911                address->ip, address->prefix_length);
3912     }
3913   }
3914
3915   return 0;
3916 }
3917
3918 static int
3919 dump_ipv4_table (vat_main_t * vam)
3920 {
3921   if (vam->json_output)
3922     {
3923       clib_warning
3924         ("JSON output supported only for VPE API calls and dump_stats_table");
3925       return -99;
3926     }
3927
3928   return dump_ip_table (vam, 0);
3929 }
3930
3931 static int
3932 dump_ipv6_table (vat_main_t * vam)
3933 {
3934   if (vam->json_output)
3935     {
3936       clib_warning
3937         ("JSON output supported only for VPE API calls and dump_stats_table");
3938       return -99;
3939     }
3940
3941   return dump_ip_table (vam, 1);
3942 }
3943
3944 static char *
3945 counter_type_to_str (u8 counter_type, u8 is_combined)
3946 {
3947   if (!is_combined)
3948     {
3949       switch (counter_type)
3950         {
3951         case VNET_INTERFACE_COUNTER_DROP:
3952           return "drop";
3953         case VNET_INTERFACE_COUNTER_PUNT:
3954           return "punt";
3955         case VNET_INTERFACE_COUNTER_IP4:
3956           return "ip4";
3957         case VNET_INTERFACE_COUNTER_IP6:
3958           return "ip6";
3959         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3960           return "rx-no-buf";
3961         case VNET_INTERFACE_COUNTER_RX_MISS:
3962           return "rx-miss";
3963         case VNET_INTERFACE_COUNTER_RX_ERROR:
3964           return "rx-error";
3965         case VNET_INTERFACE_COUNTER_TX_ERROR:
3966           return "tx-error";
3967         default:
3968           return "INVALID-COUNTER-TYPE";
3969         }
3970     }
3971   else
3972     {
3973       switch (counter_type)
3974         {
3975         case VNET_INTERFACE_COUNTER_RX:
3976           return "rx";
3977         case VNET_INTERFACE_COUNTER_TX:
3978           return "tx";
3979         default:
3980           return "INVALID-COUNTER-TYPE";
3981         }
3982     }
3983 }
3984
3985 static int
3986 dump_stats_table (vat_main_t * vam)
3987 {
3988   vat_json_node_t node;
3989   vat_json_node_t *msg_array;
3990   vat_json_node_t *msg;
3991   vat_json_node_t *counter_array;
3992   vat_json_node_t *counter;
3993   interface_counter_t c;
3994   u64 packets;
3995   ip4_fib_counter_t *c4;
3996   ip6_fib_counter_t *c6;
3997   int i, j;
3998
3999   if (!vam->json_output)
4000     {
4001       clib_warning ("dump_stats_table supported only in JSON format");
4002       return -99;
4003     }
4004
4005   vat_json_init_object (&node);
4006
4007   /* interface counters */
4008   msg_array = vat_json_object_add (&node, "interface_counters");
4009   vat_json_init_array (msg_array);
4010   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4011     {
4012       msg = vat_json_array_add (msg_array);
4013       vat_json_init_object (msg);
4014       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4015                                        (u8 *) counter_type_to_str (i, 0));
4016       vat_json_object_add_int (msg, "is_combined", 0);
4017       counter_array = vat_json_object_add (msg, "data");
4018       vat_json_init_array (counter_array);
4019       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4020         {
4021           packets = vam->simple_interface_counters[i][j];
4022           vat_json_array_add_uint (counter_array, packets);
4023         }
4024     }
4025   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4026     {
4027       msg = vat_json_array_add (msg_array);
4028       vat_json_init_object (msg);
4029       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4030                                        (u8 *) counter_type_to_str (i, 1));
4031       vat_json_object_add_int (msg, "is_combined", 1);
4032       counter_array = vat_json_object_add (msg, "data");
4033       vat_json_init_array (counter_array);
4034       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4035         {
4036           c = vam->combined_interface_counters[i][j];
4037           counter = vat_json_array_add (counter_array);
4038           vat_json_init_object (counter);
4039           vat_json_object_add_uint (counter, "packets", c.packets);
4040           vat_json_object_add_uint (counter, "bytes", c.bytes);
4041         }
4042     }
4043
4044   /* ip4 fib counters */
4045   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4046   vat_json_init_array (msg_array);
4047   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4048     {
4049       msg = vat_json_array_add (msg_array);
4050       vat_json_init_object (msg);
4051       vat_json_object_add_uint (msg, "vrf_id",
4052                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4053       counter_array = vat_json_object_add (msg, "c");
4054       vat_json_init_array (counter_array);
4055       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4056         {
4057           counter = vat_json_array_add (counter_array);
4058           vat_json_init_object (counter);
4059           c4 = &vam->ip4_fib_counters[i][j];
4060           vat_json_object_add_ip4 (counter, "address", c4->address);
4061           vat_json_object_add_uint (counter, "address_length",
4062                                     c4->address_length);
4063           vat_json_object_add_uint (counter, "packets", c4->packets);
4064           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4065         }
4066     }
4067
4068   /* ip6 fib counters */
4069   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4070   vat_json_init_array (msg_array);
4071   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4072     {
4073       msg = vat_json_array_add (msg_array);
4074       vat_json_init_object (msg);
4075       vat_json_object_add_uint (msg, "vrf_id",
4076                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4077       counter_array = vat_json_object_add (msg, "c");
4078       vat_json_init_array (counter_array);
4079       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4080         {
4081           counter = vat_json_array_add (counter_array);
4082           vat_json_init_object (counter);
4083           c6 = &vam->ip6_fib_counters[i][j];
4084           vat_json_object_add_ip6 (counter, "address", c6->address);
4085           vat_json_object_add_uint (counter, "address_length",
4086                                     c6->address_length);
4087           vat_json_object_add_uint (counter, "packets", c6->packets);
4088           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4089         }
4090     }
4091
4092   vat_json_print (vam->ofp, &node);
4093   vat_json_free (&node);
4094
4095   return 0;
4096 }
4097
4098 int
4099 exec (vat_main_t * vam)
4100 {
4101   api_main_t *am = &api_main;
4102   vl_api_cli_request_t *mp;
4103   f64 timeout;
4104   void *oldheap;
4105   u8 *cmd = 0;
4106   unformat_input_t *i = vam->input;
4107
4108   if (vec_len (i->buffer) == 0)
4109     return -1;
4110
4111   if (vam->exec_mode == 0 && unformat (i, "mode"))
4112     {
4113       vam->exec_mode = 1;
4114       return 0;
4115     }
4116   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4117     {
4118       vam->exec_mode = 0;
4119       return 0;
4120     }
4121
4122
4123   M (CLI_REQUEST, cli_request);
4124
4125   /*
4126    * Copy cmd into shared memory.
4127    * In order for the CLI command to work, it
4128    * must be a vector ending in \n, not a C-string ending
4129    * in \n\0.
4130    */
4131   pthread_mutex_lock (&am->vlib_rp->mutex);
4132   oldheap = svm_push_data_heap (am->vlib_rp);
4133
4134   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4135   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4136
4137   svm_pop_heap (oldheap);
4138   pthread_mutex_unlock (&am->vlib_rp->mutex);
4139
4140   mp->cmd_in_shmem = (u64) cmd;
4141   S;
4142   timeout = vat_time_now (vam) + 10.0;
4143
4144   while (vat_time_now (vam) < timeout)
4145     {
4146       if (vam->result_ready == 1)
4147         {
4148           u8 *free_me;
4149           if (vam->shmem_result != NULL)
4150             fformat (vam->ofp, "%s", vam->shmem_result);
4151           pthread_mutex_lock (&am->vlib_rp->mutex);
4152           oldheap = svm_push_data_heap (am->vlib_rp);
4153
4154           free_me = (u8 *) vam->shmem_result;
4155           vec_free (free_me);
4156
4157           svm_pop_heap (oldheap);
4158           pthread_mutex_unlock (&am->vlib_rp->mutex);
4159           return 0;
4160         }
4161     }
4162   return -99;
4163 }
4164
4165 /*
4166  * Future replacement of exec() that passes CLI buffers directly in
4167  * the API messages instead of an additional shared memory area.
4168  */
4169 static int
4170 exec_inband (vat_main_t * vam)
4171 {
4172   vl_api_cli_inband_t *mp;
4173   f64 timeout;
4174   unformat_input_t *i = vam->input;
4175
4176   if (vec_len (i->buffer) == 0)
4177     return -1;
4178
4179   if (vam->exec_mode == 0 && unformat (i, "mode"))
4180     {
4181       vam->exec_mode = 1;
4182       return 0;
4183     }
4184   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4185     {
4186       vam->exec_mode = 0;
4187       return 0;
4188     }
4189
4190   /*
4191    * In order for the CLI command to work, it
4192    * must be a vector ending in \n, not a C-string ending
4193    * in \n\0.
4194    */
4195   u32 len = vec_len (vam->input->buffer);
4196   M2 (CLI_INBAND, cli_inband, len);
4197   clib_memcpy (mp->cmd, vam->input->buffer, len);
4198   mp->length = htonl (len);
4199
4200   S;
4201   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4202 }
4203
4204 static int
4205 api_create_loopback (vat_main_t * vam)
4206 {
4207   unformat_input_t *i = vam->input;
4208   vl_api_create_loopback_t *mp;
4209   f64 timeout;
4210   u8 mac_address[6];
4211   u8 mac_set = 0;
4212
4213   memset (mac_address, 0, sizeof (mac_address));
4214
4215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4216     {
4217       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4218         mac_set = 1;
4219       else
4220         break;
4221     }
4222
4223   /* Construct the API message */
4224   M (CREATE_LOOPBACK, create_loopback);
4225   if (mac_set)
4226     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4227
4228   S;
4229   W;
4230 }
4231
4232 static int
4233 api_delete_loopback (vat_main_t * vam)
4234 {
4235   unformat_input_t *i = vam->input;
4236   vl_api_delete_loopback_t *mp;
4237   f64 timeout;
4238   u32 sw_if_index = ~0;
4239
4240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4241     {
4242       if (unformat (i, "sw_if_index %d", &sw_if_index))
4243         ;
4244       else
4245         break;
4246     }
4247
4248   if (sw_if_index == ~0)
4249     {
4250       errmsg ("missing sw_if_index\n");
4251       return -99;
4252     }
4253
4254   /* Construct the API message */
4255   M (DELETE_LOOPBACK, delete_loopback);
4256   mp->sw_if_index = ntohl (sw_if_index);
4257
4258   S;
4259   W;
4260 }
4261
4262 static int
4263 api_want_stats (vat_main_t * vam)
4264 {
4265   unformat_input_t *i = vam->input;
4266   vl_api_want_stats_t *mp;
4267   f64 timeout;
4268   int enable = -1;
4269
4270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4271     {
4272       if (unformat (i, "enable"))
4273         enable = 1;
4274       else if (unformat (i, "disable"))
4275         enable = 0;
4276       else
4277         break;
4278     }
4279
4280   if (enable == -1)
4281     {
4282       errmsg ("missing enable|disable\n");
4283       return -99;
4284     }
4285
4286   M (WANT_STATS, want_stats);
4287   mp->enable_disable = enable;
4288
4289   S;
4290   W;
4291 }
4292
4293 static int
4294 api_want_interface_events (vat_main_t * vam)
4295 {
4296   unformat_input_t *i = vam->input;
4297   vl_api_want_interface_events_t *mp;
4298   f64 timeout;
4299   int enable = -1;
4300
4301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4302     {
4303       if (unformat (i, "enable"))
4304         enable = 1;
4305       else if (unformat (i, "disable"))
4306         enable = 0;
4307       else
4308         break;
4309     }
4310
4311   if (enable == -1)
4312     {
4313       errmsg ("missing enable|disable\n");
4314       return -99;
4315     }
4316
4317   M (WANT_INTERFACE_EVENTS, want_interface_events);
4318   mp->enable_disable = enable;
4319
4320   vam->interface_event_display = enable;
4321
4322   S;
4323   W;
4324 }
4325
4326
4327 /* Note: non-static, called once to set up the initial intfc table */
4328 int
4329 api_sw_interface_dump (vat_main_t * vam)
4330 {
4331   vl_api_sw_interface_dump_t *mp;
4332   f64 timeout;
4333   hash_pair_t *p;
4334   name_sort_t *nses = 0, *ns;
4335   sw_interface_subif_t *sub = NULL;
4336
4337   /* Toss the old name table */
4338   /* *INDENT-OFF* */
4339   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4340   ({
4341     vec_add2 (nses, ns, 1);
4342     ns->name = (u8 *)(p->key);
4343     ns->value = (u32) p->value[0];
4344   }));
4345   /* *INDENT-ON* */
4346
4347   hash_free (vam->sw_if_index_by_interface_name);
4348
4349   vec_foreach (ns, nses) vec_free (ns->name);
4350
4351   vec_free (nses);
4352
4353   vec_foreach (sub, vam->sw_if_subif_table)
4354   {
4355     vec_free (sub->interface_name);
4356   }
4357   vec_free (vam->sw_if_subif_table);
4358
4359   /* recreate the interface name hash table */
4360   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4361
4362   /* Get list of ethernets */
4363   M (SW_INTERFACE_DUMP, sw_interface_dump);
4364   mp->name_filter_valid = 1;
4365   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4366   S;
4367
4368   /* and local / loopback interfaces */
4369   M (SW_INTERFACE_DUMP, sw_interface_dump);
4370   mp->name_filter_valid = 1;
4371   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4372   S;
4373
4374   /* and packet-generator interfaces */
4375   M (SW_INTERFACE_DUMP, sw_interface_dump);
4376   mp->name_filter_valid = 1;
4377   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4378   S;
4379
4380   /* and vxlan-gpe tunnel interfaces */
4381   M (SW_INTERFACE_DUMP, sw_interface_dump);
4382   mp->name_filter_valid = 1;
4383   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4384            sizeof (mp->name_filter) - 1);
4385   S;
4386
4387   /* and vxlan tunnel interfaces */
4388   M (SW_INTERFACE_DUMP, sw_interface_dump);
4389   mp->name_filter_valid = 1;
4390   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4391   S;
4392
4393   /* and host (af_packet) interfaces */
4394   M (SW_INTERFACE_DUMP, sw_interface_dump);
4395   mp->name_filter_valid = 1;
4396   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4397   S;
4398
4399   /* and l2tpv3 tunnel interfaces */
4400   M (SW_INTERFACE_DUMP, sw_interface_dump);
4401   mp->name_filter_valid = 1;
4402   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4403            sizeof (mp->name_filter) - 1);
4404   S;
4405
4406   /* and GRE tunnel interfaces */
4407   M (SW_INTERFACE_DUMP, sw_interface_dump);
4408   mp->name_filter_valid = 1;
4409   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4410   S;
4411
4412   /* and LISP-GPE interfaces */
4413   M (SW_INTERFACE_DUMP, sw_interface_dump);
4414   mp->name_filter_valid = 1;
4415   strncpy ((char *) mp->name_filter, "lisp_gpe",
4416            sizeof (mp->name_filter) - 1);
4417   S;
4418
4419   /* and IPSEC tunnel interfaces */
4420   M (SW_INTERFACE_DUMP, sw_interface_dump);
4421   mp->name_filter_valid = 1;
4422   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4423   S;
4424
4425   /* Use a control ping for synchronization */
4426   {
4427     vl_api_control_ping_t *mp;
4428     M (CONTROL_PING, control_ping);
4429     S;
4430   }
4431   W;
4432 }
4433
4434 static int
4435 api_sw_interface_set_flags (vat_main_t * vam)
4436 {
4437   unformat_input_t *i = vam->input;
4438   vl_api_sw_interface_set_flags_t *mp;
4439   f64 timeout;
4440   u32 sw_if_index;
4441   u8 sw_if_index_set = 0;
4442   u8 admin_up = 0, link_up = 0;
4443
4444   /* Parse args required to build the message */
4445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4446     {
4447       if (unformat (i, "admin-up"))
4448         admin_up = 1;
4449       else if (unformat (i, "admin-down"))
4450         admin_up = 0;
4451       else if (unformat (i, "link-up"))
4452         link_up = 1;
4453       else if (unformat (i, "link-down"))
4454         link_up = 0;
4455       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4456         sw_if_index_set = 1;
4457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4458         sw_if_index_set = 1;
4459       else
4460         break;
4461     }
4462
4463   if (sw_if_index_set == 0)
4464     {
4465       errmsg ("missing interface name or sw_if_index\n");
4466       return -99;
4467     }
4468
4469   /* Construct the API message */
4470   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4471   mp->sw_if_index = ntohl (sw_if_index);
4472   mp->admin_up_down = admin_up;
4473   mp->link_up_down = link_up;
4474
4475   /* send it... */
4476   S;
4477
4478   /* Wait for a reply, return the good/bad news... */
4479   W;
4480 }
4481
4482 static int
4483 api_sw_interface_clear_stats (vat_main_t * vam)
4484 {
4485   unformat_input_t *i = vam->input;
4486   vl_api_sw_interface_clear_stats_t *mp;
4487   f64 timeout;
4488   u32 sw_if_index;
4489   u8 sw_if_index_set = 0;
4490
4491   /* Parse args required to build the message */
4492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4493     {
4494       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4495         sw_if_index_set = 1;
4496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4497         sw_if_index_set = 1;
4498       else
4499         break;
4500     }
4501
4502   /* Construct the API message */
4503   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4504
4505   if (sw_if_index_set == 1)
4506     mp->sw_if_index = ntohl (sw_if_index);
4507   else
4508     mp->sw_if_index = ~0;
4509
4510   /* send it... */
4511   S;
4512
4513   /* Wait for a reply, return the good/bad news... */
4514   W;
4515 }
4516
4517 static int
4518 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4519 {
4520   unformat_input_t *i = vam->input;
4521   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4522   f64 timeout;
4523   u32 sw_if_index;
4524   u8 sw_if_index_set = 0;
4525   u32 subport;
4526   u8 subport_set = 0;
4527   u32 pipe;
4528   u8 pipe_set = 0;
4529   u32 profile;
4530   u8 profile_set = 0;
4531
4532   /* Parse args required to build the message */
4533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4534     {
4535       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4536         sw_if_index_set = 1;
4537       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4538         sw_if_index_set = 1;
4539       else if (unformat (i, "subport %u", &subport))
4540         subport_set = 1;
4541       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4542         sw_if_index_set = 1;
4543       else if (unformat (i, "pipe %u", &pipe))
4544         pipe_set = 1;
4545       else if (unformat (i, "profile %u", &profile))
4546         profile_set = 1;
4547       else
4548         break;
4549     }
4550
4551   if (sw_if_index_set == 0)
4552     {
4553       errmsg ("missing interface name or sw_if_index\n");
4554       return -99;
4555     }
4556
4557   if (subport_set == 0)
4558     {
4559       errmsg ("missing subport \n");
4560       return -99;
4561     }
4562
4563   if (pipe_set == 0)
4564     {
4565       errmsg ("missing pipe\n");
4566       return -99;
4567     }
4568
4569   if (profile_set == 0)
4570     {
4571       errmsg ("missing profile\n");
4572       return -99;
4573     }
4574
4575   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4576
4577   mp->sw_if_index = ntohl (sw_if_index);
4578   mp->subport = ntohl (subport);
4579   mp->pipe = ntohl (pipe);
4580   mp->profile = ntohl (profile);
4581
4582
4583   S;
4584   W;
4585   /* NOTREACHED */
4586   return 0;
4587 }
4588
4589 static int
4590 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4591 {
4592   unformat_input_t *i = vam->input;
4593   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4594   f64 timeout;
4595   u32 sw_if_index;
4596   u8 sw_if_index_set = 0;
4597   u32 subport;
4598   u8 subport_set = 0;
4599   u32 tb_rate = 1250000000;     /* 10GbE */
4600   u32 tb_size = 1000000;
4601   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4602   u32 tc_period = 10;
4603
4604   /* Parse args required to build the message */
4605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4606     {
4607       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4608         sw_if_index_set = 1;
4609       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4610         sw_if_index_set = 1;
4611       else if (unformat (i, "subport %u", &subport))
4612         subport_set = 1;
4613       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4614         sw_if_index_set = 1;
4615       else if (unformat (i, "rate %u", &tb_rate))
4616         {
4617           u32 tc_id;
4618
4619           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4620                tc_id++)
4621             tc_rate[tc_id] = tb_rate;
4622         }
4623       else if (unformat (i, "bktsize %u", &tb_size))
4624         ;
4625       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4626         ;
4627       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4628         ;
4629       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4630         ;
4631       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4632         ;
4633       else if (unformat (i, "period %u", &tc_period))
4634         ;
4635       else
4636         break;
4637     }
4638
4639   if (sw_if_index_set == 0)
4640     {
4641       errmsg ("missing interface name or sw_if_index\n");
4642       return -99;
4643     }
4644
4645   if (subport_set == 0)
4646     {
4647       errmsg ("missing subport \n");
4648       return -99;
4649     }
4650
4651   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4652
4653   mp->sw_if_index = ntohl (sw_if_index);
4654   mp->subport = ntohl (subport);
4655   mp->tb_rate = ntohl (tb_rate);
4656   mp->tb_size = ntohl (tb_size);
4657   mp->tc_rate[0] = ntohl (tc_rate[0]);
4658   mp->tc_rate[1] = ntohl (tc_rate[1]);
4659   mp->tc_rate[2] = ntohl (tc_rate[2]);
4660   mp->tc_rate[3] = ntohl (tc_rate[3]);
4661   mp->tc_period = ntohl (tc_period);
4662
4663   S;
4664   W;
4665   /* NOTREACHED */
4666   return 0;
4667 }
4668
4669 static int
4670 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4671 {
4672   unformat_input_t *i = vam->input;
4673   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4674   f64 timeout;
4675   u32 sw_if_index;
4676   u8 sw_if_index_set = 0;
4677   u8 entry_set = 0;
4678   u8 tc_set = 0;
4679   u8 queue_set = 0;
4680   u32 entry, tc, queue;
4681
4682   /* Parse args required to build the message */
4683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4684     {
4685       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4686         sw_if_index_set = 1;
4687       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4688         sw_if_index_set = 1;
4689       else if (unformat (i, "entry %d", &entry))
4690         entry_set = 1;
4691       else if (unformat (i, "tc %d", &tc))
4692         tc_set = 1;
4693       else if (unformat (i, "queue %d", &queue))
4694         queue_set = 1;
4695       else
4696         break;
4697     }
4698
4699   if (sw_if_index_set == 0)
4700     {
4701       errmsg ("missing interface name or sw_if_index\n");
4702       return -99;
4703     }
4704
4705   if (entry_set == 0)
4706     {
4707       errmsg ("missing entry \n");
4708       return -99;
4709     }
4710
4711   if (tc_set == 0)
4712     {
4713       errmsg ("missing traffic class \n");
4714       return -99;
4715     }
4716
4717   if (queue_set == 0)
4718     {
4719       errmsg ("missing queue \n");
4720       return -99;
4721     }
4722
4723   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4724
4725   mp->sw_if_index = ntohl (sw_if_index);
4726   mp->entry = ntohl (entry);
4727   mp->tc = ntohl (tc);
4728   mp->queue = ntohl (queue);
4729
4730   S;
4731   W;
4732   /* NOTREACHED */
4733   return 0;
4734 }
4735
4736 static int
4737 api_sw_interface_add_del_address (vat_main_t * vam)
4738 {
4739   unformat_input_t *i = vam->input;
4740   vl_api_sw_interface_add_del_address_t *mp;
4741   f64 timeout;
4742   u32 sw_if_index;
4743   u8 sw_if_index_set = 0;
4744   u8 is_add = 1, del_all = 0;
4745   u32 address_length = 0;
4746   u8 v4_address_set = 0;
4747   u8 v6_address_set = 0;
4748   ip4_address_t v4address;
4749   ip6_address_t v6address;
4750
4751   /* Parse args required to build the message */
4752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4753     {
4754       if (unformat (i, "del-all"))
4755         del_all = 1;
4756       else if (unformat (i, "del"))
4757         is_add = 0;
4758       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4759         sw_if_index_set = 1;
4760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4761         sw_if_index_set = 1;
4762       else if (unformat (i, "%U/%d",
4763                          unformat_ip4_address, &v4address, &address_length))
4764         v4_address_set = 1;
4765       else if (unformat (i, "%U/%d",
4766                          unformat_ip6_address, &v6address, &address_length))
4767         v6_address_set = 1;
4768       else
4769         break;
4770     }
4771
4772   if (sw_if_index_set == 0)
4773     {
4774       errmsg ("missing interface name or sw_if_index\n");
4775       return -99;
4776     }
4777   if (v4_address_set && v6_address_set)
4778     {
4779       errmsg ("both v4 and v6 addresses set\n");
4780       return -99;
4781     }
4782   if (!v4_address_set && !v6_address_set && !del_all)
4783     {
4784       errmsg ("no addresses set\n");
4785       return -99;
4786     }
4787
4788   /* Construct the API message */
4789   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4790
4791   mp->sw_if_index = ntohl (sw_if_index);
4792   mp->is_add = is_add;
4793   mp->del_all = del_all;
4794   if (v6_address_set)
4795     {
4796       mp->is_ipv6 = 1;
4797       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4798     }
4799   else
4800     {
4801       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4802     }
4803   mp->address_length = address_length;
4804
4805   /* send it... */
4806   S;
4807
4808   /* Wait for a reply, return good/bad news  */
4809   W;
4810 }
4811
4812 static int
4813 api_sw_interface_set_table (vat_main_t * vam)
4814 {
4815   unformat_input_t *i = vam->input;
4816   vl_api_sw_interface_set_table_t *mp;
4817   f64 timeout;
4818   u32 sw_if_index, vrf_id = 0;
4819   u8 sw_if_index_set = 0;
4820   u8 is_ipv6 = 0;
4821
4822   /* Parse args required to build the message */
4823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4824     {
4825       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4826         sw_if_index_set = 1;
4827       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4828         sw_if_index_set = 1;
4829       else if (unformat (i, "vrf %d", &vrf_id))
4830         ;
4831       else if (unformat (i, "ipv6"))
4832         is_ipv6 = 1;
4833       else
4834         break;
4835     }
4836
4837   if (sw_if_index_set == 0)
4838     {
4839       errmsg ("missing interface name or sw_if_index\n");
4840       return -99;
4841     }
4842
4843   /* Construct the API message */
4844   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4845
4846   mp->sw_if_index = ntohl (sw_if_index);
4847   mp->is_ipv6 = is_ipv6;
4848   mp->vrf_id = ntohl (vrf_id);
4849
4850   /* send it... */
4851   S;
4852
4853   /* Wait for a reply... */
4854   W;
4855 }
4856
4857 static int
4858 api_sw_interface_set_vpath (vat_main_t * vam)
4859 {
4860   unformat_input_t *i = vam->input;
4861   vl_api_sw_interface_set_vpath_t *mp;
4862   f64 timeout;
4863   u32 sw_if_index = 0;
4864   u8 sw_if_index_set = 0;
4865   u8 is_enable = 0;
4866
4867   /* Parse args required to build the message */
4868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4869     {
4870       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4871         sw_if_index_set = 1;
4872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4873         sw_if_index_set = 1;
4874       else if (unformat (i, "enable"))
4875         is_enable = 1;
4876       else if (unformat (i, "disable"))
4877         is_enable = 0;
4878       else
4879         break;
4880     }
4881
4882   if (sw_if_index_set == 0)
4883     {
4884       errmsg ("missing interface name or sw_if_index\n");
4885       return -99;
4886     }
4887
4888   /* Construct the API message */
4889   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4890
4891   mp->sw_if_index = ntohl (sw_if_index);
4892   mp->enable = is_enable;
4893
4894   /* send it... */
4895   S;
4896
4897   /* Wait for a reply... */
4898   W;
4899 }
4900
4901 static int
4902 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4903 {
4904   unformat_input_t *i = vam->input;
4905   vl_api_sw_interface_set_l2_xconnect_t *mp;
4906   f64 timeout;
4907   u32 rx_sw_if_index;
4908   u8 rx_sw_if_index_set = 0;
4909   u32 tx_sw_if_index;
4910   u8 tx_sw_if_index_set = 0;
4911   u8 enable = 1;
4912
4913   /* Parse args required to build the message */
4914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4915     {
4916       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4917         rx_sw_if_index_set = 1;
4918       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4919         tx_sw_if_index_set = 1;
4920       else if (unformat (i, "rx"))
4921         {
4922           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4923             {
4924               if (unformat (i, "%U", unformat_sw_if_index, vam,
4925                             &rx_sw_if_index))
4926                 rx_sw_if_index_set = 1;
4927             }
4928           else
4929             break;
4930         }
4931       else if (unformat (i, "tx"))
4932         {
4933           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4934             {
4935               if (unformat (i, "%U", unformat_sw_if_index, vam,
4936                             &tx_sw_if_index))
4937                 tx_sw_if_index_set = 1;
4938             }
4939           else
4940             break;
4941         }
4942       else if (unformat (i, "enable"))
4943         enable = 1;
4944       else if (unformat (i, "disable"))
4945         enable = 0;
4946       else
4947         break;
4948     }
4949
4950   if (rx_sw_if_index_set == 0)
4951     {
4952       errmsg ("missing rx interface name or rx_sw_if_index\n");
4953       return -99;
4954     }
4955
4956   if (enable && (tx_sw_if_index_set == 0))
4957     {
4958       errmsg ("missing tx interface name or tx_sw_if_index\n");
4959       return -99;
4960     }
4961
4962   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4963
4964   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4965   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4966   mp->enable = enable;
4967
4968   S;
4969   W;
4970   /* NOTREACHED */
4971   return 0;
4972 }
4973
4974 static int
4975 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4976 {
4977   unformat_input_t *i = vam->input;
4978   vl_api_sw_interface_set_l2_bridge_t *mp;
4979   f64 timeout;
4980   u32 rx_sw_if_index;
4981   u8 rx_sw_if_index_set = 0;
4982   u32 bd_id;
4983   u8 bd_id_set = 0;
4984   u8 bvi = 0;
4985   u32 shg = 0;
4986   u8 enable = 1;
4987
4988   /* Parse args required to build the message */
4989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4990     {
4991       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4992         rx_sw_if_index_set = 1;
4993       else if (unformat (i, "bd_id %d", &bd_id))
4994         bd_id_set = 1;
4995       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4996         rx_sw_if_index_set = 1;
4997       else if (unformat (i, "shg %d", &shg))
4998         ;
4999       else if (unformat (i, "bvi"))
5000         bvi = 1;
5001       else if (unformat (i, "enable"))
5002         enable = 1;
5003       else if (unformat (i, "disable"))
5004         enable = 0;
5005       else
5006         break;
5007     }
5008
5009   if (rx_sw_if_index_set == 0)
5010     {
5011       errmsg ("missing rx interface name or sw_if_index\n");
5012       return -99;
5013     }
5014
5015   if (enable && (bd_id_set == 0))
5016     {
5017       errmsg ("missing bridge domain\n");
5018       return -99;
5019     }
5020
5021   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5022
5023   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5024   mp->bd_id = ntohl (bd_id);
5025   mp->shg = (u8) shg;
5026   mp->bvi = bvi;
5027   mp->enable = enable;
5028
5029   S;
5030   W;
5031   /* NOTREACHED */
5032   return 0;
5033 }
5034
5035 static int
5036 api_bridge_domain_dump (vat_main_t * vam)
5037 {
5038   unformat_input_t *i = vam->input;
5039   vl_api_bridge_domain_dump_t *mp;
5040   f64 timeout;
5041   u32 bd_id = ~0;
5042
5043   /* Parse args required to build the message */
5044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5045     {
5046       if (unformat (i, "bd_id %d", &bd_id))
5047         ;
5048       else
5049         break;
5050     }
5051
5052   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5053   mp->bd_id = ntohl (bd_id);
5054   S;
5055
5056   /* Use a control ping for synchronization */
5057   {
5058     vl_api_control_ping_t *mp;
5059     M (CONTROL_PING, control_ping);
5060     S;
5061   }
5062
5063   W;
5064   /* NOTREACHED */
5065   return 0;
5066 }
5067
5068 static int
5069 api_bridge_domain_add_del (vat_main_t * vam)
5070 {
5071   unformat_input_t *i = vam->input;
5072   vl_api_bridge_domain_add_del_t *mp;
5073   f64 timeout;
5074   u32 bd_id = ~0;
5075   u8 is_add = 1;
5076   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5077
5078   /* Parse args required to build the message */
5079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5080     {
5081       if (unformat (i, "bd_id %d", &bd_id))
5082         ;
5083       else if (unformat (i, "flood %d", &flood))
5084         ;
5085       else if (unformat (i, "uu-flood %d", &uu_flood))
5086         ;
5087       else if (unformat (i, "forward %d", &forward))
5088         ;
5089       else if (unformat (i, "learn %d", &learn))
5090         ;
5091       else if (unformat (i, "arp-term %d", &arp_term))
5092         ;
5093       else if (unformat (i, "del"))
5094         {
5095           is_add = 0;
5096           flood = uu_flood = forward = learn = 0;
5097         }
5098       else
5099         break;
5100     }
5101
5102   if (bd_id == ~0)
5103     {
5104       errmsg ("missing bridge domain\n");
5105       return -99;
5106     }
5107
5108   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5109
5110   mp->bd_id = ntohl (bd_id);
5111   mp->flood = flood;
5112   mp->uu_flood = uu_flood;
5113   mp->forward = forward;
5114   mp->learn = learn;
5115   mp->arp_term = arp_term;
5116   mp->is_add = is_add;
5117
5118   S;
5119   W;
5120   /* NOTREACHED */
5121   return 0;
5122 }
5123
5124 static int
5125 api_l2fib_add_del (vat_main_t * vam)
5126 {
5127   unformat_input_t *i = vam->input;
5128   vl_api_l2fib_add_del_t *mp;
5129   f64 timeout;
5130   u64 mac = 0;
5131   u8 mac_set = 0;
5132   u32 bd_id;
5133   u8 bd_id_set = 0;
5134   u32 sw_if_index;
5135   u8 sw_if_index_set = 0;
5136   u8 is_add = 1;
5137   u8 static_mac = 0;
5138   u8 filter_mac = 0;
5139   u8 bvi_mac = 0;
5140   int count = 1;
5141   f64 before = 0;
5142   int j;
5143
5144   /* Parse args required to build the message */
5145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5146     {
5147       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5148         mac_set = 1;
5149       else if (unformat (i, "bd_id %d", &bd_id))
5150         bd_id_set = 1;
5151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5152         sw_if_index_set = 1;
5153       else if (unformat (i, "sw_if"))
5154         {
5155           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5156             {
5157               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5158                 sw_if_index_set = 1;
5159             }
5160           else
5161             break;
5162         }
5163       else if (unformat (i, "static"))
5164         static_mac = 1;
5165       else if (unformat (i, "filter"))
5166         {
5167           filter_mac = 1;
5168           static_mac = 1;
5169         }
5170       else if (unformat (i, "bvi"))
5171         {
5172           bvi_mac = 1;
5173           static_mac = 1;
5174         }
5175       else if (unformat (i, "del"))
5176         is_add = 0;
5177       else if (unformat (i, "count %d", &count))
5178         ;
5179       else
5180         break;
5181     }
5182
5183   if (mac_set == 0)
5184     {
5185       errmsg ("missing mac address\n");
5186       return -99;
5187     }
5188
5189   if (bd_id_set == 0)
5190     {
5191       errmsg ("missing bridge domain\n");
5192       return -99;
5193     }
5194
5195   if (is_add && (sw_if_index_set == 0))
5196     {
5197       errmsg ("missing interface name or sw_if_index\n");
5198       return -99;
5199     }
5200
5201   if (count > 1)
5202     {
5203       /* Turn on async mode */
5204       vam->async_mode = 1;
5205       vam->async_errors = 0;
5206       before = vat_time_now (vam);
5207     }
5208
5209   for (j = 0; j < count; j++)
5210     {
5211       M (L2FIB_ADD_DEL, l2fib_add_del);
5212
5213       mp->mac = mac;
5214       mp->bd_id = ntohl (bd_id);
5215       mp->is_add = is_add;
5216
5217       if (is_add)
5218         {
5219           mp->sw_if_index = ntohl (sw_if_index);
5220           mp->static_mac = static_mac;
5221           mp->filter_mac = filter_mac;
5222           mp->bvi_mac = bvi_mac;
5223         }
5224       increment_mac_address (&mac);
5225       /* send it... */
5226       S;
5227     }
5228
5229   if (count > 1)
5230     {
5231       vl_api_control_ping_t *mp;
5232       f64 after;
5233
5234       /* Shut off async mode */
5235       vam->async_mode = 0;
5236
5237       M (CONTROL_PING, control_ping);
5238       S;
5239
5240       timeout = vat_time_now (vam) + 1.0;
5241       while (vat_time_now (vam) < timeout)
5242         if (vam->result_ready == 1)
5243           goto out;
5244       vam->retval = -99;
5245
5246     out:
5247       if (vam->retval == -99)
5248         errmsg ("timeout\n");
5249
5250       if (vam->async_errors > 0)
5251         {
5252           errmsg ("%d asynchronous errors\n", vam->async_errors);
5253           vam->retval = -98;
5254         }
5255       vam->async_errors = 0;
5256       after = vat_time_now (vam);
5257
5258       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5259                count, after - before, count / (after - before));
5260     }
5261   else
5262     {
5263       /* Wait for a reply... */
5264       W;
5265     }
5266   /* Return the good/bad news */
5267   return (vam->retval);
5268 }
5269
5270 static int
5271 api_l2_flags (vat_main_t * vam)
5272 {
5273   unformat_input_t *i = vam->input;
5274   vl_api_l2_flags_t *mp;
5275   f64 timeout;
5276   u32 sw_if_index;
5277   u32 feature_bitmap = 0;
5278   u8 sw_if_index_set = 0;
5279
5280   /* Parse args required to build the message */
5281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5282     {
5283       if (unformat (i, "sw_if_index %d", &sw_if_index))
5284         sw_if_index_set = 1;
5285       else if (unformat (i, "sw_if"))
5286         {
5287           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5288             {
5289               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5290                 sw_if_index_set = 1;
5291             }
5292           else
5293             break;
5294         }
5295       else if (unformat (i, "learn"))
5296         feature_bitmap |= L2INPUT_FEAT_LEARN;
5297       else if (unformat (i, "forward"))
5298         feature_bitmap |= L2INPUT_FEAT_FWD;
5299       else if (unformat (i, "flood"))
5300         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5301       else if (unformat (i, "uu-flood"))
5302         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5303       else
5304         break;
5305     }
5306
5307   if (sw_if_index_set == 0)
5308     {
5309       errmsg ("missing interface name or sw_if_index\n");
5310       return -99;
5311     }
5312
5313   M (L2_FLAGS, l2_flags);
5314
5315   mp->sw_if_index = ntohl (sw_if_index);
5316   mp->feature_bitmap = ntohl (feature_bitmap);
5317
5318   S;
5319   W;
5320   /* NOTREACHED */
5321   return 0;
5322 }
5323
5324 static int
5325 api_bridge_flags (vat_main_t * vam)
5326 {
5327   unformat_input_t *i = vam->input;
5328   vl_api_bridge_flags_t *mp;
5329   f64 timeout;
5330   u32 bd_id;
5331   u8 bd_id_set = 0;
5332   u8 is_set = 1;
5333   u32 flags = 0;
5334
5335   /* Parse args required to build the message */
5336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5337     {
5338       if (unformat (i, "bd_id %d", &bd_id))
5339         bd_id_set = 1;
5340       else if (unformat (i, "learn"))
5341         flags |= L2_LEARN;
5342       else if (unformat (i, "forward"))
5343         flags |= L2_FWD;
5344       else if (unformat (i, "flood"))
5345         flags |= L2_FLOOD;
5346       else if (unformat (i, "uu-flood"))
5347         flags |= L2_UU_FLOOD;
5348       else if (unformat (i, "arp-term"))
5349         flags |= L2_ARP_TERM;
5350       else if (unformat (i, "off"))
5351         is_set = 0;
5352       else if (unformat (i, "disable"))
5353         is_set = 0;
5354       else
5355         break;
5356     }
5357
5358   if (bd_id_set == 0)
5359     {
5360       errmsg ("missing bridge domain\n");
5361       return -99;
5362     }
5363
5364   M (BRIDGE_FLAGS, bridge_flags);
5365
5366   mp->bd_id = ntohl (bd_id);
5367   mp->feature_bitmap = ntohl (flags);
5368   mp->is_set = is_set;
5369
5370   S;
5371   W;
5372   /* NOTREACHED */
5373   return 0;
5374 }
5375
5376 static int
5377 api_bd_ip_mac_add_del (vat_main_t * vam)
5378 {
5379   unformat_input_t *i = vam->input;
5380   vl_api_bd_ip_mac_add_del_t *mp;
5381   f64 timeout;
5382   u32 bd_id;
5383   u8 is_ipv6 = 0;
5384   u8 is_add = 1;
5385   u8 bd_id_set = 0;
5386   u8 ip_set = 0;
5387   u8 mac_set = 0;
5388   ip4_address_t v4addr;
5389   ip6_address_t v6addr;
5390   u8 macaddr[6];
5391
5392
5393   /* Parse args required to build the message */
5394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5395     {
5396       if (unformat (i, "bd_id %d", &bd_id))
5397         {
5398           bd_id_set++;
5399         }
5400       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5401         {
5402           ip_set++;
5403         }
5404       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5405         {
5406           ip_set++;
5407           is_ipv6++;
5408         }
5409       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5410         {
5411           mac_set++;
5412         }
5413       else if (unformat (i, "del"))
5414         is_add = 0;
5415       else
5416         break;
5417     }
5418
5419   if (bd_id_set == 0)
5420     {
5421       errmsg ("missing bridge domain\n");
5422       return -99;
5423     }
5424   else if (ip_set == 0)
5425     {
5426       errmsg ("missing IP address\n");
5427       return -99;
5428     }
5429   else if (mac_set == 0)
5430     {
5431       errmsg ("missing MAC address\n");
5432       return -99;
5433     }
5434
5435   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5436
5437   mp->bd_id = ntohl (bd_id);
5438   mp->is_ipv6 = is_ipv6;
5439   mp->is_add = is_add;
5440   if (is_ipv6)
5441     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5442   else
5443     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5444   clib_memcpy (mp->mac_address, macaddr, 6);
5445   S;
5446   W;
5447   /* NOTREACHED */
5448   return 0;
5449 }
5450
5451 static int
5452 api_tap_connect (vat_main_t * vam)
5453 {
5454   unformat_input_t *i = vam->input;
5455   vl_api_tap_connect_t *mp;
5456   f64 timeout;
5457   u8 mac_address[6];
5458   u8 random_mac = 1;
5459   u8 name_set = 0;
5460   u8 *tap_name;
5461
5462   memset (mac_address, 0, sizeof (mac_address));
5463
5464   /* Parse args required to build the message */
5465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5466     {
5467       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5468         {
5469           random_mac = 0;
5470         }
5471       else if (unformat (i, "random-mac"))
5472         random_mac = 1;
5473       else if (unformat (i, "tapname %s", &tap_name))
5474         name_set = 1;
5475       else
5476         break;
5477     }
5478
5479   if (name_set == 0)
5480     {
5481       errmsg ("missing tap name\n");
5482       return -99;
5483     }
5484   if (vec_len (tap_name) > 63)
5485     {
5486       errmsg ("tap name too long\n");
5487     }
5488   vec_add1 (tap_name, 0);
5489
5490   /* Construct the API message */
5491   M (TAP_CONNECT, tap_connect);
5492
5493   mp->use_random_mac = random_mac;
5494   clib_memcpy (mp->mac_address, mac_address, 6);
5495   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5496   vec_free (tap_name);
5497
5498   /* send it... */
5499   S;
5500
5501   /* Wait for a reply... */
5502   W;
5503 }
5504
5505 static int
5506 api_tap_modify (vat_main_t * vam)
5507 {
5508   unformat_input_t *i = vam->input;
5509   vl_api_tap_modify_t *mp;
5510   f64 timeout;
5511   u8 mac_address[6];
5512   u8 random_mac = 1;
5513   u8 name_set = 0;
5514   u8 *tap_name;
5515   u32 sw_if_index = ~0;
5516   u8 sw_if_index_set = 0;
5517
5518   memset (mac_address, 0, sizeof (mac_address));
5519
5520   /* Parse args required to build the message */
5521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5522     {
5523       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5524         sw_if_index_set = 1;
5525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5526         sw_if_index_set = 1;
5527       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5528         {
5529           random_mac = 0;
5530         }
5531       else if (unformat (i, "random-mac"))
5532         random_mac = 1;
5533       else if (unformat (i, "tapname %s", &tap_name))
5534         name_set = 1;
5535       else
5536         break;
5537     }
5538
5539   if (sw_if_index_set == 0)
5540     {
5541       errmsg ("missing vpp interface name");
5542       return -99;
5543     }
5544   if (name_set == 0)
5545     {
5546       errmsg ("missing tap name\n");
5547       return -99;
5548     }
5549   if (vec_len (tap_name) > 63)
5550     {
5551       errmsg ("tap name too long\n");
5552     }
5553   vec_add1 (tap_name, 0);
5554
5555   /* Construct the API message */
5556   M (TAP_MODIFY, tap_modify);
5557
5558   mp->use_random_mac = random_mac;
5559   mp->sw_if_index = ntohl (sw_if_index);
5560   clib_memcpy (mp->mac_address, mac_address, 6);
5561   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5562   vec_free (tap_name);
5563
5564   /* send it... */
5565   S;
5566
5567   /* Wait for a reply... */
5568   W;
5569 }
5570
5571 static int
5572 api_tap_delete (vat_main_t * vam)
5573 {
5574   unformat_input_t *i = vam->input;
5575   vl_api_tap_delete_t *mp;
5576   f64 timeout;
5577   u32 sw_if_index = ~0;
5578   u8 sw_if_index_set = 0;
5579
5580   /* Parse args required to build the message */
5581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5582     {
5583       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5584         sw_if_index_set = 1;
5585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5586         sw_if_index_set = 1;
5587       else
5588         break;
5589     }
5590
5591   if (sw_if_index_set == 0)
5592     {
5593       errmsg ("missing vpp interface name");
5594       return -99;
5595     }
5596
5597   /* Construct the API message */
5598   M (TAP_DELETE, tap_delete);
5599
5600   mp->sw_if_index = ntohl (sw_if_index);
5601
5602   /* send it... */
5603   S;
5604
5605   /* Wait for a reply... */
5606   W;
5607 }
5608
5609 static int
5610 api_ip_add_del_route (vat_main_t * vam)
5611 {
5612   unformat_input_t *i = vam->input;
5613   vl_api_ip_add_del_route_t *mp;
5614   f64 timeout;
5615   u32 sw_if_index = ~0, vrf_id = 0;
5616   u8 sw_if_index_set = 0;
5617   u8 is_ipv6 = 0;
5618   u8 is_local = 0, is_drop = 0;
5619   u8 create_vrf_if_needed = 0;
5620   u8 is_add = 1;
5621   u8 next_hop_weight = 1;
5622   u8 not_last = 0;
5623   u8 is_multipath = 0;
5624   u8 address_set = 0;
5625   u8 address_length_set = 0;
5626   u32 lookup_in_vrf = 0;
5627   u32 resolve_attempts = 0;
5628   u32 dst_address_length = 0;
5629   u8 next_hop_set = 0;
5630   ip4_address_t v4_dst_address, v4_next_hop_address;
5631   ip6_address_t v6_dst_address, v6_next_hop_address;
5632   int count = 1;
5633   int j;
5634   f64 before = 0;
5635   u32 random_add_del = 0;
5636   u32 *random_vector = 0;
5637   uword *random_hash;
5638   u32 random_seed = 0xdeaddabe;
5639   u32 classify_table_index = ~0;
5640   u8 is_classify = 0;
5641   u8 resolve_host, resolve_attached;
5642
5643   /* Parse args required to build the message */
5644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5645     {
5646       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5647         sw_if_index_set = 1;
5648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5649         sw_if_index_set = 1;
5650       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5651         {
5652           address_set = 1;
5653           is_ipv6 = 0;
5654         }
5655       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5656         {
5657           address_set = 1;
5658           is_ipv6 = 1;
5659         }
5660       else if (unformat (i, "/%d", &dst_address_length))
5661         {
5662           address_length_set = 1;
5663         }
5664
5665       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5666                                          &v4_next_hop_address))
5667         {
5668           next_hop_set = 1;
5669         }
5670       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5671                                          &v6_next_hop_address))
5672         {
5673           next_hop_set = 1;
5674         }
5675       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5676         ;
5677       else if (unformat (i, "weight %d", &next_hop_weight))
5678         ;
5679       else if (unformat (i, "drop"))
5680         {
5681           is_drop = 1;
5682         }
5683       else if (unformat (i, "local"))
5684         {
5685           is_local = 1;
5686         }
5687       else if (unformat (i, "classify %d", &classify_table_index))
5688         {
5689           is_classify = 1;
5690         }
5691       else if (unformat (i, "del"))
5692         is_add = 0;
5693       else if (unformat (i, "add"))
5694         is_add = 1;
5695       else if (unformat (i, "not-last"))
5696         not_last = 1;
5697       else if (unformat (i, "resolve-via-host"))
5698         resolve_host = 1;
5699       else if (unformat (i, "resolve-via-attached"))
5700         resolve_attached = 1;
5701       else if (unformat (i, "multipath"))
5702         is_multipath = 1;
5703       else if (unformat (i, "vrf %d", &vrf_id))
5704         ;
5705       else if (unformat (i, "create-vrf"))
5706         create_vrf_if_needed = 1;
5707       else if (unformat (i, "count %d", &count))
5708         ;
5709       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5710         ;
5711       else if (unformat (i, "random"))
5712         random_add_del = 1;
5713       else if (unformat (i, "seed %d", &random_seed))
5714         ;
5715       else
5716         {
5717           clib_warning ("parse error '%U'", format_unformat_error, i);
5718           return -99;
5719         }
5720     }
5721
5722   if (resolve_attempts > 0 && sw_if_index_set == 0)
5723     {
5724       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5725       return -99;
5726     }
5727
5728   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5729     {
5730       errmsg ("next hop / local / drop / classify not set\n");
5731       return -99;
5732     }
5733
5734   if (address_set == 0)
5735     {
5736       errmsg ("missing addresses\n");
5737       return -99;
5738     }
5739
5740   if (address_length_set == 0)
5741     {
5742       errmsg ("missing address length\n");
5743       return -99;
5744     }
5745
5746   /* Generate a pile of unique, random routes */
5747   if (random_add_del)
5748     {
5749       u32 this_random_address;
5750       random_hash = hash_create (count, sizeof (uword));
5751
5752       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5753       for (j = 0; j <= count; j++)
5754         {
5755           do
5756             {
5757               this_random_address = random_u32 (&random_seed);
5758               this_random_address =
5759                 clib_host_to_net_u32 (this_random_address);
5760             }
5761           while (hash_get (random_hash, this_random_address));
5762           vec_add1 (random_vector, this_random_address);
5763           hash_set (random_hash, this_random_address, 1);
5764         }
5765       hash_free (random_hash);
5766       v4_dst_address.as_u32 = random_vector[0];
5767     }
5768
5769   if (count > 1)
5770     {
5771       /* Turn on async mode */
5772       vam->async_mode = 1;
5773       vam->async_errors = 0;
5774       before = vat_time_now (vam);
5775     }
5776
5777   for (j = 0; j < count; j++)
5778     {
5779       /* Construct the API message */
5780       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5781
5782       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5783       mp->vrf_id = ntohl (vrf_id);
5784       if (resolve_attempts > 0)
5785         {
5786           mp->resolve_attempts = ntohl (resolve_attempts);
5787           mp->resolve_if_needed = 1;
5788         }
5789       mp->create_vrf_if_needed = create_vrf_if_needed;
5790
5791       mp->is_add = is_add;
5792       mp->is_drop = is_drop;
5793       mp->is_ipv6 = is_ipv6;
5794       mp->is_local = is_local;
5795       mp->is_classify = is_classify;
5796       mp->is_multipath = is_multipath;
5797       mp->is_resolve_host = resolve_host;
5798       mp->is_resolve_attached = resolve_attached;
5799       mp->not_last = not_last;
5800       mp->next_hop_weight = next_hop_weight;
5801       mp->dst_address_length = dst_address_length;
5802       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5803       mp->classify_table_index = ntohl (classify_table_index);
5804
5805       if (is_ipv6)
5806         {
5807           clib_memcpy (mp->dst_address, &v6_dst_address,
5808                        sizeof (v6_dst_address));
5809           if (next_hop_set)
5810             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5811                          sizeof (v6_next_hop_address));
5812           increment_v6_address (&v6_dst_address);
5813         }
5814       else
5815         {
5816           clib_memcpy (mp->dst_address, &v4_dst_address,
5817                        sizeof (v4_dst_address));
5818           if (next_hop_set)
5819             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5820                          sizeof (v4_next_hop_address));
5821           if (random_add_del)
5822             v4_dst_address.as_u32 = random_vector[j + 1];
5823           else
5824             increment_v4_address (&v4_dst_address);
5825         }
5826       /* send it... */
5827       S;
5828     }
5829
5830   /* When testing multiple add/del ops, use a control-ping to sync */
5831   if (count > 1)
5832     {
5833       vl_api_control_ping_t *mp;
5834       f64 after;
5835
5836       /* Shut off async mode */
5837       vam->async_mode = 0;
5838
5839       M (CONTROL_PING, control_ping);
5840       S;
5841
5842       timeout = vat_time_now (vam) + 1.0;
5843       while (vat_time_now (vam) < timeout)
5844         if (vam->result_ready == 1)
5845           goto out;
5846       vam->retval = -99;
5847
5848     out:
5849       if (vam->retval == -99)
5850         errmsg ("timeout\n");
5851
5852       if (vam->async_errors > 0)
5853         {
5854           errmsg ("%d asynchronous errors\n", vam->async_errors);
5855           vam->retval = -98;
5856         }
5857       vam->async_errors = 0;
5858       after = vat_time_now (vam);
5859
5860       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5861                count, after - before, count / (after - before));
5862     }
5863   else
5864     {
5865       /* Wait for a reply... */
5866       W;
5867     }
5868
5869   /* Return the good/bad news */
5870   return (vam->retval);
5871 }
5872
5873 static int
5874 api_proxy_arp_add_del (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_proxy_arp_add_del_t *mp;
5878   f64 timeout;
5879   u32 vrf_id = 0;
5880   u8 is_add = 1;
5881   ip4_address_t lo, hi;
5882   u8 range_set = 0;
5883
5884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5885     {
5886       if (unformat (i, "vrf %d", &vrf_id))
5887         ;
5888       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5889                          unformat_ip4_address, &hi))
5890         range_set = 1;
5891       else if (unformat (i, "del"))
5892         is_add = 0;
5893       else
5894         {
5895           clib_warning ("parse error '%U'", format_unformat_error, i);
5896           return -99;
5897         }
5898     }
5899
5900   if (range_set == 0)
5901     {
5902       errmsg ("address range not set\n");
5903       return -99;
5904     }
5905
5906   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5907
5908   mp->vrf_id = ntohl (vrf_id);
5909   mp->is_add = is_add;
5910   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5911   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5912
5913   S;
5914   W;
5915   /* NOTREACHED */
5916   return 0;
5917 }
5918
5919 static int
5920 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5921 {
5922   unformat_input_t *i = vam->input;
5923   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5924   f64 timeout;
5925   u32 sw_if_index;
5926   u8 enable = 1;
5927   u8 sw_if_index_set = 0;
5928
5929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5930     {
5931       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5932         sw_if_index_set = 1;
5933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5934         sw_if_index_set = 1;
5935       else if (unformat (i, "enable"))
5936         enable = 1;
5937       else if (unformat (i, "disable"))
5938         enable = 0;
5939       else
5940         {
5941           clib_warning ("parse error '%U'", format_unformat_error, i);
5942           return -99;
5943         }
5944     }
5945
5946   if (sw_if_index_set == 0)
5947     {
5948       errmsg ("missing interface name or sw_if_index\n");
5949       return -99;
5950     }
5951
5952   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5953
5954   mp->sw_if_index = ntohl (sw_if_index);
5955   mp->enable_disable = enable;
5956
5957   S;
5958   W;
5959   /* NOTREACHED */
5960   return 0;
5961 }
5962
5963 static int
5964 api_mpls_add_del_decap (vat_main_t * vam)
5965 {
5966   unformat_input_t *i = vam->input;
5967   vl_api_mpls_add_del_decap_t *mp;
5968   f64 timeout;
5969   u32 rx_vrf_id = 0;
5970   u32 tx_vrf_id = 0;
5971   u32 label = 0;
5972   u8 is_add = 1;
5973   u8 s_bit = 1;
5974   u32 next_index = 1;
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5979         ;
5980       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5981         ;
5982       else if (unformat (i, "label %d", &label))
5983         ;
5984       else if (unformat (i, "next-index %d", &next_index))
5985         ;
5986       else if (unformat (i, "del"))
5987         is_add = 0;
5988       else if (unformat (i, "s-bit-clear"))
5989         s_bit = 0;
5990       else
5991         {
5992           clib_warning ("parse error '%U'", format_unformat_error, i);
5993           return -99;
5994         }
5995     }
5996
5997   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5998
5999   mp->rx_vrf_id = ntohl (rx_vrf_id);
6000   mp->tx_vrf_id = ntohl (tx_vrf_id);
6001   mp->label = ntohl (label);
6002   mp->next_index = ntohl (next_index);
6003   mp->s_bit = s_bit;
6004   mp->is_add = is_add;
6005
6006   S;
6007   W;
6008   /* NOTREACHED */
6009   return 0;
6010 }
6011
6012 static int
6013 api_mpls_add_del_encap (vat_main_t * vam)
6014 {
6015   unformat_input_t *i = vam->input;
6016   vl_api_mpls_add_del_encap_t *mp;
6017   f64 timeout;
6018   u32 vrf_id = 0;
6019   u32 *labels = 0;
6020   u32 label;
6021   ip4_address_t dst_address;
6022   u8 is_add = 1;
6023
6024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (i, "vrf %d", &vrf_id))
6027         ;
6028       else if (unformat (i, "label %d", &label))
6029         vec_add1 (labels, ntohl (label));
6030       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6031         ;
6032       else if (unformat (i, "del"))
6033         is_add = 0;
6034       else
6035         {
6036           clib_warning ("parse error '%U'", format_unformat_error, i);
6037           return -99;
6038         }
6039     }
6040
6041   if (vec_len (labels) == 0)
6042     {
6043       errmsg ("missing encap label stack\n");
6044       return -99;
6045     }
6046
6047   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6048       sizeof (u32) * vec_len (labels));
6049
6050   mp->vrf_id = ntohl (vrf_id);
6051   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6052   mp->is_add = is_add;
6053   mp->nlabels = vec_len (labels);
6054   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6055
6056   vec_free (labels);
6057
6058   S;
6059   W;
6060   /* NOTREACHED */
6061   return 0;
6062 }
6063
6064 static int
6065 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
6066 {
6067   unformat_input_t *i = vam->input;
6068   vl_api_mpls_gre_add_del_tunnel_t *mp;
6069   f64 timeout;
6070   u32 inner_vrf_id = 0;
6071   u32 outer_vrf_id = 0;
6072   ip4_address_t src_address;
6073   ip4_address_t dst_address;
6074   ip4_address_t intfc_address;
6075   u32 tmp;
6076   u8 intfc_address_length = 0;
6077   u8 is_add = 1;
6078   u8 l2_only = 0;
6079
6080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6081     {
6082       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6083         ;
6084       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6085         ;
6086       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
6087         ;
6088       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6089         ;
6090       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6091                          &intfc_address, &tmp))
6092         intfc_address_length = tmp;
6093       else if (unformat (i, "l2-only"))
6094         l2_only = 1;
6095       else if (unformat (i, "del"))
6096         is_add = 0;
6097       else
6098         {
6099           clib_warning ("parse error '%U'", format_unformat_error, i);
6100           return -99;
6101         }
6102     }
6103
6104   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
6105
6106   mp->inner_vrf_id = ntohl (inner_vrf_id);
6107   mp->outer_vrf_id = ntohl (outer_vrf_id);
6108   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
6109   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6110   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
6111   mp->intfc_address_length = intfc_address_length;
6112   mp->l2_only = l2_only;
6113   mp->is_add = is_add;
6114
6115   S;
6116   W;
6117   /* NOTREACHED */
6118   return 0;
6119 }
6120
6121 static int
6122 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6123 {
6124   unformat_input_t *i = vam->input;
6125   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6126   f64 timeout;
6127   u32 inner_vrf_id = 0;
6128   ip4_address_t intfc_address;
6129   u8 dst_mac_address[6];
6130   int dst_set = 1;
6131   u32 tmp;
6132   u8 intfc_address_length = 0;
6133   u8 is_add = 1;
6134   u8 l2_only = 0;
6135   u32 tx_sw_if_index;
6136   int tx_sw_if_index_set = 0;
6137
6138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6139     {
6140       if (unformat (i, "vrf %d", &inner_vrf_id))
6141         ;
6142       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6143                          &intfc_address, &tmp))
6144         intfc_address_length = tmp;
6145       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6146         tx_sw_if_index_set = 1;
6147       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6148         tx_sw_if_index_set = 1;
6149       else if (unformat (i, "dst %U", unformat_ethernet_address,
6150                          dst_mac_address))
6151         dst_set = 1;
6152       else if (unformat (i, "l2-only"))
6153         l2_only = 1;
6154       else if (unformat (i, "del"))
6155         is_add = 0;
6156       else
6157         {
6158           clib_warning ("parse error '%U'", format_unformat_error, i);
6159           return -99;
6160         }
6161     }
6162
6163   if (!dst_set)
6164     {
6165       errmsg ("dst (mac address) not set\n");
6166       return -99;
6167     }
6168   if (!tx_sw_if_index_set)
6169     {
6170       errmsg ("tx-intfc not set\n");
6171       return -99;
6172     }
6173
6174   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6175
6176   mp->vrf_id = ntohl (inner_vrf_id);
6177   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6178   mp->adj_address_length = intfc_address_length;
6179   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6180                sizeof (dst_mac_address));
6181   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6182   mp->l2_only = l2_only;
6183   mp->is_add = is_add;
6184
6185   S;
6186   W;
6187   /* NOTREACHED */
6188   return 0;
6189 }
6190
6191 static int
6192 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6193 {
6194   unformat_input_t *i = vam->input;
6195   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6196   f64 timeout;
6197   u32 inner_vrf_id = 0;
6198   u32 outer_vrf_id = 0;
6199   ip4_address_t adj_address;
6200   int adj_address_set = 0;
6201   ip4_address_t next_hop_address;
6202   int next_hop_address_set = 0;
6203   u32 tmp;
6204   u8 adj_address_length = 0;
6205   u8 l2_only = 0;
6206   u8 is_add = 1;
6207   u32 resolve_attempts = 5;
6208   u8 resolve_if_needed = 1;
6209
6210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211     {
6212       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6213         ;
6214       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6215         ;
6216       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6217                          &adj_address, &tmp))
6218         {
6219           adj_address_length = tmp;
6220           adj_address_set = 1;
6221         }
6222       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6223                          &next_hop_address))
6224         next_hop_address_set = 1;
6225       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6226         ;
6227       else if (unformat (i, "resolve-if-needed %d", &tmp))
6228         resolve_if_needed = tmp;
6229       else if (unformat (i, "l2-only"))
6230         l2_only = 1;
6231       else if (unformat (i, "del"))
6232         is_add = 0;
6233       else
6234         {
6235           clib_warning ("parse error '%U'", format_unformat_error, i);
6236           return -99;
6237         }
6238     }
6239
6240   if (!adj_address_set)
6241     {
6242       errmsg ("adjacency address/mask not set\n");
6243       return -99;
6244     }
6245   if (!next_hop_address_set)
6246     {
6247       errmsg ("ip4 next hop address (in outer fib) not set\n");
6248       return -99;
6249     }
6250
6251   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6252
6253   mp->inner_vrf_id = ntohl (inner_vrf_id);
6254   mp->outer_vrf_id = ntohl (outer_vrf_id);
6255   mp->resolve_attempts = ntohl (resolve_attempts);
6256   mp->resolve_if_needed = resolve_if_needed;
6257   mp->is_add = is_add;
6258   mp->l2_only = l2_only;
6259   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6260   mp->adj_address_length = adj_address_length;
6261   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6262                sizeof (next_hop_address));
6263
6264   S;
6265   W;
6266   /* NOTREACHED */
6267   return 0;
6268 }
6269
6270 static int
6271 api_sw_interface_set_unnumbered (vat_main_t * vam)
6272 {
6273   unformat_input_t *i = vam->input;
6274   vl_api_sw_interface_set_unnumbered_t *mp;
6275   f64 timeout;
6276   u32 sw_if_index;
6277   u32 unnum_sw_index = ~0;
6278   u8 is_add = 1;
6279   u8 sw_if_index_set = 0;
6280
6281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6282     {
6283       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6284         sw_if_index_set = 1;
6285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6286         sw_if_index_set = 1;
6287       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6288         ;
6289       else if (unformat (i, "del"))
6290         is_add = 0;
6291       else
6292         {
6293           clib_warning ("parse error '%U'", format_unformat_error, i);
6294           return -99;
6295         }
6296     }
6297
6298   if (sw_if_index_set == 0)
6299     {
6300       errmsg ("missing interface name or sw_if_index\n");
6301       return -99;
6302     }
6303
6304   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6305
6306   mp->sw_if_index = ntohl (sw_if_index);
6307   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6308   mp->is_add = is_add;
6309
6310   S;
6311   W;
6312   /* NOTREACHED */
6313   return 0;
6314 }
6315
6316 static int
6317 api_ip_neighbor_add_del (vat_main_t * vam)
6318 {
6319   unformat_input_t *i = vam->input;
6320   vl_api_ip_neighbor_add_del_t *mp;
6321   f64 timeout;
6322   u32 sw_if_index;
6323   u8 sw_if_index_set = 0;
6324   u32 vrf_id = 0;
6325   u8 is_add = 1;
6326   u8 is_static = 0;
6327   u8 mac_address[6];
6328   u8 mac_set = 0;
6329   u8 v4_address_set = 0;
6330   u8 v6_address_set = 0;
6331   ip4_address_t v4address;
6332   ip6_address_t v6address;
6333
6334   memset (mac_address, 0, sizeof (mac_address));
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6340         {
6341           mac_set = 1;
6342         }
6343       else if (unformat (i, "del"))
6344         is_add = 0;
6345       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6348         sw_if_index_set = 1;
6349       else if (unformat (i, "is_static"))
6350         is_static = 1;
6351       else if (unformat (i, "vrf %d", &vrf_id))
6352         ;
6353       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6354         v4_address_set = 1;
6355       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6356         v6_address_set = 1;
6357       else
6358         {
6359           clib_warning ("parse error '%U'", format_unformat_error, i);
6360           return -99;
6361         }
6362     }
6363
6364   if (sw_if_index_set == 0)
6365     {
6366       errmsg ("missing interface name or sw_if_index\n");
6367       return -99;
6368     }
6369   if (v4_address_set && v6_address_set)
6370     {
6371       errmsg ("both v4 and v6 addresses set\n");
6372       return -99;
6373     }
6374   if (!v4_address_set && !v6_address_set)
6375     {
6376       errmsg ("no address set\n");
6377       return -99;
6378     }
6379
6380   /* Construct the API message */
6381   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6382
6383   mp->sw_if_index = ntohl (sw_if_index);
6384   mp->is_add = is_add;
6385   mp->vrf_id = ntohl (vrf_id);
6386   mp->is_static = is_static;
6387   if (mac_set)
6388     clib_memcpy (mp->mac_address, mac_address, 6);
6389   if (v6_address_set)
6390     {
6391       mp->is_ipv6 = 1;
6392       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6393     }
6394   else
6395     {
6396       /* mp->is_ipv6 = 0; via memset in M macro above */
6397       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6398     }
6399
6400   /* send it... */
6401   S;
6402
6403   /* Wait for a reply, return good/bad news  */
6404   W;
6405
6406   /* NOTREACHED */
6407   return 0;
6408 }
6409
6410 static int
6411 api_reset_vrf (vat_main_t * vam)
6412 {
6413   unformat_input_t *i = vam->input;
6414   vl_api_reset_vrf_t *mp;
6415   f64 timeout;
6416   u32 vrf_id = 0;
6417   u8 is_ipv6 = 0;
6418   u8 vrf_id_set = 0;
6419
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "vrf %d", &vrf_id))
6423         vrf_id_set = 1;
6424       else if (unformat (i, "ipv6"))
6425         is_ipv6 = 1;
6426       else
6427         {
6428           clib_warning ("parse error '%U'", format_unformat_error, i);
6429           return -99;
6430         }
6431     }
6432
6433   if (vrf_id_set == 0)
6434     {
6435       errmsg ("missing vrf id\n");
6436       return -99;
6437     }
6438
6439   M (RESET_VRF, reset_vrf);
6440
6441   mp->vrf_id = ntohl (vrf_id);
6442   mp->is_ipv6 = is_ipv6;
6443
6444   S;
6445   W;
6446   /* NOTREACHED */
6447   return 0;
6448 }
6449
6450 static int
6451 api_create_vlan_subif (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_create_vlan_subif_t *mp;
6455   f64 timeout;
6456   u32 sw_if_index;
6457   u8 sw_if_index_set = 0;
6458   u32 vlan_id;
6459   u8 vlan_id_set = 0;
6460
6461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6462     {
6463       if (unformat (i, "sw_if_index %d", &sw_if_index))
6464         sw_if_index_set = 1;
6465       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6466         sw_if_index_set = 1;
6467       else if (unformat (i, "vlan %d", &vlan_id))
6468         vlan_id_set = 1;
6469       else
6470         {
6471           clib_warning ("parse error '%U'", format_unformat_error, i);
6472           return -99;
6473         }
6474     }
6475
6476   if (sw_if_index_set == 0)
6477     {
6478       errmsg ("missing interface name or sw_if_index\n");
6479       return -99;
6480     }
6481
6482   if (vlan_id_set == 0)
6483     {
6484       errmsg ("missing vlan_id\n");
6485       return -99;
6486     }
6487   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6488
6489   mp->sw_if_index = ntohl (sw_if_index);
6490   mp->vlan_id = ntohl (vlan_id);
6491
6492   S;
6493   W;
6494   /* NOTREACHED */
6495   return 0;
6496 }
6497
6498 #define foreach_create_subif_bit                \
6499 _(no_tags)                                      \
6500 _(one_tag)                                      \
6501 _(two_tags)                                     \
6502 _(dot1ad)                                       \
6503 _(exact_match)                                  \
6504 _(default_sub)                                  \
6505 _(outer_vlan_id_any)                            \
6506 _(inner_vlan_id_any)
6507
6508 static int
6509 api_create_subif (vat_main_t * vam)
6510 {
6511   unformat_input_t *i = vam->input;
6512   vl_api_create_subif_t *mp;
6513   f64 timeout;
6514   u32 sw_if_index;
6515   u8 sw_if_index_set = 0;
6516   u32 sub_id;
6517   u8 sub_id_set = 0;
6518   u32 no_tags = 0;
6519   u32 one_tag = 0;
6520   u32 two_tags = 0;
6521   u32 dot1ad = 0;
6522   u32 exact_match = 0;
6523   u32 default_sub = 0;
6524   u32 outer_vlan_id_any = 0;
6525   u32 inner_vlan_id_any = 0;
6526   u32 tmp;
6527   u16 outer_vlan_id = 0;
6528   u16 inner_vlan_id = 0;
6529
6530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6531     {
6532       if (unformat (i, "sw_if_index %d", &sw_if_index))
6533         sw_if_index_set = 1;
6534       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6535         sw_if_index_set = 1;
6536       else if (unformat (i, "sub_id %d", &sub_id))
6537         sub_id_set = 1;
6538       else if (unformat (i, "outer_vlan_id %d", &tmp))
6539         outer_vlan_id = tmp;
6540       else if (unformat (i, "inner_vlan_id %d", &tmp))
6541         inner_vlan_id = tmp;
6542
6543 #define _(a) else if (unformat (i, #a)) a = 1 ;
6544       foreach_create_subif_bit
6545 #undef _
6546         else
6547         {
6548           clib_warning ("parse error '%U'", format_unformat_error, i);
6549           return -99;
6550         }
6551     }
6552
6553   if (sw_if_index_set == 0)
6554     {
6555       errmsg ("missing interface name or sw_if_index\n");
6556       return -99;
6557     }
6558
6559   if (sub_id_set == 0)
6560     {
6561       errmsg ("missing sub_id\n");
6562       return -99;
6563     }
6564   M (CREATE_SUBIF, create_subif);
6565
6566   mp->sw_if_index = ntohl (sw_if_index);
6567   mp->sub_id = ntohl (sub_id);
6568
6569 #define _(a) mp->a = a;
6570   foreach_create_subif_bit;
6571 #undef _
6572
6573   mp->outer_vlan_id = ntohs (outer_vlan_id);
6574   mp->inner_vlan_id = ntohs (inner_vlan_id);
6575
6576   S;
6577   W;
6578   /* NOTREACHED */
6579   return 0;
6580 }
6581
6582 static int
6583 api_oam_add_del (vat_main_t * vam)
6584 {
6585   unformat_input_t *i = vam->input;
6586   vl_api_oam_add_del_t *mp;
6587   f64 timeout;
6588   u32 vrf_id = 0;
6589   u8 is_add = 1;
6590   ip4_address_t src, dst;
6591   u8 src_set = 0;
6592   u8 dst_set = 0;
6593
6594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595     {
6596       if (unformat (i, "vrf %d", &vrf_id))
6597         ;
6598       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6599         src_set = 1;
6600       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6601         dst_set = 1;
6602       else if (unformat (i, "del"))
6603         is_add = 0;
6604       else
6605         {
6606           clib_warning ("parse error '%U'", format_unformat_error, i);
6607           return -99;
6608         }
6609     }
6610
6611   if (src_set == 0)
6612     {
6613       errmsg ("missing src addr\n");
6614       return -99;
6615     }
6616
6617   if (dst_set == 0)
6618     {
6619       errmsg ("missing dst addr\n");
6620       return -99;
6621     }
6622
6623   M (OAM_ADD_DEL, oam_add_del);
6624
6625   mp->vrf_id = ntohl (vrf_id);
6626   mp->is_add = is_add;
6627   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6628   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6629
6630   S;
6631   W;
6632   /* NOTREACHED */
6633   return 0;
6634 }
6635
6636 static int
6637 api_reset_fib (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_reset_fib_t *mp;
6641   f64 timeout;
6642   u32 vrf_id = 0;
6643   u8 is_ipv6 = 0;
6644   u8 vrf_id_set = 0;
6645
6646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6647     {
6648       if (unformat (i, "vrf %d", &vrf_id))
6649         vrf_id_set = 1;
6650       else if (unformat (i, "ipv6"))
6651         is_ipv6 = 1;
6652       else
6653         {
6654           clib_warning ("parse error '%U'", format_unformat_error, i);
6655           return -99;
6656         }
6657     }
6658
6659   if (vrf_id_set == 0)
6660     {
6661       errmsg ("missing vrf id\n");
6662       return -99;
6663     }
6664
6665   M (RESET_FIB, reset_fib);
6666
6667   mp->vrf_id = ntohl (vrf_id);
6668   mp->is_ipv6 = is_ipv6;
6669
6670   S;
6671   W;
6672   /* NOTREACHED */
6673   return 0;
6674 }
6675
6676 static int
6677 api_dhcp_proxy_config (vat_main_t * vam)
6678 {
6679   unformat_input_t *i = vam->input;
6680   vl_api_dhcp_proxy_config_t *mp;
6681   f64 timeout;
6682   u32 vrf_id = 0;
6683   u8 is_add = 1;
6684   u8 insert_cid = 1;
6685   u8 v4_address_set = 0;
6686   u8 v6_address_set = 0;
6687   ip4_address_t v4address;
6688   ip6_address_t v6address;
6689   u8 v4_src_address_set = 0;
6690   u8 v6_src_address_set = 0;
6691   ip4_address_t v4srcaddress;
6692   ip6_address_t v6srcaddress;
6693
6694   /* Parse args required to build the message */
6695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6696     {
6697       if (unformat (i, "del"))
6698         is_add = 0;
6699       else if (unformat (i, "vrf %d", &vrf_id))
6700         ;
6701       else if (unformat (i, "insert-cid %d", &insert_cid))
6702         ;
6703       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6704         v4_address_set = 1;
6705       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6706         v6_address_set = 1;
6707       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6708         v4_src_address_set = 1;
6709       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6710         v6_src_address_set = 1;
6711       else
6712         break;
6713     }
6714
6715   if (v4_address_set && v6_address_set)
6716     {
6717       errmsg ("both v4 and v6 server addresses set\n");
6718       return -99;
6719     }
6720   if (!v4_address_set && !v6_address_set)
6721     {
6722       errmsg ("no server addresses set\n");
6723       return -99;
6724     }
6725
6726   if (v4_src_address_set && v6_src_address_set)
6727     {
6728       errmsg ("both v4 and v6  src addresses set\n");
6729       return -99;
6730     }
6731   if (!v4_src_address_set && !v6_src_address_set)
6732     {
6733       errmsg ("no src addresses set\n");
6734       return -99;
6735     }
6736
6737   if (!(v4_src_address_set && v4_address_set) &&
6738       !(v6_src_address_set && v6_address_set))
6739     {
6740       errmsg ("no matching server and src addresses set\n");
6741       return -99;
6742     }
6743
6744   /* Construct the API message */
6745   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6746
6747   mp->insert_circuit_id = insert_cid;
6748   mp->is_add = is_add;
6749   mp->vrf_id = ntohl (vrf_id);
6750   if (v6_address_set)
6751     {
6752       mp->is_ipv6 = 1;
6753       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6754       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6755     }
6756   else
6757     {
6758       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6759       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6760     }
6761
6762   /* send it... */
6763   S;
6764
6765   /* Wait for a reply, return good/bad news  */
6766   W;
6767   /* NOTREACHED */
6768   return 0;
6769 }
6770
6771 static int
6772 api_dhcp_proxy_config_2 (vat_main_t * vam)
6773 {
6774   unformat_input_t *i = vam->input;
6775   vl_api_dhcp_proxy_config_2_t *mp;
6776   f64 timeout;
6777   u32 rx_vrf_id = 0;
6778   u32 server_vrf_id = 0;
6779   u8 is_add = 1;
6780   u8 insert_cid = 1;
6781   u8 v4_address_set = 0;
6782   u8 v6_address_set = 0;
6783   ip4_address_t v4address;
6784   ip6_address_t v6address;
6785   u8 v4_src_address_set = 0;
6786   u8 v6_src_address_set = 0;
6787   ip4_address_t v4srcaddress;
6788   ip6_address_t v6srcaddress;
6789
6790   /* Parse args required to build the message */
6791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6792     {
6793       if (unformat (i, "del"))
6794         is_add = 0;
6795       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6796         ;
6797       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6798         ;
6799       else if (unformat (i, "insert-cid %d", &insert_cid))
6800         ;
6801       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6802         v4_address_set = 1;
6803       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6804         v6_address_set = 1;
6805       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6806         v4_src_address_set = 1;
6807       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6808         v6_src_address_set = 1;
6809       else
6810         break;
6811     }
6812
6813   if (v4_address_set && v6_address_set)
6814     {
6815       errmsg ("both v4 and v6 server addresses set\n");
6816       return -99;
6817     }
6818   if (!v4_address_set && !v6_address_set)
6819     {
6820       errmsg ("no server addresses set\n");
6821       return -99;
6822     }
6823
6824   if (v4_src_address_set && v6_src_address_set)
6825     {
6826       errmsg ("both v4 and v6  src addresses set\n");
6827       return -99;
6828     }
6829   if (!v4_src_address_set && !v6_src_address_set)
6830     {
6831       errmsg ("no src addresses set\n");
6832       return -99;
6833     }
6834
6835   if (!(v4_src_address_set && v4_address_set) &&
6836       !(v6_src_address_set && v6_address_set))
6837     {
6838       errmsg ("no matching server and src addresses set\n");
6839       return -99;
6840     }
6841
6842   /* Construct the API message */
6843   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6844
6845   mp->insert_circuit_id = insert_cid;
6846   mp->is_add = is_add;
6847   mp->rx_vrf_id = ntohl (rx_vrf_id);
6848   mp->server_vrf_id = ntohl (server_vrf_id);
6849   if (v6_address_set)
6850     {
6851       mp->is_ipv6 = 1;
6852       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6853       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6854     }
6855   else
6856     {
6857       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6858       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6859     }
6860
6861   /* send it... */
6862   S;
6863
6864   /* Wait for a reply, return good/bad news  */
6865   W;
6866   /* NOTREACHED */
6867   return 0;
6868 }
6869
6870 static int
6871 api_dhcp_proxy_set_vss (vat_main_t * vam)
6872 {
6873   unformat_input_t *i = vam->input;
6874   vl_api_dhcp_proxy_set_vss_t *mp;
6875   f64 timeout;
6876   u8 is_ipv6 = 0;
6877   u8 is_add = 1;
6878   u32 tbl_id;
6879   u8 tbl_id_set = 0;
6880   u32 oui;
6881   u8 oui_set = 0;
6882   u32 fib_id;
6883   u8 fib_id_set = 0;
6884
6885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886     {
6887       if (unformat (i, "tbl_id %d", &tbl_id))
6888         tbl_id_set = 1;
6889       if (unformat (i, "fib_id %d", &fib_id))
6890         fib_id_set = 1;
6891       if (unformat (i, "oui %d", &oui))
6892         oui_set = 1;
6893       else if (unformat (i, "ipv6"))
6894         is_ipv6 = 1;
6895       else if (unformat (i, "del"))
6896         is_add = 0;
6897       else
6898         {
6899           clib_warning ("parse error '%U'", format_unformat_error, i);
6900           return -99;
6901         }
6902     }
6903
6904   if (tbl_id_set == 0)
6905     {
6906       errmsg ("missing tbl id\n");
6907       return -99;
6908     }
6909
6910   if (fib_id_set == 0)
6911     {
6912       errmsg ("missing fib id\n");
6913       return -99;
6914     }
6915   if (oui_set == 0)
6916     {
6917       errmsg ("missing oui\n");
6918       return -99;
6919     }
6920
6921   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6922   mp->tbl_id = ntohl (tbl_id);
6923   mp->fib_id = ntohl (fib_id);
6924   mp->oui = ntohl (oui);
6925   mp->is_ipv6 = is_ipv6;
6926   mp->is_add = is_add;
6927
6928   S;
6929   W;
6930   /* NOTREACHED */
6931   return 0;
6932 }
6933
6934 static int
6935 api_dhcp_client_config (vat_main_t * vam)
6936 {
6937   unformat_input_t *i = vam->input;
6938   vl_api_dhcp_client_config_t *mp;
6939   f64 timeout;
6940   u32 sw_if_index;
6941   u8 sw_if_index_set = 0;
6942   u8 is_add = 1;
6943   u8 *hostname = 0;
6944   u8 disable_event = 0;
6945
6946   /* Parse args required to build the message */
6947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6948     {
6949       if (unformat (i, "del"))
6950         is_add = 0;
6951       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6952         sw_if_index_set = 1;
6953       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6954         sw_if_index_set = 1;
6955       else if (unformat (i, "hostname %s", &hostname))
6956         ;
6957       else if (unformat (i, "disable_event"))
6958         disable_event = 1;
6959       else
6960         break;
6961     }
6962
6963   if (sw_if_index_set == 0)
6964     {
6965       errmsg ("missing interface name or sw_if_index\n");
6966       return -99;
6967     }
6968
6969   if (vec_len (hostname) > 63)
6970     {
6971       errmsg ("hostname too long\n");
6972     }
6973   vec_add1 (hostname, 0);
6974
6975   /* Construct the API message */
6976   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6977
6978   mp->sw_if_index = ntohl (sw_if_index);
6979   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6980   vec_free (hostname);
6981   mp->is_add = is_add;
6982   mp->want_dhcp_event = disable_event ? 0 : 1;
6983   mp->pid = getpid ();
6984
6985   /* send it... */
6986   S;
6987
6988   /* Wait for a reply, return good/bad news  */
6989   W;
6990   /* NOTREACHED */
6991   return 0;
6992 }
6993
6994 static int
6995 api_set_ip_flow_hash (vat_main_t * vam)
6996 {
6997   unformat_input_t *i = vam->input;
6998   vl_api_set_ip_flow_hash_t *mp;
6999   f64 timeout;
7000   u32 vrf_id = 0;
7001   u8 is_ipv6 = 0;
7002   u8 vrf_id_set = 0;
7003   u8 src = 0;
7004   u8 dst = 0;
7005   u8 sport = 0;
7006   u8 dport = 0;
7007   u8 proto = 0;
7008   u8 reverse = 0;
7009
7010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7011     {
7012       if (unformat (i, "vrf %d", &vrf_id))
7013         vrf_id_set = 1;
7014       else if (unformat (i, "ipv6"))
7015         is_ipv6 = 1;
7016       else if (unformat (i, "src"))
7017         src = 1;
7018       else if (unformat (i, "dst"))
7019         dst = 1;
7020       else if (unformat (i, "sport"))
7021         sport = 1;
7022       else if (unformat (i, "dport"))
7023         dport = 1;
7024       else if (unformat (i, "proto"))
7025         proto = 1;
7026       else if (unformat (i, "reverse"))
7027         reverse = 1;
7028
7029       else
7030         {
7031           clib_warning ("parse error '%U'", format_unformat_error, i);
7032           return -99;
7033         }
7034     }
7035
7036   if (vrf_id_set == 0)
7037     {
7038       errmsg ("missing vrf id\n");
7039       return -99;
7040     }
7041
7042   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7043   mp->src = src;
7044   mp->dst = dst;
7045   mp->sport = sport;
7046   mp->dport = dport;
7047   mp->proto = proto;
7048   mp->reverse = reverse;
7049   mp->vrf_id = ntohl (vrf_id);
7050   mp->is_ipv6 = is_ipv6;
7051
7052   S;
7053   W;
7054   /* NOTREACHED */
7055   return 0;
7056 }
7057
7058 static int
7059 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7060 {
7061   unformat_input_t *i = vam->input;
7062   vl_api_sw_interface_ip6_enable_disable_t *mp;
7063   f64 timeout;
7064   u32 sw_if_index;
7065   u8 sw_if_index_set = 0;
7066   u8 enable = 0;
7067
7068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7069     {
7070       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7071         sw_if_index_set = 1;
7072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7073         sw_if_index_set = 1;
7074       else if (unformat (i, "enable"))
7075         enable = 1;
7076       else if (unformat (i, "disable"))
7077         enable = 0;
7078       else
7079         {
7080           clib_warning ("parse error '%U'", format_unformat_error, i);
7081           return -99;
7082         }
7083     }
7084
7085   if (sw_if_index_set == 0)
7086     {
7087       errmsg ("missing interface name or sw_if_index\n");
7088       return -99;
7089     }
7090
7091   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7092
7093   mp->sw_if_index = ntohl (sw_if_index);
7094   mp->enable = enable;
7095
7096   S;
7097   W;
7098   /* NOTREACHED */
7099   return 0;
7100 }
7101
7102 static int
7103 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7104 {
7105   unformat_input_t *i = vam->input;
7106   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7107   f64 timeout;
7108   u32 sw_if_index;
7109   u8 sw_if_index_set = 0;
7110   u32 address_length = 0;
7111   u8 v6_address_set = 0;
7112   ip6_address_t v6address;
7113
7114   /* Parse args required to build the message */
7115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7116     {
7117       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7118         sw_if_index_set = 1;
7119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7120         sw_if_index_set = 1;
7121       else if (unformat (i, "%U/%d",
7122                          unformat_ip6_address, &v6address, &address_length))
7123         v6_address_set = 1;
7124       else
7125         break;
7126     }
7127
7128   if (sw_if_index_set == 0)
7129     {
7130       errmsg ("missing interface name or sw_if_index\n");
7131       return -99;
7132     }
7133   if (!v6_address_set)
7134     {
7135       errmsg ("no address set\n");
7136       return -99;
7137     }
7138
7139   /* Construct the API message */
7140   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7141      sw_interface_ip6_set_link_local_address);
7142
7143   mp->sw_if_index = ntohl (sw_if_index);
7144   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7145   mp->address_length = address_length;
7146
7147   /* send it... */
7148   S;
7149
7150   /* Wait for a reply, return good/bad news  */
7151   W;
7152
7153   /* NOTREACHED */
7154   return 0;
7155 }
7156
7157
7158 static int
7159 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7160 {
7161   unformat_input_t *i = vam->input;
7162   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7163   f64 timeout;
7164   u32 sw_if_index;
7165   u8 sw_if_index_set = 0;
7166   u32 address_length = 0;
7167   u8 v6_address_set = 0;
7168   ip6_address_t v6address;
7169   u8 use_default = 0;
7170   u8 no_advertise = 0;
7171   u8 off_link = 0;
7172   u8 no_autoconfig = 0;
7173   u8 no_onlink = 0;
7174   u8 is_no = 0;
7175   u32 val_lifetime = 0;
7176   u32 pref_lifetime = 0;
7177
7178   /* Parse args required to build the message */
7179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7180     {
7181       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7182         sw_if_index_set = 1;
7183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7184         sw_if_index_set = 1;
7185       else if (unformat (i, "%U/%d",
7186                          unformat_ip6_address, &v6address, &address_length))
7187         v6_address_set = 1;
7188       else if (unformat (i, "val_life %d", &val_lifetime))
7189         ;
7190       else if (unformat (i, "pref_life %d", &pref_lifetime))
7191         ;
7192       else if (unformat (i, "def"))
7193         use_default = 1;
7194       else if (unformat (i, "noadv"))
7195         no_advertise = 1;
7196       else if (unformat (i, "offl"))
7197         off_link = 1;
7198       else if (unformat (i, "noauto"))
7199         no_autoconfig = 1;
7200       else if (unformat (i, "nolink"))
7201         no_onlink = 1;
7202       else if (unformat (i, "isno"))
7203         is_no = 1;
7204       else
7205         {
7206           clib_warning ("parse error '%U'", format_unformat_error, i);
7207           return -99;
7208         }
7209     }
7210
7211   if (sw_if_index_set == 0)
7212     {
7213       errmsg ("missing interface name or sw_if_index\n");
7214       return -99;
7215     }
7216   if (!v6_address_set)
7217     {
7218       errmsg ("no address set\n");
7219       return -99;
7220     }
7221
7222   /* Construct the API message */
7223   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7224
7225   mp->sw_if_index = ntohl (sw_if_index);
7226   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7227   mp->address_length = address_length;
7228   mp->use_default = use_default;
7229   mp->no_advertise = no_advertise;
7230   mp->off_link = off_link;
7231   mp->no_autoconfig = no_autoconfig;
7232   mp->no_onlink = no_onlink;
7233   mp->is_no = is_no;
7234   mp->val_lifetime = ntohl (val_lifetime);
7235   mp->pref_lifetime = ntohl (pref_lifetime);
7236
7237   /* send it... */
7238   S;
7239
7240   /* Wait for a reply, return good/bad news  */
7241   W;
7242
7243   /* NOTREACHED */
7244   return 0;
7245 }
7246
7247 static int
7248 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7249 {
7250   unformat_input_t *i = vam->input;
7251   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7252   f64 timeout;
7253   u32 sw_if_index;
7254   u8 sw_if_index_set = 0;
7255   u8 suppress = 0;
7256   u8 managed = 0;
7257   u8 other = 0;
7258   u8 ll_option = 0;
7259   u8 send_unicast = 0;
7260   u8 cease = 0;
7261   u8 is_no = 0;
7262   u8 default_router = 0;
7263   u32 max_interval = 0;
7264   u32 min_interval = 0;
7265   u32 lifetime = 0;
7266   u32 initial_count = 0;
7267   u32 initial_interval = 0;
7268
7269
7270   /* Parse args required to build the message */
7271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7272     {
7273       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7274         sw_if_index_set = 1;
7275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7276         sw_if_index_set = 1;
7277       else if (unformat (i, "maxint %d", &max_interval))
7278         ;
7279       else if (unformat (i, "minint %d", &min_interval))
7280         ;
7281       else if (unformat (i, "life %d", &lifetime))
7282         ;
7283       else if (unformat (i, "count %d", &initial_count))
7284         ;
7285       else if (unformat (i, "interval %d", &initial_interval))
7286         ;
7287       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7288         suppress = 1;
7289       else if (unformat (i, "managed"))
7290         managed = 1;
7291       else if (unformat (i, "other"))
7292         other = 1;
7293       else if (unformat (i, "ll"))
7294         ll_option = 1;
7295       else if (unformat (i, "send"))
7296         send_unicast = 1;
7297       else if (unformat (i, "cease"))
7298         cease = 1;
7299       else if (unformat (i, "isno"))
7300         is_no = 1;
7301       else if (unformat (i, "def"))
7302         default_router = 1;
7303       else
7304         {
7305           clib_warning ("parse error '%U'", format_unformat_error, i);
7306           return -99;
7307         }
7308     }
7309
7310   if (sw_if_index_set == 0)
7311     {
7312       errmsg ("missing interface name or sw_if_index\n");
7313       return -99;
7314     }
7315
7316   /* Construct the API message */
7317   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7318
7319   mp->sw_if_index = ntohl (sw_if_index);
7320   mp->max_interval = ntohl (max_interval);
7321   mp->min_interval = ntohl (min_interval);
7322   mp->lifetime = ntohl (lifetime);
7323   mp->initial_count = ntohl (initial_count);
7324   mp->initial_interval = ntohl (initial_interval);
7325   mp->suppress = suppress;
7326   mp->managed = managed;
7327   mp->other = other;
7328   mp->ll_option = ll_option;
7329   mp->send_unicast = send_unicast;
7330   mp->cease = cease;
7331   mp->is_no = is_no;
7332   mp->default_router = default_router;
7333
7334   /* send it... */
7335   S;
7336
7337   /* Wait for a reply, return good/bad news  */
7338   W;
7339
7340   /* NOTREACHED */
7341   return 0;
7342 }
7343
7344 static int
7345 api_set_arp_neighbor_limit (vat_main_t * vam)
7346 {
7347   unformat_input_t *i = vam->input;
7348   vl_api_set_arp_neighbor_limit_t *mp;
7349   f64 timeout;
7350   u32 arp_nbr_limit;
7351   u8 limit_set = 0;
7352   u8 is_ipv6 = 0;
7353
7354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7357         limit_set = 1;
7358       else if (unformat (i, "ipv6"))
7359         is_ipv6 = 1;
7360       else
7361         {
7362           clib_warning ("parse error '%U'", format_unformat_error, i);
7363           return -99;
7364         }
7365     }
7366
7367   if (limit_set == 0)
7368     {
7369       errmsg ("missing limit value\n");
7370       return -99;
7371     }
7372
7373   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7374
7375   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7376   mp->is_ipv6 = is_ipv6;
7377
7378   S;
7379   W;
7380   /* NOTREACHED */
7381   return 0;
7382 }
7383
7384 static int
7385 api_l2_patch_add_del (vat_main_t * vam)
7386 {
7387   unformat_input_t *i = vam->input;
7388   vl_api_l2_patch_add_del_t *mp;
7389   f64 timeout;
7390   u32 rx_sw_if_index;
7391   u8 rx_sw_if_index_set = 0;
7392   u32 tx_sw_if_index;
7393   u8 tx_sw_if_index_set = 0;
7394   u8 is_add = 1;
7395
7396   /* Parse args required to build the message */
7397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7398     {
7399       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7400         rx_sw_if_index_set = 1;
7401       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7402         tx_sw_if_index_set = 1;
7403       else if (unformat (i, "rx"))
7404         {
7405           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7406             {
7407               if (unformat (i, "%U", unformat_sw_if_index, vam,
7408                             &rx_sw_if_index))
7409                 rx_sw_if_index_set = 1;
7410             }
7411           else
7412             break;
7413         }
7414       else if (unformat (i, "tx"))
7415         {
7416           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417             {
7418               if (unformat (i, "%U", unformat_sw_if_index, vam,
7419                             &tx_sw_if_index))
7420                 tx_sw_if_index_set = 1;
7421             }
7422           else
7423             break;
7424         }
7425       else if (unformat (i, "del"))
7426         is_add = 0;
7427       else
7428         break;
7429     }
7430
7431   if (rx_sw_if_index_set == 0)
7432     {
7433       errmsg ("missing rx interface name or rx_sw_if_index\n");
7434       return -99;
7435     }
7436
7437   if (tx_sw_if_index_set == 0)
7438     {
7439       errmsg ("missing tx interface name or tx_sw_if_index\n");
7440       return -99;
7441     }
7442
7443   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7444
7445   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7446   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7447   mp->is_add = is_add;
7448
7449   S;
7450   W;
7451   /* NOTREACHED */
7452   return 0;
7453 }
7454
7455 static int
7456 api_ioam_enable (vat_main_t * vam)
7457 {
7458   unformat_input_t *input = vam->input;
7459   vl_api_ioam_enable_t *mp;
7460   f64 timeout;
7461   u32 id = 0;
7462   int has_trace_option = 0;
7463   int has_pow_option = 0;
7464   int has_ppc_option = 0;
7465
7466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (input, "trace"))
7469         has_trace_option = 1;
7470       else if (unformat (input, "pow"))
7471         has_pow_option = 1;
7472       else if (unformat (input, "ppc encap"))
7473         has_ppc_option = PPC_ENCAP;
7474       else if (unformat (input, "ppc decap"))
7475         has_ppc_option = PPC_DECAP;
7476       else if (unformat (input, "ppc none"))
7477         has_ppc_option = PPC_NONE;
7478       else
7479         break;
7480     }
7481   M (IOAM_ENABLE, ioam_enable);
7482   mp->id = htons (id);
7483   mp->trace_ppc = has_ppc_option;
7484   mp->pow_enable = has_pow_option;
7485   mp->trace_enable = has_trace_option;
7486
7487   S;
7488   W;
7489
7490   return (0);
7491
7492 }
7493
7494
7495 static int
7496 api_ioam_disable (vat_main_t * vam)
7497 {
7498   vl_api_ioam_disable_t *mp;
7499   f64 timeout;
7500
7501   M (IOAM_DISABLE, ioam_disable);
7502   S;
7503   W;
7504   return 0;
7505 }
7506
7507 static int
7508 api_sr_tunnel_add_del (vat_main_t * vam)
7509 {
7510   unformat_input_t *i = vam->input;
7511   vl_api_sr_tunnel_add_del_t *mp;
7512   f64 timeout;
7513   int is_del = 0;
7514   int pl_index;
7515   ip6_address_t src_address;
7516   int src_address_set = 0;
7517   ip6_address_t dst_address;
7518   u32 dst_mask_width;
7519   int dst_address_set = 0;
7520   u16 flags = 0;
7521   u32 rx_table_id = 0;
7522   u32 tx_table_id = 0;
7523   ip6_address_t *segments = 0;
7524   ip6_address_t *this_seg;
7525   ip6_address_t *tags = 0;
7526   ip6_address_t *this_tag;
7527   ip6_address_t next_address, tag;
7528   u8 *name = 0;
7529   u8 *policy_name = 0;
7530
7531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7532     {
7533       if (unformat (i, "del"))
7534         is_del = 1;
7535       else if (unformat (i, "name %s", &name))
7536         ;
7537       else if (unformat (i, "policy %s", &policy_name))
7538         ;
7539       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7540         ;
7541       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7542         ;
7543       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7544         src_address_set = 1;
7545       else if (unformat (i, "dst %U/%d",
7546                          unformat_ip6_address, &dst_address, &dst_mask_width))
7547         dst_address_set = 1;
7548       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7549         {
7550           vec_add2 (segments, this_seg, 1);
7551           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7552                        sizeof (*this_seg));
7553         }
7554       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7555         {
7556           vec_add2 (tags, this_tag, 1);
7557           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7558         }
7559       else if (unformat (i, "clean"))
7560         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7561       else if (unformat (i, "protected"))
7562         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7563       else if (unformat (i, "InPE %d", &pl_index))
7564         {
7565           if (pl_index <= 0 || pl_index > 4)
7566             {
7567             pl_index_range_error:
7568               errmsg ("pl index %d out of range\n", pl_index);
7569               return -99;
7570             }
7571           flags |=
7572             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7573         }
7574       else if (unformat (i, "EgPE %d", &pl_index))
7575         {
7576           if (pl_index <= 0 || pl_index > 4)
7577             goto pl_index_range_error;
7578           flags |=
7579             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7580         }
7581       else if (unformat (i, "OrgSrc %d", &pl_index))
7582         {
7583           if (pl_index <= 0 || pl_index > 4)
7584             goto pl_index_range_error;
7585           flags |=
7586             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7587         }
7588       else
7589         break;
7590     }
7591
7592   if (!src_address_set)
7593     {
7594       errmsg ("src address required\n");
7595       return -99;
7596     }
7597
7598   if (!dst_address_set)
7599     {
7600       errmsg ("dst address required\n");
7601       return -99;
7602     }
7603
7604   if (!segments)
7605     {
7606       errmsg ("at least one sr segment required\n");
7607       return -99;
7608     }
7609
7610   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7611       vec_len (segments) * sizeof (ip6_address_t)
7612       + vec_len (tags) * sizeof (ip6_address_t));
7613
7614   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7615   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7616   mp->dst_mask_width = dst_mask_width;
7617   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7618   mp->n_segments = vec_len (segments);
7619   mp->n_tags = vec_len (tags);
7620   mp->is_add = is_del == 0;
7621   clib_memcpy (mp->segs_and_tags, segments,
7622                vec_len (segments) * sizeof (ip6_address_t));
7623   clib_memcpy (mp->segs_and_tags +
7624                vec_len (segments) * sizeof (ip6_address_t), tags,
7625                vec_len (tags) * sizeof (ip6_address_t));
7626
7627   mp->outer_vrf_id = ntohl (rx_table_id);
7628   mp->inner_vrf_id = ntohl (tx_table_id);
7629   memcpy (mp->name, name, vec_len (name));
7630   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7631
7632   vec_free (segments);
7633   vec_free (tags);
7634
7635   S;
7636   W;
7637   /* NOTREACHED */
7638 }
7639
7640 static int
7641 api_sr_policy_add_del (vat_main_t * vam)
7642 {
7643   unformat_input_t *input = vam->input;
7644   vl_api_sr_policy_add_del_t *mp;
7645   f64 timeout;
7646   int is_del = 0;
7647   u8 *name = 0;
7648   u8 *tunnel_name = 0;
7649   u8 **tunnel_names = 0;
7650
7651   int name_set = 0;
7652   int tunnel_set = 0;
7653   int j = 0;
7654   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7655   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7656
7657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7658     {
7659       if (unformat (input, "del"))
7660         is_del = 1;
7661       else if (unformat (input, "name %s", &name))
7662         name_set = 1;
7663       else if (unformat (input, "tunnel %s", &tunnel_name))
7664         {
7665           if (tunnel_name)
7666             {
7667               vec_add1 (tunnel_names, tunnel_name);
7668               /* For serializer:
7669                  - length = #bytes to store in serial vector
7670                  - +1 = byte to store that length
7671                */
7672               tunnel_names_length += (vec_len (tunnel_name) + 1);
7673               tunnel_set = 1;
7674               tunnel_name = 0;
7675             }
7676         }
7677       else
7678         break;
7679     }
7680
7681   if (!name_set)
7682     {
7683       errmsg ("policy name required\n");
7684       return -99;
7685     }
7686
7687   if ((!tunnel_set) && (!is_del))
7688     {
7689       errmsg ("tunnel name required\n");
7690       return -99;
7691     }
7692
7693   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7694
7695
7696
7697   mp->is_add = !is_del;
7698
7699   memcpy (mp->name, name, vec_len (name));
7700   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7701   u8 *serial_orig = 0;
7702   vec_validate (serial_orig, tunnel_names_length);
7703   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7704   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7705
7706   for (j = 0; j < vec_len (tunnel_names); j++)
7707     {
7708       tun_name_len = vec_len (tunnel_names[j]);
7709       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7710       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7711       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7712       serial_orig += tun_name_len;      // Advance past the copy
7713     }
7714   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7715
7716   vec_free (tunnel_names);
7717   vec_free (tunnel_name);
7718
7719   S;
7720   W;
7721   /* NOTREACHED */
7722 }
7723
7724 static int
7725 api_sr_multicast_map_add_del (vat_main_t * vam)
7726 {
7727   unformat_input_t *input = vam->input;
7728   vl_api_sr_multicast_map_add_del_t *mp;
7729   f64 timeout;
7730   int is_del = 0;
7731   ip6_address_t multicast_address;
7732   u8 *policy_name = 0;
7733   int multicast_address_set = 0;
7734
7735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7736     {
7737       if (unformat (input, "del"))
7738         is_del = 1;
7739       else
7740         if (unformat
7741             (input, "address %U", unformat_ip6_address, &multicast_address))
7742         multicast_address_set = 1;
7743       else if (unformat (input, "sr-policy %s", &policy_name))
7744         ;
7745       else
7746         break;
7747     }
7748
7749   if (!is_del && !policy_name)
7750     {
7751       errmsg ("sr-policy name required\n");
7752       return -99;
7753     }
7754
7755
7756   if (!multicast_address_set)
7757     {
7758       errmsg ("address required\n");
7759       return -99;
7760     }
7761
7762   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7763
7764   mp->is_add = !is_del;
7765   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7766   clib_memcpy (mp->multicast_address, &multicast_address,
7767                sizeof (mp->multicast_address));
7768
7769
7770   vec_free (policy_name);
7771
7772   S;
7773   W;
7774   /* NOTREACHED */
7775 }
7776
7777
7778 #define foreach_ip4_proto_field                 \
7779 _(src_address)                                  \
7780 _(dst_address)                                  \
7781 _(tos)                                          \
7782 _(length)                                       \
7783 _(fragment_id)                                  \
7784 _(ttl)                                          \
7785 _(protocol)                                     \
7786 _(checksum)
7787
7788 uword
7789 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7790 {
7791   u8 **maskp = va_arg (*args, u8 **);
7792   u8 *mask = 0;
7793   u8 found_something = 0;
7794   ip4_header_t *ip;
7795
7796 #define _(a) u8 a=0;
7797   foreach_ip4_proto_field;
7798 #undef _
7799   u8 version = 0;
7800   u8 hdr_length = 0;
7801
7802
7803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7804     {
7805       if (unformat (input, "version"))
7806         version = 1;
7807       else if (unformat (input, "hdr_length"))
7808         hdr_length = 1;
7809       else if (unformat (input, "src"))
7810         src_address = 1;
7811       else if (unformat (input, "dst"))
7812         dst_address = 1;
7813       else if (unformat (input, "proto"))
7814         protocol = 1;
7815
7816 #define _(a) else if (unformat (input, #a)) a=1;
7817       foreach_ip4_proto_field
7818 #undef _
7819         else
7820         break;
7821     }
7822
7823 #define _(a) found_something += a;
7824   foreach_ip4_proto_field;
7825 #undef _
7826
7827   if (found_something == 0)
7828     return 0;
7829
7830   vec_validate (mask, sizeof (*ip) - 1);
7831
7832   ip = (ip4_header_t *) mask;
7833
7834 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7835   foreach_ip4_proto_field;
7836 #undef _
7837
7838   ip->ip_version_and_header_length = 0;
7839
7840   if (version)
7841     ip->ip_version_and_header_length |= 0xF0;
7842
7843   if (hdr_length)
7844     ip->ip_version_and_header_length |= 0x0F;
7845
7846   *maskp = mask;
7847   return 1;
7848 }
7849
7850 #define foreach_ip6_proto_field                 \
7851 _(src_address)                                  \
7852 _(dst_address)                                  \
7853 _(payload_length)                               \
7854 _(hop_limit)                                    \
7855 _(protocol)
7856
7857 uword
7858 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7859 {
7860   u8 **maskp = va_arg (*args, u8 **);
7861   u8 *mask = 0;
7862   u8 found_something = 0;
7863   ip6_header_t *ip;
7864   u32 ip_version_traffic_class_and_flow_label;
7865
7866 #define _(a) u8 a=0;
7867   foreach_ip6_proto_field;
7868 #undef _
7869   u8 version = 0;
7870   u8 traffic_class = 0;
7871   u8 flow_label = 0;
7872
7873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7874     {
7875       if (unformat (input, "version"))
7876         version = 1;
7877       else if (unformat (input, "traffic-class"))
7878         traffic_class = 1;
7879       else if (unformat (input, "flow-label"))
7880         flow_label = 1;
7881       else if (unformat (input, "src"))
7882         src_address = 1;
7883       else if (unformat (input, "dst"))
7884         dst_address = 1;
7885       else if (unformat (input, "proto"))
7886         protocol = 1;
7887
7888 #define _(a) else if (unformat (input, #a)) a=1;
7889       foreach_ip6_proto_field
7890 #undef _
7891         else
7892         break;
7893     }
7894
7895 #define _(a) found_something += a;
7896   foreach_ip6_proto_field;
7897 #undef _
7898
7899   if (found_something == 0)
7900     return 0;
7901
7902   vec_validate (mask, sizeof (*ip) - 1);
7903
7904   ip = (ip6_header_t *) mask;
7905
7906 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7907   foreach_ip6_proto_field;
7908 #undef _
7909
7910   ip_version_traffic_class_and_flow_label = 0;
7911
7912   if (version)
7913     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7914
7915   if (traffic_class)
7916     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7917
7918   if (flow_label)
7919     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7920
7921   ip->ip_version_traffic_class_and_flow_label =
7922     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7923
7924   *maskp = mask;
7925   return 1;
7926 }
7927
7928 uword
7929 unformat_l3_mask (unformat_input_t * input, va_list * args)
7930 {
7931   u8 **maskp = va_arg (*args, u8 **);
7932
7933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7934     {
7935       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7936         return 1;
7937       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7938         return 1;
7939       else
7940         break;
7941     }
7942   return 0;
7943 }
7944
7945 uword
7946 unformat_l2_mask (unformat_input_t * input, va_list * args)
7947 {
7948   u8 **maskp = va_arg (*args, u8 **);
7949   u8 *mask = 0;
7950   u8 src = 0;
7951   u8 dst = 0;
7952   u8 proto = 0;
7953   u8 tag1 = 0;
7954   u8 tag2 = 0;
7955   u8 ignore_tag1 = 0;
7956   u8 ignore_tag2 = 0;
7957   u8 cos1 = 0;
7958   u8 cos2 = 0;
7959   u8 dot1q = 0;
7960   u8 dot1ad = 0;
7961   int len = 14;
7962
7963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7964     {
7965       if (unformat (input, "src"))
7966         src = 1;
7967       else if (unformat (input, "dst"))
7968         dst = 1;
7969       else if (unformat (input, "proto"))
7970         proto = 1;
7971       else if (unformat (input, "tag1"))
7972         tag1 = 1;
7973       else if (unformat (input, "tag2"))
7974         tag2 = 1;
7975       else if (unformat (input, "ignore-tag1"))
7976         ignore_tag1 = 1;
7977       else if (unformat (input, "ignore-tag2"))
7978         ignore_tag2 = 1;
7979       else if (unformat (input, "cos1"))
7980         cos1 = 1;
7981       else if (unformat (input, "cos2"))
7982         cos2 = 1;
7983       else if (unformat (input, "dot1q"))
7984         dot1q = 1;
7985       else if (unformat (input, "dot1ad"))
7986         dot1ad = 1;
7987       else
7988         break;
7989     }
7990   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7991        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7992     return 0;
7993
7994   if (tag1 || ignore_tag1 || cos1 || dot1q)
7995     len = 18;
7996   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7997     len = 22;
7998
7999   vec_validate (mask, len - 1);
8000
8001   if (dst)
8002     memset (mask, 0xff, 6);
8003
8004   if (src)
8005     memset (mask + 6, 0xff, 6);
8006
8007   if (tag2 || dot1ad)
8008     {
8009       /* inner vlan tag */
8010       if (tag2)
8011         {
8012           mask[19] = 0xff;
8013           mask[18] = 0x0f;
8014         }
8015       if (cos2)
8016         mask[18] |= 0xe0;
8017       if (proto)
8018         mask[21] = mask[20] = 0xff;
8019       if (tag1)
8020         {
8021           mask[15] = 0xff;
8022           mask[14] = 0x0f;
8023         }
8024       if (cos1)
8025         mask[14] |= 0xe0;
8026       *maskp = mask;
8027       return 1;
8028     }
8029   if (tag1 | dot1q)
8030     {
8031       if (tag1)
8032         {
8033           mask[15] = 0xff;
8034           mask[14] = 0x0f;
8035         }
8036       if (cos1)
8037         mask[14] |= 0xe0;
8038       if (proto)
8039         mask[16] = mask[17] = 0xff;
8040
8041       *maskp = mask;
8042       return 1;
8043     }
8044   if (cos2)
8045     mask[18] |= 0xe0;
8046   if (cos1)
8047     mask[14] |= 0xe0;
8048   if (proto)
8049     mask[12] = mask[13] = 0xff;
8050
8051   *maskp = mask;
8052   return 1;
8053 }
8054
8055 uword
8056 unformat_classify_mask (unformat_input_t * input, va_list * args)
8057 {
8058   u8 **maskp = va_arg (*args, u8 **);
8059   u32 *skipp = va_arg (*args, u32 *);
8060   u32 *matchp = va_arg (*args, u32 *);
8061   u32 match;
8062   u8 *mask = 0;
8063   u8 *l2 = 0;
8064   u8 *l3 = 0;
8065   int i;
8066
8067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8070         ;
8071       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8072         ;
8073       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8074         ;
8075       else
8076         break;
8077     }
8078
8079   if (mask || l2 || l3)
8080     {
8081       if (l2 || l3)
8082         {
8083           /* "With a free Ethernet header in every package" */
8084           if (l2 == 0)
8085             vec_validate (l2, 13);
8086           mask = l2;
8087           if (vec_len (l3))
8088             {
8089               vec_append (mask, l3);
8090               vec_free (l3);
8091             }
8092         }
8093
8094       /* Scan forward looking for the first significant mask octet */
8095       for (i = 0; i < vec_len (mask); i++)
8096         if (mask[i])
8097           break;
8098
8099       /* compute (skip, match) params */
8100       *skipp = i / sizeof (u32x4);
8101       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8102
8103       /* Pad mask to an even multiple of the vector size */
8104       while (vec_len (mask) % sizeof (u32x4))
8105         vec_add1 (mask, 0);
8106
8107       match = vec_len (mask) / sizeof (u32x4);
8108
8109       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8110         {
8111           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8112           if (*tmp || *(tmp + 1))
8113             break;
8114           match--;
8115         }
8116       if (match == 0)
8117         clib_warning ("BUG: match 0");
8118
8119       _vec_len (mask) = match * sizeof (u32x4);
8120
8121       *matchp = match;
8122       *maskp = mask;
8123
8124       return 1;
8125     }
8126
8127   return 0;
8128 }
8129
8130 #define foreach_l2_next                         \
8131 _(drop, DROP)                                   \
8132 _(ethernet, ETHERNET_INPUT)                     \
8133 _(ip4, IP4_INPUT)                               \
8134 _(ip6, IP6_INPUT)
8135
8136 uword
8137 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8138 {
8139   u32 *miss_next_indexp = va_arg (*args, u32 *);
8140   u32 next_index = 0;
8141   u32 tmp;
8142
8143 #define _(n,N) \
8144   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8145   foreach_l2_next;
8146 #undef _
8147
8148   if (unformat (input, "%d", &tmp))
8149     {
8150       next_index = tmp;
8151       goto out;
8152     }
8153
8154   return 0;
8155
8156 out:
8157   *miss_next_indexp = next_index;
8158   return 1;
8159 }
8160
8161 #define foreach_ip_next                         \
8162 _(drop, DROP)                                   \
8163 _(local, LOCAL)                                 \
8164 _(rewrite, REWRITE)
8165
8166 uword
8167 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8168 {
8169   u32 *miss_next_indexp = va_arg (*args, u32 *);
8170   u32 next_index = 0;
8171   u32 tmp;
8172
8173 #define _(n,N) \
8174   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8175   foreach_ip_next;
8176 #undef _
8177
8178   if (unformat (input, "%d", &tmp))
8179     {
8180       next_index = tmp;
8181       goto out;
8182     }
8183
8184   return 0;
8185
8186 out:
8187   *miss_next_indexp = next_index;
8188   return 1;
8189 }
8190
8191 #define foreach_acl_next                        \
8192 _(deny, DENY)
8193
8194 uword
8195 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8196 {
8197   u32 *miss_next_indexp = va_arg (*args, u32 *);
8198   u32 next_index = 0;
8199   u32 tmp;
8200
8201 #define _(n,N) \
8202   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8203   foreach_acl_next;
8204 #undef _
8205
8206   if (unformat (input, "permit"))
8207     {
8208       next_index = ~0;
8209       goto out;
8210     }
8211   else if (unformat (input, "%d", &tmp))
8212     {
8213       next_index = tmp;
8214       goto out;
8215     }
8216
8217   return 0;
8218
8219 out:
8220   *miss_next_indexp = next_index;
8221   return 1;
8222 }
8223
8224 uword
8225 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8226 {
8227   u32 *r = va_arg (*args, u32 *);
8228
8229   if (unformat (input, "conform-color"))
8230     *r = POLICE_CONFORM;
8231   else if (unformat (input, "exceed-color"))
8232     *r = POLICE_EXCEED;
8233   else
8234     return 0;
8235
8236   return 1;
8237 }
8238
8239 static int
8240 api_classify_add_del_table (vat_main_t * vam)
8241 {
8242   unformat_input_t *i = vam->input;
8243   vl_api_classify_add_del_table_t *mp;
8244
8245   u32 nbuckets = 2;
8246   u32 skip = ~0;
8247   u32 match = ~0;
8248   int is_add = 1;
8249   u32 table_index = ~0;
8250   u32 next_table_index = ~0;
8251   u32 miss_next_index = ~0;
8252   u32 memory_size = 32 << 20;
8253   u8 *mask = 0;
8254   f64 timeout;
8255
8256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8257     {
8258       if (unformat (i, "del"))
8259         is_add = 0;
8260       else if (unformat (i, "buckets %d", &nbuckets))
8261         ;
8262       else if (unformat (i, "memory_size %d", &memory_size))
8263         ;
8264       else if (unformat (i, "skip %d", &skip))
8265         ;
8266       else if (unformat (i, "match %d", &match))
8267         ;
8268       else if (unformat (i, "table %d", &table_index))
8269         ;
8270       else if (unformat (i, "mask %U", unformat_classify_mask,
8271                          &mask, &skip, &match))
8272         ;
8273       else if (unformat (i, "next-table %d", &next_table_index))
8274         ;
8275       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8276                          &miss_next_index))
8277         ;
8278       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8279                          &miss_next_index))
8280         ;
8281       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8282                          &miss_next_index))
8283         ;
8284       else
8285         break;
8286     }
8287
8288   if (is_add && mask == 0)
8289     {
8290       errmsg ("Mask required\n");
8291       return -99;
8292     }
8293
8294   if (is_add && skip == ~0)
8295     {
8296       errmsg ("skip count required\n");
8297       return -99;
8298     }
8299
8300   if (is_add && match == ~0)
8301     {
8302       errmsg ("match count required\n");
8303       return -99;
8304     }
8305
8306   if (!is_add && table_index == ~0)
8307     {
8308       errmsg ("table index required for delete\n");
8309       return -99;
8310     }
8311
8312   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8313
8314   mp->is_add = is_add;
8315   mp->table_index = ntohl (table_index);
8316   mp->nbuckets = ntohl (nbuckets);
8317   mp->memory_size = ntohl (memory_size);
8318   mp->skip_n_vectors = ntohl (skip);
8319   mp->match_n_vectors = ntohl (match);
8320   mp->next_table_index = ntohl (next_table_index);
8321   mp->miss_next_index = ntohl (miss_next_index);
8322   clib_memcpy (mp->mask, mask, vec_len (mask));
8323
8324   vec_free (mask);
8325
8326   S;
8327   W;
8328   /* NOTREACHED */
8329 }
8330
8331 uword
8332 unformat_ip4_match (unformat_input_t * input, va_list * args)
8333 {
8334   u8 **matchp = va_arg (*args, u8 **);
8335   u8 *match = 0;
8336   ip4_header_t *ip;
8337   int version = 0;
8338   u32 version_val;
8339   int hdr_length = 0;
8340   u32 hdr_length_val;
8341   int src = 0, dst = 0;
8342   ip4_address_t src_val, dst_val;
8343   int proto = 0;
8344   u32 proto_val;
8345   int tos = 0;
8346   u32 tos_val;
8347   int length = 0;
8348   u32 length_val;
8349   int fragment_id = 0;
8350   u32 fragment_id_val;
8351   int ttl = 0;
8352   int ttl_val;
8353   int checksum = 0;
8354   u32 checksum_val;
8355
8356   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8357     {
8358       if (unformat (input, "version %d", &version_val))
8359         version = 1;
8360       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8361         hdr_length = 1;
8362       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8363         src = 1;
8364       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8365         dst = 1;
8366       else if (unformat (input, "proto %d", &proto_val))
8367         proto = 1;
8368       else if (unformat (input, "tos %d", &tos_val))
8369         tos = 1;
8370       else if (unformat (input, "length %d", &length_val))
8371         length = 1;
8372       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8373         fragment_id = 1;
8374       else if (unformat (input, "ttl %d", &ttl_val))
8375         ttl = 1;
8376       else if (unformat (input, "checksum %d", &checksum_val))
8377         checksum = 1;
8378       else
8379         break;
8380     }
8381
8382   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8383       + ttl + checksum == 0)
8384     return 0;
8385
8386   /*
8387    * Aligned because we use the real comparison functions
8388    */
8389   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8390
8391   ip = (ip4_header_t *) match;
8392
8393   /* These are realistically matched in practice */
8394   if (src)
8395     ip->src_address.as_u32 = src_val.as_u32;
8396
8397   if (dst)
8398     ip->dst_address.as_u32 = dst_val.as_u32;
8399
8400   if (proto)
8401     ip->protocol = proto_val;
8402
8403
8404   /* These are not, but they're included for completeness */
8405   if (version)
8406     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8407
8408   if (hdr_length)
8409     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8410
8411   if (tos)
8412     ip->tos = tos_val;
8413
8414   if (length)
8415     ip->length = length_val;
8416
8417   if (ttl)
8418     ip->ttl = ttl_val;
8419
8420   if (checksum)
8421     ip->checksum = checksum_val;
8422
8423   *matchp = match;
8424   return 1;
8425 }
8426
8427 uword
8428 unformat_ip6_match (unformat_input_t * input, va_list * args)
8429 {
8430   u8 **matchp = va_arg (*args, u8 **);
8431   u8 *match = 0;
8432   ip6_header_t *ip;
8433   int version = 0;
8434   u32 version_val;
8435   u8 traffic_class = 0;
8436   u32 traffic_class_val = 0;
8437   u8 flow_label = 0;
8438   u8 flow_label_val;
8439   int src = 0, dst = 0;
8440   ip6_address_t src_val, dst_val;
8441   int proto = 0;
8442   u32 proto_val;
8443   int payload_length = 0;
8444   u32 payload_length_val;
8445   int hop_limit = 0;
8446   int hop_limit_val;
8447   u32 ip_version_traffic_class_and_flow_label;
8448
8449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8450     {
8451       if (unformat (input, "version %d", &version_val))
8452         version = 1;
8453       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8454         traffic_class = 1;
8455       else if (unformat (input, "flow_label %d", &flow_label_val))
8456         flow_label = 1;
8457       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8458         src = 1;
8459       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8460         dst = 1;
8461       else if (unformat (input, "proto %d", &proto_val))
8462         proto = 1;
8463       else if (unformat (input, "payload_length %d", &payload_length_val))
8464         payload_length = 1;
8465       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8466         hop_limit = 1;
8467       else
8468         break;
8469     }
8470
8471   if (version + traffic_class + flow_label + src + dst + proto +
8472       payload_length + hop_limit == 0)
8473     return 0;
8474
8475   /*
8476    * Aligned because we use the real comparison functions
8477    */
8478   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8479
8480   ip = (ip6_header_t *) match;
8481
8482   if (src)
8483     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8484
8485   if (dst)
8486     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8487
8488   if (proto)
8489     ip->protocol = proto_val;
8490
8491   ip_version_traffic_class_and_flow_label = 0;
8492
8493   if (version)
8494     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8495
8496   if (traffic_class)
8497     ip_version_traffic_class_and_flow_label |=
8498       (traffic_class_val & 0xFF) << 20;
8499
8500   if (flow_label)
8501     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8502
8503   ip->ip_version_traffic_class_and_flow_label =
8504     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8505
8506   if (payload_length)
8507     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8508
8509   if (hop_limit)
8510     ip->hop_limit = hop_limit_val;
8511
8512   *matchp = match;
8513   return 1;
8514 }
8515
8516 uword
8517 unformat_l3_match (unformat_input_t * input, va_list * args)
8518 {
8519   u8 **matchp = va_arg (*args, u8 **);
8520
8521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8522     {
8523       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8524         return 1;
8525       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8526         return 1;
8527       else
8528         break;
8529     }
8530   return 0;
8531 }
8532
8533 uword
8534 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8535 {
8536   u8 *tagp = va_arg (*args, u8 *);
8537   u32 tag;
8538
8539   if (unformat (input, "%d", &tag))
8540     {
8541       tagp[0] = (tag >> 8) & 0x0F;
8542       tagp[1] = tag & 0xFF;
8543       return 1;
8544     }
8545
8546   return 0;
8547 }
8548
8549 uword
8550 unformat_l2_match (unformat_input_t * input, va_list * args)
8551 {
8552   u8 **matchp = va_arg (*args, u8 **);
8553   u8 *match = 0;
8554   u8 src = 0;
8555   u8 src_val[6];
8556   u8 dst = 0;
8557   u8 dst_val[6];
8558   u8 proto = 0;
8559   u16 proto_val;
8560   u8 tag1 = 0;
8561   u8 tag1_val[2];
8562   u8 tag2 = 0;
8563   u8 tag2_val[2];
8564   int len = 14;
8565   u8 ignore_tag1 = 0;
8566   u8 ignore_tag2 = 0;
8567   u8 cos1 = 0;
8568   u8 cos2 = 0;
8569   u32 cos1_val = 0;
8570   u32 cos2_val = 0;
8571
8572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8573     {
8574       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8575         src = 1;
8576       else
8577         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8578         dst = 1;
8579       else if (unformat (input, "proto %U",
8580                          unformat_ethernet_type_host_byte_order, &proto_val))
8581         proto = 1;
8582       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8583         tag1 = 1;
8584       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8585         tag2 = 1;
8586       else if (unformat (input, "ignore-tag1"))
8587         ignore_tag1 = 1;
8588       else if (unformat (input, "ignore-tag2"))
8589         ignore_tag2 = 1;
8590       else if (unformat (input, "cos1 %d", &cos1_val))
8591         cos1 = 1;
8592       else if (unformat (input, "cos2 %d", &cos2_val))
8593         cos2 = 1;
8594       else
8595         break;
8596     }
8597   if ((src + dst + proto + tag1 + tag2 +
8598        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8599     return 0;
8600
8601   if (tag1 || ignore_tag1 || cos1)
8602     len = 18;
8603   if (tag2 || ignore_tag2 || cos2)
8604     len = 22;
8605
8606   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8607
8608   if (dst)
8609     clib_memcpy (match, dst_val, 6);
8610
8611   if (src)
8612     clib_memcpy (match + 6, src_val, 6);
8613
8614   if (tag2)
8615     {
8616       /* inner vlan tag */
8617       match[19] = tag2_val[1];
8618       match[18] = tag2_val[0];
8619       if (cos2)
8620         match[18] |= (cos2_val & 0x7) << 5;
8621       if (proto)
8622         {
8623           match[21] = proto_val & 0xff;
8624           match[20] = proto_val >> 8;
8625         }
8626       if (tag1)
8627         {
8628           match[15] = tag1_val[1];
8629           match[14] = tag1_val[0];
8630         }
8631       if (cos1)
8632         match[14] |= (cos1_val & 0x7) << 5;
8633       *matchp = match;
8634       return 1;
8635     }
8636   if (tag1)
8637     {
8638       match[15] = tag1_val[1];
8639       match[14] = tag1_val[0];
8640       if (proto)
8641         {
8642           match[17] = proto_val & 0xff;
8643           match[16] = proto_val >> 8;
8644         }
8645       if (cos1)
8646         match[14] |= (cos1_val & 0x7) << 5;
8647
8648       *matchp = match;
8649       return 1;
8650     }
8651   if (cos2)
8652     match[18] |= (cos2_val & 0x7) << 5;
8653   if (cos1)
8654     match[14] |= (cos1_val & 0x7) << 5;
8655   if (proto)
8656     {
8657       match[13] = proto_val & 0xff;
8658       match[12] = proto_val >> 8;
8659     }
8660
8661   *matchp = match;
8662   return 1;
8663 }
8664
8665
8666 uword
8667 unformat_classify_match (unformat_input_t * input, va_list * args)
8668 {
8669   u8 **matchp = va_arg (*args, u8 **);
8670   u32 skip_n_vectors = va_arg (*args, u32);
8671   u32 match_n_vectors = va_arg (*args, u32);
8672
8673   u8 *match = 0;
8674   u8 *l2 = 0;
8675   u8 *l3 = 0;
8676
8677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8678     {
8679       if (unformat (input, "hex %U", unformat_hex_string, &match))
8680         ;
8681       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8682         ;
8683       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8684         ;
8685       else
8686         break;
8687     }
8688
8689   if (match || l2 || l3)
8690     {
8691       if (l2 || l3)
8692         {
8693           /* "Win a free Ethernet header in every packet" */
8694           if (l2 == 0)
8695             vec_validate_aligned (l2, 13, sizeof (u32x4));
8696           match = l2;
8697           if (vec_len (l3))
8698             {
8699               vec_append_aligned (match, l3, sizeof (u32x4));
8700               vec_free (l3);
8701             }
8702         }
8703
8704       /* Make sure the vector is big enough even if key is all 0's */
8705       vec_validate_aligned
8706         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8707          sizeof (u32x4));
8708
8709       /* Set size, include skipped vectors */
8710       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8711
8712       *matchp = match;
8713
8714       return 1;
8715     }
8716
8717   return 0;
8718 }
8719
8720 static int
8721 api_classify_add_del_session (vat_main_t * vam)
8722 {
8723   unformat_input_t *i = vam->input;
8724   vl_api_classify_add_del_session_t *mp;
8725   int is_add = 1;
8726   u32 table_index = ~0;
8727   u32 hit_next_index = ~0;
8728   u32 opaque_index = ~0;
8729   u8 *match = 0;
8730   i32 advance = 0;
8731   f64 timeout;
8732   u32 skip_n_vectors = 0;
8733   u32 match_n_vectors = 0;
8734
8735   /*
8736    * Warning: you have to supply skip_n and match_n
8737    * because the API client cant simply look at the classify
8738    * table object.
8739    */
8740
8741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8742     {
8743       if (unformat (i, "del"))
8744         is_add = 0;
8745       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8746                          &hit_next_index))
8747         ;
8748       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8749                          &hit_next_index))
8750         ;
8751       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8752                          &hit_next_index))
8753         ;
8754       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8755         ;
8756       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8757         ;
8758       else if (unformat (i, "opaque-index %d", &opaque_index))
8759         ;
8760       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8761         ;
8762       else if (unformat (i, "match_n %d", &match_n_vectors))
8763         ;
8764       else if (unformat (i, "match %U", unformat_classify_match,
8765                          &match, skip_n_vectors, match_n_vectors))
8766         ;
8767       else if (unformat (i, "advance %d", &advance))
8768         ;
8769       else if (unformat (i, "table-index %d", &table_index))
8770         ;
8771       else
8772         break;
8773     }
8774
8775   if (table_index == ~0)
8776     {
8777       errmsg ("Table index required\n");
8778       return -99;
8779     }
8780
8781   if (is_add && match == 0)
8782     {
8783       errmsg ("Match value required\n");
8784       return -99;
8785     }
8786
8787   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8788
8789   mp->is_add = is_add;
8790   mp->table_index = ntohl (table_index);
8791   mp->hit_next_index = ntohl (hit_next_index);
8792   mp->opaque_index = ntohl (opaque_index);
8793   mp->advance = ntohl (advance);
8794   clib_memcpy (mp->match, match, vec_len (match));
8795   vec_free (match);
8796
8797   S;
8798   W;
8799   /* NOTREACHED */
8800 }
8801
8802 static int
8803 api_classify_set_interface_ip_table (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_classify_set_interface_ip_table_t *mp;
8807   f64 timeout;
8808   u32 sw_if_index;
8809   int sw_if_index_set;
8810   u32 table_index = ~0;
8811   u8 is_ipv6 = 0;
8812
8813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8816         sw_if_index_set = 1;
8817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "table %d", &table_index))
8820         ;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (sw_if_index_set == 0)
8829     {
8830       errmsg ("missing interface name or sw_if_index\n");
8831       return -99;
8832     }
8833
8834
8835   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8836
8837   mp->sw_if_index = ntohl (sw_if_index);
8838   mp->table_index = ntohl (table_index);
8839   mp->is_ipv6 = is_ipv6;
8840
8841   S;
8842   W;
8843   /* NOTREACHED */
8844   return 0;
8845 }
8846
8847 static int
8848 api_classify_set_interface_l2_tables (vat_main_t * vam)
8849 {
8850   unformat_input_t *i = vam->input;
8851   vl_api_classify_set_interface_l2_tables_t *mp;
8852   f64 timeout;
8853   u32 sw_if_index;
8854   int sw_if_index_set;
8855   u32 ip4_table_index = ~0;
8856   u32 ip6_table_index = ~0;
8857   u32 other_table_index = ~0;
8858   u32 is_input = 1;
8859
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8863         sw_if_index_set = 1;
8864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8865         sw_if_index_set = 1;
8866       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8867         ;
8868       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8869         ;
8870       else if (unformat (i, "other-table %d", &other_table_index))
8871         ;
8872       else if (unformat (i, "is-input %d", &is_input))
8873         ;
8874       else
8875         {
8876           clib_warning ("parse error '%U'", format_unformat_error, i);
8877           return -99;
8878         }
8879     }
8880
8881   if (sw_if_index_set == 0)
8882     {
8883       errmsg ("missing interface name or sw_if_index\n");
8884       return -99;
8885     }
8886
8887
8888   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8889
8890   mp->sw_if_index = ntohl (sw_if_index);
8891   mp->ip4_table_index = ntohl (ip4_table_index);
8892   mp->ip6_table_index = ntohl (ip6_table_index);
8893   mp->other_table_index = ntohl (other_table_index);
8894   mp->is_input = (u8) is_input;
8895
8896   S;
8897   W;
8898   /* NOTREACHED */
8899   return 0;
8900 }
8901
8902 static int
8903 api_set_ipfix_exporter (vat_main_t * vam)
8904 {
8905   unformat_input_t *i = vam->input;
8906   vl_api_set_ipfix_exporter_t *mp;
8907   ip4_address_t collector_address;
8908   u8 collector_address_set = 0;
8909   u32 collector_port = ~0;
8910   ip4_address_t src_address;
8911   u8 src_address_set = 0;
8912   u32 vrf_id = ~0;
8913   u32 path_mtu = ~0;
8914   u32 template_interval = ~0;
8915   u8 udp_checksum = 0;
8916   f64 timeout;
8917
8918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8919     {
8920       if (unformat (i, "collector_address %U", unformat_ip4_address,
8921                     &collector_address))
8922         collector_address_set = 1;
8923       else if (unformat (i, "collector_port %d", &collector_port))
8924         ;
8925       else if (unformat (i, "src_address %U", unformat_ip4_address,
8926                          &src_address))
8927         src_address_set = 1;
8928       else if (unformat (i, "vrf_id %d", &vrf_id))
8929         ;
8930       else if (unformat (i, "path_mtu %d", &path_mtu))
8931         ;
8932       else if (unformat (i, "template_interval %d", &template_interval))
8933         ;
8934       else if (unformat (i, "udp_checksum"))
8935         udp_checksum = 1;
8936       else
8937         break;
8938     }
8939
8940   if (collector_address_set == 0)
8941     {
8942       errmsg ("collector_address required\n");
8943       return -99;
8944     }
8945
8946   if (src_address_set == 0)
8947     {
8948       errmsg ("src_address required\n");
8949       return -99;
8950     }
8951
8952   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
8953
8954   memcpy (mp->collector_address, collector_address.data,
8955           sizeof (collector_address.data));
8956   mp->collector_port = htons ((u16) collector_port);
8957   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8958   mp->vrf_id = htonl (vrf_id);
8959   mp->path_mtu = htonl (path_mtu);
8960   mp->template_interval = htonl (template_interval);
8961   mp->udp_checksum = udp_checksum;
8962
8963   S;
8964   W;
8965   /* NOTREACHED */
8966 }
8967
8968 static int
8969 api_set_ipfix_classify_stream (vat_main_t * vam)
8970 {
8971   unformat_input_t *i = vam->input;
8972   vl_api_set_ipfix_classify_stream_t *mp;
8973   u32 domain_id = 0;
8974   u32 src_port = UDP_DST_PORT_ipfix;
8975   f64 timeout;
8976
8977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8978     {
8979       if (unformat (i, "domain %d", &domain_id))
8980         ;
8981       else if (unformat (i, "src_port %d", &src_port))
8982         ;
8983       else
8984         {
8985           errmsg ("unknown input `%U'", format_unformat_error, i);
8986           return -99;
8987         }
8988     }
8989
8990   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
8991
8992   mp->domain_id = htonl (domain_id);
8993   mp->src_port = htons ((u16) src_port);
8994
8995   S;
8996   W;
8997   /* NOTREACHED */
8998 }
8999
9000 static int
9001 api_ipfix_classify_table_add_del (vat_main_t * vam)
9002 {
9003   unformat_input_t *i = vam->input;
9004   vl_api_ipfix_classify_table_add_del_t *mp;
9005   int is_add = -1;
9006   u32 classify_table_index = ~0;
9007   u8 ip_version = 0;
9008   u8 transport_protocol = 255;
9009   f64 timeout;
9010
9011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9012     {
9013       if (unformat (i, "add"))
9014         is_add = 1;
9015       else if (unformat (i, "del"))
9016         is_add = 0;
9017       else if (unformat (i, "table %d", &classify_table_index))
9018         ;
9019       else if (unformat (i, "ip4"))
9020         ip_version = 4;
9021       else if (unformat (i, "ip6"))
9022         ip_version = 6;
9023       else if (unformat (i, "tcp"))
9024         transport_protocol = 6;
9025       else if (unformat (i, "udp"))
9026         transport_protocol = 17;
9027       else
9028         {
9029           errmsg ("unknown input `%U'", format_unformat_error, i);
9030           return -99;
9031         }
9032     }
9033
9034   if (is_add == -1)
9035     {
9036       errmsg ("expecting: add|del");
9037       return -99;
9038     }
9039   if (classify_table_index == ~0)
9040     {
9041       errmsg ("classifier table not specified");
9042       return -99;
9043     }
9044   if (ip_version == 0)
9045     {
9046       errmsg ("IP version not specified");
9047       return -99;
9048     }
9049
9050   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9051
9052   mp->is_add = is_add;
9053   mp->table_id = htonl (classify_table_index);
9054   mp->ip_version = ip_version;
9055   mp->transport_protocol = transport_protocol;
9056
9057   S;
9058   W;
9059   /* NOTREACHED */
9060 }
9061
9062 static int
9063 api_get_node_index (vat_main_t * vam)
9064 {
9065   unformat_input_t *i = vam->input;
9066   vl_api_get_node_index_t *mp;
9067   f64 timeout;
9068   u8 *name = 0;
9069
9070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9071     {
9072       if (unformat (i, "node %s", &name))
9073         ;
9074       else
9075         break;
9076     }
9077   if (name == 0)
9078     {
9079       errmsg ("node name required\n");
9080       return -99;
9081     }
9082   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9083     {
9084       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9085       return -99;
9086     }
9087
9088   M (GET_NODE_INDEX, get_node_index);
9089   clib_memcpy (mp->node_name, name, vec_len (name));
9090   vec_free (name);
9091
9092   S;
9093   W;
9094   /* NOTREACHED */
9095   return 0;
9096 }
9097
9098 static int
9099 api_get_next_index (vat_main_t * vam)
9100 {
9101   unformat_input_t *i = vam->input;
9102   vl_api_get_next_index_t *mp;
9103   f64 timeout;
9104   u8 *node_name = 0, *next_node_name = 0;
9105
9106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9107     {
9108       if (unformat (i, "node-name %s", &node_name))
9109         ;
9110       else if (unformat (i, "next-node-name %s", &next_node_name))
9111         break;
9112     }
9113
9114   if (node_name == 0)
9115     {
9116       errmsg ("node name required\n");
9117       return -99;
9118     }
9119   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9120     {
9121       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9122       return -99;
9123     }
9124
9125   if (next_node_name == 0)
9126     {
9127       errmsg ("next node name required\n");
9128       return -99;
9129     }
9130   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9131     {
9132       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9133       return -99;
9134     }
9135
9136   M (GET_NEXT_INDEX, get_next_index);
9137   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9138   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9139   vec_free (node_name);
9140   vec_free (next_node_name);
9141
9142   S;
9143   W;
9144   /* NOTREACHED */
9145   return 0;
9146 }
9147
9148 static int
9149 api_add_node_next (vat_main_t * vam)
9150 {
9151   unformat_input_t *i = vam->input;
9152   vl_api_add_node_next_t *mp;
9153   f64 timeout;
9154   u8 *name = 0;
9155   u8 *next = 0;
9156
9157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158     {
9159       if (unformat (i, "node %s", &name))
9160         ;
9161       else if (unformat (i, "next %s", &next))
9162         ;
9163       else
9164         break;
9165     }
9166   if (name == 0)
9167     {
9168       errmsg ("node name required\n");
9169       return -99;
9170     }
9171   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9172     {
9173       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9174       return -99;
9175     }
9176   if (next == 0)
9177     {
9178       errmsg ("next node required\n");
9179       return -99;
9180     }
9181   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9182     {
9183       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9184       return -99;
9185     }
9186
9187   M (ADD_NODE_NEXT, add_node_next);
9188   clib_memcpy (mp->node_name, name, vec_len (name));
9189   clib_memcpy (mp->next_name, next, vec_len (next));
9190   vec_free (name);
9191   vec_free (next);
9192
9193   S;
9194   W;
9195   /* NOTREACHED */
9196   return 0;
9197 }
9198
9199 static int
9200 api_l2tpv3_create_tunnel (vat_main_t * vam)
9201 {
9202   unformat_input_t *i = vam->input;
9203   ip6_address_t client_address, our_address;
9204   int client_address_set = 0;
9205   int our_address_set = 0;
9206   u32 local_session_id = 0;
9207   u32 remote_session_id = 0;
9208   u64 local_cookie = 0;
9209   u64 remote_cookie = 0;
9210   u8 l2_sublayer_present = 0;
9211   vl_api_l2tpv3_create_tunnel_t *mp;
9212   f64 timeout;
9213
9214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9215     {
9216       if (unformat (i, "client_address %U", unformat_ip6_address,
9217                     &client_address))
9218         client_address_set = 1;
9219       else if (unformat (i, "our_address %U", unformat_ip6_address,
9220                          &our_address))
9221         our_address_set = 1;
9222       else if (unformat (i, "local_session_id %d", &local_session_id))
9223         ;
9224       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9225         ;
9226       else if (unformat (i, "local_cookie %lld", &local_cookie))
9227         ;
9228       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9229         ;
9230       else if (unformat (i, "l2-sublayer-present"))
9231         l2_sublayer_present = 1;
9232       else
9233         break;
9234     }
9235
9236   if (client_address_set == 0)
9237     {
9238       errmsg ("client_address required\n");
9239       return -99;
9240     }
9241
9242   if (our_address_set == 0)
9243     {
9244       errmsg ("our_address required\n");
9245       return -99;
9246     }
9247
9248   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9249
9250   clib_memcpy (mp->client_address, client_address.as_u8,
9251                sizeof (mp->client_address));
9252
9253   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9254
9255   mp->local_session_id = ntohl (local_session_id);
9256   mp->remote_session_id = ntohl (remote_session_id);
9257   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9258   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9259   mp->l2_sublayer_present = l2_sublayer_present;
9260   mp->is_ipv6 = 1;
9261
9262   S;
9263   W;
9264   /* NOTREACHED */
9265   return 0;
9266 }
9267
9268 static int
9269 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9270 {
9271   unformat_input_t *i = vam->input;
9272   u32 sw_if_index;
9273   u8 sw_if_index_set = 0;
9274   u64 new_local_cookie = 0;
9275   u64 new_remote_cookie = 0;
9276   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9277   f64 timeout;
9278
9279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9280     {
9281       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9282         sw_if_index_set = 1;
9283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9284         sw_if_index_set = 1;
9285       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9286         ;
9287       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9288         ;
9289       else
9290         break;
9291     }
9292
9293   if (sw_if_index_set == 0)
9294     {
9295       errmsg ("missing interface name or sw_if_index\n");
9296       return -99;
9297     }
9298
9299   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9300
9301   mp->sw_if_index = ntohl (sw_if_index);
9302   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9303   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9304
9305   S;
9306   W;
9307   /* NOTREACHED */
9308   return 0;
9309 }
9310
9311 static int
9312 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9313 {
9314   unformat_input_t *i = vam->input;
9315   vl_api_l2tpv3_interface_enable_disable_t *mp;
9316   f64 timeout;
9317   u32 sw_if_index;
9318   u8 sw_if_index_set = 0;
9319   u8 enable_disable = 1;
9320
9321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9322     {
9323       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9324         sw_if_index_set = 1;
9325       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9326         sw_if_index_set = 1;
9327       else if (unformat (i, "enable"))
9328         enable_disable = 1;
9329       else if (unformat (i, "disable"))
9330         enable_disable = 0;
9331       else
9332         break;
9333     }
9334
9335   if (sw_if_index_set == 0)
9336     {
9337       errmsg ("missing interface name or sw_if_index\n");
9338       return -99;
9339     }
9340
9341   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9342
9343   mp->sw_if_index = ntohl (sw_if_index);
9344   mp->enable_disable = enable_disable;
9345
9346   S;
9347   W;
9348   /* NOTREACHED */
9349   return 0;
9350 }
9351
9352 static int
9353 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9354 {
9355   unformat_input_t *i = vam->input;
9356   vl_api_l2tpv3_set_lookup_key_t *mp;
9357   f64 timeout;
9358   u8 key = ~0;
9359
9360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (i, "lookup_v6_src"))
9363         key = L2T_LOOKUP_SRC_ADDRESS;
9364       else if (unformat (i, "lookup_v6_dst"))
9365         key = L2T_LOOKUP_DST_ADDRESS;
9366       else if (unformat (i, "lookup_session_id"))
9367         key = L2T_LOOKUP_SESSION_ID;
9368       else
9369         break;
9370     }
9371
9372   if (key == (u8) ~ 0)
9373     {
9374       errmsg ("l2tp session lookup key unset\n");
9375       return -99;
9376     }
9377
9378   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9379
9380   mp->key = key;
9381
9382   S;
9383   W;
9384   /* NOTREACHED */
9385   return 0;
9386 }
9387
9388 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9389   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9390 {
9391   vat_main_t *vam = &vat_main;
9392
9393   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9394            format_ip6_address, mp->our_address,
9395            format_ip6_address, mp->client_address,
9396            clib_net_to_host_u32 (mp->sw_if_index));
9397
9398   fformat (vam->ofp,
9399            "   local cookies %016llx %016llx remote cookie %016llx\n",
9400            clib_net_to_host_u64 (mp->local_cookie[0]),
9401            clib_net_to_host_u64 (mp->local_cookie[1]),
9402            clib_net_to_host_u64 (mp->remote_cookie));
9403
9404   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9405            clib_net_to_host_u32 (mp->local_session_id),
9406            clib_net_to_host_u32 (mp->remote_session_id));
9407
9408   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9409            mp->l2_sublayer_present ? "preset" : "absent");
9410
9411 }
9412
9413 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9414   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9415 {
9416   vat_main_t *vam = &vat_main;
9417   vat_json_node_t *node = NULL;
9418   struct in6_addr addr;
9419
9420   if (VAT_JSON_ARRAY != vam->json_tree.type)
9421     {
9422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9423       vat_json_init_array (&vam->json_tree);
9424     }
9425   node = vat_json_array_add (&vam->json_tree);
9426
9427   vat_json_init_object (node);
9428
9429   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9430   vat_json_object_add_ip6 (node, "our_address", addr);
9431   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9432   vat_json_object_add_ip6 (node, "client_address", addr);
9433
9434   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9435   vat_json_init_array (lc);
9436   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9437   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9438   vat_json_object_add_uint (node, "remote_cookie",
9439                             clib_net_to_host_u64 (mp->remote_cookie));
9440
9441   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9442   vat_json_object_add_uint (node, "local_session_id",
9443                             clib_net_to_host_u32 (mp->local_session_id));
9444   vat_json_object_add_uint (node, "remote_session_id",
9445                             clib_net_to_host_u32 (mp->remote_session_id));
9446   vat_json_object_add_string_copy (node, "l2_sublayer",
9447                                    mp->l2_sublayer_present ? (u8 *) "present"
9448                                    : (u8 *) "absent");
9449 }
9450
9451 static int
9452 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9453 {
9454   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9455   f64 timeout;
9456
9457   /* Get list of l2tpv3-tunnel interfaces */
9458   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9459   S;
9460
9461   /* Use a control ping for synchronization */
9462   {
9463     vl_api_control_ping_t *mp;
9464     M (CONTROL_PING, control_ping);
9465     S;
9466   }
9467   W;
9468 }
9469
9470
9471 static void vl_api_sw_interface_tap_details_t_handler
9472   (vl_api_sw_interface_tap_details_t * mp)
9473 {
9474   vat_main_t *vam = &vat_main;
9475
9476   fformat (vam->ofp, "%-16s %d\n",
9477            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9478 }
9479
9480 static void vl_api_sw_interface_tap_details_t_handler_json
9481   (vl_api_sw_interface_tap_details_t * mp)
9482 {
9483   vat_main_t *vam = &vat_main;
9484   vat_json_node_t *node = NULL;
9485
9486   if (VAT_JSON_ARRAY != vam->json_tree.type)
9487     {
9488       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9489       vat_json_init_array (&vam->json_tree);
9490     }
9491   node = vat_json_array_add (&vam->json_tree);
9492
9493   vat_json_init_object (node);
9494   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9495   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9496 }
9497
9498 static int
9499 api_sw_interface_tap_dump (vat_main_t * vam)
9500 {
9501   vl_api_sw_interface_tap_dump_t *mp;
9502   f64 timeout;
9503
9504   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9505   /* Get list of tap interfaces */
9506   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9507   S;
9508
9509   /* Use a control ping for synchronization */
9510   {
9511     vl_api_control_ping_t *mp;
9512     M (CONTROL_PING, control_ping);
9513     S;
9514   }
9515   W;
9516 }
9517
9518 static uword unformat_vxlan_decap_next
9519   (unformat_input_t * input, va_list * args)
9520 {
9521   u32 *result = va_arg (*args, u32 *);
9522   u32 tmp;
9523
9524   if (unformat (input, "drop"))
9525     *result = VXLAN_INPUT_NEXT_DROP;
9526   else if (unformat (input, "ip4"))
9527     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9528   else if (unformat (input, "ip6"))
9529     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9530   else if (unformat (input, "l2"))
9531     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9532   else if (unformat (input, "%d", &tmp))
9533     *result = tmp;
9534   else
9535     return 0;
9536   return 1;
9537 }
9538
9539 static int
9540 api_vxlan_add_del_tunnel (vat_main_t * vam)
9541 {
9542   unformat_input_t *line_input = vam->input;
9543   vl_api_vxlan_add_del_tunnel_t *mp;
9544   f64 timeout;
9545   ip4_address_t src4, dst4;
9546   ip6_address_t src6, dst6;
9547   u8 is_add = 1;
9548   u8 ipv4_set = 0, ipv6_set = 0;
9549   u8 src_set = 0;
9550   u8 dst_set = 0;
9551   u32 encap_vrf_id = 0;
9552   u32 decap_next_index = ~0;
9553   u32 vni = 0;
9554
9555   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9556     {
9557       if (unformat (line_input, "del"))
9558         is_add = 0;
9559       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9560         {
9561           ipv4_set = 1;
9562           src_set = 1;
9563         }
9564       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9565         {
9566           ipv4_set = 1;
9567           dst_set = 1;
9568         }
9569       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9570         {
9571           ipv6_set = 1;
9572           src_set = 1;
9573         }
9574       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9575         {
9576           ipv6_set = 1;
9577           dst_set = 1;
9578         }
9579       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9580         ;
9581       else if (unformat (line_input, "decap-next %U",
9582                          unformat_vxlan_decap_next, &decap_next_index))
9583         ;
9584       else if (unformat (line_input, "vni %d", &vni))
9585         ;
9586       else
9587         {
9588           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9589           return -99;
9590         }
9591     }
9592
9593   if (src_set == 0)
9594     {
9595       errmsg ("tunnel src address not specified\n");
9596       return -99;
9597     }
9598   if (dst_set == 0)
9599     {
9600       errmsg ("tunnel dst address not specified\n");
9601       return -99;
9602     }
9603
9604   if (ipv4_set && ipv6_set)
9605     {
9606       errmsg ("both IPv4 and IPv6 addresses specified");
9607       return -99;
9608     }
9609
9610   if ((vni == 0) || (vni >> 24))
9611     {
9612       errmsg ("vni not specified or out of range\n");
9613       return -99;
9614     }
9615
9616   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9617
9618   if (ipv6_set)
9619     {
9620       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9621       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9622     }
9623   else
9624     {
9625       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9626       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9627     }
9628   mp->encap_vrf_id = ntohl (encap_vrf_id);
9629   mp->decap_next_index = ntohl (decap_next_index);
9630   mp->vni = ntohl (vni);
9631   mp->is_add = is_add;
9632   mp->is_ipv6 = ipv6_set;
9633
9634   S;
9635   W;
9636   /* NOTREACHED */
9637   return 0;
9638 }
9639
9640 static void vl_api_vxlan_tunnel_details_t_handler
9641   (vl_api_vxlan_tunnel_details_t * mp)
9642 {
9643   vat_main_t *vam = &vat_main;
9644
9645   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9646            ntohl (mp->sw_if_index),
9647            format_ip46_address, &(mp->src_address[0]),
9648            IP46_TYPE_ANY,
9649            format_ip46_address, &(mp->dst_address[0]),
9650            IP46_TYPE_ANY,
9651            ntohl (mp->encap_vrf_id),
9652            ntohl (mp->decap_next_index), ntohl (mp->vni));
9653 }
9654
9655 static void vl_api_vxlan_tunnel_details_t_handler_json
9656   (vl_api_vxlan_tunnel_details_t * mp)
9657 {
9658   vat_main_t *vam = &vat_main;
9659   vat_json_node_t *node = NULL;
9660   struct in_addr ip4;
9661   struct in6_addr ip6;
9662
9663   if (VAT_JSON_ARRAY != vam->json_tree.type)
9664     {
9665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9666       vat_json_init_array (&vam->json_tree);
9667     }
9668   node = vat_json_array_add (&vam->json_tree);
9669
9670   vat_json_init_object (node);
9671   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9672   if (mp->is_ipv6)
9673     {
9674       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9675       vat_json_object_add_ip6 (node, "src_address", ip6);
9676       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9677       vat_json_object_add_ip6 (node, "dst_address", ip6);
9678     }
9679   else
9680     {
9681       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9682       vat_json_object_add_ip4 (node, "src_address", ip4);
9683       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9684       vat_json_object_add_ip4 (node, "dst_address", ip4);
9685     }
9686   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9687   vat_json_object_add_uint (node, "decap_next_index",
9688                             ntohl (mp->decap_next_index));
9689   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9690   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9691 }
9692
9693 static int
9694 api_vxlan_tunnel_dump (vat_main_t * vam)
9695 {
9696   unformat_input_t *i = vam->input;
9697   vl_api_vxlan_tunnel_dump_t *mp;
9698   f64 timeout;
9699   u32 sw_if_index;
9700   u8 sw_if_index_set = 0;
9701
9702   /* Parse args required to build the message */
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "sw_if_index %d", &sw_if_index))
9706         sw_if_index_set = 1;
9707       else
9708         break;
9709     }
9710
9711   if (sw_if_index_set == 0)
9712     {
9713       sw_if_index = ~0;
9714     }
9715
9716   if (!vam->json_output)
9717     {
9718       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9719                "sw_if_index", "src_address", "dst_address",
9720                "encap_vrf_id", "decap_next_index", "vni");
9721     }
9722
9723   /* Get list of vxlan-tunnel interfaces */
9724   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9725
9726   mp->sw_if_index = htonl (sw_if_index);
9727
9728   S;
9729
9730   /* Use a control ping for synchronization */
9731   {
9732     vl_api_control_ping_t *mp;
9733     M (CONTROL_PING, control_ping);
9734     S;
9735   }
9736   W;
9737 }
9738
9739 static int
9740 api_gre_add_del_tunnel (vat_main_t * vam)
9741 {
9742   unformat_input_t *line_input = vam->input;
9743   vl_api_gre_add_del_tunnel_t *mp;
9744   f64 timeout;
9745   ip4_address_t src4, dst4;
9746   u8 is_add = 1;
9747   u8 teb = 0;
9748   u8 src_set = 0;
9749   u8 dst_set = 0;
9750   u32 outer_fib_id = 0;
9751
9752   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9753     {
9754       if (unformat (line_input, "del"))
9755         is_add = 0;
9756       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9757         src_set = 1;
9758       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9759         dst_set = 1;
9760       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9761         ;
9762       else if (unformat (line_input, "teb"))
9763         teb = 1;
9764       else
9765         {
9766           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9767           return -99;
9768         }
9769     }
9770
9771   if (src_set == 0)
9772     {
9773       errmsg ("tunnel src address not specified\n");
9774       return -99;
9775     }
9776   if (dst_set == 0)
9777     {
9778       errmsg ("tunnel dst address not specified\n");
9779       return -99;
9780     }
9781
9782
9783   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9784
9785   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9786   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9787   mp->outer_fib_id = ntohl (outer_fib_id);
9788   mp->is_add = is_add;
9789   mp->teb = teb;
9790
9791   S;
9792   W;
9793   /* NOTREACHED */
9794   return 0;
9795 }
9796
9797 static void vl_api_gre_tunnel_details_t_handler
9798   (vl_api_gre_tunnel_details_t * mp)
9799 {
9800   vat_main_t *vam = &vat_main;
9801
9802   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
9803            ntohl (mp->sw_if_index),
9804            format_ip4_address, &mp->src_address,
9805            format_ip4_address, &mp->dst_address,
9806            mp->teb, ntohl (mp->outer_fib_id));
9807 }
9808
9809 static void vl_api_gre_tunnel_details_t_handler_json
9810   (vl_api_gre_tunnel_details_t * mp)
9811 {
9812   vat_main_t *vam = &vat_main;
9813   vat_json_node_t *node = NULL;
9814   struct in_addr ip4;
9815
9816   if (VAT_JSON_ARRAY != vam->json_tree.type)
9817     {
9818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9819       vat_json_init_array (&vam->json_tree);
9820     }
9821   node = vat_json_array_add (&vam->json_tree);
9822
9823   vat_json_init_object (node);
9824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9825   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9826   vat_json_object_add_ip4 (node, "src_address", ip4);
9827   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9828   vat_json_object_add_ip4 (node, "dst_address", ip4);
9829   vat_json_object_add_uint (node, "teb", mp->teb);
9830   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9831 }
9832
9833 static int
9834 api_gre_tunnel_dump (vat_main_t * vam)
9835 {
9836   unformat_input_t *i = vam->input;
9837   vl_api_gre_tunnel_dump_t *mp;
9838   f64 timeout;
9839   u32 sw_if_index;
9840   u8 sw_if_index_set = 0;
9841
9842   /* Parse args required to build the message */
9843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9844     {
9845       if (unformat (i, "sw_if_index %d", &sw_if_index))
9846         sw_if_index_set = 1;
9847       else
9848         break;
9849     }
9850
9851   if (sw_if_index_set == 0)
9852     {
9853       sw_if_index = ~0;
9854     }
9855
9856   if (!vam->json_output)
9857     {
9858       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
9859                "sw_if_index", "src_address", "dst_address", "teb",
9860                "outer_fib_id");
9861     }
9862
9863   /* Get list of gre-tunnel interfaces */
9864   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9865
9866   mp->sw_if_index = htonl (sw_if_index);
9867
9868   S;
9869
9870   /* Use a control ping for synchronization */
9871   {
9872     vl_api_control_ping_t *mp;
9873     M (CONTROL_PING, control_ping);
9874     S;
9875   }
9876   W;
9877 }
9878
9879 static int
9880 api_l2_fib_clear_table (vat_main_t * vam)
9881 {
9882 //  unformat_input_t * i = vam->input;
9883   vl_api_l2_fib_clear_table_t *mp;
9884   f64 timeout;
9885
9886   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9887
9888   S;
9889   W;
9890   /* NOTREACHED */
9891   return 0;
9892 }
9893
9894 static int
9895 api_l2_interface_efp_filter (vat_main_t * vam)
9896 {
9897   unformat_input_t *i = vam->input;
9898   vl_api_l2_interface_efp_filter_t *mp;
9899   f64 timeout;
9900   u32 sw_if_index;
9901   u8 enable = 1;
9902   u8 sw_if_index_set = 0;
9903
9904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9905     {
9906       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9907         sw_if_index_set = 1;
9908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9909         sw_if_index_set = 1;
9910       else if (unformat (i, "enable"))
9911         enable = 1;
9912       else if (unformat (i, "disable"))
9913         enable = 0;
9914       else
9915         {
9916           clib_warning ("parse error '%U'", format_unformat_error, i);
9917           return -99;
9918         }
9919     }
9920
9921   if (sw_if_index_set == 0)
9922     {
9923       errmsg ("missing sw_if_index\n");
9924       return -99;
9925     }
9926
9927   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9928
9929   mp->sw_if_index = ntohl (sw_if_index);
9930   mp->enable_disable = enable;
9931
9932   S;
9933   W;
9934   /* NOTREACHED */
9935   return 0;
9936 }
9937
9938 #define foreach_vtr_op                          \
9939 _("disable",  L2_VTR_DISABLED)                  \
9940 _("push-1",  L2_VTR_PUSH_1)                     \
9941 _("push-2",  L2_VTR_PUSH_2)                     \
9942 _("pop-1",  L2_VTR_POP_1)                       \
9943 _("pop-2",  L2_VTR_POP_2)                       \
9944 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9945 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9946 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9947 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9948
9949 static int
9950 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9951 {
9952   unformat_input_t *i = vam->input;
9953   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9954   f64 timeout;
9955   u32 sw_if_index;
9956   u8 sw_if_index_set = 0;
9957   u8 vtr_op_set = 0;
9958   u32 vtr_op = 0;
9959   u32 push_dot1q = 1;
9960   u32 tag1 = ~0;
9961   u32 tag2 = ~0;
9962
9963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9966         sw_if_index_set = 1;
9967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9968         sw_if_index_set = 1;
9969       else if (unformat (i, "vtr_op %d", &vtr_op))
9970         vtr_op_set = 1;
9971 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9972       foreach_vtr_op
9973 #undef _
9974         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9975         ;
9976       else if (unformat (i, "tag1 %d", &tag1))
9977         ;
9978       else if (unformat (i, "tag2 %d", &tag2))
9979         ;
9980       else
9981         {
9982           clib_warning ("parse error '%U'", format_unformat_error, i);
9983           return -99;
9984         }
9985     }
9986
9987   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9988     {
9989       errmsg ("missing vtr operation or sw_if_index\n");
9990       return -99;
9991     }
9992
9993   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9994     mp->sw_if_index = ntohl (sw_if_index);
9995   mp->vtr_op = ntohl (vtr_op);
9996   mp->push_dot1q = ntohl (push_dot1q);
9997   mp->tag1 = ntohl (tag1);
9998   mp->tag2 = ntohl (tag2);
9999
10000   S;
10001   W;
10002   /* NOTREACHED */
10003   return 0;
10004 }
10005
10006 static int
10007 api_create_vhost_user_if (vat_main_t * vam)
10008 {
10009   unformat_input_t *i = vam->input;
10010   vl_api_create_vhost_user_if_t *mp;
10011   f64 timeout;
10012   u8 *file_name;
10013   u8 is_server = 0;
10014   u8 file_name_set = 0;
10015   u32 custom_dev_instance = ~0;
10016   u8 hwaddr[6];
10017   u8 use_custom_mac = 0;
10018
10019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10020     {
10021       if (unformat (i, "socket %s", &file_name))
10022         {
10023           file_name_set = 1;
10024         }
10025       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10026         ;
10027       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10028         use_custom_mac = 1;
10029       else if (unformat (i, "server"))
10030         is_server = 1;
10031       else
10032         break;
10033     }
10034
10035   if (file_name_set == 0)
10036     {
10037       errmsg ("missing socket file name\n");
10038       return -99;
10039     }
10040
10041   if (vec_len (file_name) > 255)
10042     {
10043       errmsg ("socket file name too long\n");
10044       return -99;
10045     }
10046   vec_add1 (file_name, 0);
10047
10048   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10049
10050   mp->is_server = is_server;
10051   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10052   vec_free (file_name);
10053   if (custom_dev_instance != ~0)
10054     {
10055       mp->renumber = 1;
10056       mp->custom_dev_instance = ntohl (custom_dev_instance);
10057     }
10058   mp->use_custom_mac = use_custom_mac;
10059   clib_memcpy (mp->mac_address, hwaddr, 6);
10060
10061   S;
10062   W;
10063   /* NOTREACHED */
10064   return 0;
10065 }
10066
10067 static int
10068 api_modify_vhost_user_if (vat_main_t * vam)
10069 {
10070   unformat_input_t *i = vam->input;
10071   vl_api_modify_vhost_user_if_t *mp;
10072   f64 timeout;
10073   u8 *file_name;
10074   u8 is_server = 0;
10075   u8 file_name_set = 0;
10076   u32 custom_dev_instance = ~0;
10077   u8 sw_if_index_set = 0;
10078   u32 sw_if_index = (u32) ~ 0;
10079
10080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10081     {
10082       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10083         sw_if_index_set = 1;
10084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10085         sw_if_index_set = 1;
10086       else if (unformat (i, "socket %s", &file_name))
10087         {
10088           file_name_set = 1;
10089         }
10090       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10091         ;
10092       else if (unformat (i, "server"))
10093         is_server = 1;
10094       else
10095         break;
10096     }
10097
10098   if (sw_if_index_set == 0)
10099     {
10100       errmsg ("missing sw_if_index or interface name\n");
10101       return -99;
10102     }
10103
10104   if (file_name_set == 0)
10105     {
10106       errmsg ("missing socket file name\n");
10107       return -99;
10108     }
10109
10110   if (vec_len (file_name) > 255)
10111     {
10112       errmsg ("socket file name too long\n");
10113       return -99;
10114     }
10115   vec_add1 (file_name, 0);
10116
10117   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10118
10119   mp->sw_if_index = ntohl (sw_if_index);
10120   mp->is_server = is_server;
10121   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10122   vec_free (file_name);
10123   if (custom_dev_instance != ~0)
10124     {
10125       mp->renumber = 1;
10126       mp->custom_dev_instance = ntohl (custom_dev_instance);
10127     }
10128
10129   S;
10130   W;
10131   /* NOTREACHED */
10132   return 0;
10133 }
10134
10135 static int
10136 api_delete_vhost_user_if (vat_main_t * vam)
10137 {
10138   unformat_input_t *i = vam->input;
10139   vl_api_delete_vhost_user_if_t *mp;
10140   f64 timeout;
10141   u32 sw_if_index = ~0;
10142   u8 sw_if_index_set = 0;
10143
10144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10145     {
10146       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10147         sw_if_index_set = 1;
10148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10149         sw_if_index_set = 1;
10150       else
10151         break;
10152     }
10153
10154   if (sw_if_index_set == 0)
10155     {
10156       errmsg ("missing sw_if_index or interface name\n");
10157       return -99;
10158     }
10159
10160
10161   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10162
10163   mp->sw_if_index = ntohl (sw_if_index);
10164
10165   S;
10166   W;
10167   /* NOTREACHED */
10168   return 0;
10169 }
10170
10171 static void vl_api_sw_interface_vhost_user_details_t_handler
10172   (vl_api_sw_interface_vhost_user_details_t * mp)
10173 {
10174   vat_main_t *vam = &vat_main;
10175
10176   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10177            (char *) mp->interface_name,
10178            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10179            clib_net_to_host_u64 (mp->features), mp->is_server,
10180            ntohl (mp->num_regions), (char *) mp->sock_filename);
10181   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10182 }
10183
10184 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10185   (vl_api_sw_interface_vhost_user_details_t * mp)
10186 {
10187   vat_main_t *vam = &vat_main;
10188   vat_json_node_t *node = NULL;
10189
10190   if (VAT_JSON_ARRAY != vam->json_tree.type)
10191     {
10192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10193       vat_json_init_array (&vam->json_tree);
10194     }
10195   node = vat_json_array_add (&vam->json_tree);
10196
10197   vat_json_init_object (node);
10198   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10199   vat_json_object_add_string_copy (node, "interface_name",
10200                                    mp->interface_name);
10201   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10202                             ntohl (mp->virtio_net_hdr_sz));
10203   vat_json_object_add_uint (node, "features",
10204                             clib_net_to_host_u64 (mp->features));
10205   vat_json_object_add_uint (node, "is_server", mp->is_server);
10206   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10207   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10208   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10209 }
10210
10211 static int
10212 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10213 {
10214   vl_api_sw_interface_vhost_user_dump_t *mp;
10215   f64 timeout;
10216   fformat (vam->ofp,
10217            "Interface name           idx hdr_sz features server regions filename\n");
10218
10219   /* Get list of vhost-user interfaces */
10220   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10221   S;
10222
10223   /* Use a control ping for synchronization */
10224   {
10225     vl_api_control_ping_t *mp;
10226     M (CONTROL_PING, control_ping);
10227     S;
10228   }
10229   W;
10230 }
10231
10232 static int
10233 api_show_version (vat_main_t * vam)
10234 {
10235   vl_api_show_version_t *mp;
10236   f64 timeout;
10237
10238   M (SHOW_VERSION, show_version);
10239
10240   S;
10241   W;
10242   /* NOTREACHED */
10243   return 0;
10244 }
10245
10246
10247 static int
10248 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10249 {
10250   unformat_input_t *line_input = vam->input;
10251   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10252   f64 timeout;
10253   ip4_address_t local4, remote4;
10254   ip6_address_t local6, remote6;
10255   u8 is_add = 1;
10256   u8 ipv4_set = 0, ipv6_set = 0;
10257   u8 local_set = 0;
10258   u8 remote_set = 0;
10259   u32 encap_vrf_id = 0;
10260   u32 decap_vrf_id = 0;
10261   u8 protocol = ~0;
10262   u32 vni;
10263   u8 vni_set = 0;
10264
10265   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10266     {
10267       if (unformat (line_input, "del"))
10268         is_add = 0;
10269       else if (unformat (line_input, "local %U",
10270                          unformat_ip4_address, &local4))
10271         {
10272           local_set = 1;
10273           ipv4_set = 1;
10274         }
10275       else if (unformat (line_input, "remote %U",
10276                          unformat_ip4_address, &remote4))
10277         {
10278           remote_set = 1;
10279           ipv4_set = 1;
10280         }
10281       else if (unformat (line_input, "local %U",
10282                          unformat_ip6_address, &local6))
10283         {
10284           local_set = 1;
10285           ipv6_set = 1;
10286         }
10287       else if (unformat (line_input, "remote %U",
10288                          unformat_ip6_address, &remote6))
10289         {
10290           remote_set = 1;
10291           ipv6_set = 1;
10292         }
10293       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10294         ;
10295       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10296         ;
10297       else if (unformat (line_input, "vni %d", &vni))
10298         vni_set = 1;
10299       else if (unformat (line_input, "next-ip4"))
10300         protocol = 1;
10301       else if (unformat (line_input, "next-ip6"))
10302         protocol = 2;
10303       else if (unformat (line_input, "next-ethernet"))
10304         protocol = 3;
10305       else if (unformat (line_input, "next-nsh"))
10306         protocol = 4;
10307       else
10308         {
10309           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10310           return -99;
10311         }
10312     }
10313
10314   if (local_set == 0)
10315     {
10316       errmsg ("tunnel local address not specified\n");
10317       return -99;
10318     }
10319   if (remote_set == 0)
10320     {
10321       errmsg ("tunnel remote address not specified\n");
10322       return -99;
10323     }
10324   if (ipv4_set && ipv6_set)
10325     {
10326       errmsg ("both IPv4 and IPv6 addresses specified");
10327       return -99;
10328     }
10329
10330   if (vni_set == 0)
10331     {
10332       errmsg ("vni not specified\n");
10333       return -99;
10334     }
10335
10336   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10337
10338
10339   if (ipv6_set)
10340     {
10341       clib_memcpy (&mp->local, &local6, sizeof (local6));
10342       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10343     }
10344   else
10345     {
10346       clib_memcpy (&mp->local, &local4, sizeof (local4));
10347       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10348     }
10349
10350   mp->encap_vrf_id = ntohl (encap_vrf_id);
10351   mp->decap_vrf_id = ntohl (decap_vrf_id);
10352   mp->protocol = ntohl (protocol);
10353   mp->vni = ntohl (vni);
10354   mp->is_add = is_add;
10355   mp->is_ipv6 = ipv6_set;
10356
10357   S;
10358   W;
10359   /* NOTREACHED */
10360   return 0;
10361 }
10362
10363 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10364   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10365 {
10366   vat_main_t *vam = &vat_main;
10367
10368   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10369            ntohl (mp->sw_if_index),
10370            format_ip46_address, &(mp->local[0]),
10371            format_ip46_address, &(mp->remote[0]),
10372            ntohl (mp->vni),
10373            ntohl (mp->protocol),
10374            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10375 }
10376
10377 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10378   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10379 {
10380   vat_main_t *vam = &vat_main;
10381   vat_json_node_t *node = NULL;
10382   struct in_addr ip4;
10383   struct in6_addr ip6;
10384
10385   if (VAT_JSON_ARRAY != vam->json_tree.type)
10386     {
10387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10388       vat_json_init_array (&vam->json_tree);
10389     }
10390   node = vat_json_array_add (&vam->json_tree);
10391
10392   vat_json_init_object (node);
10393   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10394   if (mp->is_ipv6)
10395     {
10396       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10397       vat_json_object_add_ip6 (node, "local", ip6);
10398       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10399       vat_json_object_add_ip6 (node, "remote", ip6);
10400     }
10401   else
10402     {
10403       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10404       vat_json_object_add_ip4 (node, "local", ip4);
10405       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10406       vat_json_object_add_ip4 (node, "remote", ip4);
10407     }
10408   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10409   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10410   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10411   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10412   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10413 }
10414
10415 static int
10416 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10417 {
10418   unformat_input_t *i = vam->input;
10419   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10420   f64 timeout;
10421   u32 sw_if_index;
10422   u8 sw_if_index_set = 0;
10423
10424   /* Parse args required to build the message */
10425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10426     {
10427       if (unformat (i, "sw_if_index %d", &sw_if_index))
10428         sw_if_index_set = 1;
10429       else
10430         break;
10431     }
10432
10433   if (sw_if_index_set == 0)
10434     {
10435       sw_if_index = ~0;
10436     }
10437
10438   if (!vam->json_output)
10439     {
10440       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10441                "sw_if_index", "local", "remote", "vni",
10442                "protocol", "encap_vrf_id", "decap_vrf_id");
10443     }
10444
10445   /* Get list of vxlan-tunnel interfaces */
10446   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10447
10448   mp->sw_if_index = htonl (sw_if_index);
10449
10450   S;
10451
10452   /* Use a control ping for synchronization */
10453   {
10454     vl_api_control_ping_t *mp;
10455     M (CONTROL_PING, control_ping);
10456     S;
10457   }
10458   W;
10459 }
10460
10461 u8 *
10462 format_l2_fib_mac_address (u8 * s, va_list * args)
10463 {
10464   u8 *a = va_arg (*args, u8 *);
10465
10466   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10467                  a[2], a[3], a[4], a[5], a[6], a[7]);
10468 }
10469
10470 static void vl_api_l2_fib_table_entry_t_handler
10471   (vl_api_l2_fib_table_entry_t * mp)
10472 {
10473   vat_main_t *vam = &vat_main;
10474
10475   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10476            "       %d       %d     %d\n",
10477            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10478            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10479            mp->bvi_mac);
10480 }
10481
10482 static void vl_api_l2_fib_table_entry_t_handler_json
10483   (vl_api_l2_fib_table_entry_t * mp)
10484 {
10485   vat_main_t *vam = &vat_main;
10486   vat_json_node_t *node = NULL;
10487
10488   if (VAT_JSON_ARRAY != vam->json_tree.type)
10489     {
10490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10491       vat_json_init_array (&vam->json_tree);
10492     }
10493   node = vat_json_array_add (&vam->json_tree);
10494
10495   vat_json_init_object (node);
10496   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10497   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10498   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10499   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10500   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10501   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10502 }
10503
10504 static int
10505 api_l2_fib_table_dump (vat_main_t * vam)
10506 {
10507   unformat_input_t *i = vam->input;
10508   vl_api_l2_fib_table_dump_t *mp;
10509   f64 timeout;
10510   u32 bd_id;
10511   u8 bd_id_set = 0;
10512
10513   /* Parse args required to build the message */
10514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (unformat (i, "bd_id %d", &bd_id))
10517         bd_id_set = 1;
10518       else
10519         break;
10520     }
10521
10522   if (bd_id_set == 0)
10523     {
10524       errmsg ("missing bridge domain\n");
10525       return -99;
10526     }
10527
10528   fformat (vam->ofp,
10529            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10530
10531   /* Get list of l2 fib entries */
10532   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10533
10534   mp->bd_id = ntohl (bd_id);
10535   S;
10536
10537   /* Use a control ping for synchronization */
10538   {
10539     vl_api_control_ping_t *mp;
10540     M (CONTROL_PING, control_ping);
10541     S;
10542   }
10543   W;
10544 }
10545
10546
10547 static int
10548 api_interface_name_renumber (vat_main_t * vam)
10549 {
10550   unformat_input_t *line_input = vam->input;
10551   vl_api_interface_name_renumber_t *mp;
10552   u32 sw_if_index = ~0;
10553   f64 timeout;
10554   u32 new_show_dev_instance = ~0;
10555
10556   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10557     {
10558       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10559                     &sw_if_index))
10560         ;
10561       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10562         ;
10563       else if (unformat (line_input, "new_show_dev_instance %d",
10564                          &new_show_dev_instance))
10565         ;
10566       else
10567         break;
10568     }
10569
10570   if (sw_if_index == ~0)
10571     {
10572       errmsg ("missing interface name or sw_if_index\n");
10573       return -99;
10574     }
10575
10576   if (new_show_dev_instance == ~0)
10577     {
10578       errmsg ("missing new_show_dev_instance\n");
10579       return -99;
10580     }
10581
10582   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10583
10584   mp->sw_if_index = ntohl (sw_if_index);
10585   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10586
10587   S;
10588   W;
10589 }
10590
10591 static int
10592 api_want_ip4_arp_events (vat_main_t * vam)
10593 {
10594   unformat_input_t *line_input = vam->input;
10595   vl_api_want_ip4_arp_events_t *mp;
10596   f64 timeout;
10597   ip4_address_t address;
10598   int address_set = 0;
10599   u32 enable_disable = 1;
10600
10601   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10602     {
10603       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10604         address_set = 1;
10605       else if (unformat (line_input, "del"))
10606         enable_disable = 0;
10607       else
10608         break;
10609     }
10610
10611   if (address_set == 0)
10612     {
10613       errmsg ("missing addresses\n");
10614       return -99;
10615     }
10616
10617   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10618   mp->enable_disable = enable_disable;
10619   mp->pid = getpid ();
10620   mp->address = address.as_u32;
10621
10622   S;
10623   W;
10624 }
10625
10626 static int
10627 api_want_ip6_nd_events (vat_main_t * vam)
10628 {
10629   unformat_input_t *line_input = vam->input;
10630   vl_api_want_ip6_nd_events_t *mp;
10631   f64 timeout;
10632   ip6_address_t address;
10633   int address_set = 0;
10634   u32 enable_disable = 1;
10635
10636   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10637     {
10638       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10639         address_set = 1;
10640       else if (unformat (line_input, "del"))
10641         enable_disable = 0;
10642       else
10643         break;
10644     }
10645
10646   if (address_set == 0)
10647     {
10648       errmsg ("missing addresses\n");
10649       return -99;
10650     }
10651
10652   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10653   mp->enable_disable = enable_disable;
10654   mp->pid = getpid ();
10655   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10656
10657   S;
10658   W;
10659 }
10660
10661 static int
10662 api_input_acl_set_interface (vat_main_t * vam)
10663 {
10664   unformat_input_t *i = vam->input;
10665   vl_api_input_acl_set_interface_t *mp;
10666   f64 timeout;
10667   u32 sw_if_index;
10668   int sw_if_index_set;
10669   u32 ip4_table_index = ~0;
10670   u32 ip6_table_index = ~0;
10671   u32 l2_table_index = ~0;
10672   u8 is_add = 1;
10673
10674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10675     {
10676       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10677         sw_if_index_set = 1;
10678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10679         sw_if_index_set = 1;
10680       else if (unformat (i, "del"))
10681         is_add = 0;
10682       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10683         ;
10684       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10685         ;
10686       else if (unformat (i, "l2-table %d", &l2_table_index))
10687         ;
10688       else
10689         {
10690           clib_warning ("parse error '%U'", format_unformat_error, i);
10691           return -99;
10692         }
10693     }
10694
10695   if (sw_if_index_set == 0)
10696     {
10697       errmsg ("missing interface name or sw_if_index\n");
10698       return -99;
10699     }
10700
10701   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10702
10703   mp->sw_if_index = ntohl (sw_if_index);
10704   mp->ip4_table_index = ntohl (ip4_table_index);
10705   mp->ip6_table_index = ntohl (ip6_table_index);
10706   mp->l2_table_index = ntohl (l2_table_index);
10707   mp->is_add = is_add;
10708
10709   S;
10710   W;
10711   /* NOTREACHED */
10712   return 0;
10713 }
10714
10715 static int
10716 api_ip_address_dump (vat_main_t * vam)
10717 {
10718   unformat_input_t *i = vam->input;
10719   vl_api_ip_address_dump_t *mp;
10720   u32 sw_if_index = ~0;
10721   u8 sw_if_index_set = 0;
10722   u8 ipv4_set = 0;
10723   u8 ipv6_set = 0;
10724   f64 timeout;
10725
10726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10727     {
10728       if (unformat (i, "sw_if_index %d", &sw_if_index))
10729         sw_if_index_set = 1;
10730       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10731         sw_if_index_set = 1;
10732       else if (unformat (i, "ipv4"))
10733         ipv4_set = 1;
10734       else if (unformat (i, "ipv6"))
10735         ipv6_set = 1;
10736       else
10737         break;
10738     }
10739
10740   if (ipv4_set && ipv6_set)
10741     {
10742       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10743       return -99;
10744     }
10745
10746   if ((!ipv4_set) && (!ipv6_set))
10747     {
10748       errmsg ("no ipv4 nor ipv6 flag set\n");
10749       return -99;
10750     }
10751
10752   if (sw_if_index_set == 0)
10753     {
10754       errmsg ("missing interface name or sw_if_index\n");
10755       return -99;
10756     }
10757
10758   vam->current_sw_if_index = sw_if_index;
10759   vam->is_ipv6 = ipv6_set;
10760
10761   M (IP_ADDRESS_DUMP, ip_address_dump);
10762   mp->sw_if_index = ntohl (sw_if_index);
10763   mp->is_ipv6 = ipv6_set;
10764   S;
10765
10766   /* Use a control ping for synchronization */
10767   {
10768     vl_api_control_ping_t *mp;
10769     M (CONTROL_PING, control_ping);
10770     S;
10771   }
10772   W;
10773 }
10774
10775 static int
10776 api_ip_dump (vat_main_t * vam)
10777 {
10778   vl_api_ip_dump_t *mp;
10779   unformat_input_t *in = vam->input;
10780   int ipv4_set = 0;
10781   int ipv6_set = 0;
10782   int is_ipv6;
10783   f64 timeout;
10784   int i;
10785
10786   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10787     {
10788       if (unformat (in, "ipv4"))
10789         ipv4_set = 1;
10790       else if (unformat (in, "ipv6"))
10791         ipv6_set = 1;
10792       else
10793         break;
10794     }
10795
10796   if (ipv4_set && ipv6_set)
10797     {
10798       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10799       return -99;
10800     }
10801
10802   if ((!ipv4_set) && (!ipv6_set))
10803     {
10804       errmsg ("no ipv4 nor ipv6 flag set\n");
10805       return -99;
10806     }
10807
10808   is_ipv6 = ipv6_set;
10809   vam->is_ipv6 = is_ipv6;
10810
10811   /* free old data */
10812   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10813     {
10814       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10815     }
10816   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10817
10818   M (IP_DUMP, ip_dump);
10819   mp->is_ipv6 = ipv6_set;
10820   S;
10821
10822   /* Use a control ping for synchronization */
10823   {
10824     vl_api_control_ping_t *mp;
10825     M (CONTROL_PING, control_ping);
10826     S;
10827   }
10828   W;
10829 }
10830
10831 static int
10832 api_ipsec_spd_add_del (vat_main_t * vam)
10833 {
10834 #if DPDK > 0
10835   unformat_input_t *i = vam->input;
10836   vl_api_ipsec_spd_add_del_t *mp;
10837   f64 timeout;
10838   u32 spd_id = ~0;
10839   u8 is_add = 1;
10840
10841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10842     {
10843       if (unformat (i, "spd_id %d", &spd_id))
10844         ;
10845       else if (unformat (i, "del"))
10846         is_add = 0;
10847       else
10848         {
10849           clib_warning ("parse error '%U'", format_unformat_error, i);
10850           return -99;
10851         }
10852     }
10853   if (spd_id == ~0)
10854     {
10855       errmsg ("spd_id must be set\n");
10856       return -99;
10857     }
10858
10859   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10860
10861   mp->spd_id = ntohl (spd_id);
10862   mp->is_add = is_add;
10863
10864   S;
10865   W;
10866   /* NOTREACHED */
10867   return 0;
10868 #else
10869   clib_warning ("unsupported (no dpdk)");
10870   return -99;
10871 #endif
10872 }
10873
10874 static int
10875 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10876 {
10877 #if DPDK > 0
10878   unformat_input_t *i = vam->input;
10879   vl_api_ipsec_interface_add_del_spd_t *mp;
10880   f64 timeout;
10881   u32 sw_if_index;
10882   u8 sw_if_index_set = 0;
10883   u32 spd_id = (u32) ~ 0;
10884   u8 is_add = 1;
10885
10886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10887     {
10888       if (unformat (i, "del"))
10889         is_add = 0;
10890       else if (unformat (i, "spd_id %d", &spd_id))
10891         ;
10892       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10893         sw_if_index_set = 1;
10894       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10895         sw_if_index_set = 1;
10896       else
10897         {
10898           clib_warning ("parse error '%U'", format_unformat_error, i);
10899           return -99;
10900         }
10901
10902     }
10903
10904   if (spd_id == (u32) ~ 0)
10905     {
10906       errmsg ("spd_id must be set\n");
10907       return -99;
10908     }
10909
10910   if (sw_if_index_set == 0)
10911     {
10912       errmsg ("missing interface name or sw_if_index\n");
10913       return -99;
10914     }
10915
10916   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10917
10918   mp->spd_id = ntohl (spd_id);
10919   mp->sw_if_index = ntohl (sw_if_index);
10920   mp->is_add = is_add;
10921
10922   S;
10923   W;
10924   /* NOTREACHED */
10925   return 0;
10926 #else
10927   clib_warning ("unsupported (no dpdk)");
10928   return -99;
10929 #endif
10930 }
10931
10932 static int
10933 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10934 {
10935 #if DPDK > 0
10936   unformat_input_t *i = vam->input;
10937   vl_api_ipsec_spd_add_del_entry_t *mp;
10938   f64 timeout;
10939   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10940   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10941   i32 priority = 0;
10942   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10943   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10944   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10945   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10946
10947   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10948   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10949   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10950   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10951   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10952   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10953
10954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10955     {
10956       if (unformat (i, "del"))
10957         is_add = 0;
10958       if (unformat (i, "outbound"))
10959         is_outbound = 1;
10960       if (unformat (i, "inbound"))
10961         is_outbound = 0;
10962       else if (unformat (i, "spd_id %d", &spd_id))
10963         ;
10964       else if (unformat (i, "sa_id %d", &sa_id))
10965         ;
10966       else if (unformat (i, "priority %d", &priority))
10967         ;
10968       else if (unformat (i, "protocol %d", &protocol))
10969         ;
10970       else if (unformat (i, "lport_start %d", &lport_start))
10971         ;
10972       else if (unformat (i, "lport_stop %d", &lport_stop))
10973         ;
10974       else if (unformat (i, "rport_start %d", &rport_start))
10975         ;
10976       else if (unformat (i, "rport_stop %d", &rport_stop))
10977         ;
10978       else
10979         if (unformat
10980             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10981         {
10982           is_ipv6 = 0;
10983           is_ip_any = 0;
10984         }
10985       else
10986         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10987         {
10988           is_ipv6 = 0;
10989           is_ip_any = 0;
10990         }
10991       else
10992         if (unformat
10993             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10994         {
10995           is_ipv6 = 0;
10996           is_ip_any = 0;
10997         }
10998       else
10999         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11000         {
11001           is_ipv6 = 0;
11002           is_ip_any = 0;
11003         }
11004       else
11005         if (unformat
11006             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11007         {
11008           is_ipv6 = 1;
11009           is_ip_any = 0;
11010         }
11011       else
11012         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11013         {
11014           is_ipv6 = 1;
11015           is_ip_any = 0;
11016         }
11017       else
11018         if (unformat
11019             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11020         {
11021           is_ipv6 = 1;
11022           is_ip_any = 0;
11023         }
11024       else
11025         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11026         {
11027           is_ipv6 = 1;
11028           is_ip_any = 0;
11029         }
11030       else
11031         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11032         {
11033           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11034             {
11035               clib_warning ("unsupported action: 'resolve'");
11036               return -99;
11037             }
11038         }
11039       else
11040         {
11041           clib_warning ("parse error '%U'", format_unformat_error, i);
11042           return -99;
11043         }
11044
11045     }
11046
11047   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11048
11049   mp->spd_id = ntohl (spd_id);
11050   mp->priority = ntohl (priority);
11051   mp->is_outbound = is_outbound;
11052
11053   mp->is_ipv6 = is_ipv6;
11054   if (is_ipv6 || is_ip_any)
11055     {
11056       clib_memcpy (mp->remote_address_start, &raddr6_start,
11057                    sizeof (ip6_address_t));
11058       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11059                    sizeof (ip6_address_t));
11060       clib_memcpy (mp->local_address_start, &laddr6_start,
11061                    sizeof (ip6_address_t));
11062       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11063                    sizeof (ip6_address_t));
11064     }
11065   else
11066     {
11067       clib_memcpy (mp->remote_address_start, &raddr4_start,
11068                    sizeof (ip4_address_t));
11069       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11070                    sizeof (ip4_address_t));
11071       clib_memcpy (mp->local_address_start, &laddr4_start,
11072                    sizeof (ip4_address_t));
11073       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11074                    sizeof (ip4_address_t));
11075     }
11076   mp->protocol = (u8) protocol;
11077   mp->local_port_start = ntohs ((u16) lport_start);
11078   mp->local_port_stop = ntohs ((u16) lport_stop);
11079   mp->remote_port_start = ntohs ((u16) rport_start);
11080   mp->remote_port_stop = ntohs ((u16) rport_stop);
11081   mp->policy = (u8) policy;
11082   mp->sa_id = ntohl (sa_id);
11083   mp->is_add = is_add;
11084   mp->is_ip_any = is_ip_any;
11085   S;
11086   W;
11087   /* NOTREACHED */
11088   return 0;
11089 #else
11090   clib_warning ("unsupported (no dpdk)");
11091   return -99;
11092 #endif
11093 }
11094
11095 static int
11096 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11097 {
11098 #if DPDK > 0
11099   unformat_input_t *i = vam->input;
11100   vl_api_ipsec_sad_add_del_entry_t *mp;
11101   f64 timeout;
11102   u32 sad_id = 0, spi = 0;
11103   u8 *ck = 0, *ik = 0;
11104   u8 is_add = 1;
11105
11106   u8 protocol = IPSEC_PROTOCOL_AH;
11107   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11108   u32 crypto_alg = 0, integ_alg = 0;
11109   ip4_address_t tun_src4;
11110   ip4_address_t tun_dst4;
11111   ip6_address_t tun_src6;
11112   ip6_address_t tun_dst6;
11113
11114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11115     {
11116       if (unformat (i, "del"))
11117         is_add = 0;
11118       else if (unformat (i, "sad_id %d", &sad_id))
11119         ;
11120       else if (unformat (i, "spi %d", &spi))
11121         ;
11122       else if (unformat (i, "esp"))
11123         protocol = IPSEC_PROTOCOL_ESP;
11124       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11125         {
11126           is_tunnel = 1;
11127           is_tunnel_ipv6 = 0;
11128         }
11129       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11130         {
11131           is_tunnel = 1;
11132           is_tunnel_ipv6 = 0;
11133         }
11134       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11135         {
11136           is_tunnel = 1;
11137           is_tunnel_ipv6 = 1;
11138         }
11139       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11140         {
11141           is_tunnel = 1;
11142           is_tunnel_ipv6 = 1;
11143         }
11144       else
11145         if (unformat
11146             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11147         {
11148           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11149               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11150             {
11151               clib_warning ("unsupported crypto-alg: '%U'",
11152                             format_ipsec_crypto_alg, crypto_alg);
11153               return -99;
11154             }
11155         }
11156       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11157         ;
11158       else
11159         if (unformat
11160             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11161         {
11162           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11163               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11164             {
11165               clib_warning ("unsupported integ-alg: '%U'",
11166                             format_ipsec_integ_alg, integ_alg);
11167               return -99;
11168             }
11169         }
11170       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11171         ;
11172       else
11173         {
11174           clib_warning ("parse error '%U'", format_unformat_error, i);
11175           return -99;
11176         }
11177
11178     }
11179
11180   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11181
11182   mp->sad_id = ntohl (sad_id);
11183   mp->is_add = is_add;
11184   mp->protocol = protocol;
11185   mp->spi = ntohl (spi);
11186   mp->is_tunnel = is_tunnel;
11187   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11188   mp->crypto_algorithm = crypto_alg;
11189   mp->integrity_algorithm = integ_alg;
11190   mp->crypto_key_length = vec_len (ck);
11191   mp->integrity_key_length = vec_len (ik);
11192
11193   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11194     mp->crypto_key_length = sizeof (mp->crypto_key);
11195
11196   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11197     mp->integrity_key_length = sizeof (mp->integrity_key);
11198
11199   if (ck)
11200     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11201   if (ik)
11202     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11203
11204   if (is_tunnel)
11205     {
11206       if (is_tunnel_ipv6)
11207         {
11208           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11209                        sizeof (ip6_address_t));
11210           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11211                        sizeof (ip6_address_t));
11212         }
11213       else
11214         {
11215           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11216                        sizeof (ip4_address_t));
11217           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11218                        sizeof (ip4_address_t));
11219         }
11220     }
11221
11222   S;
11223   W;
11224   /* NOTREACHED */
11225   return 0;
11226 #else
11227   clib_warning ("unsupported (no dpdk)");
11228   return -99;
11229 #endif
11230 }
11231
11232 static int
11233 api_ipsec_sa_set_key (vat_main_t * vam)
11234 {
11235 #if DPDK > 0
11236   unformat_input_t *i = vam->input;
11237   vl_api_ipsec_sa_set_key_t *mp;
11238   f64 timeout;
11239   u32 sa_id;
11240   u8 *ck = 0, *ik = 0;
11241
11242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11243     {
11244       if (unformat (i, "sa_id %d", &sa_id))
11245         ;
11246       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11247         ;
11248       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11249         ;
11250       else
11251         {
11252           clib_warning ("parse error '%U'", format_unformat_error, i);
11253           return -99;
11254         }
11255     }
11256
11257   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11258
11259   mp->sa_id = ntohl (sa_id);
11260   mp->crypto_key_length = vec_len (ck);
11261   mp->integrity_key_length = vec_len (ik);
11262
11263   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11264     mp->crypto_key_length = sizeof (mp->crypto_key);
11265
11266   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11267     mp->integrity_key_length = sizeof (mp->integrity_key);
11268
11269   if (ck)
11270     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11271   if (ik)
11272     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11273
11274   S;
11275   W;
11276   /* NOTREACHED */
11277   return 0;
11278 #else
11279   clib_warning ("unsupported (no dpdk)");
11280   return -99;
11281 #endif
11282 }
11283
11284 static int
11285 api_ikev2_profile_add_del (vat_main_t * vam)
11286 {
11287 #if DPDK > 0
11288   unformat_input_t *i = vam->input;
11289   vl_api_ikev2_profile_add_del_t *mp;
11290   f64 timeout;
11291   u8 is_add = 1;
11292   u8 *name = 0;
11293
11294   const char *valid_chars = "a-zA-Z0-9_";
11295
11296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11297     {
11298       if (unformat (i, "del"))
11299         is_add = 0;
11300       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11301         vec_add1 (name, 0);
11302       else
11303         {
11304           errmsg ("parse error '%U'", format_unformat_error, i);
11305           return -99;
11306         }
11307     }
11308
11309   if (!vec_len (name))
11310     {
11311       errmsg ("profile name must be specified");
11312       return -99;
11313     }
11314
11315   if (vec_len (name) > 64)
11316     {
11317       errmsg ("profile name too long");
11318       return -99;
11319     }
11320
11321   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11322
11323   clib_memcpy (mp->name, name, vec_len (name));
11324   mp->is_add = is_add;
11325   vec_free (name);
11326
11327   S;
11328   W;
11329   /* NOTREACHED */
11330   return 0;
11331 #else
11332   clib_warning ("unsupported (no dpdk)");
11333   return -99;
11334 #endif
11335 }
11336
11337 static int
11338 api_ikev2_profile_set_auth (vat_main_t * vam)
11339 {
11340 #if DPDK > 0
11341   unformat_input_t *i = vam->input;
11342   vl_api_ikev2_profile_set_auth_t *mp;
11343   f64 timeout;
11344   u8 *name = 0;
11345   u8 *data = 0;
11346   u32 auth_method = 0;
11347   u8 is_hex = 0;
11348
11349   const char *valid_chars = "a-zA-Z0-9_";
11350
11351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11354         vec_add1 (name, 0);
11355       else if (unformat (i, "auth_method %U",
11356                          unformat_ikev2_auth_method, &auth_method))
11357         ;
11358       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11359         is_hex = 1;
11360       else if (unformat (i, "auth_data %v", &data))
11361         ;
11362       else
11363         {
11364           errmsg ("parse error '%U'", format_unformat_error, i);
11365           return -99;
11366         }
11367     }
11368
11369   if (!vec_len (name))
11370     {
11371       errmsg ("profile name must be specified");
11372       return -99;
11373     }
11374
11375   if (vec_len (name) > 64)
11376     {
11377       errmsg ("profile name too long");
11378       return -99;
11379     }
11380
11381   if (!vec_len (data))
11382     {
11383       errmsg ("auth_data must be specified");
11384       return -99;
11385     }
11386
11387   if (!auth_method)
11388     {
11389       errmsg ("auth_method must be specified");
11390       return -99;
11391     }
11392
11393   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11394
11395   mp->is_hex = is_hex;
11396   mp->auth_method = (u8) auth_method;
11397   mp->data_len = vec_len (data);
11398   clib_memcpy (mp->name, name, vec_len (name));
11399   clib_memcpy (mp->data, data, vec_len (data));
11400   vec_free (name);
11401   vec_free (data);
11402
11403   S;
11404   W;
11405   /* NOTREACHED */
11406   return 0;
11407 #else
11408   clib_warning ("unsupported (no dpdk)");
11409   return -99;
11410 #endif
11411 }
11412
11413 static int
11414 api_ikev2_profile_set_id (vat_main_t * vam)
11415 {
11416 #if DPDK > 0
11417   unformat_input_t *i = vam->input;
11418   vl_api_ikev2_profile_set_id_t *mp;
11419   f64 timeout;
11420   u8 *name = 0;
11421   u8 *data = 0;
11422   u8 is_local = 0;
11423   u32 id_type = 0;
11424   ip4_address_t ip4;
11425
11426   const char *valid_chars = "a-zA-Z0-9_";
11427
11428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11429     {
11430       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11431         vec_add1 (name, 0);
11432       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11433         ;
11434       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11435         {
11436           data = vec_new (u8, 4);
11437           clib_memcpy (data, ip4.as_u8, 4);
11438         }
11439       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11440         ;
11441       else if (unformat (i, "id_data %v", &data))
11442         ;
11443       else if (unformat (i, "local"))
11444         is_local = 1;
11445       else if (unformat (i, "remote"))
11446         is_local = 0;
11447       else
11448         {
11449           errmsg ("parse error '%U'", format_unformat_error, i);
11450           return -99;
11451         }
11452     }
11453
11454   if (!vec_len (name))
11455     {
11456       errmsg ("profile name must be specified");
11457       return -99;
11458     }
11459
11460   if (vec_len (name) > 64)
11461     {
11462       errmsg ("profile name too long");
11463       return -99;
11464     }
11465
11466   if (!vec_len (data))
11467     {
11468       errmsg ("id_data must be specified");
11469       return -99;
11470     }
11471
11472   if (!id_type)
11473     {
11474       errmsg ("id_type must be specified");
11475       return -99;
11476     }
11477
11478   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11479
11480   mp->is_local = is_local;
11481   mp->id_type = (u8) id_type;
11482   mp->data_len = vec_len (data);
11483   clib_memcpy (mp->name, name, vec_len (name));
11484   clib_memcpy (mp->data, data, vec_len (data));
11485   vec_free (name);
11486   vec_free (data);
11487
11488   S;
11489   W;
11490   /* NOTREACHED */
11491   return 0;
11492 #else
11493   clib_warning ("unsupported (no dpdk)");
11494   return -99;
11495 #endif
11496 }
11497
11498 static int
11499 api_ikev2_profile_set_ts (vat_main_t * vam)
11500 {
11501 #if DPDK > 0
11502   unformat_input_t *i = vam->input;
11503   vl_api_ikev2_profile_set_ts_t *mp;
11504   f64 timeout;
11505   u8 *name = 0;
11506   u8 is_local = 0;
11507   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11508   ip4_address_t start_addr, end_addr;
11509
11510   const char *valid_chars = "a-zA-Z0-9_";
11511
11512   start_addr.as_u32 = 0;
11513   end_addr.as_u32 = (u32) ~ 0;
11514
11515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11516     {
11517       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11518         vec_add1 (name, 0);
11519       else if (unformat (i, "protocol %d", &proto))
11520         ;
11521       else if (unformat (i, "start_port %d", &start_port))
11522         ;
11523       else if (unformat (i, "end_port %d", &end_port))
11524         ;
11525       else
11526         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11527         ;
11528       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11529         ;
11530       else if (unformat (i, "local"))
11531         is_local = 1;
11532       else if (unformat (i, "remote"))
11533         is_local = 0;
11534       else
11535         {
11536           errmsg ("parse error '%U'", format_unformat_error, i);
11537           return -99;
11538         }
11539     }
11540
11541   if (!vec_len (name))
11542     {
11543       errmsg ("profile name must be specified");
11544       return -99;
11545     }
11546
11547   if (vec_len (name) > 64)
11548     {
11549       errmsg ("profile name too long");
11550       return -99;
11551     }
11552
11553   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11554
11555   mp->is_local = is_local;
11556   mp->proto = (u8) proto;
11557   mp->start_port = (u16) start_port;
11558   mp->end_port = (u16) end_port;
11559   mp->start_addr = start_addr.as_u32;
11560   mp->end_addr = end_addr.as_u32;
11561   clib_memcpy (mp->name, name, vec_len (name));
11562   vec_free (name);
11563
11564   S;
11565   W;
11566   /* NOTREACHED */
11567   return 0;
11568 #else
11569   clib_warning ("unsupported (no dpdk)");
11570   return -99;
11571 #endif
11572 }
11573
11574 static int
11575 api_ikev2_set_local_key (vat_main_t * vam)
11576 {
11577 #if DPDK > 0
11578   unformat_input_t *i = vam->input;
11579   vl_api_ikev2_set_local_key_t *mp;
11580   f64 timeout;
11581   u8 *file = 0;
11582
11583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11584     {
11585       if (unformat (i, "file %v", &file))
11586         vec_add1 (file, 0);
11587       else
11588         {
11589           errmsg ("parse error '%U'", format_unformat_error, i);
11590           return -99;
11591         }
11592     }
11593
11594   if (!vec_len (file))
11595     {
11596       errmsg ("RSA key file must be specified");
11597       return -99;
11598     }
11599
11600   if (vec_len (file) > 256)
11601     {
11602       errmsg ("file name too long");
11603       return -99;
11604     }
11605
11606   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11607
11608   clib_memcpy (mp->key_file, file, vec_len (file));
11609   vec_free (file);
11610
11611   S;
11612   W;
11613   /* NOTREACHED */
11614   return 0;
11615 #else
11616   clib_warning ("unsupported (no dpdk)");
11617   return -99;
11618 #endif
11619 }
11620
11621 /*
11622  * MAP
11623  */
11624 static int
11625 api_map_add_domain (vat_main_t * vam)
11626 {
11627   unformat_input_t *i = vam->input;
11628   vl_api_map_add_domain_t *mp;
11629   f64 timeout;
11630
11631   ip4_address_t ip4_prefix;
11632   ip6_address_t ip6_prefix;
11633   ip6_address_t ip6_src;
11634   u32 num_m_args = 0;
11635   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11636     0, psid_length = 0;
11637   u8 is_translation = 0;
11638   u32 mtu = 0;
11639   u32 ip6_src_len = 128;
11640
11641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11642     {
11643       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11644                     &ip4_prefix, &ip4_prefix_len))
11645         num_m_args++;
11646       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11647                          &ip6_prefix, &ip6_prefix_len))
11648         num_m_args++;
11649       else
11650         if (unformat
11651             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11652              &ip6_src_len))
11653         num_m_args++;
11654       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11655         num_m_args++;
11656       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11657         num_m_args++;
11658       else if (unformat (i, "psid-offset %d", &psid_offset))
11659         num_m_args++;
11660       else if (unformat (i, "psid-len %d", &psid_length))
11661         num_m_args++;
11662       else if (unformat (i, "mtu %d", &mtu))
11663         num_m_args++;
11664       else if (unformat (i, "map-t"))
11665         is_translation = 1;
11666       else
11667         {
11668           clib_warning ("parse error '%U'", format_unformat_error, i);
11669           return -99;
11670         }
11671     }
11672
11673   if (num_m_args < 3)
11674     {
11675       errmsg ("mandatory argument(s) missing\n");
11676       return -99;
11677     }
11678
11679   /* Construct the API message */
11680   M (MAP_ADD_DOMAIN, map_add_domain);
11681
11682   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11683   mp->ip4_prefix_len = ip4_prefix_len;
11684
11685   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11686   mp->ip6_prefix_len = ip6_prefix_len;
11687
11688   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11689   mp->ip6_src_prefix_len = ip6_src_len;
11690
11691   mp->ea_bits_len = ea_bits_len;
11692   mp->psid_offset = psid_offset;
11693   mp->psid_length = psid_length;
11694   mp->is_translation = is_translation;
11695   mp->mtu = htons (mtu);
11696
11697   /* send it... */
11698   S;
11699
11700   /* Wait for a reply, return good/bad news  */
11701   W;
11702 }
11703
11704 static int
11705 api_map_del_domain (vat_main_t * vam)
11706 {
11707   unformat_input_t *i = vam->input;
11708   vl_api_map_del_domain_t *mp;
11709   f64 timeout;
11710
11711   u32 num_m_args = 0;
11712   u32 index;
11713
11714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11715     {
11716       if (unformat (i, "index %d", &index))
11717         num_m_args++;
11718       else
11719         {
11720           clib_warning ("parse error '%U'", format_unformat_error, i);
11721           return -99;
11722         }
11723     }
11724
11725   if (num_m_args != 1)
11726     {
11727       errmsg ("mandatory argument(s) missing\n");
11728       return -99;
11729     }
11730
11731   /* Construct the API message */
11732   M (MAP_DEL_DOMAIN, map_del_domain);
11733
11734   mp->index = ntohl (index);
11735
11736   /* send it... */
11737   S;
11738
11739   /* Wait for a reply, return good/bad news  */
11740   W;
11741 }
11742
11743 static int
11744 api_map_add_del_rule (vat_main_t * vam)
11745 {
11746   unformat_input_t *i = vam->input;
11747   vl_api_map_add_del_rule_t *mp;
11748   f64 timeout;
11749   u8 is_add = 1;
11750   ip6_address_t ip6_dst;
11751   u32 num_m_args = 0, index, psid = 0;
11752
11753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11754     {
11755       if (unformat (i, "index %d", &index))
11756         num_m_args++;
11757       else if (unformat (i, "psid %d", &psid))
11758         num_m_args++;
11759       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11760         num_m_args++;
11761       else if (unformat (i, "del"))
11762         {
11763           is_add = 0;
11764         }
11765       else
11766         {
11767           clib_warning ("parse error '%U'", format_unformat_error, i);
11768           return -99;
11769         }
11770     }
11771
11772   /* Construct the API message */
11773   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11774
11775   mp->index = ntohl (index);
11776   mp->is_add = is_add;
11777   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11778   mp->psid = ntohs (psid);
11779
11780   /* send it... */
11781   S;
11782
11783   /* Wait for a reply, return good/bad news  */
11784   W;
11785 }
11786
11787 static int
11788 api_map_domain_dump (vat_main_t * vam)
11789 {
11790   vl_api_map_domain_dump_t *mp;
11791   f64 timeout;
11792
11793   /* Construct the API message */
11794   M (MAP_DOMAIN_DUMP, map_domain_dump);
11795
11796   /* send it... */
11797   S;
11798
11799   /* Use a control ping for synchronization */
11800   {
11801     vl_api_control_ping_t *mp;
11802     M (CONTROL_PING, control_ping);
11803     S;
11804   }
11805   W;
11806 }
11807
11808 static int
11809 api_map_rule_dump (vat_main_t * vam)
11810 {
11811   unformat_input_t *i = vam->input;
11812   vl_api_map_rule_dump_t *mp;
11813   f64 timeout;
11814   u32 domain_index = ~0;
11815
11816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11817     {
11818       if (unformat (i, "index %u", &domain_index))
11819         ;
11820       else
11821         break;
11822     }
11823
11824   if (domain_index == ~0)
11825     {
11826       clib_warning ("parse error: domain index expected");
11827       return -99;
11828     }
11829
11830   /* Construct the API message */
11831   M (MAP_RULE_DUMP, map_rule_dump);
11832
11833   mp->domain_index = htonl (domain_index);
11834
11835   /* send it... */
11836   S;
11837
11838   /* Use a control ping for synchronization */
11839   {
11840     vl_api_control_ping_t *mp;
11841     M (CONTROL_PING, control_ping);
11842     S;
11843   }
11844   W;
11845 }
11846
11847 static void vl_api_map_add_domain_reply_t_handler
11848   (vl_api_map_add_domain_reply_t * mp)
11849 {
11850   vat_main_t *vam = &vat_main;
11851   i32 retval = ntohl (mp->retval);
11852
11853   if (vam->async_mode)
11854     {
11855       vam->async_errors += (retval < 0);
11856     }
11857   else
11858     {
11859       vam->retval = retval;
11860       vam->result_ready = 1;
11861     }
11862 }
11863
11864 static void vl_api_map_add_domain_reply_t_handler_json
11865   (vl_api_map_add_domain_reply_t * mp)
11866 {
11867   vat_main_t *vam = &vat_main;
11868   vat_json_node_t node;
11869
11870   vat_json_init_object (&node);
11871   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11872   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11873
11874   vat_json_print (vam->ofp, &node);
11875   vat_json_free (&node);
11876
11877   vam->retval = ntohl (mp->retval);
11878   vam->result_ready = 1;
11879 }
11880
11881 static int
11882 api_get_first_msg_id (vat_main_t * vam)
11883 {
11884   vl_api_get_first_msg_id_t *mp;
11885   f64 timeout;
11886   unformat_input_t *i = vam->input;
11887   u8 *name;
11888   u8 name_set = 0;
11889
11890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11891     {
11892       if (unformat (i, "client %s", &name))
11893         name_set = 1;
11894       else
11895         break;
11896     }
11897
11898   if (name_set == 0)
11899     {
11900       errmsg ("missing client name\n");
11901       return -99;
11902     }
11903   vec_add1 (name, 0);
11904
11905   if (vec_len (name) > 63)
11906     {
11907       errmsg ("client name too long\n");
11908       return -99;
11909     }
11910
11911   M (GET_FIRST_MSG_ID, get_first_msg_id);
11912   clib_memcpy (mp->name, name, vec_len (name));
11913   S;
11914   W;
11915   /* NOTREACHED */
11916   return 0;
11917 }
11918
11919 static int
11920 api_cop_interface_enable_disable (vat_main_t * vam)
11921 {
11922   unformat_input_t *line_input = vam->input;
11923   vl_api_cop_interface_enable_disable_t *mp;
11924   f64 timeout;
11925   u32 sw_if_index = ~0;
11926   u8 enable_disable = 1;
11927
11928   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11929     {
11930       if (unformat (line_input, "disable"))
11931         enable_disable = 0;
11932       if (unformat (line_input, "enable"))
11933         enable_disable = 1;
11934       else if (unformat (line_input, "%U", unformat_sw_if_index,
11935                          vam, &sw_if_index))
11936         ;
11937       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11938         ;
11939       else
11940         break;
11941     }
11942
11943   if (sw_if_index == ~0)
11944     {
11945       errmsg ("missing interface name or sw_if_index\n");
11946       return -99;
11947     }
11948
11949   /* Construct the API message */
11950   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11951   mp->sw_if_index = ntohl (sw_if_index);
11952   mp->enable_disable = enable_disable;
11953
11954   /* send it... */
11955   S;
11956   /* Wait for the reply */
11957   W;
11958 }
11959
11960 static int
11961 api_cop_whitelist_enable_disable (vat_main_t * vam)
11962 {
11963   unformat_input_t *line_input = vam->input;
11964   vl_api_cop_whitelist_enable_disable_t *mp;
11965   f64 timeout;
11966   u32 sw_if_index = ~0;
11967   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11968   u32 fib_id = 0;
11969
11970   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11971     {
11972       if (unformat (line_input, "ip4"))
11973         ip4 = 1;
11974       else if (unformat (line_input, "ip6"))
11975         ip6 = 1;
11976       else if (unformat (line_input, "default"))
11977         default_cop = 1;
11978       else if (unformat (line_input, "%U", unformat_sw_if_index,
11979                          vam, &sw_if_index))
11980         ;
11981       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11982         ;
11983       else if (unformat (line_input, "fib-id %d", &fib_id))
11984         ;
11985       else
11986         break;
11987     }
11988
11989   if (sw_if_index == ~0)
11990     {
11991       errmsg ("missing interface name or sw_if_index\n");
11992       return -99;
11993     }
11994
11995   /* Construct the API message */
11996   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11997   mp->sw_if_index = ntohl (sw_if_index);
11998   mp->fib_id = ntohl (fib_id);
11999   mp->ip4 = ip4;
12000   mp->ip6 = ip6;
12001   mp->default_cop = default_cop;
12002
12003   /* send it... */
12004   S;
12005   /* Wait for the reply */
12006   W;
12007 }
12008
12009 static int
12010 api_get_node_graph (vat_main_t * vam)
12011 {
12012   vl_api_get_node_graph_t *mp;
12013   f64 timeout;
12014
12015   M (GET_NODE_GRAPH, get_node_graph);
12016
12017   /* send it... */
12018   S;
12019   /* Wait for the reply */
12020   W;
12021 }
12022
12023 /* *INDENT-OFF* */
12024 /** Used for parsing LISP eids */
12025 typedef CLIB_PACKED(struct{
12026   u8 addr[16];   /**< eid address */
12027   u32 len;       /**< prefix length if IP */
12028   u8 type;      /**< type of eid */
12029 }) lisp_eid_vat_t;
12030 /* *INDENT-ON* */
12031
12032 static uword
12033 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12034 {
12035   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12036
12037   memset (a, 0, sizeof (a[0]));
12038
12039   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12040     {
12041       a->type = 0;              /* ipv4 type */
12042     }
12043   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12044     {
12045       a->type = 1;              /* ipv6 type */
12046     }
12047   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12048     {
12049       a->type = 2;              /* mac type */
12050     }
12051   else
12052     {
12053       return 0;
12054     }
12055
12056   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12057     {
12058       return 0;
12059     }
12060
12061   return 1;
12062 }
12063
12064 static int
12065 lisp_eid_size_vat (u8 type)
12066 {
12067   switch (type)
12068     {
12069     case 0:
12070       return 4;
12071     case 1:
12072       return 16;
12073     case 2:
12074       return 6;
12075     }
12076   return 0;
12077 }
12078
12079 static void
12080 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12081 {
12082   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12083 }
12084
12085 /* *INDENT-OFF* */
12086 /** Used for transferring locators via VPP API */
12087 typedef CLIB_PACKED(struct
12088 {
12089   u32 sw_if_index; /**< locator sw_if_index */
12090   u8 priority; /**< locator priority */
12091   u8 weight;   /**< locator weight */
12092 }) ls_locator_t;
12093 /* *INDENT-ON* */
12094
12095 static int
12096 api_lisp_add_del_locator_set (vat_main_t * vam)
12097 {
12098   unformat_input_t *input = vam->input;
12099   vl_api_lisp_add_del_locator_set_t *mp;
12100   f64 timeout = ~0;
12101   u8 is_add = 1;
12102   u8 *locator_set_name = NULL;
12103   u8 locator_set_name_set = 0;
12104   ls_locator_t locator, *locators = 0;
12105   u32 sw_if_index, priority, weight;
12106   u32 data_len = 0;
12107
12108   /* Parse args required to build the message */
12109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (input, "del"))
12112         {
12113           is_add = 0;
12114         }
12115       else if (unformat (input, "locator-set %s", &locator_set_name))
12116         {
12117           locator_set_name_set = 1;
12118         }
12119       else if (unformat (input, "sw_if_index %u p %u w %u",
12120                          &sw_if_index, &priority, &weight))
12121         {
12122           locator.sw_if_index = htonl (sw_if_index);
12123           locator.priority = priority;
12124           locator.weight = weight;
12125           vec_add1 (locators, locator);
12126         }
12127       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12128                          vam, &sw_if_index, &priority, &weight))
12129         {
12130           locator.sw_if_index = htonl (sw_if_index);
12131           locator.priority = priority;
12132           locator.weight = weight;
12133           vec_add1 (locators, locator);
12134         }
12135       else
12136         break;
12137     }
12138
12139   if (locator_set_name_set == 0)
12140     {
12141       errmsg ("missing locator-set name");
12142       vec_free (locators);
12143       return -99;
12144     }
12145
12146   if (vec_len (locator_set_name) > 64)
12147     {
12148       errmsg ("locator-set name too long\n");
12149       vec_free (locator_set_name);
12150       vec_free (locators);
12151       return -99;
12152     }
12153   vec_add1 (locator_set_name, 0);
12154
12155   data_len = sizeof (ls_locator_t) * vec_len (locators);
12156
12157   /* Construct the API message */
12158   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12159
12160   mp->is_add = is_add;
12161   clib_memcpy (mp->locator_set_name, locator_set_name,
12162                vec_len (locator_set_name));
12163   vec_free (locator_set_name);
12164
12165   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12166   if (locators)
12167     clib_memcpy (mp->locators, locators, data_len);
12168   vec_free (locators);
12169
12170   /* send it... */
12171   S;
12172
12173   /* Wait for a reply... */
12174   W;
12175
12176   /* NOTREACHED */
12177   return 0;
12178 }
12179
12180 static int
12181 api_lisp_add_del_locator (vat_main_t * vam)
12182 {
12183   unformat_input_t *input = vam->input;
12184   vl_api_lisp_add_del_locator_t *mp;
12185   f64 timeout = ~0;
12186   u32 tmp_if_index = ~0;
12187   u32 sw_if_index = ~0;
12188   u8 sw_if_index_set = 0;
12189   u8 sw_if_index_if_name_set = 0;
12190   u32 priority = ~0;
12191   u8 priority_set = 0;
12192   u32 weight = ~0;
12193   u8 weight_set = 0;
12194   u8 is_add = 1;
12195   u8 *locator_set_name = NULL;
12196   u8 locator_set_name_set = 0;
12197
12198   /* Parse args required to build the message */
12199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12200     {
12201       if (unformat (input, "del"))
12202         {
12203           is_add = 0;
12204         }
12205       else if (unformat (input, "locator-set %s", &locator_set_name))
12206         {
12207           locator_set_name_set = 1;
12208         }
12209       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12210                          &tmp_if_index))
12211         {
12212           sw_if_index_if_name_set = 1;
12213           sw_if_index = tmp_if_index;
12214         }
12215       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12216         {
12217           sw_if_index_set = 1;
12218           sw_if_index = tmp_if_index;
12219         }
12220       else if (unformat (input, "p %d", &priority))
12221         {
12222           priority_set = 1;
12223         }
12224       else if (unformat (input, "w %d", &weight))
12225         {
12226           weight_set = 1;
12227         }
12228       else
12229         break;
12230     }
12231
12232   if (locator_set_name_set == 0)
12233     {
12234       errmsg ("missing locator-set name");
12235       return -99;
12236     }
12237
12238   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12239     {
12240       errmsg ("missing sw_if_index");
12241       vec_free (locator_set_name);
12242       return -99;
12243     }
12244
12245   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12246     {
12247       errmsg ("cannot use both params interface name and sw_if_index");
12248       vec_free (locator_set_name);
12249       return -99;
12250     }
12251
12252   if (priority_set == 0)
12253     {
12254       errmsg ("missing locator-set priority\n");
12255       vec_free (locator_set_name);
12256       return -99;
12257     }
12258
12259   if (weight_set == 0)
12260     {
12261       errmsg ("missing locator-set weight\n");
12262       vec_free (locator_set_name);
12263       return -99;
12264     }
12265
12266   if (vec_len (locator_set_name) > 64)
12267     {
12268       errmsg ("locator-set name too long\n");
12269       vec_free (locator_set_name);
12270       return -99;
12271     }
12272   vec_add1 (locator_set_name, 0);
12273
12274   /* Construct the API message */
12275   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12276
12277   mp->is_add = is_add;
12278   mp->sw_if_index = ntohl (sw_if_index);
12279   mp->priority = priority;
12280   mp->weight = weight;
12281   clib_memcpy (mp->locator_set_name, locator_set_name,
12282                vec_len (locator_set_name));
12283   vec_free (locator_set_name);
12284
12285   /* send it... */
12286   S;
12287
12288   /* Wait for a reply... */
12289   W;
12290
12291   /* NOTREACHED */
12292   return 0;
12293 }
12294
12295 static int
12296 api_lisp_add_del_local_eid (vat_main_t * vam)
12297 {
12298   unformat_input_t *input = vam->input;
12299   vl_api_lisp_add_del_local_eid_t *mp;
12300   f64 timeout = ~0;
12301   u8 is_add = 1;
12302   u8 eid_set = 0;
12303   lisp_eid_vat_t _eid, *eid = &_eid;
12304   u8 *locator_set_name = 0;
12305   u8 locator_set_name_set = 0;
12306   u32 vni = 0;
12307
12308   /* Parse args required to build the message */
12309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (input, "del"))
12312         {
12313           is_add = 0;
12314         }
12315       else if (unformat (input, "vni %d", &vni))
12316         {
12317           ;
12318         }
12319       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12320         {
12321           eid_set = 1;
12322         }
12323       else if (unformat (input, "locator-set %s", &locator_set_name))
12324         {
12325           locator_set_name_set = 1;
12326         }
12327       else
12328         break;
12329     }
12330
12331   if (locator_set_name_set == 0)
12332     {
12333       errmsg ("missing locator-set name\n");
12334       return -99;
12335     }
12336
12337   if (0 == eid_set)
12338     {
12339       errmsg ("EID address not set!");
12340       vec_free (locator_set_name);
12341       return -99;
12342     }
12343
12344   if (vec_len (locator_set_name) > 64)
12345     {
12346       errmsg ("locator-set name too long\n");
12347       vec_free (locator_set_name);
12348       return -99;
12349     }
12350   vec_add1 (locator_set_name, 0);
12351
12352   /* Construct the API message */
12353   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12354
12355   mp->is_add = is_add;
12356   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12357   mp->eid_type = eid->type;
12358   mp->prefix_len = eid->len;
12359   mp->vni = clib_host_to_net_u32 (vni);
12360   clib_memcpy (mp->locator_set_name, locator_set_name,
12361                vec_len (locator_set_name));
12362
12363   vec_free (locator_set_name);
12364
12365   /* send it... */
12366   S;
12367
12368   /* Wait for a reply... */
12369   W;
12370
12371   /* NOTREACHED */
12372   return 0;
12373 }
12374
12375 /* *INDENT-OFF* */
12376 /** Used for transferring locators via VPP API */
12377 typedef CLIB_PACKED(struct
12378 {
12379   u8 is_ip4; /**< is locator an IPv4 address? */
12380   u8 priority; /**< locator priority */
12381   u8 weight;   /**< locator weight */
12382   u8 addr[16]; /**< IPv4/IPv6 address */
12383 }) rloc_t;
12384 /* *INDENT-ON* */
12385
12386 static int
12387 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12388 {
12389   unformat_input_t *input = vam->input;
12390   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12391   f64 timeout = ~0;
12392   u8 is_add = 1;
12393   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12394   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12395   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12396   u32 action = ~0, p, w;
12397   ip4_address_t rmt_rloc4, lcl_rloc4;
12398   ip6_address_t rmt_rloc6, lcl_rloc6;
12399   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12400
12401   memset (&rloc, 0, sizeof (rloc));
12402
12403   /* Parse args required to build the message */
12404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12405     {
12406       if (unformat (input, "del"))
12407         {
12408           is_add = 0;
12409         }
12410       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12411         {
12412           rmt_eid_set = 1;
12413         }
12414       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12415         {
12416           lcl_eid_set = 1;
12417         }
12418       else if (unformat (input, "p %d w %d", &p, &w))
12419         {
12420           if (!curr_rloc)
12421             {
12422               errmsg ("No RLOC configured for setting priority/weight!");
12423               return -99;
12424             }
12425           curr_rloc->priority = p;
12426           curr_rloc->weight = w;
12427         }
12428       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12429                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12430         {
12431           rloc.is_ip4 = 1;
12432
12433           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12434           rloc.priority = rloc.weight = 0;
12435           vec_add1 (lcl_locs, rloc);
12436
12437           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12438           vec_add1 (rmt_locs, rloc);
12439           /* priority and weight saved in rmt loc */
12440           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12441         }
12442       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12443                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12444         {
12445           rloc.is_ip4 = 0;
12446           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12447           rloc.priority = rloc.weight = 0;
12448           vec_add1 (lcl_locs, rloc);
12449
12450           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12451           vec_add1 (rmt_locs, rloc);
12452           /* priority and weight saved in rmt loc */
12453           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12454         }
12455       else if (unformat (input, "action %d", &action))
12456         {
12457           ;
12458         }
12459       else
12460         {
12461           clib_warning ("parse error '%U'", format_unformat_error, input);
12462           return -99;
12463         }
12464     }
12465
12466   if (!rmt_eid_set)
12467     {
12468       errmsg ("remote eid addresses not set\n");
12469       return -99;
12470     }
12471
12472   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12473     {
12474       errmsg ("eid types don't match\n");
12475       return -99;
12476     }
12477
12478   if (0 == rmt_locs && (u32) ~ 0 == action)
12479     {
12480       errmsg ("action not set for negative mapping\n");
12481       return -99;
12482     }
12483
12484   /* Construct the API message */
12485   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12486
12487   mp->is_add = is_add;
12488   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12489   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12490   mp->eid_type = rmt_eid->type;
12491   mp->rmt_len = rmt_eid->len;
12492   mp->lcl_len = lcl_eid->len;
12493   mp->action = action;
12494
12495   if (0 != rmt_locs && 0 != lcl_locs)
12496     {
12497       mp->loc_num = vec_len (rmt_locs);
12498       clib_memcpy (mp->lcl_locs, lcl_locs,
12499                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12500       clib_memcpy (mp->rmt_locs, rmt_locs,
12501                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12502     }
12503   vec_free (lcl_locs);
12504   vec_free (rmt_locs);
12505
12506   /* send it... */
12507   S;
12508
12509   /* Wait for a reply... */
12510   W;
12511
12512   /* NOTREACHED */
12513   return 0;
12514 }
12515
12516 static int
12517 api_lisp_add_del_map_resolver (vat_main_t * vam)
12518 {
12519   unformat_input_t *input = vam->input;
12520   vl_api_lisp_add_del_map_resolver_t *mp;
12521   f64 timeout = ~0;
12522   u8 is_add = 1;
12523   u8 ipv4_set = 0;
12524   u8 ipv6_set = 0;
12525   ip4_address_t ipv4;
12526   ip6_address_t ipv6;
12527
12528   /* Parse args required to build the message */
12529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12530     {
12531       if (unformat (input, "del"))
12532         {
12533           is_add = 0;
12534         }
12535       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12536         {
12537           ipv4_set = 1;
12538         }
12539       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12540         {
12541           ipv6_set = 1;
12542         }
12543       else
12544         break;
12545     }
12546
12547   if (ipv4_set && ipv6_set)
12548     {
12549       errmsg ("both eid v4 and v6 addresses set\n");
12550       return -99;
12551     }
12552
12553   if (!ipv4_set && !ipv6_set)
12554     {
12555       errmsg ("eid addresses not set\n");
12556       return -99;
12557     }
12558
12559   /* Construct the API message */
12560   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12561
12562   mp->is_add = is_add;
12563   if (ipv6_set)
12564     {
12565       mp->is_ipv6 = 1;
12566       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12567     }
12568   else
12569     {
12570       mp->is_ipv6 = 0;
12571       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12572     }
12573
12574   /* send it... */
12575   S;
12576
12577   /* Wait for a reply... */
12578   W;
12579
12580   /* NOTREACHED */
12581   return 0;
12582 }
12583
12584 static int
12585 api_lisp_gpe_enable_disable (vat_main_t * vam)
12586 {
12587   unformat_input_t *input = vam->input;
12588   vl_api_lisp_gpe_enable_disable_t *mp;
12589   f64 timeout = ~0;
12590   u8 is_set = 0;
12591   u8 is_en = 1;
12592
12593   /* Parse args required to build the message */
12594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12595     {
12596       if (unformat (input, "enable"))
12597         {
12598           is_set = 1;
12599           is_en = 1;
12600         }
12601       else if (unformat (input, "disable"))
12602         {
12603           is_set = 1;
12604           is_en = 0;
12605         }
12606       else
12607         break;
12608     }
12609
12610   if (is_set == 0)
12611     {
12612       errmsg ("Value not set\n");
12613       return -99;
12614     }
12615
12616   /* Construct the API message */
12617   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12618
12619   mp->is_en = is_en;
12620
12621   /* send it... */
12622   S;
12623
12624   /* Wait for a reply... */
12625   W;
12626
12627   /* NOTREACHED */
12628   return 0;
12629 }
12630
12631 static int
12632 api_lisp_enable_disable (vat_main_t * vam)
12633 {
12634   unformat_input_t *input = vam->input;
12635   vl_api_lisp_enable_disable_t *mp;
12636   f64 timeout = ~0;
12637   u8 is_set = 0;
12638   u8 is_en = 0;
12639
12640   /* Parse args required to build the message */
12641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12642     {
12643       if (unformat (input, "enable"))
12644         {
12645           is_set = 1;
12646           is_en = 1;
12647         }
12648       else if (unformat (input, "disable"))
12649         {
12650           is_set = 1;
12651         }
12652       else
12653         break;
12654     }
12655
12656   if (!is_set)
12657     {
12658       errmsg ("Value not set\n");
12659       return -99;
12660     }
12661
12662   /* Construct the API message */
12663   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12664
12665   mp->is_en = is_en;
12666
12667   /* send it... */
12668   S;
12669
12670   /* Wait for a reply... */
12671   W;
12672
12673   /* NOTREACHED */
12674   return 0;
12675 }
12676
12677 static int
12678 api_show_lisp_map_request_mode (vat_main_t * vam)
12679 {
12680   f64 timeout = ~0;
12681   vl_api_show_lisp_map_request_mode_t *mp;
12682
12683   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
12684
12685   /* send */
12686   S;
12687
12688   /* wait for reply */
12689   W;
12690
12691   return 0;
12692 }
12693
12694 static int
12695 api_lisp_map_request_mode (vat_main_t * vam)
12696 {
12697   f64 timeout = ~0;
12698   unformat_input_t *input = vam->input;
12699   vl_api_lisp_map_request_mode_t *mp;
12700   u8 mode = 0;
12701
12702   /* Parse args required to build the message */
12703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12704     {
12705       if (unformat (input, "dst-only"))
12706         mode = 0;
12707       else if (unformat (input, "src-dst"))
12708         mode = 1;
12709       else
12710         {
12711           errmsg ("parse error '%U'", format_unformat_error, input);
12712           return -99;
12713         }
12714     }
12715
12716   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
12717
12718   mp->mode = mode;
12719
12720   /* send */
12721   S;
12722
12723   /* wait for reply */
12724   W;
12725
12726   /* notreached */
12727   return 0;
12728 }
12729
12730 /**
12731  * Enable/disable LISP proxy ITR.
12732  *
12733  * @param vam vpp API test context
12734  * @return return code
12735  */
12736 static int
12737 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12738 {
12739   f64 timeout = ~0;
12740   u8 ls_name_set = 0;
12741   unformat_input_t *input = vam->input;
12742   vl_api_lisp_pitr_set_locator_set_t *mp;
12743   u8 is_add = 1;
12744   u8 *ls_name = 0;
12745
12746   /* Parse args required to build the message */
12747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12748     {
12749       if (unformat (input, "del"))
12750         is_add = 0;
12751       else if (unformat (input, "locator-set %s", &ls_name))
12752         ls_name_set = 1;
12753       else
12754         {
12755           errmsg ("parse error '%U'", format_unformat_error, input);
12756           return -99;
12757         }
12758     }
12759
12760   if (!ls_name_set)
12761     {
12762       errmsg ("locator-set name not set!");
12763       return -99;
12764     }
12765
12766   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12767
12768   mp->is_add = is_add;
12769   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12770   vec_free (ls_name);
12771
12772   /* send */
12773   S;
12774
12775   /* wait for reply */
12776   W;
12777
12778   /* notreached */
12779   return 0;
12780 }
12781
12782 static int
12783 api_show_lisp_pitr (vat_main_t * vam)
12784 {
12785   vl_api_show_lisp_pitr_t *mp;
12786   f64 timeout = ~0;
12787
12788   if (!vam->json_output)
12789     {
12790       fformat (vam->ofp, "%=20s\n", "lisp status:");
12791     }
12792
12793   M (SHOW_LISP_PITR, show_lisp_pitr);
12794   /* send it... */
12795   S;
12796
12797   /* Wait for a reply... */
12798   W;
12799
12800   /* NOTREACHED */
12801   return 0;
12802 }
12803
12804 /**
12805  * Add/delete mapping between vni and vrf
12806  */
12807 static int
12808 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12809 {
12810   f64 timeout = ~0;
12811   unformat_input_t *input = vam->input;
12812   vl_api_lisp_eid_table_add_del_map_t *mp;
12813   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12814   u32 vni, vrf, bd_index;
12815
12816   /* Parse args required to build the message */
12817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12818     {
12819       if (unformat (input, "del"))
12820         is_add = 0;
12821       else if (unformat (input, "vrf %d", &vrf))
12822         vrf_set = 1;
12823       else if (unformat (input, "bd_index %d", &bd_index))
12824         bd_index_set = 1;
12825       else if (unformat (input, "vni %d", &vni))
12826         vni_set = 1;
12827       else
12828         break;
12829     }
12830
12831   if (!vni_set || (!vrf_set && !bd_index_set))
12832     {
12833       errmsg ("missing arguments!");
12834       return -99;
12835     }
12836
12837   if (vrf_set && bd_index_set)
12838     {
12839       errmsg ("error: both vrf and bd entered!");
12840       return -99;
12841     }
12842
12843   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12844
12845   mp->is_add = is_add;
12846   mp->vni = htonl (vni);
12847   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12848   mp->is_l2 = bd_index_set;
12849
12850   /* send */
12851   S;
12852
12853   /* wait for reply */
12854   W;
12855
12856   /* notreached */
12857   return 0;
12858 }
12859
12860 uword
12861 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
12862 {
12863   u32 *action = va_arg (*args, u32 *);
12864   u8 *s = 0;
12865
12866   if (unformat (input, "%s", &s))
12867     {
12868       if (!strcmp ((char *) s, "no-action"))
12869         action[0] = 0;
12870       else if (!strcmp ((char *) s, "natively-forward"))
12871         action[0] = 1;
12872       else if (!strcmp ((char *) s, "send-map-request"))
12873         action[0] = 2;
12874       else if (!strcmp ((char *) s, "drop"))
12875         action[0] = 3;
12876       else
12877         {
12878           clib_warning ("invalid action: '%s'", s);
12879           action[0] = 3;
12880         }
12881     }
12882   else
12883     return 0;
12884
12885   vec_free (s);
12886   return 1;
12887 }
12888
12889 /**
12890  * Add/del remote mapping to/from LISP control plane
12891  *
12892  * @param vam vpp API test context
12893  * @return return code
12894  */
12895 static int
12896 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12897 {
12898   unformat_input_t *input = vam->input;
12899   vl_api_lisp_add_del_remote_mapping_t *mp;
12900   f64 timeout = ~0;
12901   u32 vni = 0;
12902   lisp_eid_vat_t _eid, *eid = &_eid;
12903   lisp_eid_vat_t _seid, *seid = &_seid;
12904   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
12905   u32 action = ~0, p, w, data_len;
12906   ip4_address_t rloc4;
12907   ip6_address_t rloc6;
12908   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12909
12910   memset (&rloc, 0, sizeof (rloc));
12911
12912   /* Parse args required to build the message */
12913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12914     {
12915       if (unformat (input, "del-all"))
12916         {
12917           del_all = 1;
12918         }
12919       else if (unformat (input, "del"))
12920         {
12921           is_add = 0;
12922         }
12923       else if (unformat (input, "add"))
12924         {
12925           is_add = 1;
12926         }
12927       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12928         {
12929           eid_set = 1;
12930         }
12931       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
12932         {
12933           seid_set = 1;
12934         }
12935       else if (unformat (input, "vni %d", &vni))
12936         {
12937           ;
12938         }
12939       else if (unformat (input, "p %d w %d", &p, &w))
12940         {
12941           if (!curr_rloc)
12942             {
12943               errmsg ("No RLOC configured for setting priority/weight!");
12944               return -99;
12945             }
12946           curr_rloc->priority = p;
12947           curr_rloc->weight = w;
12948         }
12949       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12950         {
12951           rloc.is_ip4 = 1;
12952           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12953           vec_add1 (rlocs, rloc);
12954           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12955         }
12956       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12957         {
12958           rloc.is_ip4 = 0;
12959           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12960           vec_add1 (rlocs, rloc);
12961           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12962         }
12963       else if (unformat (input, "action %U",
12964                          unformat_negative_mapping_action, &action))
12965         {
12966           ;
12967         }
12968       else
12969         {
12970           clib_warning ("parse error '%U'", format_unformat_error, input);
12971           return -99;
12972         }
12973     }
12974
12975   if (0 == eid_set)
12976     {
12977       errmsg ("missing params!");
12978       return -99;
12979     }
12980
12981   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12982     {
12983       errmsg ("no action set for negative map-reply!");
12984       return -99;
12985     }
12986
12987   data_len = vec_len (rlocs) * sizeof (rloc_t);
12988
12989   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
12990   mp->is_add = is_add;
12991   mp->vni = htonl (vni);
12992   mp->action = (u8) action;
12993   mp->is_src_dst = seid_set;
12994   mp->eid_len = eid->len;
12995   mp->seid_len = seid->len;
12996   mp->del_all = del_all;
12997   mp->eid_type = eid->type;
12998   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12999   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13000
13001   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13002   clib_memcpy (mp->rlocs, rlocs, data_len);
13003   vec_free (rlocs);
13004
13005   /* send it... */
13006   S;
13007
13008   /* Wait for a reply... */
13009   W;
13010
13011   /* NOTREACHED */
13012   return 0;
13013 }
13014
13015 /**
13016  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13017  * forwarding entries in data-plane accordingly.
13018  *
13019  * @param vam vpp API test context
13020  * @return return code
13021  */
13022 static int
13023 api_lisp_add_del_adjacency (vat_main_t * vam)
13024 {
13025   unformat_input_t *input = vam->input;
13026   vl_api_lisp_add_del_adjacency_t *mp;
13027   f64 timeout = ~0;
13028   u32 vni = 0;
13029   ip4_address_t leid4, reid4;
13030   ip6_address_t leid6, reid6;
13031   u8 reid_mac[6] = { 0 };
13032   u8 leid_mac[6] = { 0 };
13033   u8 reid_type, leid_type;
13034   u32 leid_len = 0, reid_len = 0, len;
13035   u8 is_add = 1;
13036
13037   leid_type = reid_type = (u8) ~ 0;
13038
13039   /* Parse args required to build the message */
13040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13041     {
13042       if (unformat (input, "del"))
13043         {
13044           is_add = 0;
13045         }
13046       else if (unformat (input, "add"))
13047         {
13048           is_add = 1;
13049         }
13050       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13051                          &reid4, &len))
13052         {
13053           reid_type = 0;        /* ipv4 */
13054           reid_len = len;
13055         }
13056       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13057                          &reid6, &len))
13058         {
13059           reid_type = 1;        /* ipv6 */
13060           reid_len = len;
13061         }
13062       else if (unformat (input, "reid %U", unformat_ethernet_address,
13063                          reid_mac))
13064         {
13065           reid_type = 2;        /* mac */
13066         }
13067       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13068                          &leid4, &len))
13069         {
13070           leid_type = 0;        /* ipv4 */
13071           leid_len = len;
13072         }
13073       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13074                          &leid6, &len))
13075         {
13076           leid_type = 1;        /* ipv6 */
13077           leid_len = len;
13078         }
13079       else if (unformat (input, "leid %U", unformat_ethernet_address,
13080                          leid_mac))
13081         {
13082           leid_type = 2;        /* mac */
13083         }
13084       else if (unformat (input, "vni %d", &vni))
13085         {
13086           ;
13087         }
13088       else
13089         {
13090           errmsg ("parse error '%U'", format_unformat_error, input);
13091           return -99;
13092         }
13093     }
13094
13095   if ((u8) ~ 0 == reid_type)
13096     {
13097       errmsg ("missing params!");
13098       return -99;
13099     }
13100
13101   if (leid_type != reid_type)
13102     {
13103       errmsg ("remote and local EIDs are of different types!");
13104       return -99;
13105     }
13106
13107   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13108   mp->is_add = is_add;
13109   mp->vni = htonl (vni);
13110   mp->leid_len = leid_len;
13111   mp->reid_len = reid_len;
13112   mp->eid_type = reid_type;
13113
13114   switch (mp->eid_type)
13115     {
13116     case 0:
13117       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13118       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13119       break;
13120     case 1:
13121       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13122       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13123       break;
13124     case 2:
13125       clib_memcpy (mp->leid, leid_mac, 6);
13126       clib_memcpy (mp->reid, reid_mac, 6);
13127       break;
13128     default:
13129       errmsg ("unknown EID type %d!", mp->eid_type);
13130       return 0;
13131     }
13132
13133   /* send it... */
13134   S;
13135
13136   /* Wait for a reply... */
13137   W;
13138
13139   /* NOTREACHED */
13140   return 0;
13141 }
13142
13143 static int
13144 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13145 {
13146   unformat_input_t *input = vam->input;
13147   vl_api_lisp_gpe_add_del_iface_t *mp;
13148   f64 timeout = ~0;
13149   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13150   u32 dp_table = 0, vni = 0;
13151
13152   /* Parse args required to build the message */
13153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13154     {
13155       if (unformat (input, "up"))
13156         {
13157           action_set = 1;
13158           is_add = 1;
13159         }
13160       else if (unformat (input, "down"))
13161         {
13162           action_set = 1;
13163           is_add = 0;
13164         }
13165       else if (unformat (input, "table_id %d", &dp_table))
13166         {
13167           dp_table_set = 1;
13168         }
13169       else if (unformat (input, "bd_id %d", &dp_table))
13170         {
13171           dp_table_set = 1;
13172           is_l2 = 1;
13173         }
13174       else if (unformat (input, "vni %d", &vni))
13175         {
13176           vni_set = 1;
13177         }
13178       else
13179         break;
13180     }
13181
13182   if (action_set == 0)
13183     {
13184       errmsg ("Action not set\n");
13185       return -99;
13186     }
13187   if (dp_table_set == 0 || vni_set == 0)
13188     {
13189       errmsg ("vni and dp_table must be set\n");
13190       return -99;
13191     }
13192
13193   /* Construct the API message */
13194   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13195
13196   mp->is_add = is_add;
13197   mp->dp_table = dp_table;
13198   mp->is_l2 = is_l2;
13199   mp->vni = vni;
13200
13201   /* send it... */
13202   S;
13203
13204   /* Wait for a reply... */
13205   W;
13206
13207   /* NOTREACHED */
13208   return 0;
13209 }
13210
13211 /**
13212  * Add/del map request itr rlocs from LISP control plane and updates
13213  *
13214  * @param vam vpp API test context
13215  * @return return code
13216  */
13217 static int
13218 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13219 {
13220   unformat_input_t *input = vam->input;
13221   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13222   f64 timeout = ~0;
13223   u8 *locator_set_name = 0;
13224   u8 locator_set_name_set = 0;
13225   u8 is_add = 1;
13226
13227   /* Parse args required to build the message */
13228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13229     {
13230       if (unformat (input, "del"))
13231         {
13232           is_add = 0;
13233         }
13234       else if (unformat (input, "%_%v%_", &locator_set_name))
13235         {
13236           locator_set_name_set = 1;
13237         }
13238       else
13239         {
13240           clib_warning ("parse error '%U'", format_unformat_error, input);
13241           return -99;
13242         }
13243     }
13244
13245   if (is_add && !locator_set_name_set)
13246     {
13247       errmsg ("itr-rloc is not set!");
13248       return -99;
13249     }
13250
13251   if (is_add && vec_len (locator_set_name) > 64)
13252     {
13253       errmsg ("itr-rloc locator-set name too long\n");
13254       vec_free (locator_set_name);
13255       return -99;
13256     }
13257
13258   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13259   mp->is_add = is_add;
13260   if (is_add)
13261     {
13262       clib_memcpy (mp->locator_set_name, locator_set_name,
13263                    vec_len (locator_set_name));
13264     }
13265   else
13266     {
13267       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13268     }
13269   vec_free (locator_set_name);
13270
13271   /* send it... */
13272   S;
13273
13274   /* Wait for a reply... */
13275   W;
13276
13277   /* NOTREACHED */
13278   return 0;
13279 }
13280
13281 static int
13282 api_lisp_locator_dump (vat_main_t * vam)
13283 {
13284   unformat_input_t *input = vam->input;
13285   vl_api_lisp_locator_dump_t *mp;
13286   f64 timeout = ~0;
13287   u8 is_index_set = 0, is_name_set = 0;
13288   u8 *ls_name = 0;
13289   u32 ls_index = ~0;
13290
13291   /* Parse args required to build the message */
13292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13293     {
13294       if (unformat (input, "ls_name %_%v%_", &ls_name))
13295         {
13296           is_name_set = 1;
13297         }
13298       else if (unformat (input, "ls_index %d", &ls_index))
13299         {
13300           is_index_set = 1;
13301         }
13302       else
13303         {
13304           errmsg ("parse error '%U'", format_unformat_error, input);
13305           return -99;
13306         }
13307     }
13308
13309   if (!is_index_set && !is_name_set)
13310     {
13311       errmsg ("error: expected one of index or name!\n");
13312       return -99;
13313     }
13314
13315   if (is_index_set && is_name_set)
13316     {
13317       errmsg ("error: only one param expected!\n");
13318       return -99;
13319     }
13320
13321   if (vec_len (ls_name) > 62)
13322     {
13323       errmsg ("error: locator set name too long!");
13324       return -99;
13325     }
13326
13327   if (!vam->json_output)
13328     {
13329       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13330                "weight");
13331     }
13332
13333   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13334   mp->is_index_set = is_index_set;
13335
13336   if (is_index_set)
13337     mp->ls_index = clib_host_to_net_u32 (ls_index);
13338   else
13339     {
13340       vec_add1 (ls_name, 0);
13341       strncpy ((char *) mp->ls_name, (char *) ls_name,
13342                sizeof (mp->ls_name) - 1);
13343     }
13344
13345   /* send it... */
13346   S;
13347
13348   /* Use a control ping for synchronization */
13349   {
13350     vl_api_control_ping_t *mp;
13351     M (CONTROL_PING, control_ping);
13352     S;
13353   }
13354   /* Wait for a reply... */
13355   W;
13356
13357   /* NOTREACHED */
13358   return 0;
13359 }
13360
13361 static int
13362 api_lisp_locator_set_dump (vat_main_t * vam)
13363 {
13364   vl_api_lisp_locator_set_dump_t *mp;
13365   unformat_input_t *input = vam->input;
13366   f64 timeout = ~0;
13367   u8 filter = 0;
13368
13369   /* Parse args required to build the message */
13370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13371     {
13372       if (unformat (input, "local"))
13373         {
13374           filter = 1;
13375         }
13376       else if (unformat (input, "remote"))
13377         {
13378           filter = 2;
13379         }
13380       else
13381         {
13382           errmsg ("parse error '%U'", format_unformat_error, input);
13383           return -99;
13384         }
13385     }
13386
13387   if (!vam->json_output)
13388     {
13389       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13390     }
13391
13392   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13393
13394   mp->filter = filter;
13395
13396   /* send it... */
13397   S;
13398
13399   /* Use a control ping for synchronization */
13400   {
13401     vl_api_control_ping_t *mp;
13402     M (CONTROL_PING, control_ping);
13403     S;
13404   }
13405   /* Wait for a reply... */
13406   W;
13407
13408   /* NOTREACHED */
13409   return 0;
13410 }
13411
13412 static int
13413 api_lisp_eid_table_map_dump (vat_main_t * vam)
13414 {
13415   u8 is_l2 = 0;
13416   u8 mode_set = 0;
13417   unformat_input_t *input = vam->input;
13418   vl_api_lisp_eid_table_map_dump_t *mp;
13419   f64 timeout = ~0;
13420
13421   /* Parse args required to build the message */
13422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13423     {
13424       if (unformat (input, "l2"))
13425         {
13426           is_l2 = 1;
13427           mode_set = 1;
13428         }
13429       else if (unformat (input, "l3"))
13430         {
13431           is_l2 = 0;
13432           mode_set = 1;
13433         }
13434       else
13435         {
13436           errmsg ("parse error '%U'", format_unformat_error, input);
13437           return -99;
13438         }
13439     }
13440
13441   if (!mode_set)
13442     {
13443       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13444       return -99;
13445     }
13446
13447   if (!vam->json_output)
13448     {
13449       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13450     }
13451
13452   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13453   mp->is_l2 = is_l2;
13454
13455   /* send it... */
13456   S;
13457
13458   /* Use a control ping for synchronization */
13459   {
13460     vl_api_control_ping_t *mp;
13461     M (CONTROL_PING, control_ping);
13462     S;
13463   }
13464   /* Wait for a reply... */
13465   W;
13466
13467   /* NOTREACHED */
13468   return 0;
13469 }
13470
13471 static int
13472 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13473 {
13474   vl_api_lisp_eid_table_vni_dump_t *mp;
13475   f64 timeout = ~0;
13476
13477   if (!vam->json_output)
13478     {
13479       fformat (vam->ofp, "VNI\n");
13480     }
13481
13482   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13483
13484   /* send it... */
13485   S;
13486
13487   /* Use a control ping for synchronization */
13488   {
13489     vl_api_control_ping_t *mp;
13490     M (CONTROL_PING, control_ping);
13491     S;
13492   }
13493   /* Wait for a reply... */
13494   W;
13495
13496   /* NOTREACHED */
13497   return 0;
13498 }
13499
13500 static int
13501 api_lisp_eid_table_dump (vat_main_t * vam)
13502 {
13503   unformat_input_t *i = vam->input;
13504   vl_api_lisp_eid_table_dump_t *mp;
13505   f64 timeout = ~0;
13506   struct in_addr ip4;
13507   struct in6_addr ip6;
13508   u8 mac[6];
13509   u8 eid_type = ~0, eid_set = 0;
13510   u32 prefix_length = ~0, t, vni = 0;
13511   u8 filter = 0;
13512
13513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13514     {
13515       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13516         {
13517           eid_set = 1;
13518           eid_type = 0;
13519           prefix_length = t;
13520         }
13521       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13522         {
13523           eid_set = 1;
13524           eid_type = 1;
13525           prefix_length = t;
13526         }
13527       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13528         {
13529           eid_set = 1;
13530           eid_type = 2;
13531         }
13532       else if (unformat (i, "vni %d", &t))
13533         {
13534           vni = t;
13535         }
13536       else if (unformat (i, "local"))
13537         {
13538           filter = 1;
13539         }
13540       else if (unformat (i, "remote"))
13541         {
13542           filter = 2;
13543         }
13544       else
13545         {
13546           errmsg ("parse error '%U'", format_unformat_error, i);
13547           return -99;
13548         }
13549     }
13550
13551   if (!vam->json_output)
13552     {
13553       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
13554                "ls_index", "ttl", "authoritative");
13555     }
13556
13557   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13558
13559   mp->filter = filter;
13560   if (eid_set)
13561     {
13562       mp->eid_set = 1;
13563       mp->vni = htonl (vni);
13564       mp->eid_type = eid_type;
13565       switch (eid_type)
13566         {
13567         case 0:
13568           mp->prefix_length = prefix_length;
13569           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13570           break;
13571         case 1:
13572           mp->prefix_length = prefix_length;
13573           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13574           break;
13575         case 2:
13576           clib_memcpy (mp->eid, mac, sizeof (mac));
13577           break;
13578         default:
13579           errmsg ("unknown EID type %d!", eid_type);
13580           return -99;
13581         }
13582     }
13583
13584   /* send it... */
13585   S;
13586
13587   /* Use a control ping for synchronization */
13588   {
13589     vl_api_control_ping_t *mp;
13590     M (CONTROL_PING, control_ping);
13591     S;
13592   }
13593
13594   /* Wait for a reply... */
13595   W;
13596
13597   /* NOTREACHED */
13598   return 0;
13599 }
13600
13601 static int
13602 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13603 {
13604   vl_api_lisp_gpe_tunnel_dump_t *mp;
13605   f64 timeout = ~0;
13606
13607   if (!vam->json_output)
13608     {
13609       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13610                "%=16s%=16s%=16s%=16s%=16s\n",
13611                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13612                "Decap next", "Lisp version", "Flags", "Next protocol",
13613                "ver_res", "res", "iid");
13614     }
13615
13616   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13617   /* send it... */
13618   S;
13619
13620   /* Use a control ping for synchronization */
13621   {
13622     vl_api_control_ping_t *mp;
13623     M (CONTROL_PING, control_ping);
13624     S;
13625   }
13626   /* Wait for a reply... */
13627   W;
13628
13629   /* NOTREACHED */
13630   return 0;
13631 }
13632
13633 static int
13634 api_lisp_map_resolver_dump (vat_main_t * vam)
13635 {
13636   vl_api_lisp_map_resolver_dump_t *mp;
13637   f64 timeout = ~0;
13638
13639   if (!vam->json_output)
13640     {
13641       fformat (vam->ofp, "%=20s\n", "Map resolver");
13642     }
13643
13644   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13645   /* send it... */
13646   S;
13647
13648   /* Use a control ping for synchronization */
13649   {
13650     vl_api_control_ping_t *mp;
13651     M (CONTROL_PING, control_ping);
13652     S;
13653   }
13654   /* Wait for a reply... */
13655   W;
13656
13657   /* NOTREACHED */
13658   return 0;
13659 }
13660
13661 static int
13662 api_show_lisp_status (vat_main_t * vam)
13663 {
13664   vl_api_show_lisp_status_t *mp;
13665   f64 timeout = ~0;
13666
13667   if (!vam->json_output)
13668     {
13669       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13670     }
13671
13672   M (SHOW_LISP_STATUS, show_lisp_status);
13673   /* send it... */
13674   S;
13675   /* Wait for a reply... */
13676   W;
13677
13678   /* NOTREACHED */
13679   return 0;
13680 }
13681
13682 static int
13683 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13684 {
13685   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13686   f64 timeout = ~0;
13687
13688   if (!vam->json_output)
13689     {
13690       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13691     }
13692
13693   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13694   /* send it... */
13695   S;
13696   /* Wait for a reply... */
13697   W;
13698
13699   /* NOTREACHED */
13700   return 0;
13701 }
13702
13703 static int
13704 api_af_packet_create (vat_main_t * vam)
13705 {
13706   unformat_input_t *i = vam->input;
13707   vl_api_af_packet_create_t *mp;
13708   f64 timeout;
13709   u8 *host_if_name = 0;
13710   u8 hw_addr[6];
13711   u8 random_hw_addr = 1;
13712
13713   memset (hw_addr, 0, sizeof (hw_addr));
13714
13715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13716     {
13717       if (unformat (i, "name %s", &host_if_name))
13718         vec_add1 (host_if_name, 0);
13719       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13720         random_hw_addr = 0;
13721       else
13722         break;
13723     }
13724
13725   if (!vec_len (host_if_name))
13726     {
13727       errmsg ("host-interface name must be specified");
13728       return -99;
13729     }
13730
13731   if (vec_len (host_if_name) > 64)
13732     {
13733       errmsg ("host-interface name too long");
13734       return -99;
13735     }
13736
13737   M (AF_PACKET_CREATE, af_packet_create);
13738
13739   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13740   clib_memcpy (mp->hw_addr, hw_addr, 6);
13741   mp->use_random_hw_addr = random_hw_addr;
13742   vec_free (host_if_name);
13743
13744   S;
13745   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13746   /* NOTREACHED */
13747   return 0;
13748 }
13749
13750 static int
13751 api_af_packet_delete (vat_main_t * vam)
13752 {
13753   unformat_input_t *i = vam->input;
13754   vl_api_af_packet_delete_t *mp;
13755   f64 timeout;
13756   u8 *host_if_name = 0;
13757
13758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13759     {
13760       if (unformat (i, "name %s", &host_if_name))
13761         vec_add1 (host_if_name, 0);
13762       else
13763         break;
13764     }
13765
13766   if (!vec_len (host_if_name))
13767     {
13768       errmsg ("host-interface name must be specified");
13769       return -99;
13770     }
13771
13772   if (vec_len (host_if_name) > 64)
13773     {
13774       errmsg ("host-interface name too long");
13775       return -99;
13776     }
13777
13778   M (AF_PACKET_DELETE, af_packet_delete);
13779
13780   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13781   vec_free (host_if_name);
13782
13783   S;
13784   W;
13785   /* NOTREACHED */
13786   return 0;
13787 }
13788
13789 static int
13790 api_policer_add_del (vat_main_t * vam)
13791 {
13792   unformat_input_t *i = vam->input;
13793   vl_api_policer_add_del_t *mp;
13794   f64 timeout;
13795   u8 is_add = 1;
13796   u8 *name = 0;
13797   u32 cir = 0;
13798   u32 eir = 0;
13799   u64 cb = 0;
13800   u64 eb = 0;
13801   u8 rate_type = 0;
13802   u8 round_type = 0;
13803   u8 type = 0;
13804   u8 color_aware = 0;
13805   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13806
13807   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13808   conform_action.dscp = 0;
13809   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13810   exceed_action.dscp = 0;
13811   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13812   violate_action.dscp = 0;
13813
13814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13815     {
13816       if (unformat (i, "del"))
13817         is_add = 0;
13818       else if (unformat (i, "name %s", &name))
13819         vec_add1 (name, 0);
13820       else if (unformat (i, "cir %u", &cir))
13821         ;
13822       else if (unformat (i, "eir %u", &eir))
13823         ;
13824       else if (unformat (i, "cb %u", &cb))
13825         ;
13826       else if (unformat (i, "eb %u", &eb))
13827         ;
13828       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13829                          &rate_type))
13830         ;
13831       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13832                          &round_type))
13833         ;
13834       else if (unformat (i, "type %U", unformat_policer_type, &type))
13835         ;
13836       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13837                          &conform_action))
13838         ;
13839       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13840                          &exceed_action))
13841         ;
13842       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13843                          &violate_action))
13844         ;
13845       else if (unformat (i, "color-aware"))
13846         color_aware = 1;
13847       else
13848         break;
13849     }
13850
13851   if (!vec_len (name))
13852     {
13853       errmsg ("policer name must be specified");
13854       return -99;
13855     }
13856
13857   if (vec_len (name) > 64)
13858     {
13859       errmsg ("policer name too long");
13860       return -99;
13861     }
13862
13863   M (POLICER_ADD_DEL, policer_add_del);
13864
13865   clib_memcpy (mp->name, name, vec_len (name));
13866   vec_free (name);
13867   mp->is_add = is_add;
13868   mp->cir = cir;
13869   mp->eir = eir;
13870   mp->cb = cb;
13871   mp->eb = eb;
13872   mp->rate_type = rate_type;
13873   mp->round_type = round_type;
13874   mp->type = type;
13875   mp->conform_action_type = conform_action.action_type;
13876   mp->conform_dscp = conform_action.dscp;
13877   mp->exceed_action_type = exceed_action.action_type;
13878   mp->exceed_dscp = exceed_action.dscp;
13879   mp->violate_action_type = violate_action.action_type;
13880   mp->violate_dscp = violate_action.dscp;
13881   mp->color_aware = color_aware;
13882
13883   S;
13884   W;
13885   /* NOTREACHED */
13886   return 0;
13887 }
13888
13889 static int
13890 api_policer_dump (vat_main_t * vam)
13891 {
13892   unformat_input_t *i = vam->input;
13893   vl_api_policer_dump_t *mp;
13894   f64 timeout = ~0;
13895   u8 *match_name = 0;
13896   u8 match_name_valid = 0;
13897
13898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13899     {
13900       if (unformat (i, "name %s", &match_name))
13901         {
13902           vec_add1 (match_name, 0);
13903           match_name_valid = 1;
13904         }
13905       else
13906         break;
13907     }
13908
13909   M (POLICER_DUMP, policer_dump);
13910   mp->match_name_valid = match_name_valid;
13911   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13912   vec_free (match_name);
13913   /* send it... */
13914   S;
13915
13916   /* Use a control ping for synchronization */
13917   {
13918     vl_api_control_ping_t *mp;
13919     M (CONTROL_PING, control_ping);
13920     S;
13921   }
13922   /* Wait for a reply... */
13923   W;
13924
13925   /* NOTREACHED */
13926   return 0;
13927 }
13928
13929 static int
13930 api_policer_classify_set_interface (vat_main_t * vam)
13931 {
13932   unformat_input_t *i = vam->input;
13933   vl_api_policer_classify_set_interface_t *mp;
13934   f64 timeout;
13935   u32 sw_if_index;
13936   int sw_if_index_set;
13937   u32 ip4_table_index = ~0;
13938   u32 ip6_table_index = ~0;
13939   u32 l2_table_index = ~0;
13940   u8 is_add = 1;
13941
13942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13943     {
13944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13945         sw_if_index_set = 1;
13946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13947         sw_if_index_set = 1;
13948       else if (unformat (i, "del"))
13949         is_add = 0;
13950       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13951         ;
13952       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13953         ;
13954       else if (unformat (i, "l2-table %d", &l2_table_index))
13955         ;
13956       else
13957         {
13958           clib_warning ("parse error '%U'", format_unformat_error, i);
13959           return -99;
13960         }
13961     }
13962
13963   if (sw_if_index_set == 0)
13964     {
13965       errmsg ("missing interface name or sw_if_index\n");
13966       return -99;
13967     }
13968
13969   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13970
13971   mp->sw_if_index = ntohl (sw_if_index);
13972   mp->ip4_table_index = ntohl (ip4_table_index);
13973   mp->ip6_table_index = ntohl (ip6_table_index);
13974   mp->l2_table_index = ntohl (l2_table_index);
13975   mp->is_add = is_add;
13976
13977   S;
13978   W;
13979   /* NOTREACHED */
13980   return 0;
13981 }
13982
13983 static int
13984 api_policer_classify_dump (vat_main_t * vam)
13985 {
13986   unformat_input_t *i = vam->input;
13987   vl_api_policer_classify_dump_t *mp;
13988   f64 timeout = ~0;
13989   u8 type = POLICER_CLASSIFY_N_TABLES;
13990
13991   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13992     ;
13993   else
13994     {
13995       errmsg ("classify table type must be specified\n");
13996       return -99;
13997     }
13998
13999   if (!vam->json_output)
14000     {
14001       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14002     }
14003
14004   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14005   mp->type = type;
14006   /* send it... */
14007   S;
14008
14009   /* Use a control ping for synchronization */
14010   {
14011     vl_api_control_ping_t *mp;
14012     M (CONTROL_PING, control_ping);
14013     S;
14014   }
14015   /* Wait for a reply... */
14016   W;
14017
14018   /* NOTREACHED */
14019   return 0;
14020 }
14021
14022 static int
14023 api_netmap_create (vat_main_t * vam)
14024 {
14025   unformat_input_t *i = vam->input;
14026   vl_api_netmap_create_t *mp;
14027   f64 timeout;
14028   u8 *if_name = 0;
14029   u8 hw_addr[6];
14030   u8 random_hw_addr = 1;
14031   u8 is_pipe = 0;
14032   u8 is_master = 0;
14033
14034   memset (hw_addr, 0, sizeof (hw_addr));
14035
14036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14037     {
14038       if (unformat (i, "name %s", &if_name))
14039         vec_add1 (if_name, 0);
14040       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14041         random_hw_addr = 0;
14042       else if (unformat (i, "pipe"))
14043         is_pipe = 1;
14044       else if (unformat (i, "master"))
14045         is_master = 1;
14046       else if (unformat (i, "slave"))
14047         is_master = 0;
14048       else
14049         break;
14050     }
14051
14052   if (!vec_len (if_name))
14053     {
14054       errmsg ("interface name must be specified");
14055       return -99;
14056     }
14057
14058   if (vec_len (if_name) > 64)
14059     {
14060       errmsg ("interface name too long");
14061       return -99;
14062     }
14063
14064   M (NETMAP_CREATE, netmap_create);
14065
14066   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14067   clib_memcpy (mp->hw_addr, hw_addr, 6);
14068   mp->use_random_hw_addr = random_hw_addr;
14069   mp->is_pipe = is_pipe;
14070   mp->is_master = is_master;
14071   vec_free (if_name);
14072
14073   S;
14074   W;
14075   /* NOTREACHED */
14076   return 0;
14077 }
14078
14079 static int
14080 api_netmap_delete (vat_main_t * vam)
14081 {
14082   unformat_input_t *i = vam->input;
14083   vl_api_netmap_delete_t *mp;
14084   f64 timeout;
14085   u8 *if_name = 0;
14086
14087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14088     {
14089       if (unformat (i, "name %s", &if_name))
14090         vec_add1 (if_name, 0);
14091       else
14092         break;
14093     }
14094
14095   if (!vec_len (if_name))
14096     {
14097       errmsg ("interface name must be specified");
14098       return -99;
14099     }
14100
14101   if (vec_len (if_name) > 64)
14102     {
14103       errmsg ("interface name too long");
14104       return -99;
14105     }
14106
14107   M (NETMAP_DELETE, netmap_delete);
14108
14109   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14110   vec_free (if_name);
14111
14112   S;
14113   W;
14114   /* NOTREACHED */
14115   return 0;
14116 }
14117
14118 static void vl_api_mpls_gre_tunnel_details_t_handler
14119   (vl_api_mpls_gre_tunnel_details_t * mp)
14120 {
14121   vat_main_t *vam = &vat_main;
14122   i32 i;
14123   i32 len = ntohl (mp->nlabels);
14124
14125   if (mp->l2_only == 0)
14126     {
14127       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14128                ntohl (mp->tunnel_index),
14129                format_ip4_address, &mp->tunnel_src,
14130                format_ip4_address, &mp->tunnel_dst,
14131                format_ip4_address, &mp->intfc_address,
14132                ntohl (mp->mask_width));
14133       for (i = 0; i < len; i++)
14134         {
14135           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14136         }
14137       fformat (vam->ofp, "\n");
14138       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14139                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14140     }
14141   else
14142     {
14143       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14144                ntohl (mp->tunnel_index),
14145                format_ip4_address, &mp->tunnel_src,
14146                format_ip4_address, &mp->tunnel_dst,
14147                format_ip4_address, &mp->intfc_address);
14148       for (i = 0; i < len; i++)
14149         {
14150           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14151         }
14152       fformat (vam->ofp, "\n");
14153       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14154                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14155     }
14156 }
14157
14158 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14159   (vl_api_mpls_gre_tunnel_details_t * mp)
14160 {
14161   vat_main_t *vam = &vat_main;
14162   vat_json_node_t *node = NULL;
14163   struct in_addr ip4;
14164   i32 i;
14165   i32 len = ntohl (mp->nlabels);
14166
14167   if (VAT_JSON_ARRAY != vam->json_tree.type)
14168     {
14169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14170       vat_json_init_array (&vam->json_tree);
14171     }
14172   node = vat_json_array_add (&vam->json_tree);
14173
14174   vat_json_init_object (node);
14175   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14176   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14177   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14178   vat_json_object_add_uint (node, "inner_fib_index",
14179                             ntohl (mp->inner_fib_index));
14180   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14181   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14182   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14183   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14184   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14185   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14186   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14187   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14188   vat_json_object_add_uint (node, "outer_fib_index",
14189                             ntohl (mp->outer_fib_index));
14190   vat_json_object_add_uint (node, "label_count", len);
14191   for (i = 0; i < len; i++)
14192     {
14193       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14194     }
14195 }
14196
14197 static int
14198 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14199 {
14200   vl_api_mpls_gre_tunnel_dump_t *mp;
14201   f64 timeout;
14202   i32 index = -1;
14203
14204   /* Parse args required to build the message */
14205   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14206     {
14207       if (!unformat (vam->input, "tunnel_index %d", &index))
14208         {
14209           index = -1;
14210           break;
14211         }
14212     }
14213
14214   fformat (vam->ofp, "  tunnel_index %d\n", index);
14215
14216   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14217   mp->tunnel_index = htonl (index);
14218   S;
14219
14220   /* Use a control ping for synchronization */
14221   {
14222     vl_api_control_ping_t *mp;
14223     M (CONTROL_PING, control_ping);
14224     S;
14225   }
14226   W;
14227 }
14228
14229 static void vl_api_mpls_eth_tunnel_details_t_handler
14230   (vl_api_mpls_eth_tunnel_details_t * mp)
14231 {
14232   vat_main_t *vam = &vat_main;
14233   i32 i;
14234   i32 len = ntohl (mp->nlabels);
14235
14236   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14237            ntohl (mp->tunnel_index),
14238            format_ethernet_address, &mp->tunnel_dst_mac,
14239            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14240   for (i = 0; i < len; i++)
14241     {
14242       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14243     }
14244   fformat (vam->ofp, "\n");
14245   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14246            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14247 }
14248
14249 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14250   (vl_api_mpls_eth_tunnel_details_t * mp)
14251 {
14252   vat_main_t *vam = &vat_main;
14253   vat_json_node_t *node = NULL;
14254   struct in_addr ip4;
14255   i32 i;
14256   i32 len = ntohl (mp->nlabels);
14257
14258   if (VAT_JSON_ARRAY != vam->json_tree.type)
14259     {
14260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14261       vat_json_init_array (&vam->json_tree);
14262     }
14263   node = vat_json_array_add (&vam->json_tree);
14264
14265   vat_json_init_object (node);
14266   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14267   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14268   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14269   vat_json_object_add_uint (node, "inner_fib_index",
14270                             ntohl (mp->inner_fib_index));
14271   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14272   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14273   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14274   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14275   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14276                                    format (0, "%U", format_ethernet_address,
14277                                            &mp->tunnel_dst_mac));
14278   vat_json_object_add_uint (node, "tx_sw_if_index",
14279                             ntohl (mp->tx_sw_if_index));
14280   vat_json_object_add_uint (node, "label_count", len);
14281   for (i = 0; i < len; i++)
14282     {
14283       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14284     }
14285 }
14286
14287 static int
14288 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14289 {
14290   vl_api_mpls_eth_tunnel_dump_t *mp;
14291   f64 timeout;
14292   i32 index = -1;
14293
14294   /* Parse args required to build the message */
14295   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14296     {
14297       if (!unformat (vam->input, "tunnel_index %d", &index))
14298         {
14299           index = -1;
14300           break;
14301         }
14302     }
14303
14304   fformat (vam->ofp, "  tunnel_index %d\n", index);
14305
14306   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14307   mp->tunnel_index = htonl (index);
14308   S;
14309
14310   /* Use a control ping for synchronization */
14311   {
14312     vl_api_control_ping_t *mp;
14313     M (CONTROL_PING, control_ping);
14314     S;
14315   }
14316   W;
14317 }
14318
14319 static void vl_api_mpls_fib_encap_details_t_handler
14320   (vl_api_mpls_fib_encap_details_t * mp)
14321 {
14322   vat_main_t *vam = &vat_main;
14323   i32 i;
14324   i32 len = ntohl (mp->nlabels);
14325
14326   fformat (vam->ofp, "table %d, dest %U, label ",
14327            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14328   for (i = 0; i < len; i++)
14329     {
14330       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14331     }
14332   fformat (vam->ofp, "\n");
14333 }
14334
14335 static void vl_api_mpls_fib_encap_details_t_handler_json
14336   (vl_api_mpls_fib_encap_details_t * mp)
14337 {
14338   vat_main_t *vam = &vat_main;
14339   vat_json_node_t *node = NULL;
14340   i32 i;
14341   i32 len = ntohl (mp->nlabels);
14342   struct in_addr ip4;
14343
14344   if (VAT_JSON_ARRAY != vam->json_tree.type)
14345     {
14346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14347       vat_json_init_array (&vam->json_tree);
14348     }
14349   node = vat_json_array_add (&vam->json_tree);
14350
14351   vat_json_init_object (node);
14352   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14353   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14354   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14355   vat_json_object_add_ip4 (node, "dest", ip4);
14356   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14357   vat_json_object_add_uint (node, "label_count", len);
14358   for (i = 0; i < len; i++)
14359     {
14360       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14361     }
14362 }
14363
14364 static int
14365 api_mpls_fib_encap_dump (vat_main_t * vam)
14366 {
14367   vl_api_mpls_fib_encap_dump_t *mp;
14368   f64 timeout;
14369
14370   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14371   S;
14372
14373   /* Use a control ping for synchronization */
14374   {
14375     vl_api_control_ping_t *mp;
14376     M (CONTROL_PING, control_ping);
14377     S;
14378   }
14379   W;
14380 }
14381
14382 static void vl_api_mpls_fib_decap_details_t_handler
14383   (vl_api_mpls_fib_decap_details_t * mp)
14384 {
14385   vat_main_t *vam = &vat_main;
14386
14387   fformat (vam->ofp,
14388            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14389            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14390            ntohl (mp->label), ntohl (mp->s_bit));
14391 }
14392
14393 static void vl_api_mpls_fib_decap_details_t_handler_json
14394   (vl_api_mpls_fib_decap_details_t * mp)
14395 {
14396   vat_main_t *vam = &vat_main;
14397   vat_json_node_t *node = NULL;
14398   struct in_addr ip4;
14399
14400   if (VAT_JSON_ARRAY != vam->json_tree.type)
14401     {
14402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14403       vat_json_init_array (&vam->json_tree);
14404     }
14405   node = vat_json_array_add (&vam->json_tree);
14406
14407   vat_json_init_object (node);
14408   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14409   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14410   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14411   vat_json_object_add_ip4 (node, "dest", ip4);
14412   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14413   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14414   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14415   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14416   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14417 }
14418
14419 static int
14420 api_mpls_fib_decap_dump (vat_main_t * vam)
14421 {
14422   vl_api_mpls_fib_decap_dump_t *mp;
14423   f64 timeout;
14424
14425   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14426   S;
14427
14428   /* Use a control ping for synchronization */
14429   {
14430     vl_api_control_ping_t *mp;
14431     M (CONTROL_PING, control_ping);
14432     S;
14433   }
14434   W;
14435 }
14436
14437 int
14438 api_classify_table_ids (vat_main_t * vam)
14439 {
14440   vl_api_classify_table_ids_t *mp;
14441   f64 timeout;
14442
14443   /* Construct the API message */
14444   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14445   mp->context = 0;
14446
14447   S;
14448   W;
14449   /* NOTREACHED */
14450   return 0;
14451 }
14452
14453 int
14454 api_classify_table_by_interface (vat_main_t * vam)
14455 {
14456   unformat_input_t *input = vam->input;
14457   vl_api_classify_table_by_interface_t *mp;
14458   f64 timeout;
14459
14460   u32 sw_if_index = ~0;
14461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14462     {
14463       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14464         ;
14465       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14466         ;
14467       else
14468         break;
14469     }
14470   if (sw_if_index == ~0)
14471     {
14472       errmsg ("missing interface name or sw_if_index\n");
14473       return -99;
14474     }
14475
14476   /* Construct the API message */
14477   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14478   mp->context = 0;
14479   mp->sw_if_index = ntohl (sw_if_index);
14480
14481   S;
14482   W;
14483   /* NOTREACHED */
14484   return 0;
14485 }
14486
14487 int
14488 api_classify_table_info (vat_main_t * vam)
14489 {
14490   unformat_input_t *input = vam->input;
14491   vl_api_classify_table_info_t *mp;
14492   f64 timeout;
14493
14494   u32 table_id = ~0;
14495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14496     {
14497       if (unformat (input, "table_id %d", &table_id))
14498         ;
14499       else
14500         break;
14501     }
14502   if (table_id == ~0)
14503     {
14504       errmsg ("missing table id\n");
14505       return -99;
14506     }
14507
14508   /* Construct the API message */
14509   M (CLASSIFY_TABLE_INFO, classify_table_info);
14510   mp->context = 0;
14511   mp->table_id = ntohl (table_id);
14512
14513   S;
14514   W;
14515   /* NOTREACHED */
14516   return 0;
14517 }
14518
14519 int
14520 api_classify_session_dump (vat_main_t * vam)
14521 {
14522   unformat_input_t *input = vam->input;
14523   vl_api_classify_session_dump_t *mp;
14524   f64 timeout;
14525
14526   u32 table_id = ~0;
14527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (input, "table_id %d", &table_id))
14530         ;
14531       else
14532         break;
14533     }
14534   if (table_id == ~0)
14535     {
14536       errmsg ("missing table id\n");
14537       return -99;
14538     }
14539
14540   /* Construct the API message */
14541   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14542   mp->context = 0;
14543   mp->table_id = ntohl (table_id);
14544   S;
14545
14546   /* Use a control ping for synchronization */
14547   {
14548     vl_api_control_ping_t *mp;
14549     M (CONTROL_PING, control_ping);
14550     S;
14551   }
14552   W;
14553   /* NOTREACHED */
14554   return 0;
14555 }
14556
14557 static void
14558 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
14559 {
14560   vat_main_t *vam = &vat_main;
14561
14562   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14563            "src_address %U, vrf_id %d, path_mtu %u, "
14564            "template_interval %u, udp_checksum %d\n",
14565            format_ip4_address, mp->collector_address,
14566            ntohs (mp->collector_port),
14567            format_ip4_address, mp->src_address,
14568            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
14569            ntohl (mp->template_interval), mp->udp_checksum);
14570
14571   vam->retval = 0;
14572   vam->result_ready = 1;
14573 }
14574
14575 static void
14576   vl_api_ipfix_exporter_details_t_handler_json
14577   (vl_api_ipfix_exporter_details_t * mp)
14578 {
14579   vat_main_t *vam = &vat_main;
14580   vat_json_node_t node;
14581   struct in_addr collector_address;
14582   struct in_addr src_address;
14583
14584   vat_json_init_object (&node);
14585   clib_memcpy (&collector_address, &mp->collector_address,
14586                sizeof (collector_address));
14587   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14588   vat_json_object_add_uint (&node, "collector_port",
14589                             ntohs (mp->collector_port));
14590   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14591   vat_json_object_add_ip4 (&node, "src_address", src_address);
14592   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
14593   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14594   vat_json_object_add_uint (&node, "template_interval",
14595                             ntohl (mp->template_interval));
14596   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
14597
14598   vat_json_print (vam->ofp, &node);
14599   vat_json_free (&node);
14600   vam->retval = 0;
14601   vam->result_ready = 1;
14602 }
14603
14604 int
14605 api_ipfix_exporter_dump (vat_main_t * vam)
14606 {
14607   vl_api_ipfix_exporter_dump_t *mp;
14608   f64 timeout;
14609
14610   /* Construct the API message */
14611   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
14612   mp->context = 0;
14613
14614   S;
14615   W;
14616   /* NOTREACHED */
14617   return 0;
14618 }
14619
14620 static int
14621 api_ipfix_classify_stream_dump (vat_main_t * vam)
14622 {
14623   vl_api_ipfix_classify_stream_dump_t *mp;
14624   f64 timeout;
14625
14626   /* Construct the API message */
14627   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
14628   mp->context = 0;
14629
14630   S;
14631   W;
14632   /* NOTREACHED */
14633   return 0;
14634 }
14635
14636 static void
14637   vl_api_ipfix_classify_stream_details_t_handler
14638   (vl_api_ipfix_classify_stream_details_t * mp)
14639 {
14640   vat_main_t *vam = &vat_main;
14641   fformat (vam->ofp, "domain_id %d, src_port %d\n",
14642            ntohl (mp->domain_id), ntohs (mp->src_port));
14643   vam->retval = 0;
14644   vam->result_ready = 1;
14645 }
14646
14647 static void
14648   vl_api_ipfix_classify_stream_details_t_handler_json
14649   (vl_api_ipfix_classify_stream_details_t * mp)
14650 {
14651   vat_main_t *vam = &vat_main;
14652   vat_json_node_t node;
14653
14654   vat_json_init_object (&node);
14655   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
14656   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
14657
14658   vat_json_print (vam->ofp, &node);
14659   vat_json_free (&node);
14660   vam->retval = 0;
14661   vam->result_ready = 1;
14662 }
14663
14664 static int
14665 api_ipfix_classify_table_dump (vat_main_t * vam)
14666 {
14667   vl_api_ipfix_classify_table_dump_t *mp;
14668   f64 timeout;
14669
14670   if (!vam->json_output)
14671     {
14672       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
14673                "transport_protocol");
14674     }
14675
14676   /* Construct the API message */
14677   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
14678
14679   /* send it... */
14680   S;
14681
14682   /* Use a control ping for synchronization */
14683   {
14684     vl_api_control_ping_t *mp;
14685     M (CONTROL_PING, control_ping);
14686     S;
14687   }
14688   W;
14689 }
14690
14691 static void
14692   vl_api_ipfix_classify_table_details_t_handler
14693   (vl_api_ipfix_classify_table_details_t * mp)
14694 {
14695   vat_main_t *vam = &vat_main;
14696   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
14697            mp->transport_protocol);
14698 }
14699
14700 static void
14701   vl_api_ipfix_classify_table_details_t_handler_json
14702   (vl_api_ipfix_classify_table_details_t * mp)
14703 {
14704   vat_json_node_t *node = NULL;
14705   vat_main_t *vam = &vat_main;
14706
14707   if (VAT_JSON_ARRAY != vam->json_tree.type)
14708     {
14709       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14710       vat_json_init_array (&vam->json_tree);
14711     }
14712
14713   node = vat_json_array_add (&vam->json_tree);
14714   vat_json_init_object (node);
14715
14716   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
14717   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
14718   vat_json_object_add_uint (node, "transport_protocol",
14719                             mp->transport_protocol);
14720 }
14721
14722 int
14723 api_pg_create_interface (vat_main_t * vam)
14724 {
14725   unformat_input_t *input = vam->input;
14726   vl_api_pg_create_interface_t *mp;
14727   f64 timeout;
14728
14729   u32 if_id = ~0;
14730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14731     {
14732       if (unformat (input, "if_id %d", &if_id))
14733         ;
14734       else
14735         break;
14736     }
14737   if (if_id == ~0)
14738     {
14739       errmsg ("missing pg interface index\n");
14740       return -99;
14741     }
14742
14743   /* Construct the API message */
14744   M (PG_CREATE_INTERFACE, pg_create_interface);
14745   mp->context = 0;
14746   mp->interface_id = ntohl (if_id);
14747
14748   S;
14749   W;
14750   /* NOTREACHED */
14751   return 0;
14752 }
14753
14754 int
14755 api_pg_capture (vat_main_t * vam)
14756 {
14757   unformat_input_t *input = vam->input;
14758   vl_api_pg_capture_t *mp;
14759   f64 timeout;
14760
14761   u32 if_id = ~0;
14762   u8 enable = 1;
14763   u32 count = 1;
14764   u8 pcap_file_set = 0;
14765   u8 *pcap_file = 0;
14766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14767     {
14768       if (unformat (input, "if_id %d", &if_id))
14769         ;
14770       else if (unformat (input, "pcap %s", &pcap_file))
14771         pcap_file_set = 1;
14772       else if (unformat (input, "count %d", &count))
14773         ;
14774       else if (unformat (input, "disable"))
14775         enable = 0;
14776       else
14777         break;
14778     }
14779   if (if_id == ~0)
14780     {
14781       errmsg ("missing pg interface index\n");
14782       return -99;
14783     }
14784   if (pcap_file_set > 0)
14785     {
14786       if (vec_len (pcap_file) > 255)
14787         {
14788           errmsg ("pcap file name is too long\n");
14789           return -99;
14790         }
14791     }
14792
14793   u32 name_len = vec_len (pcap_file);
14794   /* Construct the API message */
14795   M (PG_CAPTURE, pg_capture);
14796   mp->context = 0;
14797   mp->interface_id = ntohl (if_id);
14798   mp->is_enabled = enable;
14799   mp->count = ntohl (count);
14800   mp->pcap_name_length = ntohl (name_len);
14801   if (pcap_file_set != 0)
14802     {
14803       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14804     }
14805   vec_free (pcap_file);
14806
14807   S;
14808   W;
14809   /* NOTREACHED */
14810   return 0;
14811 }
14812
14813 int
14814 api_pg_enable_disable (vat_main_t * vam)
14815 {
14816   unformat_input_t *input = vam->input;
14817   vl_api_pg_enable_disable_t *mp;
14818   f64 timeout;
14819
14820   u8 enable = 1;
14821   u8 stream_name_set = 0;
14822   u8 *stream_name = 0;
14823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14824     {
14825       if (unformat (input, "stream %s", &stream_name))
14826         stream_name_set = 1;
14827       else if (unformat (input, "disable"))
14828         enable = 0;
14829       else
14830         break;
14831     }
14832
14833   if (stream_name_set > 0)
14834     {
14835       if (vec_len (stream_name) > 255)
14836         {
14837           errmsg ("stream name too long\n");
14838           return -99;
14839         }
14840     }
14841
14842   u32 name_len = vec_len (stream_name);
14843   /* Construct the API message */
14844   M (PG_ENABLE_DISABLE, pg_enable_disable);
14845   mp->context = 0;
14846   mp->is_enabled = enable;
14847   if (stream_name_set != 0)
14848     {
14849       mp->stream_name_length = ntohl (name_len);
14850       clib_memcpy (mp->stream_name, stream_name, name_len);
14851     }
14852   vec_free (stream_name);
14853
14854   S;
14855   W;
14856   /* NOTREACHED */
14857   return 0;
14858 }
14859
14860 int
14861 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14862 {
14863   unformat_input_t *input = vam->input;
14864   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14865   f64 timeout;
14866
14867   u16 *low_ports = 0;
14868   u16 *high_ports = 0;
14869   u16 this_low;
14870   u16 this_hi;
14871   ip4_address_t ip4_addr;
14872   ip6_address_t ip6_addr;
14873   u32 length;
14874   u32 tmp, tmp2;
14875   u8 prefix_set = 0;
14876   u32 vrf_id = ~0;
14877   u8 is_add = 1;
14878   u8 is_ipv6 = 0;
14879
14880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14883         {
14884           prefix_set = 1;
14885         }
14886       else
14887         if (unformat
14888             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14889         {
14890           prefix_set = 1;
14891           is_ipv6 = 1;
14892         }
14893       else if (unformat (input, "vrf %d", &vrf_id))
14894         ;
14895       else if (unformat (input, "del"))
14896         is_add = 0;
14897       else if (unformat (input, "port %d", &tmp))
14898         {
14899           if (tmp == 0 || tmp > 65535)
14900             {
14901               errmsg ("port %d out of range", tmp);
14902               return -99;
14903             }
14904           this_low = tmp;
14905           this_hi = this_low + 1;
14906           vec_add1 (low_ports, this_low);
14907           vec_add1 (high_ports, this_hi);
14908         }
14909       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14910         {
14911           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14912             {
14913               errmsg ("incorrect range parameters\n");
14914               return -99;
14915             }
14916           this_low = tmp;
14917           /* Note: in debug CLI +1 is added to high before
14918              passing to real fn that does "the work"
14919              (ip_source_and_port_range_check_add_del).
14920              This fn is a wrapper around the binary API fn a
14921              control plane will call, which expects this increment
14922              to have occurred. Hence letting the binary API control
14923              plane fn do the increment for consistency between VAT
14924              and other control planes.
14925            */
14926           this_hi = tmp2;
14927           vec_add1 (low_ports, this_low);
14928           vec_add1 (high_ports, this_hi);
14929         }
14930       else
14931         break;
14932     }
14933
14934   if (prefix_set == 0)
14935     {
14936       errmsg ("<address>/<mask> not specified\n");
14937       return -99;
14938     }
14939
14940   if (vrf_id == ~0)
14941     {
14942       errmsg ("VRF ID required, not specified\n");
14943       return -99;
14944     }
14945
14946   if (vrf_id == 0)
14947     {
14948       errmsg
14949         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14950       return -99;
14951     }
14952
14953   if (vec_len (low_ports) == 0)
14954     {
14955       errmsg ("At least one port or port range required\n");
14956       return -99;
14957     }
14958
14959   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14960      ip_source_and_port_range_check_add_del);
14961
14962   mp->is_add = is_add;
14963
14964   if (is_ipv6)
14965     {
14966       mp->is_ipv6 = 1;
14967       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14968     }
14969   else
14970     {
14971       mp->is_ipv6 = 0;
14972       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14973     }
14974
14975   mp->mask_length = length;
14976   mp->number_of_ranges = vec_len (low_ports);
14977
14978   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14979   vec_free (low_ports);
14980
14981   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14982   vec_free (high_ports);
14983
14984   mp->vrf_id = ntohl (vrf_id);
14985
14986   S;
14987   W;
14988   /* NOTREACHED */
14989   return 0;
14990 }
14991
14992 int
14993 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14994 {
14995   unformat_input_t *input = vam->input;
14996   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14997   f64 timeout;
14998   u32 sw_if_index = ~0;
14999   int vrf_set = 0;
15000   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15001   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15002   u8 is_add = 1;
15003
15004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15005     {
15006       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15007         ;
15008       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15009         ;
15010       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15011         vrf_set = 1;
15012       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15013         vrf_set = 1;
15014       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15015         vrf_set = 1;
15016       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15017         vrf_set = 1;
15018       else if (unformat (input, "del"))
15019         is_add = 0;
15020       else
15021         break;
15022     }
15023
15024   if (sw_if_index == ~0)
15025     {
15026       errmsg ("Interface required but not specified\n");
15027       return -99;
15028     }
15029
15030   if (vrf_set == 0)
15031     {
15032       errmsg ("VRF ID required but not specified\n");
15033       return -99;
15034     }
15035
15036   if (tcp_out_vrf_id == 0
15037       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15038     {
15039       errmsg
15040         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15041       return -99;
15042     }
15043
15044   /* Construct the API message */
15045   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15046      ip_source_and_port_range_check_interface_add_del);
15047
15048   mp->sw_if_index = ntohl (sw_if_index);
15049   mp->is_add = is_add;
15050   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15051   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15052   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15053   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15054
15055   /* send it... */
15056   S;
15057
15058   /* Wait for a reply... */
15059   W;
15060 }
15061
15062 static int
15063 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15064 {
15065   unformat_input_t *i = vam->input;
15066   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15067   f64 timeout;
15068   u32 local_sa_id = 0;
15069   u32 remote_sa_id = 0;
15070   ip4_address_t src_address;
15071   ip4_address_t dst_address;
15072   u8 is_add = 1;
15073
15074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15075     {
15076       if (unformat (i, "local_sa %d", &local_sa_id))
15077         ;
15078       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15079         ;
15080       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15081         ;
15082       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15083         ;
15084       else if (unformat (i, "del"))
15085         is_add = 0;
15086       else
15087         {
15088           clib_warning ("parse error '%U'", format_unformat_error, i);
15089           return -99;
15090         }
15091     }
15092
15093   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15094
15095   mp->local_sa_id = ntohl (local_sa_id);
15096   mp->remote_sa_id = ntohl (remote_sa_id);
15097   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15098   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15099   mp->is_add = is_add;
15100
15101   S;
15102   W;
15103   /* NOTREACHED */
15104   return 0;
15105 }
15106
15107 static void vl_api_ipsec_gre_tunnel_details_t_handler
15108   (vl_api_ipsec_gre_tunnel_details_t * mp)
15109 {
15110   vat_main_t *vam = &vat_main;
15111
15112   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15113            ntohl (mp->sw_if_index),
15114            format_ip4_address, &mp->src_address,
15115            format_ip4_address, &mp->dst_address,
15116            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15117 }
15118
15119 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15120   (vl_api_ipsec_gre_tunnel_details_t * mp)
15121 {
15122   vat_main_t *vam = &vat_main;
15123   vat_json_node_t *node = NULL;
15124   struct in_addr ip4;
15125
15126   if (VAT_JSON_ARRAY != vam->json_tree.type)
15127     {
15128       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15129       vat_json_init_array (&vam->json_tree);
15130     }
15131   node = vat_json_array_add (&vam->json_tree);
15132
15133   vat_json_init_object (node);
15134   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15135   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15136   vat_json_object_add_ip4 (node, "src_address", ip4);
15137   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15138   vat_json_object_add_ip4 (node, "dst_address", ip4);
15139   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15140   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15141 }
15142
15143 static int
15144 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15145 {
15146   unformat_input_t *i = vam->input;
15147   vl_api_ipsec_gre_tunnel_dump_t *mp;
15148   f64 timeout;
15149   u32 sw_if_index;
15150   u8 sw_if_index_set = 0;
15151
15152   /* Parse args required to build the message */
15153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15154     {
15155       if (unformat (i, "sw_if_index %d", &sw_if_index))
15156         sw_if_index_set = 1;
15157       else
15158         break;
15159     }
15160
15161   if (sw_if_index_set == 0)
15162     {
15163       sw_if_index = ~0;
15164     }
15165
15166   if (!vam->json_output)
15167     {
15168       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15169                "sw_if_index", "src_address", "dst_address",
15170                "local_sa_id", "remote_sa_id");
15171     }
15172
15173   /* Get list of gre-tunnel interfaces */
15174   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15175
15176   mp->sw_if_index = htonl (sw_if_index);
15177
15178   S;
15179
15180   /* Use a control ping for synchronization */
15181   {
15182     vl_api_control_ping_t *mp;
15183     M (CONTROL_PING, control_ping);
15184     S;
15185   }
15186   W;
15187 }
15188
15189 static int
15190 api_delete_subif (vat_main_t * vam)
15191 {
15192   unformat_input_t *i = vam->input;
15193   vl_api_delete_subif_t *mp;
15194   f64 timeout;
15195   u32 sw_if_index = ~0;
15196
15197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15198     {
15199       if (unformat (i, "sw_if_index %d", &sw_if_index))
15200         ;
15201       else
15202         break;
15203     }
15204
15205   if (sw_if_index == ~0)
15206     {
15207       errmsg ("missing sw_if_index\n");
15208       return -99;
15209     }
15210
15211   /* Construct the API message */
15212   M (DELETE_SUBIF, delete_subif);
15213   mp->sw_if_index = ntohl (sw_if_index);
15214
15215   S;
15216   W;
15217 }
15218
15219 static int
15220 q_or_quit (vat_main_t * vam)
15221 {
15222   longjmp (vam->jump_buf, 1);
15223   return 0;                     /* not so much */
15224 }
15225
15226 static int
15227 q (vat_main_t * vam)
15228 {
15229   return q_or_quit (vam);
15230 }
15231
15232 static int
15233 quit (vat_main_t * vam)
15234 {
15235   return q_or_quit (vam);
15236 }
15237
15238 static int
15239 comment (vat_main_t * vam)
15240 {
15241   return 0;
15242 }
15243
15244 static int
15245 cmd_cmp (void *a1, void *a2)
15246 {
15247   u8 **c1 = a1;
15248   u8 **c2 = a2;
15249
15250   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15251 }
15252
15253 static int
15254 help (vat_main_t * vam)
15255 {
15256   u8 **cmds = 0;
15257   u8 *name = 0;
15258   hash_pair_t *p;
15259   unformat_input_t *i = vam->input;
15260   int j;
15261
15262   if (unformat (i, "%s", &name))
15263     {
15264       uword *hs;
15265
15266       vec_add1 (name, 0);
15267
15268       hs = hash_get_mem (vam->help_by_name, name);
15269       if (hs)
15270         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15271       else
15272         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15273       vec_free (name);
15274       return 0;
15275     }
15276
15277   fformat (vam->ofp, "Help is available for the following:\n");
15278
15279     /* *INDENT-OFF* */
15280     hash_foreach_pair (p, vam->function_by_name,
15281     ({
15282       vec_add1 (cmds, (u8 *)(p->key));
15283     }));
15284     /* *INDENT-ON* */
15285
15286   vec_sort_with_function (cmds, cmd_cmp);
15287
15288   for (j = 0; j < vec_len (cmds); j++)
15289     fformat (vam->ofp, "%s\n", cmds[j]);
15290
15291   vec_free (cmds);
15292   return 0;
15293 }
15294
15295 static int
15296 set (vat_main_t * vam)
15297 {
15298   u8 *name = 0, *value = 0;
15299   unformat_input_t *i = vam->input;
15300
15301   if (unformat (i, "%s", &name))
15302     {
15303       /* The input buffer is a vector, not a string. */
15304       value = vec_dup (i->buffer);
15305       vec_delete (value, i->index, 0);
15306       /* Almost certainly has a trailing newline */
15307       if (value[vec_len (value) - 1] == '\n')
15308         value[vec_len (value) - 1] = 0;
15309       /* Make sure it's a proper string, one way or the other */
15310       vec_add1 (value, 0);
15311       (void) clib_macro_set_value (&vam->macro_main,
15312                                    (char *) name, (char *) value);
15313     }
15314   else
15315     errmsg ("usage: set <name> <value>\n");
15316
15317   vec_free (name);
15318   vec_free (value);
15319   return 0;
15320 }
15321
15322 static int
15323 unset (vat_main_t * vam)
15324 {
15325   u8 *name = 0;
15326
15327   if (unformat (vam->input, "%s", &name))
15328     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15329       errmsg ("unset: %s wasn't set\n", name);
15330   vec_free (name);
15331   return 0;
15332 }
15333
15334 typedef struct
15335 {
15336   u8 *name;
15337   u8 *value;
15338 } macro_sort_t;
15339
15340
15341 static int
15342 macro_sort_cmp (void *a1, void *a2)
15343 {
15344   macro_sort_t *s1 = a1;
15345   macro_sort_t *s2 = a2;
15346
15347   return strcmp ((char *) (s1->name), (char *) (s2->name));
15348 }
15349
15350 static int
15351 dump_macro_table (vat_main_t * vam)
15352 {
15353   macro_sort_t *sort_me = 0, *sm;
15354   int i;
15355   hash_pair_t *p;
15356
15357     /* *INDENT-OFF* */
15358     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15359     ({
15360       vec_add2 (sort_me, sm, 1);
15361       sm->name = (u8 *)(p->key);
15362       sm->value = (u8 *) (p->value[0]);
15363     }));
15364     /* *INDENT-ON* */
15365
15366   vec_sort_with_function (sort_me, macro_sort_cmp);
15367
15368   if (vec_len (sort_me))
15369     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15370   else
15371     fformat (vam->ofp, "The macro table is empty...\n");
15372
15373   for (i = 0; i < vec_len (sort_me); i++)
15374     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15375   return 0;
15376 }
15377
15378 static int
15379 dump_node_table (vat_main_t * vam)
15380 {
15381   int i, j;
15382   vlib_node_t *node, *next_node;
15383
15384   if (vec_len (vam->graph_nodes) == 0)
15385     {
15386       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15387       return 0;
15388     }
15389
15390   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15391     {
15392       node = vam->graph_nodes[i];
15393       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15394       for (j = 0; j < vec_len (node->next_nodes); j++)
15395         {
15396           if (node->next_nodes[j] != ~0)
15397             {
15398               next_node = vam->graph_nodes[node->next_nodes[j]];
15399               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15400             }
15401         }
15402     }
15403   return 0;
15404 }
15405
15406 static int
15407 search_node_table (vat_main_t * vam)
15408 {
15409   unformat_input_t *line_input = vam->input;
15410   u8 *node_to_find;
15411   int j;
15412   vlib_node_t *node, *next_node;
15413   uword *p;
15414
15415   if (vam->graph_node_index_by_name == 0)
15416     {
15417       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15418       return 0;
15419     }
15420
15421   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15422     {
15423       if (unformat (line_input, "%s", &node_to_find))
15424         {
15425           vec_add1 (node_to_find, 0);
15426           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15427           if (p == 0)
15428             {
15429               fformat (vam->ofp, "%s not found...\n", node_to_find);
15430               goto out;
15431             }
15432           node = vam->graph_nodes[p[0]];
15433           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15434           for (j = 0; j < vec_len (node->next_nodes); j++)
15435             {
15436               if (node->next_nodes[j] != ~0)
15437                 {
15438                   next_node = vam->graph_nodes[node->next_nodes[j]];
15439                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15440                 }
15441             }
15442         }
15443
15444       else
15445         {
15446           clib_warning ("parse error '%U'", format_unformat_error,
15447                         line_input);
15448           return -99;
15449         }
15450
15451     out:
15452       vec_free (node_to_find);
15453
15454     }
15455
15456   return 0;
15457 }
15458
15459
15460 static int
15461 script (vat_main_t * vam)
15462 {
15463   u8 *s = 0;
15464   char *save_current_file;
15465   unformat_input_t save_input;
15466   jmp_buf save_jump_buf;
15467   u32 save_line_number;
15468
15469   FILE *new_fp, *save_ifp;
15470
15471   if (unformat (vam->input, "%s", &s))
15472     {
15473       new_fp = fopen ((char *) s, "r");
15474       if (new_fp == 0)
15475         {
15476           errmsg ("Couldn't open script file %s\n", s);
15477           vec_free (s);
15478           return -99;
15479         }
15480     }
15481   else
15482     {
15483       errmsg ("Missing script name\n");
15484       return -99;
15485     }
15486
15487   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15488   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15489   save_ifp = vam->ifp;
15490   save_line_number = vam->input_line_number;
15491   save_current_file = (char *) vam->current_file;
15492
15493   vam->input_line_number = 0;
15494   vam->ifp = new_fp;
15495   vam->current_file = s;
15496   do_one_file (vam);
15497
15498   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15499   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15500   vam->ifp = save_ifp;
15501   vam->input_line_number = save_line_number;
15502   vam->current_file = (u8 *) save_current_file;
15503   vec_free (s);
15504
15505   return 0;
15506 }
15507
15508 static int
15509 echo (vat_main_t * vam)
15510 {
15511   fformat (vam->ofp, "%v", vam->input->buffer);
15512   return 0;
15513 }
15514
15515 /* List of API message constructors, CLI names map to api_xxx */
15516 #define foreach_vpe_api_msg                                             \
15517 _(create_loopback,"[mac <mac-addr>]")                                   \
15518 _(sw_interface_dump,"")                                                 \
15519 _(sw_interface_set_flags,                                               \
15520   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15521 _(sw_interface_add_del_address,                                         \
15522   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15523 _(sw_interface_set_table,                                               \
15524   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15525 _(sw_interface_set_vpath,                                               \
15526   "<intfc> | sw_if_index <id> enable | disable")                        \
15527 _(sw_interface_set_l2_xconnect,                                         \
15528   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15529   "enable | disable")                                                   \
15530 _(sw_interface_set_l2_bridge,                                           \
15531   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15532   "[shg <split-horizon-group>] [bvi]\n"                                 \
15533   "enable | disable")                                                   \
15534 _(sw_interface_set_dpdk_hqos_pipe,                                      \
15535   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
15536   "profile <profile-id>\n")                                             \
15537 _(sw_interface_set_dpdk_hqos_subport,                                   \
15538   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
15539   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
15540 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
15541   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
15542 _(bridge_domain_add_del,                                                \
15543   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15544 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15545 _(l2fib_add_del,                                                        \
15546   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15547 _(l2_flags,                                                             \
15548   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15549 _(bridge_flags,                                                         \
15550   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15551 _(tap_connect,                                                          \
15552   "tapname <name> mac <mac-addr> | random-mac")                         \
15553 _(tap_modify,                                                           \
15554   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15555 _(tap_delete,                                                           \
15556   "<vpp-if-name> | sw_if_index <id>")                                   \
15557 _(sw_interface_tap_dump, "")                                            \
15558 _(ip_add_del_route,                                                     \
15559   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15560   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15561   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15562   "[multipath] [count <n>]")                                            \
15563 _(proxy_arp_add_del,                                                    \
15564   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15565 _(proxy_arp_intfc_enable_disable,                                       \
15566   "<intfc> | sw_if_index <id> enable | disable")                        \
15567 _(mpls_add_del_encap,                                                   \
15568   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15569 _(mpls_add_del_decap,                                                   \
15570   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15571 _(mpls_gre_add_del_tunnel,                                              \
15572   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15573   "adj <ip4-address>/<mask-width> [del]")                               \
15574 _(sw_interface_set_unnumbered,                                          \
15575   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15576 _(ip_neighbor_add_del,                                                  \
15577   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15578   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15579 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15580 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15581 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15582   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15583   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15584   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15585 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15586 _(reset_fib, "vrf <n> [ipv6]")                                          \
15587 _(dhcp_proxy_config,                                                    \
15588   "svr <v46-address> src <v46-address>\n"                               \
15589    "insert-cid <n> [del]")                                              \
15590 _(dhcp_proxy_config_2,                                                  \
15591   "svr <v46-address> src <v46-address>\n"                               \
15592    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15593 _(dhcp_proxy_set_vss,                                                   \
15594   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15595 _(dhcp_client_config,                                                   \
15596   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15597 _(set_ip_flow_hash,                                                     \
15598   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15599 _(sw_interface_ip6_enable_disable,                                      \
15600   "<intfc> | sw_if_index <id> enable | disable")                        \
15601 _(sw_interface_ip6_set_link_local_address,                              \
15602   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15603 _(sw_interface_ip6nd_ra_prefix,                                         \
15604   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15605   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15606   "[nolink] [isno]")                                                    \
15607 _(sw_interface_ip6nd_ra_config,                                         \
15608   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15609   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15610   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15611 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15612 _(l2_patch_add_del,                                                     \
15613   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15614   "enable | disable")                                                   \
15615 _(mpls_ethernet_add_del_tunnel,                                         \
15616   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15617   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15618 _(mpls_ethernet_add_del_tunnel_2,                                       \
15619   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15620   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15621 _(sr_tunnel_add_del,                                                    \
15622   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15623   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15624   "[policy <policy_name>]")                                             \
15625 _(sr_policy_add_del,                                                    \
15626   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15627 _(sr_multicast_map_add_del,                                             \
15628   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15629 _(classify_add_del_table,                                               \
15630   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15631   "[del] mask <mask-value>\n"                                           \
15632   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15633 _(classify_add_del_session,                                             \
15634   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15635   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15636   "  [l3 [ip4|ip6]]")                                                   \
15637 _(classify_set_interface_ip_table,                                      \
15638   "<intfc> | sw_if_index <nn> table <nn>")                              \
15639 _(classify_set_interface_l2_tables,                                     \
15640   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15641   "  [other-table <nn>]")                                               \
15642 _(get_node_index, "node <node-name")                                    \
15643 _(add_node_next, "node <node-name> next <next-node-name>")              \
15644 _(l2tpv3_create_tunnel,                                                 \
15645   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15646   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15647   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15648 _(l2tpv3_set_tunnel_cookies,                                            \
15649   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15650   "[new_remote_cookie <nn>]\n")                                         \
15651 _(l2tpv3_interface_enable_disable,                                      \
15652   "<intfc> | sw_if_index <nn> enable | disable")                        \
15653 _(l2tpv3_set_lookup_key,                                                \
15654   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15655 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15656 _(vxlan_add_del_tunnel,                                                 \
15657   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15658   " [decap-next l2|ip4|ip6] [del]")                                     \
15659 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15660 _(gre_add_del_tunnel,                                                   \
15661   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
15662 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15663 _(l2_fib_clear_table, "")                                               \
15664 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15665 _(l2_interface_vlan_tag_rewrite,                                        \
15666   "<intfc> | sw_if_index <nn> \n"                                       \
15667   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15668   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15669 _(create_vhost_user_if,                                                 \
15670         "socket <filename> [server] [renumber <dev_instance>] "         \
15671         "[mac <mac_address>]")                                          \
15672 _(modify_vhost_user_if,                                                 \
15673         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15674         "[server] [renumber <dev_instance>]")                           \
15675 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15676 _(sw_interface_vhost_user_dump, "")                                     \
15677 _(show_version, "")                                                     \
15678 _(vxlan_gpe_add_del_tunnel,                                             \
15679   "local <addr> remote <addr> vni <nn>\n"                               \
15680     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15681   "[next-ethernet] [next-nsh]\n")                                       \
15682 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15683 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15684 _(interface_name_renumber,                                              \
15685   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15686 _(input_acl_set_interface,                                              \
15687   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15688   "  [l2-table <nn>] [del]")                                            \
15689 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15690 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15691 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15692 _(ip_dump, "ipv4 | ipv6")                                               \
15693 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15694 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15695   "  spid_id <n> ")                                                     \
15696 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15697   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15698   "  integ_alg <alg> integ_key <hex>")                                  \
15699 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15700   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15701   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15702   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15703 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15704 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15705 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15706   "(auth_data 0x<data> | auth_data <data>)")                            \
15707 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15708   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15709 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15710   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15711   "(local|remote)")                                                     \
15712 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15713 _(delete_loopback,"sw_if_index <nn>")                                   \
15714 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15715 _(map_add_domain,                                                       \
15716   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15717   "ip6-src <ip6addr> "                                                  \
15718   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15719 _(map_del_domain, "index <n>")                                          \
15720 _(map_add_del_rule,                                                     \
15721   "index <n> psid <n> dst <ip6addr> [del]")                             \
15722 _(map_domain_dump, "")                                                  \
15723 _(map_rule_dump, "index <map-domain>")                                  \
15724 _(want_interface_events,  "enable|disable")                             \
15725 _(want_stats,"enable|disable")                                          \
15726 _(get_first_msg_id, "client <name>")                                    \
15727 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15728 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15729   "fib-id <nn> [ip4][ip6][default]")                                    \
15730 _(get_node_graph, " ")                                                  \
15731 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15732 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
15733 _(ioam_disable, "")                                                \
15734 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15735                             " sw_if_index <sw_if_index> p <priority> "  \
15736                             "w <weight>] [del]")                        \
15737 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15738                         "iface <intf> | sw_if_index <sw_if_index> "     \
15739                         "p <priority> w <weight> [del]")                \
15740 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15741                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15742                           "locator-set <locator_name> [del]")           \
15743 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15744   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15745 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15746 _(lisp_gpe_enable_disable, "enable|disable")                            \
15747 _(lisp_enable_disable, "enable|disable")                                \
15748 _(lisp_gpe_add_del_iface, "up|down")                                    \
15749 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
15750                                "[seid <seid>] "                         \
15751                                "rloc <locator> p <prio> "               \
15752                                "w <weight> [rloc <loc> ... ] "          \
15753                                "action <action> [del-all]")             \
15754 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
15755                           "<local-eid>")                                \
15756 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15757 _(lisp_map_request_mode, "src-dst|dst-only")                            \
15758 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15759 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15760 _(lisp_locator_set_dump, "[local | remote]")                            \
15761 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
15762 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15763                        "[local] | [remote]")                            \
15764 _(lisp_eid_table_vni_dump, "")                                          \
15765 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15766 _(lisp_gpe_tunnel_dump, "")                                             \
15767 _(lisp_map_resolver_dump, "")                                           \
15768 _(show_lisp_status, "")                                                 \
15769 _(lisp_get_map_request_itr_rlocs, "")                                   \
15770 _(show_lisp_pitr, "")                                                   \
15771 _(show_lisp_map_request_mode, "")                                       \
15772 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15773 _(af_packet_delete, "name <host interface name>")                       \
15774 _(policer_add_del, "name <policer name> <params> [del]")                \
15775 _(policer_dump, "[name <policer name>]")                                \
15776 _(policer_classify_set_interface,                                       \
15777   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15778   "  [l2-table <nn>] [del]")                                            \
15779 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15780 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15781     "[master|slave]")                                                   \
15782 _(netmap_delete, "name <interface name>")                               \
15783 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15784 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15785 _(mpls_fib_encap_dump, "")                                              \
15786 _(mpls_fib_decap_dump, "")                                              \
15787 _(classify_table_ids, "")                                               \
15788 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15789 _(classify_table_info, "table_id <nn>")                                 \
15790 _(classify_session_dump, "table_id <nn>")                               \
15791 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15792     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15793     "[template_interval <nn>] [udp_checksum]")                          \
15794 _(ipfix_exporter_dump, "")                                              \
15795 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15796 _(ipfix_classify_stream_dump, "")                                       \
15797 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
15798 _(ipfix_classify_table_dump, "")                                        \
15799 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15800 _(pg_create_interface, "if_id <nn>")                                    \
15801 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15802 _(pg_enable_disable, "[stream <id>] disable")                           \
15803 _(ip_source_and_port_range_check_add_del,                               \
15804   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15805 _(ip_source_and_port_range_check_interface_add_del,                     \
15806   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15807   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15808 _(ipsec_gre_add_del_tunnel,                                             \
15809   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15810 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15811 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15812
15813 /* List of command functions, CLI names map directly to functions */
15814 #define foreach_cli_function                                    \
15815 _(comment, "usage: comment <ignore-rest-of-line>")              \
15816 _(dump_interface_table, "usage: dump_interface_table")          \
15817 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15818 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15819 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15820 _(dump_stats_table, "usage: dump_stats_table")                  \
15821 _(dump_macro_table, "usage: dump_macro_table ")                 \
15822 _(dump_node_table, "usage: dump_node_table")                    \
15823 _(echo, "usage: echo <message>")                                \
15824 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15825 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15826 _(help, "usage: help")                                          \
15827 _(q, "usage: quit")                                             \
15828 _(quit, "usage: quit")                                          \
15829 _(search_node_table, "usage: search_node_table <name>...")      \
15830 _(set, "usage: set <variable-name> <value>")                    \
15831 _(script, "usage: script <file-name>")                          \
15832 _(unset, "usage: unset <variable-name>")
15833
15834 #define _(N,n)                                  \
15835     static void vl_api_##n##_t_handler_uni      \
15836     (vl_api_##n##_t * mp)                       \
15837     {                                           \
15838         vat_main_t * vam = &vat_main;           \
15839         if (vam->json_output) {                 \
15840             vl_api_##n##_t_handler_json(mp);    \
15841         } else {                                \
15842             vl_api_##n##_t_handler(mp);         \
15843         }                                       \
15844     }
15845 foreach_vpe_api_reply_msg;
15846 #undef _
15847
15848 void
15849 vat_api_hookup (vat_main_t * vam)
15850 {
15851 #define _(N,n)                                                  \
15852     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15853                            vl_api_##n##_t_handler_uni,          \
15854                            vl_noop_handler,                     \
15855                            vl_api_##n##_t_endian,               \
15856                            vl_api_##n##_t_print,                \
15857                            sizeof(vl_api_##n##_t), 1);
15858   foreach_vpe_api_reply_msg;
15859 #undef _
15860
15861   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15862
15863   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15864
15865   vam->function_by_name = hash_create_string (0, sizeof (uword));
15866
15867   vam->help_by_name = hash_create_string (0, sizeof (uword));
15868
15869   /* API messages we can send */
15870 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15871   foreach_vpe_api_msg;
15872 #undef _
15873
15874   /* Help strings */
15875 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15876   foreach_vpe_api_msg;
15877 #undef _
15878
15879   /* CLI functions */
15880 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15881   foreach_cli_function;
15882 #undef _
15883
15884   /* Help strings */
15885 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15886   foreach_cli_function;
15887 #undef _
15888 }
15889
15890 #undef vl_api_version
15891 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15892 #include <vpp-api/vpe.api.h>
15893 #undef vl_api_version
15894
15895 void
15896 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15897 {
15898   /*
15899    * Send the main API signature in slot 0. This bit of code must
15900    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15901    */
15902   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15903 }
15904
15905 /*
15906  * fd.io coding-style-patch-verification: ON
15907  *
15908  * Local Variables:
15909  * eval: (c-set-style "gnu")
15910  * End:
15911  */