VPP-189 Fix coverity warnings
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1559   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   i32 retval = ntohl (mp->retval);
1563   if (vam->async_mode)
1564     {
1565       vam->async_errors += (retval < 0);
1566     }
1567   else
1568     {
1569       vam->retval = retval;
1570       vam->sw_if_index = ntohl (mp->sw_if_index);
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1576   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_gre_add_del_tunnel_reply_t_handler
1593   (vl_api_gre_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1610   (vl_api_gre_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_create_vhost_user_if_reply_t_handler
1627   (vl_api_create_vhost_user_if_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_create_vhost_user_if_reply_t_handler_json
1644   (vl_api_create_vhost_user_if_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_ip_address_details_t_handler
1661   (vl_api_ip_address_details_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   static ip_address_details_t empty_ip_address_details = { {0} };
1665   ip_address_details_t *address = NULL;
1666   ip_details_t *current_ip_details = NULL;
1667   ip_details_t *details = NULL;
1668
1669   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1670
1671   if (!details || vam->current_sw_if_index >= vec_len (details)
1672       || !details[vam->current_sw_if_index].present)
1673     {
1674       errmsg ("ip address details arrived but not stored\n");
1675       errmsg ("ip_dump should be called first\n");
1676       return;
1677     }
1678
1679   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1680
1681 #define addresses (current_ip_details->addr)
1682
1683   vec_validate_init_empty (addresses, vec_len (addresses),
1684                            empty_ip_address_details);
1685
1686   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1687
1688   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1689   address->prefix_length = mp->prefix_length;
1690 #undef addresses
1691 }
1692
1693 static void vl_api_ip_address_details_t_handler_json
1694   (vl_api_ip_address_details_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   vat_json_node_t *node = NULL;
1698   struct in6_addr ip6;
1699   struct in_addr ip4;
1700
1701   if (VAT_JSON_ARRAY != vam->json_tree.type)
1702     {
1703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1704       vat_json_init_array (&vam->json_tree);
1705     }
1706   node = vat_json_array_add (&vam->json_tree);
1707
1708   vat_json_init_object (node);
1709   if (vam->is_ipv6)
1710     {
1711       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1712       vat_json_object_add_ip6 (node, "ip", ip6);
1713     }
1714   else
1715     {
1716       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1717       vat_json_object_add_ip4 (node, "ip", ip4);
1718     }
1719   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1720 }
1721
1722 static void
1723 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   static ip_details_t empty_ip_details = { 0 };
1727   ip_details_t *ip = NULL;
1728   u32 sw_if_index = ~0;
1729
1730   sw_if_index = ntohl (mp->sw_if_index);
1731
1732   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1733                            sw_if_index, empty_ip_details);
1734
1735   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1736                          sw_if_index);
1737
1738   ip->present = 1;
1739 }
1740
1741 static void
1742 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745
1746   if (VAT_JSON_ARRAY != vam->json_tree.type)
1747     {
1748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1749       vat_json_init_array (&vam->json_tree);
1750     }
1751   vat_json_array_add_uint (&vam->json_tree,
1752                            clib_net_to_host_u32 (mp->sw_if_index));
1753 }
1754
1755 static void vl_api_map_domain_details_t_handler_json
1756   (vl_api_map_domain_details_t * mp)
1757 {
1758   vat_json_node_t *node = NULL;
1759   vat_main_t *vam = &vat_main;
1760   struct in6_addr ip6;
1761   struct in_addr ip4;
1762
1763   if (VAT_JSON_ARRAY != vam->json_tree.type)
1764     {
1765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1766       vat_json_init_array (&vam->json_tree);
1767     }
1768
1769   node = vat_json_array_add (&vam->json_tree);
1770   vat_json_init_object (node);
1771
1772   vat_json_object_add_uint (node, "domain_index",
1773                             clib_net_to_host_u32 (mp->domain_index));
1774   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1775   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1776   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1777   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1778   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1779   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1780   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1781   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1782   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1783   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1784   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1785   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1786   vat_json_object_add_uint (node, "flags", mp->flags);
1787   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1788   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1789 }
1790
1791 static void vl_api_map_domain_details_t_handler
1792   (vl_api_map_domain_details_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795
1796   if (mp->is_translation)
1797     {
1798       fformat (vam->ofp,
1799                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1800                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1801                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1802                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1803                clib_net_to_host_u32 (mp->domain_index));
1804     }
1805   else
1806     {
1807       fformat (vam->ofp,
1808                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1809                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1810                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1811                format_ip6_address, mp->ip6_src,
1812                clib_net_to_host_u32 (mp->domain_index));
1813     }
1814   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1815            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1816            mp->is_translation ? "map-t" : "");
1817 }
1818
1819 static void vl_api_map_rule_details_t_handler_json
1820   (vl_api_map_rule_details_t * mp)
1821 {
1822   struct in6_addr ip6;
1823   vat_json_node_t *node = NULL;
1824   vat_main_t *vam = &vat_main;
1825
1826   if (VAT_JSON_ARRAY != vam->json_tree.type)
1827     {
1828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1829       vat_json_init_array (&vam->json_tree);
1830     }
1831
1832   node = vat_json_array_add (&vam->json_tree);
1833   vat_json_init_object (node);
1834
1835   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1836   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1837   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1838 }
1839
1840 static void
1841 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1845            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1846 }
1847
1848 static void
1849 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1853           "router_addr %U host_mac %U\n",
1854           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1855           format_ip4_address, &mp->host_address,
1856           format_ip4_address, &mp->router_address,
1857           format_ethernet_address, mp->host_mac);
1858 }
1859
1860 static void vl_api_dhcp_compl_event_t_handler_json
1861   (vl_api_dhcp_compl_event_t * mp)
1862 {
1863   /* JSON output not supported */
1864 }
1865
1866 static void
1867 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1868                               u32 counter)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   static u64 default_counter = 0;
1872
1873   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1874                            NULL);
1875   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1876                            sw_if_index, default_counter);
1877   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1878 }
1879
1880 static void
1881 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1882                                 interface_counter_t counter)
1883 {
1884   vat_main_t *vam = &vat_main;
1885   static interface_counter_t default_counter = { 0, };
1886
1887   vec_validate_init_empty (vam->combined_interface_counters,
1888                            vnet_counter_type, NULL);
1889   vec_validate_init_empty (vam->combined_interface_counters
1890                            [vnet_counter_type], sw_if_index, default_counter);
1891   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1892 }
1893
1894 static void vl_api_vnet_interface_counters_t_handler
1895   (vl_api_vnet_interface_counters_t * mp)
1896 {
1897   /* not supported */
1898 }
1899
1900 static void vl_api_vnet_interface_counters_t_handler_json
1901   (vl_api_vnet_interface_counters_t * mp)
1902 {
1903   interface_counter_t counter;
1904   vlib_counter_t *v;
1905   u64 *v_packets;
1906   u64 packets;
1907   u32 count;
1908   u32 first_sw_if_index;
1909   int i;
1910
1911   count = ntohl (mp->count);
1912   first_sw_if_index = ntohl (mp->first_sw_if_index);
1913
1914   if (!mp->is_combined)
1915     {
1916       v_packets = (u64 *) & mp->data;
1917       for (i = 0; i < count; i++)
1918         {
1919           packets =
1920             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1921           set_simple_interface_counter (mp->vnet_counter_type,
1922                                         first_sw_if_index + i, packets);
1923           v_packets++;
1924         }
1925     }
1926   else
1927     {
1928       v = (vlib_counter_t *) & mp->data;
1929       for (i = 0; i < count; i++)
1930         {
1931           counter.packets =
1932             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1933           counter.bytes =
1934             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1935           set_combined_interface_counter (mp->vnet_counter_type,
1936                                           first_sw_if_index + i, counter);
1937           v++;
1938         }
1939     }
1940 }
1941
1942 static u32
1943 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   u32 i;
1947
1948   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1949     {
1950       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1951         {
1952           return i;
1953         }
1954     }
1955   return ~0;
1956 }
1957
1958 static u32
1959 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static void vl_api_vnet_ip4_fib_counters_t_handler
1975   (vl_api_vnet_ip4_fib_counters_t * mp)
1976 {
1977   /* not supported */
1978 }
1979
1980 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1981   (vl_api_vnet_ip4_fib_counters_t * mp)
1982 {
1983   vat_main_t *vam = &vat_main;
1984   vl_api_ip4_fib_counter_t *v;
1985   ip4_fib_counter_t *counter;
1986   struct in_addr ip4;
1987   u32 vrf_id;
1988   u32 vrf_index;
1989   u32 count;
1990   int i;
1991
1992   vrf_id = ntohl (mp->vrf_id);
1993   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1994   if (~0 == vrf_index)
1995     {
1996       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1997       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1998       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1999       vec_validate (vam->ip4_fib_counters, vrf_index);
2000       vam->ip4_fib_counters[vrf_index] = NULL;
2001     }
2002
2003   vec_free (vam->ip4_fib_counters[vrf_index]);
2004   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2005   count = ntohl (mp->count);
2006   for (i = 0; i < count; i++)
2007     {
2008       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2009       counter = &vam->ip4_fib_counters[vrf_index][i];
2010       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2011       counter->address = ip4;
2012       counter->address_length = v->address_length;
2013       counter->packets = clib_net_to_host_u64 (v->packets);
2014       counter->bytes = clib_net_to_host_u64 (v->bytes);
2015       v++;
2016     }
2017 }
2018
2019 static void vl_api_vnet_ip6_fib_counters_t_handler
2020   (vl_api_vnet_ip6_fib_counters_t * mp)
2021 {
2022   /* not supported */
2023 }
2024
2025 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2026   (vl_api_vnet_ip6_fib_counters_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vl_api_ip6_fib_counter_t *v;
2030   ip6_fib_counter_t *counter;
2031   struct in6_addr ip6;
2032   u32 vrf_id;
2033   u32 vrf_index;
2034   u32 count;
2035   int i;
2036
2037   vrf_id = ntohl (mp->vrf_id);
2038   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2039   if (~0 == vrf_index)
2040     {
2041       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2042       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2043       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2044       vec_validate (vam->ip6_fib_counters, vrf_index);
2045       vam->ip6_fib_counters[vrf_index] = NULL;
2046     }
2047
2048   vec_free (vam->ip6_fib_counters[vrf_index]);
2049   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2050   count = ntohl (mp->count);
2051   for (i = 0; i < count; i++)
2052     {
2053       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2054       counter = &vam->ip6_fib_counters[vrf_index][i];
2055       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2056       counter->address = ip6;
2057       counter->address_length = v->address_length;
2058       counter->packets = clib_net_to_host_u64 (v->packets);
2059       counter->bytes = clib_net_to_host_u64 (v->bytes);
2060       v++;
2061     }
2062 }
2063
2064 static void vl_api_get_first_msg_id_reply_t_handler
2065   (vl_api_get_first_msg_id_reply_t * mp)
2066 {
2067   vat_main_t *vam = &vat_main;
2068   i32 retval = ntohl (mp->retval);
2069
2070   if (vam->async_mode)
2071     {
2072       vam->async_errors += (retval < 0);
2073     }
2074   else
2075     {
2076       vam->retval = retval;
2077       vam->result_ready = 1;
2078     }
2079   if (retval >= 0)
2080     {
2081       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2082     }
2083 }
2084
2085 static void vl_api_get_first_msg_id_reply_t_handler_json
2086   (vl_api_get_first_msg_id_reply_t * mp)
2087 {
2088   vat_main_t *vam = &vat_main;
2089   vat_json_node_t node;
2090
2091   vat_json_init_object (&node);
2092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2093   vat_json_object_add_uint (&node, "first_msg_id",
2094                             (uint) ntohs (mp->first_msg_id));
2095
2096   vat_json_print (vam->ofp, &node);
2097   vat_json_free (&node);
2098
2099   vam->retval = ntohl (mp->retval);
2100   vam->result_ready = 1;
2101 }
2102
2103 static void vl_api_get_node_graph_reply_t_handler
2104   (vl_api_get_node_graph_reply_t * mp)
2105 {
2106   vat_main_t *vam = &vat_main;
2107   api_main_t *am = &api_main;
2108   i32 retval = ntohl (mp->retval);
2109   u8 *pvt_copy, *reply;
2110   void *oldheap;
2111   vlib_node_t *node;
2112   int i;
2113
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->result_ready = 1;
2122     }
2123
2124   /* "Should never happen..." */
2125   if (retval != 0)
2126     return;
2127
2128   reply = (u8 *) (mp->reply_in_shmem);
2129   pvt_copy = vec_dup (reply);
2130
2131   /* Toss the shared-memory original... */
2132   pthread_mutex_lock (&am->vlib_rp->mutex);
2133   oldheap = svm_push_data_heap (am->vlib_rp);
2134
2135   vec_free (reply);
2136
2137   svm_pop_heap (oldheap);
2138   pthread_mutex_unlock (&am->vlib_rp->mutex);
2139
2140   if (vam->graph_nodes)
2141     {
2142       hash_free (vam->graph_node_index_by_name);
2143
2144       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2145         {
2146           node = vam->graph_nodes[i];
2147           vec_free (node->name);
2148           vec_free (node->next_nodes);
2149           vec_free (node);
2150         }
2151       vec_free (vam->graph_nodes);
2152     }
2153
2154   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2155   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2156   vec_free (pvt_copy);
2157
2158   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2159     {
2160       node = vam->graph_nodes[i];
2161       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2162     }
2163 }
2164
2165 static void vl_api_get_node_graph_reply_t_handler_json
2166   (vl_api_get_node_graph_reply_t * mp)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   api_main_t *am = &api_main;
2170   void *oldheap;
2171   vat_json_node_t node;
2172   u8 *reply;
2173
2174   /* $$$$ make this real? */
2175   vat_json_init_object (&node);
2176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2177   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2178
2179   reply = (u8 *) (mp->reply_in_shmem);
2180
2181   /* Toss the shared-memory original... */
2182   pthread_mutex_lock (&am->vlib_rp->mutex);
2183   oldheap = svm_push_data_heap (am->vlib_rp);
2184
2185   vec_free (reply);
2186
2187   svm_pop_heap (oldheap);
2188   pthread_mutex_unlock (&am->vlib_rp->mutex);
2189
2190   vat_json_print (vam->ofp, &node);
2191   vat_json_free (&node);
2192
2193   vam->retval = ntohl (mp->retval);
2194   vam->result_ready = 1;
2195 }
2196
2197 static void
2198 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   locator_msg_t loc;
2202   u8 *tmp_str = 0;
2203
2204   memset (&loc, 0, sizeof (loc));
2205   if (vam->noprint_msg)
2206     {
2207       loc.local = mp->local;
2208       loc.priority = mp->priority;
2209       loc.weight = mp->weight;
2210       if (loc.local)
2211         {
2212           loc.sw_if_index = ntohl (mp->sw_if_index);
2213         }
2214       else
2215         {
2216           loc.is_ipv6 = mp->is_ipv6;
2217           clib_memcpy (loc.ip_address, mp->ip_address,
2218                        sizeof (loc.ip_address));
2219         }
2220       vec_add1 (vam->locator_msg, loc);
2221     }
2222   else
2223     {
2224       if (mp->local)
2225         {
2226           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2227                             ntohl (mp->sw_if_index),
2228                             mp->priority, mp->weight);
2229         }
2230       else
2231         {
2232           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2233                             mp->is_ipv6 ? format_ip6_address :
2234                             format_ip4_address,
2235                             mp->ip_address, mp->priority, mp->weight);
2236         }
2237
2238       fformat (vam->ofp, "%s", tmp_str);
2239
2240       vec_free (tmp_str);
2241     }
2242 }
2243
2244 static void
2245 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2246                                             mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   vat_json_node_t *node = NULL;
2250   locator_msg_t loc;
2251   struct in6_addr ip6;
2252   struct in_addr ip4;
2253
2254   memset (&loc, 0, sizeof (loc));
2255   if (vam->noprint_msg)
2256     {
2257       loc.local = mp->local;
2258       loc.priority = mp->priority;
2259       loc.weight = mp->weight;
2260       if (loc.local)
2261         {
2262           loc.sw_if_index = ntohl (mp->sw_if_index);
2263         }
2264       else
2265         {
2266           loc.is_ipv6 = mp->is_ipv6;
2267           clib_memcpy (loc.ip_address, mp->ip_address,
2268                        sizeof (loc.ip_address));
2269         }
2270       vec_add1 (vam->locator_msg, loc);
2271       return;
2272     }
2273
2274   if (VAT_JSON_ARRAY != vam->json_tree.type)
2275     {
2276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2277       vat_json_init_array (&vam->json_tree);
2278     }
2279   node = vat_json_array_add (&vam->json_tree);
2280
2281   vat_json_init_object (node);
2282
2283   if (mp->local)
2284     {
2285       vat_json_object_add_uint (node, "locator_index",
2286                                 ntohl (mp->sw_if_index));
2287     }
2288   else
2289     {
2290       if (mp->is_ipv6)
2291         {
2292           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2293           vat_json_object_add_ip6 (node, "locator", ip6);
2294         }
2295       else
2296         {
2297           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2298           vat_json_object_add_ip4 (node, "locator", ip4);
2299         }
2300     }
2301   vat_json_object_add_uint (node, "priority", mp->priority);
2302   vat_json_object_add_uint (node, "weight", mp->weight);
2303 }
2304
2305 static void
2306 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2307                                            mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   locator_set_msg_t ls;
2311
2312   ls.locator_set_index = ntohl (mp->locator_set_index);
2313   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2314   vec_add1 (vam->locator_set_msg, ls);
2315 }
2316
2317 static void
2318   vl_api_lisp_locator_set_details_t_handler_json
2319   (vl_api_lisp_locator_set_details_t * mp)
2320 {
2321   vat_main_t *vam = &vat_main;
2322   locator_set_msg_t ls;
2323
2324   ls.locator_set_index = ntohl (mp->locator_set_index);
2325   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2326   vec_add1 (vam->locator_set_msg, ls);
2327 }
2328
2329 static void
2330 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   eid_table_t eid_table;
2334
2335   memset (&eid_table, 0, sizeof (eid_table));
2336   eid_table.is_local = mp->is_local;
2337   eid_table.locator_set_index = mp->locator_set_index;
2338   eid_table.eid_type = mp->eid_type;
2339   eid_table.vni = mp->vni;
2340   eid_table.eid_prefix_len = mp->eid_prefix_len;
2341   eid_table.ttl = mp->ttl;
2342   eid_table.authoritative = mp->authoritative;
2343   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2344   vec_add1 (vam->eid_tables, eid_table);
2345 }
2346
2347 static void
2348 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2349                                               * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   eid_table_t eid_table;
2353
2354   memset (&eid_table, 0, sizeof (eid_table));
2355   eid_table.is_local = mp->is_local;
2356   eid_table.locator_set_index = mp->locator_set_index;
2357   eid_table.eid_type = mp->eid_type;
2358   eid_table.vni = mp->vni;
2359   eid_table.eid_prefix_len = mp->eid_prefix_len;
2360   eid_table.ttl = mp->ttl;
2361   eid_table.authoritative = mp->authoritative;
2362   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2363   vec_add1 (vam->eid_tables, eid_table);
2364 }
2365
2366 static void
2367   vl_api_lisp_eid_table_map_details_t_handler
2368   (vl_api_lisp_eid_table_map_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371
2372   u8 *line = format (0, "%=10d%=10d",
2373                      clib_net_to_host_u32 (mp->vni),
2374                      clib_net_to_host_u32 (mp->vrf));
2375   fformat (vam->ofp, "%v\n", line);
2376   vec_free (line);
2377 }
2378
2379 static void
2380   vl_api_lisp_eid_table_map_details_t_handler_json
2381   (vl_api_lisp_eid_table_map_details_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t *node = NULL;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392   vat_json_init_object (node);
2393   vat_json_object_add_uint (node, "vrf", clib_net_to_host_u32 (mp->vrf));
2394   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2395 }
2396
2397
2398
2399 static u8 *
2400 format_decap_next (u8 * s, va_list * args)
2401 {
2402   u32 next_index = va_arg (*args, u32);
2403
2404   switch (next_index)
2405     {
2406     case LISP_GPE_INPUT_NEXT_DROP:
2407       return format (s, "drop");
2408     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2409       return format (s, "ip4");
2410     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2411       return format (s, "ip6");
2412     default:
2413       return format (s, "unknown %d", next_index);
2414     }
2415   return s;
2416 }
2417
2418 static void
2419 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2420                                           mp)
2421 {
2422   vat_main_t *vam = &vat_main;
2423   u8 *iid_str;
2424   u8 *flag_str = NULL;
2425
2426   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2427
2428 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2429   foreach_lisp_gpe_flag_bit;
2430 #undef _
2431
2432   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2433            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2434            mp->tunnels,
2435            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2436            mp->source_ip,
2437            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2438            mp->destination_ip,
2439            ntohl (mp->encap_fib_id),
2440            ntohl (mp->decap_fib_id),
2441            format_decap_next, ntohl (mp->dcap_next),
2442            mp->ver_res >> 6,
2443            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2444
2445   vec_free (iid_str);
2446 }
2447
2448 static void
2449   vl_api_lisp_gpe_tunnel_details_t_handler_json
2450   (vl_api_lisp_gpe_tunnel_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t *node = NULL;
2454   struct in6_addr ip6;
2455   struct in_addr ip4;
2456   u8 *next_decap_str;
2457
2458   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2459
2460   if (VAT_JSON_ARRAY != vam->json_tree.type)
2461     {
2462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2463       vat_json_init_array (&vam->json_tree);
2464     }
2465   node = vat_json_array_add (&vam->json_tree);
2466
2467   vat_json_init_object (node);
2468   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2469   if (mp->is_ipv6)
2470     {
2471       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2472       vat_json_object_add_ip6 (node, "source address", ip6);
2473       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2474       vat_json_object_add_ip6 (node, "destination address", ip6);
2475     }
2476   else
2477     {
2478       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2479       vat_json_object_add_ip4 (node, "source address", ip4);
2480       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2481       vat_json_object_add_ip4 (node, "destination address", ip4);
2482     }
2483   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2484   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2485   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2486   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2487   vat_json_object_add_uint (node, "flags", mp->flags);
2488   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2489   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2490   vat_json_object_add_uint (node, "res", mp->res);
2491   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2492
2493   vec_free (next_decap_str);
2494 }
2495
2496 static void
2497 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2498                                             * mp)
2499 {
2500   vat_main_t *vam = &vat_main;
2501
2502   fformat (vam->ofp, "%=20U\n",
2503            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2504            mp->ip_address);
2505 }
2506
2507 static void
2508   vl_api_lisp_map_resolver_details_t_handler_json
2509   (vl_api_lisp_map_resolver_details_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t *node = NULL;
2513   struct in6_addr ip6;
2514   struct in_addr ip4;
2515
2516   if (VAT_JSON_ARRAY != vam->json_tree.type)
2517     {
2518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2519       vat_json_init_array (&vam->json_tree);
2520     }
2521   node = vat_json_array_add (&vam->json_tree);
2522
2523   vat_json_init_object (node);
2524   if (mp->is_ipv6)
2525     {
2526       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2527       vat_json_object_add_ip6 (node, "map resolver", ip6);
2528     }
2529   else
2530     {
2531       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2532       vat_json_object_add_ip4 (node, "map resolver", ip4);
2533     }
2534 }
2535
2536 static void
2537   vl_api_show_lisp_status_reply_t_handler
2538   (vl_api_show_lisp_status_reply_t * mp)
2539 {
2540   vat_main_t *vam = &vat_main;
2541   i32 retval = ntohl (mp->retval);
2542
2543   if (0 <= retval)
2544     {
2545       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2546                mp->feature_status ? "enabled" : "disabled",
2547                mp->gpe_status ? "enabled" : "disabled");
2548     }
2549
2550   vam->retval = retval;
2551   vam->result_ready = 1;
2552 }
2553
2554 static void
2555   vl_api_show_lisp_status_reply_t_handler_json
2556   (vl_api_show_lisp_status_reply_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t node;
2560   u8 *gpe_status = NULL;
2561   u8 *feature_status = NULL;
2562
2563   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2564   feature_status = format (0, "%s",
2565                            mp->feature_status ? "enabled" : "disabled");
2566   vec_add1 (gpe_status, 0);
2567   vec_add1 (feature_status, 0);
2568
2569   vat_json_init_object (&node);
2570   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2571   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2572
2573   vec_free (gpe_status);
2574   vec_free (feature_status);
2575
2576   vat_json_print (vam->ofp, &node);
2577   vat_json_free (&node);
2578
2579   vam->retval = ntohl (mp->retval);
2580   vam->result_ready = 1;
2581 }
2582
2583 static void
2584   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2585   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   i32 retval = ntohl (mp->retval);
2589
2590   if (retval >= 0)
2591     {
2592       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2593     }
2594
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2601   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604   vat_json_node_t *node = NULL;
2605
2606   if (VAT_JSON_ARRAY != vam->json_tree.type)
2607     {
2608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2609       vat_json_init_array (&vam->json_tree);
2610     }
2611   node = vat_json_array_add (&vam->json_tree);
2612
2613   vat_json_init_object (node);
2614   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2615
2616   vat_json_print (vam->ofp, node);
2617   vat_json_free (node);
2618
2619   vam->retval = ntohl (mp->retval);
2620   vam->result_ready = 1;
2621 }
2622
2623 static void
2624 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2625 {
2626   vat_main_t *vam = &vat_main;
2627   i32 retval = ntohl (mp->retval);
2628
2629   if (0 <= retval)
2630     {
2631       fformat (vam->ofp, "%-20s%-16s\n",
2632                mp->status ? "enabled" : "disabled",
2633                mp->status ? (char *) mp->locator_set_name : "");
2634     }
2635
2636   vam->retval = retval;
2637   vam->result_ready = 1;
2638 }
2639
2640 static void
2641 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2642                                             mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   vat_json_node_t node;
2646   u8 *status = 0;
2647
2648   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2649   vec_add1 (status, 0);
2650
2651   vat_json_init_object (&node);
2652   vat_json_object_add_string_copy (&node, "status", status);
2653   if (mp->status)
2654     {
2655       vat_json_object_add_string_copy (&node, "locator_set",
2656                                        mp->locator_set_name);
2657     }
2658
2659   vec_free (status);
2660
2661   vat_json_print (vam->ofp, &node);
2662   vat_json_free (&node);
2663
2664   vam->retval = ntohl (mp->retval);
2665   vam->result_ready = 1;
2666 }
2667
2668 static u8 *
2669 format_policer_type (u8 * s, va_list * va)
2670 {
2671   u32 i = va_arg (*va, u32);
2672
2673   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2674     s = format (s, "1r2c");
2675   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2676     s = format (s, "1r3c");
2677   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2678     s = format (s, "2r3c-2698");
2679   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2680     s = format (s, "2r3c-4115");
2681   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2682     s = format (s, "2r3c-mef5cf1");
2683   else
2684     s = format (s, "ILLEGAL");
2685   return s;
2686 }
2687
2688 static u8 *
2689 format_policer_rate_type (u8 * s, va_list * va)
2690 {
2691   u32 i = va_arg (*va, u32);
2692
2693   if (i == SSE2_QOS_RATE_KBPS)
2694     s = format (s, "kbps");
2695   else if (i == SSE2_QOS_RATE_PPS)
2696     s = format (s, "pps");
2697   else
2698     s = format (s, "ILLEGAL");
2699   return s;
2700 }
2701
2702 static u8 *
2703 format_policer_round_type (u8 * s, va_list * va)
2704 {
2705   u32 i = va_arg (*va, u32);
2706
2707   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2708     s = format (s, "closest");
2709   else if (i == SSE2_QOS_ROUND_TO_UP)
2710     s = format (s, "up");
2711   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2712     s = format (s, "down");
2713   else
2714     s = format (s, "ILLEGAL");
2715   return s;
2716 }
2717
2718 static u8 *
2719 format_policer_action_type (u8 * s, va_list * va)
2720 {
2721   u32 i = va_arg (*va, u32);
2722
2723   if (i == SSE2_QOS_ACTION_DROP)
2724     s = format (s, "drop");
2725   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2726     s = format (s, "transmit");
2727   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2728     s = format (s, "mark-and-transmit");
2729   else
2730     s = format (s, "ILLEGAL");
2731   return s;
2732 }
2733
2734 static u8 *
2735 format_dscp (u8 * s, va_list * va)
2736 {
2737   u32 i = va_arg (*va, u32);
2738   char *t = 0;
2739
2740   switch (i)
2741     {
2742 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2743       foreach_vnet_dscp
2744 #undef _
2745     default:
2746       return format (s, "ILLEGAL");
2747     }
2748   s = format (s, "%s", t);
2749   return s;
2750 }
2751
2752 static void
2753 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2754 {
2755   vat_main_t *vam = &vat_main;
2756   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2757
2758   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2759     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2760   else
2761     conform_dscp_str = format (0, "");
2762
2763   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2764     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2765   else
2766     exceed_dscp_str = format (0, "");
2767
2768   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2769     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2770   else
2771     violate_dscp_str = format (0, "");
2772
2773   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2774            "rate type %U, round type %U, %s rate, %s color-aware, "
2775            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2776            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2777            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2778            mp->name,
2779            format_policer_type, mp->type,
2780            ntohl (mp->cir),
2781            ntohl (mp->eir),
2782            clib_net_to_host_u64 (mp->cb),
2783            clib_net_to_host_u64 (mp->eb),
2784            format_policer_rate_type, mp->rate_type,
2785            format_policer_round_type, mp->round_type,
2786            mp->single_rate ? "single" : "dual",
2787            mp->color_aware ? "is" : "not",
2788            ntohl (mp->cir_tokens_per_period),
2789            ntohl (mp->pir_tokens_per_period),
2790            ntohl (mp->scale),
2791            ntohl (mp->current_limit),
2792            ntohl (mp->current_bucket),
2793            ntohl (mp->extended_limit),
2794            ntohl (mp->extended_bucket),
2795            clib_net_to_host_u64 (mp->last_update_time),
2796            format_policer_action_type, mp->conform_action_type,
2797            conform_dscp_str,
2798            format_policer_action_type, mp->exceed_action_type,
2799            exceed_dscp_str,
2800            format_policer_action_type, mp->violate_action_type,
2801            violate_dscp_str);
2802
2803   vec_free (conform_dscp_str);
2804   vec_free (exceed_dscp_str);
2805   vec_free (violate_dscp_str);
2806 }
2807
2808 static void vl_api_policer_details_t_handler_json
2809   (vl_api_policer_details_t * mp)
2810 {
2811   vat_main_t *vam = &vat_main;
2812   vat_json_node_t *node;
2813   u8 *rate_type_str, *round_type_str, *type_str;
2814   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2815
2816   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2817   round_type_str =
2818     format (0, "%U", format_policer_round_type, mp->round_type);
2819   type_str = format (0, "%U", format_policer_type, mp->type);
2820   conform_action_str = format (0, "%U", format_policer_action_type,
2821                                mp->conform_action_type);
2822   exceed_action_str = format (0, "%U", format_policer_action_type,
2823                               mp->exceed_action_type);
2824   violate_action_str = format (0, "%U", format_policer_action_type,
2825                                mp->violate_action_type);
2826
2827   if (VAT_JSON_ARRAY != vam->json_tree.type)
2828     {
2829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2830       vat_json_init_array (&vam->json_tree);
2831     }
2832   node = vat_json_array_add (&vam->json_tree);
2833
2834   vat_json_init_object (node);
2835   vat_json_object_add_string_copy (node, "name", mp->name);
2836   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2837   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2838   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2839   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2840   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2841   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2842   vat_json_object_add_string_copy (node, "type", type_str);
2843   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2844   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2845   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2846   vat_json_object_add_uint (node, "cir_tokens_per_period",
2847                             ntohl (mp->cir_tokens_per_period));
2848   vat_json_object_add_uint (node, "eir_tokens_per_period",
2849                             ntohl (mp->pir_tokens_per_period));
2850   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2851   vat_json_object_add_uint (node, "current_bucket",
2852                             ntohl (mp->current_bucket));
2853   vat_json_object_add_uint (node, "extended_limit",
2854                             ntohl (mp->extended_limit));
2855   vat_json_object_add_uint (node, "extended_bucket",
2856                             ntohl (mp->extended_bucket));
2857   vat_json_object_add_uint (node, "last_update_time",
2858                             ntohl (mp->last_update_time));
2859   vat_json_object_add_string_copy (node, "conform_action",
2860                                    conform_action_str);
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     {
2863       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2864       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2865       vec_free (dscp_str);
2866     }
2867   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2868   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2869     {
2870       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2871       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2872       vec_free (dscp_str);
2873     }
2874   vat_json_object_add_string_copy (node, "violate_action",
2875                                    violate_action_str);
2876   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2877     {
2878       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2879       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2880       vec_free (dscp_str);
2881     }
2882
2883   vec_free (rate_type_str);
2884   vec_free (round_type_str);
2885   vec_free (type_str);
2886   vec_free (conform_action_str);
2887   vec_free (exceed_action_str);
2888   vec_free (violate_action_str);
2889 }
2890
2891 static void
2892 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2893                                            mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   int i, count = ntohl (mp->count);
2897
2898   if (count > 0)
2899     fformat (vam->ofp, "classify table ids (%d) : ", count);
2900   for (i = 0; i < count; i++)
2901     {
2902       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2903       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2904     }
2905   vam->retval = ntohl (mp->retval);
2906   vam->result_ready = 1;
2907 }
2908
2909 static void
2910   vl_api_classify_table_ids_reply_t_handler_json
2911   (vl_api_classify_table_ids_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int i, count = ntohl (mp->count);
2915
2916   if (count > 0)
2917     {
2918       vat_json_node_t node;
2919
2920       vat_json_init_object (&node);
2921       for (i = 0; i < count; i++)
2922         {
2923           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2924         }
2925       vat_json_print (vam->ofp, &node);
2926       vat_json_free (&node);
2927     }
2928   vam->retval = ntohl (mp->retval);
2929   vam->result_ready = 1;
2930 }
2931
2932 static void
2933   vl_api_classify_table_by_interface_reply_t_handler
2934   (vl_api_classify_table_by_interface_reply_t * mp)
2935 {
2936   vat_main_t *vam = &vat_main;
2937   u32 table_id;
2938
2939   table_id = ntohl (mp->l2_table_id);
2940   if (table_id != ~0)
2941     fformat (vam->ofp, "l2 table id : %d\n", table_id);
2942   else
2943     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2944   table_id = ntohl (mp->ip4_table_id);
2945   if (table_id != ~0)
2946     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2947   else
2948     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2949   table_id = ntohl (mp->ip6_table_id);
2950   if (table_id != ~0)
2951     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2952   else
2953     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2954   vam->retval = ntohl (mp->retval);
2955   vam->result_ready = 1;
2956 }
2957
2958 static void
2959   vl_api_classify_table_by_interface_reply_t_handler_json
2960   (vl_api_classify_table_by_interface_reply_t * mp)
2961 {
2962   vat_main_t *vam = &vat_main;
2963   vat_json_node_t node;
2964
2965   vat_json_init_object (&node);
2966
2967   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2968   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2969   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2970
2971   vat_json_print (vam->ofp, &node);
2972   vat_json_free (&node);
2973
2974   vam->retval = ntohl (mp->retval);
2975   vam->result_ready = 1;
2976 }
2977
2978 static void vl_api_policer_add_del_reply_t_handler
2979   (vl_api_policer_add_del_reply_t * mp)
2980 {
2981   vat_main_t *vam = &vat_main;
2982   i32 retval = ntohl (mp->retval);
2983   if (vam->async_mode)
2984     {
2985       vam->async_errors += (retval < 0);
2986     }
2987   else
2988     {
2989       vam->retval = retval;
2990       vam->result_ready = 1;
2991       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2992         /*
2993          * Note: this is just barely thread-safe, depends on
2994          * the main thread spinning waiting for an answer...
2995          */
2996         errmsg ("policer index %d\n", ntohl (mp->policer_index));
2997     }
2998 }
2999
3000 static void vl_api_policer_add_del_reply_t_handler_json
3001   (vl_api_policer_add_del_reply_t * mp)
3002 {
3003   vat_main_t *vam = &vat_main;
3004   vat_json_node_t node;
3005
3006   vat_json_init_object (&node);
3007   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3008   vat_json_object_add_uint (&node, "policer_index",
3009                             ntohl (mp->policer_index));
3010
3011   vat_json_print (vam->ofp, &node);
3012   vat_json_free (&node);
3013
3014   vam->retval = ntohl (mp->retval);
3015   vam->result_ready = 1;
3016 }
3017
3018 /* Format hex dump. */
3019 u8 *
3020 format_hex_bytes (u8 * s, va_list * va)
3021 {
3022   u8 *bytes = va_arg (*va, u8 *);
3023   int n_bytes = va_arg (*va, int);
3024   uword i;
3025
3026   /* Print short or long form depending on byte count. */
3027   uword short_form = n_bytes <= 32;
3028   uword indent = format_get_indent (s);
3029
3030   if (n_bytes == 0)
3031     return s;
3032
3033   for (i = 0; i < n_bytes; i++)
3034     {
3035       if (!short_form && (i % 32) == 0)
3036         s = format (s, "%08x: ", i);
3037       s = format (s, "%02x", bytes[i]);
3038       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3039         s = format (s, "\n%U", format_white_space, indent);
3040     }
3041
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3047                                             * mp)
3048 {
3049   vat_main_t *vam = &vat_main;
3050   i32 retval = ntohl (mp->retval);
3051   if (retval == 0)
3052     {
3053       fformat (vam->ofp, "classify table info :\n");
3054       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3055                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3056                ntohl (mp->miss_next_index));
3057       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3058                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3059                ntohl (mp->match_n_vectors));
3060       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3061                ntohl (mp->mask_length));
3062     }
3063   vam->retval = retval;
3064   vam->result_ready = 1;
3065 }
3066
3067 static void
3068   vl_api_classify_table_info_reply_t_handler_json
3069   (vl_api_classify_table_info_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   vat_json_node_t node;
3073
3074   i32 retval = ntohl (mp->retval);
3075   if (retval == 0)
3076     {
3077       vat_json_init_object (&node);
3078
3079       vat_json_object_add_int (&node, "sessions",
3080                                ntohl (mp->active_sessions));
3081       vat_json_object_add_int (&node, "nexttbl",
3082                                ntohl (mp->next_table_index));
3083       vat_json_object_add_int (&node, "nextnode",
3084                                ntohl (mp->miss_next_index));
3085       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3086       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3087       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3088       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3089                       ntohl (mp->mask_length), 0);
3090       vat_json_object_add_string_copy (&node, "mask", s);
3091
3092       vat_json_print (vam->ofp, &node);
3093       vat_json_free (&node);
3094     }
3095   vam->retval = ntohl (mp->retval);
3096   vam->result_ready = 1;
3097 }
3098
3099 static void
3100 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3101                                            mp)
3102 {
3103   vat_main_t *vam = &vat_main;
3104
3105   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3106            ntohl (mp->hit_next_index), ntohl (mp->advance),
3107            ntohl (mp->opaque_index));
3108   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3109            ntohl (mp->match_length));
3110 }
3111
3112 static void
3113   vl_api_classify_session_details_t_handler_json
3114   (vl_api_classify_session_details_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t *node = NULL;
3118
3119   if (VAT_JSON_ARRAY != vam->json_tree.type)
3120     {
3121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3122       vat_json_init_array (&vam->json_tree);
3123     }
3124   node = vat_json_array_add (&vam->json_tree);
3125
3126   vat_json_init_object (node);
3127   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3128   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3129   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3130   u8 *s =
3131     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3132             0);
3133   vat_json_object_add_string_copy (node, "match", s);
3134 }
3135
3136 static void vl_api_pg_create_interface_reply_t_handler
3137   (vl_api_pg_create_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140
3141   vam->retval = ntohl (mp->retval);
3142   vam->result_ready = 1;
3143 }
3144
3145 static void vl_api_pg_create_interface_reply_t_handler_json
3146   (vl_api_pg_create_interface_reply_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t node;
3150
3151   i32 retval = ntohl (mp->retval);
3152   if (retval == 0)
3153     {
3154       vat_json_init_object (&node);
3155
3156       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_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 static void vl_api_policer_classify_details_t_handler
3166   (vl_api_policer_classify_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3171            ntohl (mp->table_index));
3172 }
3173
3174 static void vl_api_policer_classify_details_t_handler_json
3175   (vl_api_policer_classify_details_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t *node;
3179
3180   if (VAT_JSON_ARRAY != vam->json_tree.type)
3181     {
3182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3183       vat_json_init_array (&vam->json_tree);
3184     }
3185   node = vat_json_array_add (&vam->json_tree);
3186
3187   vat_json_init_object (node);
3188   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3189   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3190 }
3191
3192
3193 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3194 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3195 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3196 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3197
3198 /*
3199  * Generate boilerplate reply handlers, which
3200  * dig the return value out of the xxx_reply_t API message,
3201  * stick it into vam->retval, and set vam->result_ready
3202  *
3203  * Could also do this by pointing N message decode slots at
3204  * a single function, but that could break in subtle ways.
3205  */
3206
3207 #define foreach_standard_reply_retval_handler           \
3208 _(sw_interface_set_flags_reply)                         \
3209 _(sw_interface_add_del_address_reply)                   \
3210 _(sw_interface_set_table_reply)                         \
3211 _(sw_interface_set_vpath_reply)                         \
3212 _(sw_interface_set_l2_bridge_reply)                     \
3213 _(bridge_domain_add_del_reply)                          \
3214 _(sw_interface_set_l2_xconnect_reply)                   \
3215 _(l2fib_add_del_reply)                                  \
3216 _(ip_add_del_route_reply)                               \
3217 _(proxy_arp_add_del_reply)                              \
3218 _(proxy_arp_intfc_enable_disable_reply)                 \
3219 _(mpls_add_del_encap_reply)                             \
3220 _(mpls_add_del_decap_reply)                             \
3221 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3222 _(sw_interface_set_unnumbered_reply)                    \
3223 _(ip_neighbor_add_del_reply)                            \
3224 _(reset_vrf_reply)                                      \
3225 _(oam_add_del_reply)                                    \
3226 _(reset_fib_reply)                                      \
3227 _(dhcp_proxy_config_reply)                              \
3228 _(dhcp_proxy_config_2_reply)                            \
3229 _(dhcp_proxy_set_vss_reply)                             \
3230 _(dhcp_client_config_reply)                             \
3231 _(set_ip_flow_hash_reply)                               \
3232 _(sw_interface_ip6_enable_disable_reply)                \
3233 _(sw_interface_ip6_set_link_local_address_reply)        \
3234 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3235 _(sw_interface_ip6nd_ra_config_reply)                   \
3236 _(set_arp_neighbor_limit_reply)                         \
3237 _(l2_patch_add_del_reply)                               \
3238 _(sr_tunnel_add_del_reply)                              \
3239 _(sr_policy_add_del_reply)                              \
3240 _(sr_multicast_map_add_del_reply)                       \
3241 _(classify_add_del_session_reply)                       \
3242 _(classify_set_interface_ip_table_reply)                \
3243 _(classify_set_interface_l2_tables_reply)               \
3244 _(l2tpv3_set_tunnel_cookies_reply)                      \
3245 _(l2tpv3_interface_enable_disable_reply)                \
3246 _(l2tpv3_set_lookup_key_reply)                          \
3247 _(l2_fib_clear_table_reply)                             \
3248 _(l2_interface_efp_filter_reply)                        \
3249 _(l2_interface_vlan_tag_rewrite_reply)                  \
3250 _(modify_vhost_user_if_reply)                           \
3251 _(delete_vhost_user_if_reply)                           \
3252 _(want_ip4_arp_events_reply)                            \
3253 _(input_acl_set_interface_reply)                        \
3254 _(ipsec_spd_add_del_reply)                              \
3255 _(ipsec_interface_add_del_spd_reply)                    \
3256 _(ipsec_spd_add_del_entry_reply)                        \
3257 _(ipsec_sad_add_del_entry_reply)                        \
3258 _(ipsec_sa_set_key_reply)                               \
3259 _(ikev2_profile_add_del_reply)                          \
3260 _(ikev2_profile_set_auth_reply)                         \
3261 _(ikev2_profile_set_id_reply)                           \
3262 _(ikev2_profile_set_ts_reply)                           \
3263 _(ikev2_set_local_key_reply)                            \
3264 _(delete_loopback_reply)                                \
3265 _(bd_ip_mac_add_del_reply)                              \
3266 _(map_del_domain_reply)                                 \
3267 _(map_add_del_rule_reply)                               \
3268 _(want_interface_events_reply)                          \
3269 _(want_stats_reply)                                     \
3270 _(cop_interface_enable_disable_reply)                   \
3271 _(cop_whitelist_enable_disable_reply)                   \
3272 _(sw_interface_clear_stats_reply)                       \
3273 _(trace_profile_add_reply)                              \
3274 _(trace_profile_apply_reply)                            \
3275 _(trace_profile_del_reply)                              \
3276 _(lisp_add_del_locator_set_reply)                       \
3277 _(lisp_add_del_locator_reply)                           \
3278 _(lisp_add_del_local_eid_reply)                         \
3279 _(lisp_add_del_remote_mapping_reply)                    \
3280 _(lisp_add_del_adjacency_reply)                         \
3281 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3282 _(lisp_add_del_map_resolver_reply)                      \
3283 _(lisp_gpe_enable_disable_reply)                        \
3284 _(lisp_gpe_add_del_iface_reply)                         \
3285 _(lisp_enable_disable_reply)                            \
3286 _(lisp_pitr_set_locator_set_reply)                      \
3287 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3288 _(lisp_eid_table_add_del_map_reply)                     \
3289 _(vxlan_gpe_add_del_tunnel_reply)                       \
3290 _(af_packet_delete_reply)                               \
3291 _(policer_classify_set_interface_reply)                 \
3292 _(netmap_create_reply)                                  \
3293 _(netmap_delete_reply)                                  \
3294 _(ipfix_enable_reply)                                   \
3295 _(pg_capture_reply)                                     \
3296 _(pg_enable_disable_reply)                              \
3297 _(ip_source_and_port_range_check_add_del_reply)         \
3298 _(ip_source_and_port_range_check_interface_add_del_reply)
3299
3300 #define _(n)                                    \
3301     static void vl_api_##n##_t_handler          \
3302     (vl_api_##n##_t * mp)                       \
3303     {                                           \
3304         vat_main_t * vam = &vat_main;           \
3305         i32 retval = ntohl(mp->retval);         \
3306         if (vam->async_mode) {                  \
3307             vam->async_errors += (retval < 0);  \
3308         } else {                                \
3309             vam->retval = retval;               \
3310             vam->result_ready = 1;              \
3311         }                                       \
3312     }
3313 foreach_standard_reply_retval_handler;
3314 #undef _
3315
3316 #define _(n)                                    \
3317     static void vl_api_##n##_t_handler_json     \
3318     (vl_api_##n##_t * mp)                       \
3319     {                                           \
3320         vat_main_t * vam = &vat_main;           \
3321         vat_json_node_t node;                   \
3322         vat_json_init_object(&node);            \
3323         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3324         vat_json_print(vam->ofp, &node);        \
3325         vam->retval = ntohl(mp->retval);        \
3326         vam->result_ready = 1;                  \
3327     }
3328 foreach_standard_reply_retval_handler;
3329 #undef _
3330
3331 /*
3332  * Table of message reply handlers, must include boilerplate handlers
3333  * we just generated
3334  */
3335
3336 #define foreach_vpe_api_reply_msg                                       \
3337 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3338 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3339 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3340 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3341 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3342 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3343 _(CLI_REPLY, cli_reply)                                                 \
3344 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3345   sw_interface_add_del_address_reply)                                   \
3346 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3347 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3348 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3349   sw_interface_set_l2_xconnect_reply)                                   \
3350 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3351   sw_interface_set_l2_bridge_reply)                                     \
3352 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3353 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3354 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3355 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3356 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3357 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3358 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3359 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3360 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3361 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3362 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3363 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3364 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3365   proxy_arp_intfc_enable_disable_reply)                                 \
3366 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3367 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3368 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3369 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3370   mpls_ethernet_add_del_tunnel_reply)                                   \
3371 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3372   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3373 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3374   sw_interface_set_unnumbered_reply)                                    \
3375 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3376 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3377 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3378 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3379 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3380 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3381 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3382 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3383 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3384 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3385 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3386 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3387   sw_interface_ip6_enable_disable_reply)                                \
3388 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3389   sw_interface_ip6_set_link_local_address_reply)                        \
3390 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3391   sw_interface_ip6nd_ra_prefix_reply)                                   \
3392 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3393   sw_interface_ip6nd_ra_config_reply)                                   \
3394 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3395 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3396 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3397 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3398 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3399 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3400 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3401 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3402 classify_set_interface_ip_table_reply)                                  \
3403 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3404   classify_set_interface_l2_tables_reply)                               \
3405 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3406 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3407 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3408 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3409 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3410   l2tpv3_interface_enable_disable_reply)                                \
3411 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3412 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3413 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3414 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3415 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3416 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3417 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3418 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3419 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3420 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3421 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3422 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3423 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3424 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3425 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3426 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3427 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3428 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3429 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3430 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3431 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3432 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3433 _(IP_DETAILS, ip_details)                                               \
3434 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3435 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3436 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3437 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3438 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3439 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3440 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3441 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3442 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3443 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3444 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3445 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3446 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3447 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3448 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3449 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3450 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3451 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3452 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3453 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3454 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3455 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3456 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3457 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3458 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3459 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3460 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3461 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3462 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3463 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3464 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3465 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3466 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3467 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3468 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3469 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3470 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3471 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3472 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3473 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3474 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3475 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3476 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3477 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3478 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3479 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3480 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3481 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3482 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3483 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3484 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3485   lisp_add_del_map_request_itr_rlocs_reply)                             \
3486 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3487   lisp_get_map_request_itr_rlocs_reply)                                 \
3488 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3489 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3490 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3491 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3492 _(POLICER_DETAILS, policer_details)                                     \
3493 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3494 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3495 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3496 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3497 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3498 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3499 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3500 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3501 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3502 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3503 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3504 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3505 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3506 _(IPFIX_DETAILS, ipfix_details)                                         \
3507 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3508 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3509 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3510 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3511 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3512  ip_source_and_port_range_check_add_del_reply)                          \
3513 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3514  ip_source_and_port_range_check_interface_add_del_reply)
3515
3516 /* M: construct, but don't yet send a message */
3517
3518 #define M(T,t)                                  \
3519 do {                                            \
3520     vam->result_ready = 0;                      \
3521     mp = vl_msg_api_alloc(sizeof(*mp));         \
3522     memset (mp, 0, sizeof (*mp));               \
3523     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3524     mp->client_index = vam->my_client_index;    \
3525 } while(0);
3526
3527 #define M2(T,t,n)                               \
3528 do {                                            \
3529     vam->result_ready = 0;                      \
3530     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3531     memset (mp, 0, sizeof (*mp));               \
3532     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3533     mp->client_index = vam->my_client_index;    \
3534 } while(0);
3535
3536
3537 /* S: send a message */
3538 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3539
3540 /* W: wait for results, with timeout */
3541 #define W                                       \
3542 do {                                            \
3543     timeout = vat_time_now (vam) + 1.0;         \
3544                                                 \
3545     while (vat_time_now (vam) < timeout) {      \
3546         if (vam->result_ready == 1) {           \
3547             return (vam->retval);               \
3548         }                                       \
3549     }                                           \
3550     return -99;                                 \
3551 } while(0);
3552
3553 /* W2: wait for results, with timeout */
3554 #define W2(body)                                \
3555 do {                                            \
3556     timeout = vat_time_now (vam) + 1.0;         \
3557                                                 \
3558     while (vat_time_now (vam) < timeout) {      \
3559         if (vam->result_ready == 1) {           \
3560           (body);                               \
3561           return (vam->retval);                 \
3562         }                                       \
3563     }                                           \
3564     return -99;                                 \
3565 } while(0);
3566
3567 /* W_L: wait for results, with timeout */
3568 #define W_L(body)                               \
3569 do {                                            \
3570     timeout = vat_time_now (vam) + 1.0;         \
3571                                                 \
3572     while (vat_time_now (vam) < timeout) {      \
3573         if (vam->result_ready == 1) {           \
3574           (body);                               \
3575           return (vam->retval);                 \
3576         }                                       \
3577     }                                           \
3578     vam->noprint_msg = 0;     \
3579     return -99;                                 \
3580 } while(0);
3581
3582 typedef struct
3583 {
3584   u8 *name;
3585   u32 value;
3586 } name_sort_t;
3587
3588
3589 #define STR_VTR_OP_CASE(op)     \
3590     case L2_VTR_ ## op:         \
3591         return "" # op;
3592
3593 static const char *
3594 str_vtr_op (u32 vtr_op)
3595 {
3596   switch (vtr_op)
3597     {
3598       STR_VTR_OP_CASE (DISABLED);
3599       STR_VTR_OP_CASE (PUSH_1);
3600       STR_VTR_OP_CASE (PUSH_2);
3601       STR_VTR_OP_CASE (POP_1);
3602       STR_VTR_OP_CASE (POP_2);
3603       STR_VTR_OP_CASE (TRANSLATE_1_1);
3604       STR_VTR_OP_CASE (TRANSLATE_1_2);
3605       STR_VTR_OP_CASE (TRANSLATE_2_1);
3606       STR_VTR_OP_CASE (TRANSLATE_2_2);
3607     }
3608
3609   return "UNKNOWN";
3610 }
3611
3612 static int
3613 dump_sub_interface_table (vat_main_t * vam)
3614 {
3615   const sw_interface_subif_t *sub = NULL;
3616
3617   if (vam->json_output)
3618     {
3619       clib_warning
3620         ("JSON output supported only for VPE API calls and dump_stats_table");
3621       return -99;
3622     }
3623
3624   fformat (vam->ofp,
3625            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3626            "Interface", "sw_if_index",
3627            "sub id", "dot1ad", "tags", "outer id",
3628            "inner id", "exact", "default", "outer any", "inner any");
3629
3630   vec_foreach (sub, vam->sw_if_subif_table)
3631   {
3632     fformat (vam->ofp,
3633              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3634              sub->interface_name,
3635              sub->sw_if_index,
3636              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3637              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3638              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3639              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3640     if (sub->vtr_op != L2_VTR_DISABLED)
3641       {
3642         fformat (vam->ofp,
3643                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3644                  "tag1: %d tag2: %d ]\n",
3645                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3646                  sub->vtr_tag1, sub->vtr_tag2);
3647       }
3648   }
3649
3650   return 0;
3651 }
3652
3653 static int
3654 name_sort_cmp (void *a1, void *a2)
3655 {
3656   name_sort_t *n1 = a1;
3657   name_sort_t *n2 = a2;
3658
3659   return strcmp ((char *) n1->name, (char *) n2->name);
3660 }
3661
3662 static int
3663 dump_interface_table (vat_main_t * vam)
3664 {
3665   hash_pair_t *p;
3666   name_sort_t *nses = 0, *ns;
3667
3668   if (vam->json_output)
3669     {
3670       clib_warning
3671         ("JSON output supported only for VPE API calls and dump_stats_table");
3672       return -99;
3673     }
3674
3675   /* *INDENT-OFF* */
3676   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3677   ({
3678     vec_add2 (nses, ns, 1);
3679     ns->name = (u8 *)(p->key);
3680     ns->value = (u32) p->value[0];
3681   }));
3682   /* *INDENT-ON* */
3683
3684   vec_sort_with_function (nses, name_sort_cmp);
3685
3686   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3687   vec_foreach (ns, nses)
3688   {
3689     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3690   }
3691   vec_free (nses);
3692   return 0;
3693 }
3694
3695 static int
3696 dump_ip_table (vat_main_t * vam, int is_ipv6)
3697 {
3698   const ip_details_t *det = NULL;
3699   const ip_address_details_t *address = NULL;
3700   u32 i = ~0;
3701
3702   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3703
3704   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3705   {
3706     i++;
3707     if (!det->present)
3708       {
3709         continue;
3710       }
3711     fformat (vam->ofp, "%-12d\n", i);
3712     fformat (vam->ofp,
3713              "            %-30s%-13s\n", "Address", "Prefix length");
3714     if (!det->addr)
3715       {
3716         continue;
3717       }
3718     vec_foreach (address, det->addr)
3719     {
3720       fformat (vam->ofp,
3721                "            %-30U%-13d\n",
3722                is_ipv6 ? format_ip6_address : format_ip4_address,
3723                address->ip, address->prefix_length);
3724     }
3725   }
3726
3727   return 0;
3728 }
3729
3730 static int
3731 dump_ipv4_table (vat_main_t * vam)
3732 {
3733   if (vam->json_output)
3734     {
3735       clib_warning
3736         ("JSON output supported only for VPE API calls and dump_stats_table");
3737       return -99;
3738     }
3739
3740   return dump_ip_table (vam, 0);
3741 }
3742
3743 static int
3744 dump_ipv6_table (vat_main_t * vam)
3745 {
3746   if (vam->json_output)
3747     {
3748       clib_warning
3749         ("JSON output supported only for VPE API calls and dump_stats_table");
3750       return -99;
3751     }
3752
3753   return dump_ip_table (vam, 1);
3754 }
3755
3756 static char *
3757 counter_type_to_str (u8 counter_type, u8 is_combined)
3758 {
3759   if (!is_combined)
3760     {
3761       switch (counter_type)
3762         {
3763         case VNET_INTERFACE_COUNTER_DROP:
3764           return "drop";
3765         case VNET_INTERFACE_COUNTER_PUNT:
3766           return "punt";
3767         case VNET_INTERFACE_COUNTER_IP4:
3768           return "ip4";
3769         case VNET_INTERFACE_COUNTER_IP6:
3770           return "ip6";
3771         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3772           return "rx-no-buf";
3773         case VNET_INTERFACE_COUNTER_RX_MISS:
3774           return "rx-miss";
3775         case VNET_INTERFACE_COUNTER_RX_ERROR:
3776           return "rx-error";
3777         case VNET_INTERFACE_COUNTER_TX_ERROR:
3778           return "tx-error";
3779         default:
3780           return "INVALID-COUNTER-TYPE";
3781         }
3782     }
3783   else
3784     {
3785       switch (counter_type)
3786         {
3787         case VNET_INTERFACE_COUNTER_RX:
3788           return "rx";
3789         case VNET_INTERFACE_COUNTER_TX:
3790           return "tx";
3791         default:
3792           return "INVALID-COUNTER-TYPE";
3793         }
3794     }
3795 }
3796
3797 static int
3798 dump_stats_table (vat_main_t * vam)
3799 {
3800   vat_json_node_t node;
3801   vat_json_node_t *msg_array;
3802   vat_json_node_t *msg;
3803   vat_json_node_t *counter_array;
3804   vat_json_node_t *counter;
3805   interface_counter_t c;
3806   u64 packets;
3807   ip4_fib_counter_t *c4;
3808   ip6_fib_counter_t *c6;
3809   int i, j;
3810
3811   if (!vam->json_output)
3812     {
3813       clib_warning ("dump_stats_table supported only in JSON format");
3814       return -99;
3815     }
3816
3817   vat_json_init_object (&node);
3818
3819   /* interface counters */
3820   msg_array = vat_json_object_add (&node, "interface_counters");
3821   vat_json_init_array (msg_array);
3822   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3823     {
3824       msg = vat_json_array_add (msg_array);
3825       vat_json_init_object (msg);
3826       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3827                                        (u8 *) counter_type_to_str (i, 0));
3828       vat_json_object_add_int (msg, "is_combined", 0);
3829       counter_array = vat_json_object_add (msg, "data");
3830       vat_json_init_array (counter_array);
3831       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3832         {
3833           packets = vam->simple_interface_counters[i][j];
3834           vat_json_array_add_uint (counter_array, packets);
3835         }
3836     }
3837   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3838     {
3839       msg = vat_json_array_add (msg_array);
3840       vat_json_init_object (msg);
3841       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3842                                        (u8 *) counter_type_to_str (i, 1));
3843       vat_json_object_add_int (msg, "is_combined", 1);
3844       counter_array = vat_json_object_add (msg, "data");
3845       vat_json_init_array (counter_array);
3846       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3847         {
3848           c = vam->combined_interface_counters[i][j];
3849           counter = vat_json_array_add (counter_array);
3850           vat_json_init_object (counter);
3851           vat_json_object_add_uint (counter, "packets", c.packets);
3852           vat_json_object_add_uint (counter, "bytes", c.bytes);
3853         }
3854     }
3855
3856   /* ip4 fib counters */
3857   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3858   vat_json_init_array (msg_array);
3859   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3860     {
3861       msg = vat_json_array_add (msg_array);
3862       vat_json_init_object (msg);
3863       vat_json_object_add_uint (msg, "vrf_id",
3864                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3865       counter_array = vat_json_object_add (msg, "c");
3866       vat_json_init_array (counter_array);
3867       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3868         {
3869           counter = vat_json_array_add (counter_array);
3870           vat_json_init_object (counter);
3871           c4 = &vam->ip4_fib_counters[i][j];
3872           vat_json_object_add_ip4 (counter, "address", c4->address);
3873           vat_json_object_add_uint (counter, "address_length",
3874                                     c4->address_length);
3875           vat_json_object_add_uint (counter, "packets", c4->packets);
3876           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3877         }
3878     }
3879
3880   /* ip6 fib counters */
3881   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3882   vat_json_init_array (msg_array);
3883   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3884     {
3885       msg = vat_json_array_add (msg_array);
3886       vat_json_init_object (msg);
3887       vat_json_object_add_uint (msg, "vrf_id",
3888                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3889       counter_array = vat_json_object_add (msg, "c");
3890       vat_json_init_array (counter_array);
3891       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3892         {
3893           counter = vat_json_array_add (counter_array);
3894           vat_json_init_object (counter);
3895           c6 = &vam->ip6_fib_counters[i][j];
3896           vat_json_object_add_ip6 (counter, "address", c6->address);
3897           vat_json_object_add_uint (counter, "address_length",
3898                                     c6->address_length);
3899           vat_json_object_add_uint (counter, "packets", c6->packets);
3900           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3901         }
3902     }
3903
3904   vat_json_print (vam->ofp, &node);
3905   vat_json_free (&node);
3906
3907   return 0;
3908 }
3909
3910 int
3911 exec (vat_main_t * vam)
3912 {
3913   api_main_t *am = &api_main;
3914   vl_api_cli_request_t *mp;
3915   f64 timeout;
3916   void *oldheap;
3917   u8 *cmd = 0;
3918   unformat_input_t *i = vam->input;
3919
3920   if (vec_len (i->buffer) == 0)
3921     return -1;
3922
3923   if (vam->exec_mode == 0 && unformat (i, "mode"))
3924     {
3925       vam->exec_mode = 1;
3926       return 0;
3927     }
3928   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3929     {
3930       vam->exec_mode = 0;
3931       return 0;
3932     }
3933
3934
3935   M (CLI_REQUEST, cli_request);
3936
3937   /*
3938    * Copy cmd into shared memory.
3939    * In order for the CLI command to work, it
3940    * must be a vector ending in \n, not a C-string ending
3941    * in \n\0.
3942    */
3943   pthread_mutex_lock (&am->vlib_rp->mutex);
3944   oldheap = svm_push_data_heap (am->vlib_rp);
3945
3946   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
3947   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
3948
3949   svm_pop_heap (oldheap);
3950   pthread_mutex_unlock (&am->vlib_rp->mutex);
3951
3952   mp->cmd_in_shmem = (u64) cmd;
3953   S;
3954   timeout = vat_time_now (vam) + 10.0;
3955
3956   while (vat_time_now (vam) < timeout)
3957     {
3958       if (vam->result_ready == 1)
3959         {
3960           u8 *free_me;
3961           if (vam->shmem_result != NULL)
3962             fformat (vam->ofp, "%s", vam->shmem_result);
3963           pthread_mutex_lock (&am->vlib_rp->mutex);
3964           oldheap = svm_push_data_heap (am->vlib_rp);
3965
3966           free_me = (u8 *) vam->shmem_result;
3967           vec_free (free_me);
3968
3969           svm_pop_heap (oldheap);
3970           pthread_mutex_unlock (&am->vlib_rp->mutex);
3971           return 0;
3972         }
3973     }
3974   return -99;
3975 }
3976
3977 static int
3978 api_create_loopback (vat_main_t * vam)
3979 {
3980   unformat_input_t *i = vam->input;
3981   vl_api_create_loopback_t *mp;
3982   f64 timeout;
3983   u8 mac_address[6];
3984   u8 mac_set = 0;
3985
3986   memset (mac_address, 0, sizeof (mac_address));
3987
3988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3989     {
3990       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3991         mac_set = 1;
3992       else
3993         break;
3994     }
3995
3996   /* Construct the API message */
3997   M (CREATE_LOOPBACK, create_loopback);
3998   if (mac_set)
3999     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4000
4001   S;
4002   W;
4003 }
4004
4005 static int
4006 api_delete_loopback (vat_main_t * vam)
4007 {
4008   unformat_input_t *i = vam->input;
4009   vl_api_delete_loopback_t *mp;
4010   f64 timeout;
4011   u32 sw_if_index = ~0;
4012
4013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4014     {
4015       if (unformat (i, "sw_if_index %d", &sw_if_index))
4016         ;
4017       else
4018         break;
4019     }
4020
4021   if (sw_if_index == ~0)
4022     {
4023       errmsg ("missing sw_if_index\n");
4024       return -99;
4025     }
4026
4027   /* Construct the API message */
4028   M (DELETE_LOOPBACK, delete_loopback);
4029   mp->sw_if_index = ntohl (sw_if_index);
4030
4031   S;
4032   W;
4033 }
4034
4035 static int
4036 api_want_stats (vat_main_t * vam)
4037 {
4038   unformat_input_t *i = vam->input;
4039   vl_api_want_stats_t *mp;
4040   f64 timeout;
4041   int enable = -1;
4042
4043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4044     {
4045       if (unformat (i, "enable"))
4046         enable = 1;
4047       else if (unformat (i, "disable"))
4048         enable = 0;
4049       else
4050         break;
4051     }
4052
4053   if (enable == -1)
4054     {
4055       errmsg ("missing enable|disable\n");
4056       return -99;
4057     }
4058
4059   M (WANT_STATS, want_stats);
4060   mp->enable_disable = enable;
4061
4062   S;
4063   W;
4064 }
4065
4066 static int
4067 api_want_interface_events (vat_main_t * vam)
4068 {
4069   unformat_input_t *i = vam->input;
4070   vl_api_want_interface_events_t *mp;
4071   f64 timeout;
4072   int enable = -1;
4073
4074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4075     {
4076       if (unformat (i, "enable"))
4077         enable = 1;
4078       else if (unformat (i, "disable"))
4079         enable = 0;
4080       else
4081         break;
4082     }
4083
4084   if (enable == -1)
4085     {
4086       errmsg ("missing enable|disable\n");
4087       return -99;
4088     }
4089
4090   M (WANT_INTERFACE_EVENTS, want_interface_events);
4091   mp->enable_disable = enable;
4092
4093   vam->interface_event_display = enable;
4094
4095   S;
4096   W;
4097 }
4098
4099
4100 /* Note: non-static, called once to set up the initial intfc table */
4101 int
4102 api_sw_interface_dump (vat_main_t * vam)
4103 {
4104   vl_api_sw_interface_dump_t *mp;
4105   f64 timeout;
4106   hash_pair_t *p;
4107   name_sort_t *nses = 0, *ns;
4108   sw_interface_subif_t *sub = NULL;
4109
4110   /* Toss the old name table */
4111   /* *INDENT-OFF* */
4112   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4113   ({
4114     vec_add2 (nses, ns, 1);
4115     ns->name = (u8 *)(p->key);
4116     ns->value = (u32) p->value[0];
4117   }));
4118   /* *INDENT-ON* */
4119
4120   hash_free (vam->sw_if_index_by_interface_name);
4121
4122   vec_foreach (ns, nses) vec_free (ns->name);
4123
4124   vec_free (nses);
4125
4126   vec_foreach (sub, vam->sw_if_subif_table)
4127   {
4128     vec_free (sub->interface_name);
4129   }
4130   vec_free (vam->sw_if_subif_table);
4131
4132   /* recreate the interface name hash table */
4133   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4134
4135   /* Get list of ethernets */
4136   M (SW_INTERFACE_DUMP, sw_interface_dump);
4137   mp->name_filter_valid = 1;
4138   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4139   S;
4140
4141   /* and local / loopback interfaces */
4142   M (SW_INTERFACE_DUMP, sw_interface_dump);
4143   mp->name_filter_valid = 1;
4144   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4145   S;
4146
4147
4148   /* and vxlan-gpe tunnel interfaces */
4149   M (SW_INTERFACE_DUMP, sw_interface_dump);
4150   mp->name_filter_valid = 1;
4151   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4152            sizeof (mp->name_filter) - 1);
4153   S;
4154
4155   /* and vxlan tunnel interfaces */
4156   M (SW_INTERFACE_DUMP, sw_interface_dump);
4157   mp->name_filter_valid = 1;
4158   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4159   S;
4160
4161   /* and host (af_packet) interfaces */
4162   M (SW_INTERFACE_DUMP, sw_interface_dump);
4163   mp->name_filter_valid = 1;
4164   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4165   S;
4166
4167   /* and l2tpv3 tunnel interfaces */
4168   M (SW_INTERFACE_DUMP, sw_interface_dump);
4169   mp->name_filter_valid = 1;
4170   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4171            sizeof (mp->name_filter) - 1);
4172   S;
4173
4174   /* and GRE tunnel interfaces */
4175   M (SW_INTERFACE_DUMP, sw_interface_dump);
4176   mp->name_filter_valid = 1;
4177   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4178   S;
4179
4180   /* Use a control ping for synchronization */
4181   {
4182     vl_api_control_ping_t *mp;
4183     M (CONTROL_PING, control_ping);
4184     S;
4185   }
4186   W;
4187 }
4188
4189 static int
4190 api_sw_interface_set_flags (vat_main_t * vam)
4191 {
4192   unformat_input_t *i = vam->input;
4193   vl_api_sw_interface_set_flags_t *mp;
4194   f64 timeout;
4195   u32 sw_if_index;
4196   u8 sw_if_index_set = 0;
4197   u8 admin_up = 0, link_up = 0;
4198
4199   /* Parse args required to build the message */
4200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4201     {
4202       if (unformat (i, "admin-up"))
4203         admin_up = 1;
4204       else if (unformat (i, "admin-down"))
4205         admin_up = 0;
4206       else if (unformat (i, "link-up"))
4207         link_up = 1;
4208       else if (unformat (i, "link-down"))
4209         link_up = 0;
4210       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4211         sw_if_index_set = 1;
4212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4213         sw_if_index_set = 1;
4214       else
4215         break;
4216     }
4217
4218   if (sw_if_index_set == 0)
4219     {
4220       errmsg ("missing interface name or sw_if_index\n");
4221       return -99;
4222     }
4223
4224   /* Construct the API message */
4225   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4226   mp->sw_if_index = ntohl (sw_if_index);
4227   mp->admin_up_down = admin_up;
4228   mp->link_up_down = link_up;
4229
4230   /* send it... */
4231   S;
4232
4233   /* Wait for a reply, return the good/bad news... */
4234   W;
4235 }
4236
4237 static int
4238 api_sw_interface_clear_stats (vat_main_t * vam)
4239 {
4240   unformat_input_t *i = vam->input;
4241   vl_api_sw_interface_clear_stats_t *mp;
4242   f64 timeout;
4243   u32 sw_if_index;
4244   u8 sw_if_index_set = 0;
4245
4246   /* Parse args required to build the message */
4247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4248     {
4249       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4250         sw_if_index_set = 1;
4251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4252         sw_if_index_set = 1;
4253       else
4254         break;
4255     }
4256
4257   /* Construct the API message */
4258   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4259
4260   if (sw_if_index_set == 1)
4261     mp->sw_if_index = ntohl (sw_if_index);
4262   else
4263     mp->sw_if_index = ~0;
4264
4265   /* send it... */
4266   S;
4267
4268   /* Wait for a reply, return the good/bad news... */
4269   W;
4270 }
4271
4272 static int
4273 api_sw_interface_add_del_address (vat_main_t * vam)
4274 {
4275   unformat_input_t *i = vam->input;
4276   vl_api_sw_interface_add_del_address_t *mp;
4277   f64 timeout;
4278   u32 sw_if_index;
4279   u8 sw_if_index_set = 0;
4280   u8 is_add = 1, del_all = 0;
4281   u32 address_length = 0;
4282   u8 v4_address_set = 0;
4283   u8 v6_address_set = 0;
4284   ip4_address_t v4address;
4285   ip6_address_t v6address;
4286
4287   /* Parse args required to build the message */
4288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4289     {
4290       if (unformat (i, "del-all"))
4291         del_all = 1;
4292       else if (unformat (i, "del"))
4293         is_add = 0;
4294       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4295         sw_if_index_set = 1;
4296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4297         sw_if_index_set = 1;
4298       else if (unformat (i, "%U/%d",
4299                          unformat_ip4_address, &v4address, &address_length))
4300         v4_address_set = 1;
4301       else if (unformat (i, "%U/%d",
4302                          unformat_ip6_address, &v6address, &address_length))
4303         v6_address_set = 1;
4304       else
4305         break;
4306     }
4307
4308   if (sw_if_index_set == 0)
4309     {
4310       errmsg ("missing interface name or sw_if_index\n");
4311       return -99;
4312     }
4313   if (v4_address_set && v6_address_set)
4314     {
4315       errmsg ("both v4 and v6 addresses set\n");
4316       return -99;
4317     }
4318   if (!v4_address_set && !v6_address_set && !del_all)
4319     {
4320       errmsg ("no addresses set\n");
4321       return -99;
4322     }
4323
4324   /* Construct the API message */
4325   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4326
4327   mp->sw_if_index = ntohl (sw_if_index);
4328   mp->is_add = is_add;
4329   mp->del_all = del_all;
4330   if (v6_address_set)
4331     {
4332       mp->is_ipv6 = 1;
4333       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4334     }
4335   else
4336     {
4337       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4338     }
4339   mp->address_length = address_length;
4340
4341   /* send it... */
4342   S;
4343
4344   /* Wait for a reply, return good/bad news  */
4345   W;
4346 }
4347
4348 static int
4349 api_sw_interface_set_table (vat_main_t * vam)
4350 {
4351   unformat_input_t *i = vam->input;
4352   vl_api_sw_interface_set_table_t *mp;
4353   f64 timeout;
4354   u32 sw_if_index, vrf_id = 0;
4355   u8 sw_if_index_set = 0;
4356   u8 is_ipv6 = 0;
4357
4358   /* Parse args required to build the message */
4359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4360     {
4361       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4362         sw_if_index_set = 1;
4363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4364         sw_if_index_set = 1;
4365       else if (unformat (i, "vrf %d", &vrf_id))
4366         ;
4367       else if (unformat (i, "ipv6"))
4368         is_ipv6 = 1;
4369       else
4370         break;
4371     }
4372
4373   if (sw_if_index_set == 0)
4374     {
4375       errmsg ("missing interface name or sw_if_index\n");
4376       return -99;
4377     }
4378
4379   /* Construct the API message */
4380   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4381
4382   mp->sw_if_index = ntohl (sw_if_index);
4383   mp->is_ipv6 = is_ipv6;
4384   mp->vrf_id = ntohl (vrf_id);
4385
4386   /* send it... */
4387   S;
4388
4389   /* Wait for a reply... */
4390   W;
4391 }
4392
4393 static int
4394 api_sw_interface_set_vpath (vat_main_t * vam)
4395 {
4396   unformat_input_t *i = vam->input;
4397   vl_api_sw_interface_set_vpath_t *mp;
4398   f64 timeout;
4399   u32 sw_if_index = 0;
4400   u8 sw_if_index_set = 0;
4401   u8 is_enable = 0;
4402
4403   /* Parse args required to build the message */
4404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4405     {
4406       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4407         sw_if_index_set = 1;
4408       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4409         sw_if_index_set = 1;
4410       else if (unformat (i, "enable"))
4411         is_enable = 1;
4412       else if (unformat (i, "disable"))
4413         is_enable = 0;
4414       else
4415         break;
4416     }
4417
4418   if (sw_if_index_set == 0)
4419     {
4420       errmsg ("missing interface name or sw_if_index\n");
4421       return -99;
4422     }
4423
4424   /* Construct the API message */
4425   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4426
4427   mp->sw_if_index = ntohl (sw_if_index);
4428   mp->enable = is_enable;
4429
4430   /* send it... */
4431   S;
4432
4433   /* Wait for a reply... */
4434   W;
4435 }
4436
4437 static int
4438 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4439 {
4440   unformat_input_t *i = vam->input;
4441   vl_api_sw_interface_set_l2_xconnect_t *mp;
4442   f64 timeout;
4443   u32 rx_sw_if_index;
4444   u8 rx_sw_if_index_set = 0;
4445   u32 tx_sw_if_index;
4446   u8 tx_sw_if_index_set = 0;
4447   u8 enable = 1;
4448
4449   /* Parse args required to build the message */
4450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4451     {
4452       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4453         rx_sw_if_index_set = 1;
4454       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4455         tx_sw_if_index_set = 1;
4456       else if (unformat (i, "rx"))
4457         {
4458           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4459             {
4460               if (unformat (i, "%U", unformat_sw_if_index, vam,
4461                             &rx_sw_if_index))
4462                 rx_sw_if_index_set = 1;
4463             }
4464           else
4465             break;
4466         }
4467       else if (unformat (i, "tx"))
4468         {
4469           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4470             {
4471               if (unformat (i, "%U", unformat_sw_if_index, vam,
4472                             &tx_sw_if_index))
4473                 tx_sw_if_index_set = 1;
4474             }
4475           else
4476             break;
4477         }
4478       else if (unformat (i, "enable"))
4479         enable = 1;
4480       else if (unformat (i, "disable"))
4481         enable = 0;
4482       else
4483         break;
4484     }
4485
4486   if (rx_sw_if_index_set == 0)
4487     {
4488       errmsg ("missing rx interface name or rx_sw_if_index\n");
4489       return -99;
4490     }
4491
4492   if (enable && (tx_sw_if_index_set == 0))
4493     {
4494       errmsg ("missing tx interface name or tx_sw_if_index\n");
4495       return -99;
4496     }
4497
4498   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4499
4500   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4501   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4502   mp->enable = enable;
4503
4504   S;
4505   W;
4506   /* NOTREACHED */
4507   return 0;
4508 }
4509
4510 static int
4511 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4512 {
4513   unformat_input_t *i = vam->input;
4514   vl_api_sw_interface_set_l2_bridge_t *mp;
4515   f64 timeout;
4516   u32 rx_sw_if_index;
4517   u8 rx_sw_if_index_set = 0;
4518   u32 bd_id;
4519   u8 bd_id_set = 0;
4520   u8 bvi = 0;
4521   u32 shg = 0;
4522   u8 enable = 1;
4523
4524   /* Parse args required to build the message */
4525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4526     {
4527       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4528         rx_sw_if_index_set = 1;
4529       else if (unformat (i, "bd_id %d", &bd_id))
4530         bd_id_set = 1;
4531       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4532         rx_sw_if_index_set = 1;
4533       else if (unformat (i, "shg %d", &shg))
4534         ;
4535       else if (unformat (i, "bvi"))
4536         bvi = 1;
4537       else if (unformat (i, "enable"))
4538         enable = 1;
4539       else if (unformat (i, "disable"))
4540         enable = 0;
4541       else
4542         break;
4543     }
4544
4545   if (rx_sw_if_index_set == 0)
4546     {
4547       errmsg ("missing rx interface name or sw_if_index\n");
4548       return -99;
4549     }
4550
4551   if (enable && (bd_id_set == 0))
4552     {
4553       errmsg ("missing bridge domain\n");
4554       return -99;
4555     }
4556
4557   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4558
4559   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4560   mp->bd_id = ntohl (bd_id);
4561   mp->shg = (u8) shg;
4562   mp->bvi = bvi;
4563   mp->enable = enable;
4564
4565   S;
4566   W;
4567   /* NOTREACHED */
4568   return 0;
4569 }
4570
4571 static int
4572 api_bridge_domain_dump (vat_main_t * vam)
4573 {
4574   unformat_input_t *i = vam->input;
4575   vl_api_bridge_domain_dump_t *mp;
4576   f64 timeout;
4577   u32 bd_id = ~0;
4578
4579   /* Parse args required to build the message */
4580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4581     {
4582       if (unformat (i, "bd_id %d", &bd_id))
4583         ;
4584       else
4585         break;
4586     }
4587
4588   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4589   mp->bd_id = ntohl (bd_id);
4590   S;
4591
4592   /* Use a control ping for synchronization */
4593   {
4594     vl_api_control_ping_t *mp;
4595     M (CONTROL_PING, control_ping);
4596     S;
4597   }
4598
4599   W;
4600   /* NOTREACHED */
4601   return 0;
4602 }
4603
4604 static int
4605 api_bridge_domain_add_del (vat_main_t * vam)
4606 {
4607   unformat_input_t *i = vam->input;
4608   vl_api_bridge_domain_add_del_t *mp;
4609   f64 timeout;
4610   u32 bd_id = ~0;
4611   u8 is_add = 1;
4612   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4613
4614   /* Parse args required to build the message */
4615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4616     {
4617       if (unformat (i, "bd_id %d", &bd_id))
4618         ;
4619       else if (unformat (i, "flood %d", &flood))
4620         ;
4621       else if (unformat (i, "uu-flood %d", &uu_flood))
4622         ;
4623       else if (unformat (i, "forward %d", &forward))
4624         ;
4625       else if (unformat (i, "learn %d", &learn))
4626         ;
4627       else if (unformat (i, "arp-term %d", &arp_term))
4628         ;
4629       else if (unformat (i, "del"))
4630         {
4631           is_add = 0;
4632           flood = uu_flood = forward = learn = 0;
4633         }
4634       else
4635         break;
4636     }
4637
4638   if (bd_id == ~0)
4639     {
4640       errmsg ("missing bridge domain\n");
4641       return -99;
4642     }
4643
4644   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4645
4646   mp->bd_id = ntohl (bd_id);
4647   mp->flood = flood;
4648   mp->uu_flood = uu_flood;
4649   mp->forward = forward;
4650   mp->learn = learn;
4651   mp->arp_term = arp_term;
4652   mp->is_add = is_add;
4653
4654   S;
4655   W;
4656   /* NOTREACHED */
4657   return 0;
4658 }
4659
4660 static int
4661 api_l2fib_add_del (vat_main_t * vam)
4662 {
4663   unformat_input_t *i = vam->input;
4664   vl_api_l2fib_add_del_t *mp;
4665   f64 timeout;
4666   u64 mac = 0;
4667   u8 mac_set = 0;
4668   u32 bd_id;
4669   u8 bd_id_set = 0;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u8 is_add = 1;
4673   u8 static_mac = 0;
4674   u8 filter_mac = 0;
4675   u8 bvi_mac = 0;
4676   int count = 1;
4677   f64 before = 0;
4678   int j;
4679
4680   /* Parse args required to build the message */
4681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4682     {
4683       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4684         mac_set = 1;
4685       else if (unformat (i, "bd_id %d", &bd_id))
4686         bd_id_set = 1;
4687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4688         sw_if_index_set = 1;
4689       else if (unformat (i, "sw_if"))
4690         {
4691           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4692             {
4693               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4694                 sw_if_index_set = 1;
4695             }
4696           else
4697             break;
4698         }
4699       else if (unformat (i, "static"))
4700         static_mac = 1;
4701       else if (unformat (i, "filter"))
4702         {
4703           filter_mac = 1;
4704           static_mac = 1;
4705         }
4706       else if (unformat (i, "bvi"))
4707         {
4708           bvi_mac = 1;
4709           static_mac = 1;
4710         }
4711       else if (unformat (i, "del"))
4712         is_add = 0;
4713       else if (unformat (i, "count %d", &count))
4714         ;
4715       else
4716         break;
4717     }
4718
4719   if (mac_set == 0)
4720     {
4721       errmsg ("missing mac address\n");
4722       return -99;
4723     }
4724
4725   if (bd_id_set == 0)
4726     {
4727       errmsg ("missing bridge domain\n");
4728       return -99;
4729     }
4730
4731   if (is_add && (sw_if_index_set == 0))
4732     {
4733       errmsg ("missing interface name or sw_if_index\n");
4734       return -99;
4735     }
4736
4737   if (count > 1)
4738     {
4739       /* Turn on async mode */
4740       vam->async_mode = 1;
4741       vam->async_errors = 0;
4742       before = vat_time_now (vam);
4743     }
4744
4745   for (j = 0; j < count; j++)
4746     {
4747       M (L2FIB_ADD_DEL, l2fib_add_del);
4748
4749       mp->mac = mac;
4750       mp->bd_id = ntohl (bd_id);
4751       mp->is_add = is_add;
4752
4753       if (is_add)
4754         {
4755           mp->sw_if_index = ntohl (sw_if_index);
4756           mp->static_mac = static_mac;
4757           mp->filter_mac = filter_mac;
4758           mp->bvi_mac = bvi_mac;
4759         }
4760       increment_mac_address (&mac);
4761       /* send it... */
4762       S;
4763     }
4764
4765   if (count > 1)
4766     {
4767       vl_api_control_ping_t *mp;
4768       f64 after;
4769
4770       /* Shut off async mode */
4771       vam->async_mode = 0;
4772
4773       M (CONTROL_PING, control_ping);
4774       S;
4775
4776       timeout = vat_time_now (vam) + 1.0;
4777       while (vat_time_now (vam) < timeout)
4778         if (vam->result_ready == 1)
4779           goto out;
4780       vam->retval = -99;
4781
4782     out:
4783       if (vam->retval == -99)
4784         errmsg ("timeout\n");
4785
4786       if (vam->async_errors > 0)
4787         {
4788           errmsg ("%d asynchronous errors\n", vam->async_errors);
4789           vam->retval = -98;
4790         }
4791       vam->async_errors = 0;
4792       after = vat_time_now (vam);
4793
4794       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4795                count, after - before, count / (after - before));
4796     }
4797   else
4798     {
4799       /* Wait for a reply... */
4800       W;
4801     }
4802   /* Return the good/bad news */
4803   return (vam->retval);
4804 }
4805
4806 static int
4807 api_l2_flags (vat_main_t * vam)
4808 {
4809   unformat_input_t *i = vam->input;
4810   vl_api_l2_flags_t *mp;
4811   f64 timeout;
4812   u32 sw_if_index;
4813   u32 feature_bitmap = 0;
4814   u8 sw_if_index_set = 0;
4815
4816   /* Parse args required to build the message */
4817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4818     {
4819       if (unformat (i, "sw_if_index %d", &sw_if_index))
4820         sw_if_index_set = 1;
4821       else if (unformat (i, "sw_if"))
4822         {
4823           if (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             }
4828           else
4829             break;
4830         }
4831       else if (unformat (i, "learn"))
4832         feature_bitmap |= L2INPUT_FEAT_LEARN;
4833       else if (unformat (i, "forward"))
4834         feature_bitmap |= L2INPUT_FEAT_FWD;
4835       else if (unformat (i, "flood"))
4836         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4837       else if (unformat (i, "uu-flood"))
4838         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4839       else
4840         break;
4841     }
4842
4843   if (sw_if_index_set == 0)
4844     {
4845       errmsg ("missing interface name or sw_if_index\n");
4846       return -99;
4847     }
4848
4849   M (L2_FLAGS, l2_flags);
4850
4851   mp->sw_if_index = ntohl (sw_if_index);
4852   mp->feature_bitmap = ntohl (feature_bitmap);
4853
4854   S;
4855   W;
4856   /* NOTREACHED */
4857   return 0;
4858 }
4859
4860 static int
4861 api_bridge_flags (vat_main_t * vam)
4862 {
4863   unformat_input_t *i = vam->input;
4864   vl_api_bridge_flags_t *mp;
4865   f64 timeout;
4866   u32 bd_id;
4867   u8 bd_id_set = 0;
4868   u8 is_set = 1;
4869   u32 flags = 0;
4870
4871   /* Parse args required to build the message */
4872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4873     {
4874       if (unformat (i, "bd_id %d", &bd_id))
4875         bd_id_set = 1;
4876       else if (unformat (i, "learn"))
4877         flags |= L2_LEARN;
4878       else if (unformat (i, "forward"))
4879         flags |= L2_FWD;
4880       else if (unformat (i, "flood"))
4881         flags |= L2_FLOOD;
4882       else if (unformat (i, "uu-flood"))
4883         flags |= L2_UU_FLOOD;
4884       else if (unformat (i, "arp-term"))
4885         flags |= L2_ARP_TERM;
4886       else if (unformat (i, "off"))
4887         is_set = 0;
4888       else if (unformat (i, "disable"))
4889         is_set = 0;
4890       else
4891         break;
4892     }
4893
4894   if (bd_id_set == 0)
4895     {
4896       errmsg ("missing bridge domain\n");
4897       return -99;
4898     }
4899
4900   M (BRIDGE_FLAGS, bridge_flags);
4901
4902   mp->bd_id = ntohl (bd_id);
4903   mp->feature_bitmap = ntohl (flags);
4904   mp->is_set = is_set;
4905
4906   S;
4907   W;
4908   /* NOTREACHED */
4909   return 0;
4910 }
4911
4912 static int
4913 api_bd_ip_mac_add_del (vat_main_t * vam)
4914 {
4915   unformat_input_t *i = vam->input;
4916   vl_api_bd_ip_mac_add_del_t *mp;
4917   f64 timeout;
4918   u32 bd_id;
4919   u8 is_ipv6 = 0;
4920   u8 is_add = 1;
4921   u8 bd_id_set = 0;
4922   u8 ip_set = 0;
4923   u8 mac_set = 0;
4924   ip4_address_t v4addr;
4925   ip6_address_t v6addr;
4926   u8 macaddr[6];
4927
4928
4929   /* Parse args required to build the message */
4930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4931     {
4932       if (unformat (i, "bd_id %d", &bd_id))
4933         {
4934           bd_id_set++;
4935         }
4936       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
4937         {
4938           ip_set++;
4939         }
4940       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
4941         {
4942           ip_set++;
4943           is_ipv6++;
4944         }
4945       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
4946         {
4947           mac_set++;
4948         }
4949       else if (unformat (i, "del"))
4950         is_add = 0;
4951       else
4952         break;
4953     }
4954
4955   if (bd_id_set == 0)
4956     {
4957       errmsg ("missing bridge domain\n");
4958       return -99;
4959     }
4960   else if (ip_set == 0)
4961     {
4962       errmsg ("missing IP address\n");
4963       return -99;
4964     }
4965   else if (mac_set == 0)
4966     {
4967       errmsg ("missing MAC address\n");
4968       return -99;
4969     }
4970
4971   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
4972
4973   mp->bd_id = ntohl (bd_id);
4974   mp->is_ipv6 = is_ipv6;
4975   mp->is_add = is_add;
4976   if (is_ipv6)
4977     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
4978   else
4979     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
4980   clib_memcpy (mp->mac_address, macaddr, 6);
4981   S;
4982   W;
4983   /* NOTREACHED */
4984   return 0;
4985 }
4986
4987 static int
4988 api_tap_connect (vat_main_t * vam)
4989 {
4990   unformat_input_t *i = vam->input;
4991   vl_api_tap_connect_t *mp;
4992   f64 timeout;
4993   u8 mac_address[6];
4994   u8 random_mac = 1;
4995   u8 name_set = 0;
4996   u8 *tap_name;
4997
4998   memset (mac_address, 0, sizeof (mac_address));
4999
5000   /* Parse args required to build the message */
5001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5002     {
5003       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5004         {
5005           random_mac = 0;
5006         }
5007       else if (unformat (i, "random-mac"))
5008         random_mac = 1;
5009       else if (unformat (i, "tapname %s", &tap_name))
5010         name_set = 1;
5011       else
5012         break;
5013     }
5014
5015   if (name_set == 0)
5016     {
5017       errmsg ("missing tap name\n");
5018       return -99;
5019     }
5020   if (vec_len (tap_name) > 63)
5021     {
5022       errmsg ("tap name too long\n");
5023     }
5024   vec_add1 (tap_name, 0);
5025
5026   /* Construct the API message */
5027   M (TAP_CONNECT, tap_connect);
5028
5029   mp->use_random_mac = random_mac;
5030   clib_memcpy (mp->mac_address, mac_address, 6);
5031   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5032   vec_free (tap_name);
5033
5034   /* send it... */
5035   S;
5036
5037   /* Wait for a reply... */
5038   W;
5039 }
5040
5041 static int
5042 api_tap_modify (vat_main_t * vam)
5043 {
5044   unformat_input_t *i = vam->input;
5045   vl_api_tap_modify_t *mp;
5046   f64 timeout;
5047   u8 mac_address[6];
5048   u8 random_mac = 1;
5049   u8 name_set = 0;
5050   u8 *tap_name;
5051   u32 sw_if_index = ~0;
5052   u8 sw_if_index_set = 0;
5053
5054   memset (mac_address, 0, sizeof (mac_address));
5055
5056   /* Parse args required to build the message */
5057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5058     {
5059       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5060         sw_if_index_set = 1;
5061       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5062         sw_if_index_set = 1;
5063       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5064         {
5065           random_mac = 0;
5066         }
5067       else if (unformat (i, "random-mac"))
5068         random_mac = 1;
5069       else if (unformat (i, "tapname %s", &tap_name))
5070         name_set = 1;
5071       else
5072         break;
5073     }
5074
5075   if (sw_if_index_set == 0)
5076     {
5077       errmsg ("missing vpp interface name");
5078       return -99;
5079     }
5080   if (name_set == 0)
5081     {
5082       errmsg ("missing tap name\n");
5083       return -99;
5084     }
5085   if (vec_len (tap_name) > 63)
5086     {
5087       errmsg ("tap name too long\n");
5088     }
5089   vec_add1 (tap_name, 0);
5090
5091   /* Construct the API message */
5092   M (TAP_MODIFY, tap_modify);
5093
5094   mp->use_random_mac = random_mac;
5095   mp->sw_if_index = ntohl (sw_if_index);
5096   clib_memcpy (mp->mac_address, mac_address, 6);
5097   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5098   vec_free (tap_name);
5099
5100   /* send it... */
5101   S;
5102
5103   /* Wait for a reply... */
5104   W;
5105 }
5106
5107 static int
5108 api_tap_delete (vat_main_t * vam)
5109 {
5110   unformat_input_t *i = vam->input;
5111   vl_api_tap_delete_t *mp;
5112   f64 timeout;
5113   u32 sw_if_index = ~0;
5114   u8 sw_if_index_set = 0;
5115
5116   /* Parse args required to build the message */
5117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5118     {
5119       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5120         sw_if_index_set = 1;
5121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5122         sw_if_index_set = 1;
5123       else
5124         break;
5125     }
5126
5127   if (sw_if_index_set == 0)
5128     {
5129       errmsg ("missing vpp interface name");
5130       return -99;
5131     }
5132
5133   /* Construct the API message */
5134   M (TAP_DELETE, tap_delete);
5135
5136   mp->sw_if_index = ntohl (sw_if_index);
5137
5138   /* send it... */
5139   S;
5140
5141   /* Wait for a reply... */
5142   W;
5143 }
5144
5145 static int
5146 api_ip_add_del_route (vat_main_t * vam)
5147 {
5148   unformat_input_t *i = vam->input;
5149   vl_api_ip_add_del_route_t *mp;
5150   f64 timeout;
5151   u32 sw_if_index = ~0, vrf_id = 0;
5152   u8 sw_if_index_set = 0;
5153   u8 is_ipv6 = 0;
5154   u8 is_local = 0, is_drop = 0;
5155   u8 create_vrf_if_needed = 0;
5156   u8 is_add = 1;
5157   u8 next_hop_weight = 1;
5158   u8 not_last = 0;
5159   u8 is_multipath = 0;
5160   u8 address_set = 0;
5161   u8 address_length_set = 0;
5162   u32 lookup_in_vrf = 0;
5163   u32 resolve_attempts = 0;
5164   u32 dst_address_length = 0;
5165   u8 next_hop_set = 0;
5166   ip4_address_t v4_dst_address, v4_next_hop_address;
5167   ip6_address_t v6_dst_address, v6_next_hop_address;
5168   int count = 1;
5169   int j;
5170   f64 before = 0;
5171   u32 random_add_del = 0;
5172   u32 *random_vector = 0;
5173   uword *random_hash;
5174   u32 random_seed = 0xdeaddabe;
5175   u32 classify_table_index = ~0;
5176   u8 is_classify = 0;
5177
5178   /* Parse args required to build the message */
5179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5180     {
5181       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5184         sw_if_index_set = 1;
5185       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5186         {
5187           address_set = 1;
5188           is_ipv6 = 0;
5189         }
5190       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5191         {
5192           address_set = 1;
5193           is_ipv6 = 1;
5194         }
5195       else if (unformat (i, "/%d", &dst_address_length))
5196         {
5197           address_length_set = 1;
5198         }
5199
5200       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5201                                          &v4_next_hop_address))
5202         {
5203           next_hop_set = 1;
5204         }
5205       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5206                                          &v6_next_hop_address))
5207         {
5208           next_hop_set = 1;
5209         }
5210       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5211         ;
5212       else if (unformat (i, "weight %d", &next_hop_weight))
5213         ;
5214       else if (unformat (i, "drop"))
5215         {
5216           is_drop = 1;
5217         }
5218       else if (unformat (i, "local"))
5219         {
5220           is_local = 1;
5221         }
5222       else if (unformat (i, "classify %d", &classify_table_index))
5223         {
5224           is_classify = 1;
5225         }
5226       else if (unformat (i, "del"))
5227         is_add = 0;
5228       else if (unformat (i, "add"))
5229         is_add = 1;
5230       else if (unformat (i, "not-last"))
5231         not_last = 1;
5232       else if (unformat (i, "multipath"))
5233         is_multipath = 1;
5234       else if (unformat (i, "vrf %d", &vrf_id))
5235         ;
5236       else if (unformat (i, "create-vrf"))
5237         create_vrf_if_needed = 1;
5238       else if (unformat (i, "count %d", &count))
5239         ;
5240       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5241         ;
5242       else if (unformat (i, "random"))
5243         random_add_del = 1;
5244       else if (unformat (i, "seed %d", &random_seed))
5245         ;
5246       else
5247         {
5248           clib_warning ("parse error '%U'", format_unformat_error, i);
5249           return -99;
5250         }
5251     }
5252
5253   if (resolve_attempts > 0 && sw_if_index_set == 0)
5254     {
5255       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5256       return -99;
5257     }
5258
5259   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5260     {
5261       errmsg ("next hop / local / drop / classify not set\n");
5262       return -99;
5263     }
5264
5265   if (address_set == 0)
5266     {
5267       errmsg ("missing addresses\n");
5268       return -99;
5269     }
5270
5271   if (address_length_set == 0)
5272     {
5273       errmsg ("missing address length\n");
5274       return -99;
5275     }
5276
5277   /* Generate a pile of unique, random routes */
5278   if (random_add_del)
5279     {
5280       u32 this_random_address;
5281       random_hash = hash_create (count, sizeof (uword));
5282
5283       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5284       for (j = 0; j <= count; j++)
5285         {
5286           do
5287             {
5288               this_random_address = random_u32 (&random_seed);
5289               this_random_address =
5290                 clib_host_to_net_u32 (this_random_address);
5291             }
5292           while (hash_get (random_hash, this_random_address));
5293           vec_add1 (random_vector, this_random_address);
5294           hash_set (random_hash, this_random_address, 1);
5295         }
5296       hash_free (random_hash);
5297       v4_dst_address.as_u32 = random_vector[0];
5298     }
5299
5300   if (count > 1)
5301     {
5302       /* Turn on async mode */
5303       vam->async_mode = 1;
5304       vam->async_errors = 0;
5305       before = vat_time_now (vam);
5306     }
5307
5308   for (j = 0; j < count; j++)
5309     {
5310       /* Construct the API message */
5311       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5312
5313       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5314       mp->vrf_id = ntohl (vrf_id);
5315       if (resolve_attempts > 0)
5316         {
5317           mp->resolve_attempts = ntohl (resolve_attempts);
5318           mp->resolve_if_needed = 1;
5319         }
5320       mp->create_vrf_if_needed = create_vrf_if_needed;
5321
5322       mp->is_add = is_add;
5323       mp->is_drop = is_drop;
5324       mp->is_ipv6 = is_ipv6;
5325       mp->is_local = is_local;
5326       mp->is_classify = is_classify;
5327       mp->is_multipath = is_multipath;
5328       mp->not_last = not_last;
5329       mp->next_hop_weight = next_hop_weight;
5330       mp->dst_address_length = dst_address_length;
5331       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5332       mp->classify_table_index = ntohl (classify_table_index);
5333
5334       if (is_ipv6)
5335         {
5336           clib_memcpy (mp->dst_address, &v6_dst_address,
5337                        sizeof (v6_dst_address));
5338           if (next_hop_set)
5339             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5340                          sizeof (v6_next_hop_address));
5341           increment_v6_address (&v6_dst_address);
5342         }
5343       else
5344         {
5345           clib_memcpy (mp->dst_address, &v4_dst_address,
5346                        sizeof (v4_dst_address));
5347           if (next_hop_set)
5348             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5349                          sizeof (v4_next_hop_address));
5350           if (random_add_del)
5351             v4_dst_address.as_u32 = random_vector[j + 1];
5352           else
5353             increment_v4_address (&v4_dst_address);
5354         }
5355       /* send it... */
5356       S;
5357     }
5358
5359   /* When testing multiple add/del ops, use a control-ping to sync */
5360   if (count > 1)
5361     {
5362       vl_api_control_ping_t *mp;
5363       f64 after;
5364
5365       /* Shut off async mode */
5366       vam->async_mode = 0;
5367
5368       M (CONTROL_PING, control_ping);
5369       S;
5370
5371       timeout = vat_time_now (vam) + 1.0;
5372       while (vat_time_now (vam) < timeout)
5373         if (vam->result_ready == 1)
5374           goto out;
5375       vam->retval = -99;
5376
5377     out:
5378       if (vam->retval == -99)
5379         errmsg ("timeout\n");
5380
5381       if (vam->async_errors > 0)
5382         {
5383           errmsg ("%d asynchronous errors\n", vam->async_errors);
5384           vam->retval = -98;
5385         }
5386       vam->async_errors = 0;
5387       after = vat_time_now (vam);
5388
5389       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5390                count, after - before, count / (after - before));
5391     }
5392   else
5393     {
5394       /* Wait for a reply... */
5395       W;
5396     }
5397
5398   /* Return the good/bad news */
5399   return (vam->retval);
5400 }
5401
5402 static int
5403 api_proxy_arp_add_del (vat_main_t * vam)
5404 {
5405   unformat_input_t *i = vam->input;
5406   vl_api_proxy_arp_add_del_t *mp;
5407   f64 timeout;
5408   u32 vrf_id = 0;
5409   u8 is_add = 1;
5410   ip4_address_t lo, hi;
5411   u8 range_set = 0;
5412
5413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5414     {
5415       if (unformat (i, "vrf %d", &vrf_id))
5416         ;
5417       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5418                          unformat_ip4_address, &hi))
5419         range_set = 1;
5420       else if (unformat (i, "del"))
5421         is_add = 0;
5422       else
5423         {
5424           clib_warning ("parse error '%U'", format_unformat_error, i);
5425           return -99;
5426         }
5427     }
5428
5429   if (range_set == 0)
5430     {
5431       errmsg ("address range not set\n");
5432       return -99;
5433     }
5434
5435   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5436
5437   mp->vrf_id = ntohl (vrf_id);
5438   mp->is_add = is_add;
5439   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5440   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5441
5442   S;
5443   W;
5444   /* NOTREACHED */
5445   return 0;
5446 }
5447
5448 static int
5449 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5450 {
5451   unformat_input_t *i = vam->input;
5452   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5453   f64 timeout;
5454   u32 sw_if_index;
5455   u8 enable = 1;
5456   u8 sw_if_index_set = 0;
5457
5458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5459     {
5460       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5461         sw_if_index_set = 1;
5462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5463         sw_if_index_set = 1;
5464       else if (unformat (i, "enable"))
5465         enable = 1;
5466       else if (unformat (i, "disable"))
5467         enable = 0;
5468       else
5469         {
5470           clib_warning ("parse error '%U'", format_unformat_error, i);
5471           return -99;
5472         }
5473     }
5474
5475   if (sw_if_index_set == 0)
5476     {
5477       errmsg ("missing interface name or sw_if_index\n");
5478       return -99;
5479     }
5480
5481   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5482
5483   mp->sw_if_index = ntohl (sw_if_index);
5484   mp->enable_disable = enable;
5485
5486   S;
5487   W;
5488   /* NOTREACHED */
5489   return 0;
5490 }
5491
5492 static int
5493 api_mpls_add_del_decap (vat_main_t * vam)
5494 {
5495   unformat_input_t *i = vam->input;
5496   vl_api_mpls_add_del_decap_t *mp;
5497   f64 timeout;
5498   u32 rx_vrf_id = 0;
5499   u32 tx_vrf_id = 0;
5500   u32 label = 0;
5501   u8 is_add = 1;
5502   u8 s_bit = 1;
5503   u32 next_index = 1;
5504
5505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5506     {
5507       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5508         ;
5509       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5510         ;
5511       else if (unformat (i, "label %d", &label))
5512         ;
5513       else if (unformat (i, "next-index %d", &next_index))
5514         ;
5515       else if (unformat (i, "del"))
5516         is_add = 0;
5517       else if (unformat (i, "s-bit-clear"))
5518         s_bit = 0;
5519       else
5520         {
5521           clib_warning ("parse error '%U'", format_unformat_error, i);
5522           return -99;
5523         }
5524     }
5525
5526   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5527
5528   mp->rx_vrf_id = ntohl (rx_vrf_id);
5529   mp->tx_vrf_id = ntohl (tx_vrf_id);
5530   mp->label = ntohl (label);
5531   mp->next_index = ntohl (next_index);
5532   mp->s_bit = s_bit;
5533   mp->is_add = is_add;
5534
5535   S;
5536   W;
5537   /* NOTREACHED */
5538   return 0;
5539 }
5540
5541 static int
5542 api_mpls_add_del_encap (vat_main_t * vam)
5543 {
5544   unformat_input_t *i = vam->input;
5545   vl_api_mpls_add_del_encap_t *mp;
5546   f64 timeout;
5547   u32 vrf_id = 0;
5548   u32 *labels = 0;
5549   u32 label;
5550   ip4_address_t dst_address;
5551   u8 is_add = 1;
5552
5553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5554     {
5555       if (unformat (i, "vrf %d", &vrf_id))
5556         ;
5557       else if (unformat (i, "label %d", &label))
5558         vec_add1 (labels, ntohl (label));
5559       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5560         ;
5561       else if (unformat (i, "del"))
5562         is_add = 0;
5563       else
5564         {
5565           clib_warning ("parse error '%U'", format_unformat_error, i);
5566           return -99;
5567         }
5568     }
5569
5570   if (vec_len (labels) == 0)
5571     {
5572       errmsg ("missing encap label stack\n");
5573       return -99;
5574     }
5575
5576   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5577       sizeof (u32) * vec_len (labels));
5578
5579   mp->vrf_id = ntohl (vrf_id);
5580   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5581   mp->is_add = is_add;
5582   mp->nlabels = vec_len (labels);
5583   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5584
5585   vec_free (labels);
5586
5587   S;
5588   W;
5589   /* NOTREACHED */
5590   return 0;
5591 }
5592
5593 static int
5594 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5595 {
5596   unformat_input_t *i = vam->input;
5597   vl_api_mpls_gre_add_del_tunnel_t *mp;
5598   f64 timeout;
5599   u32 inner_vrf_id = 0;
5600   u32 outer_vrf_id = 0;
5601   ip4_address_t src_address;
5602   ip4_address_t dst_address;
5603   ip4_address_t intfc_address;
5604   u32 tmp;
5605   u8 intfc_address_length = 0;
5606   u8 is_add = 1;
5607   u8 l2_only = 0;
5608
5609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5610     {
5611       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5612         ;
5613       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5614         ;
5615       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5616         ;
5617       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5618         ;
5619       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5620                          &intfc_address, &tmp))
5621         intfc_address_length = tmp;
5622       else if (unformat (i, "l2-only"))
5623         l2_only = 1;
5624       else if (unformat (i, "del"))
5625         is_add = 0;
5626       else
5627         {
5628           clib_warning ("parse error '%U'", format_unformat_error, i);
5629           return -99;
5630         }
5631     }
5632
5633   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5634
5635   mp->inner_vrf_id = ntohl (inner_vrf_id);
5636   mp->outer_vrf_id = ntohl (outer_vrf_id);
5637   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5638   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5639   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5640   mp->intfc_address_length = intfc_address_length;
5641   mp->l2_only = l2_only;
5642   mp->is_add = is_add;
5643
5644   S;
5645   W;
5646   /* NOTREACHED */
5647   return 0;
5648 }
5649
5650 static int
5651 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5652 {
5653   unformat_input_t *i = vam->input;
5654   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5655   f64 timeout;
5656   u32 inner_vrf_id = 0;
5657   ip4_address_t intfc_address;
5658   u8 dst_mac_address[6];
5659   int dst_set = 1;
5660   u32 tmp;
5661   u8 intfc_address_length = 0;
5662   u8 is_add = 1;
5663   u8 l2_only = 0;
5664   u32 tx_sw_if_index;
5665   int tx_sw_if_index_set = 0;
5666
5667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668     {
5669       if (unformat (i, "vrf %d", &inner_vrf_id))
5670         ;
5671       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5672                          &intfc_address, &tmp))
5673         intfc_address_length = tmp;
5674       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5675         tx_sw_if_index_set = 1;
5676       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5677         tx_sw_if_index_set = 1;
5678       else if (unformat (i, "dst %U", unformat_ethernet_address,
5679                          dst_mac_address))
5680         dst_set = 1;
5681       else if (unformat (i, "l2-only"))
5682         l2_only = 1;
5683       else if (unformat (i, "del"))
5684         is_add = 0;
5685       else
5686         {
5687           clib_warning ("parse error '%U'", format_unformat_error, i);
5688           return -99;
5689         }
5690     }
5691
5692   if (!dst_set)
5693     {
5694       errmsg ("dst (mac address) not set\n");
5695       return -99;
5696     }
5697   if (!tx_sw_if_index_set)
5698     {
5699       errmsg ("tx-intfc not set\n");
5700       return -99;
5701     }
5702
5703   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5704
5705   mp->vrf_id = ntohl (inner_vrf_id);
5706   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5707   mp->adj_address_length = intfc_address_length;
5708   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5709                sizeof (dst_mac_address));
5710   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5711   mp->l2_only = l2_only;
5712   mp->is_add = is_add;
5713
5714   S;
5715   W;
5716   /* NOTREACHED */
5717   return 0;
5718 }
5719
5720 static int
5721 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5722 {
5723   unformat_input_t *i = vam->input;
5724   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5725   f64 timeout;
5726   u32 inner_vrf_id = 0;
5727   u32 outer_vrf_id = 0;
5728   ip4_address_t adj_address;
5729   int adj_address_set = 0;
5730   ip4_address_t next_hop_address;
5731   int next_hop_address_set = 0;
5732   u32 tmp;
5733   u8 adj_address_length = 0;
5734   u8 l2_only = 0;
5735   u8 is_add = 1;
5736   u32 resolve_attempts = 5;
5737   u8 resolve_if_needed = 1;
5738
5739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5740     {
5741       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5742         ;
5743       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5744         ;
5745       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5746                          &adj_address, &tmp))
5747         {
5748           adj_address_length = tmp;
5749           adj_address_set = 1;
5750         }
5751       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5752                          &next_hop_address))
5753         next_hop_address_set = 1;
5754       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5755         ;
5756       else if (unformat (i, "resolve-if-needed %d", &tmp))
5757         resolve_if_needed = tmp;
5758       else if (unformat (i, "l2-only"))
5759         l2_only = 1;
5760       else if (unformat (i, "del"))
5761         is_add = 0;
5762       else
5763         {
5764           clib_warning ("parse error '%U'", format_unformat_error, i);
5765           return -99;
5766         }
5767     }
5768
5769   if (!adj_address_set)
5770     {
5771       errmsg ("adjacency address/mask not set\n");
5772       return -99;
5773     }
5774   if (!next_hop_address_set)
5775     {
5776       errmsg ("ip4 next hop address (in outer fib) not set\n");
5777       return -99;
5778     }
5779
5780   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5781
5782   mp->inner_vrf_id = ntohl (inner_vrf_id);
5783   mp->outer_vrf_id = ntohl (outer_vrf_id);
5784   mp->resolve_attempts = ntohl (resolve_attempts);
5785   mp->resolve_if_needed = resolve_if_needed;
5786   mp->is_add = is_add;
5787   mp->l2_only = l2_only;
5788   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5789   mp->adj_address_length = adj_address_length;
5790   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5791                sizeof (next_hop_address));
5792
5793   S;
5794   W;
5795   /* NOTREACHED */
5796   return 0;
5797 }
5798
5799 static int
5800 api_sw_interface_set_unnumbered (vat_main_t * vam)
5801 {
5802   unformat_input_t *i = vam->input;
5803   vl_api_sw_interface_set_unnumbered_t *mp;
5804   f64 timeout;
5805   u32 sw_if_index;
5806   u32 unnum_sw_index = ~0;
5807   u8 is_add = 1;
5808   u8 sw_if_index_set = 0;
5809
5810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5811     {
5812       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5813         sw_if_index_set = 1;
5814       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5815         sw_if_index_set = 1;
5816       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5817         ;
5818       else if (unformat (i, "del"))
5819         is_add = 0;
5820       else
5821         {
5822           clib_warning ("parse error '%U'", format_unformat_error, i);
5823           return -99;
5824         }
5825     }
5826
5827   if (sw_if_index_set == 0)
5828     {
5829       errmsg ("missing interface name or sw_if_index\n");
5830       return -99;
5831     }
5832
5833   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5834
5835   mp->sw_if_index = ntohl (sw_if_index);
5836   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5837   mp->is_add = is_add;
5838
5839   S;
5840   W;
5841   /* NOTREACHED */
5842   return 0;
5843 }
5844
5845 static int
5846 api_ip_neighbor_add_del (vat_main_t * vam)
5847 {
5848   unformat_input_t *i = vam->input;
5849   vl_api_ip_neighbor_add_del_t *mp;
5850   f64 timeout;
5851   u32 sw_if_index;
5852   u8 sw_if_index_set = 0;
5853   u32 vrf_id = 0;
5854   u8 is_add = 1;
5855   u8 is_static = 0;
5856   u8 mac_address[6];
5857   u8 mac_set = 0;
5858   u8 v4_address_set = 0;
5859   u8 v6_address_set = 0;
5860   ip4_address_t v4address;
5861   ip6_address_t v6address;
5862
5863   memset (mac_address, 0, sizeof (mac_address));
5864
5865   /* Parse args required to build the message */
5866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5867     {
5868       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5869         {
5870           mac_set = 1;
5871         }
5872       else if (unformat (i, "del"))
5873         is_add = 0;
5874       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5875         sw_if_index_set = 1;
5876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5877         sw_if_index_set = 1;
5878       else if (unformat (i, "is_static"))
5879         is_static = 1;
5880       else if (unformat (i, "vrf %d", &vrf_id))
5881         ;
5882       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5883         v4_address_set = 1;
5884       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5885         v6_address_set = 1;
5886       else
5887         {
5888           clib_warning ("parse error '%U'", format_unformat_error, i);
5889           return -99;
5890         }
5891     }
5892
5893   if (sw_if_index_set == 0)
5894     {
5895       errmsg ("missing interface name or sw_if_index\n");
5896       return -99;
5897     }
5898   if (v4_address_set && v6_address_set)
5899     {
5900       errmsg ("both v4 and v6 addresses set\n");
5901       return -99;
5902     }
5903   if (!v4_address_set && !v6_address_set)
5904     {
5905       errmsg ("no address set\n");
5906       return -99;
5907     }
5908
5909   /* Construct the API message */
5910   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5911
5912   mp->sw_if_index = ntohl (sw_if_index);
5913   mp->is_add = is_add;
5914   mp->vrf_id = ntohl (vrf_id);
5915   mp->is_static = is_static;
5916   if (mac_set)
5917     clib_memcpy (mp->mac_address, mac_address, 6);
5918   if (v6_address_set)
5919     {
5920       mp->is_ipv6 = 1;
5921       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
5922     }
5923   else
5924     {
5925       /* mp->is_ipv6 = 0; via memset in M macro above */
5926       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
5927     }
5928
5929   /* send it... */
5930   S;
5931
5932   /* Wait for a reply, return good/bad news  */
5933   W;
5934
5935   /* NOTREACHED */
5936   return 0;
5937 }
5938
5939 static int
5940 api_reset_vrf (vat_main_t * vam)
5941 {
5942   unformat_input_t *i = vam->input;
5943   vl_api_reset_vrf_t *mp;
5944   f64 timeout;
5945   u32 vrf_id = 0;
5946   u8 is_ipv6 = 0;
5947   u8 vrf_id_set = 0;
5948
5949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5950     {
5951       if (unformat (i, "vrf %d", &vrf_id))
5952         vrf_id_set = 1;
5953       else if (unformat (i, "ipv6"))
5954         is_ipv6 = 1;
5955       else
5956         {
5957           clib_warning ("parse error '%U'", format_unformat_error, i);
5958           return -99;
5959         }
5960     }
5961
5962   if (vrf_id_set == 0)
5963     {
5964       errmsg ("missing vrf id\n");
5965       return -99;
5966     }
5967
5968   M (RESET_VRF, reset_vrf);
5969
5970   mp->vrf_id = ntohl (vrf_id);
5971   mp->is_ipv6 = is_ipv6;
5972
5973   S;
5974   W;
5975   /* NOTREACHED */
5976   return 0;
5977 }
5978
5979 static int
5980 api_create_vlan_subif (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_create_vlan_subif_t *mp;
5984   f64 timeout;
5985   u32 sw_if_index;
5986   u8 sw_if_index_set = 0;
5987   u32 vlan_id;
5988   u8 vlan_id_set = 0;
5989
5990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5991     {
5992       if (unformat (i, "sw_if_index %d", &sw_if_index))
5993         sw_if_index_set = 1;
5994       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5995         sw_if_index_set = 1;
5996       else if (unformat (i, "vlan %d", &vlan_id))
5997         vlan_id_set = 1;
5998       else
5999         {
6000           clib_warning ("parse error '%U'", format_unformat_error, i);
6001           return -99;
6002         }
6003     }
6004
6005   if (sw_if_index_set == 0)
6006     {
6007       errmsg ("missing interface name or sw_if_index\n");
6008       return -99;
6009     }
6010
6011   if (vlan_id_set == 0)
6012     {
6013       errmsg ("missing vlan_id\n");
6014       return -99;
6015     }
6016   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6017
6018   mp->sw_if_index = ntohl (sw_if_index);
6019   mp->vlan_id = ntohl (vlan_id);
6020
6021   S;
6022   W;
6023   /* NOTREACHED */
6024   return 0;
6025 }
6026
6027 #define foreach_create_subif_bit                \
6028 _(no_tags)                                      \
6029 _(one_tag)                                      \
6030 _(two_tags)                                     \
6031 _(dot1ad)                                       \
6032 _(exact_match)                                  \
6033 _(default_sub)                                  \
6034 _(outer_vlan_id_any)                            \
6035 _(inner_vlan_id_any)
6036
6037 static int
6038 api_create_subif (vat_main_t * vam)
6039 {
6040   unformat_input_t *i = vam->input;
6041   vl_api_create_subif_t *mp;
6042   f64 timeout;
6043   u32 sw_if_index;
6044   u8 sw_if_index_set = 0;
6045   u32 sub_id;
6046   u8 sub_id_set = 0;
6047   u32 no_tags = 0;
6048   u32 one_tag = 0;
6049   u32 two_tags = 0;
6050   u32 dot1ad = 0;
6051   u32 exact_match = 0;
6052   u32 default_sub = 0;
6053   u32 outer_vlan_id_any = 0;
6054   u32 inner_vlan_id_any = 0;
6055   u32 tmp;
6056   u16 outer_vlan_id = 0;
6057   u16 inner_vlan_id = 0;
6058
6059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6060     {
6061       if (unformat (i, "sw_if_index %d", &sw_if_index))
6062         sw_if_index_set = 1;
6063       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6064         sw_if_index_set = 1;
6065       else if (unformat (i, "sub_id %d", &sub_id))
6066         sub_id_set = 1;
6067       else if (unformat (i, "outer_vlan_id %d", &tmp))
6068         outer_vlan_id = tmp;
6069       else if (unformat (i, "inner_vlan_id %d", &tmp))
6070         inner_vlan_id = tmp;
6071
6072 #define _(a) else if (unformat (i, #a)) a = 1 ;
6073       foreach_create_subif_bit
6074 #undef _
6075         else
6076         {
6077           clib_warning ("parse error '%U'", format_unformat_error, i);
6078           return -99;
6079         }
6080     }
6081
6082   if (sw_if_index_set == 0)
6083     {
6084       errmsg ("missing interface name or sw_if_index\n");
6085       return -99;
6086     }
6087
6088   if (sub_id_set == 0)
6089     {
6090       errmsg ("missing sub_id\n");
6091       return -99;
6092     }
6093   M (CREATE_SUBIF, create_subif);
6094
6095   mp->sw_if_index = ntohl (sw_if_index);
6096   mp->sub_id = ntohl (sub_id);
6097
6098 #define _(a) mp->a = a;
6099   foreach_create_subif_bit;
6100 #undef _
6101
6102   mp->outer_vlan_id = ntohs (outer_vlan_id);
6103   mp->inner_vlan_id = ntohs (inner_vlan_id);
6104
6105   S;
6106   W;
6107   /* NOTREACHED */
6108   return 0;
6109 }
6110
6111 static int
6112 api_oam_add_del (vat_main_t * vam)
6113 {
6114   unformat_input_t *i = vam->input;
6115   vl_api_oam_add_del_t *mp;
6116   f64 timeout;
6117   u32 vrf_id = 0;
6118   u8 is_add = 1;
6119   ip4_address_t src, dst;
6120   u8 src_set = 0;
6121   u8 dst_set = 0;
6122
6123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6124     {
6125       if (unformat (i, "vrf %d", &vrf_id))
6126         ;
6127       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6128         src_set = 1;
6129       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6130         dst_set = 1;
6131       else if (unformat (i, "del"))
6132         is_add = 0;
6133       else
6134         {
6135           clib_warning ("parse error '%U'", format_unformat_error, i);
6136           return -99;
6137         }
6138     }
6139
6140   if (src_set == 0)
6141     {
6142       errmsg ("missing src addr\n");
6143       return -99;
6144     }
6145
6146   if (dst_set == 0)
6147     {
6148       errmsg ("missing dst addr\n");
6149       return -99;
6150     }
6151
6152   M (OAM_ADD_DEL, oam_add_del);
6153
6154   mp->vrf_id = ntohl (vrf_id);
6155   mp->is_add = is_add;
6156   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6157   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6158
6159   S;
6160   W;
6161   /* NOTREACHED */
6162   return 0;
6163 }
6164
6165 static int
6166 api_reset_fib (vat_main_t * vam)
6167 {
6168   unformat_input_t *i = vam->input;
6169   vl_api_reset_fib_t *mp;
6170   f64 timeout;
6171   u32 vrf_id = 0;
6172   u8 is_ipv6 = 0;
6173   u8 vrf_id_set = 0;
6174
6175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6176     {
6177       if (unformat (i, "vrf %d", &vrf_id))
6178         vrf_id_set = 1;
6179       else if (unformat (i, "ipv6"))
6180         is_ipv6 = 1;
6181       else
6182         {
6183           clib_warning ("parse error '%U'", format_unformat_error, i);
6184           return -99;
6185         }
6186     }
6187
6188   if (vrf_id_set == 0)
6189     {
6190       errmsg ("missing vrf id\n");
6191       return -99;
6192     }
6193
6194   M (RESET_FIB, reset_fib);
6195
6196   mp->vrf_id = ntohl (vrf_id);
6197   mp->is_ipv6 = is_ipv6;
6198
6199   S;
6200   W;
6201   /* NOTREACHED */
6202   return 0;
6203 }
6204
6205 static int
6206 api_dhcp_proxy_config (vat_main_t * vam)
6207 {
6208   unformat_input_t *i = vam->input;
6209   vl_api_dhcp_proxy_config_t *mp;
6210   f64 timeout;
6211   u32 vrf_id = 0;
6212   u8 is_add = 1;
6213   u8 insert_cid = 1;
6214   u8 v4_address_set = 0;
6215   u8 v6_address_set = 0;
6216   ip4_address_t v4address;
6217   ip6_address_t v6address;
6218   u8 v4_src_address_set = 0;
6219   u8 v6_src_address_set = 0;
6220   ip4_address_t v4srcaddress;
6221   ip6_address_t v6srcaddress;
6222
6223   /* Parse args required to build the message */
6224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6225     {
6226       if (unformat (i, "del"))
6227         is_add = 0;
6228       else if (unformat (i, "vrf %d", &vrf_id))
6229         ;
6230       else if (unformat (i, "insert-cid %d", &insert_cid))
6231         ;
6232       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6233         v4_address_set = 1;
6234       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6235         v6_address_set = 1;
6236       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6237         v4_src_address_set = 1;
6238       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6239         v6_src_address_set = 1;
6240       else
6241         break;
6242     }
6243
6244   if (v4_address_set && v6_address_set)
6245     {
6246       errmsg ("both v4 and v6 server addresses set\n");
6247       return -99;
6248     }
6249   if (!v4_address_set && !v6_address_set)
6250     {
6251       errmsg ("no server addresses set\n");
6252       return -99;
6253     }
6254
6255   if (v4_src_address_set && v6_src_address_set)
6256     {
6257       errmsg ("both v4 and v6  src addresses set\n");
6258       return -99;
6259     }
6260   if (!v4_src_address_set && !v6_src_address_set)
6261     {
6262       errmsg ("no src addresses set\n");
6263       return -99;
6264     }
6265
6266   if (!(v4_src_address_set && v4_address_set) &&
6267       !(v6_src_address_set && v6_address_set))
6268     {
6269       errmsg ("no matching server and src addresses set\n");
6270       return -99;
6271     }
6272
6273   /* Construct the API message */
6274   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6275
6276   mp->insert_circuit_id = insert_cid;
6277   mp->is_add = is_add;
6278   mp->vrf_id = ntohl (vrf_id);
6279   if (v6_address_set)
6280     {
6281       mp->is_ipv6 = 1;
6282       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6283       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6284     }
6285   else
6286     {
6287       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6288       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6289     }
6290
6291   /* send it... */
6292   S;
6293
6294   /* Wait for a reply, return good/bad news  */
6295   W;
6296   /* NOTREACHED */
6297   return 0;
6298 }
6299
6300 static int
6301 api_dhcp_proxy_config_2 (vat_main_t * vam)
6302 {
6303   unformat_input_t *i = vam->input;
6304   vl_api_dhcp_proxy_config_2_t *mp;
6305   f64 timeout;
6306   u32 rx_vrf_id = 0;
6307   u32 server_vrf_id = 0;
6308   u8 is_add = 1;
6309   u8 insert_cid = 1;
6310   u8 v4_address_set = 0;
6311   u8 v6_address_set = 0;
6312   ip4_address_t v4address;
6313   ip6_address_t v6address;
6314   u8 v4_src_address_set = 0;
6315   u8 v6_src_address_set = 0;
6316   ip4_address_t v4srcaddress;
6317   ip6_address_t v6srcaddress;
6318
6319   /* Parse args required to build the message */
6320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6321     {
6322       if (unformat (i, "del"))
6323         is_add = 0;
6324       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6325         ;
6326       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6327         ;
6328       else if (unformat (i, "insert-cid %d", &insert_cid))
6329         ;
6330       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6331         v4_address_set = 1;
6332       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6333         v6_address_set = 1;
6334       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6335         v4_src_address_set = 1;
6336       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6337         v6_src_address_set = 1;
6338       else
6339         break;
6340     }
6341
6342   if (v4_address_set && v6_address_set)
6343     {
6344       errmsg ("both v4 and v6 server addresses set\n");
6345       return -99;
6346     }
6347   if (!v4_address_set && !v6_address_set)
6348     {
6349       errmsg ("no server addresses set\n");
6350       return -99;
6351     }
6352
6353   if (v4_src_address_set && v6_src_address_set)
6354     {
6355       errmsg ("both v4 and v6  src addresses set\n");
6356       return -99;
6357     }
6358   if (!v4_src_address_set && !v6_src_address_set)
6359     {
6360       errmsg ("no src addresses set\n");
6361       return -99;
6362     }
6363
6364   if (!(v4_src_address_set && v4_address_set) &&
6365       !(v6_src_address_set && v6_address_set))
6366     {
6367       errmsg ("no matching server and src addresses set\n");
6368       return -99;
6369     }
6370
6371   /* Construct the API message */
6372   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6373
6374   mp->insert_circuit_id = insert_cid;
6375   mp->is_add = is_add;
6376   mp->rx_vrf_id = ntohl (rx_vrf_id);
6377   mp->server_vrf_id = ntohl (server_vrf_id);
6378   if (v6_address_set)
6379     {
6380       mp->is_ipv6 = 1;
6381       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6382       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6383     }
6384   else
6385     {
6386       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6387       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6388     }
6389
6390   /* send it... */
6391   S;
6392
6393   /* Wait for a reply, return good/bad news  */
6394   W;
6395   /* NOTREACHED */
6396   return 0;
6397 }
6398
6399 static int
6400 api_dhcp_proxy_set_vss (vat_main_t * vam)
6401 {
6402   unformat_input_t *i = vam->input;
6403   vl_api_dhcp_proxy_set_vss_t *mp;
6404   f64 timeout;
6405   u8 is_ipv6 = 0;
6406   u8 is_add = 1;
6407   u32 tbl_id;
6408   u8 tbl_id_set = 0;
6409   u32 oui;
6410   u8 oui_set = 0;
6411   u32 fib_id;
6412   u8 fib_id_set = 0;
6413
6414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6415     {
6416       if (unformat (i, "tbl_id %d", &tbl_id))
6417         tbl_id_set = 1;
6418       if (unformat (i, "fib_id %d", &fib_id))
6419         fib_id_set = 1;
6420       if (unformat (i, "oui %d", &oui))
6421         oui_set = 1;
6422       else if (unformat (i, "ipv6"))
6423         is_ipv6 = 1;
6424       else if (unformat (i, "del"))
6425         is_add = 0;
6426       else
6427         {
6428           clib_warning ("parse error '%U'", format_unformat_error, i);
6429           return -99;
6430         }
6431     }
6432
6433   if (tbl_id_set == 0)
6434     {
6435       errmsg ("missing tbl id\n");
6436       return -99;
6437     }
6438
6439   if (fib_id_set == 0)
6440     {
6441       errmsg ("missing fib id\n");
6442       return -99;
6443     }
6444   if (oui_set == 0)
6445     {
6446       errmsg ("missing oui\n");
6447       return -99;
6448     }
6449
6450   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6451   mp->tbl_id = ntohl (tbl_id);
6452   mp->fib_id = ntohl (fib_id);
6453   mp->oui = ntohl (oui);
6454   mp->is_ipv6 = is_ipv6;
6455   mp->is_add = is_add;
6456
6457   S;
6458   W;
6459   /* NOTREACHED */
6460   return 0;
6461 }
6462
6463 static int
6464 api_dhcp_client_config (vat_main_t * vam)
6465 {
6466   unformat_input_t *i = vam->input;
6467   vl_api_dhcp_client_config_t *mp;
6468   f64 timeout;
6469   u32 sw_if_index;
6470   u8 sw_if_index_set = 0;
6471   u8 is_add = 1;
6472   u8 *hostname = 0;
6473   u8 disable_event = 0;
6474
6475   /* Parse args required to build the message */
6476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6477     {
6478       if (unformat (i, "del"))
6479         is_add = 0;
6480       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6481         sw_if_index_set = 1;
6482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6483         sw_if_index_set = 1;
6484       else if (unformat (i, "hostname %s", &hostname))
6485         ;
6486       else if (unformat (i, "disable_event"))
6487         disable_event = 1;
6488       else
6489         break;
6490     }
6491
6492   if (sw_if_index_set == 0)
6493     {
6494       errmsg ("missing interface name or sw_if_index\n");
6495       return -99;
6496     }
6497
6498   if (vec_len (hostname) > 63)
6499     {
6500       errmsg ("hostname too long\n");
6501     }
6502   vec_add1 (hostname, 0);
6503
6504   /* Construct the API message */
6505   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6506
6507   mp->sw_if_index = ntohl (sw_if_index);
6508   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6509   vec_free (hostname);
6510   mp->is_add = is_add;
6511   mp->want_dhcp_event = disable_event ? 0 : 1;
6512   mp->pid = getpid ();
6513
6514   /* send it... */
6515   S;
6516
6517   /* Wait for a reply, return good/bad news  */
6518   W;
6519   /* NOTREACHED */
6520   return 0;
6521 }
6522
6523 static int
6524 api_set_ip_flow_hash (vat_main_t * vam)
6525 {
6526   unformat_input_t *i = vam->input;
6527   vl_api_set_ip_flow_hash_t *mp;
6528   f64 timeout;
6529   u32 vrf_id = 0;
6530   u8 is_ipv6 = 0;
6531   u8 vrf_id_set = 0;
6532   u8 src = 0;
6533   u8 dst = 0;
6534   u8 sport = 0;
6535   u8 dport = 0;
6536   u8 proto = 0;
6537   u8 reverse = 0;
6538
6539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6540     {
6541       if (unformat (i, "vrf %d", &vrf_id))
6542         vrf_id_set = 1;
6543       else if (unformat (i, "ipv6"))
6544         is_ipv6 = 1;
6545       else if (unformat (i, "src"))
6546         src = 1;
6547       else if (unformat (i, "dst"))
6548         dst = 1;
6549       else if (unformat (i, "sport"))
6550         sport = 1;
6551       else if (unformat (i, "dport"))
6552         dport = 1;
6553       else if (unformat (i, "proto"))
6554         proto = 1;
6555       else if (unformat (i, "reverse"))
6556         reverse = 1;
6557
6558       else
6559         {
6560           clib_warning ("parse error '%U'", format_unformat_error, i);
6561           return -99;
6562         }
6563     }
6564
6565   if (vrf_id_set == 0)
6566     {
6567       errmsg ("missing vrf id\n");
6568       return -99;
6569     }
6570
6571   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6572   mp->src = src;
6573   mp->dst = dst;
6574   mp->sport = sport;
6575   mp->dport = dport;
6576   mp->proto = proto;
6577   mp->reverse = reverse;
6578   mp->vrf_id = ntohl (vrf_id);
6579   mp->is_ipv6 = is_ipv6;
6580
6581   S;
6582   W;
6583   /* NOTREACHED */
6584   return 0;
6585 }
6586
6587 static int
6588 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6589 {
6590   unformat_input_t *i = vam->input;
6591   vl_api_sw_interface_ip6_enable_disable_t *mp;
6592   f64 timeout;
6593   u32 sw_if_index;
6594   u8 sw_if_index_set = 0;
6595   u8 enable = 0;
6596
6597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6598     {
6599       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6600         sw_if_index_set = 1;
6601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6602         sw_if_index_set = 1;
6603       else if (unformat (i, "enable"))
6604         enable = 1;
6605       else if (unformat (i, "disable"))
6606         enable = 0;
6607       else
6608         {
6609           clib_warning ("parse error '%U'", format_unformat_error, i);
6610           return -99;
6611         }
6612     }
6613
6614   if (sw_if_index_set == 0)
6615     {
6616       errmsg ("missing interface name or sw_if_index\n");
6617       return -99;
6618     }
6619
6620   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6621
6622   mp->sw_if_index = ntohl (sw_if_index);
6623   mp->enable = enable;
6624
6625   S;
6626   W;
6627   /* NOTREACHED */
6628   return 0;
6629 }
6630
6631 static int
6632 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6633 {
6634   unformat_input_t *i = vam->input;
6635   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6636   f64 timeout;
6637   u32 sw_if_index;
6638   u8 sw_if_index_set = 0;
6639   u32 address_length = 0;
6640   u8 v6_address_set = 0;
6641   ip6_address_t v6address;
6642
6643   /* Parse args required to build the message */
6644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6645     {
6646       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6647         sw_if_index_set = 1;
6648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6649         sw_if_index_set = 1;
6650       else if (unformat (i, "%U/%d",
6651                          unformat_ip6_address, &v6address, &address_length))
6652         v6_address_set = 1;
6653       else
6654         break;
6655     }
6656
6657   if (sw_if_index_set == 0)
6658     {
6659       errmsg ("missing interface name or sw_if_index\n");
6660       return -99;
6661     }
6662   if (!v6_address_set)
6663     {
6664       errmsg ("no address set\n");
6665       return -99;
6666     }
6667
6668   /* Construct the API message */
6669   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6670      sw_interface_ip6_set_link_local_address);
6671
6672   mp->sw_if_index = ntohl (sw_if_index);
6673   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6674   mp->address_length = address_length;
6675
6676   /* send it... */
6677   S;
6678
6679   /* Wait for a reply, return good/bad news  */
6680   W;
6681
6682   /* NOTREACHED */
6683   return 0;
6684 }
6685
6686
6687 static int
6688 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6689 {
6690   unformat_input_t *i = vam->input;
6691   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6692   f64 timeout;
6693   u32 sw_if_index;
6694   u8 sw_if_index_set = 0;
6695   u32 address_length = 0;
6696   u8 v6_address_set = 0;
6697   ip6_address_t v6address;
6698   u8 use_default = 0;
6699   u8 no_advertise = 0;
6700   u8 off_link = 0;
6701   u8 no_autoconfig = 0;
6702   u8 no_onlink = 0;
6703   u8 is_no = 0;
6704   u32 val_lifetime = 0;
6705   u32 pref_lifetime = 0;
6706
6707   /* Parse args required to build the message */
6708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6709     {
6710       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6711         sw_if_index_set = 1;
6712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "%U/%d",
6715                          unformat_ip6_address, &v6address, &address_length))
6716         v6_address_set = 1;
6717       else if (unformat (i, "val_life %d", &val_lifetime))
6718         ;
6719       else if (unformat (i, "pref_life %d", &pref_lifetime))
6720         ;
6721       else if (unformat (i, "def"))
6722         use_default = 1;
6723       else if (unformat (i, "noadv"))
6724         no_advertise = 1;
6725       else if (unformat (i, "offl"))
6726         off_link = 1;
6727       else if (unformat (i, "noauto"))
6728         no_autoconfig = 1;
6729       else if (unformat (i, "nolink"))
6730         no_onlink = 1;
6731       else if (unformat (i, "isno"))
6732         is_no = 1;
6733       else
6734         {
6735           clib_warning ("parse error '%U'", format_unformat_error, i);
6736           return -99;
6737         }
6738     }
6739
6740   if (sw_if_index_set == 0)
6741     {
6742       errmsg ("missing interface name or sw_if_index\n");
6743       return -99;
6744     }
6745   if (!v6_address_set)
6746     {
6747       errmsg ("no address set\n");
6748       return -99;
6749     }
6750
6751   /* Construct the API message */
6752   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6753
6754   mp->sw_if_index = ntohl (sw_if_index);
6755   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6756   mp->address_length = address_length;
6757   mp->use_default = use_default;
6758   mp->no_advertise = no_advertise;
6759   mp->off_link = off_link;
6760   mp->no_autoconfig = no_autoconfig;
6761   mp->no_onlink = no_onlink;
6762   mp->is_no = is_no;
6763   mp->val_lifetime = ntohl (val_lifetime);
6764   mp->pref_lifetime = ntohl (pref_lifetime);
6765
6766   /* send it... */
6767   S;
6768
6769   /* Wait for a reply, return good/bad news  */
6770   W;
6771
6772   /* NOTREACHED */
6773   return 0;
6774 }
6775
6776 static int
6777 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6778 {
6779   unformat_input_t *i = vam->input;
6780   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6781   f64 timeout;
6782   u32 sw_if_index;
6783   u8 sw_if_index_set = 0;
6784   u8 suppress = 0;
6785   u8 managed = 0;
6786   u8 other = 0;
6787   u8 ll_option = 0;
6788   u8 send_unicast = 0;
6789   u8 cease = 0;
6790   u8 is_no = 0;
6791   u8 default_router = 0;
6792   u32 max_interval = 0;
6793   u32 min_interval = 0;
6794   u32 lifetime = 0;
6795   u32 initial_count = 0;
6796   u32 initial_interval = 0;
6797
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6803         sw_if_index_set = 1;
6804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6805         sw_if_index_set = 1;
6806       else if (unformat (i, "maxint %d", &max_interval))
6807         ;
6808       else if (unformat (i, "minint %d", &min_interval))
6809         ;
6810       else if (unformat (i, "life %d", &lifetime))
6811         ;
6812       else if (unformat (i, "count %d", &initial_count))
6813         ;
6814       else if (unformat (i, "interval %d", &initial_interval))
6815         ;
6816       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6817         suppress = 1;
6818       else if (unformat (i, "managed"))
6819         managed = 1;
6820       else if (unformat (i, "other"))
6821         other = 1;
6822       else if (unformat (i, "ll"))
6823         ll_option = 1;
6824       else if (unformat (i, "send"))
6825         send_unicast = 1;
6826       else if (unformat (i, "cease"))
6827         cease = 1;
6828       else if (unformat (i, "isno"))
6829         is_no = 1;
6830       else if (unformat (i, "def"))
6831         default_router = 1;
6832       else
6833         {
6834           clib_warning ("parse error '%U'", format_unformat_error, i);
6835           return -99;
6836         }
6837     }
6838
6839   if (sw_if_index_set == 0)
6840     {
6841       errmsg ("missing interface name or sw_if_index\n");
6842       return -99;
6843     }
6844
6845   /* Construct the API message */
6846   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6847
6848   mp->sw_if_index = ntohl (sw_if_index);
6849   mp->max_interval = ntohl (max_interval);
6850   mp->min_interval = ntohl (min_interval);
6851   mp->lifetime = ntohl (lifetime);
6852   mp->initial_count = ntohl (initial_count);
6853   mp->initial_interval = ntohl (initial_interval);
6854   mp->suppress = suppress;
6855   mp->managed = managed;
6856   mp->other = other;
6857   mp->ll_option = ll_option;
6858   mp->send_unicast = send_unicast;
6859   mp->cease = cease;
6860   mp->is_no = is_no;
6861   mp->default_router = default_router;
6862
6863   /* send it... */
6864   S;
6865
6866   /* Wait for a reply, return good/bad news  */
6867   W;
6868
6869   /* NOTREACHED */
6870   return 0;
6871 }
6872
6873 static int
6874 api_set_arp_neighbor_limit (vat_main_t * vam)
6875 {
6876   unformat_input_t *i = vam->input;
6877   vl_api_set_arp_neighbor_limit_t *mp;
6878   f64 timeout;
6879   u32 arp_nbr_limit;
6880   u8 limit_set = 0;
6881   u8 is_ipv6 = 0;
6882
6883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6884     {
6885       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6886         limit_set = 1;
6887       else if (unformat (i, "ipv6"))
6888         is_ipv6 = 1;
6889       else
6890         {
6891           clib_warning ("parse error '%U'", format_unformat_error, i);
6892           return -99;
6893         }
6894     }
6895
6896   if (limit_set == 0)
6897     {
6898       errmsg ("missing limit value\n");
6899       return -99;
6900     }
6901
6902   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6903
6904   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
6905   mp->is_ipv6 = is_ipv6;
6906
6907   S;
6908   W;
6909   /* NOTREACHED */
6910   return 0;
6911 }
6912
6913 static int
6914 api_l2_patch_add_del (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_l2_patch_add_del_t *mp;
6918   f64 timeout;
6919   u32 rx_sw_if_index;
6920   u8 rx_sw_if_index_set = 0;
6921   u32 tx_sw_if_index;
6922   u8 tx_sw_if_index_set = 0;
6923   u8 is_add = 1;
6924
6925   /* Parse args required to build the message */
6926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6927     {
6928       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6929         rx_sw_if_index_set = 1;
6930       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6931         tx_sw_if_index_set = 1;
6932       else if (unformat (i, "rx"))
6933         {
6934           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935             {
6936               if (unformat (i, "%U", unformat_sw_if_index, vam,
6937                             &rx_sw_if_index))
6938                 rx_sw_if_index_set = 1;
6939             }
6940           else
6941             break;
6942         }
6943       else if (unformat (i, "tx"))
6944         {
6945           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6946             {
6947               if (unformat (i, "%U", unformat_sw_if_index, vam,
6948                             &tx_sw_if_index))
6949                 tx_sw_if_index_set = 1;
6950             }
6951           else
6952             break;
6953         }
6954       else if (unformat (i, "del"))
6955         is_add = 0;
6956       else
6957         break;
6958     }
6959
6960   if (rx_sw_if_index_set == 0)
6961     {
6962       errmsg ("missing rx interface name or rx_sw_if_index\n");
6963       return -99;
6964     }
6965
6966   if (tx_sw_if_index_set == 0)
6967     {
6968       errmsg ("missing tx interface name or tx_sw_if_index\n");
6969       return -99;
6970     }
6971
6972   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
6973
6974   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6975   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6976   mp->is_add = is_add;
6977
6978   S;
6979   W;
6980   /* NOTREACHED */
6981   return 0;
6982 }
6983
6984 static int
6985 api_trace_profile_add (vat_main_t * vam)
6986 {
6987   unformat_input_t *input = vam->input;
6988   vl_api_trace_profile_add_t *mp;
6989   f64 timeout;
6990   u32 id = 0;
6991   u32 trace_option_elts = 0;
6992   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
6993   int has_pow_option = 0;
6994   int has_ppc_option = 0;
6995
6996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6997     {
6998       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
6999                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7000                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7001                     &node_id, &app_data))
7002         ;
7003       else if (unformat (input, "pow"))
7004         has_pow_option = 1;
7005       else if (unformat (input, "ppc encap"))
7006         has_ppc_option = PPC_ENCAP;
7007       else if (unformat (input, "ppc decap"))
7008         has_ppc_option = PPC_DECAP;
7009       else if (unformat (input, "ppc none"))
7010         has_ppc_option = PPC_NONE;
7011       else
7012         break;
7013     }
7014   M (TRACE_PROFILE_ADD, trace_profile_add);
7015   mp->id = htons (id);
7016   mp->trace_type = trace_type;
7017   mp->trace_num_elt = trace_option_elts;
7018   mp->trace_ppc = has_ppc_option;
7019   mp->trace_app_data = htonl (app_data);
7020   mp->pow_enable = has_pow_option;
7021   mp->trace_tsp = trace_tsp;
7022   mp->node_id = htonl (node_id);
7023
7024   S;
7025   W;
7026
7027   return (0);
7028
7029 }
7030
7031 static int
7032 api_trace_profile_apply (vat_main_t * vam)
7033 {
7034   unformat_input_t *input = vam->input;
7035   vl_api_trace_profile_apply_t *mp;
7036   f64 timeout;
7037   ip6_address_t addr;
7038   u32 mask_width = ~0;
7039   int is_add = 0;
7040   int is_pop = 0;
7041   int is_none = 0;
7042   u32 vrf_id = 0;
7043   u32 id = 0;
7044
7045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7046     {
7047       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7048         ;
7049       else if (unformat (input, "id %d", &id))
7050         ;
7051       else if (unformat (input, "vrf-id %d", &vrf_id))
7052         ;
7053       else if (unformat (input, "add"))
7054         is_add = 1;
7055       else if (unformat (input, "pop"))
7056         is_pop = 1;
7057       else if (unformat (input, "none"))
7058         is_none = 1;
7059       else
7060         break;
7061     }
7062
7063   if ((is_add + is_pop + is_none) != 1)
7064     {
7065       errmsg ("One of (add, pop, none) required");
7066       return -99;
7067     }
7068   if (mask_width == ~0)
7069     {
7070       errmsg ("<address>/<mask-width> required");
7071       return -99;
7072     }
7073   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7074   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7075   mp->id = htons (id);
7076   mp->prefix_length = htonl (mask_width);
7077   mp->vrf_id = htonl (vrf_id);
7078   if (is_add)
7079     mp->trace_op = IOAM_HBYH_ADD;
7080   else if (is_pop)
7081     mp->trace_op = IOAM_HBYH_POP;
7082   else
7083     mp->trace_op = IOAM_HBYH_MOD;
7084
7085   if (is_none)
7086     mp->enable = 0;
7087   else
7088     mp->enable = 1;
7089
7090   S;
7091   W;
7092
7093   return 0;
7094 }
7095
7096 static int
7097 api_trace_profile_del (vat_main_t * vam)
7098 {
7099   vl_api_trace_profile_del_t *mp;
7100   f64 timeout;
7101
7102   M (TRACE_PROFILE_DEL, trace_profile_del);
7103   S;
7104   W;
7105   return 0;
7106 }
7107
7108 static int
7109 api_sr_tunnel_add_del (vat_main_t * vam)
7110 {
7111   unformat_input_t *i = vam->input;
7112   vl_api_sr_tunnel_add_del_t *mp;
7113   f64 timeout;
7114   int is_del = 0;
7115   int pl_index;
7116   ip6_address_t src_address;
7117   int src_address_set = 0;
7118   ip6_address_t dst_address;
7119   u32 dst_mask_width;
7120   int dst_address_set = 0;
7121   u16 flags = 0;
7122   u32 rx_table_id = 0;
7123   u32 tx_table_id = 0;
7124   ip6_address_t *segments = 0;
7125   ip6_address_t *this_seg;
7126   ip6_address_t *tags = 0;
7127   ip6_address_t *this_tag;
7128   ip6_address_t next_address, tag;
7129   u8 *name = 0;
7130   u8 *policy_name = 0;
7131
7132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7133     {
7134       if (unformat (i, "del"))
7135         is_del = 1;
7136       else if (unformat (i, "name %s", &name))
7137         ;
7138       else if (unformat (i, "policy %s", &policy_name))
7139         ;
7140       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7141         ;
7142       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7143         ;
7144       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7145         src_address_set = 1;
7146       else if (unformat (i, "dst %U/%d",
7147                          unformat_ip6_address, &dst_address, &dst_mask_width))
7148         dst_address_set = 1;
7149       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7150         {
7151           vec_add2 (segments, this_seg, 1);
7152           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7153                        sizeof (*this_seg));
7154         }
7155       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7156         {
7157           vec_add2 (tags, this_tag, 1);
7158           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7159         }
7160       else if (unformat (i, "clean"))
7161         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7162       else if (unformat (i, "protected"))
7163         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7164       else if (unformat (i, "InPE %d", &pl_index))
7165         {
7166           if (pl_index <= 0 || pl_index > 4)
7167             {
7168             pl_index_range_error:
7169               errmsg ("pl index %d out of range\n", pl_index);
7170               return -99;
7171             }
7172           flags |=
7173             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7174         }
7175       else if (unformat (i, "EgPE %d", &pl_index))
7176         {
7177           if (pl_index <= 0 || pl_index > 4)
7178             goto pl_index_range_error;
7179           flags |=
7180             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7181         }
7182       else if (unformat (i, "OrgSrc %d", &pl_index))
7183         {
7184           if (pl_index <= 0 || pl_index > 4)
7185             goto pl_index_range_error;
7186           flags |=
7187             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7188         }
7189       else
7190         break;
7191     }
7192
7193   if (!src_address_set)
7194     {
7195       errmsg ("src address required\n");
7196       return -99;
7197     }
7198
7199   if (!dst_address_set)
7200     {
7201       errmsg ("dst address required\n");
7202       return -99;
7203     }
7204
7205   if (!segments)
7206     {
7207       errmsg ("at least one sr segment required\n");
7208       return -99;
7209     }
7210
7211   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7212       vec_len (segments) * sizeof (ip6_address_t)
7213       + vec_len (tags) * sizeof (ip6_address_t));
7214
7215   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7216   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7217   mp->dst_mask_width = dst_mask_width;
7218   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7219   mp->n_segments = vec_len (segments);
7220   mp->n_tags = vec_len (tags);
7221   mp->is_add = is_del == 0;
7222   clib_memcpy (mp->segs_and_tags, segments,
7223                vec_len (segments) * sizeof (ip6_address_t));
7224   clib_memcpy (mp->segs_and_tags +
7225                vec_len (segments) * sizeof (ip6_address_t), tags,
7226                vec_len (tags) * sizeof (ip6_address_t));
7227
7228   mp->outer_vrf_id = ntohl (rx_table_id);
7229   mp->inner_vrf_id = ntohl (tx_table_id);
7230   memcpy (mp->name, name, vec_len (name));
7231   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7232
7233   vec_free (segments);
7234   vec_free (tags);
7235
7236   S;
7237   W;
7238   /* NOTREACHED */
7239 }
7240
7241 static int
7242 api_sr_policy_add_del (vat_main_t * vam)
7243 {
7244   unformat_input_t *input = vam->input;
7245   vl_api_sr_policy_add_del_t *mp;
7246   f64 timeout;
7247   int is_del = 0;
7248   u8 *name = 0;
7249   u8 *tunnel_name = 0;
7250   u8 **tunnel_names = 0;
7251
7252   int name_set = 0;
7253   int tunnel_set = 0;
7254   int j = 0;
7255   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7256   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7257
7258   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7259     {
7260       if (unformat (input, "del"))
7261         is_del = 1;
7262       else if (unformat (input, "name %s", &name))
7263         name_set = 1;
7264       else if (unformat (input, "tunnel %s", &tunnel_name))
7265         {
7266           if (tunnel_name)
7267             {
7268               vec_add1 (tunnel_names, tunnel_name);
7269               /* For serializer:
7270                  - length = #bytes to store in serial vector
7271                  - +1 = byte to store that length
7272                */
7273               tunnel_names_length += (vec_len (tunnel_name) + 1);
7274               tunnel_set = 1;
7275               tunnel_name = 0;
7276             }
7277         }
7278       else
7279         break;
7280     }
7281
7282   if (!name_set)
7283     {
7284       errmsg ("policy name required\n");
7285       return -99;
7286     }
7287
7288   if ((!tunnel_set) && (!is_del))
7289     {
7290       errmsg ("tunnel name required\n");
7291       return -99;
7292     }
7293
7294   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7295
7296
7297
7298   mp->is_add = !is_del;
7299
7300   memcpy (mp->name, name, vec_len (name));
7301   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7302   u8 *serial_orig = 0;
7303   vec_validate (serial_orig, tunnel_names_length);
7304   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7305   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7306
7307   for (j = 0; j < vec_len (tunnel_names); j++)
7308     {
7309       tun_name_len = vec_len (tunnel_names[j]);
7310       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7311       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7312       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7313       serial_orig += tun_name_len;      // Advance past the copy
7314     }
7315   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7316
7317   vec_free (tunnel_names);
7318   vec_free (tunnel_name);
7319
7320   S;
7321   W;
7322   /* NOTREACHED */
7323 }
7324
7325 static int
7326 api_sr_multicast_map_add_del (vat_main_t * vam)
7327 {
7328   unformat_input_t *input = vam->input;
7329   vl_api_sr_multicast_map_add_del_t *mp;
7330   f64 timeout;
7331   int is_del = 0;
7332   ip6_address_t multicast_address;
7333   u8 *policy_name = 0;
7334   int multicast_address_set = 0;
7335
7336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7337     {
7338       if (unformat (input, "del"))
7339         is_del = 1;
7340       else
7341         if (unformat
7342             (input, "address %U", unformat_ip6_address, &multicast_address))
7343         multicast_address_set = 1;
7344       else if (unformat (input, "sr-policy %s", &policy_name))
7345         ;
7346       else
7347         break;
7348     }
7349
7350   if (!is_del && !policy_name)
7351     {
7352       errmsg ("sr-policy name required\n");
7353       return -99;
7354     }
7355
7356
7357   if (!multicast_address_set)
7358     {
7359       errmsg ("address required\n");
7360       return -99;
7361     }
7362
7363   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7364
7365   mp->is_add = !is_del;
7366   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7367   clib_memcpy (mp->multicast_address, &multicast_address,
7368                sizeof (mp->multicast_address));
7369
7370
7371   vec_free (policy_name);
7372
7373   S;
7374   W;
7375   /* NOTREACHED */
7376 }
7377
7378
7379 #define foreach_ip4_proto_field                 \
7380 _(src_address)                                  \
7381 _(dst_address)                                  \
7382 _(tos)                                          \
7383 _(length)                                       \
7384 _(fragment_id)                                  \
7385 _(ttl)                                          \
7386 _(protocol)                                     \
7387 _(checksum)
7388
7389 uword
7390 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7391 {
7392   u8 **maskp = va_arg (*args, u8 **);
7393   u8 *mask = 0;
7394   u8 found_something = 0;
7395   ip4_header_t *ip;
7396
7397 #define _(a) u8 a=0;
7398   foreach_ip4_proto_field;
7399 #undef _
7400   u8 version = 0;
7401   u8 hdr_length = 0;
7402
7403
7404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7405     {
7406       if (unformat (input, "version"))
7407         version = 1;
7408       else if (unformat (input, "hdr_length"))
7409         hdr_length = 1;
7410       else if (unformat (input, "src"))
7411         src_address = 1;
7412       else if (unformat (input, "dst"))
7413         dst_address = 1;
7414       else if (unformat (input, "proto"))
7415         protocol = 1;
7416
7417 #define _(a) else if (unformat (input, #a)) a=1;
7418       foreach_ip4_proto_field
7419 #undef _
7420         else
7421         break;
7422     }
7423
7424 #define _(a) found_something += a;
7425   foreach_ip4_proto_field;
7426 #undef _
7427
7428   if (found_something == 0)
7429     return 0;
7430
7431   vec_validate (mask, sizeof (*ip) - 1);
7432
7433   ip = (ip4_header_t *) mask;
7434
7435 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7436   foreach_ip4_proto_field;
7437 #undef _
7438
7439   ip->ip_version_and_header_length = 0;
7440
7441   if (version)
7442     ip->ip_version_and_header_length |= 0xF0;
7443
7444   if (hdr_length)
7445     ip->ip_version_and_header_length |= 0x0F;
7446
7447   *maskp = mask;
7448   return 1;
7449 }
7450
7451 #define foreach_ip6_proto_field                 \
7452 _(src_address)                                  \
7453 _(dst_address)                                  \
7454 _(payload_length)                               \
7455 _(hop_limit)                                    \
7456 _(protocol)
7457
7458 uword
7459 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7460 {
7461   u8 **maskp = va_arg (*args, u8 **);
7462   u8 *mask = 0;
7463   u8 found_something = 0;
7464   ip6_header_t *ip;
7465   u32 ip_version_traffic_class_and_flow_label;
7466
7467 #define _(a) u8 a=0;
7468   foreach_ip6_proto_field;
7469 #undef _
7470   u8 version = 0;
7471   u8 traffic_class = 0;
7472   u8 flow_label = 0;
7473
7474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7475     {
7476       if (unformat (input, "version"))
7477         version = 1;
7478       else if (unformat (input, "traffic-class"))
7479         traffic_class = 1;
7480       else if (unformat (input, "flow-label"))
7481         flow_label = 1;
7482       else if (unformat (input, "src"))
7483         src_address = 1;
7484       else if (unformat (input, "dst"))
7485         dst_address = 1;
7486       else if (unformat (input, "proto"))
7487         protocol = 1;
7488
7489 #define _(a) else if (unformat (input, #a)) a=1;
7490       foreach_ip6_proto_field
7491 #undef _
7492         else
7493         break;
7494     }
7495
7496 #define _(a) found_something += a;
7497   foreach_ip6_proto_field;
7498 #undef _
7499
7500   if (found_something == 0)
7501     return 0;
7502
7503   vec_validate (mask, sizeof (*ip) - 1);
7504
7505   ip = (ip6_header_t *) mask;
7506
7507 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7508   foreach_ip6_proto_field;
7509 #undef _
7510
7511   ip_version_traffic_class_and_flow_label = 0;
7512
7513   if (version)
7514     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7515
7516   if (traffic_class)
7517     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7518
7519   if (flow_label)
7520     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7521
7522   ip->ip_version_traffic_class_and_flow_label =
7523     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7524
7525   *maskp = mask;
7526   return 1;
7527 }
7528
7529 uword
7530 unformat_l3_mask (unformat_input_t * input, va_list * args)
7531 {
7532   u8 **maskp = va_arg (*args, u8 **);
7533
7534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7535     {
7536       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7537         return 1;
7538       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7539         return 1;
7540       else
7541         break;
7542     }
7543   return 0;
7544 }
7545
7546 uword
7547 unformat_l2_mask (unformat_input_t * input, va_list * args)
7548 {
7549   u8 **maskp = va_arg (*args, u8 **);
7550   u8 *mask = 0;
7551   u8 src = 0;
7552   u8 dst = 0;
7553   u8 proto = 0;
7554   u8 tag1 = 0;
7555   u8 tag2 = 0;
7556   u8 ignore_tag1 = 0;
7557   u8 ignore_tag2 = 0;
7558   u8 cos1 = 0;
7559   u8 cos2 = 0;
7560   u8 dot1q = 0;
7561   u8 dot1ad = 0;
7562   int len = 14;
7563
7564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7565     {
7566       if (unformat (input, "src"))
7567         src = 1;
7568       else if (unformat (input, "dst"))
7569         dst = 1;
7570       else if (unformat (input, "proto"))
7571         proto = 1;
7572       else if (unformat (input, "tag1"))
7573         tag1 = 1;
7574       else if (unformat (input, "tag2"))
7575         tag2 = 1;
7576       else if (unformat (input, "ignore-tag1"))
7577         ignore_tag1 = 1;
7578       else if (unformat (input, "ignore-tag2"))
7579         ignore_tag2 = 1;
7580       else if (unformat (input, "cos1"))
7581         cos1 = 1;
7582       else if (unformat (input, "cos2"))
7583         cos2 = 1;
7584       else if (unformat (input, "dot1q"))
7585         dot1q = 1;
7586       else if (unformat (input, "dot1ad"))
7587         dot1ad = 1;
7588       else
7589         break;
7590     }
7591   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7592        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7593     return 0;
7594
7595   if (tag1 || ignore_tag1 || cos1 || dot1q)
7596     len = 18;
7597   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7598     len = 22;
7599
7600   vec_validate (mask, len - 1);
7601
7602   if (dst)
7603     memset (mask, 0xff, 6);
7604
7605   if (src)
7606     memset (mask + 6, 0xff, 6);
7607
7608   if (tag2 || dot1ad)
7609     {
7610       /* inner vlan tag */
7611       if (tag2)
7612         {
7613           mask[19] = 0xff;
7614           mask[18] = 0x0f;
7615         }
7616       if (cos2)
7617         mask[18] |= 0xe0;
7618       if (proto)
7619         mask[21] = mask[20] = 0xff;
7620       if (tag1)
7621         {
7622           mask[15] = 0xff;
7623           mask[14] = 0x0f;
7624         }
7625       if (cos1)
7626         mask[14] |= 0xe0;
7627       *maskp = mask;
7628       return 1;
7629     }
7630   if (tag1 | dot1q)
7631     {
7632       if (tag1)
7633         {
7634           mask[15] = 0xff;
7635           mask[14] = 0x0f;
7636         }
7637       if (cos1)
7638         mask[14] |= 0xe0;
7639       if (proto)
7640         mask[16] = mask[17] = 0xff;
7641
7642       *maskp = mask;
7643       return 1;
7644     }
7645   if (cos2)
7646     mask[18] |= 0xe0;
7647   if (cos1)
7648     mask[14] |= 0xe0;
7649   if (proto)
7650     mask[12] = mask[13] = 0xff;
7651
7652   *maskp = mask;
7653   return 1;
7654 }
7655
7656 uword
7657 unformat_classify_mask (unformat_input_t * input, va_list * args)
7658 {
7659   u8 **maskp = va_arg (*args, u8 **);
7660   u32 *skipp = va_arg (*args, u32 *);
7661   u32 *matchp = va_arg (*args, u32 *);
7662   u32 match;
7663   u8 *mask = 0;
7664   u8 *l2 = 0;
7665   u8 *l3 = 0;
7666   int i;
7667
7668   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7671         ;
7672       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7673         ;
7674       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7675         ;
7676       else
7677         break;
7678     }
7679
7680   if (mask || l2 || l3)
7681     {
7682       if (l2 || l3)
7683         {
7684           /* "With a free Ethernet header in every package" */
7685           if (l2 == 0)
7686             vec_validate (l2, 13);
7687           mask = l2;
7688           if (vec_len (l3))
7689             {
7690               vec_append (mask, l3);
7691               vec_free (l3);
7692             }
7693         }
7694
7695       /* Scan forward looking for the first significant mask octet */
7696       for (i = 0; i < vec_len (mask); i++)
7697         if (mask[i])
7698           break;
7699
7700       /* compute (skip, match) params */
7701       *skipp = i / sizeof (u32x4);
7702       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7703
7704       /* Pad mask to an even multiple of the vector size */
7705       while (vec_len (mask) % sizeof (u32x4))
7706         vec_add1 (mask, 0);
7707
7708       match = vec_len (mask) / sizeof (u32x4);
7709
7710       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7711         {
7712           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7713           if (*tmp || *(tmp + 1))
7714             break;
7715           match--;
7716         }
7717       if (match == 0)
7718         clib_warning ("BUG: match 0");
7719
7720       _vec_len (mask) = match * sizeof (u32x4);
7721
7722       *matchp = match;
7723       *maskp = mask;
7724
7725       return 1;
7726     }
7727
7728   return 0;
7729 }
7730
7731 #define foreach_l2_next                         \
7732 _(drop, DROP)                                   \
7733 _(ethernet, ETHERNET_INPUT)                     \
7734 _(ip4, IP4_INPUT)                               \
7735 _(ip6, IP6_INPUT)
7736
7737 uword
7738 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7739 {
7740   u32 *miss_next_indexp = va_arg (*args, u32 *);
7741   u32 next_index = 0;
7742   u32 tmp;
7743
7744 #define _(n,N) \
7745   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7746   foreach_l2_next;
7747 #undef _
7748
7749   if (unformat (input, "%d", &tmp))
7750     {
7751       next_index = tmp;
7752       goto out;
7753     }
7754
7755   return 0;
7756
7757 out:
7758   *miss_next_indexp = next_index;
7759   return 1;
7760 }
7761
7762 #define foreach_ip_next                         \
7763 _(miss, MISS)                                   \
7764 _(drop, DROP)                                   \
7765 _(local, LOCAL)                                 \
7766 _(rewrite, REWRITE)
7767
7768 uword
7769 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7770 {
7771   u32 *miss_next_indexp = va_arg (*args, u32 *);
7772   u32 next_index = 0;
7773   u32 tmp;
7774
7775 #define _(n,N) \
7776   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7777   foreach_ip_next;
7778 #undef _
7779
7780   if (unformat (input, "%d", &tmp))
7781     {
7782       next_index = tmp;
7783       goto out;
7784     }
7785
7786   return 0;
7787
7788 out:
7789   *miss_next_indexp = next_index;
7790   return 1;
7791 }
7792
7793 #define foreach_acl_next                        \
7794 _(deny, DENY)
7795
7796 uword
7797 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7798 {
7799   u32 *miss_next_indexp = va_arg (*args, u32 *);
7800   u32 next_index = 0;
7801   u32 tmp;
7802
7803 #define _(n,N) \
7804   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7805   foreach_acl_next;
7806 #undef _
7807
7808   if (unformat (input, "permit"))
7809     {
7810       next_index = ~0;
7811       goto out;
7812     }
7813   else if (unformat (input, "%d", &tmp))
7814     {
7815       next_index = tmp;
7816       goto out;
7817     }
7818
7819   return 0;
7820
7821 out:
7822   *miss_next_indexp = next_index;
7823   return 1;
7824 }
7825
7826 uword
7827 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7828 {
7829   u32 *r = va_arg (*args, u32 *);
7830
7831   if (unformat (input, "conform-color"))
7832     *r = POLICE_CONFORM;
7833   else if (unformat (input, "exceed-color"))
7834     *r = POLICE_EXCEED;
7835   else
7836     return 0;
7837
7838   return 1;
7839 }
7840
7841 static int
7842 api_classify_add_del_table (vat_main_t * vam)
7843 {
7844   unformat_input_t *i = vam->input;
7845   vl_api_classify_add_del_table_t *mp;
7846
7847   u32 nbuckets = 2;
7848   u32 skip = ~0;
7849   u32 match = ~0;
7850   int is_add = 1;
7851   u32 table_index = ~0;
7852   u32 next_table_index = ~0;
7853   u32 miss_next_index = ~0;
7854   u32 memory_size = 32 << 20;
7855   u8 *mask = 0;
7856   f64 timeout;
7857
7858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7859     {
7860       if (unformat (i, "del"))
7861         is_add = 0;
7862       else if (unformat (i, "buckets %d", &nbuckets))
7863         ;
7864       else if (unformat (i, "memory_size %d", &memory_size))
7865         ;
7866       else if (unformat (i, "skip %d", &skip))
7867         ;
7868       else if (unformat (i, "match %d", &match))
7869         ;
7870       else if (unformat (i, "table %d", &table_index))
7871         ;
7872       else if (unformat (i, "mask %U", unformat_classify_mask,
7873                          &mask, &skip, &match))
7874         ;
7875       else if (unformat (i, "next-table %d", &next_table_index))
7876         ;
7877       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7878                          &miss_next_index))
7879         ;
7880       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7881                          &miss_next_index))
7882         ;
7883       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7884                          &miss_next_index))
7885         ;
7886       else
7887         break;
7888     }
7889
7890   if (is_add && mask == 0)
7891     {
7892       errmsg ("Mask required\n");
7893       return -99;
7894     }
7895
7896   if (is_add && skip == ~0)
7897     {
7898       errmsg ("skip count required\n");
7899       return -99;
7900     }
7901
7902   if (is_add && match == ~0)
7903     {
7904       errmsg ("match count required\n");
7905       return -99;
7906     }
7907
7908   if (!is_add && table_index == ~0)
7909     {
7910       errmsg ("table index required for delete\n");
7911       return -99;
7912     }
7913
7914   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
7915
7916   mp->is_add = is_add;
7917   mp->table_index = ntohl (table_index);
7918   mp->nbuckets = ntohl (nbuckets);
7919   mp->memory_size = ntohl (memory_size);
7920   mp->skip_n_vectors = ntohl (skip);
7921   mp->match_n_vectors = ntohl (match);
7922   mp->next_table_index = ntohl (next_table_index);
7923   mp->miss_next_index = ntohl (miss_next_index);
7924   clib_memcpy (mp->mask, mask, vec_len (mask));
7925
7926   vec_free (mask);
7927
7928   S;
7929   W;
7930   /* NOTREACHED */
7931 }
7932
7933 uword
7934 unformat_ip4_match (unformat_input_t * input, va_list * args)
7935 {
7936   u8 **matchp = va_arg (*args, u8 **);
7937   u8 *match = 0;
7938   ip4_header_t *ip;
7939   int version = 0;
7940   u32 version_val;
7941   int hdr_length = 0;
7942   u32 hdr_length_val;
7943   int src = 0, dst = 0;
7944   ip4_address_t src_val, dst_val;
7945   int proto = 0;
7946   u32 proto_val;
7947   int tos = 0;
7948   u32 tos_val;
7949   int length = 0;
7950   u32 length_val;
7951   int fragment_id = 0;
7952   u32 fragment_id_val;
7953   int ttl = 0;
7954   int ttl_val;
7955   int checksum = 0;
7956   u32 checksum_val;
7957
7958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (input, "version %d", &version_val))
7961         version = 1;
7962       else if (unformat (input, "hdr_length %d", &hdr_length_val))
7963         hdr_length = 1;
7964       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
7965         src = 1;
7966       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
7967         dst = 1;
7968       else if (unformat (input, "proto %d", &proto_val))
7969         proto = 1;
7970       else if (unformat (input, "tos %d", &tos_val))
7971         tos = 1;
7972       else if (unformat (input, "length %d", &length_val))
7973         length = 1;
7974       else if (unformat (input, "fragment_id %d", &fragment_id_val))
7975         fragment_id = 1;
7976       else if (unformat (input, "ttl %d", &ttl_val))
7977         ttl = 1;
7978       else if (unformat (input, "checksum %d", &checksum_val))
7979         checksum = 1;
7980       else
7981         break;
7982     }
7983
7984   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
7985       + ttl + checksum == 0)
7986     return 0;
7987
7988   /*
7989    * Aligned because we use the real comparison functions
7990    */
7991   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
7992
7993   ip = (ip4_header_t *) match;
7994
7995   /* These are realistically matched in practice */
7996   if (src)
7997     ip->src_address.as_u32 = src_val.as_u32;
7998
7999   if (dst)
8000     ip->dst_address.as_u32 = dst_val.as_u32;
8001
8002   if (proto)
8003     ip->protocol = proto_val;
8004
8005
8006   /* These are not, but they're included for completeness */
8007   if (version)
8008     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8009
8010   if (hdr_length)
8011     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8012
8013   if (tos)
8014     ip->tos = tos_val;
8015
8016   if (length)
8017     ip->length = length_val;
8018
8019   if (ttl)
8020     ip->ttl = ttl_val;
8021
8022   if (checksum)
8023     ip->checksum = checksum_val;
8024
8025   *matchp = match;
8026   return 1;
8027 }
8028
8029 uword
8030 unformat_ip6_match (unformat_input_t * input, va_list * args)
8031 {
8032   u8 **matchp = va_arg (*args, u8 **);
8033   u8 *match = 0;
8034   ip6_header_t *ip;
8035   int version = 0;
8036   u32 version_val;
8037   u8 traffic_class = 0;
8038   u32 traffic_class_val = 0;
8039   u8 flow_label = 0;
8040   u8 flow_label_val;
8041   int src = 0, dst = 0;
8042   ip6_address_t src_val, dst_val;
8043   int proto = 0;
8044   u32 proto_val;
8045   int payload_length = 0;
8046   u32 payload_length_val;
8047   int hop_limit = 0;
8048   int hop_limit_val;
8049   u32 ip_version_traffic_class_and_flow_label;
8050
8051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8052     {
8053       if (unformat (input, "version %d", &version_val))
8054         version = 1;
8055       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8056         traffic_class = 1;
8057       else if (unformat (input, "flow_label %d", &flow_label_val))
8058         flow_label = 1;
8059       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8060         src = 1;
8061       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8062         dst = 1;
8063       else if (unformat (input, "proto %d", &proto_val))
8064         proto = 1;
8065       else if (unformat (input, "payload_length %d", &payload_length_val))
8066         payload_length = 1;
8067       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8068         hop_limit = 1;
8069       else
8070         break;
8071     }
8072
8073   if (version + traffic_class + flow_label + src + dst + proto +
8074       payload_length + hop_limit == 0)
8075     return 0;
8076
8077   /*
8078    * Aligned because we use the real comparison functions
8079    */
8080   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8081
8082   ip = (ip6_header_t *) match;
8083
8084   if (src)
8085     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8086
8087   if (dst)
8088     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8089
8090   if (proto)
8091     ip->protocol = proto_val;
8092
8093   ip_version_traffic_class_and_flow_label = 0;
8094
8095   if (version)
8096     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8097
8098   if (traffic_class)
8099     ip_version_traffic_class_and_flow_label |=
8100       (traffic_class_val & 0xFF) << 20;
8101
8102   if (flow_label)
8103     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8104
8105   ip->ip_version_traffic_class_and_flow_label =
8106     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8107
8108   if (payload_length)
8109     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8110
8111   if (hop_limit)
8112     ip->hop_limit = hop_limit_val;
8113
8114   *matchp = match;
8115   return 1;
8116 }
8117
8118 uword
8119 unformat_l3_match (unformat_input_t * input, va_list * args)
8120 {
8121   u8 **matchp = va_arg (*args, u8 **);
8122
8123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8124     {
8125       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8126         return 1;
8127       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8128         return 1;
8129       else
8130         break;
8131     }
8132   return 0;
8133 }
8134
8135 uword
8136 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8137 {
8138   u8 *tagp = va_arg (*args, u8 *);
8139   u32 tag;
8140
8141   if (unformat (input, "%d", &tag))
8142     {
8143       tagp[0] = (tag >> 8) & 0x0F;
8144       tagp[1] = tag & 0xFF;
8145       return 1;
8146     }
8147
8148   return 0;
8149 }
8150
8151 uword
8152 unformat_l2_match (unformat_input_t * input, va_list * args)
8153 {
8154   u8 **matchp = va_arg (*args, u8 **);
8155   u8 *match = 0;
8156   u8 src = 0;
8157   u8 src_val[6];
8158   u8 dst = 0;
8159   u8 dst_val[6];
8160   u8 proto = 0;
8161   u16 proto_val;
8162   u8 tag1 = 0;
8163   u8 tag1_val[2];
8164   u8 tag2 = 0;
8165   u8 tag2_val[2];
8166   int len = 14;
8167   u8 ignore_tag1 = 0;
8168   u8 ignore_tag2 = 0;
8169   u8 cos1 = 0;
8170   u8 cos2 = 0;
8171   u32 cos1_val = 0;
8172   u32 cos2_val = 0;
8173
8174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8175     {
8176       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8177         src = 1;
8178       else
8179         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8180         dst = 1;
8181       else if (unformat (input, "proto %U",
8182                          unformat_ethernet_type_host_byte_order, &proto_val))
8183         proto = 1;
8184       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8185         tag1 = 1;
8186       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8187         tag2 = 1;
8188       else if (unformat (input, "ignore-tag1"))
8189         ignore_tag1 = 1;
8190       else if (unformat (input, "ignore-tag2"))
8191         ignore_tag2 = 1;
8192       else if (unformat (input, "cos1 %d", &cos1_val))
8193         cos1 = 1;
8194       else if (unformat (input, "cos2 %d", &cos2_val))
8195         cos2 = 1;
8196       else
8197         break;
8198     }
8199   if ((src + dst + proto + tag1 + tag2 +
8200        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8201     return 0;
8202
8203   if (tag1 || ignore_tag1 || cos1)
8204     len = 18;
8205   if (tag2 || ignore_tag2 || cos2)
8206     len = 22;
8207
8208   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8209
8210   if (dst)
8211     clib_memcpy (match, dst_val, 6);
8212
8213   if (src)
8214     clib_memcpy (match + 6, src_val, 6);
8215
8216   if (tag2)
8217     {
8218       /* inner vlan tag */
8219       match[19] = tag2_val[1];
8220       match[18] = tag2_val[0];
8221       if (cos2)
8222         match[18] |= (cos2_val & 0x7) << 5;
8223       if (proto)
8224         {
8225           match[21] = proto_val & 0xff;
8226           match[20] = proto_val >> 8;
8227         }
8228       if (tag1)
8229         {
8230           match[15] = tag1_val[1];
8231           match[14] = tag1_val[0];
8232         }
8233       if (cos1)
8234         match[14] |= (cos1_val & 0x7) << 5;
8235       *matchp = match;
8236       return 1;
8237     }
8238   if (tag1)
8239     {
8240       match[15] = tag1_val[1];
8241       match[14] = tag1_val[0];
8242       if (proto)
8243         {
8244           match[17] = proto_val & 0xff;
8245           match[16] = proto_val >> 8;
8246         }
8247       if (cos1)
8248         match[14] |= (cos1_val & 0x7) << 5;
8249
8250       *matchp = match;
8251       return 1;
8252     }
8253   if (cos2)
8254     match[18] |= (cos2_val & 0x7) << 5;
8255   if (cos1)
8256     match[14] |= (cos1_val & 0x7) << 5;
8257   if (proto)
8258     {
8259       match[13] = proto_val & 0xff;
8260       match[12] = proto_val >> 8;
8261     }
8262
8263   *matchp = match;
8264   return 1;
8265 }
8266
8267
8268 uword
8269 unformat_classify_match (unformat_input_t * input, va_list * args)
8270 {
8271   u8 **matchp = va_arg (*args, u8 **);
8272   u32 skip_n_vectors = va_arg (*args, u32);
8273   u32 match_n_vectors = va_arg (*args, u32);
8274
8275   u8 *match = 0;
8276   u8 *l2 = 0;
8277   u8 *l3 = 0;
8278
8279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8280     {
8281       if (unformat (input, "hex %U", unformat_hex_string, &match))
8282         ;
8283       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8284         ;
8285       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8286         ;
8287       else
8288         break;
8289     }
8290
8291   if (match || l2 || l3)
8292     {
8293       if (l2 || l3)
8294         {
8295           /* "Win a free Ethernet header in every packet" */
8296           if (l2 == 0)
8297             vec_validate_aligned (l2, 13, sizeof (u32x4));
8298           match = l2;
8299           if (vec_len (l3))
8300             {
8301               vec_append_aligned (match, l3, sizeof (u32x4));
8302               vec_free (l3);
8303             }
8304         }
8305
8306       /* Make sure the vector is big enough even if key is all 0's */
8307       vec_validate_aligned
8308         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8309          sizeof (u32x4));
8310
8311       /* Set size, include skipped vectors */
8312       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8313
8314       *matchp = match;
8315
8316       return 1;
8317     }
8318
8319   return 0;
8320 }
8321
8322 static int
8323 api_classify_add_del_session (vat_main_t * vam)
8324 {
8325   unformat_input_t *i = vam->input;
8326   vl_api_classify_add_del_session_t *mp;
8327   int is_add = 1;
8328   u32 table_index = ~0;
8329   u32 hit_next_index = ~0;
8330   u32 opaque_index = ~0;
8331   u8 *match = 0;
8332   i32 advance = 0;
8333   f64 timeout;
8334   u32 skip_n_vectors = 0;
8335   u32 match_n_vectors = 0;
8336
8337   /*
8338    * Warning: you have to supply skip_n and match_n
8339    * because the API client cant simply look at the classify
8340    * table object.
8341    */
8342
8343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8344     {
8345       if (unformat (i, "del"))
8346         is_add = 0;
8347       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8348                          &hit_next_index))
8349         ;
8350       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8351                          &hit_next_index))
8352         ;
8353       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8354                          &hit_next_index))
8355         ;
8356       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8357         ;
8358       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8359         ;
8360       else if (unformat (i, "opaque-index %d", &opaque_index))
8361         ;
8362       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8363         ;
8364       else if (unformat (i, "match_n %d", &match_n_vectors))
8365         ;
8366       else if (unformat (i, "match %U", unformat_classify_match,
8367                          &match, skip_n_vectors, match_n_vectors))
8368         ;
8369       else if (unformat (i, "advance %d", &advance))
8370         ;
8371       else if (unformat (i, "table-index %d", &table_index))
8372         ;
8373       else
8374         break;
8375     }
8376
8377   if (table_index == ~0)
8378     {
8379       errmsg ("Table index required\n");
8380       return -99;
8381     }
8382
8383   if (is_add && match == 0)
8384     {
8385       errmsg ("Match value required\n");
8386       return -99;
8387     }
8388
8389   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8390
8391   mp->is_add = is_add;
8392   mp->table_index = ntohl (table_index);
8393   mp->hit_next_index = ntohl (hit_next_index);
8394   mp->opaque_index = ntohl (opaque_index);
8395   mp->advance = ntohl (advance);
8396   clib_memcpy (mp->match, match, vec_len (match));
8397   vec_free (match);
8398
8399   S;
8400   W;
8401   /* NOTREACHED */
8402 }
8403
8404 static int
8405 api_classify_set_interface_ip_table (vat_main_t * vam)
8406 {
8407   unformat_input_t *i = vam->input;
8408   vl_api_classify_set_interface_ip_table_t *mp;
8409   f64 timeout;
8410   u32 sw_if_index;
8411   int sw_if_index_set;
8412   u32 table_index = ~0;
8413   u8 is_ipv6 = 0;
8414
8415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8416     {
8417       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8418         sw_if_index_set = 1;
8419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8420         sw_if_index_set = 1;
8421       else if (unformat (i, "table %d", &table_index))
8422         ;
8423       else
8424         {
8425           clib_warning ("parse error '%U'", format_unformat_error, i);
8426           return -99;
8427         }
8428     }
8429
8430   if (sw_if_index_set == 0)
8431     {
8432       errmsg ("missing interface name or sw_if_index\n");
8433       return -99;
8434     }
8435
8436
8437   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8438
8439   mp->sw_if_index = ntohl (sw_if_index);
8440   mp->table_index = ntohl (table_index);
8441   mp->is_ipv6 = is_ipv6;
8442
8443   S;
8444   W;
8445   /* NOTREACHED */
8446   return 0;
8447 }
8448
8449 static int
8450 api_classify_set_interface_l2_tables (vat_main_t * vam)
8451 {
8452   unformat_input_t *i = vam->input;
8453   vl_api_classify_set_interface_l2_tables_t *mp;
8454   f64 timeout;
8455   u32 sw_if_index;
8456   int sw_if_index_set;
8457   u32 ip4_table_index = ~0;
8458   u32 ip6_table_index = ~0;
8459   u32 other_table_index = ~0;
8460
8461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8462     {
8463       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8464         sw_if_index_set = 1;
8465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8466         sw_if_index_set = 1;
8467       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8468         ;
8469       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8470         ;
8471       else if (unformat (i, "other-table %d", &other_table_index))
8472         ;
8473       else
8474         {
8475           clib_warning ("parse error '%U'", format_unformat_error, i);
8476           return -99;
8477         }
8478     }
8479
8480   if (sw_if_index_set == 0)
8481     {
8482       errmsg ("missing interface name or sw_if_index\n");
8483       return -99;
8484     }
8485
8486
8487   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8488
8489   mp->sw_if_index = ntohl (sw_if_index);
8490   mp->ip4_table_index = ntohl (ip4_table_index);
8491   mp->ip6_table_index = ntohl (ip6_table_index);
8492   mp->other_table_index = ntohl (other_table_index);
8493
8494
8495   S;
8496   W;
8497   /* NOTREACHED */
8498   return 0;
8499 }
8500
8501 static int
8502 api_ipfix_enable (vat_main_t * vam)
8503 {
8504   unformat_input_t *i = vam->input;
8505   vl_api_ipfix_enable_t *mp;
8506   ip4_address_t collector_address;
8507   u8 collector_address_set = 0;
8508   u32 collector_port = ~0;
8509   ip4_address_t src_address;
8510   u8 src_address_set = 0;
8511   u32 vrf_id = ~0;
8512   u32 path_mtu = ~0;
8513   u32 template_interval = ~0;
8514   f64 timeout;
8515
8516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8517     {
8518       if (unformat (i, "collector_address %U", unformat_ip4_address,
8519                     &collector_address))
8520         collector_address_set = 1;
8521       else if (unformat (i, "collector_port %d", &collector_port))
8522         ;
8523       else if (unformat (i, "src_address %U", unformat_ip4_address,
8524                          &src_address))
8525         src_address_set = 1;
8526       else if (unformat (i, "vrf_id %d", &vrf_id))
8527         ;
8528       else if (unformat (i, "path_mtu %d", &path_mtu))
8529         ;
8530       else if (unformat (i, "template_interval %d", &template_interval))
8531         ;
8532       else
8533         break;
8534     }
8535
8536   if (collector_address_set == 0)
8537     {
8538       errmsg ("collector_address required\n");
8539       return -99;
8540     }
8541
8542   if (src_address_set == 0)
8543     {
8544       errmsg ("src_address required\n");
8545       return -99;
8546     }
8547
8548   M (IPFIX_ENABLE, ipfix_enable);
8549
8550   memcpy (mp->collector_address, collector_address.data,
8551           sizeof (collector_address.data));
8552   mp->collector_port = htons ((u16) collector_port);
8553   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8554   mp->vrf_id = htonl (vrf_id);
8555   mp->path_mtu = htonl (path_mtu);
8556   mp->template_interval = htonl (template_interval);
8557
8558   S;
8559   W;
8560   /* NOTREACHED */
8561 }
8562
8563 static int
8564 api_get_node_index (vat_main_t * vam)
8565 {
8566   unformat_input_t *i = vam->input;
8567   vl_api_get_node_index_t *mp;
8568   f64 timeout;
8569   u8 *name = 0;
8570
8571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8572     {
8573       if (unformat (i, "node %s", &name))
8574         ;
8575       else
8576         break;
8577     }
8578   if (name == 0)
8579     {
8580       errmsg ("node name required\n");
8581       return -99;
8582     }
8583   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8584     {
8585       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8586       return -99;
8587     }
8588
8589   M (GET_NODE_INDEX, get_node_index);
8590   clib_memcpy (mp->node_name, name, vec_len (name));
8591   vec_free (name);
8592
8593   S;
8594   W;
8595   /* NOTREACHED */
8596   return 0;
8597 }
8598
8599 static int
8600 api_get_next_index (vat_main_t * vam)
8601 {
8602   unformat_input_t *i = vam->input;
8603   vl_api_get_next_index_t *mp;
8604   f64 timeout;
8605   u8 *node_name = 0, *next_node_name = 0;
8606
8607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8608     {
8609       if (unformat (i, "node-name %s", &node_name))
8610         ;
8611       else if (unformat (i, "next-node-name %s", &next_node_name))
8612         break;
8613     }
8614
8615   if (node_name == 0)
8616     {
8617       errmsg ("node name required\n");
8618       return -99;
8619     }
8620   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8621     {
8622       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8623       return -99;
8624     }
8625
8626   if (next_node_name == 0)
8627     {
8628       errmsg ("next node name required\n");
8629       return -99;
8630     }
8631   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8632     {
8633       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8634       return -99;
8635     }
8636
8637   M (GET_NEXT_INDEX, get_next_index);
8638   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8639   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8640   vec_free (node_name);
8641   vec_free (next_node_name);
8642
8643   S;
8644   W;
8645   /* NOTREACHED */
8646   return 0;
8647 }
8648
8649 static int
8650 api_add_node_next (vat_main_t * vam)
8651 {
8652   unformat_input_t *i = vam->input;
8653   vl_api_add_node_next_t *mp;
8654   f64 timeout;
8655   u8 *name = 0;
8656   u8 *next = 0;
8657
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "node %s", &name))
8661         ;
8662       else if (unformat (i, "next %s", &next))
8663         ;
8664       else
8665         break;
8666     }
8667   if (name == 0)
8668     {
8669       errmsg ("node name required\n");
8670       return -99;
8671     }
8672   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8673     {
8674       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8675       return -99;
8676     }
8677   if (next == 0)
8678     {
8679       errmsg ("next node required\n");
8680       return -99;
8681     }
8682   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8683     {
8684       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8685       return -99;
8686     }
8687
8688   M (ADD_NODE_NEXT, add_node_next);
8689   clib_memcpy (mp->node_name, name, vec_len (name));
8690   clib_memcpy (mp->next_name, next, vec_len (next));
8691   vec_free (name);
8692   vec_free (next);
8693
8694   S;
8695   W;
8696   /* NOTREACHED */
8697   return 0;
8698 }
8699
8700 static int
8701 api_l2tpv3_create_tunnel (vat_main_t * vam)
8702 {
8703   unformat_input_t *i = vam->input;
8704   ip6_address_t client_address, our_address;
8705   int client_address_set = 0;
8706   int our_address_set = 0;
8707   u32 local_session_id = 0;
8708   u32 remote_session_id = 0;
8709   u64 local_cookie = 0;
8710   u64 remote_cookie = 0;
8711   u8 l2_sublayer_present = 0;
8712   vl_api_l2tpv3_create_tunnel_t *mp;
8713   f64 timeout;
8714
8715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8716     {
8717       if (unformat (i, "client_address %U", unformat_ip6_address,
8718                     &client_address))
8719         client_address_set = 1;
8720       else if (unformat (i, "our_address %U", unformat_ip6_address,
8721                          &our_address))
8722         our_address_set = 1;
8723       else if (unformat (i, "local_session_id %d", &local_session_id))
8724         ;
8725       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8726         ;
8727       else if (unformat (i, "local_cookie %lld", &local_cookie))
8728         ;
8729       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8730         ;
8731       else if (unformat (i, "l2-sublayer-present"))
8732         l2_sublayer_present = 1;
8733       else
8734         break;
8735     }
8736
8737   if (client_address_set == 0)
8738     {
8739       errmsg ("client_address required\n");
8740       return -99;
8741     }
8742
8743   if (our_address_set == 0)
8744     {
8745       errmsg ("our_address required\n");
8746       return -99;
8747     }
8748
8749   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8750
8751   clib_memcpy (mp->client_address, client_address.as_u8,
8752                sizeof (mp->client_address));
8753
8754   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8755
8756   mp->local_session_id = ntohl (local_session_id);
8757   mp->remote_session_id = ntohl (remote_session_id);
8758   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8759   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8760   mp->l2_sublayer_present = l2_sublayer_present;
8761   mp->is_ipv6 = 1;
8762
8763   S;
8764   W;
8765   /* NOTREACHED */
8766   return 0;
8767 }
8768
8769 static int
8770 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8771 {
8772   unformat_input_t *i = vam->input;
8773   u32 sw_if_index;
8774   u8 sw_if_index_set = 0;
8775   u64 new_local_cookie = 0;
8776   u64 new_remote_cookie = 0;
8777   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8778   f64 timeout;
8779
8780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781     {
8782       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8783         sw_if_index_set = 1;
8784       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8785         sw_if_index_set = 1;
8786       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8787         ;
8788       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8789         ;
8790       else
8791         break;
8792     }
8793
8794   if (sw_if_index_set == 0)
8795     {
8796       errmsg ("missing interface name or sw_if_index\n");
8797       return -99;
8798     }
8799
8800   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8801
8802   mp->sw_if_index = ntohl (sw_if_index);
8803   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8804   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8805
8806   S;
8807   W;
8808   /* NOTREACHED */
8809   return 0;
8810 }
8811
8812 static int
8813 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8814 {
8815   unformat_input_t *i = vam->input;
8816   vl_api_l2tpv3_interface_enable_disable_t *mp;
8817   f64 timeout;
8818   u32 sw_if_index;
8819   u8 sw_if_index_set = 0;
8820   u8 enable_disable = 1;
8821
8822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8823     {
8824       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8825         sw_if_index_set = 1;
8826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8827         sw_if_index_set = 1;
8828       else if (unformat (i, "enable"))
8829         enable_disable = 1;
8830       else if (unformat (i, "disable"))
8831         enable_disable = 0;
8832       else
8833         break;
8834     }
8835
8836   if (sw_if_index_set == 0)
8837     {
8838       errmsg ("missing interface name or sw_if_index\n");
8839       return -99;
8840     }
8841
8842   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8843
8844   mp->sw_if_index = ntohl (sw_if_index);
8845   mp->enable_disable = enable_disable;
8846
8847   S;
8848   W;
8849   /* NOTREACHED */
8850   return 0;
8851 }
8852
8853 static int
8854 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8855 {
8856   unformat_input_t *i = vam->input;
8857   vl_api_l2tpv3_set_lookup_key_t *mp;
8858   f64 timeout;
8859   u8 key = ~0;
8860
8861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (i, "lookup_v6_src"))
8864         key = L2T_LOOKUP_SRC_ADDRESS;
8865       else if (unformat (i, "lookup_v6_dst"))
8866         key = L2T_LOOKUP_DST_ADDRESS;
8867       else if (unformat (i, "lookup_session_id"))
8868         key = L2T_LOOKUP_SESSION_ID;
8869       else
8870         break;
8871     }
8872
8873   if (key == (u8) ~ 0)
8874     {
8875       errmsg ("l2tp session lookup key unset\n");
8876       return -99;
8877     }
8878
8879   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8880
8881   mp->key = key;
8882
8883   S;
8884   W;
8885   /* NOTREACHED */
8886   return 0;
8887 }
8888
8889 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8890   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8891 {
8892   vat_main_t *vam = &vat_main;
8893
8894   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8895            format_ip6_address, mp->our_address,
8896            format_ip6_address, mp->client_address,
8897            clib_net_to_host_u32 (mp->sw_if_index));
8898
8899   fformat (vam->ofp,
8900            "   local cookies %016llx %016llx remote cookie %016llx\n",
8901            clib_net_to_host_u64 (mp->local_cookie[0]),
8902            clib_net_to_host_u64 (mp->local_cookie[1]),
8903            clib_net_to_host_u64 (mp->remote_cookie));
8904
8905   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
8906            clib_net_to_host_u32 (mp->local_session_id),
8907            clib_net_to_host_u32 (mp->remote_session_id));
8908
8909   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
8910            mp->l2_sublayer_present ? "preset" : "absent");
8911
8912 }
8913
8914 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8915   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8916 {
8917   vat_main_t *vam = &vat_main;
8918   vat_json_node_t *node = NULL;
8919   struct in6_addr addr;
8920
8921   if (VAT_JSON_ARRAY != vam->json_tree.type)
8922     {
8923       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8924       vat_json_init_array (&vam->json_tree);
8925     }
8926   node = vat_json_array_add (&vam->json_tree);
8927
8928   vat_json_init_object (node);
8929
8930   clib_memcpy (&addr, mp->our_address, sizeof (addr));
8931   vat_json_object_add_ip6 (node, "our_address", addr);
8932   clib_memcpy (&addr, mp->client_address, sizeof (addr));
8933   vat_json_object_add_ip6 (node, "client_address", addr);
8934
8935   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
8936   vat_json_init_array (lc);
8937   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
8938   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
8939   vat_json_object_add_uint (node, "remote_cookie",
8940                             clib_net_to_host_u64 (mp->remote_cookie));
8941
8942   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
8943   vat_json_object_add_uint (node, "local_session_id",
8944                             clib_net_to_host_u32 (mp->local_session_id));
8945   vat_json_object_add_uint (node, "remote_session_id",
8946                             clib_net_to_host_u32 (mp->remote_session_id));
8947   vat_json_object_add_string_copy (node, "l2_sublayer",
8948                                    mp->l2_sublayer_present ? (u8 *) "present"
8949                                    : (u8 *) "absent");
8950 }
8951
8952 static int
8953 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
8954 {
8955   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
8956   f64 timeout;
8957
8958   /* Get list of l2tpv3-tunnel interfaces */
8959   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
8960   S;
8961
8962   /* Use a control ping for synchronization */
8963   {
8964     vl_api_control_ping_t *mp;
8965     M (CONTROL_PING, control_ping);
8966     S;
8967   }
8968   W;
8969 }
8970
8971
8972 static void vl_api_sw_interface_tap_details_t_handler
8973   (vl_api_sw_interface_tap_details_t * mp)
8974 {
8975   vat_main_t *vam = &vat_main;
8976
8977   fformat (vam->ofp, "%-16s %d\n",
8978            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
8979 }
8980
8981 static void vl_api_sw_interface_tap_details_t_handler_json
8982   (vl_api_sw_interface_tap_details_t * mp)
8983 {
8984   vat_main_t *vam = &vat_main;
8985   vat_json_node_t *node = NULL;
8986
8987   if (VAT_JSON_ARRAY != vam->json_tree.type)
8988     {
8989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8990       vat_json_init_array (&vam->json_tree);
8991     }
8992   node = vat_json_array_add (&vam->json_tree);
8993
8994   vat_json_init_object (node);
8995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8996   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
8997 }
8998
8999 static int
9000 api_sw_interface_tap_dump (vat_main_t * vam)
9001 {
9002   vl_api_sw_interface_tap_dump_t *mp;
9003   f64 timeout;
9004
9005   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9006   /* Get list of tap interfaces */
9007   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9008   S;
9009
9010   /* Use a control ping for synchronization */
9011   {
9012     vl_api_control_ping_t *mp;
9013     M (CONTROL_PING, control_ping);
9014     S;
9015   }
9016   W;
9017 }
9018
9019 static uword unformat_vxlan_decap_next
9020   (unformat_input_t * input, va_list * args)
9021 {
9022   u32 *result = va_arg (*args, u32 *);
9023   u32 tmp;
9024
9025   if (unformat (input, "drop"))
9026     *result = VXLAN_INPUT_NEXT_DROP;
9027   else if (unformat (input, "ip4"))
9028     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9029   else if (unformat (input, "ip6"))
9030     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9031   else if (unformat (input, "l2"))
9032     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9033   else if (unformat (input, "%d", &tmp))
9034     *result = tmp;
9035   else
9036     return 0;
9037   return 1;
9038 }
9039
9040 static int
9041 api_vxlan_add_del_tunnel (vat_main_t * vam)
9042 {
9043   unformat_input_t *line_input = vam->input;
9044   vl_api_vxlan_add_del_tunnel_t *mp;
9045   f64 timeout;
9046   ip4_address_t src4, dst4;
9047   ip6_address_t src6, dst6;
9048   u8 is_add = 1;
9049   u8 ipv4_set = 0, ipv6_set = 0;
9050   u8 src_set = 0;
9051   u8 dst_set = 0;
9052   u32 encap_vrf_id = 0;
9053   u32 decap_next_index = ~0;
9054   u32 vni = 0;
9055
9056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9057     {
9058       if (unformat (line_input, "del"))
9059         is_add = 0;
9060       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9061         {
9062           ipv4_set = 1;
9063           src_set = 1;
9064         }
9065       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9066         {
9067           ipv4_set = 1;
9068           dst_set = 1;
9069         }
9070       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9071         {
9072           ipv6_set = 1;
9073           src_set = 1;
9074         }
9075       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9076         {
9077           ipv6_set = 1;
9078           dst_set = 1;
9079         }
9080       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9081         ;
9082       else if (unformat (line_input, "decap-next %U",
9083                          unformat_vxlan_decap_next, &decap_next_index))
9084         ;
9085       else if (unformat (line_input, "vni %d", &vni))
9086         ;
9087       else
9088         {
9089           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9090           return -99;
9091         }
9092     }
9093
9094   if (src_set == 0)
9095     {
9096       errmsg ("tunnel src address not specified\n");
9097       return -99;
9098     }
9099   if (dst_set == 0)
9100     {
9101       errmsg ("tunnel dst address not specified\n");
9102       return -99;
9103     }
9104
9105   if (ipv4_set && ipv6_set)
9106     {
9107       errmsg ("both IPv4 and IPv6 addresses specified");
9108       return -99;
9109     }
9110
9111   if ((vni == 0) || (vni >> 24))
9112     {
9113       errmsg ("vni not specified or out of range\n");
9114       return -99;
9115     }
9116
9117   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9118
9119   if (ipv6_set)
9120     {
9121       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9122       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9123     }
9124   else
9125     {
9126       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9127       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9128     }
9129   mp->encap_vrf_id = ntohl (encap_vrf_id);
9130   mp->decap_next_index = ntohl (decap_next_index);
9131   mp->vni = ntohl (vni);
9132   mp->is_add = is_add;
9133   mp->is_ipv6 = ipv6_set;
9134
9135   S;
9136   W;
9137   /* NOTREACHED */
9138   return 0;
9139 }
9140
9141 static void vl_api_vxlan_tunnel_details_t_handler
9142   (vl_api_vxlan_tunnel_details_t * mp)
9143 {
9144   vat_main_t *vam = &vat_main;
9145
9146   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9147            ntohl (mp->sw_if_index),
9148            format_ip46_address, &(mp->src_address[0]),
9149            IP46_TYPE_ANY,
9150            format_ip46_address, &(mp->dst_address[0]),
9151            IP46_TYPE_ANY,
9152            ntohl (mp->encap_vrf_id),
9153            ntohl (mp->decap_next_index), ntohl (mp->vni));
9154 }
9155
9156 static void vl_api_vxlan_tunnel_details_t_handler_json
9157   (vl_api_vxlan_tunnel_details_t * mp)
9158 {
9159   vat_main_t *vam = &vat_main;
9160   vat_json_node_t *node = NULL;
9161   struct in_addr ip4;
9162   struct in6_addr ip6;
9163
9164   if (VAT_JSON_ARRAY != vam->json_tree.type)
9165     {
9166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9167       vat_json_init_array (&vam->json_tree);
9168     }
9169   node = vat_json_array_add (&vam->json_tree);
9170
9171   vat_json_init_object (node);
9172   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9173   if (mp->is_ipv6)
9174     {
9175       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9176       vat_json_object_add_ip6 (node, "src_address", ip6);
9177       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9178       vat_json_object_add_ip6 (node, "dst_address", ip6);
9179     }
9180   else
9181     {
9182       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9183       vat_json_object_add_ip4 (node, "src_address", ip4);
9184       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9185       vat_json_object_add_ip4 (node, "dst_address", ip4);
9186     }
9187   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9188   vat_json_object_add_uint (node, "decap_next_index",
9189                             ntohl (mp->decap_next_index));
9190   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9191   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9192 }
9193
9194 static int
9195 api_vxlan_tunnel_dump (vat_main_t * vam)
9196 {
9197   unformat_input_t *i = vam->input;
9198   vl_api_vxlan_tunnel_dump_t *mp;
9199   f64 timeout;
9200   u32 sw_if_index;
9201   u8 sw_if_index_set = 0;
9202
9203   /* Parse args required to build the message */
9204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9205     {
9206       if (unformat (i, "sw_if_index %d", &sw_if_index))
9207         sw_if_index_set = 1;
9208       else
9209         break;
9210     }
9211
9212   if (sw_if_index_set == 0)
9213     {
9214       sw_if_index = ~0;
9215     }
9216
9217   if (!vam->json_output)
9218     {
9219       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9220                "sw_if_index", "src_address", "dst_address",
9221                "encap_vrf_id", "decap_next_index", "vni");
9222     }
9223
9224   /* Get list of vxlan-tunnel interfaces */
9225   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9226
9227   mp->sw_if_index = htonl (sw_if_index);
9228
9229   S;
9230
9231   /* Use a control ping for synchronization */
9232   {
9233     vl_api_control_ping_t *mp;
9234     M (CONTROL_PING, control_ping);
9235     S;
9236   }
9237   W;
9238 }
9239
9240 static int
9241 api_gre_add_del_tunnel (vat_main_t * vam)
9242 {
9243   unformat_input_t *line_input = vam->input;
9244   vl_api_gre_add_del_tunnel_t *mp;
9245   f64 timeout;
9246   ip4_address_t src4, dst4;
9247   u8 is_add = 1;
9248   u8 src_set = 0;
9249   u8 dst_set = 0;
9250   u32 outer_fib_id = 0;
9251
9252   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9253     {
9254       if (unformat (line_input, "del"))
9255         is_add = 0;
9256       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9257         src_set = 1;
9258       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9259         dst_set = 1;
9260       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9261         ;
9262       else
9263         {
9264           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9265           return -99;
9266         }
9267     }
9268
9269   if (src_set == 0)
9270     {
9271       errmsg ("tunnel src address not specified\n");
9272       return -99;
9273     }
9274   if (dst_set == 0)
9275     {
9276       errmsg ("tunnel dst address not specified\n");
9277       return -99;
9278     }
9279
9280
9281   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9282
9283   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9284   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9285   mp->outer_fib_id = ntohl (outer_fib_id);
9286   mp->is_add = is_add;
9287
9288   S;
9289   W;
9290   /* NOTREACHED */
9291   return 0;
9292 }
9293
9294 static void vl_api_gre_tunnel_details_t_handler
9295   (vl_api_gre_tunnel_details_t * mp)
9296 {
9297   vat_main_t *vam = &vat_main;
9298
9299   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9300            ntohl (mp->sw_if_index),
9301            format_ip4_address, &mp->src_address,
9302            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9303 }
9304
9305 static void vl_api_gre_tunnel_details_t_handler_json
9306   (vl_api_gre_tunnel_details_t * mp)
9307 {
9308   vat_main_t *vam = &vat_main;
9309   vat_json_node_t *node = NULL;
9310   struct in_addr ip4;
9311
9312   if (VAT_JSON_ARRAY != vam->json_tree.type)
9313     {
9314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9315       vat_json_init_array (&vam->json_tree);
9316     }
9317   node = vat_json_array_add (&vam->json_tree);
9318
9319   vat_json_init_object (node);
9320   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9321   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9322   vat_json_object_add_ip4 (node, "src_address", ip4);
9323   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9324   vat_json_object_add_ip4 (node, "dst_address", ip4);
9325   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9326 }
9327
9328 static int
9329 api_gre_tunnel_dump (vat_main_t * vam)
9330 {
9331   unformat_input_t *i = vam->input;
9332   vl_api_gre_tunnel_dump_t *mp;
9333   f64 timeout;
9334   u32 sw_if_index;
9335   u8 sw_if_index_set = 0;
9336
9337   /* Parse args required to build the message */
9338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9339     {
9340       if (unformat (i, "sw_if_index %d", &sw_if_index))
9341         sw_if_index_set = 1;
9342       else
9343         break;
9344     }
9345
9346   if (sw_if_index_set == 0)
9347     {
9348       sw_if_index = ~0;
9349     }
9350
9351   if (!vam->json_output)
9352     {
9353       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9354                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9355     }
9356
9357   /* Get list of gre-tunnel interfaces */
9358   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9359
9360   mp->sw_if_index = htonl (sw_if_index);
9361
9362   S;
9363
9364   /* Use a control ping for synchronization */
9365   {
9366     vl_api_control_ping_t *mp;
9367     M (CONTROL_PING, control_ping);
9368     S;
9369   }
9370   W;
9371 }
9372
9373 static int
9374 api_l2_fib_clear_table (vat_main_t * vam)
9375 {
9376 //  unformat_input_t * i = vam->input;
9377   vl_api_l2_fib_clear_table_t *mp;
9378   f64 timeout;
9379
9380   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9381
9382   S;
9383   W;
9384   /* NOTREACHED */
9385   return 0;
9386 }
9387
9388 static int
9389 api_l2_interface_efp_filter (vat_main_t * vam)
9390 {
9391   unformat_input_t *i = vam->input;
9392   vl_api_l2_interface_efp_filter_t *mp;
9393   f64 timeout;
9394   u32 sw_if_index;
9395   u8 enable = 1;
9396   u8 sw_if_index_set = 0;
9397
9398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9399     {
9400       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9401         sw_if_index_set = 1;
9402       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9403         sw_if_index_set = 1;
9404       else if (unformat (i, "enable"))
9405         enable = 1;
9406       else if (unformat (i, "disable"))
9407         enable = 0;
9408       else
9409         {
9410           clib_warning ("parse error '%U'", format_unformat_error, i);
9411           return -99;
9412         }
9413     }
9414
9415   if (sw_if_index_set == 0)
9416     {
9417       errmsg ("missing sw_if_index\n");
9418       return -99;
9419     }
9420
9421   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9422
9423   mp->sw_if_index = ntohl (sw_if_index);
9424   mp->enable_disable = enable;
9425
9426   S;
9427   W;
9428   /* NOTREACHED */
9429   return 0;
9430 }
9431
9432 #define foreach_vtr_op                          \
9433 _("disable",  L2_VTR_DISABLED)                  \
9434 _("push-1",  L2_VTR_PUSH_1)                     \
9435 _("push-2",  L2_VTR_PUSH_2)                     \
9436 _("pop-1",  L2_VTR_POP_1)                       \
9437 _("pop-2",  L2_VTR_POP_2)                       \
9438 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9439 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9440 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9441 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9442
9443 static int
9444 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9445 {
9446   unformat_input_t *i = vam->input;
9447   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9448   f64 timeout;
9449   u32 sw_if_index;
9450   u8 sw_if_index_set = 0;
9451   u8 vtr_op_set = 0;
9452   u32 vtr_op = 0;
9453   u32 push_dot1q = 1;
9454   u32 tag1 = ~0;
9455   u32 tag2 = ~0;
9456
9457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9458     {
9459       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9460         sw_if_index_set = 1;
9461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9462         sw_if_index_set = 1;
9463       else if (unformat (i, "vtr_op %d", &vtr_op))
9464         vtr_op_set = 1;
9465 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9466       foreach_vtr_op
9467 #undef _
9468         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9469         ;
9470       else if (unformat (i, "tag1 %d", &tag1))
9471         ;
9472       else if (unformat (i, "tag2 %d", &tag2))
9473         ;
9474       else
9475         {
9476           clib_warning ("parse error '%U'", format_unformat_error, i);
9477           return -99;
9478         }
9479     }
9480
9481   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9482     {
9483       errmsg ("missing vtr operation or sw_if_index\n");
9484       return -99;
9485     }
9486
9487   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9488     mp->sw_if_index = ntohl (sw_if_index);
9489   mp->vtr_op = ntohl (vtr_op);
9490   mp->push_dot1q = ntohl (push_dot1q);
9491   mp->tag1 = ntohl (tag1);
9492   mp->tag2 = ntohl (tag2);
9493
9494   S;
9495   W;
9496   /* NOTREACHED */
9497   return 0;
9498 }
9499
9500 static int
9501 api_create_vhost_user_if (vat_main_t * vam)
9502 {
9503   unformat_input_t *i = vam->input;
9504   vl_api_create_vhost_user_if_t *mp;
9505   f64 timeout;
9506   u8 *file_name;
9507   u8 is_server = 0;
9508   u8 file_name_set = 0;
9509   u32 custom_dev_instance = ~0;
9510   u8 hwaddr[6];
9511   u8 use_custom_mac = 0;
9512
9513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9514     {
9515       if (unformat (i, "socket %s", &file_name))
9516         {
9517           file_name_set = 1;
9518         }
9519       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9520         ;
9521       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9522         use_custom_mac = 1;
9523       else if (unformat (i, "server"))
9524         is_server = 1;
9525       else
9526         break;
9527     }
9528
9529   if (file_name_set == 0)
9530     {
9531       errmsg ("missing socket file name\n");
9532       return -99;
9533     }
9534
9535   if (vec_len (file_name) > 255)
9536     {
9537       errmsg ("socket file name too long\n");
9538       return -99;
9539     }
9540   vec_add1 (file_name, 0);
9541
9542   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9543
9544   mp->is_server = is_server;
9545   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9546   vec_free (file_name);
9547   if (custom_dev_instance != ~0)
9548     {
9549       mp->renumber = 1;
9550       mp->custom_dev_instance = ntohl (custom_dev_instance);
9551     }
9552   mp->use_custom_mac = use_custom_mac;
9553   clib_memcpy (mp->mac_address, hwaddr, 6);
9554
9555   S;
9556   W;
9557   /* NOTREACHED */
9558   return 0;
9559 }
9560
9561 static int
9562 api_modify_vhost_user_if (vat_main_t * vam)
9563 {
9564   unformat_input_t *i = vam->input;
9565   vl_api_modify_vhost_user_if_t *mp;
9566   f64 timeout;
9567   u8 *file_name;
9568   u8 is_server = 0;
9569   u8 file_name_set = 0;
9570   u32 custom_dev_instance = ~0;
9571   u8 sw_if_index_set = 0;
9572   u32 sw_if_index = (u32) ~ 0;
9573
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9577         sw_if_index_set = 1;
9578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9579         sw_if_index_set = 1;
9580       else if (unformat (i, "socket %s", &file_name))
9581         {
9582           file_name_set = 1;
9583         }
9584       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9585         ;
9586       else if (unformat (i, "server"))
9587         is_server = 1;
9588       else
9589         break;
9590     }
9591
9592   if (sw_if_index_set == 0)
9593     {
9594       errmsg ("missing sw_if_index or interface name\n");
9595       return -99;
9596     }
9597
9598   if (file_name_set == 0)
9599     {
9600       errmsg ("missing socket file name\n");
9601       return -99;
9602     }
9603
9604   if (vec_len (file_name) > 255)
9605     {
9606       errmsg ("socket file name too long\n");
9607       return -99;
9608     }
9609   vec_add1 (file_name, 0);
9610
9611   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9612
9613   mp->sw_if_index = ntohl (sw_if_index);
9614   mp->is_server = is_server;
9615   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9616   vec_free (file_name);
9617   if (custom_dev_instance != ~0)
9618     {
9619       mp->renumber = 1;
9620       mp->custom_dev_instance = ntohl (custom_dev_instance);
9621     }
9622
9623   S;
9624   W;
9625   /* NOTREACHED */
9626   return 0;
9627 }
9628
9629 static int
9630 api_delete_vhost_user_if (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_delete_vhost_user_if_t *mp;
9634   f64 timeout;
9635   u32 sw_if_index = ~0;
9636   u8 sw_if_index_set = 0;
9637
9638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9639     {
9640       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9641         sw_if_index_set = 1;
9642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9643         sw_if_index_set = 1;
9644       else
9645         break;
9646     }
9647
9648   if (sw_if_index_set == 0)
9649     {
9650       errmsg ("missing sw_if_index or interface name\n");
9651       return -99;
9652     }
9653
9654
9655   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9656
9657   mp->sw_if_index = ntohl (sw_if_index);
9658
9659   S;
9660   W;
9661   /* NOTREACHED */
9662   return 0;
9663 }
9664
9665 static void vl_api_sw_interface_vhost_user_details_t_handler
9666   (vl_api_sw_interface_vhost_user_details_t * mp)
9667 {
9668   vat_main_t *vam = &vat_main;
9669
9670   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9671            (char *) mp->interface_name,
9672            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9673            clib_net_to_host_u64 (mp->features), mp->is_server,
9674            ntohl (mp->num_regions), (char *) mp->sock_filename);
9675   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9676 }
9677
9678 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9679   (vl_api_sw_interface_vhost_user_details_t * mp)
9680 {
9681   vat_main_t *vam = &vat_main;
9682   vat_json_node_t *node = NULL;
9683
9684   if (VAT_JSON_ARRAY != vam->json_tree.type)
9685     {
9686       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9687       vat_json_init_array (&vam->json_tree);
9688     }
9689   node = vat_json_array_add (&vam->json_tree);
9690
9691   vat_json_init_object (node);
9692   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9693   vat_json_object_add_string_copy (node, "interface_name",
9694                                    mp->interface_name);
9695   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9696                             ntohl (mp->virtio_net_hdr_sz));
9697   vat_json_object_add_uint (node, "features",
9698                             clib_net_to_host_u64 (mp->features));
9699   vat_json_object_add_uint (node, "is_server", mp->is_server);
9700   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9701   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9702   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9703 }
9704
9705 static int
9706 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9707 {
9708   vl_api_sw_interface_vhost_user_dump_t *mp;
9709   f64 timeout;
9710   fformat (vam->ofp,
9711            "Interface name           idx hdr_sz features server regions filename\n");
9712
9713   /* Get list of vhost-user interfaces */
9714   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9715   S;
9716
9717   /* Use a control ping for synchronization */
9718   {
9719     vl_api_control_ping_t *mp;
9720     M (CONTROL_PING, control_ping);
9721     S;
9722   }
9723   W;
9724 }
9725
9726 static int
9727 api_show_version (vat_main_t * vam)
9728 {
9729   vl_api_show_version_t *mp;
9730   f64 timeout;
9731
9732   M (SHOW_VERSION, show_version);
9733
9734   S;
9735   W;
9736   /* NOTREACHED */
9737   return 0;
9738 }
9739
9740
9741 static int
9742 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9743 {
9744   unformat_input_t *line_input = vam->input;
9745   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9746   f64 timeout;
9747   ip4_address_t local4, remote4;
9748   ip6_address_t local6, remote6;
9749   u8 is_add = 1;
9750   u8 ipv4_set = 0, ipv6_set = 0;
9751   u8 local_set = 0;
9752   u8 remote_set = 0;
9753   u32 encap_vrf_id = 0;
9754   u32 decap_vrf_id = 0;
9755   u8 protocol = ~0;
9756   u32 vni;
9757   u8 vni_set = 0;
9758
9759   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (line_input, "del"))
9762         is_add = 0;
9763       else if (unformat (line_input, "local %U",
9764                          unformat_ip4_address, &local4))
9765         {
9766           local_set = 1;
9767           ipv4_set = 1;
9768         }
9769       else if (unformat (line_input, "remote %U",
9770                          unformat_ip4_address, &remote4))
9771         {
9772           remote_set = 1;
9773           ipv4_set = 1;
9774         }
9775       else if (unformat (line_input, "local %U",
9776                          unformat_ip6_address, &local6))
9777         {
9778           local_set = 1;
9779           ipv6_set = 1;
9780         }
9781       else if (unformat (line_input, "remote %U",
9782                          unformat_ip6_address, &remote6))
9783         {
9784           remote_set = 1;
9785           ipv6_set = 1;
9786         }
9787       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9788         ;
9789       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9790         ;
9791       else if (unformat (line_input, "vni %d", &vni))
9792         vni_set = 1;
9793       else if (unformat (line_input, "next-ip4"))
9794         protocol = 1;
9795       else if (unformat (line_input, "next-ip6"))
9796         protocol = 2;
9797       else if (unformat (line_input, "next-ethernet"))
9798         protocol = 3;
9799       else if (unformat (line_input, "next-nsh"))
9800         protocol = 4;
9801       else
9802         {
9803           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9804           return -99;
9805         }
9806     }
9807
9808   if (local_set == 0)
9809     {
9810       errmsg ("tunnel local address not specified\n");
9811       return -99;
9812     }
9813   if (remote_set == 0)
9814     {
9815       errmsg ("tunnel remote address not specified\n");
9816       return -99;
9817     }
9818   if (ipv4_set && ipv6_set)
9819     {
9820       errmsg ("both IPv4 and IPv6 addresses specified");
9821       return -99;
9822     }
9823
9824   if (vni_set == 0)
9825     {
9826       errmsg ("vni not specified\n");
9827       return -99;
9828     }
9829
9830   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9831
9832
9833   if (ipv6_set)
9834     {
9835       clib_memcpy (&mp->local, &local6, sizeof (local6));
9836       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9837     }
9838   else
9839     {
9840       clib_memcpy (&mp->local, &local4, sizeof (local4));
9841       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9842     }
9843
9844   mp->encap_vrf_id = ntohl (encap_vrf_id);
9845   mp->decap_vrf_id = ntohl (decap_vrf_id);
9846   mp->protocol = ntohl (protocol);
9847   mp->vni = ntohl (vni);
9848   mp->is_add = is_add;
9849   mp->is_ipv6 = ipv6_set;
9850
9851   S;
9852   W;
9853   /* NOTREACHED */
9854   return 0;
9855 }
9856
9857 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9858   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9859 {
9860   vat_main_t *vam = &vat_main;
9861
9862   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9863            ntohl (mp->sw_if_index),
9864            format_ip46_address, &(mp->local[0]),
9865            format_ip46_address, &(mp->remote[0]),
9866            ntohl (mp->vni),
9867            ntohl (mp->protocol),
9868            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9869 }
9870
9871 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9872   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9873 {
9874   vat_main_t *vam = &vat_main;
9875   vat_json_node_t *node = NULL;
9876   struct in_addr ip4;
9877   struct in6_addr ip6;
9878
9879   if (VAT_JSON_ARRAY != vam->json_tree.type)
9880     {
9881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9882       vat_json_init_array (&vam->json_tree);
9883     }
9884   node = vat_json_array_add (&vam->json_tree);
9885
9886   vat_json_init_object (node);
9887   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9888   if (mp->is_ipv6)
9889     {
9890       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9891       vat_json_object_add_ip6 (node, "local", ip6);
9892       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9893       vat_json_object_add_ip6 (node, "remote", ip6);
9894     }
9895   else
9896     {
9897       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9898       vat_json_object_add_ip4 (node, "local", ip4);
9899       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9900       vat_json_object_add_ip4 (node, "remote", ip4);
9901     }
9902   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9903   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9904   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9905   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
9906   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9907 }
9908
9909 static int
9910 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9911 {
9912   unformat_input_t *i = vam->input;
9913   vl_api_vxlan_gpe_tunnel_dump_t *mp;
9914   f64 timeout;
9915   u32 sw_if_index;
9916   u8 sw_if_index_set = 0;
9917
9918   /* Parse args required to build the message */
9919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9920     {
9921       if (unformat (i, "sw_if_index %d", &sw_if_index))
9922         sw_if_index_set = 1;
9923       else
9924         break;
9925     }
9926
9927   if (sw_if_index_set == 0)
9928     {
9929       sw_if_index = ~0;
9930     }
9931
9932   if (!vam->json_output)
9933     {
9934       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
9935                "sw_if_index", "local", "remote", "vni",
9936                "protocol", "encap_vrf_id", "decap_vrf_id");
9937     }
9938
9939   /* Get list of vxlan-tunnel interfaces */
9940   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
9941
9942   mp->sw_if_index = htonl (sw_if_index);
9943
9944   S;
9945
9946   /* Use a control ping for synchronization */
9947   {
9948     vl_api_control_ping_t *mp;
9949     M (CONTROL_PING, control_ping);
9950     S;
9951   }
9952   W;
9953 }
9954
9955 u8 *
9956 format_l2_fib_mac_address (u8 * s, va_list * args)
9957 {
9958   u8 *a = va_arg (*args, u8 *);
9959
9960   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
9961                  a[2], a[3], a[4], a[5], a[6], a[7]);
9962 }
9963
9964 static void vl_api_l2_fib_table_entry_t_handler
9965   (vl_api_l2_fib_table_entry_t * mp)
9966 {
9967   vat_main_t *vam = &vat_main;
9968
9969   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
9970            "       %d       %d     %d\n",
9971            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
9972            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
9973            mp->bvi_mac);
9974 }
9975
9976 static void vl_api_l2_fib_table_entry_t_handler_json
9977   (vl_api_l2_fib_table_entry_t * mp)
9978 {
9979   vat_main_t *vam = &vat_main;
9980   vat_json_node_t *node = NULL;
9981
9982   if (VAT_JSON_ARRAY != vam->json_tree.type)
9983     {
9984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9985       vat_json_init_array (&vam->json_tree);
9986     }
9987   node = vat_json_array_add (&vam->json_tree);
9988
9989   vat_json_init_object (node);
9990   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
9991   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
9992   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9993   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
9994   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
9995   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
9996 }
9997
9998 static int
9999 api_l2_fib_table_dump (vat_main_t * vam)
10000 {
10001   unformat_input_t *i = vam->input;
10002   vl_api_l2_fib_table_dump_t *mp;
10003   f64 timeout;
10004   u32 bd_id;
10005   u8 bd_id_set = 0;
10006
10007   /* Parse args required to build the message */
10008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10009     {
10010       if (unformat (i, "bd_id %d", &bd_id))
10011         bd_id_set = 1;
10012       else
10013         break;
10014     }
10015
10016   if (bd_id_set == 0)
10017     {
10018       errmsg ("missing bridge domain\n");
10019       return -99;
10020     }
10021
10022   fformat (vam->ofp,
10023            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10024
10025   /* Get list of l2 fib entries */
10026   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10027
10028   mp->bd_id = ntohl (bd_id);
10029   S;
10030
10031   /* Use a control ping for synchronization */
10032   {
10033     vl_api_control_ping_t *mp;
10034     M (CONTROL_PING, control_ping);
10035     S;
10036   }
10037   W;
10038 }
10039
10040
10041 static int
10042 api_interface_name_renumber (vat_main_t * vam)
10043 {
10044   unformat_input_t *line_input = vam->input;
10045   vl_api_interface_name_renumber_t *mp;
10046   u32 sw_if_index = ~0;
10047   f64 timeout;
10048   u32 new_show_dev_instance = ~0;
10049
10050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10051     {
10052       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10053                     &sw_if_index))
10054         ;
10055       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10056         ;
10057       else if (unformat (line_input, "new_show_dev_instance %d",
10058                          &new_show_dev_instance))
10059         ;
10060       else
10061         break;
10062     }
10063
10064   if (sw_if_index == ~0)
10065     {
10066       errmsg ("missing interface name or sw_if_index\n");
10067       return -99;
10068     }
10069
10070   if (new_show_dev_instance == ~0)
10071     {
10072       errmsg ("missing new_show_dev_instance\n");
10073       return -99;
10074     }
10075
10076   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10077
10078   mp->sw_if_index = ntohl (sw_if_index);
10079   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10080
10081   S;
10082   W;
10083 }
10084
10085 static int
10086 api_want_ip4_arp_events (vat_main_t * vam)
10087 {
10088   unformat_input_t *line_input = vam->input;
10089   vl_api_want_ip4_arp_events_t *mp;
10090   f64 timeout;
10091   ip4_address_t address;
10092   int address_set = 0;
10093   u32 enable_disable = 1;
10094
10095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10096     {
10097       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10098         address_set = 1;
10099       else if (unformat (line_input, "del"))
10100         enable_disable = 0;
10101       else
10102         break;
10103     }
10104
10105   if (address_set == 0)
10106     {
10107       errmsg ("missing addresses\n");
10108       return -99;
10109     }
10110
10111   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10112   mp->enable_disable = enable_disable;
10113   mp->pid = getpid ();
10114   mp->address = address.as_u32;
10115
10116   S;
10117   W;
10118 }
10119
10120 static int
10121 api_input_acl_set_interface (vat_main_t * vam)
10122 {
10123   unformat_input_t *i = vam->input;
10124   vl_api_input_acl_set_interface_t *mp;
10125   f64 timeout;
10126   u32 sw_if_index;
10127   int sw_if_index_set;
10128   u32 ip4_table_index = ~0;
10129   u32 ip6_table_index = ~0;
10130   u32 l2_table_index = ~0;
10131   u8 is_add = 1;
10132
10133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10134     {
10135       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10136         sw_if_index_set = 1;
10137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10138         sw_if_index_set = 1;
10139       else if (unformat (i, "del"))
10140         is_add = 0;
10141       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10142         ;
10143       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10144         ;
10145       else if (unformat (i, "l2-table %d", &l2_table_index))
10146         ;
10147       else
10148         {
10149           clib_warning ("parse error '%U'", format_unformat_error, i);
10150           return -99;
10151         }
10152     }
10153
10154   if (sw_if_index_set == 0)
10155     {
10156       errmsg ("missing interface name or sw_if_index\n");
10157       return -99;
10158     }
10159
10160   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10161
10162   mp->sw_if_index = ntohl (sw_if_index);
10163   mp->ip4_table_index = ntohl (ip4_table_index);
10164   mp->ip6_table_index = ntohl (ip6_table_index);
10165   mp->l2_table_index = ntohl (l2_table_index);
10166   mp->is_add = is_add;
10167
10168   S;
10169   W;
10170   /* NOTREACHED */
10171   return 0;
10172 }
10173
10174 static int
10175 api_ip_address_dump (vat_main_t * vam)
10176 {
10177   unformat_input_t *i = vam->input;
10178   vl_api_ip_address_dump_t *mp;
10179   u32 sw_if_index = ~0;
10180   u8 sw_if_index_set = 0;
10181   u8 ipv4_set = 0;
10182   u8 ipv6_set = 0;
10183   f64 timeout;
10184
10185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10186     {
10187       if (unformat (i, "sw_if_index %d", &sw_if_index))
10188         sw_if_index_set = 1;
10189       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10190         sw_if_index_set = 1;
10191       else if (unformat (i, "ipv4"))
10192         ipv4_set = 1;
10193       else if (unformat (i, "ipv6"))
10194         ipv6_set = 1;
10195       else
10196         break;
10197     }
10198
10199   if (ipv4_set && ipv6_set)
10200     {
10201       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10202       return -99;
10203     }
10204
10205   if ((!ipv4_set) && (!ipv6_set))
10206     {
10207       errmsg ("no ipv4 nor ipv6 flag set\n");
10208       return -99;
10209     }
10210
10211   if (sw_if_index_set == 0)
10212     {
10213       errmsg ("missing interface name or sw_if_index\n");
10214       return -99;
10215     }
10216
10217   vam->current_sw_if_index = sw_if_index;
10218   vam->is_ipv6 = ipv6_set;
10219
10220   M (IP_ADDRESS_DUMP, ip_address_dump);
10221   mp->sw_if_index = ntohl (sw_if_index);
10222   mp->is_ipv6 = ipv6_set;
10223   S;
10224
10225   /* Use a control ping for synchronization */
10226   {
10227     vl_api_control_ping_t *mp;
10228     M (CONTROL_PING, control_ping);
10229     S;
10230   }
10231   W;
10232 }
10233
10234 static int
10235 api_ip_dump (vat_main_t * vam)
10236 {
10237   vl_api_ip_dump_t *mp;
10238   unformat_input_t *in = vam->input;
10239   int ipv4_set = 0;
10240   int ipv6_set = 0;
10241   int is_ipv6;
10242   f64 timeout;
10243   int i;
10244
10245   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10246     {
10247       if (unformat (in, "ipv4"))
10248         ipv4_set = 1;
10249       else if (unformat (in, "ipv6"))
10250         ipv6_set = 1;
10251       else
10252         break;
10253     }
10254
10255   if (ipv4_set && ipv6_set)
10256     {
10257       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10258       return -99;
10259     }
10260
10261   if ((!ipv4_set) && (!ipv6_set))
10262     {
10263       errmsg ("no ipv4 nor ipv6 flag set\n");
10264       return -99;
10265     }
10266
10267   is_ipv6 = ipv6_set;
10268   vam->is_ipv6 = is_ipv6;
10269
10270   /* free old data */
10271   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10272     {
10273       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10274     }
10275   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10276
10277   M (IP_DUMP, ip_dump);
10278   mp->is_ipv6 = ipv6_set;
10279   S;
10280
10281   /* Use a control ping for synchronization */
10282   {
10283     vl_api_control_ping_t *mp;
10284     M (CONTROL_PING, control_ping);
10285     S;
10286   }
10287   W;
10288 }
10289
10290 static int
10291 api_ipsec_spd_add_del (vat_main_t * vam)
10292 {
10293 #if DPDK > 0
10294   unformat_input_t *i = vam->input;
10295   vl_api_ipsec_spd_add_del_t *mp;
10296   f64 timeout;
10297   u32 spd_id = ~0;
10298   u8 is_add = 1;
10299
10300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10301     {
10302       if (unformat (i, "spd_id %d", &spd_id))
10303         ;
10304       else if (unformat (i, "del"))
10305         is_add = 0;
10306       else
10307         {
10308           clib_warning ("parse error '%U'", format_unformat_error, i);
10309           return -99;
10310         }
10311     }
10312   if (spd_id == ~0)
10313     {
10314       errmsg ("spd_id must be set\n");
10315       return -99;
10316     }
10317
10318   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10319
10320   mp->spd_id = ntohl (spd_id);
10321   mp->is_add = is_add;
10322
10323   S;
10324   W;
10325   /* NOTREACHED */
10326   return 0;
10327 #else
10328   clib_warning ("unsupported (no dpdk)");
10329   return -99;
10330 #endif
10331 }
10332
10333 static int
10334 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10335 {
10336 #if DPDK > 0
10337   unformat_input_t *i = vam->input;
10338   vl_api_ipsec_interface_add_del_spd_t *mp;
10339   f64 timeout;
10340   u32 sw_if_index;
10341   u8 sw_if_index_set = 0;
10342   u32 spd_id = (u32) ~ 0;
10343   u8 is_add = 1;
10344
10345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10346     {
10347       if (unformat (i, "del"))
10348         is_add = 0;
10349       else if (unformat (i, "spd_id %d", &spd_id))
10350         ;
10351       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10352         sw_if_index_set = 1;
10353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10354         sw_if_index_set = 1;
10355       else
10356         {
10357           clib_warning ("parse error '%U'", format_unformat_error, i);
10358           return -99;
10359         }
10360
10361     }
10362
10363   if (spd_id == (u32) ~ 0)
10364     {
10365       errmsg ("spd_id must be set\n");
10366       return -99;
10367     }
10368
10369   if (sw_if_index_set == 0)
10370     {
10371       errmsg ("missing interface name or sw_if_index\n");
10372       return -99;
10373     }
10374
10375   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10376
10377   mp->spd_id = ntohl (spd_id);
10378   mp->sw_if_index = ntohl (sw_if_index);
10379   mp->is_add = is_add;
10380
10381   S;
10382   W;
10383   /* NOTREACHED */
10384   return 0;
10385 #else
10386   clib_warning ("unsupported (no dpdk)");
10387   return -99;
10388 #endif
10389 }
10390
10391 static int
10392 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10393 {
10394 #if DPDK > 0
10395   unformat_input_t *i = vam->input;
10396   vl_api_ipsec_spd_add_del_entry_t *mp;
10397   f64 timeout;
10398   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10399   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10400   i32 priority;
10401   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10402   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10403   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10404   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10405
10406   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10407   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10408   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10409   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10410   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10411   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10412
10413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (i, "del"))
10416         is_add = 0;
10417       if (unformat (i, "outbound"))
10418         is_outbound = 1;
10419       if (unformat (i, "inbound"))
10420         is_outbound = 0;
10421       else if (unformat (i, "spd_id %d", &spd_id))
10422         ;
10423       else if (unformat (i, "sa_id %d", &sa_id))
10424         ;
10425       else if (unformat (i, "priority %d", &priority))
10426         ;
10427       else if (unformat (i, "protocol %d", &protocol))
10428         ;
10429       else if (unformat (i, "lport_start %d", &lport_start))
10430         ;
10431       else if (unformat (i, "lport_stop %d", &lport_stop))
10432         ;
10433       else if (unformat (i, "rport_start %d", &rport_start))
10434         ;
10435       else if (unformat (i, "rport_stop %d", &rport_stop))
10436         ;
10437       else
10438         if (unformat
10439             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10440         {
10441           is_ipv6 = 0;
10442           is_ip_any = 0;
10443         }
10444       else
10445         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10446         {
10447           is_ipv6 = 0;
10448           is_ip_any = 0;
10449         }
10450       else
10451         if (unformat
10452             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10453         {
10454           is_ipv6 = 0;
10455           is_ip_any = 0;
10456         }
10457       else
10458         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10459         {
10460           is_ipv6 = 0;
10461           is_ip_any = 0;
10462         }
10463       else
10464         if (unformat
10465             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10466         {
10467           is_ipv6 = 1;
10468           is_ip_any = 0;
10469         }
10470       else
10471         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10472         {
10473           is_ipv6 = 1;
10474           is_ip_any = 0;
10475         }
10476       else
10477         if (unformat
10478             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10479         {
10480           is_ipv6 = 1;
10481           is_ip_any = 0;
10482         }
10483       else
10484         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10485         {
10486           is_ipv6 = 1;
10487           is_ip_any = 0;
10488         }
10489       else
10490         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10491         {
10492           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10493             {
10494               clib_warning ("unsupported action: 'resolve'");
10495               return -99;
10496             }
10497         }
10498       else
10499         {
10500           clib_warning ("parse error '%U'", format_unformat_error, i);
10501           return -99;
10502         }
10503
10504     }
10505
10506   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10507
10508   mp->spd_id = ntohl (spd_id);
10509   mp->priority = ntohl (priority);
10510   mp->is_outbound = is_outbound;
10511
10512   mp->is_ipv6 = is_ipv6;
10513   if (is_ipv6 || is_ip_any)
10514     {
10515       clib_memcpy (mp->remote_address_start, &raddr6_start,
10516                    sizeof (ip6_address_t));
10517       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10518                    sizeof (ip6_address_t));
10519       clib_memcpy (mp->local_address_start, &laddr6_start,
10520                    sizeof (ip6_address_t));
10521       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10522                    sizeof (ip6_address_t));
10523     }
10524   else
10525     {
10526       clib_memcpy (mp->remote_address_start, &raddr4_start,
10527                    sizeof (ip4_address_t));
10528       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10529                    sizeof (ip4_address_t));
10530       clib_memcpy (mp->local_address_start, &laddr4_start,
10531                    sizeof (ip4_address_t));
10532       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10533                    sizeof (ip4_address_t));
10534     }
10535   mp->protocol = (u8) protocol;
10536   mp->local_port_start = ntohs ((u16) lport_start);
10537   mp->local_port_stop = ntohs ((u16) lport_stop);
10538   mp->remote_port_start = ntohs ((u16) rport_start);
10539   mp->remote_port_stop = ntohs ((u16) rport_stop);
10540   mp->policy = (u8) policy;
10541   mp->sa_id = ntohl (sa_id);
10542   mp->is_add = is_add;
10543   mp->is_ip_any = is_ip_any;
10544   S;
10545   W;
10546   /* NOTREACHED */
10547   return 0;
10548 #else
10549   clib_warning ("unsupported (no dpdk)");
10550   return -99;
10551 #endif
10552 }
10553
10554 static int
10555 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10556 {
10557 #if DPDK > 0
10558   unformat_input_t *i = vam->input;
10559   vl_api_ipsec_sad_add_del_entry_t *mp;
10560   f64 timeout;
10561   u32 sad_id = 0, spi = 0;
10562   u8 *ck = 0, *ik = 0;
10563   u8 is_add = 1;
10564
10565   u8 protocol = IPSEC_PROTOCOL_AH;
10566   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10567   u32 crypto_alg = 0, integ_alg = 0;
10568   ip4_address_t tun_src4;
10569   ip4_address_t tun_dst4;
10570   ip6_address_t tun_src6;
10571   ip6_address_t tun_dst6;
10572
10573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10574     {
10575       if (unformat (i, "del"))
10576         is_add = 0;
10577       else if (unformat (i, "sad_id %d", &sad_id))
10578         ;
10579       else if (unformat (i, "spi %d", &spi))
10580         ;
10581       else if (unformat (i, "esp"))
10582         protocol = IPSEC_PROTOCOL_ESP;
10583       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10584         {
10585           is_tunnel = 1;
10586           is_tunnel_ipv6 = 0;
10587         }
10588       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10589         {
10590           is_tunnel = 1;
10591           is_tunnel_ipv6 = 0;
10592         }
10593       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10594         {
10595           is_tunnel = 1;
10596           is_tunnel_ipv6 = 1;
10597         }
10598       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10599         {
10600           is_tunnel = 1;
10601           is_tunnel_ipv6 = 1;
10602         }
10603       else
10604         if (unformat
10605             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10606         {
10607           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10608               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10609             {
10610               clib_warning ("unsupported crypto-alg: '%U'",
10611                             format_ipsec_crypto_alg, crypto_alg);
10612               return -99;
10613             }
10614         }
10615       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10616         ;
10617       else
10618         if (unformat
10619             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10620         {
10621           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10622               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10623             {
10624               clib_warning ("unsupported integ-alg: '%U'",
10625                             format_ipsec_integ_alg, integ_alg);
10626               return -99;
10627             }
10628         }
10629       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10630         ;
10631       else
10632         {
10633           clib_warning ("parse error '%U'", format_unformat_error, i);
10634           return -99;
10635         }
10636
10637     }
10638
10639   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10640
10641   mp->sad_id = ntohl (sad_id);
10642   mp->is_add = is_add;
10643   mp->protocol = protocol;
10644   mp->spi = ntohl (spi);
10645   mp->is_tunnel = is_tunnel;
10646   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10647   mp->crypto_algorithm = crypto_alg;
10648   mp->integrity_algorithm = integ_alg;
10649   mp->crypto_key_length = vec_len (ck);
10650   mp->integrity_key_length = vec_len (ik);
10651
10652   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10653     mp->crypto_key_length = sizeof (mp->crypto_key);
10654
10655   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10656     mp->integrity_key_length = sizeof (mp->integrity_key);
10657
10658   if (ck)
10659     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10660   if (ik)
10661     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10662
10663   if (is_tunnel)
10664     {
10665       if (is_tunnel_ipv6)
10666         {
10667           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10668                        sizeof (ip6_address_t));
10669           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10670                        sizeof (ip6_address_t));
10671         }
10672       else
10673         {
10674           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10675                        sizeof (ip4_address_t));
10676           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10677                        sizeof (ip4_address_t));
10678         }
10679     }
10680
10681   S;
10682   W;
10683   /* NOTREACHED */
10684   return 0;
10685 #else
10686   clib_warning ("unsupported (no dpdk)");
10687   return -99;
10688 #endif
10689 }
10690
10691 static int
10692 api_ipsec_sa_set_key (vat_main_t * vam)
10693 {
10694 #if DPDK > 0
10695   unformat_input_t *i = vam->input;
10696   vl_api_ipsec_sa_set_key_t *mp;
10697   f64 timeout;
10698   u32 sa_id;
10699   u8 *ck = 0, *ik = 0;
10700
10701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10702     {
10703       if (unformat (i, "sa_id %d", &sa_id))
10704         ;
10705       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10706         ;
10707       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10708         ;
10709       else
10710         {
10711           clib_warning ("parse error '%U'", format_unformat_error, i);
10712           return -99;
10713         }
10714     }
10715
10716   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10717
10718   mp->sa_id = ntohl (sa_id);
10719   mp->crypto_key_length = vec_len (ck);
10720   mp->integrity_key_length = vec_len (ik);
10721
10722   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10723     mp->crypto_key_length = sizeof (mp->crypto_key);
10724
10725   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10726     mp->integrity_key_length = sizeof (mp->integrity_key);
10727
10728   if (ck)
10729     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10730   if (ik)
10731     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10732
10733   S;
10734   W;
10735   /* NOTREACHED */
10736   return 0;
10737 #else
10738   clib_warning ("unsupported (no dpdk)");
10739   return -99;
10740 #endif
10741 }
10742
10743 static int
10744 api_ikev2_profile_add_del (vat_main_t * vam)
10745 {
10746 #if DPDK > 0
10747   unformat_input_t *i = vam->input;
10748   vl_api_ikev2_profile_add_del_t *mp;
10749   f64 timeout;
10750   u8 is_add = 1;
10751   u8 *name = 0;
10752
10753   const char *valid_chars = "a-zA-Z0-9_";
10754
10755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10756     {
10757       if (unformat (i, "del"))
10758         is_add = 0;
10759       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10760         vec_add1 (name, 0);
10761       else
10762         {
10763           errmsg ("parse error '%U'", format_unformat_error, i);
10764           return -99;
10765         }
10766     }
10767
10768   if (!vec_len (name))
10769     {
10770       errmsg ("profile name must be specified");
10771       return -99;
10772     }
10773
10774   if (vec_len (name) > 64)
10775     {
10776       errmsg ("profile name too long");
10777       return -99;
10778     }
10779
10780   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10781
10782   clib_memcpy (mp->name, name, vec_len (name));
10783   mp->is_add = is_add;
10784   vec_free (name);
10785
10786   S;
10787   W;
10788   /* NOTREACHED */
10789   return 0;
10790 #else
10791   clib_warning ("unsupported (no dpdk)");
10792   return -99;
10793 #endif
10794 }
10795
10796 static int
10797 api_ikev2_profile_set_auth (vat_main_t * vam)
10798 {
10799 #if DPDK > 0
10800   unformat_input_t *i = vam->input;
10801   vl_api_ikev2_profile_set_auth_t *mp;
10802   f64 timeout;
10803   u8 *name = 0;
10804   u8 *data = 0;
10805   u32 auth_method = 0;
10806   u8 is_hex = 0;
10807
10808   const char *valid_chars = "a-zA-Z0-9_";
10809
10810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10813         vec_add1 (name, 0);
10814       else if (unformat (i, "auth_method %U",
10815                          unformat_ikev2_auth_method, &auth_method))
10816         ;
10817       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10818         is_hex = 1;
10819       else if (unformat (i, "auth_data %v", &data))
10820         ;
10821       else
10822         {
10823           errmsg ("parse error '%U'", format_unformat_error, i);
10824           return -99;
10825         }
10826     }
10827
10828   if (!vec_len (name))
10829     {
10830       errmsg ("profile name must be specified");
10831       return -99;
10832     }
10833
10834   if (vec_len (name) > 64)
10835     {
10836       errmsg ("profile name too long");
10837       return -99;
10838     }
10839
10840   if (!vec_len (data))
10841     {
10842       errmsg ("auth_data must be specified");
10843       return -99;
10844     }
10845
10846   if (!auth_method)
10847     {
10848       errmsg ("auth_method must be specified");
10849       return -99;
10850     }
10851
10852   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10853
10854   mp->is_hex = is_hex;
10855   mp->auth_method = (u8) auth_method;
10856   mp->data_len = vec_len (data);
10857   clib_memcpy (mp->name, name, vec_len (name));
10858   clib_memcpy (mp->data, data, vec_len (data));
10859   vec_free (name);
10860   vec_free (data);
10861
10862   S;
10863   W;
10864   /* NOTREACHED */
10865   return 0;
10866 #else
10867   clib_warning ("unsupported (no dpdk)");
10868   return -99;
10869 #endif
10870 }
10871
10872 static int
10873 api_ikev2_profile_set_id (vat_main_t * vam)
10874 {
10875 #if DPDK > 0
10876   unformat_input_t *i = vam->input;
10877   vl_api_ikev2_profile_set_id_t *mp;
10878   f64 timeout;
10879   u8 *name = 0;
10880   u8 *data = 0;
10881   u8 is_local = 0;
10882   u32 id_type = 0;
10883   ip4_address_t ip4;
10884
10885   const char *valid_chars = "a-zA-Z0-9_";
10886
10887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10888     {
10889       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10890         vec_add1 (name, 0);
10891       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10892         ;
10893       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10894         {
10895           data = vec_new (u8, 4);
10896           clib_memcpy (data, ip4.as_u8, 4);
10897         }
10898       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10899         ;
10900       else if (unformat (i, "id_data %v", &data))
10901         ;
10902       else if (unformat (i, "local"))
10903         is_local = 1;
10904       else if (unformat (i, "remote"))
10905         is_local = 0;
10906       else
10907         {
10908           errmsg ("parse error '%U'", format_unformat_error, i);
10909           return -99;
10910         }
10911     }
10912
10913   if (!vec_len (name))
10914     {
10915       errmsg ("profile name must be specified");
10916       return -99;
10917     }
10918
10919   if (vec_len (name) > 64)
10920     {
10921       errmsg ("profile name too long");
10922       return -99;
10923     }
10924
10925   if (!vec_len (data))
10926     {
10927       errmsg ("id_data must be specified");
10928       return -99;
10929     }
10930
10931   if (!id_type)
10932     {
10933       errmsg ("id_type must be specified");
10934       return -99;
10935     }
10936
10937   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
10938
10939   mp->is_local = is_local;
10940   mp->id_type = (u8) id_type;
10941   mp->data_len = vec_len (data);
10942   clib_memcpy (mp->name, name, vec_len (name));
10943   clib_memcpy (mp->data, data, vec_len (data));
10944   vec_free (name);
10945   vec_free (data);
10946
10947   S;
10948   W;
10949   /* NOTREACHED */
10950   return 0;
10951 #else
10952   clib_warning ("unsupported (no dpdk)");
10953   return -99;
10954 #endif
10955 }
10956
10957 static int
10958 api_ikev2_profile_set_ts (vat_main_t * vam)
10959 {
10960 #if DPDK > 0
10961   unformat_input_t *i = vam->input;
10962   vl_api_ikev2_profile_set_ts_t *mp;
10963   f64 timeout;
10964   u8 *name = 0;
10965   u8 is_local = 0;
10966   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
10967   ip4_address_t start_addr, end_addr;
10968
10969   const char *valid_chars = "a-zA-Z0-9_";
10970
10971   start_addr.as_u32 = 0;
10972   end_addr.as_u32 = (u32) ~ 0;
10973
10974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10975     {
10976       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10977         vec_add1 (name, 0);
10978       else if (unformat (i, "protocol %d", &proto))
10979         ;
10980       else if (unformat (i, "start_port %d", &start_port))
10981         ;
10982       else if (unformat (i, "end_port %d", &end_port))
10983         ;
10984       else
10985         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
10986         ;
10987       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
10988         ;
10989       else if (unformat (i, "local"))
10990         is_local = 1;
10991       else if (unformat (i, "remote"))
10992         is_local = 0;
10993       else
10994         {
10995           errmsg ("parse error '%U'", format_unformat_error, i);
10996           return -99;
10997         }
10998     }
10999
11000   if (!vec_len (name))
11001     {
11002       errmsg ("profile name must be specified");
11003       return -99;
11004     }
11005
11006   if (vec_len (name) > 64)
11007     {
11008       errmsg ("profile name too long");
11009       return -99;
11010     }
11011
11012   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11013
11014   mp->is_local = is_local;
11015   mp->proto = (u8) proto;
11016   mp->start_port = (u16) start_port;
11017   mp->end_port = (u16) end_port;
11018   mp->start_addr = start_addr.as_u32;
11019   mp->end_addr = end_addr.as_u32;
11020   clib_memcpy (mp->name, name, vec_len (name));
11021   vec_free (name);
11022
11023   S;
11024   W;
11025   /* NOTREACHED */
11026   return 0;
11027 #else
11028   clib_warning ("unsupported (no dpdk)");
11029   return -99;
11030 #endif
11031 }
11032
11033 static int
11034 api_ikev2_set_local_key (vat_main_t * vam)
11035 {
11036 #if DPDK > 0
11037   unformat_input_t *i = vam->input;
11038   vl_api_ikev2_set_local_key_t *mp;
11039   f64 timeout;
11040   u8 *file = 0;
11041
11042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11043     {
11044       if (unformat (i, "file %v", &file))
11045         vec_add1 (file, 0);
11046       else
11047         {
11048           errmsg ("parse error '%U'", format_unformat_error, i);
11049           return -99;
11050         }
11051     }
11052
11053   if (!vec_len (file))
11054     {
11055       errmsg ("RSA key file must be specified");
11056       return -99;
11057     }
11058
11059   if (vec_len (file) > 256)
11060     {
11061       errmsg ("file name too long");
11062       return -99;
11063     }
11064
11065   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11066
11067   clib_memcpy (mp->key_file, file, vec_len (file));
11068   vec_free (file);
11069
11070   S;
11071   W;
11072   /* NOTREACHED */
11073   return 0;
11074 #else
11075   clib_warning ("unsupported (no dpdk)");
11076   return -99;
11077 #endif
11078 }
11079
11080 /*
11081  * MAP
11082  */
11083 static int
11084 api_map_add_domain (vat_main_t * vam)
11085 {
11086   unformat_input_t *i = vam->input;
11087   vl_api_map_add_domain_t *mp;
11088   f64 timeout;
11089
11090   ip4_address_t ip4_prefix;
11091   ip6_address_t ip6_prefix;
11092   ip6_address_t ip6_src;
11093   u32 num_m_args = 0;
11094   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11095     0, psid_length = 0;
11096   u8 is_translation = 0;
11097   u32 mtu = 0;
11098   u8 ip6_src_len = 128;
11099
11100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11101     {
11102       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11103                     &ip4_prefix, &ip4_prefix_len))
11104         num_m_args++;
11105       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11106                          &ip6_prefix, &ip6_prefix_len))
11107         num_m_args++;
11108       else
11109         if (unformat
11110             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11111              &ip6_src_len))
11112         num_m_args++;
11113       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11114         num_m_args++;
11115       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11116         num_m_args++;
11117       else if (unformat (i, "psid-offset %d", &psid_offset))
11118         num_m_args++;
11119       else if (unformat (i, "psid-len %d", &psid_length))
11120         num_m_args++;
11121       else if (unformat (i, "mtu %d", &mtu))
11122         num_m_args++;
11123       else if (unformat (i, "map-t"))
11124         is_translation = 1;
11125       else
11126         {
11127           clib_warning ("parse error '%U'", format_unformat_error, i);
11128           return -99;
11129         }
11130     }
11131
11132   if (num_m_args != 6)
11133     {
11134       errmsg ("mandatory argument(s) missing\n");
11135       return -99;
11136     }
11137
11138   /* Construct the API message */
11139   M (MAP_ADD_DOMAIN, map_add_domain);
11140
11141   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11142   mp->ip4_prefix_len = ip4_prefix_len;
11143
11144   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11145   mp->ip6_prefix_len = ip6_prefix_len;
11146
11147   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11148   mp->ip6_src_prefix_len = ip6_src_len;
11149
11150   mp->ea_bits_len = ea_bits_len;
11151   mp->psid_offset = psid_offset;
11152   mp->psid_length = psid_length;
11153   mp->is_translation = is_translation;
11154   mp->mtu = htons (mtu);
11155
11156   /* send it... */
11157   S;
11158
11159   /* Wait for a reply, return good/bad news  */
11160   W;
11161 }
11162
11163 static int
11164 api_map_del_domain (vat_main_t * vam)
11165 {
11166   unformat_input_t *i = vam->input;
11167   vl_api_map_del_domain_t *mp;
11168   f64 timeout;
11169
11170   u32 num_m_args = 0;
11171   u32 index;
11172
11173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11174     {
11175       if (unformat (i, "index %d", &index))
11176         num_m_args++;
11177       else
11178         {
11179           clib_warning ("parse error '%U'", format_unformat_error, i);
11180           return -99;
11181         }
11182     }
11183
11184   if (num_m_args != 1)
11185     {
11186       errmsg ("mandatory argument(s) missing\n");
11187       return -99;
11188     }
11189
11190   /* Construct the API message */
11191   M (MAP_DEL_DOMAIN, map_del_domain);
11192
11193   mp->index = ntohl (index);
11194
11195   /* send it... */
11196   S;
11197
11198   /* Wait for a reply, return good/bad news  */
11199   W;
11200 }
11201
11202 static int
11203 api_map_add_del_rule (vat_main_t * vam)
11204 {
11205   unformat_input_t *i = vam->input;
11206   vl_api_map_add_del_rule_t *mp;
11207   f64 timeout;
11208   u8 is_add = 1;
11209   ip6_address_t ip6_dst;
11210   u32 num_m_args = 0, index, psid = 0;
11211
11212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11213     {
11214       if (unformat (i, "index %d", &index))
11215         num_m_args++;
11216       else if (unformat (i, "psid %d", &psid))
11217         num_m_args++;
11218       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11219         num_m_args++;
11220       else if (unformat (i, "del"))
11221         {
11222           is_add = 0;
11223         }
11224       else
11225         {
11226           clib_warning ("parse error '%U'", format_unformat_error, i);
11227           return -99;
11228         }
11229     }
11230
11231   /* Construct the API message */
11232   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11233
11234   mp->index = ntohl (index);
11235   mp->is_add = is_add;
11236   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11237   mp->psid = ntohs (psid);
11238
11239   /* send it... */
11240   S;
11241
11242   /* Wait for a reply, return good/bad news  */
11243   W;
11244 }
11245
11246 static int
11247 api_map_domain_dump (vat_main_t * vam)
11248 {
11249   vl_api_map_domain_dump_t *mp;
11250   f64 timeout;
11251
11252   /* Construct the API message */
11253   M (MAP_DOMAIN_DUMP, map_domain_dump);
11254
11255   /* send it... */
11256   S;
11257
11258   /* Use a control ping for synchronization */
11259   {
11260     vl_api_control_ping_t *mp;
11261     M (CONTROL_PING, control_ping);
11262     S;
11263   }
11264   W;
11265 }
11266
11267 static int
11268 api_map_rule_dump (vat_main_t * vam)
11269 {
11270   unformat_input_t *i = vam->input;
11271   vl_api_map_rule_dump_t *mp;
11272   f64 timeout;
11273   u32 domain_index = ~0;
11274
11275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11276     {
11277       if (unformat (i, "index %u", &domain_index))
11278         ;
11279       else
11280         break;
11281     }
11282
11283   if (domain_index == ~0)
11284     {
11285       clib_warning ("parse error: domain index expected");
11286       return -99;
11287     }
11288
11289   /* Construct the API message */
11290   M (MAP_RULE_DUMP, map_rule_dump);
11291
11292   mp->domain_index = htonl (domain_index);
11293
11294   /* send it... */
11295   S;
11296
11297   /* Use a control ping for synchronization */
11298   {
11299     vl_api_control_ping_t *mp;
11300     M (CONTROL_PING, control_ping);
11301     S;
11302   }
11303   W;
11304 }
11305
11306 static void vl_api_map_add_domain_reply_t_handler
11307   (vl_api_map_add_domain_reply_t * mp)
11308 {
11309   vat_main_t *vam = &vat_main;
11310   i32 retval = ntohl (mp->retval);
11311
11312   if (vam->async_mode)
11313     {
11314       vam->async_errors += (retval < 0);
11315     }
11316   else
11317     {
11318       vam->retval = retval;
11319       vam->result_ready = 1;
11320     }
11321 }
11322
11323 static void vl_api_map_add_domain_reply_t_handler_json
11324   (vl_api_map_add_domain_reply_t * mp)
11325 {
11326   vat_main_t *vam = &vat_main;
11327   vat_json_node_t node;
11328
11329   vat_json_init_object (&node);
11330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11331   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11332
11333   vat_json_print (vam->ofp, &node);
11334   vat_json_free (&node);
11335
11336   vam->retval = ntohl (mp->retval);
11337   vam->result_ready = 1;
11338 }
11339
11340 static int
11341 api_get_first_msg_id (vat_main_t * vam)
11342 {
11343   vl_api_get_first_msg_id_t *mp;
11344   f64 timeout;
11345   unformat_input_t *i = vam->input;
11346   u8 *name;
11347   u8 name_set = 0;
11348
11349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11350     {
11351       if (unformat (i, "client %s", &name))
11352         name_set = 1;
11353       else
11354         break;
11355     }
11356
11357   if (name_set == 0)
11358     {
11359       errmsg ("missing client name\n");
11360       return -99;
11361     }
11362   vec_add1 (name, 0);
11363
11364   if (vec_len (name) > 63)
11365     {
11366       errmsg ("client name too long\n");
11367       return -99;
11368     }
11369
11370   M (GET_FIRST_MSG_ID, get_first_msg_id);
11371   clib_memcpy (mp->name, name, vec_len (name));
11372   S;
11373   W;
11374   /* NOTREACHED */
11375   return 0;
11376 }
11377
11378 static int
11379 api_cop_interface_enable_disable (vat_main_t * vam)
11380 {
11381   unformat_input_t *line_input = vam->input;
11382   vl_api_cop_interface_enable_disable_t *mp;
11383   f64 timeout;
11384   u32 sw_if_index = ~0;
11385   u8 enable_disable = 1;
11386
11387   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11388     {
11389       if (unformat (line_input, "disable"))
11390         enable_disable = 0;
11391       if (unformat (line_input, "enable"))
11392         enable_disable = 1;
11393       else if (unformat (line_input, "%U", unformat_sw_if_index,
11394                          vam, &sw_if_index))
11395         ;
11396       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11397         ;
11398       else
11399         break;
11400     }
11401
11402   if (sw_if_index == ~0)
11403     {
11404       errmsg ("missing interface name or sw_if_index\n");
11405       return -99;
11406     }
11407
11408   /* Construct the API message */
11409   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11410   mp->sw_if_index = ntohl (sw_if_index);
11411   mp->enable_disable = enable_disable;
11412
11413   /* send it... */
11414   S;
11415   /* Wait for the reply */
11416   W;
11417 }
11418
11419 static int
11420 api_cop_whitelist_enable_disable (vat_main_t * vam)
11421 {
11422   unformat_input_t *line_input = vam->input;
11423   vl_api_cop_whitelist_enable_disable_t *mp;
11424   f64 timeout;
11425   u32 sw_if_index = ~0;
11426   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11427   u32 fib_id = 0;
11428
11429   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (line_input, "ip4"))
11432         ip4 = 1;
11433       else if (unformat (line_input, "ip6"))
11434         ip6 = 1;
11435       else if (unformat (line_input, "default"))
11436         default_cop = 1;
11437       else if (unformat (line_input, "%U", unformat_sw_if_index,
11438                          vam, &sw_if_index))
11439         ;
11440       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11441         ;
11442       else if (unformat (line_input, "fib-id %d", &fib_id))
11443         ;
11444       else
11445         break;
11446     }
11447
11448   if (sw_if_index == ~0)
11449     {
11450       errmsg ("missing interface name or sw_if_index\n");
11451       return -99;
11452     }
11453
11454   /* Construct the API message */
11455   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11456   mp->sw_if_index = ntohl (sw_if_index);
11457   mp->fib_id = ntohl (fib_id);
11458   mp->ip4 = ip4;
11459   mp->ip6 = ip6;
11460   mp->default_cop = default_cop;
11461
11462   /* send it... */
11463   S;
11464   /* Wait for the reply */
11465   W;
11466 }
11467
11468 static int
11469 api_get_node_graph (vat_main_t * vam)
11470 {
11471   vl_api_get_node_graph_t *mp;
11472   f64 timeout;
11473
11474   M (GET_NODE_GRAPH, get_node_graph);
11475
11476   /* send it... */
11477   S;
11478   /* Wait for the reply */
11479   W;
11480 }
11481
11482 /* *INDENT-OFF* */
11483 /** Used for parsing LISP eids */
11484 typedef CLIB_PACKED(struct{
11485   u8 addr[16];   /**< eid address */
11486   u32 len;       /**< prefix length if IP */
11487   u8 type;      /**< type of eid */
11488 }) lisp_eid_vat_t;
11489 /* *INDENT-ON* */
11490
11491 static uword
11492 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11493 {
11494   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11495
11496   memset (a, 0, sizeof (a[0]));
11497
11498   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11499     {
11500       a->type = 0;              /* ipv4 type */
11501     }
11502   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11503     {
11504       a->type = 1;              /* ipv6 type */
11505     }
11506   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11507     {
11508       a->type = 2;              /* mac type */
11509     }
11510   else
11511     {
11512       return 0;
11513     }
11514
11515   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11516     {
11517       return 0;
11518     }
11519
11520   return 1;
11521 }
11522
11523 static int
11524 lisp_eid_size_vat (u8 type)
11525 {
11526   switch (type)
11527     {
11528     case 0:
11529       return 4;
11530     case 1:
11531       return 16;
11532     case 2:
11533       return 6;
11534     }
11535   return 0;
11536 }
11537
11538 static void
11539 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11540 {
11541   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11542 }
11543
11544 /* *INDENT-OFF* */
11545 /** Used for transferring locators via VPP API */
11546 typedef CLIB_PACKED(struct
11547 {
11548   u32 sw_if_index; /**< locator sw_if_index */
11549   u8 priority; /**< locator priority */
11550   u8 weight;   /**< locator weight */
11551 }) ls_locator_t;
11552 /* *INDENT-ON* */
11553
11554 static int
11555 api_lisp_add_del_locator_set (vat_main_t * vam)
11556 {
11557   unformat_input_t *input = vam->input;
11558   vl_api_lisp_add_del_locator_set_t *mp;
11559   f64 timeout = ~0;
11560   u8 is_add = 1;
11561   u8 *locator_set_name = NULL;
11562   u8 locator_set_name_set = 0;
11563   ls_locator_t locator, *locators = 0;
11564   u32 sw_if_index, priority, weight;
11565
11566   /* Parse args required to build the message */
11567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11568     {
11569       if (unformat (input, "del"))
11570         {
11571           is_add = 0;
11572         }
11573       else if (unformat (input, "locator-set %s", &locator_set_name))
11574         {
11575           locator_set_name_set = 1;
11576         }
11577       else if (unformat (input, "sw_if_index %u p %u w %u",
11578                          &sw_if_index, &priority, &weight))
11579         {
11580           locator.sw_if_index = htonl (sw_if_index);
11581           locator.priority = priority;
11582           locator.weight = weight;
11583           vec_add1 (locators, locator);
11584         }
11585       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11586                          vam, &sw_if_index, &priority, &weight))
11587         {
11588           locator.sw_if_index = htonl (sw_if_index);
11589           locator.priority = priority;
11590           locator.weight = weight;
11591           vec_add1 (locators, locator);
11592         }
11593       else
11594         break;
11595     }
11596
11597   if (locator_set_name_set == 0)
11598     {
11599       errmsg ("missing locator-set name");
11600       vec_free (locators);
11601       return -99;
11602     }
11603
11604   if (vec_len (locator_set_name) > 64)
11605     {
11606       errmsg ("locator-set name too long\n");
11607       vec_free (locator_set_name);
11608       vec_free (locators);
11609       return -99;
11610     }
11611   vec_add1 (locator_set_name, 0);
11612
11613   /* Construct the API message */
11614   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11615
11616   mp->is_add = is_add;
11617   clib_memcpy (mp->locator_set_name, locator_set_name,
11618                vec_len (locator_set_name));
11619   vec_free (locator_set_name);
11620
11621   mp->locator_num = vec_len (locators);
11622   if (locators)
11623     clib_memcpy (mp->locators, locators,
11624                  (sizeof (ls_locator_t) * vec_len (locators)));
11625   vec_free (locators);
11626
11627   /* send it... */
11628   S;
11629
11630   /* Wait for a reply... */
11631   W;
11632
11633   /* NOTREACHED */
11634   return 0;
11635 }
11636
11637 static int
11638 api_lisp_add_del_locator (vat_main_t * vam)
11639 {
11640   unformat_input_t *input = vam->input;
11641   vl_api_lisp_add_del_locator_t *mp;
11642   f64 timeout = ~0;
11643   u32 tmp_if_index = ~0;
11644   u32 sw_if_index = ~0;
11645   u8 sw_if_index_set = 0;
11646   u8 sw_if_index_if_name_set = 0;
11647   u32 priority = ~0;
11648   u8 priority_set = 0;
11649   u32 weight = ~0;
11650   u8 weight_set = 0;
11651   u8 is_add = 1;
11652   u8 *locator_set_name = NULL;
11653   u8 locator_set_name_set = 0;
11654
11655   /* Parse args required to build the message */
11656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11657     {
11658       if (unformat (input, "del"))
11659         {
11660           is_add = 0;
11661         }
11662       else if (unformat (input, "locator-set %s", &locator_set_name))
11663         {
11664           locator_set_name_set = 1;
11665         }
11666       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11667                          &tmp_if_index))
11668         {
11669           sw_if_index_if_name_set = 1;
11670           sw_if_index = tmp_if_index;
11671         }
11672       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11673         {
11674           sw_if_index_set = 1;
11675           sw_if_index = tmp_if_index;
11676         }
11677       else if (unformat (input, "p %d", &priority))
11678         {
11679           priority_set = 1;
11680         }
11681       else if (unformat (input, "w %d", &weight))
11682         {
11683           weight_set = 1;
11684         }
11685       else
11686         break;
11687     }
11688
11689   if (locator_set_name_set == 0)
11690     {
11691       errmsg ("missing locator-set name");
11692       return -99;
11693     }
11694
11695   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11696     {
11697       errmsg ("missing sw_if_index");
11698       vec_free (locator_set_name);
11699       return -99;
11700     }
11701
11702   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11703     {
11704       errmsg ("cannot use both params interface name and sw_if_index");
11705       vec_free (locator_set_name);
11706       return -99;
11707     }
11708
11709   if (priority_set == 0)
11710     {
11711       errmsg ("missing locator-set priority\n");
11712       vec_free (locator_set_name);
11713       return -99;
11714     }
11715
11716   if (weight_set == 0)
11717     {
11718       errmsg ("missing locator-set weight\n");
11719       vec_free (locator_set_name);
11720       return -99;
11721     }
11722
11723   if (vec_len (locator_set_name) > 64)
11724     {
11725       errmsg ("locator-set name too long\n");
11726       vec_free (locator_set_name);
11727       return -99;
11728     }
11729   vec_add1 (locator_set_name, 0);
11730
11731   /* Construct the API message */
11732   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11733
11734   mp->is_add = is_add;
11735   mp->sw_if_index = ntohl (sw_if_index);
11736   mp->priority = priority;
11737   mp->weight = weight;
11738   clib_memcpy (mp->locator_set_name, locator_set_name,
11739                vec_len (locator_set_name));
11740   vec_free (locator_set_name);
11741
11742   /* send it... */
11743   S;
11744
11745   /* Wait for a reply... */
11746   W;
11747
11748   /* NOTREACHED */
11749   return 0;
11750 }
11751
11752 static int
11753 api_lisp_add_del_local_eid (vat_main_t * vam)
11754 {
11755   unformat_input_t *input = vam->input;
11756   vl_api_lisp_add_del_local_eid_t *mp;
11757   f64 timeout = ~0;
11758   u8 is_add = 1;
11759   u8 eid_set = 0;
11760   lisp_eid_vat_t _eid, *eid = &_eid;
11761   u8 *locator_set_name = 0;
11762   u8 locator_set_name_set = 0;
11763   u32 vni = 0;
11764
11765   /* Parse args required to build the message */
11766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11767     {
11768       if (unformat (input, "del"))
11769         {
11770           is_add = 0;
11771         }
11772       else if (unformat (input, "vni %d", &vni))
11773         {
11774           ;
11775         }
11776       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11777         {
11778           eid_set = 1;
11779         }
11780       else if (unformat (input, "locator-set %s", &locator_set_name))
11781         {
11782           locator_set_name_set = 1;
11783         }
11784       else
11785         break;
11786     }
11787
11788   if (locator_set_name_set == 0)
11789     {
11790       errmsg ("missing locator-set name\n");
11791       return -99;
11792     }
11793
11794   if (0 == eid_set)
11795     {
11796       errmsg ("EID address not set!");
11797       vec_free (locator_set_name);
11798       return -99;
11799     }
11800
11801   if (vec_len (locator_set_name) > 64)
11802     {
11803       errmsg ("locator-set name too long\n");
11804       vec_free (locator_set_name);
11805       return -99;
11806     }
11807   vec_add1 (locator_set_name, 0);
11808
11809   /* Construct the API message */
11810   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11811
11812   mp->is_add = is_add;
11813   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11814   mp->eid_type = eid->type;
11815   mp->prefix_len = eid->len;
11816   mp->vni = clib_host_to_net_u32 (vni);
11817   clib_memcpy (mp->locator_set_name, locator_set_name,
11818                vec_len (locator_set_name));
11819
11820   vec_free (locator_set_name);
11821
11822   /* send it... */
11823   S;
11824
11825   /* Wait for a reply... */
11826   W;
11827
11828   /* NOTREACHED */
11829   return 0;
11830 }
11831
11832 /* *INDENT-OFF* */
11833 /** Used for transferring locators via VPP API */
11834 typedef CLIB_PACKED(struct
11835 {
11836   u8 is_ip4; /**< is locator an IPv4 address? */
11837   u8 priority; /**< locator priority */
11838   u8 weight;   /**< locator weight */
11839   u8 addr[16]; /**< IPv4/IPv6 address */
11840 }) rloc_t;
11841 /* *INDENT-ON* */
11842
11843 static int
11844 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11845 {
11846   unformat_input_t *input = vam->input;
11847   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11848   f64 timeout = ~0;
11849   u8 is_add = 1;
11850   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11851   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11852   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11853   u32 action = ~0, p, w;
11854   ip4_address_t rmt_rloc4, lcl_rloc4;
11855   ip6_address_t rmt_rloc6, lcl_rloc6;
11856   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11857
11858   memset (&rloc, 0, sizeof (rloc));
11859
11860   /* Parse args required to build the message */
11861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11862     {
11863       if (unformat (input, "del"))
11864         {
11865           is_add = 0;
11866         }
11867       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11868         {
11869           rmt_eid_set = 1;
11870         }
11871       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11872         {
11873           lcl_eid_set = 1;
11874         }
11875       else if (unformat (input, "p %d w %d", &p, &w))
11876         {
11877           if (!curr_rloc)
11878             {
11879               errmsg ("No RLOC configured for setting priority/weight!");
11880               return -99;
11881             }
11882           curr_rloc->priority = p;
11883           curr_rloc->weight = w;
11884         }
11885       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11886                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11887         {
11888           rloc.is_ip4 = 1;
11889
11890           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11891           rloc.priority = rloc.weight = 0;
11892           vec_add1 (lcl_locs, rloc);
11893
11894           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11895           vec_add1 (rmt_locs, rloc);
11896           /* priority and weight saved in rmt loc */
11897           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11898         }
11899       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11900                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11901         {
11902           rloc.is_ip4 = 0;
11903           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11904           rloc.priority = rloc.weight = 0;
11905           vec_add1 (lcl_locs, rloc);
11906
11907           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
11908           vec_add1 (rmt_locs, rloc);
11909           /* priority and weight saved in rmt loc */
11910           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11911         }
11912       else if (unformat (input, "action %d", &action))
11913         {
11914           ;
11915         }
11916       else
11917         {
11918           clib_warning ("parse error '%U'", format_unformat_error, input);
11919           return -99;
11920         }
11921     }
11922
11923   if (!rmt_eid_set)
11924     {
11925       errmsg ("remote eid addresses not set\n");
11926       return -99;
11927     }
11928
11929   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
11930     {
11931       errmsg ("eid types don't match\n");
11932       return -99;
11933     }
11934
11935   if (0 == rmt_locs && (u32) ~ 0 == action)
11936     {
11937       errmsg ("action not set for negative mapping\n");
11938       return -99;
11939     }
11940
11941   /* Construct the API message */
11942   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
11943
11944   mp->is_add = is_add;
11945   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
11946   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
11947   mp->eid_type = rmt_eid->type;
11948   mp->rmt_len = rmt_eid->len;
11949   mp->lcl_len = lcl_eid->len;
11950   mp->action = action;
11951
11952   if (0 != rmt_locs && 0 != lcl_locs)
11953     {
11954       mp->loc_num = vec_len (rmt_locs);
11955       clib_memcpy (mp->lcl_locs, lcl_locs,
11956                    (sizeof (rloc_t) * vec_len (lcl_locs)));
11957       clib_memcpy (mp->rmt_locs, rmt_locs,
11958                    (sizeof (rloc_t) * vec_len (rmt_locs)));
11959     }
11960   vec_free (lcl_locs);
11961   vec_free (rmt_locs);
11962
11963   /* send it... */
11964   S;
11965
11966   /* Wait for a reply... */
11967   W;
11968
11969   /* NOTREACHED */
11970   return 0;
11971 }
11972
11973 static int
11974 api_lisp_add_del_map_resolver (vat_main_t * vam)
11975 {
11976   unformat_input_t *input = vam->input;
11977   vl_api_lisp_add_del_map_resolver_t *mp;
11978   f64 timeout = ~0;
11979   u8 is_add = 1;
11980   u8 ipv4_set = 0;
11981   u8 ipv6_set = 0;
11982   ip4_address_t ipv4;
11983   ip6_address_t ipv6;
11984
11985   /* Parse args required to build the message */
11986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11987     {
11988       if (unformat (input, "del"))
11989         {
11990           is_add = 0;
11991         }
11992       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
11993         {
11994           ipv4_set = 1;
11995         }
11996       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
11997         {
11998           ipv6_set = 1;
11999         }
12000       else
12001         break;
12002     }
12003
12004   if (ipv4_set && ipv6_set)
12005     {
12006       errmsg ("both eid v4 and v6 addresses set\n");
12007       return -99;
12008     }
12009
12010   if (!ipv4_set && !ipv6_set)
12011     {
12012       errmsg ("eid addresses not set\n");
12013       return -99;
12014     }
12015
12016   /* Construct the API message */
12017   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12018
12019   mp->is_add = is_add;
12020   if (ipv6_set)
12021     {
12022       mp->is_ipv6 = 1;
12023       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12024     }
12025   else
12026     {
12027       mp->is_ipv6 = 0;
12028       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12029     }
12030
12031   /* send it... */
12032   S;
12033
12034   /* Wait for a reply... */
12035   W;
12036
12037   /* NOTREACHED */
12038   return 0;
12039 }
12040
12041 static int
12042 api_lisp_gpe_enable_disable (vat_main_t * vam)
12043 {
12044   unformat_input_t *input = vam->input;
12045   vl_api_lisp_gpe_enable_disable_t *mp;
12046   f64 timeout = ~0;
12047   u8 is_set = 0;
12048   u8 is_en = 1;
12049
12050   /* Parse args required to build the message */
12051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12052     {
12053       if (unformat (input, "enable"))
12054         {
12055           is_set = 1;
12056           is_en = 1;
12057         }
12058       else if (unformat (input, "disable"))
12059         {
12060           is_set = 1;
12061           is_en = 0;
12062         }
12063       else
12064         break;
12065     }
12066
12067   if (is_set == 0)
12068     {
12069       errmsg ("Value not set\n");
12070       return -99;
12071     }
12072
12073   /* Construct the API message */
12074   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12075
12076   mp->is_en = is_en;
12077
12078   /* send it... */
12079   S;
12080
12081   /* Wait for a reply... */
12082   W;
12083
12084   /* NOTREACHED */
12085   return 0;
12086 }
12087
12088 static int
12089 api_lisp_enable_disable (vat_main_t * vam)
12090 {
12091   unformat_input_t *input = vam->input;
12092   vl_api_lisp_enable_disable_t *mp;
12093   f64 timeout = ~0;
12094   u8 is_set = 0;
12095   u8 is_en = 0;
12096
12097   /* Parse args required to build the message */
12098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12099     {
12100       if (unformat (input, "enable"))
12101         {
12102           is_set = 1;
12103           is_en = 1;
12104         }
12105       else if (unformat (input, "disable"))
12106         {
12107           is_set = 1;
12108         }
12109       else
12110         break;
12111     }
12112
12113   if (!is_set)
12114     {
12115       errmsg ("Value not set\n");
12116       return -99;
12117     }
12118
12119   /* Construct the API message */
12120   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12121
12122   mp->is_en = is_en;
12123
12124   /* send it... */
12125   S;
12126
12127   /* Wait for a reply... */
12128   W;
12129
12130   /* NOTREACHED */
12131   return 0;
12132 }
12133
12134 /**
12135  * Enable/disable LISP proxy ITR.
12136  *
12137  * @param vam vpp API test context
12138  * @return return code
12139  */
12140 static int
12141 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12142 {
12143   f64 timeout = ~0;
12144   u8 ls_name_set = 0;
12145   unformat_input_t *input = vam->input;
12146   vl_api_lisp_pitr_set_locator_set_t *mp;
12147   u8 is_add = 1;
12148   u8 *ls_name = 0;
12149
12150   /* Parse args required to build the message */
12151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12152     {
12153       if (unformat (input, "del"))
12154         is_add = 0;
12155       else if (unformat (input, "locator-set %s", &ls_name))
12156         ls_name_set = 1;
12157       else
12158         {
12159           errmsg ("parse error '%U'", format_unformat_error, input);
12160           return -99;
12161         }
12162     }
12163
12164   if (!ls_name_set)
12165     {
12166       errmsg ("locator-set name not set!");
12167       return -99;
12168     }
12169
12170   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12171
12172   mp->is_add = is_add;
12173   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12174   vec_free (ls_name);
12175
12176   /* send */
12177   S;
12178
12179   /* wait for reply */
12180   W;
12181
12182   /* notreached */
12183   return 0;
12184 }
12185
12186 static int
12187 api_show_lisp_pitr (vat_main_t * vam)
12188 {
12189   vl_api_show_lisp_pitr_t *mp;
12190   f64 timeout = ~0;
12191
12192   if (!vam->json_output)
12193     {
12194       fformat (vam->ofp, "%=20s\n", "lisp status:");
12195     }
12196
12197   M (SHOW_LISP_PITR, show_lisp_pitr);
12198   /* send it... */
12199   S;
12200
12201   /* Wait for a reply... */
12202   W;
12203
12204   /* NOTREACHED */
12205   return 0;
12206 }
12207
12208 /**
12209  * Add/delete mapping between vni and vrf
12210  */
12211 static int
12212 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12213 {
12214   f64 timeout = ~0;
12215   unformat_input_t *input = vam->input;
12216   vl_api_lisp_eid_table_add_del_map_t *mp;
12217   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12218   u32 vni, vrf, bd_index;
12219
12220   /* Parse args required to build the message */
12221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12222     {
12223       if (unformat (input, "del"))
12224         is_add = 0;
12225       else if (unformat (input, "vrf %d", &vrf))
12226         vrf_set = 1;
12227       else if (unformat (input, "bd_index %d", &bd_index))
12228         bd_index_set = 1;
12229       else if (unformat (input, "vni %d", &vni))
12230         vni_set = 1;
12231       else
12232         break;
12233     }
12234
12235   if (!vni_set || (!vrf_set && !bd_index_set))
12236     {
12237       errmsg ("missing arguments!");
12238       return -99;
12239     }
12240
12241   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12242
12243   mp->is_add = is_add;
12244   mp->vni = htonl (vni);
12245   mp->dp_table = htonl (vrf);
12246   mp->is_l2 = bd_index_set;
12247
12248   /* send */
12249   S;
12250
12251   /* wait for reply */
12252   W;
12253
12254   /* notreached */
12255   return 0;
12256 }
12257
12258 /**
12259  * Add/del remote mapping to/from LISP control plane
12260  *
12261  * @param vam vpp API test context
12262  * @return return code
12263  */
12264 static int
12265 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12266 {
12267   unformat_input_t *input = vam->input;
12268   vl_api_lisp_add_del_remote_mapping_t *mp;
12269   f64 timeout = ~0;
12270   u32 vni = 0;
12271   //TODO: seid need remove
12272   lisp_eid_vat_t _eid, *eid = &_eid;
12273   lisp_eid_vat_t _seid, *seid = &_seid;
12274   u8 is_add = 1, del_all = 0, eid_set = 0;
12275   u32 action = ~0, p, w;
12276   ip4_address_t rloc4;
12277   ip6_address_t rloc6;
12278   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12279
12280   memset (&rloc, 0, sizeof (rloc));
12281
12282   /* Parse args required to build the message */
12283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12284     {
12285       if (unformat (input, "del-all"))
12286         {
12287           del_all = 1;
12288         }
12289       else if (unformat (input, "del"))
12290         {
12291           is_add = 0;
12292         }
12293       else if (unformat (input, "add"))
12294         {
12295           is_add = 1;
12296         }
12297       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12298         {
12299           eid_set = 1;
12300         }
12301       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12302         {
12303           //TODO: Need remove, but first must be remove from CSIT test
12304         }
12305       else if (unformat (input, "vni %d", &vni))
12306         {
12307           ;
12308         }
12309       else if (unformat (input, "p %d w %d", &p, &w))
12310         {
12311           if (!curr_rloc)
12312             {
12313               errmsg ("No RLOC configured for setting priority/weight!");
12314               return -99;
12315             }
12316           curr_rloc->priority = p;
12317           curr_rloc->weight = w;
12318         }
12319       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12320         {
12321           rloc.is_ip4 = 1;
12322           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12323           vec_add1 (rlocs, rloc);
12324           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12325         }
12326       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12327         {
12328           rloc.is_ip4 = 0;
12329           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12330           vec_add1 (rlocs, rloc);
12331           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12332         }
12333       else if (unformat (input, "action %d", &action))
12334         {
12335           ;
12336         }
12337       else
12338         {
12339           clib_warning ("parse error '%U'", format_unformat_error, input);
12340           return -99;
12341         }
12342     }
12343
12344   if (0 == eid_set)
12345     {
12346       errmsg ("missing params!");
12347       return -99;
12348     }
12349
12350   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12351     {
12352       errmsg ("no action set for negative map-reply!");
12353       return -99;
12354     }
12355
12356   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12357   mp->is_add = is_add;
12358   mp->vni = htonl (vni);
12359   mp->action = (u8) action;
12360   mp->eid_len = eid->len;
12361   mp->del_all = del_all;
12362   mp->eid_type = eid->type;
12363   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12364
12365   mp->rloc_num = vec_len (rlocs);
12366   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12367   vec_free (rlocs);
12368
12369   /* send it... */
12370   S;
12371
12372   /* Wait for a reply... */
12373   W;
12374
12375   /* NOTREACHED */
12376   return 0;
12377 }
12378
12379 /**
12380  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12381  * forwarding entries in data-plane accordingly.
12382  *
12383  * @param vam vpp API test context
12384  * @return return code
12385  */
12386 static int
12387 api_lisp_add_del_adjacency (vat_main_t * vam)
12388 {
12389   unformat_input_t *input = vam->input;
12390   vl_api_lisp_add_del_adjacency_t *mp;
12391   f64 timeout = ~0;
12392   u32 vni = 0;
12393   ip4_address_t seid4, deid4;
12394   ip6_address_t seid6, deid6;
12395   u8 deid_mac[6] = { 0 };
12396   u8 seid_mac[6] = { 0 };
12397   u8 deid_type, seid_type;
12398   u32 seid_len = 0, deid_len = 0, len;
12399   u8 is_add = 1;
12400
12401   seid_type = deid_type = (u8) ~ 0;
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, "add"))
12411         {
12412           is_add = 1;
12413         }
12414       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12415                          &deid4, &len))
12416         {
12417           deid_type = 0;        /* ipv4 */
12418           deid_len = len;
12419         }
12420       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12421                          &deid6, &len))
12422         {
12423           deid_type = 1;        /* ipv6 */
12424           deid_len = len;
12425         }
12426       else if (unformat (input, "deid %U", unformat_ethernet_address,
12427                          deid_mac))
12428         {
12429           deid_type = 2;        /* mac */
12430         }
12431       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12432                          &seid4, &len))
12433         {
12434           seid_type = 0;        /* ipv4 */
12435           seid_len = len;
12436         }
12437       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12438                          &seid6, &len))
12439         {
12440           seid_type = 1;        /* ipv6 */
12441           seid_len = len;
12442         }
12443       else if (unformat (input, "seid %U", unformat_ethernet_address,
12444                          seid_mac))
12445         {
12446           seid_type = 2;        /* mac */
12447         }
12448       else if (unformat (input, "vni %d", &vni))
12449         {
12450           ;
12451         }
12452       else
12453         {
12454           errmsg ("parse error '%U'", format_unformat_error, input);
12455           return -99;
12456         }
12457     }
12458
12459   if ((u8) ~ 0 == deid_type)
12460     {
12461       errmsg ("missing params!");
12462       return -99;
12463     }
12464
12465   if (seid_type != deid_type)
12466     {
12467       errmsg ("source and destination EIDs are of different types!");
12468       return -99;
12469     }
12470
12471   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12472   mp->is_add = is_add;
12473   mp->vni = htonl (vni);
12474   mp->seid_len = seid_len;
12475   mp->deid_len = deid_len;
12476   mp->eid_type = deid_type;
12477
12478   switch (mp->eid_type)
12479     {
12480     case 0:
12481       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12482       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12483       break;
12484     case 1:
12485       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12486       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12487       break;
12488     case 2:
12489       clib_memcpy (mp->seid, seid_mac, 6);
12490       clib_memcpy (mp->deid, deid_mac, 6);
12491       break;
12492     default:
12493       errmsg ("unknown EID type %d!", mp->eid_type);
12494       return 0;
12495     }
12496
12497   /* send it... */
12498   S;
12499
12500   /* Wait for a reply... */
12501   W;
12502
12503   /* NOTREACHED */
12504   return 0;
12505 }
12506
12507 static int
12508 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12509 {
12510   unformat_input_t *input = vam->input;
12511   vl_api_lisp_gpe_add_del_iface_t *mp;
12512   f64 timeout = ~0;
12513   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12514   u32 dp_table = 0, vni = 0;
12515
12516   /* Parse args required to build the message */
12517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12518     {
12519       if (unformat (input, "up"))
12520         {
12521           action_set = 1;
12522           is_add = 1;
12523         }
12524       else if (unformat (input, "down"))
12525         {
12526           action_set = 1;
12527           is_add = 0;
12528         }
12529       else if (unformat (input, "table_id %d", &dp_table))
12530         {
12531           dp_table_set = 1;
12532         }
12533       else if (unformat (input, "bd_id %d", &dp_table))
12534         {
12535           dp_table_set = 1;
12536           is_l2 = 1;
12537         }
12538       else if (unformat (input, "vni %d", &vni))
12539         {
12540           vni_set = 1;
12541         }
12542       else
12543         break;
12544     }
12545
12546   if (action_set == 0)
12547     {
12548       errmsg ("Action not set\n");
12549       return -99;
12550     }
12551   if (dp_table_set == 0 || vni_set == 0)
12552     {
12553       errmsg ("vni and dp_table must be set\n");
12554       return -99;
12555     }
12556
12557   /* Construct the API message */
12558   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12559
12560   mp->is_add = is_add;
12561   mp->dp_table = dp_table;
12562   mp->is_l2 = is_l2;
12563   mp->vni = vni;
12564
12565   /* send it... */
12566   S;
12567
12568   /* Wait for a reply... */
12569   W;
12570
12571   /* NOTREACHED */
12572   return 0;
12573 }
12574
12575 /**
12576  * Add/del map request itr rlocs from LISP control plane and updates
12577  *
12578  * @param vam vpp API test context
12579  * @return return code
12580  */
12581 static int
12582 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12583 {
12584   unformat_input_t *input = vam->input;
12585   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12586   f64 timeout = ~0;
12587   u8 *locator_set_name = 0;
12588   u8 locator_set_name_set = 0;
12589   u8 is_add = 1;
12590
12591   /* Parse args required to build the message */
12592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12593     {
12594       if (unformat (input, "del"))
12595         {
12596           is_add = 0;
12597         }
12598       else if (unformat (input, "%_%v%_", &locator_set_name))
12599         {
12600           locator_set_name_set = 1;
12601         }
12602       else
12603         {
12604           clib_warning ("parse error '%U'", format_unformat_error, input);
12605           return -99;
12606         }
12607     }
12608
12609   if (is_add && !locator_set_name_set)
12610     {
12611       errmsg ("itr-rloc is not set!");
12612       return -99;
12613     }
12614
12615   if (is_add && vec_len (locator_set_name) > 64)
12616     {
12617       errmsg ("itr-rloc locator-set name too long\n");
12618       vec_free (locator_set_name);
12619       return -99;
12620     }
12621
12622   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12623   mp->is_add = is_add;
12624   if (is_add)
12625     {
12626       clib_memcpy (mp->locator_set_name, locator_set_name,
12627                    vec_len (locator_set_name));
12628     }
12629   else
12630     {
12631       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12632     }
12633   vec_free (locator_set_name);
12634
12635   /* send it... */
12636   S;
12637
12638   /* Wait for a reply... */
12639   W;
12640
12641   /* NOTREACHED */
12642   return 0;
12643 }
12644
12645 static int
12646 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12647                             u8 filter)
12648 {
12649   vl_api_lisp_locator_dump_t *mp;
12650   f64 timeout = ~0;
12651
12652   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12653
12654   mp->locator_set_index = htonl (locator_set_index);
12655   mp->filter = filter;
12656
12657   /* send it... */
12658   S;
12659
12660   /* Use a control ping for synchronization */
12661   {
12662     vl_api_noprint_control_ping_t *mp;
12663     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12664     S;
12665   }
12666   /* Wait for a reply... */
12667   W;
12668 }
12669
12670 static inline void
12671 clean_locator_set_message (vat_main_t * vam)
12672 {
12673   locator_set_msg_t *ls = 0;
12674
12675   vec_foreach (ls, vam->locator_set_msg)
12676   {
12677     vec_free (ls->locator_set_name);
12678   }
12679
12680   vec_free (vam->locator_set_msg);
12681 }
12682
12683 static int
12684 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12685 {
12686   locator_set_msg_t *ls;
12687   locator_msg_t *loc;
12688   u8 *tmp_str = 0;
12689   int i = 0, ret = 0;
12690
12691   vec_foreach (ls, vam->locator_set_msg)
12692   {
12693     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12694     if (ret)
12695       {
12696         vec_free (vam->locator_msg);
12697         clean_locator_set_message (vam);
12698         return ret;
12699       }
12700
12701     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12702                       ls->locator_set_index,
12703                       vec_len (vam->locator_msg) ? "" : "\n");
12704     i = 0;
12705     vec_foreach (loc, vam->locator_msg)
12706     {
12707       if (i)
12708         {
12709           tmp_str = format (tmp_str, "%=37s", " ");
12710         }
12711       if (loc->local)
12712         {
12713           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12714                             loc->sw_if_index, loc->priority, loc->weight);
12715         }
12716       else
12717         {
12718           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12719                             loc->is_ipv6 ? format_ip6_address :
12720                             format_ip4_address,
12721                             loc->ip_address, loc->priority, loc->weight);
12722         }
12723       i++;
12724     }
12725
12726     fformat (vam->ofp, "%s", tmp_str);
12727     vec_free (tmp_str);
12728     vec_free (vam->locator_msg);
12729   }
12730
12731   clean_locator_set_message (vam);
12732
12733   return ret;
12734 }
12735
12736 static int
12737 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12738 {
12739   locator_set_msg_t *ls;
12740   locator_msg_t *loc;
12741   vat_json_node_t *node = NULL;
12742   vat_json_node_t *locator_array;
12743   vat_json_node_t *locator;
12744   struct in6_addr ip6;
12745   struct in_addr ip4;
12746   int ret = 0;
12747
12748   if (!vec_len (vam->locator_set_msg))
12749     {
12750       /* just print [] */
12751       vat_json_init_array (&vam->json_tree);
12752       vat_json_print (vam->ofp, &vam->json_tree);
12753       vam->json_tree.type = VAT_JSON_NONE;
12754       return ret;
12755     }
12756
12757   if (VAT_JSON_ARRAY != vam->json_tree.type)
12758     {
12759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12760       vat_json_init_array (&vam->json_tree);
12761     }
12762
12763   vec_foreach (ls, vam->locator_set_msg)
12764   {
12765     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12766     if (ret)
12767       {
12768         vec_free (ls->locator_set_name);
12769         vec_free (vam->locator_msg);
12770         vec_free (vam->locator_set_msg);
12771         vat_json_free (&vam->json_tree);
12772         vam->json_tree.type = VAT_JSON_NONE;
12773         return ret;
12774       }
12775
12776     node = vat_json_array_add (&vam->json_tree);
12777     vat_json_init_object (node);
12778
12779     vat_json_object_add_uint (node, "locator-set-index",
12780                               ls->locator_set_index);
12781     vat_json_object_add_string_copy (node, "locator-set",
12782                                      ls->locator_set_name);
12783     locator_array = vat_json_object_add_list (node, "locator");
12784     vec_foreach (loc, vam->locator_msg)
12785     {
12786       locator = vat_json_array_add (locator_array);
12787       vat_json_init_object (locator);
12788       if (loc->local)
12789         {
12790           vat_json_object_add_uint (locator, "locator-index",
12791                                     loc->sw_if_index);
12792         }
12793       else
12794         {
12795           if (loc->is_ipv6)
12796             {
12797               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12798               vat_json_object_add_ip6 (locator, "locator", ip6);
12799             }
12800           else
12801             {
12802               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12803               vat_json_object_add_ip4 (locator, "locator", ip4);
12804             }
12805         }
12806       vat_json_object_add_uint (locator, "priority", loc->priority);
12807       vat_json_object_add_uint (locator, "weight", loc->weight);
12808     }
12809
12810     vec_free (ls->locator_set_name);
12811     vec_free (vam->locator_msg);
12812   }
12813
12814   vat_json_print (vam->ofp, &vam->json_tree);
12815   vat_json_free (&vam->json_tree);
12816   vam->json_tree.type = VAT_JSON_NONE;
12817
12818   vec_free (vam->locator_set_msg);
12819
12820   return ret;
12821 }
12822
12823 static int
12824 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12825                                 u32 * locator_set_index)
12826 {
12827   locator_set_msg_t *ls;
12828   int ret = 0;
12829
12830   *locator_set_index = ~0;
12831
12832   if (!vec_len (vam->locator_set_msg))
12833     {
12834       return ret;
12835     }
12836
12837   vec_foreach (ls, vam->locator_set_msg)
12838   {
12839     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12840       {
12841         *locator_set_index = ls->locator_set_index;
12842         vec_free (vam->locator_set_msg);
12843         return ret;
12844       }
12845   }
12846
12847   vec_free (vam->locator_set_msg);
12848
12849   return ret;
12850 }
12851
12852 static int
12853 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12854                        u32 * locator_set_index)
12855 {
12856   vl_api_lisp_locator_set_dump_t *mp;
12857   f64 timeout = ~0;
12858
12859   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12860   /* send it... */
12861   S;
12862
12863   /* Use a control ping for synchronization */
12864   {
12865     vl_api_noprint_control_ping_t *mp;
12866     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12867     S;
12868   }
12869
12870   vam->noprint_msg = 1;
12871   /* Wait for a reply... */
12872   /* *INDENT-OFF* */
12873   W_L
12874   ({
12875     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12876     vam->noprint_msg = 0;
12877   });
12878   /* *INDENT-ON* */
12879
12880   /* NOTREACHED */
12881   return 0;
12882 }
12883
12884 static inline int
12885 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12886                    u8 filter)
12887 {
12888   int ret = 0;
12889
12890   ASSERT (vam);
12891
12892   if (!vam->json_output)
12893     {
12894       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12895                "locator", "priority", "weight");
12896     }
12897
12898   if (locator_set)
12899     {
12900       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
12901     }
12902
12903   if (!ret && ~0 == locator_set_index)
12904     {
12905       return -99;
12906     }
12907
12908   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
12909
12910   return ret;
12911 }
12912
12913 static int
12914 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
12915 {
12916   vl_api_lisp_locator_set_dump_t *mp;
12917   f64 timeout = ~0;
12918
12919   if (!vam->json_output)
12920     {
12921       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
12922                "locator-set", "locator-set-index", "locator", "priority",
12923                "weight");
12924     }
12925
12926   vam->noprint_msg = 1;
12927
12928   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12929
12930   mp->filter = filter;
12931
12932   /* send it... */
12933   S;
12934
12935   /* Use a control ping for synchronization */
12936   {
12937     vl_api_noprint_control_ping_t *mp;
12938     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12939     S;
12940   }
12941
12942   /* Wait for a reply... */
12943   /* *INDENT-OFF* */
12944   W_L
12945   ({
12946     if (vam->noprint_msg)
12947       {
12948         if (!vam->json_output)
12949           {
12950             print_locator_in_locator_set(vam, filter);
12951           }
12952         else
12953           {
12954             json_locator_in_locator_set(vam, filter);
12955           }
12956       }
12957     vam->noprint_msg = 0;
12958   });
12959   /* *INDENT-ON* */
12960
12961   /* NOTREACHED */
12962   return 0;
12963 }
12964
12965 static int
12966 api_lisp_locator_set_dump (vat_main_t * vam)
12967 {
12968   unformat_input_t *input = vam->input;
12969   vam->noprint_msg = 0;
12970   u32 locator_set_index = ~0;
12971   u8 locator_set_index_set = 0;
12972   u8 *locator_set = 0;
12973   u8 locator_set_set = 0;
12974   u8 filter = 0;
12975   int ret = 0;
12976
12977   /* Parse args required to build the message */
12978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12979     {
12980       if (unformat (input, "locator-set-index %u", &locator_set_index))
12981         {
12982           locator_set_index_set = 1;
12983         }
12984       else if (unformat (input, "locator-set %s", &locator_set))
12985         {
12986           locator_set_set = 1;
12987         }
12988       else if (unformat (input, "local"))
12989         {
12990           filter = 1;
12991         }
12992       else if (unformat (input, "remote"))
12993         {
12994           filter = 2;
12995         }
12996       else
12997         {
12998           break;
12999         }
13000     }
13001
13002   if (locator_set_index_set && locator_set_set)
13003     {
13004       errmsg ("use only input parameter!\n");
13005       return -99;
13006     }
13007
13008   if (locator_set_index_set || locator_set_set)
13009     {
13010       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13011     }
13012   else
13013     {
13014       ret = lisp_locator_set_dump (vam, filter);
13015     }
13016
13017   vec_free (locator_set);
13018
13019   return ret;
13020 }
13021
13022 static int
13023 api_lisp_eid_table_map_dump (vat_main_t * vam)
13024 {
13025   vl_api_lisp_eid_table_map_dump_t *mp;
13026   f64 timeout = ~0;
13027
13028   if (!vam->json_output)
13029     {
13030       fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
13031     }
13032
13033   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13034
13035   /* send it... */
13036   S;
13037
13038   /* Use a control ping for synchronization */
13039   {
13040     vl_api_control_ping_t *mp;
13041     M (CONTROL_PING, control_ping);
13042     S;
13043   }
13044   /* Wait for a reply... */
13045   W;
13046
13047   /* NOTREACHED */
13048   return 0;
13049 }
13050
13051 static int
13052 get_locator_set (vat_main_t * vam)
13053 {
13054   vl_api_lisp_locator_set_dump_t *mp;
13055   f64 timeout = ~0;
13056
13057   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13058   /* send it... */
13059   S;
13060
13061   /* Use a control ping for synchronization */
13062   {
13063     vl_api_noprint_control_ping_t *mp;
13064     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13065     S;
13066   }
13067
13068   /* Wait for a reply... */
13069   W;
13070
13071   /* NOTREACHED */
13072   return 0;
13073 }
13074
13075 static inline u8 *
13076 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13077                           int *ret)
13078 {
13079   u8 *(*format_eid) (u8 *, va_list *) = 0;
13080
13081   ASSERT (vam != NULL);
13082   ASSERT (eid_table != NULL);
13083
13084   if (ret)
13085     {
13086       *ret = 0;
13087     }
13088
13089   switch (eid_table->eid_type)
13090     {
13091     case 0:
13092     case 1:
13093       format_eid = (eid_table->eid_type ? format_ip6_address :
13094                     format_ip4_address);
13095       str = format (0, "[%d] %U/%d",
13096                     clib_net_to_host_u32 (eid_table->vni),
13097                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13098       break;
13099     case 2:
13100       str = format (0, "[%d] %U",
13101                     clib_net_to_host_u32 (eid_table->vni),
13102                     format_ethernet_address, eid_table->eid);
13103       break;
13104     default:
13105       errmsg ("unknown EID type %d!", eid_table->eid_type);
13106       if (ret)
13107         {
13108           *ret = -99;
13109         }
13110       return 0;
13111     }
13112
13113   return str;
13114 }
13115
13116 static inline u8 *
13117 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13118                                   eid_table_t * eid_table)
13119 {
13120   locator_set_msg_t *ls = 0;
13121
13122   ASSERT (vam != NULL);
13123   ASSERT (eid_table != NULL);
13124
13125   if (eid_table->is_local)
13126     {
13127       vec_foreach (ls, vam->locator_set_msg)
13128       {
13129         if (ls->locator_set_index == eid_table->locator_set_index)
13130           {
13131             str = format (0, "local(%s)", ls->locator_set_name);
13132             return str;
13133           }
13134       }
13135
13136       str = format (0, "local(N/A)");
13137     }
13138   else
13139     {
13140       str = format (0, "remote");
13141     }
13142
13143   return str;
13144 }
13145
13146 static inline u8 *
13147 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13148                               eid_table_t * eid_table)
13149 {
13150   locator_msg_t *loc = 0;
13151   int first_line = 1;
13152
13153   ASSERT (vam != NULL);
13154   ASSERT (eid_table != NULL);
13155
13156   vec_foreach (loc, vam->locator_msg)
13157   {
13158     if (!first_line)
13159       {
13160         if (loc->local)
13161           {
13162             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13163           }
13164         else
13165           {
13166             str = format (str, "%=55s%-U\n", " ",
13167                           loc->is_ipv6 ? format_ip6_address :
13168                           format_ip4_address, loc->ip_address);
13169           }
13170
13171         continue;
13172       }
13173
13174     if (loc->local)
13175       {
13176         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13177                       eid_table->ttl, eid_table->authoritative);
13178       }
13179     else
13180       {
13181         str = format (str, "%-30U%-20u%-u\n",
13182                       loc->is_ipv6 ? format_ip6_address :
13183                       format_ip4_address,
13184                       loc->ip_address, eid_table->ttl,
13185                       eid_table->authoritative);
13186       }
13187     first_line = 0;
13188   }
13189
13190   return str;
13191 }
13192
13193 static int
13194 print_lisp_eid_table_dump (vat_main_t * vam)
13195 {
13196   eid_table_t *eid_table = 0;
13197   u8 *tmp_str = 0, *tmp_str2 = 0;
13198   int ret = 0;
13199
13200   ASSERT (vam != NULL);
13201
13202   ret = get_locator_set (vam);
13203   if (ret)
13204     {
13205       vec_free (vam->eid_tables);
13206       return ret;
13207     }
13208
13209   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13210            "ttl", "authoritative");
13211
13212   vec_foreach (eid_table, vam->eid_tables)
13213   {
13214     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13215     if (ret)
13216       {
13217         vec_free (vam->locator_msg);
13218         clean_locator_set_message (vam);
13219         vec_free (vam->eid_tables);
13220         return ret;
13221       }
13222
13223     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13224     if (ret)
13225       {
13226         vec_free (vam->locator_msg);
13227         clean_locator_set_message (vam);
13228         vec_free (vam->eid_tables);
13229         return ret;
13230       }
13231
13232     tmp_str = format (0, "%-35s", tmp_str2);
13233     vec_free (tmp_str2);
13234
13235     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13236     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13237     vec_free (tmp_str2);
13238
13239     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13240     tmp_str = format (tmp_str, "%-s", tmp_str2);
13241     vec_free (tmp_str2);
13242
13243     fformat (vam->ofp, "%s", tmp_str);
13244     vec_free (tmp_str);
13245     vec_free (vam->locator_msg);
13246   }
13247
13248   clean_locator_set_message (vam);
13249   vec_free (vam->eid_tables);
13250
13251   return ret;
13252 }
13253
13254 static inline void
13255 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13256                                 eid_table_t * eid_table)
13257 {
13258   locator_set_msg_t *ls = 0;
13259   u8 *s = 0;
13260
13261   ASSERT (vam != NULL);
13262   ASSERT (node != NULL);
13263   ASSERT (eid_table != NULL);
13264
13265   if (eid_table->is_local)
13266     {
13267       vec_foreach (ls, vam->locator_set_msg)
13268       {
13269         if (ls->locator_set_index == eid_table->locator_set_index)
13270           {
13271             vat_json_object_add_string_copy (node, "locator-set",
13272                                              ls->locator_set_name);
13273             return;
13274           }
13275       }
13276
13277       s = format (0, "N/A");
13278       vec_add1 (s, 0);
13279       vat_json_object_add_string_copy (node, "locator-set", s);
13280       vec_free (s);
13281     }
13282   else
13283     {
13284       s = format (0, "remote");
13285       vec_add1 (s, 0);
13286       vat_json_object_add_string_copy (node, "locator-set", s);
13287       vec_free (s);
13288     }
13289 }
13290
13291 static inline int
13292 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13293                         eid_table_t * eid_table)
13294 {
13295   u8 *s = 0;
13296   struct in6_addr ip6;
13297   struct in_addr ip4;
13298
13299   ASSERT (vam != NULL);
13300   ASSERT (node != NULL);
13301   ASSERT (eid_table != NULL);
13302
13303   switch (eid_table->eid_type)
13304     {
13305     case 0:
13306       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13307       vat_json_object_add_ip4 (node, "eid", ip4);
13308       vat_json_object_add_uint (node, "eid-prefix-len",
13309                                 eid_table->eid_prefix_len);
13310       break;
13311     case 1:
13312       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13313       vat_json_object_add_ip6 (node, "eid", ip6);
13314       vat_json_object_add_uint (node, "eid-prefix-len",
13315                                 eid_table->eid_prefix_len);
13316       break;
13317     case 2:
13318       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13319       vec_add1 (s, 0);
13320       vat_json_object_add_string_copy (node, "eid", s);
13321       vec_free (s);
13322       break;
13323     default:
13324       errmsg ("unknown EID type %d!", eid_table->eid_type);
13325       return -99;
13326     }
13327
13328   return 0;
13329 }
13330
13331 static inline void
13332 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13333                             eid_table_t * eid_table)
13334 {
13335   locator_msg_t *loc = 0;
13336   vat_json_node_t *locator_array = 0;
13337   vat_json_node_t *locator = 0;
13338   struct in6_addr ip6;
13339   struct in_addr ip4;
13340
13341   ASSERT (vam != NULL);
13342   ASSERT (node != NULL);
13343   ASSERT (eid_table != NULL);
13344
13345   locator_array = vat_json_object_add_list (node, "locator");
13346   vec_foreach (loc, vam->locator_msg)
13347   {
13348     locator = vat_json_array_add (locator_array);
13349     vat_json_init_object (locator);
13350     if (loc->local)
13351       {
13352         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13353       }
13354     else
13355       {
13356         if (loc->is_ipv6)
13357           {
13358             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13359             vat_json_object_add_ip6 (locator, "locator", ip6);
13360           }
13361         else
13362           {
13363             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13364             vat_json_object_add_ip4 (locator, "locator", ip4);
13365           }
13366       }
13367   }
13368 }
13369
13370 static int
13371 json_lisp_eid_table_dump (vat_main_t * vam)
13372 {
13373   eid_table_t *eid_table;
13374   vat_json_node_t *node = 0;
13375   int ret = 0;
13376
13377   ASSERT (vam != NULL);
13378
13379   ret = get_locator_set (vam);
13380   if (ret)
13381     {
13382       vec_free (vam->eid_tables);
13383       return ret;
13384     }
13385
13386   if (!vec_len (vam->eid_tables))
13387     {
13388       /* just print [] */
13389       vat_json_init_array (&vam->json_tree);
13390       vat_json_print (vam->ofp, &vam->json_tree);
13391       vam->json_tree.type = VAT_JSON_NONE;
13392       return ret;
13393     }
13394
13395   if (VAT_JSON_ARRAY != vam->json_tree.type)
13396     {
13397       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13398       vat_json_init_array (&vam->json_tree);
13399     }
13400
13401   vec_foreach (eid_table, vam->eid_tables)
13402   {
13403     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13404     if (ret)
13405       {
13406         vec_free (vam->locator_msg);
13407         vec_free (vam->eid_tables);
13408         clean_locator_set_message (vam);
13409         vat_json_free (&vam->json_tree);
13410         vam->json_tree.type = VAT_JSON_NONE;
13411         return ret;
13412       }
13413
13414     node = vat_json_array_add (&vam->json_tree);
13415     vat_json_init_object (node);
13416
13417     vat_json_object_add_uint (node, "vni", eid_table->vni);
13418
13419     json_locator_set_for_eid_table (vam, node, eid_table);
13420     ret = json_eid_for_eid_table (vam, node, eid_table);
13421     if (ret)
13422       {
13423         vec_free (vam->locator_msg);
13424         vec_free (vam->eid_tables);
13425         clean_locator_set_message (vam);
13426         vat_json_free (&vam->json_tree);
13427         vam->json_tree.type = VAT_JSON_NONE;
13428         return ret;
13429       }
13430
13431     json_locator_for_eid_table (vam, node, eid_table);
13432
13433     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13434     vat_json_object_add_uint (node, "authoritative",
13435                               eid_table->authoritative);
13436
13437     vec_free (vam->locator_msg);
13438   }
13439
13440   vat_json_print (vam->ofp, &vam->json_tree);
13441   vat_json_free (&vam->json_tree);
13442   vam->json_tree.type = VAT_JSON_NONE;
13443
13444   clean_locator_set_message (vam);
13445   vec_free (vam->eid_tables);
13446
13447   return ret;
13448 }
13449
13450 static int
13451 api_lisp_eid_table_dump (vat_main_t * vam)
13452 {
13453   unformat_input_t *i = vam->input;
13454   vl_api_lisp_eid_table_dump_t *mp;
13455   f64 timeout = ~0;
13456   struct in_addr ip4;
13457   struct in6_addr ip6;
13458   u8 mac[6];
13459   u8 eid_type = ~0, eid_set = 0;
13460   u32 prefix_length = ~0, t, vni = 0;
13461   u8 filter = 0;
13462
13463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13466         {
13467           eid_set = 1;
13468           eid_type = 0;
13469           prefix_length = t;
13470         }
13471       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13472         {
13473           eid_set = 1;
13474           eid_type = 1;
13475           prefix_length = t;
13476         }
13477       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13478         {
13479           eid_set = 1;
13480           eid_type = 2;
13481         }
13482       else if (unformat (i, "vni %d", &t))
13483         {
13484           vni = t;
13485         }
13486       else if (unformat (i, "local"))
13487         {
13488           filter = 1;
13489         }
13490       else if (unformat (i, "remote"))
13491         {
13492           filter = 2;
13493         }
13494       else
13495         {
13496           errmsg ("parse error '%U'", format_unformat_error, i);
13497           return -99;
13498         }
13499     }
13500
13501   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13502
13503   mp->filter = filter;
13504   if (eid_set)
13505     {
13506       mp->eid_set = 1;
13507       mp->vni = htonl (vni);
13508       mp->eid_type = eid_type;
13509       switch (eid_type)
13510         {
13511         case 0:
13512           mp->prefix_length = prefix_length;
13513           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13514           break;
13515         case 1:
13516           mp->prefix_length = prefix_length;
13517           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13518           break;
13519         case 2:
13520           clib_memcpy (mp->eid, mac, sizeof (mac));
13521           break;
13522         default:
13523           errmsg ("unknown EID type %d!", eid_type);
13524           return -99;
13525         }
13526     }
13527
13528   vam->noprint_msg = 1;
13529
13530   /* send it... */
13531   S;
13532
13533   /* Use a control ping for synchronization */
13534   {
13535     vl_api_noprint_control_ping_t *mp;
13536     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13537     S;
13538   }
13539
13540   /* Wait for a reply... */
13541   /* *INDENT-OFF* */
13542   W_L
13543   ({
13544     if (vam->noprint_msg)
13545       {
13546         if (!vam->json_output)
13547           {
13548             vam->retval = print_lisp_eid_table_dump(vam);
13549           }
13550         else
13551           {
13552             vam->retval = json_lisp_eid_table_dump(vam);
13553           }
13554       }
13555     vam->noprint_msg = 0;
13556   });
13557   /* *INDENT-ON* */
13558
13559   /* NOTREACHED */
13560   return 0;
13561 }
13562
13563 static int
13564 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13565 {
13566   vl_api_lisp_gpe_tunnel_dump_t *mp;
13567   f64 timeout = ~0;
13568
13569   if (!vam->json_output)
13570     {
13571       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13572                "%=16s%=16s%=16s%=16s%=16s\n",
13573                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13574                "Decap next", "Lisp version", "Flags", "Next protocol",
13575                "ver_res", "res", "iid");
13576     }
13577
13578   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13579   /* send it... */
13580   S;
13581
13582   /* Use a control ping for synchronization */
13583   {
13584     vl_api_control_ping_t *mp;
13585     M (CONTROL_PING, control_ping);
13586     S;
13587   }
13588   /* Wait for a reply... */
13589   W;
13590
13591   /* NOTREACHED */
13592   return 0;
13593 }
13594
13595 static int
13596 api_lisp_map_resolver_dump (vat_main_t * vam)
13597 {
13598   vl_api_lisp_map_resolver_dump_t *mp;
13599   f64 timeout = ~0;
13600
13601   if (!vam->json_output)
13602     {
13603       fformat (vam->ofp, "%=20s\n", "Map resolver");
13604     }
13605
13606   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13607   /* send it... */
13608   S;
13609
13610   /* Use a control ping for synchronization */
13611   {
13612     vl_api_control_ping_t *mp;
13613     M (CONTROL_PING, control_ping);
13614     S;
13615   }
13616   /* Wait for a reply... */
13617   W;
13618
13619   /* NOTREACHED */
13620   return 0;
13621 }
13622
13623 static int
13624 api_show_lisp_status (vat_main_t * vam)
13625 {
13626   vl_api_show_lisp_status_t *mp;
13627   f64 timeout = ~0;
13628
13629   if (!vam->json_output)
13630     {
13631       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13632     }
13633
13634   M (SHOW_LISP_STATUS, show_lisp_status);
13635   /* send it... */
13636   S;
13637   /* Wait for a reply... */
13638   W;
13639
13640   /* NOTREACHED */
13641   return 0;
13642 }
13643
13644 static int
13645 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13646 {
13647   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13648   f64 timeout = ~0;
13649
13650   if (!vam->json_output)
13651     {
13652       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13653     }
13654
13655   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13656   /* send it... */
13657   S;
13658   /* Wait for a reply... */
13659   W;
13660
13661   /* NOTREACHED */
13662   return 0;
13663 }
13664
13665 static int
13666 api_af_packet_create (vat_main_t * vam)
13667 {
13668   unformat_input_t *i = vam->input;
13669   vl_api_af_packet_create_t *mp;
13670   f64 timeout;
13671   u8 *host_if_name = 0;
13672   u8 hw_addr[6];
13673   u8 random_hw_addr = 1;
13674
13675   memset (hw_addr, 0, sizeof (hw_addr));
13676
13677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13678     {
13679       if (unformat (i, "name %s", &host_if_name))
13680         vec_add1 (host_if_name, 0);
13681       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13682         random_hw_addr = 0;
13683       else
13684         break;
13685     }
13686
13687   if (!vec_len (host_if_name))
13688     {
13689       errmsg ("host-interface name must be specified");
13690       return -99;
13691     }
13692
13693   if (vec_len (host_if_name) > 64)
13694     {
13695       errmsg ("host-interface name too long");
13696       return -99;
13697     }
13698
13699   M (AF_PACKET_CREATE, af_packet_create);
13700
13701   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13702   clib_memcpy (mp->hw_addr, hw_addr, 6);
13703   mp->use_random_hw_addr = random_hw_addr;
13704   vec_free (host_if_name);
13705
13706   S;
13707   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13708   /* NOTREACHED */
13709   return 0;
13710 }
13711
13712 static int
13713 api_af_packet_delete (vat_main_t * vam)
13714 {
13715   unformat_input_t *i = vam->input;
13716   vl_api_af_packet_delete_t *mp;
13717   f64 timeout;
13718   u8 *host_if_name = 0;
13719
13720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13721     {
13722       if (unformat (i, "name %s", &host_if_name))
13723         vec_add1 (host_if_name, 0);
13724       else
13725         break;
13726     }
13727
13728   if (!vec_len (host_if_name))
13729     {
13730       errmsg ("host-interface name must be specified");
13731       return -99;
13732     }
13733
13734   if (vec_len (host_if_name) > 64)
13735     {
13736       errmsg ("host-interface name too long");
13737       return -99;
13738     }
13739
13740   M (AF_PACKET_DELETE, af_packet_delete);
13741
13742   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13743   vec_free (host_if_name);
13744
13745   S;
13746   W;
13747   /* NOTREACHED */
13748   return 0;
13749 }
13750
13751 static int
13752 api_policer_add_del (vat_main_t * vam)
13753 {
13754   unformat_input_t *i = vam->input;
13755   vl_api_policer_add_del_t *mp;
13756   f64 timeout;
13757   u8 is_add = 1;
13758   u8 *name = 0;
13759   u32 cir = 0;
13760   u32 eir = 0;
13761   u64 cb = 0;
13762   u64 eb = 0;
13763   u8 rate_type = 0;
13764   u8 round_type = 0;
13765   u8 type = 0;
13766   u8 color_aware = 0;
13767   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13768
13769   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13770   conform_action.dscp = 0;
13771   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13772   exceed_action.dscp = 0;
13773   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13774   violate_action.dscp = 0;
13775
13776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (i, "del"))
13779         is_add = 0;
13780       else if (unformat (i, "name %s", &name))
13781         vec_add1 (name, 0);
13782       else if (unformat (i, "cir %u", &cir))
13783         ;
13784       else if (unformat (i, "eir %u", &eir))
13785         ;
13786       else if (unformat (i, "cb %u", &cb))
13787         ;
13788       else if (unformat (i, "eb %u", &eb))
13789         ;
13790       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13791                          &rate_type))
13792         ;
13793       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13794                          &round_type))
13795         ;
13796       else if (unformat (i, "type %U", unformat_policer_type, &type))
13797         ;
13798       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13799                          &conform_action))
13800         ;
13801       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13802                          &exceed_action))
13803         ;
13804       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13805                          &violate_action))
13806         ;
13807       else if (unformat (i, "color-aware"))
13808         color_aware = 1;
13809       else
13810         break;
13811     }
13812
13813   if (!vec_len (name))
13814     {
13815       errmsg ("policer name must be specified");
13816       return -99;
13817     }
13818
13819   if (vec_len (name) > 64)
13820     {
13821       errmsg ("policer name too long");
13822       return -99;
13823     }
13824
13825   M (POLICER_ADD_DEL, policer_add_del);
13826
13827   clib_memcpy (mp->name, name, vec_len (name));
13828   vec_free (name);
13829   mp->is_add = is_add;
13830   mp->cir = cir;
13831   mp->eir = eir;
13832   mp->cb = cb;
13833   mp->eb = eb;
13834   mp->rate_type = rate_type;
13835   mp->round_type = round_type;
13836   mp->type = type;
13837   mp->conform_action_type = conform_action.action_type;
13838   mp->conform_dscp = conform_action.dscp;
13839   mp->exceed_action_type = exceed_action.action_type;
13840   mp->exceed_dscp = exceed_action.dscp;
13841   mp->violate_action_type = violate_action.action_type;
13842   mp->violate_dscp = violate_action.dscp;
13843   mp->color_aware = color_aware;
13844
13845   S;
13846   W;
13847   /* NOTREACHED */
13848   return 0;
13849 }
13850
13851 static int
13852 api_policer_dump (vat_main_t * vam)
13853 {
13854   unformat_input_t *i = vam->input;
13855   vl_api_policer_dump_t *mp;
13856   f64 timeout = ~0;
13857   u8 *match_name = 0;
13858   u8 match_name_valid = 0;
13859
13860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13861     {
13862       if (unformat (i, "name %s", &match_name))
13863         {
13864           vec_add1 (match_name, 0);
13865           match_name_valid = 1;
13866         }
13867       else
13868         break;
13869     }
13870
13871   M (POLICER_DUMP, policer_dump);
13872   mp->match_name_valid = match_name_valid;
13873   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13874   vec_free (match_name);
13875   /* send it... */
13876   S;
13877
13878   /* Use a control ping for synchronization */
13879   {
13880     vl_api_control_ping_t *mp;
13881     M (CONTROL_PING, control_ping);
13882     S;
13883   }
13884   /* Wait for a reply... */
13885   W;
13886
13887   /* NOTREACHED */
13888   return 0;
13889 }
13890
13891 static int
13892 api_policer_classify_set_interface (vat_main_t * vam)
13893 {
13894   unformat_input_t *i = vam->input;
13895   vl_api_policer_classify_set_interface_t *mp;
13896   f64 timeout;
13897   u32 sw_if_index;
13898   int sw_if_index_set;
13899   u32 ip4_table_index = ~0;
13900   u32 ip6_table_index = ~0;
13901   u32 l2_table_index = ~0;
13902   u8 is_add = 1;
13903
13904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13905     {
13906       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13907         sw_if_index_set = 1;
13908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13909         sw_if_index_set = 1;
13910       else if (unformat (i, "del"))
13911         is_add = 0;
13912       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13913         ;
13914       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13915         ;
13916       else if (unformat (i, "l2-table %d", &l2_table_index))
13917         ;
13918       else
13919         {
13920           clib_warning ("parse error '%U'", format_unformat_error, i);
13921           return -99;
13922         }
13923     }
13924
13925   if (sw_if_index_set == 0)
13926     {
13927       errmsg ("missing interface name or sw_if_index\n");
13928       return -99;
13929     }
13930
13931   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13932
13933   mp->sw_if_index = ntohl (sw_if_index);
13934   mp->ip4_table_index = ntohl (ip4_table_index);
13935   mp->ip6_table_index = ntohl (ip6_table_index);
13936   mp->l2_table_index = ntohl (l2_table_index);
13937   mp->is_add = is_add;
13938
13939   S;
13940   W;
13941   /* NOTREACHED */
13942   return 0;
13943 }
13944
13945 static int
13946 api_policer_classify_dump (vat_main_t * vam)
13947 {
13948   unformat_input_t *i = vam->input;
13949   vl_api_policer_classify_dump_t *mp;
13950   f64 timeout = ~0;
13951   u8 type = POLICER_CLASSIFY_N_TABLES;
13952
13953   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13954     ;
13955   else
13956     {
13957       errmsg ("classify table type must be specified\n");
13958       return -99;
13959     }
13960
13961   if (!vam->json_output)
13962     {
13963       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13964     }
13965
13966   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
13967   mp->type = type;
13968   /* send it... */
13969   S;
13970
13971   /* Use a control ping for synchronization */
13972   {
13973     vl_api_control_ping_t *mp;
13974     M (CONTROL_PING, control_ping);
13975     S;
13976   }
13977   /* Wait for a reply... */
13978   W;
13979
13980   /* NOTREACHED */
13981   return 0;
13982 }
13983
13984 static int
13985 api_netmap_create (vat_main_t * vam)
13986 {
13987   unformat_input_t *i = vam->input;
13988   vl_api_netmap_create_t *mp;
13989   f64 timeout;
13990   u8 *if_name = 0;
13991   u8 hw_addr[6];
13992   u8 random_hw_addr = 1;
13993   u8 is_pipe = 0;
13994   u8 is_master = 0;
13995
13996   memset (hw_addr, 0, sizeof (hw_addr));
13997
13998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13999     {
14000       if (unformat (i, "name %s", &if_name))
14001         vec_add1 (if_name, 0);
14002       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14003         random_hw_addr = 0;
14004       else if (unformat (i, "pipe"))
14005         is_pipe = 1;
14006       else if (unformat (i, "master"))
14007         is_master = 1;
14008       else if (unformat (i, "slave"))
14009         is_master = 0;
14010       else
14011         break;
14012     }
14013
14014   if (!vec_len (if_name))
14015     {
14016       errmsg ("interface name must be specified");
14017       return -99;
14018     }
14019
14020   if (vec_len (if_name) > 64)
14021     {
14022       errmsg ("interface name too long");
14023       return -99;
14024     }
14025
14026   M (NETMAP_CREATE, netmap_create);
14027
14028   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14029   clib_memcpy (mp->hw_addr, hw_addr, 6);
14030   mp->use_random_hw_addr = random_hw_addr;
14031   mp->is_pipe = is_pipe;
14032   mp->is_master = is_master;
14033   vec_free (if_name);
14034
14035   S;
14036   W;
14037   /* NOTREACHED */
14038   return 0;
14039 }
14040
14041 static int
14042 api_netmap_delete (vat_main_t * vam)
14043 {
14044   unformat_input_t *i = vam->input;
14045   vl_api_netmap_delete_t *mp;
14046   f64 timeout;
14047   u8 *if_name = 0;
14048
14049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14050     {
14051       if (unformat (i, "name %s", &if_name))
14052         vec_add1 (if_name, 0);
14053       else
14054         break;
14055     }
14056
14057   if (!vec_len (if_name))
14058     {
14059       errmsg ("interface name must be specified");
14060       return -99;
14061     }
14062
14063   if (vec_len (if_name) > 64)
14064     {
14065       errmsg ("interface name too long");
14066       return -99;
14067     }
14068
14069   M (NETMAP_DELETE, netmap_delete);
14070
14071   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14072   vec_free (if_name);
14073
14074   S;
14075   W;
14076   /* NOTREACHED */
14077   return 0;
14078 }
14079
14080 static void vl_api_mpls_gre_tunnel_details_t_handler
14081   (vl_api_mpls_gre_tunnel_details_t * mp)
14082 {
14083   vat_main_t *vam = &vat_main;
14084   i32 i;
14085   i32 len = ntohl (mp->nlabels);
14086
14087   if (mp->l2_only == 0)
14088     {
14089       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14090                ntohl (mp->tunnel_index),
14091                format_ip4_address, &mp->tunnel_src,
14092                format_ip4_address, &mp->tunnel_dst,
14093                format_ip4_address, &mp->intfc_address,
14094                ntohl (mp->mask_width));
14095       for (i = 0; i < len; i++)
14096         {
14097           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14098         }
14099       fformat (vam->ofp, "\n");
14100       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14101                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14102     }
14103   else
14104     {
14105       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14106                ntohl (mp->tunnel_index),
14107                format_ip4_address, &mp->tunnel_src,
14108                format_ip4_address, &mp->tunnel_dst,
14109                format_ip4_address, &mp->intfc_address);
14110       for (i = 0; i < len; i++)
14111         {
14112           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14113         }
14114       fformat (vam->ofp, "\n");
14115       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14116                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14117     }
14118 }
14119
14120 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14121   (vl_api_mpls_gre_tunnel_details_t * mp)
14122 {
14123   vat_main_t *vam = &vat_main;
14124   vat_json_node_t *node = NULL;
14125   struct in_addr ip4;
14126   i32 i;
14127   i32 len = ntohl (mp->nlabels);
14128
14129   if (VAT_JSON_ARRAY != vam->json_tree.type)
14130     {
14131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14132       vat_json_init_array (&vam->json_tree);
14133     }
14134   node = vat_json_array_add (&vam->json_tree);
14135
14136   vat_json_init_object (node);
14137   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14138   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14139   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14140   vat_json_object_add_uint (node, "inner_fib_index",
14141                             ntohl (mp->inner_fib_index));
14142   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14143   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14144   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14145   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14146   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14147   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14148   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14149   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14150   vat_json_object_add_uint (node, "outer_fib_index",
14151                             ntohl (mp->outer_fib_index));
14152   vat_json_object_add_uint (node, "label_count", len);
14153   for (i = 0; i < len; i++)
14154     {
14155       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14156     }
14157 }
14158
14159 static int
14160 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14161 {
14162   vl_api_mpls_gre_tunnel_dump_t *mp;
14163   f64 timeout;
14164   i32 index = -1;
14165
14166   /* Parse args required to build the message */
14167   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14168     {
14169       if (!unformat (vam->input, "tunnel_index %d", &index))
14170         {
14171           index = -1;
14172           break;
14173         }
14174     }
14175
14176   fformat (vam->ofp, "  tunnel_index %d\n", index);
14177
14178   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14179   mp->tunnel_index = htonl (index);
14180   S;
14181
14182   /* Use a control ping for synchronization */
14183   {
14184     vl_api_control_ping_t *mp;
14185     M (CONTROL_PING, control_ping);
14186     S;
14187   }
14188   W;
14189 }
14190
14191 static void vl_api_mpls_eth_tunnel_details_t_handler
14192   (vl_api_mpls_eth_tunnel_details_t * mp)
14193 {
14194   vat_main_t *vam = &vat_main;
14195   i32 i;
14196   i32 len = ntohl (mp->nlabels);
14197
14198   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14199            ntohl (mp->tunnel_index),
14200            format_ethernet_address, &mp->tunnel_dst_mac,
14201            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14202   for (i = 0; i < len; i++)
14203     {
14204       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14205     }
14206   fformat (vam->ofp, "\n");
14207   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14208            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14209 }
14210
14211 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14212   (vl_api_mpls_eth_tunnel_details_t * mp)
14213 {
14214   vat_main_t *vam = &vat_main;
14215   vat_json_node_t *node = NULL;
14216   struct in_addr ip4;
14217   i32 i;
14218   i32 len = ntohl (mp->nlabels);
14219
14220   if (VAT_JSON_ARRAY != vam->json_tree.type)
14221     {
14222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14223       vat_json_init_array (&vam->json_tree);
14224     }
14225   node = vat_json_array_add (&vam->json_tree);
14226
14227   vat_json_init_object (node);
14228   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14229   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14230   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14231   vat_json_object_add_uint (node, "inner_fib_index",
14232                             ntohl (mp->inner_fib_index));
14233   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14234   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14235   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14236   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14237   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14238                                    format (0, "%U", format_ethernet_address,
14239                                            &mp->tunnel_dst_mac));
14240   vat_json_object_add_uint (node, "tx_sw_if_index",
14241                             ntohl (mp->tx_sw_if_index));
14242   vat_json_object_add_uint (node, "label_count", len);
14243   for (i = 0; i < len; i++)
14244     {
14245       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14246     }
14247 }
14248
14249 static int
14250 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14251 {
14252   vl_api_mpls_eth_tunnel_dump_t *mp;
14253   f64 timeout;
14254   i32 index = -1;
14255
14256   /* Parse args required to build the message */
14257   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14258     {
14259       if (!unformat (vam->input, "tunnel_index %d", &index))
14260         {
14261           index = -1;
14262           break;
14263         }
14264     }
14265
14266   fformat (vam->ofp, "  tunnel_index %d\n", index);
14267
14268   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14269   mp->tunnel_index = htonl (index);
14270   S;
14271
14272   /* Use a control ping for synchronization */
14273   {
14274     vl_api_control_ping_t *mp;
14275     M (CONTROL_PING, control_ping);
14276     S;
14277   }
14278   W;
14279 }
14280
14281 static void vl_api_mpls_fib_encap_details_t_handler
14282   (vl_api_mpls_fib_encap_details_t * mp)
14283 {
14284   vat_main_t *vam = &vat_main;
14285   i32 i;
14286   i32 len = ntohl (mp->nlabels);
14287
14288   fformat (vam->ofp, "table %d, dest %U, label ",
14289            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14290   for (i = 0; i < len; i++)
14291     {
14292       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14293     }
14294   fformat (vam->ofp, "\n");
14295 }
14296
14297 static void vl_api_mpls_fib_encap_details_t_handler_json
14298   (vl_api_mpls_fib_encap_details_t * mp)
14299 {
14300   vat_main_t *vam = &vat_main;
14301   vat_json_node_t *node = NULL;
14302   i32 i;
14303   i32 len = ntohl (mp->nlabels);
14304   struct in_addr ip4;
14305
14306   if (VAT_JSON_ARRAY != vam->json_tree.type)
14307     {
14308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14309       vat_json_init_array (&vam->json_tree);
14310     }
14311   node = vat_json_array_add (&vam->json_tree);
14312
14313   vat_json_init_object (node);
14314   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14315   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14316   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14317   vat_json_object_add_ip4 (node, "dest", ip4);
14318   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14319   vat_json_object_add_uint (node, "label_count", len);
14320   for (i = 0; i < len; i++)
14321     {
14322       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14323     }
14324 }
14325
14326 static int
14327 api_mpls_fib_encap_dump (vat_main_t * vam)
14328 {
14329   vl_api_mpls_fib_encap_dump_t *mp;
14330   f64 timeout;
14331
14332   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14333   S;
14334
14335   /* Use a control ping for synchronization */
14336   {
14337     vl_api_control_ping_t *mp;
14338     M (CONTROL_PING, control_ping);
14339     S;
14340   }
14341   W;
14342 }
14343
14344 static void vl_api_mpls_fib_decap_details_t_handler
14345   (vl_api_mpls_fib_decap_details_t * mp)
14346 {
14347   vat_main_t *vam = &vat_main;
14348
14349   fformat (vam->ofp,
14350            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14351            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14352            ntohl (mp->label), ntohl (mp->s_bit));
14353 }
14354
14355 static void vl_api_mpls_fib_decap_details_t_handler_json
14356   (vl_api_mpls_fib_decap_details_t * mp)
14357 {
14358   vat_main_t *vam = &vat_main;
14359   vat_json_node_t *node = NULL;
14360   struct in_addr ip4;
14361
14362   if (VAT_JSON_ARRAY != vam->json_tree.type)
14363     {
14364       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14365       vat_json_init_array (&vam->json_tree);
14366     }
14367   node = vat_json_array_add (&vam->json_tree);
14368
14369   vat_json_init_object (node);
14370   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14371   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14372   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14373   vat_json_object_add_ip4 (node, "dest", ip4);
14374   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14375   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14376   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14377   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14378   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14379 }
14380
14381 static int
14382 api_mpls_fib_decap_dump (vat_main_t * vam)
14383 {
14384   vl_api_mpls_fib_decap_dump_t *mp;
14385   f64 timeout;
14386
14387   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14388   S;
14389
14390   /* Use a control ping for synchronization */
14391   {
14392     vl_api_control_ping_t *mp;
14393     M (CONTROL_PING, control_ping);
14394     S;
14395   }
14396   W;
14397 }
14398
14399 int
14400 api_classify_table_ids (vat_main_t * vam)
14401 {
14402   vl_api_classify_table_ids_t *mp;
14403   f64 timeout;
14404
14405   /* Construct the API message */
14406   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14407   mp->context = 0;
14408
14409   S;
14410   W;
14411   /* NOTREACHED */
14412   return 0;
14413 }
14414
14415 int
14416 api_classify_table_by_interface (vat_main_t * vam)
14417 {
14418   unformat_input_t *input = vam->input;
14419   vl_api_classify_table_by_interface_t *mp;
14420   f64 timeout;
14421
14422   u32 sw_if_index = ~0;
14423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14424     {
14425       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14426         ;
14427       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14428         ;
14429       else
14430         break;
14431     }
14432   if (sw_if_index == ~0)
14433     {
14434       errmsg ("missing interface name or sw_if_index\n");
14435       return -99;
14436     }
14437
14438   /* Construct the API message */
14439   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14440   mp->context = 0;
14441   mp->sw_if_index = ntohl (sw_if_index);
14442
14443   S;
14444   W;
14445   /* NOTREACHED */
14446   return 0;
14447 }
14448
14449 int
14450 api_classify_table_info (vat_main_t * vam)
14451 {
14452   unformat_input_t *input = vam->input;
14453   vl_api_classify_table_info_t *mp;
14454   f64 timeout;
14455
14456   u32 table_id = ~0;
14457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14458     {
14459       if (unformat (input, "table_id %d", &table_id))
14460         ;
14461       else
14462         break;
14463     }
14464   if (table_id == ~0)
14465     {
14466       errmsg ("missing table id\n");
14467       return -99;
14468     }
14469
14470   /* Construct the API message */
14471   M (CLASSIFY_TABLE_INFO, classify_table_info);
14472   mp->context = 0;
14473   mp->table_id = ntohl (table_id);
14474
14475   S;
14476   W;
14477   /* NOTREACHED */
14478   return 0;
14479 }
14480
14481 int
14482 api_classify_session_dump (vat_main_t * vam)
14483 {
14484   unformat_input_t *input = vam->input;
14485   vl_api_classify_session_dump_t *mp;
14486   f64 timeout;
14487
14488   u32 table_id = ~0;
14489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14490     {
14491       if (unformat (input, "table_id %d", &table_id))
14492         ;
14493       else
14494         break;
14495     }
14496   if (table_id == ~0)
14497     {
14498       errmsg ("missing table id\n");
14499       return -99;
14500     }
14501
14502   /* Construct the API message */
14503   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14504   mp->context = 0;
14505   mp->table_id = ntohl (table_id);
14506   S;
14507
14508   /* Use a control ping for synchronization */
14509   {
14510     vl_api_control_ping_t *mp;
14511     M (CONTROL_PING, control_ping);
14512     S;
14513   }
14514   W;
14515   /* NOTREACHED */
14516   return 0;
14517 }
14518
14519 static void
14520 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14521 {
14522   vat_main_t *vam = &vat_main;
14523
14524   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14525            "src_address %U, fib_index %u, path_mtu %u, "
14526            "template_interval %u\n",
14527            format_ip4_address, mp->collector_address,
14528            ntohs (mp->collector_port),
14529            format_ip4_address, mp->src_address,
14530            ntohl (mp->fib_index),
14531            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14532
14533   vam->retval = 0;
14534   vam->result_ready = 1;
14535 }
14536
14537 static void
14538 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14539 {
14540   vat_main_t *vam = &vat_main;
14541   vat_json_node_t node;
14542   struct in_addr collector_address;
14543   struct in_addr src_address;
14544
14545   vat_json_init_object (&node);
14546   clib_memcpy (&collector_address, &mp->collector_address,
14547                sizeof (collector_address));
14548   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14549   vat_json_object_add_uint (&node, "collector_port",
14550                             ntohs (mp->collector_port));
14551   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14552   vat_json_object_add_ip4 (&node, "src_address", src_address);
14553   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14554   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14555   vat_json_object_add_uint (&node, "template_interval",
14556                             ntohl (mp->template_interval));
14557
14558   vat_json_print (vam->ofp, &node);
14559   vat_json_free (&node);
14560   vam->retval = 0;
14561   vam->result_ready = 1;
14562 }
14563
14564 int
14565 api_ipfix_dump (vat_main_t * vam)
14566 {
14567   vl_api_ipfix_dump_t *mp;
14568   f64 timeout;
14569
14570   /* Construct the API message */
14571   M (IPFIX_DUMP, ipfix_dump);
14572   mp->context = 0;
14573
14574   S;
14575   W;
14576   /* NOTREACHED */
14577   return 0;
14578 }
14579
14580 int
14581 api_pg_create_interface (vat_main_t * vam)
14582 {
14583   unformat_input_t *input = vam->input;
14584   vl_api_pg_create_interface_t *mp;
14585   f64 timeout;
14586
14587   u32 if_id = ~0;
14588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (input, "if_id %d", &if_id))
14591         ;
14592       else
14593         break;
14594     }
14595   if (if_id == ~0)
14596     {
14597       errmsg ("missing pg interface index\n");
14598       return -99;
14599     }
14600
14601   /* Construct the API message */
14602   M (PG_CREATE_INTERFACE, pg_create_interface);
14603   mp->context = 0;
14604   mp->interface_id = ntohl (if_id);
14605
14606   S;
14607   W;
14608   /* NOTREACHED */
14609   return 0;
14610 }
14611
14612 int
14613 api_pg_capture (vat_main_t * vam)
14614 {
14615   unformat_input_t *input = vam->input;
14616   vl_api_pg_capture_t *mp;
14617   f64 timeout;
14618
14619   u32 if_id = ~0;
14620   u8 enable = 1;
14621   u32 count = 1;
14622   u8 pcap_file_set = 0;
14623   u8 *pcap_file = 0;
14624   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14625     {
14626       if (unformat (input, "if_id %d", &if_id))
14627         ;
14628       else if (unformat (input, "pcap %s", &pcap_file))
14629         pcap_file_set = 1;
14630       else if (unformat (input, "count %d", &count))
14631         ;
14632       else if (unformat (input, "disable"))
14633         enable = 0;
14634       else
14635         break;
14636     }
14637   if (if_id == ~0)
14638     {
14639       errmsg ("missing pg interface index\n");
14640       return -99;
14641     }
14642   if (pcap_file_set > 0)
14643     {
14644       if (vec_len (pcap_file) > 255)
14645         {
14646           errmsg ("pcap file name is too long\n");
14647           return -99;
14648         }
14649     }
14650
14651   u32 name_len = vec_len (pcap_file);
14652   /* Construct the API message */
14653   M (PG_CAPTURE, pg_capture);
14654   mp->context = 0;
14655   mp->interface_id = ntohl (if_id);
14656   mp->is_enabled = enable;
14657   mp->count = ntohl (count);
14658   mp->pcap_name_length = ntohl (name_len);
14659   if (pcap_file_set != 0)
14660     {
14661       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14662     }
14663   vec_free (pcap_file);
14664
14665   S;
14666   W;
14667   /* NOTREACHED */
14668   return 0;
14669 }
14670
14671 int
14672 api_pg_enable_disable (vat_main_t * vam)
14673 {
14674   unformat_input_t *input = vam->input;
14675   vl_api_pg_enable_disable_t *mp;
14676   f64 timeout;
14677
14678   u8 enable = 1;
14679   u8 stream_name_set = 0;
14680   u8 *stream_name = 0;
14681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14682     {
14683       if (unformat (input, "stream %s", &stream_name))
14684         stream_name_set = 1;
14685       else if (unformat (input, "disable"))
14686         enable = 0;
14687       else
14688         break;
14689     }
14690
14691   if (stream_name_set > 0)
14692     {
14693       if (vec_len (stream_name) > 255)
14694         {
14695           errmsg ("stream name too long\n");
14696           return -99;
14697         }
14698     }
14699
14700   u32 name_len = vec_len (stream_name);
14701   /* Construct the API message */
14702   M (PG_ENABLE_DISABLE, pg_enable_disable);
14703   mp->context = 0;
14704   mp->is_enabled = enable;
14705   if (stream_name_set != 0)
14706     {
14707       mp->stream_name_length = ntohl (name_len);
14708       clib_memcpy (mp->stream_name, stream_name, name_len);
14709     }
14710   vec_free (stream_name);
14711
14712   S;
14713   W;
14714   /* NOTREACHED */
14715   return 0;
14716 }
14717
14718 int
14719 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14720 {
14721   unformat_input_t *input = vam->input;
14722   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14723   f64 timeout;
14724
14725   u16 *low_ports = 0;
14726   u16 *high_ports = 0;
14727   u16 this_low;
14728   u16 this_hi;
14729   ip4_address_t ip4_addr;
14730   ip6_address_t ip6_addr;
14731   u32 length;
14732   u32 tmp, tmp2;
14733   u8 prefix_set = 0;
14734   u32 vrf_id = ~0;
14735   u8 is_add = 1;
14736   u8 is_ipv6 = 0;
14737
14738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14739     {
14740       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14741         {
14742           prefix_set = 1;
14743         }
14744       else
14745         if (unformat
14746             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14747         {
14748           prefix_set = 1;
14749           is_ipv6 = 1;
14750         }
14751       else if (unformat (input, "vrf %d", &vrf_id))
14752         ;
14753       else if (unformat (input, "del"))
14754         is_add = 0;
14755       else if (unformat (input, "port %d", &tmp))
14756         {
14757           if (tmp == 0 || tmp > 65535)
14758             {
14759               errmsg ("port %d out of range", tmp);
14760               return -99;
14761             }
14762           this_low = tmp;
14763           this_hi = this_low + 1;
14764           vec_add1 (low_ports, this_low);
14765           vec_add1 (high_ports, this_hi);
14766         }
14767       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14768         {
14769           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14770             {
14771               errmsg ("incorrect range parameters\n");
14772               return -99;
14773             }
14774           this_low = tmp;
14775           /* Note: in debug CLI +1 is added to high before
14776              passing to real fn that does "the work"
14777              (ip_source_and_port_range_check_add_del).
14778              This fn is a wrapper around the binary API fn a
14779              control plane will call, which expects this increment
14780              to have occurred. Hence letting the binary API control
14781              plane fn do the increment for consistency between VAT
14782              and other control planes.
14783            */
14784           this_hi = tmp2;
14785           vec_add1 (low_ports, this_low);
14786           vec_add1 (high_ports, this_hi);
14787         }
14788       else
14789         break;
14790     }
14791
14792   if (prefix_set == 0)
14793     {
14794       errmsg ("<address>/<mask> not specified\n");
14795       return -99;
14796     }
14797
14798   if (vrf_id == ~0)
14799     {
14800       errmsg ("VRF ID required, not specified\n");
14801       return -99;
14802     }
14803
14804   if (vrf_id == 0)
14805     {
14806       errmsg
14807         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14808       return -99;
14809     }
14810
14811   if (vec_len (low_ports) == 0)
14812     {
14813       errmsg ("At least one port or port range required\n");
14814       return -99;
14815     }
14816
14817   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14818      ip_source_and_port_range_check_add_del);
14819
14820   mp->is_add = is_add;
14821
14822   if (is_ipv6)
14823     {
14824       mp->is_ipv6 = 1;
14825       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14826     }
14827   else
14828     {
14829       mp->is_ipv6 = 0;
14830       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14831     }
14832
14833   mp->mask_length = length;
14834   mp->number_of_ranges = vec_len (low_ports);
14835
14836   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14837   vec_free (low_ports);
14838
14839   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14840   vec_free (high_ports);
14841
14842   mp->vrf_id = ntohl (vrf_id);
14843
14844   S;
14845   W;
14846   /* NOTREACHED */
14847   return 0;
14848 }
14849
14850 int
14851 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14852 {
14853   unformat_input_t *input = vam->input;
14854   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14855   f64 timeout;
14856   u32 sw_if_index = ~0;
14857   int vrf_set = 0;
14858   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14859   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14860   u8 is_add = 1;
14861
14862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14863     {
14864       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14865         ;
14866       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14867         ;
14868       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14869         vrf_set = 1;
14870       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14871         vrf_set = 1;
14872       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14873         vrf_set = 1;
14874       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14875         vrf_set = 1;
14876       else if (unformat (input, "del"))
14877         is_add = 0;
14878       else
14879         break;
14880     }
14881
14882   if (sw_if_index == ~0)
14883     {
14884       errmsg ("Interface required but not specified\n");
14885       return -99;
14886     }
14887
14888   if (vrf_set == 0)
14889     {
14890       errmsg ("VRF ID required but not specified\n");
14891       return -99;
14892     }
14893
14894   if (tcp_out_vrf_id == 0
14895       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14896     {
14897       errmsg
14898         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14899       return -99;
14900     }
14901
14902   /* Construct the API message */
14903   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14904      ip_source_and_port_range_check_interface_add_del);
14905
14906   mp->sw_if_index = ntohl (sw_if_index);
14907   mp->is_add = is_add;
14908   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14909   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14910   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14911   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14912
14913   /* send it... */
14914   S;
14915
14916   /* Wait for a reply... */
14917   W;
14918 }
14919
14920 static int
14921 q_or_quit (vat_main_t * vam)
14922 {
14923   longjmp (vam->jump_buf, 1);
14924   return 0;                     /* not so much */
14925 }
14926
14927 static int
14928 q (vat_main_t * vam)
14929 {
14930   return q_or_quit (vam);
14931 }
14932
14933 static int
14934 quit (vat_main_t * vam)
14935 {
14936   return q_or_quit (vam);
14937 }
14938
14939 static int
14940 comment (vat_main_t * vam)
14941 {
14942   return 0;
14943 }
14944
14945 static int
14946 cmd_cmp (void *a1, void *a2)
14947 {
14948   u8 **c1 = a1;
14949   u8 **c2 = a2;
14950
14951   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14952 }
14953
14954 static int
14955 help (vat_main_t * vam)
14956 {
14957   u8 **cmds = 0;
14958   u8 *name = 0;
14959   hash_pair_t *p;
14960   unformat_input_t *i = vam->input;
14961   int j;
14962
14963   if (unformat (i, "%s", &name))
14964     {
14965       uword *hs;
14966
14967       vec_add1 (name, 0);
14968
14969       hs = hash_get_mem (vam->help_by_name, name);
14970       if (hs)
14971         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
14972       else
14973         fformat (vam->ofp, "No such msg / command '%s'\n", name);
14974       vec_free (name);
14975       return 0;
14976     }
14977
14978   fformat (vam->ofp, "Help is available for the following:\n");
14979
14980     /* *INDENT-OFF* */
14981     hash_foreach_pair (p, vam->function_by_name,
14982     ({
14983       vec_add1 (cmds, (u8 *)(p->key));
14984     }));
14985     /* *INDENT-ON* */
14986
14987   vec_sort_with_function (cmds, cmd_cmp);
14988
14989   for (j = 0; j < vec_len (cmds); j++)
14990     fformat (vam->ofp, "%s\n", cmds[j]);
14991
14992   vec_free (cmds);
14993   return 0;
14994 }
14995
14996 static int
14997 set (vat_main_t * vam)
14998 {
14999   u8 *name = 0, *value = 0;
15000   unformat_input_t *i = vam->input;
15001
15002   if (unformat (i, "%s", &name))
15003     {
15004       /* The input buffer is a vector, not a string. */
15005       value = vec_dup (i->buffer);
15006       vec_delete (value, i->index, 0);
15007       /* Almost certainly has a trailing newline */
15008       if (value[vec_len (value) - 1] == '\n')
15009         value[vec_len (value) - 1] = 0;
15010       /* Make sure it's a proper string, one way or the other */
15011       vec_add1 (value, 0);
15012       (void) clib_macro_set_value (&vam->macro_main,
15013                                    (char *) name, (char *) value);
15014     }
15015   else
15016     errmsg ("usage: set <name> <value>\n");
15017
15018   vec_free (name);
15019   vec_free (value);
15020   return 0;
15021 }
15022
15023 static int
15024 unset (vat_main_t * vam)
15025 {
15026   u8 *name = 0;
15027
15028   if (unformat (vam->input, "%s", &name))
15029     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15030       errmsg ("unset: %s wasn't set\n", name);
15031   vec_free (name);
15032   return 0;
15033 }
15034
15035 typedef struct
15036 {
15037   u8 *name;
15038   u8 *value;
15039 } macro_sort_t;
15040
15041
15042 static int
15043 macro_sort_cmp (void *a1, void *a2)
15044 {
15045   macro_sort_t *s1 = a1;
15046   macro_sort_t *s2 = a2;
15047
15048   return strcmp ((char *) (s1->name), (char *) (s2->name));
15049 }
15050
15051 static int
15052 dump_macro_table (vat_main_t * vam)
15053 {
15054   macro_sort_t *sort_me = 0, *sm;
15055   int i;
15056   hash_pair_t *p;
15057
15058     /* *INDENT-OFF* */
15059     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15060     ({
15061       vec_add2 (sort_me, sm, 1);
15062       sm->name = (u8 *)(p->key);
15063       sm->value = (u8 *) (p->value[0]);
15064     }));
15065     /* *INDENT-ON* */
15066
15067   vec_sort_with_function (sort_me, macro_sort_cmp);
15068
15069   if (vec_len (sort_me))
15070     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15071   else
15072     fformat (vam->ofp, "The macro table is empty...\n");
15073
15074   for (i = 0; i < vec_len (sort_me); i++)
15075     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15076   return 0;
15077 }
15078
15079 static int
15080 dump_node_table (vat_main_t * vam)
15081 {
15082   int i, j;
15083   vlib_node_t *node, *next_node;
15084
15085   if (vec_len (vam->graph_nodes) == 0)
15086     {
15087       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15088       return 0;
15089     }
15090
15091   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15092     {
15093       node = vam->graph_nodes[i];
15094       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15095       for (j = 0; j < vec_len (node->next_nodes); j++)
15096         {
15097           if (node->next_nodes[j] != ~0)
15098             {
15099               next_node = vam->graph_nodes[node->next_nodes[j]];
15100               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15101             }
15102         }
15103     }
15104   return 0;
15105 }
15106
15107 static int
15108 search_node_table (vat_main_t * vam)
15109 {
15110   unformat_input_t *line_input = vam->input;
15111   u8 *node_to_find;
15112   int j;
15113   vlib_node_t *node, *next_node;
15114   uword *p;
15115
15116   if (vam->graph_node_index_by_name == 0)
15117     {
15118       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15119       return 0;
15120     }
15121
15122   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15123     {
15124       if (unformat (line_input, "%s", &node_to_find))
15125         {
15126           vec_add1 (node_to_find, 0);
15127           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15128           if (p == 0)
15129             {
15130               fformat (vam->ofp, "%s not found...\n", node_to_find);
15131               goto out;
15132             }
15133           node = vam->graph_nodes[p[0]];
15134           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15135           for (j = 0; j < vec_len (node->next_nodes); j++)
15136             {
15137               if (node->next_nodes[j] != ~0)
15138                 {
15139                   next_node = vam->graph_nodes[node->next_nodes[j]];
15140                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15141                 }
15142             }
15143         }
15144
15145       else
15146         {
15147           clib_warning ("parse error '%U'", format_unformat_error,
15148                         line_input);
15149           return -99;
15150         }
15151
15152     out:
15153       vec_free (node_to_find);
15154
15155     }
15156
15157   return 0;
15158 }
15159
15160
15161 static int
15162 script (vat_main_t * vam)
15163 {
15164   u8 *s = 0;
15165   char *save_current_file;
15166   unformat_input_t save_input;
15167   jmp_buf save_jump_buf;
15168   u32 save_line_number;
15169
15170   FILE *new_fp, *save_ifp;
15171
15172   if (unformat (vam->input, "%s", &s))
15173     {
15174       new_fp = fopen ((char *) s, "r");
15175       if (new_fp == 0)
15176         {
15177           errmsg ("Couldn't open script file %s\n", s);
15178           vec_free (s);
15179           return -99;
15180         }
15181     }
15182   else
15183     {
15184       errmsg ("Missing script name\n");
15185       return -99;
15186     }
15187
15188   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15189   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15190   save_ifp = vam->ifp;
15191   save_line_number = vam->input_line_number;
15192   save_current_file = (char *) vam->current_file;
15193
15194   vam->input_line_number = 0;
15195   vam->ifp = new_fp;
15196   vam->current_file = s;
15197   do_one_file (vam);
15198
15199   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15200   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15201   vam->ifp = save_ifp;
15202   vam->input_line_number = save_line_number;
15203   vam->current_file = (u8 *) save_current_file;
15204   vec_free (s);
15205
15206   return 0;
15207 }
15208
15209 static int
15210 echo (vat_main_t * vam)
15211 {
15212   fformat (vam->ofp, "%v", vam->input->buffer);
15213   return 0;
15214 }
15215
15216 /* List of API message constructors, CLI names map to api_xxx */
15217 #define foreach_vpe_api_msg                                             \
15218 _(create_loopback,"[mac <mac-addr>]")                                   \
15219 _(sw_interface_dump,"")                                                 \
15220 _(sw_interface_set_flags,                                               \
15221   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15222 _(sw_interface_add_del_address,                                         \
15223   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15224 _(sw_interface_set_table,                                               \
15225   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15226 _(sw_interface_set_vpath,                                               \
15227   "<intfc> | sw_if_index <id> enable | disable")                        \
15228 _(sw_interface_set_l2_xconnect,                                         \
15229   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15230   "enable | disable")                                                   \
15231 _(sw_interface_set_l2_bridge,                                           \
15232   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15233   "[shg <split-horizon-group>] [bvi]\n"                                 \
15234   "enable | disable")                                                   \
15235 _(bridge_domain_add_del,                                                \
15236   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15237 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15238 _(l2fib_add_del,                                                        \
15239   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15240 _(l2_flags,                                                             \
15241   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15242 _(bridge_flags,                                                         \
15243   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15244 _(tap_connect,                                                          \
15245   "tapname <name> mac <mac-addr> | random-mac")                         \
15246 _(tap_modify,                                                           \
15247   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15248 _(tap_delete,                                                           \
15249   "<vpp-if-name> | sw_if_index <id>")                                   \
15250 _(sw_interface_tap_dump, "")                                            \
15251 _(ip_add_del_route,                                                     \
15252   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15253   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15254   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15255   "[multipath] [count <n>]")                                            \
15256 _(proxy_arp_add_del,                                                    \
15257   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15258 _(proxy_arp_intfc_enable_disable,                                       \
15259   "<intfc> | sw_if_index <id> enable | disable")                        \
15260 _(mpls_add_del_encap,                                                   \
15261   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15262 _(mpls_add_del_decap,                                                   \
15263   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15264 _(mpls_gre_add_del_tunnel,                                              \
15265   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15266   "adj <ip4-address>/<mask-width> [del]")                               \
15267 _(sw_interface_set_unnumbered,                                          \
15268   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15269 _(ip_neighbor_add_del,                                                  \
15270   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15271   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15272 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15273 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15274 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15275   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15276   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15277   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15278 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15279 _(reset_fib, "vrf <n> [ipv6]")                                          \
15280 _(dhcp_proxy_config,                                                    \
15281   "svr <v46-address> src <v46-address>\n"                               \
15282    "insert-cid <n> [del]")                                              \
15283 _(dhcp_proxy_config_2,                                                  \
15284   "svr <v46-address> src <v46-address>\n"                               \
15285    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15286 _(dhcp_proxy_set_vss,                                                   \
15287   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15288 _(dhcp_client_config,                                                   \
15289   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15290 _(set_ip_flow_hash,                                                     \
15291   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15292 _(sw_interface_ip6_enable_disable,                                      \
15293   "<intfc> | sw_if_index <id> enable | disable")                        \
15294 _(sw_interface_ip6_set_link_local_address,                              \
15295   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15296 _(sw_interface_ip6nd_ra_prefix,                                         \
15297   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15298   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15299   "[nolink] [isno]")                                                    \
15300 _(sw_interface_ip6nd_ra_config,                                         \
15301   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15302   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15303   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15304 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15305 _(l2_patch_add_del,                                                     \
15306   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15307   "enable | disable")                                                   \
15308 _(mpls_ethernet_add_del_tunnel,                                         \
15309   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15310   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15311 _(mpls_ethernet_add_del_tunnel_2,                                       \
15312   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15313   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15314 _(sr_tunnel_add_del,                                                    \
15315   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15316   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15317   "[policy <policy_name>]")                                             \
15318 _(sr_policy_add_del,                                                    \
15319   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15320 _(sr_multicast_map_add_del,                                             \
15321   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15322 _(classify_add_del_table,                                               \
15323   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15324   "[del] mask <mask-value>\n"                                           \
15325   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15326 _(classify_add_del_session,                                             \
15327   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15328   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15329   "  [l3 [ip4|ip6]]")                                                   \
15330 _(classify_set_interface_ip_table,                                      \
15331   "<intfc> | sw_if_index <nn> table <nn>")                              \
15332 _(classify_set_interface_l2_tables,                                     \
15333   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15334   "  [other-table <nn>]")                                               \
15335 _(get_node_index, "node <node-name")                                    \
15336 _(add_node_next, "node <node-name> next <next-node-name>")              \
15337 _(l2tpv3_create_tunnel,                                                 \
15338   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15339   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15340   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15341 _(l2tpv3_set_tunnel_cookies,                                            \
15342   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15343   "[new_remote_cookie <nn>]\n")                                         \
15344 _(l2tpv3_interface_enable_disable,                                      \
15345   "<intfc> | sw_if_index <nn> enable | disable")                        \
15346 _(l2tpv3_set_lookup_key,                                                \
15347   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15348 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15349 _(vxlan_add_del_tunnel,                                                 \
15350   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15351   " [decap-next l2|ip4|ip6] [del]")                                     \
15352 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15353 _(gre_add_del_tunnel,                                                   \
15354   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15355 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15356 _(l2_fib_clear_table, "")                                               \
15357 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15358 _(l2_interface_vlan_tag_rewrite,                                        \
15359   "<intfc> | sw_if_index <nn> \n"                                       \
15360   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15361   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15362 _(create_vhost_user_if,                                                 \
15363         "socket <filename> [server] [renumber <dev_instance>] "         \
15364         "[mac <mac_address>]")                                          \
15365 _(modify_vhost_user_if,                                                 \
15366         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15367         "[server] [renumber <dev_instance>]")                           \
15368 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15369 _(sw_interface_vhost_user_dump, "")                                     \
15370 _(show_version, "")                                                     \
15371 _(vxlan_gpe_add_del_tunnel,                                             \
15372   "local <addr> remote <addr> vni <nn>\n"                               \
15373     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15374   "[next-ethernet] [next-nsh]\n")                                       \
15375 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15376 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15377 _(interface_name_renumber,                                              \
15378   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15379 _(input_acl_set_interface,                                              \
15380   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15381   "  [l2-table <nn>] [del]")                                            \
15382 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15383 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15384 _(ip_dump, "ipv4 | ipv6")                                               \
15385 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15386 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15387   "  spid_id <n> ")                                                     \
15388 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15389   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15390   "  integ_alg <alg> integ_key <hex>")                                  \
15391 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15392   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15393   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15394   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15395 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15396 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15397 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15398   "(auth_data 0x<data> | auth_data <data>)")                            \
15399 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15400   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15401 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15402   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15403   "(local|remote)")                                                     \
15404 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15405 _(delete_loopback,"sw_if_index <nn>")                                   \
15406 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15407 _(map_add_domain,                                                       \
15408   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15409   "ip6-src <ip6addr> "                                                  \
15410   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15411 _(map_del_domain, "index <n>")                                          \
15412 _(map_add_del_rule,                                                     \
15413   "index <n> psid <n> dst <ip6addr> [del]")                             \
15414 _(map_domain_dump, "")                                                  \
15415 _(map_rule_dump, "index <map-domain>")                                  \
15416 _(want_interface_events,  "enable|disable")                             \
15417 _(want_stats,"enable|disable")                                          \
15418 _(get_first_msg_id, "client <name>")                                    \
15419 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15420 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15421   "fib-id <nn> [ip4][ip6][default]")                                    \
15422 _(get_node_graph, " ")                                                  \
15423 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15424 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15425   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15426   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15427 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15428   " vrf_id <nn>  add | pop | none")                                     \
15429 _(trace_profile_del, "")                                                \
15430 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15431                             " sw_if_index <sw_if_index> p <priority> "  \
15432                             "w <weight>] [del]")                        \
15433 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15434                         "iface <intf> | sw_if_index <sw_if_index> "     \
15435                         "p <priority> w <weight> [del]")                \
15436 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15437                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15438                           "locator-set <locator_name> [del]")           \
15439 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15440   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15441 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15442 _(lisp_gpe_enable_disable, "enable|disable")                            \
15443 _(lisp_enable_disable, "enable|disable")                                \
15444 _(lisp_gpe_add_del_iface, "up|down")                                    \
15445 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15446                                "rloc <locator> p <prio> "               \
15447                                "w <weight> [rloc <loc> ... ] "          \
15448                                "action <action> [del-all]")             \
15449 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15450                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15451                           "[rloc <loc> ... ] action <action>")          \
15452 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15453 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15454 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15455 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15456                          "locator-set <loc-set-name>] [local | remote]")\
15457 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15458                        "[local] | [remote]")                            \
15459 _(lisp_eid_table_map_dump, "")                                          \
15460 _(lisp_gpe_tunnel_dump, "")                                             \
15461 _(lisp_map_resolver_dump, "")                                           \
15462 _(show_lisp_status, "")                                                 \
15463 _(lisp_get_map_request_itr_rlocs, "")                                   \
15464 _(show_lisp_pitr, "")                                                   \
15465 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15466 _(af_packet_delete, "name <host interface name>")                       \
15467 _(policer_add_del, "name <policer name> <params> [del]")                \
15468 _(policer_dump, "[name <policer name>]")                                \
15469 _(policer_classify_set_interface,                                       \
15470   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15471   "  [l2-table <nn>] [del]")                                            \
15472 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15473 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15474     "[master|slave]")                                                   \
15475 _(netmap_delete, "name <interface name>")                               \
15476 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15477 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15478 _(mpls_fib_encap_dump, "")                                              \
15479 _(mpls_fib_decap_dump, "")                                              \
15480 _(classify_table_ids, "")                                               \
15481 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15482 _(classify_table_info, "table_id <nn>")                                 \
15483 _(classify_session_dump, "table_id <nn>")                               \
15484 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15485                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15486                 "[template_interval <nn>]")                             \
15487 _(ipfix_dump, "")                                                       \
15488 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15489 _(pg_create_interface, "if_id <nn>")                                    \
15490 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15491 _(pg_enable_disable, "[stream <id>] disable")                           \
15492 _(ip_source_and_port_range_check_add_del,                               \
15493   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15494 _(ip_source_and_port_range_check_interface_add_del,                     \
15495   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15496   "[udp-in-vrf <id>] [udp-out-vrf <id>]")
15497
15498 /* List of command functions, CLI names map directly to functions */
15499 #define foreach_cli_function                                    \
15500 _(comment, "usage: comment <ignore-rest-of-line>")              \
15501 _(dump_interface_table, "usage: dump_interface_table")          \
15502 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15503 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15504 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15505 _(dump_stats_table, "usage: dump_stats_table")                  \
15506 _(dump_macro_table, "usage: dump_macro_table ")                 \
15507 _(dump_node_table, "usage: dump_node_table")                    \
15508 _(echo, "usage: echo <message>")                                \
15509 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15510 _(help, "usage: help")                                          \
15511 _(q, "usage: quit")                                             \
15512 _(quit, "usage: quit")                                          \
15513 _(search_node_table, "usage: search_node_table <name>...")      \
15514 _(set, "usage: set <variable-name> <value>")                    \
15515 _(script, "usage: script <file-name>")                          \
15516 _(unset, "usage: unset <variable-name>")
15517
15518 #define _(N,n)                                  \
15519     static void vl_api_##n##_t_handler_uni      \
15520     (vl_api_##n##_t * mp)                       \
15521     {                                           \
15522         vat_main_t * vam = &vat_main;           \
15523         if (vam->json_output) {                 \
15524             vl_api_##n##_t_handler_json(mp);    \
15525         } else {                                \
15526             vl_api_##n##_t_handler(mp);         \
15527         }                                       \
15528     }
15529 foreach_vpe_api_reply_msg;
15530 #undef _
15531
15532 void
15533 vat_api_hookup (vat_main_t * vam)
15534 {
15535 #define _(N,n)                                                  \
15536     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15537                            vl_api_##n##_t_handler_uni,          \
15538                            vl_noop_handler,                     \
15539                            vl_api_##n##_t_endian,               \
15540                            vl_api_##n##_t_print,                \
15541                            sizeof(vl_api_##n##_t), 1);
15542   foreach_vpe_api_reply_msg;
15543 #undef _
15544
15545   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15546
15547   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15548
15549   vam->function_by_name = hash_create_string (0, sizeof (uword));
15550
15551   vam->help_by_name = hash_create_string (0, sizeof (uword));
15552
15553   /* API messages we can send */
15554 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15555   foreach_vpe_api_msg;
15556 #undef _
15557
15558   /* Help strings */
15559 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15560   foreach_vpe_api_msg;
15561 #undef _
15562
15563   /* CLI functions */
15564 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15565   foreach_cli_function;
15566 #undef _
15567
15568   /* Help strings */
15569 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15570   foreach_cli_function;
15571 #undef _
15572 }
15573
15574 #undef vl_api_version
15575 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15576 #include <vpp-api/vpe.api.h>
15577 #undef vl_api_version
15578
15579 void
15580 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15581 {
15582   /*
15583    * Send the main API signature in slot 0. This bit of code must
15584    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15585    */
15586   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15587 }
15588
15589 /*
15590  * fd.io coding-style-patch-verification: ON
15591  *
15592  * Local Variables:
15593  * eval: (c-set-style "gnu")
15594  * End:
15595  */