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