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