VPP-328: Add dump call for listing LISP VNIs
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558
1559 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1560   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1610   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1644   (vl_api_gre_add_del_tunnel_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->sw_if_index = ntohl (mp->sw_if_index);
1673       vam->result_ready = 1;
1674     }
1675 }
1676
1677 static void vl_api_create_vhost_user_if_reply_t_handler_json
1678   (vl_api_create_vhost_user_if_reply_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   vat_json_node_t node;
1682
1683   vat_json_init_object (&node);
1684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1685   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_ip_address_details_t_handler
1695   (vl_api_ip_address_details_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   static ip_address_details_t empty_ip_address_details = { {0} };
1699   ip_address_details_t *address = NULL;
1700   ip_details_t *current_ip_details = NULL;
1701   ip_details_t *details = NULL;
1702
1703   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1704
1705   if (!details || vam->current_sw_if_index >= vec_len (details)
1706       || !details[vam->current_sw_if_index].present)
1707     {
1708       errmsg ("ip address details arrived but not stored\n");
1709       errmsg ("ip_dump should be called first\n");
1710       return;
1711     }
1712
1713   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1714
1715 #define addresses (current_ip_details->addr)
1716
1717   vec_validate_init_empty (addresses, vec_len (addresses),
1718                            empty_ip_address_details);
1719
1720   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1721
1722   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1723   address->prefix_length = mp->prefix_length;
1724 #undef addresses
1725 }
1726
1727 static void vl_api_ip_address_details_t_handler_json
1728   (vl_api_ip_address_details_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   vat_json_node_t *node = NULL;
1732   struct in6_addr ip6;
1733   struct in_addr ip4;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   node = vat_json_array_add (&vam->json_tree);
1741
1742   vat_json_init_object (node);
1743   if (vam->is_ipv6)
1744     {
1745       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1746       vat_json_object_add_ip6 (node, "ip", ip6);
1747     }
1748   else
1749     {
1750       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1751       vat_json_object_add_ip4 (node, "ip", ip4);
1752     }
1753   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1754 }
1755
1756 static void
1757 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   static ip_details_t empty_ip_details = { 0 };
1761   ip_details_t *ip = NULL;
1762   u32 sw_if_index = ~0;
1763
1764   sw_if_index = ntohl (mp->sw_if_index);
1765
1766   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1767                            sw_if_index, empty_ip_details);
1768
1769   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1770                          sw_if_index);
1771
1772   ip->present = 1;
1773 }
1774
1775 static void
1776 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   vat_json_array_add_uint (&vam->json_tree,
1786                            clib_net_to_host_u32 (mp->sw_if_index));
1787 }
1788
1789 static void vl_api_map_domain_details_t_handler_json
1790   (vl_api_map_domain_details_t * mp)
1791 {
1792   vat_json_node_t *node = NULL;
1793   vat_main_t *vam = &vat_main;
1794   struct in6_addr ip6;
1795   struct in_addr ip4;
1796
1797   if (VAT_JSON_ARRAY != vam->json_tree.type)
1798     {
1799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1800       vat_json_init_array (&vam->json_tree);
1801     }
1802
1803   node = vat_json_array_add (&vam->json_tree);
1804   vat_json_init_object (node);
1805
1806   vat_json_object_add_uint (node, "domain_index",
1807                             clib_net_to_host_u32 (mp->domain_index));
1808   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1809   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1810   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1811   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1812   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1813   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1814   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1815   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1816   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1817   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1818   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1819   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1820   vat_json_object_add_uint (node, "flags", mp->flags);
1821   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1822   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1823 }
1824
1825 static void vl_api_map_domain_details_t_handler
1826   (vl_api_map_domain_details_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829
1830   if (mp->is_translation)
1831     {
1832       fformat (vam->ofp,
1833                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1834                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1835                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1836                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1837                clib_net_to_host_u32 (mp->domain_index));
1838     }
1839   else
1840     {
1841       fformat (vam->ofp,
1842                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1843                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1844                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1845                format_ip6_address, mp->ip6_src,
1846                clib_net_to_host_u32 (mp->domain_index));
1847     }
1848   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1849            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1850            mp->is_translation ? "map-t" : "");
1851 }
1852
1853 static void vl_api_map_rule_details_t_handler_json
1854   (vl_api_map_rule_details_t * mp)
1855 {
1856   struct in6_addr ip6;
1857   vat_json_node_t *node = NULL;
1858   vat_main_t *vam = &vat_main;
1859
1860   if (VAT_JSON_ARRAY != vam->json_tree.type)
1861     {
1862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1863       vat_json_init_array (&vam->json_tree);
1864     }
1865
1866   node = vat_json_array_add (&vam->json_tree);
1867   vat_json_init_object (node);
1868
1869   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1870   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1871   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1872 }
1873
1874 static void
1875 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1879            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1880 }
1881
1882 static void
1883 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1887           "router_addr %U host_mac %U\n",
1888           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1889           format_ip4_address, &mp->host_address,
1890           format_ip4_address, &mp->router_address,
1891           format_ethernet_address, mp->host_mac);
1892 }
1893
1894 static void vl_api_dhcp_compl_event_t_handler_json
1895   (vl_api_dhcp_compl_event_t * mp)
1896 {
1897   /* JSON output not supported */
1898 }
1899
1900 static void
1901 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1902                               u32 counter)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   static u64 default_counter = 0;
1906
1907   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1908                            NULL);
1909   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1910                            sw_if_index, default_counter);
1911   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1912 }
1913
1914 static void
1915 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1916                                 interface_counter_t counter)
1917 {
1918   vat_main_t *vam = &vat_main;
1919   static interface_counter_t default_counter = { 0, };
1920
1921   vec_validate_init_empty (vam->combined_interface_counters,
1922                            vnet_counter_type, NULL);
1923   vec_validate_init_empty (vam->combined_interface_counters
1924                            [vnet_counter_type], sw_if_index, default_counter);
1925   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1926 }
1927
1928 static void vl_api_vnet_interface_counters_t_handler
1929   (vl_api_vnet_interface_counters_t * mp)
1930 {
1931   /* not supported */
1932 }
1933
1934 static void vl_api_vnet_interface_counters_t_handler_json
1935   (vl_api_vnet_interface_counters_t * mp)
1936 {
1937   interface_counter_t counter;
1938   vlib_counter_t *v;
1939   u64 *v_packets;
1940   u64 packets;
1941   u32 count;
1942   u32 first_sw_if_index;
1943   int i;
1944
1945   count = ntohl (mp->count);
1946   first_sw_if_index = ntohl (mp->first_sw_if_index);
1947
1948   if (!mp->is_combined)
1949     {
1950       v_packets = (u64 *) & mp->data;
1951       for (i = 0; i < count; i++)
1952         {
1953           packets =
1954             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1955           set_simple_interface_counter (mp->vnet_counter_type,
1956                                         first_sw_if_index + i, packets);
1957           v_packets++;
1958         }
1959     }
1960   else
1961     {
1962       v = (vlib_counter_t *) & mp->data;
1963       for (i = 0; i < count; i++)
1964         {
1965           counter.packets =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1967           counter.bytes =
1968             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1969           set_combined_interface_counter (mp->vnet_counter_type,
1970                                           first_sw_if_index + i, counter);
1971           v++;
1972         }
1973     }
1974 }
1975
1976 static u32
1977 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   u32 i;
1981
1982   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1983     {
1984       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1985         {
1986           return i;
1987         }
1988     }
1989   return ~0;
1990 }
1991
1992 static u32
1993 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static void vl_api_vnet_ip4_fib_counters_t_handler
2009   (vl_api_vnet_ip4_fib_counters_t * mp)
2010 {
2011   /* not supported */
2012 }
2013
2014 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2015   (vl_api_vnet_ip4_fib_counters_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vl_api_ip4_fib_counter_t *v;
2019   ip4_fib_counter_t *counter;
2020   struct in_addr ip4;
2021   u32 vrf_id;
2022   u32 vrf_index;
2023   u32 count;
2024   int i;
2025
2026   vrf_id = ntohl (mp->vrf_id);
2027   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2028   if (~0 == vrf_index)
2029     {
2030       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2031       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2032       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2033       vec_validate (vam->ip4_fib_counters, vrf_index);
2034       vam->ip4_fib_counters[vrf_index] = NULL;
2035     }
2036
2037   vec_free (vam->ip4_fib_counters[vrf_index]);
2038   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2039   count = ntohl (mp->count);
2040   for (i = 0; i < count; i++)
2041     {
2042       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2043       counter = &vam->ip4_fib_counters[vrf_index][i];
2044       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2045       counter->address = ip4;
2046       counter->address_length = v->address_length;
2047       counter->packets = clib_net_to_host_u64 (v->packets);
2048       counter->bytes = clib_net_to_host_u64 (v->bytes);
2049       v++;
2050     }
2051 }
2052
2053 static void vl_api_vnet_ip6_fib_counters_t_handler
2054   (vl_api_vnet_ip6_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2060   (vl_api_vnet_ip6_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip6_fib_counter_t *v;
2064   ip6_fib_counter_t *counter;
2065   struct in6_addr ip6;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip6_fib_counters, vrf_index);
2079       vam->ip6_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip6_fib_counters[vrf_index]);
2083   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2088       counter = &vam->ip6_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2090       counter->address = ip6;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_get_first_msg_id_reply_t_handler
2099   (vl_api_get_first_msg_id_reply_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102   i32 retval = ntohl (mp->retval);
2103
2104   if (vam->async_mode)
2105     {
2106       vam->async_errors += (retval < 0);
2107     }
2108   else
2109     {
2110       vam->retval = retval;
2111       vam->result_ready = 1;
2112     }
2113   if (retval >= 0)
2114     {
2115       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2116     }
2117 }
2118
2119 static void vl_api_get_first_msg_id_reply_t_handler_json
2120   (vl_api_get_first_msg_id_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t node;
2124
2125   vat_json_init_object (&node);
2126   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2127   vat_json_object_add_uint (&node, "first_msg_id",
2128                             (uint) ntohs (mp->first_msg_id));
2129
2130   vat_json_print (vam->ofp, &node);
2131   vat_json_free (&node);
2132
2133   vam->retval = ntohl (mp->retval);
2134   vam->result_ready = 1;
2135 }
2136
2137 static void vl_api_get_node_graph_reply_t_handler
2138   (vl_api_get_node_graph_reply_t * mp)
2139 {
2140   vat_main_t *vam = &vat_main;
2141   api_main_t *am = &api_main;
2142   i32 retval = ntohl (mp->retval);
2143   u8 *pvt_copy, *reply;
2144   void *oldheap;
2145   vlib_node_t *node;
2146   int i;
2147
2148   if (vam->async_mode)
2149     {
2150       vam->async_errors += (retval < 0);
2151     }
2152   else
2153     {
2154       vam->retval = retval;
2155       vam->result_ready = 1;
2156     }
2157
2158   /* "Should never happen..." */
2159   if (retval != 0)
2160     return;
2161
2162   reply = (u8 *) (mp->reply_in_shmem);
2163   pvt_copy = vec_dup (reply);
2164
2165   /* Toss the shared-memory original... */
2166   pthread_mutex_lock (&am->vlib_rp->mutex);
2167   oldheap = svm_push_data_heap (am->vlib_rp);
2168
2169   vec_free (reply);
2170
2171   svm_pop_heap (oldheap);
2172   pthread_mutex_unlock (&am->vlib_rp->mutex);
2173
2174   if (vam->graph_nodes)
2175     {
2176       hash_free (vam->graph_node_index_by_name);
2177
2178       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2179         {
2180           node = vam->graph_nodes[i];
2181           vec_free (node->name);
2182           vec_free (node->next_nodes);
2183           vec_free (node);
2184         }
2185       vec_free (vam->graph_nodes);
2186     }
2187
2188   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2189   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2190   vec_free (pvt_copy);
2191
2192   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2193     {
2194       node = vam->graph_nodes[i];
2195       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2196     }
2197 }
2198
2199 static void vl_api_get_node_graph_reply_t_handler_json
2200   (vl_api_get_node_graph_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   api_main_t *am = &api_main;
2204   void *oldheap;
2205   vat_json_node_t node;
2206   u8 *reply;
2207
2208   /* $$$$ make this real? */
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2212
2213   reply = (u8 *) (mp->reply_in_shmem);
2214
2215   /* Toss the shared-memory original... */
2216   pthread_mutex_lock (&am->vlib_rp->mutex);
2217   oldheap = svm_push_data_heap (am->vlib_rp);
2218
2219   vec_free (reply);
2220
2221   svm_pop_heap (oldheap);
2222   pthread_mutex_unlock (&am->vlib_rp->mutex);
2223
2224   vat_json_print (vam->ofp, &node);
2225   vat_json_free (&node);
2226
2227   vam->retval = ntohl (mp->retval);
2228   vam->result_ready = 1;
2229 }
2230
2231 static void
2232 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   locator_msg_t loc;
2236   u8 *tmp_str = 0;
2237
2238   memset (&loc, 0, sizeof (loc));
2239   if (vam->noprint_msg)
2240     {
2241       loc.local = mp->local;
2242       loc.priority = mp->priority;
2243       loc.weight = mp->weight;
2244       if (loc.local)
2245         {
2246           loc.sw_if_index = ntohl (mp->sw_if_index);
2247         }
2248       else
2249         {
2250           loc.is_ipv6 = mp->is_ipv6;
2251           clib_memcpy (loc.ip_address, mp->ip_address,
2252                        sizeof (loc.ip_address));
2253         }
2254       vec_add1 (vam->locator_msg, loc);
2255     }
2256   else
2257     {
2258       if (mp->local)
2259         {
2260           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2261                             ntohl (mp->sw_if_index),
2262                             mp->priority, mp->weight);
2263         }
2264       else
2265         {
2266           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2267                             mp->is_ipv6 ? format_ip6_address :
2268                             format_ip4_address,
2269                             mp->ip_address, mp->priority, mp->weight);
2270         }
2271
2272       fformat (vam->ofp, "%s", tmp_str);
2273
2274       vec_free (tmp_str);
2275     }
2276 }
2277
2278 static void
2279 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2280                                             mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t *node = NULL;
2284   locator_msg_t loc;
2285   struct in6_addr ip6;
2286   struct in_addr ip4;
2287
2288   memset (&loc, 0, sizeof (loc));
2289   if (vam->noprint_msg)
2290     {
2291       loc.local = mp->local;
2292       loc.priority = mp->priority;
2293       loc.weight = mp->weight;
2294       if (loc.local)
2295         {
2296           loc.sw_if_index = ntohl (mp->sw_if_index);
2297         }
2298       else
2299         {
2300           loc.is_ipv6 = mp->is_ipv6;
2301           clib_memcpy (loc.ip_address, mp->ip_address,
2302                        sizeof (loc.ip_address));
2303         }
2304       vec_add1 (vam->locator_msg, loc);
2305       return;
2306     }
2307
2308   if (VAT_JSON_ARRAY != vam->json_tree.type)
2309     {
2310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2311       vat_json_init_array (&vam->json_tree);
2312     }
2313   node = vat_json_array_add (&vam->json_tree);
2314
2315   vat_json_init_object (node);
2316
2317   if (mp->local)
2318     {
2319       vat_json_object_add_uint (node, "locator_index",
2320                                 ntohl (mp->sw_if_index));
2321     }
2322   else
2323     {
2324       if (mp->is_ipv6)
2325         {
2326           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2327           vat_json_object_add_ip6 (node, "locator", ip6);
2328         }
2329       else
2330         {
2331           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2332           vat_json_object_add_ip4 (node, "locator", ip4);
2333         }
2334     }
2335   vat_json_object_add_uint (node, "priority", mp->priority);
2336   vat_json_object_add_uint (node, "weight", mp->weight);
2337 }
2338
2339 static void
2340 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2341                                            mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   locator_set_msg_t ls;
2345
2346   ls.locator_set_index = ntohl (mp->locator_set_index);
2347   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2348   vec_add1 (vam->locator_set_msg, ls);
2349 }
2350
2351 static void
2352   vl_api_lisp_locator_set_details_t_handler_json
2353   (vl_api_lisp_locator_set_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   locator_set_msg_t ls;
2357
2358   ls.locator_set_index = ntohl (mp->locator_set_index);
2359   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2360   vec_add1 (vam->locator_set_msg, ls);
2361 }
2362
2363 static void
2364 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   eid_table_t eid_table;
2368
2369   memset (&eid_table, 0, sizeof (eid_table));
2370   eid_table.is_local = mp->is_local;
2371   eid_table.locator_set_index = mp->locator_set_index;
2372   eid_table.eid_type = mp->eid_type;
2373   eid_table.vni = mp->vni;
2374   eid_table.eid_prefix_len = mp->eid_prefix_len;
2375   eid_table.ttl = mp->ttl;
2376   eid_table.authoritative = mp->authoritative;
2377   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2378   vec_add1 (vam->eid_tables, eid_table);
2379 }
2380
2381 static void
2382 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2383                                               * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   eid_table_t eid_table;
2387
2388   memset (&eid_table, 0, sizeof (eid_table));
2389   eid_table.is_local = mp->is_local;
2390   eid_table.locator_set_index = mp->locator_set_index;
2391   eid_table.eid_type = mp->eid_type;
2392   eid_table.vni = mp->vni;
2393   eid_table.eid_prefix_len = mp->eid_prefix_len;
2394   eid_table.ttl = mp->ttl;
2395   eid_table.authoritative = mp->authoritative;
2396   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2397   vec_add1 (vam->eid_tables, eid_table);
2398 }
2399
2400 static void
2401   vl_api_lisp_eid_table_map_details_t_handler
2402   (vl_api_lisp_eid_table_map_details_t * mp)
2403 {
2404   vat_main_t *vam = &vat_main;
2405
2406   u8 *line = format (0, "%=10d%=10d",
2407                      clib_net_to_host_u32 (mp->vni),
2408                      clib_net_to_host_u32 (mp->vrf));
2409   fformat (vam->ofp, "%v\n", line);
2410   vec_free (line);
2411 }
2412
2413 static void
2414   vl_api_lisp_eid_table_map_details_t_handler_json
2415   (vl_api_lisp_eid_table_map_details_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   vat_json_node_t *node = NULL;
2419
2420   if (VAT_JSON_ARRAY != vam->json_tree.type)
2421     {
2422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2423       vat_json_init_array (&vam->json_tree);
2424     }
2425   node = vat_json_array_add (&vam->json_tree);
2426   vat_json_init_object (node);
2427   vat_json_object_add_uint (node, "vrf", clib_net_to_host_u32 (mp->vrf));
2428   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2429 }
2430
2431 static void
2432   vl_api_lisp_eid_table_vni_details_t_handler
2433   (vl_api_lisp_eid_table_vni_details_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436
2437   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2438   fformat (vam->ofp, "%v\n", line);
2439   vec_free (line);
2440 }
2441
2442 static void
2443   vl_api_lisp_eid_table_vni_details_t_handler_json
2444   (vl_api_lisp_eid_table_vni_details_t * mp)
2445 {
2446   vat_main_t *vam = &vat_main;
2447   vat_json_node_t *node = NULL;
2448
2449   if (VAT_JSON_ARRAY != vam->json_tree.type)
2450     {
2451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2452       vat_json_init_array (&vam->json_tree);
2453     }
2454   node = vat_json_array_add (&vam->json_tree);
2455   vat_json_init_object (node);
2456   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2457 }
2458
2459 static u8 *
2460 format_decap_next (u8 * s, va_list * args)
2461 {
2462   u32 next_index = va_arg (*args, u32);
2463
2464   switch (next_index)
2465     {
2466     case LISP_GPE_INPUT_NEXT_DROP:
2467       return format (s, "drop");
2468     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2469       return format (s, "ip4");
2470     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2471       return format (s, "ip6");
2472     default:
2473       return format (s, "unknown %d", next_index);
2474     }
2475   return s;
2476 }
2477
2478 static void
2479 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2480                                           mp)
2481 {
2482   vat_main_t *vam = &vat_main;
2483   u8 *iid_str;
2484   u8 *flag_str = NULL;
2485
2486   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2487
2488 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2489   foreach_lisp_gpe_flag_bit;
2490 #undef _
2491
2492   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2493            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2494            mp->tunnels,
2495            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2496            mp->source_ip,
2497            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2498            mp->destination_ip,
2499            ntohl (mp->encap_fib_id),
2500            ntohl (mp->decap_fib_id),
2501            format_decap_next, ntohl (mp->dcap_next),
2502            mp->ver_res >> 6,
2503            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2504
2505   vec_free (iid_str);
2506 }
2507
2508 static void
2509   vl_api_lisp_gpe_tunnel_details_t_handler_json
2510   (vl_api_lisp_gpe_tunnel_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t *node = NULL;
2514   struct in6_addr ip6;
2515   struct in_addr ip4;
2516   u8 *next_decap_str;
2517
2518   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2519
2520   if (VAT_JSON_ARRAY != vam->json_tree.type)
2521     {
2522       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2523       vat_json_init_array (&vam->json_tree);
2524     }
2525   node = vat_json_array_add (&vam->json_tree);
2526
2527   vat_json_init_object (node);
2528   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2529   if (mp->is_ipv6)
2530     {
2531       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2532       vat_json_object_add_ip6 (node, "source address", ip6);
2533       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2534       vat_json_object_add_ip6 (node, "destination address", ip6);
2535     }
2536   else
2537     {
2538       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2539       vat_json_object_add_ip4 (node, "source address", ip4);
2540       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2541       vat_json_object_add_ip4 (node, "destination address", ip4);
2542     }
2543   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2544   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2545   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2546   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2547   vat_json_object_add_uint (node, "flags", mp->flags);
2548   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2549   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2550   vat_json_object_add_uint (node, "res", mp->res);
2551   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2552
2553   vec_free (next_decap_str);
2554 }
2555
2556 static void
2557 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2558                                             * mp)
2559 {
2560   vat_main_t *vam = &vat_main;
2561
2562   fformat (vam->ofp, "%=20U\n",
2563            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2564            mp->ip_address);
2565 }
2566
2567 static void
2568   vl_api_lisp_map_resolver_details_t_handler_json
2569   (vl_api_lisp_map_resolver_details_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   vat_json_node_t *node = NULL;
2573   struct in6_addr ip6;
2574   struct in_addr ip4;
2575
2576   if (VAT_JSON_ARRAY != vam->json_tree.type)
2577     {
2578       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2579       vat_json_init_array (&vam->json_tree);
2580     }
2581   node = vat_json_array_add (&vam->json_tree);
2582
2583   vat_json_init_object (node);
2584   if (mp->is_ipv6)
2585     {
2586       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2587       vat_json_object_add_ip6 (node, "map resolver", ip6);
2588     }
2589   else
2590     {
2591       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2592       vat_json_object_add_ip4 (node, "map resolver", ip4);
2593     }
2594 }
2595
2596 static void
2597   vl_api_show_lisp_status_reply_t_handler
2598   (vl_api_show_lisp_status_reply_t * mp)
2599 {
2600   vat_main_t *vam = &vat_main;
2601   i32 retval = ntohl (mp->retval);
2602
2603   if (0 <= retval)
2604     {
2605       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2606                mp->feature_status ? "enabled" : "disabled",
2607                mp->gpe_status ? "enabled" : "disabled");
2608     }
2609
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615   vl_api_show_lisp_status_reply_t_handler_json
2616   (vl_api_show_lisp_status_reply_t * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619   vat_json_node_t node;
2620   u8 *gpe_status = NULL;
2621   u8 *feature_status = NULL;
2622
2623   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2624   feature_status = format (0, "%s",
2625                            mp->feature_status ? "enabled" : "disabled");
2626   vec_add1 (gpe_status, 0);
2627   vec_add1 (feature_status, 0);
2628
2629   vat_json_init_object (&node);
2630   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2631   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2632
2633   vec_free (gpe_status);
2634   vec_free (feature_status);
2635
2636   vat_json_print (vam->ofp, &node);
2637   vat_json_free (&node);
2638
2639   vam->retval = ntohl (mp->retval);
2640   vam->result_ready = 1;
2641 }
2642
2643 static void
2644   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2645   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   i32 retval = ntohl (mp->retval);
2649
2650   if (retval >= 0)
2651     {
2652       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2653     }
2654
2655   vam->retval = retval;
2656   vam->result_ready = 1;
2657 }
2658
2659 static void
2660   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2661   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2662 {
2663   vat_main_t *vam = &vat_main;
2664   vat_json_node_t *node = NULL;
2665
2666   if (VAT_JSON_ARRAY != vam->json_tree.type)
2667     {
2668       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2669       vat_json_init_array (&vam->json_tree);
2670     }
2671   node = vat_json_array_add (&vam->json_tree);
2672
2673   vat_json_init_object (node);
2674   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2675
2676   vat_json_print (vam->ofp, node);
2677   vat_json_free (node);
2678
2679   vam->retval = ntohl (mp->retval);
2680   vam->result_ready = 1;
2681 }
2682
2683 static void
2684 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2685 {
2686   vat_main_t *vam = &vat_main;
2687   i32 retval = ntohl (mp->retval);
2688
2689   if (0 <= retval)
2690     {
2691       fformat (vam->ofp, "%-20s%-16s\n",
2692                mp->status ? "enabled" : "disabled",
2693                mp->status ? (char *) mp->locator_set_name : "");
2694     }
2695
2696   vam->retval = retval;
2697   vam->result_ready = 1;
2698 }
2699
2700 static void
2701 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2702                                             mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vat_json_node_t node;
2706   u8 *status = 0;
2707
2708   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2709   vec_add1 (status, 0);
2710
2711   vat_json_init_object (&node);
2712   vat_json_object_add_string_copy (&node, "status", status);
2713   if (mp->status)
2714     {
2715       vat_json_object_add_string_copy (&node, "locator_set",
2716                                        mp->locator_set_name);
2717     }
2718
2719   vec_free (status);
2720
2721   vat_json_print (vam->ofp, &node);
2722   vat_json_free (&node);
2723
2724   vam->retval = ntohl (mp->retval);
2725   vam->result_ready = 1;
2726 }
2727
2728 static u8 *
2729 format_policer_type (u8 * s, va_list * va)
2730 {
2731   u32 i = va_arg (*va, u32);
2732
2733   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2734     s = format (s, "1r2c");
2735   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2736     s = format (s, "1r3c");
2737   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2738     s = format (s, "2r3c-2698");
2739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2740     s = format (s, "2r3c-4115");
2741   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2742     s = format (s, "2r3c-mef5cf1");
2743   else
2744     s = format (s, "ILLEGAL");
2745   return s;
2746 }
2747
2748 static u8 *
2749 format_policer_rate_type (u8 * s, va_list * va)
2750 {
2751   u32 i = va_arg (*va, u32);
2752
2753   if (i == SSE2_QOS_RATE_KBPS)
2754     s = format (s, "kbps");
2755   else if (i == SSE2_QOS_RATE_PPS)
2756     s = format (s, "pps");
2757   else
2758     s = format (s, "ILLEGAL");
2759   return s;
2760 }
2761
2762 static u8 *
2763 format_policer_round_type (u8 * s, va_list * va)
2764 {
2765   u32 i = va_arg (*va, u32);
2766
2767   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2768     s = format (s, "closest");
2769   else if (i == SSE2_QOS_ROUND_TO_UP)
2770     s = format (s, "up");
2771   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2772     s = format (s, "down");
2773   else
2774     s = format (s, "ILLEGAL");
2775   return s;
2776 }
2777
2778 static u8 *
2779 format_policer_action_type (u8 * s, va_list * va)
2780 {
2781   u32 i = va_arg (*va, u32);
2782
2783   if (i == SSE2_QOS_ACTION_DROP)
2784     s = format (s, "drop");
2785   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2786     s = format (s, "transmit");
2787   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2788     s = format (s, "mark-and-transmit");
2789   else
2790     s = format (s, "ILLEGAL");
2791   return s;
2792 }
2793
2794 static u8 *
2795 format_dscp (u8 * s, va_list * va)
2796 {
2797   u32 i = va_arg (*va, u32);
2798   char *t = 0;
2799
2800   switch (i)
2801     {
2802 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2803       foreach_vnet_dscp
2804 #undef _
2805     default:
2806       return format (s, "ILLEGAL");
2807     }
2808   s = format (s, "%s", t);
2809   return s;
2810 }
2811
2812 static void
2813 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2814 {
2815   vat_main_t *vam = &vat_main;
2816   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2817
2818   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2819     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2820   else
2821     conform_dscp_str = format (0, "");
2822
2823   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2824     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2825   else
2826     exceed_dscp_str = format (0, "");
2827
2828   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2829     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2830   else
2831     violate_dscp_str = format (0, "");
2832
2833   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2834            "rate type %U, round type %U, %s rate, %s color-aware, "
2835            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2836            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2837            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2838            mp->name,
2839            format_policer_type, mp->type,
2840            ntohl (mp->cir),
2841            ntohl (mp->eir),
2842            clib_net_to_host_u64 (mp->cb),
2843            clib_net_to_host_u64 (mp->eb),
2844            format_policer_rate_type, mp->rate_type,
2845            format_policer_round_type, mp->round_type,
2846            mp->single_rate ? "single" : "dual",
2847            mp->color_aware ? "is" : "not",
2848            ntohl (mp->cir_tokens_per_period),
2849            ntohl (mp->pir_tokens_per_period),
2850            ntohl (mp->scale),
2851            ntohl (mp->current_limit),
2852            ntohl (mp->current_bucket),
2853            ntohl (mp->extended_limit),
2854            ntohl (mp->extended_bucket),
2855            clib_net_to_host_u64 (mp->last_update_time),
2856            format_policer_action_type, mp->conform_action_type,
2857            conform_dscp_str,
2858            format_policer_action_type, mp->exceed_action_type,
2859            exceed_dscp_str,
2860            format_policer_action_type, mp->violate_action_type,
2861            violate_dscp_str);
2862
2863   vec_free (conform_dscp_str);
2864   vec_free (exceed_dscp_str);
2865   vec_free (violate_dscp_str);
2866 }
2867
2868 static void vl_api_policer_details_t_handler_json
2869   (vl_api_policer_details_t * mp)
2870 {
2871   vat_main_t *vam = &vat_main;
2872   vat_json_node_t *node;
2873   u8 *rate_type_str, *round_type_str, *type_str;
2874   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2875
2876   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2877   round_type_str =
2878     format (0, "%U", format_policer_round_type, mp->round_type);
2879   type_str = format (0, "%U", format_policer_type, mp->type);
2880   conform_action_str = format (0, "%U", format_policer_action_type,
2881                                mp->conform_action_type);
2882   exceed_action_str = format (0, "%U", format_policer_action_type,
2883                               mp->exceed_action_type);
2884   violate_action_str = format (0, "%U", format_policer_action_type,
2885                                mp->violate_action_type);
2886
2887   if (VAT_JSON_ARRAY != vam->json_tree.type)
2888     {
2889       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2890       vat_json_init_array (&vam->json_tree);
2891     }
2892   node = vat_json_array_add (&vam->json_tree);
2893
2894   vat_json_init_object (node);
2895   vat_json_object_add_string_copy (node, "name", mp->name);
2896   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2897   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2898   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2899   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2900   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2901   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2902   vat_json_object_add_string_copy (node, "type", type_str);
2903   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2904   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2905   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2906   vat_json_object_add_uint (node, "cir_tokens_per_period",
2907                             ntohl (mp->cir_tokens_per_period));
2908   vat_json_object_add_uint (node, "eir_tokens_per_period",
2909                             ntohl (mp->pir_tokens_per_period));
2910   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2911   vat_json_object_add_uint (node, "current_bucket",
2912                             ntohl (mp->current_bucket));
2913   vat_json_object_add_uint (node, "extended_limit",
2914                             ntohl (mp->extended_limit));
2915   vat_json_object_add_uint (node, "extended_bucket",
2916                             ntohl (mp->extended_bucket));
2917   vat_json_object_add_uint (node, "last_update_time",
2918                             ntohl (mp->last_update_time));
2919   vat_json_object_add_string_copy (node, "conform_action",
2920                                    conform_action_str);
2921   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2922     {
2923       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2924       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2925       vec_free (dscp_str);
2926     }
2927   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2928   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2929     {
2930       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2931       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2932       vec_free (dscp_str);
2933     }
2934   vat_json_object_add_string_copy (node, "violate_action",
2935                                    violate_action_str);
2936   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2937     {
2938       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2939       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2940       vec_free (dscp_str);
2941     }
2942
2943   vec_free (rate_type_str);
2944   vec_free (round_type_str);
2945   vec_free (type_str);
2946   vec_free (conform_action_str);
2947   vec_free (exceed_action_str);
2948   vec_free (violate_action_str);
2949 }
2950
2951 static void
2952 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2953                                            mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   int i, count = ntohl (mp->count);
2957
2958   if (count > 0)
2959     fformat (vam->ofp, "classify table ids (%d) : ", count);
2960   for (i = 0; i < count; i++)
2961     {
2962       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2963       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2964     }
2965   vam->retval = ntohl (mp->retval);
2966   vam->result_ready = 1;
2967 }
2968
2969 static void
2970   vl_api_classify_table_ids_reply_t_handler_json
2971   (vl_api_classify_table_ids_reply_t * mp)
2972 {
2973   vat_main_t *vam = &vat_main;
2974   int i, count = ntohl (mp->count);
2975
2976   if (count > 0)
2977     {
2978       vat_json_node_t node;
2979
2980       vat_json_init_object (&node);
2981       for (i = 0; i < count; i++)
2982         {
2983           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2984         }
2985       vat_json_print (vam->ofp, &node);
2986       vat_json_free (&node);
2987     }
2988   vam->retval = ntohl (mp->retval);
2989   vam->result_ready = 1;
2990 }
2991
2992 static void
2993   vl_api_classify_table_by_interface_reply_t_handler
2994   (vl_api_classify_table_by_interface_reply_t * mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   u32 table_id;
2998
2999   table_id = ntohl (mp->l2_table_id);
3000   if (table_id != ~0)
3001     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3002   else
3003     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3004   table_id = ntohl (mp->ip4_table_id);
3005   if (table_id != ~0)
3006     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3007   else
3008     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3009   table_id = ntohl (mp->ip6_table_id);
3010   if (table_id != ~0)
3011     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3012   else
3013     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3014   vam->retval = ntohl (mp->retval);
3015   vam->result_ready = 1;
3016 }
3017
3018 static void
3019   vl_api_classify_table_by_interface_reply_t_handler_json
3020   (vl_api_classify_table_by_interface_reply_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   vat_json_node_t node;
3024
3025   vat_json_init_object (&node);
3026
3027   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3028   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3029   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3030
3031   vat_json_print (vam->ofp, &node);
3032   vat_json_free (&node);
3033
3034   vam->retval = ntohl (mp->retval);
3035   vam->result_ready = 1;
3036 }
3037
3038 static void vl_api_policer_add_del_reply_t_handler
3039   (vl_api_policer_add_del_reply_t * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   i32 retval = ntohl (mp->retval);
3043   if (vam->async_mode)
3044     {
3045       vam->async_errors += (retval < 0);
3046     }
3047   else
3048     {
3049       vam->retval = retval;
3050       vam->result_ready = 1;
3051       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3052         /*
3053          * Note: this is just barely thread-safe, depends on
3054          * the main thread spinning waiting for an answer...
3055          */
3056         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3057     }
3058 }
3059
3060 static void vl_api_policer_add_del_reply_t_handler_json
3061   (vl_api_policer_add_del_reply_t * mp)
3062 {
3063   vat_main_t *vam = &vat_main;
3064   vat_json_node_t node;
3065
3066   vat_json_init_object (&node);
3067   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3068   vat_json_object_add_uint (&node, "policer_index",
3069                             ntohl (mp->policer_index));
3070
3071   vat_json_print (vam->ofp, &node);
3072   vat_json_free (&node);
3073
3074   vam->retval = ntohl (mp->retval);
3075   vam->result_ready = 1;
3076 }
3077
3078 /* Format hex dump. */
3079 u8 *
3080 format_hex_bytes (u8 * s, va_list * va)
3081 {
3082   u8 *bytes = va_arg (*va, u8 *);
3083   int n_bytes = va_arg (*va, int);
3084   uword i;
3085
3086   /* Print short or long form depending on byte count. */
3087   uword short_form = n_bytes <= 32;
3088   uword indent = format_get_indent (s);
3089
3090   if (n_bytes == 0)
3091     return s;
3092
3093   for (i = 0; i < n_bytes; i++)
3094     {
3095       if (!short_form && (i % 32) == 0)
3096         s = format (s, "%08x: ", i);
3097       s = format (s, "%02x", bytes[i]);
3098       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3099         s = format (s, "\n%U", format_white_space, indent);
3100     }
3101
3102   return s;
3103 }
3104
3105 static void
3106 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3107                                             * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   i32 retval = ntohl (mp->retval);
3111   if (retval == 0)
3112     {
3113       fformat (vam->ofp, "classify table info :\n");
3114       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3115                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3116                ntohl (mp->miss_next_index));
3117       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3118                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3119                ntohl (mp->match_n_vectors));
3120       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3121                ntohl (mp->mask_length));
3122     }
3123   vam->retval = retval;
3124   vam->result_ready = 1;
3125 }
3126
3127 static void
3128   vl_api_classify_table_info_reply_t_handler_json
3129   (vl_api_classify_table_info_reply_t * mp)
3130 {
3131   vat_main_t *vam = &vat_main;
3132   vat_json_node_t node;
3133
3134   i32 retval = ntohl (mp->retval);
3135   if (retval == 0)
3136     {
3137       vat_json_init_object (&node);
3138
3139       vat_json_object_add_int (&node, "sessions",
3140                                ntohl (mp->active_sessions));
3141       vat_json_object_add_int (&node, "nexttbl",
3142                                ntohl (mp->next_table_index));
3143       vat_json_object_add_int (&node, "nextnode",
3144                                ntohl (mp->miss_next_index));
3145       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3146       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3147       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3148       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3149                       ntohl (mp->mask_length), 0);
3150       vat_json_object_add_string_copy (&node, "mask", s);
3151
3152       vat_json_print (vam->ofp, &node);
3153       vat_json_free (&node);
3154     }
3155   vam->retval = ntohl (mp->retval);
3156   vam->result_ready = 1;
3157 }
3158
3159 static void
3160 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3161                                            mp)
3162 {
3163   vat_main_t *vam = &vat_main;
3164
3165   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3166            ntohl (mp->hit_next_index), ntohl (mp->advance),
3167            ntohl (mp->opaque_index));
3168   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3169            ntohl (mp->match_length));
3170 }
3171
3172 static void
3173   vl_api_classify_session_details_t_handler_json
3174   (vl_api_classify_session_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *node = NULL;
3178
3179   if (VAT_JSON_ARRAY != vam->json_tree.type)
3180     {
3181       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3182       vat_json_init_array (&vam->json_tree);
3183     }
3184   node = vat_json_array_add (&vam->json_tree);
3185
3186   vat_json_init_object (node);
3187   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3188   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3189   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3190   u8 *s =
3191     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3192             0);
3193   vat_json_object_add_string_copy (node, "match", s);
3194 }
3195
3196 static void vl_api_pg_create_interface_reply_t_handler
3197   (vl_api_pg_create_interface_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200
3201   vam->retval = ntohl (mp->retval);
3202   vam->result_ready = 1;
3203 }
3204
3205 static void vl_api_pg_create_interface_reply_t_handler_json
3206   (vl_api_pg_create_interface_reply_t * mp)
3207 {
3208   vat_main_t *vam = &vat_main;
3209   vat_json_node_t node;
3210
3211   i32 retval = ntohl (mp->retval);
3212   if (retval == 0)
3213     {
3214       vat_json_init_object (&node);
3215
3216       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3217
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void vl_api_policer_classify_details_t_handler
3226   (vl_api_policer_classify_details_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229
3230   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3231            ntohl (mp->table_index));
3232 }
3233
3234 static void vl_api_policer_classify_details_t_handler_json
3235   (vl_api_policer_classify_details_t * mp)
3236 {
3237   vat_main_t *vam = &vat_main;
3238   vat_json_node_t *node;
3239
3240   if (VAT_JSON_ARRAY != vam->json_tree.type)
3241     {
3242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3243       vat_json_init_array (&vam->json_tree);
3244     }
3245   node = vat_json_array_add (&vam->json_tree);
3246
3247   vat_json_init_object (node);
3248   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3249   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3250 }
3251
3252 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3253   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   i32 retval = ntohl (mp->retval);
3257   if (vam->async_mode)
3258     {
3259       vam->async_errors += (retval < 0);
3260     }
3261   else
3262     {
3263       vam->retval = retval;
3264       vam->sw_if_index = ntohl (mp->sw_if_index);
3265       vam->result_ready = 1;
3266     }
3267 }
3268
3269 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3270   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3271 {
3272   vat_main_t *vam = &vat_main;
3273   vat_json_node_t node;
3274
3275   vat_json_init_object (&node);
3276   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3277   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3278
3279   vat_json_print (vam->ofp, &node);
3280   vat_json_free (&node);
3281
3282   vam->retval = ntohl (mp->retval);
3283   vam->result_ready = 1;
3284 }
3285
3286 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3287 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3288 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3289 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3290
3291 /*
3292  * Generate boilerplate reply handlers, which
3293  * dig the return value out of the xxx_reply_t API message,
3294  * stick it into vam->retval, and set vam->result_ready
3295  *
3296  * Could also do this by pointing N message decode slots at
3297  * a single function, but that could break in subtle ways.
3298  */
3299
3300 #define foreach_standard_reply_retval_handler           \
3301 _(sw_interface_set_flags_reply)                         \
3302 _(sw_interface_add_del_address_reply)                   \
3303 _(sw_interface_set_table_reply)                         \
3304 _(sw_interface_set_vpath_reply)                         \
3305 _(sw_interface_set_l2_bridge_reply)                     \
3306 _(bridge_domain_add_del_reply)                          \
3307 _(sw_interface_set_l2_xconnect_reply)                   \
3308 _(l2fib_add_del_reply)                                  \
3309 _(ip_add_del_route_reply)                               \
3310 _(proxy_arp_add_del_reply)                              \
3311 _(proxy_arp_intfc_enable_disable_reply)                 \
3312 _(mpls_add_del_encap_reply)                             \
3313 _(mpls_add_del_decap_reply)                             \
3314 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3315 _(sw_interface_set_unnumbered_reply)                    \
3316 _(ip_neighbor_add_del_reply)                            \
3317 _(reset_vrf_reply)                                      \
3318 _(oam_add_del_reply)                                    \
3319 _(reset_fib_reply)                                      \
3320 _(dhcp_proxy_config_reply)                              \
3321 _(dhcp_proxy_config_2_reply)                            \
3322 _(dhcp_proxy_set_vss_reply)                             \
3323 _(dhcp_client_config_reply)                             \
3324 _(set_ip_flow_hash_reply)                               \
3325 _(sw_interface_ip6_enable_disable_reply)                \
3326 _(sw_interface_ip6_set_link_local_address_reply)        \
3327 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3328 _(sw_interface_ip6nd_ra_config_reply)                   \
3329 _(set_arp_neighbor_limit_reply)                         \
3330 _(l2_patch_add_del_reply)                               \
3331 _(sr_tunnel_add_del_reply)                              \
3332 _(sr_policy_add_del_reply)                              \
3333 _(sr_multicast_map_add_del_reply)                       \
3334 _(classify_add_del_session_reply)                       \
3335 _(classify_set_interface_ip_table_reply)                \
3336 _(classify_set_interface_l2_tables_reply)               \
3337 _(l2tpv3_set_tunnel_cookies_reply)                      \
3338 _(l2tpv3_interface_enable_disable_reply)                \
3339 _(l2tpv3_set_lookup_key_reply)                          \
3340 _(l2_fib_clear_table_reply)                             \
3341 _(l2_interface_efp_filter_reply)                        \
3342 _(l2_interface_vlan_tag_rewrite_reply)                  \
3343 _(modify_vhost_user_if_reply)                           \
3344 _(delete_vhost_user_if_reply)                           \
3345 _(want_ip4_arp_events_reply)                            \
3346 _(input_acl_set_interface_reply)                        \
3347 _(ipsec_spd_add_del_reply)                              \
3348 _(ipsec_interface_add_del_spd_reply)                    \
3349 _(ipsec_spd_add_del_entry_reply)                        \
3350 _(ipsec_sad_add_del_entry_reply)                        \
3351 _(ipsec_sa_set_key_reply)                               \
3352 _(ikev2_profile_add_del_reply)                          \
3353 _(ikev2_profile_set_auth_reply)                         \
3354 _(ikev2_profile_set_id_reply)                           \
3355 _(ikev2_profile_set_ts_reply)                           \
3356 _(ikev2_set_local_key_reply)                            \
3357 _(delete_loopback_reply)                                \
3358 _(bd_ip_mac_add_del_reply)                              \
3359 _(map_del_domain_reply)                                 \
3360 _(map_add_del_rule_reply)                               \
3361 _(want_interface_events_reply)                          \
3362 _(want_stats_reply)                                     \
3363 _(cop_interface_enable_disable_reply)                   \
3364 _(cop_whitelist_enable_disable_reply)                   \
3365 _(sw_interface_clear_stats_reply)                       \
3366 _(trace_profile_add_reply)                              \
3367 _(trace_profile_apply_reply)                            \
3368 _(trace_profile_del_reply)                              \
3369 _(lisp_add_del_locator_reply)                           \
3370 _(lisp_add_del_local_eid_reply)                         \
3371 _(lisp_add_del_remote_mapping_reply)                    \
3372 _(lisp_add_del_adjacency_reply)                         \
3373 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3374 _(lisp_add_del_map_resolver_reply)                      \
3375 _(lisp_gpe_enable_disable_reply)                        \
3376 _(lisp_gpe_add_del_iface_reply)                         \
3377 _(lisp_enable_disable_reply)                            \
3378 _(lisp_pitr_set_locator_set_reply)                      \
3379 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3380 _(lisp_eid_table_add_del_map_reply)                     \
3381 _(vxlan_gpe_add_del_tunnel_reply)                       \
3382 _(af_packet_delete_reply)                               \
3383 _(policer_classify_set_interface_reply)                 \
3384 _(netmap_create_reply)                                  \
3385 _(netmap_delete_reply)                                  \
3386 _(ipfix_enable_reply)                                   \
3387 _(pg_capture_reply)                                     \
3388 _(pg_enable_disable_reply)                              \
3389 _(ip_source_and_port_range_check_add_del_reply)         \
3390 _(ip_source_and_port_range_check_interface_add_del_reply)
3391
3392 #define _(n)                                    \
3393     static void vl_api_##n##_t_handler          \
3394     (vl_api_##n##_t * mp)                       \
3395     {                                           \
3396         vat_main_t * vam = &vat_main;           \
3397         i32 retval = ntohl(mp->retval);         \
3398         if (vam->async_mode) {                  \
3399             vam->async_errors += (retval < 0);  \
3400         } else {                                \
3401             vam->retval = retval;               \
3402             vam->result_ready = 1;              \
3403         }                                       \
3404     }
3405 foreach_standard_reply_retval_handler;
3406 #undef _
3407
3408 #define _(n)                                    \
3409     static void vl_api_##n##_t_handler_json     \
3410     (vl_api_##n##_t * mp)                       \
3411     {                                           \
3412         vat_main_t * vam = &vat_main;           \
3413         vat_json_node_t node;                   \
3414         vat_json_init_object(&node);            \
3415         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3416         vat_json_print(vam->ofp, &node);        \
3417         vam->retval = ntohl(mp->retval);        \
3418         vam->result_ready = 1;                  \
3419     }
3420 foreach_standard_reply_retval_handler;
3421 #undef _
3422
3423 /*
3424  * Table of message reply handlers, must include boilerplate handlers
3425  * we just generated
3426  */
3427
3428 #define foreach_vpe_api_reply_msg                                       \
3429 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3430 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3431 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3432 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3433 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3434 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3435 _(CLI_REPLY, cli_reply)                                                 \
3436 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3437   sw_interface_add_del_address_reply)                                   \
3438 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3439 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3440 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3441   sw_interface_set_l2_xconnect_reply)                                   \
3442 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3443   sw_interface_set_l2_bridge_reply)                                     \
3444 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3445 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3446 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3447 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3448 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3449 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3450 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3451 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3452 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3453 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3454 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3455 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3456 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3457   proxy_arp_intfc_enable_disable_reply)                                 \
3458 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3459 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3460 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3461 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3462   mpls_ethernet_add_del_tunnel_reply)                                   \
3463 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3464   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3465 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3466   sw_interface_set_unnumbered_reply)                                    \
3467 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3468 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3469 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3470 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3471 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3472 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3473 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3474 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3475 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3476 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3477 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3478 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3479   sw_interface_ip6_enable_disable_reply)                                \
3480 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3481   sw_interface_ip6_set_link_local_address_reply)                        \
3482 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3483   sw_interface_ip6nd_ra_prefix_reply)                                   \
3484 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3485   sw_interface_ip6nd_ra_config_reply)                                   \
3486 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3487 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3488 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3489 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3490 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3491 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3492 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3493 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3494 classify_set_interface_ip_table_reply)                                  \
3495 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3496   classify_set_interface_l2_tables_reply)                               \
3497 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3498 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3499 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3500 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3501 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3502   l2tpv3_interface_enable_disable_reply)                                \
3503 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3504 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3505 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3506 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3507 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3508 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3509 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3510 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3511 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3512 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3513 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3514 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3515 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3516 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3517 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3518 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3519 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3520 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3521 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3522 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3523 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3524 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3525 _(IP_DETAILS, ip_details)                                               \
3526 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3527 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3528 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3529 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3530 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3531 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3532 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3533 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3534 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3535 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3536 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3537 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3538 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3539 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3540 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3541 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3542 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3543 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3544 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3545 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3546 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3547 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3548 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3549 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3550 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3551 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3552 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3553 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3554 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3555 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3556 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3557 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3558 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3559 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3560 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3561 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3562 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3563 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3564 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3565 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3566 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3567 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3568 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3569 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3570 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3571 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3572 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3573 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3574 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3575 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3576 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3577 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3578   lisp_add_del_map_request_itr_rlocs_reply)                             \
3579 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3580   lisp_get_map_request_itr_rlocs_reply)                                 \
3581 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3582 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3583 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3584 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3585 _(POLICER_DETAILS, policer_details)                                     \
3586 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3587 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3588 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3589 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3590 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3591 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3592 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3593 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3594 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3595 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3596 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3597 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3598 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3599 _(IPFIX_DETAILS, ipfix_details)                                         \
3600 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3601 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3602 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3603 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3604 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3605  ip_source_and_port_range_check_add_del_reply)                          \
3606 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3607  ip_source_and_port_range_check_interface_add_del_reply)                \
3608 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3609 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)
3610
3611 /* M: construct, but don't yet send a message */
3612
3613 #define M(T,t)                                  \
3614 do {                                            \
3615     vam->result_ready = 0;                      \
3616     mp = vl_msg_api_alloc(sizeof(*mp));         \
3617     memset (mp, 0, sizeof (*mp));               \
3618     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3619     mp->client_index = vam->my_client_index;    \
3620 } while(0);
3621
3622 #define M2(T,t,n)                               \
3623 do {                                            \
3624     vam->result_ready = 0;                      \
3625     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3626     memset (mp, 0, sizeof (*mp));               \
3627     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3628     mp->client_index = vam->my_client_index;    \
3629 } while(0);
3630
3631
3632 /* S: send a message */
3633 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3634
3635 /* W: wait for results, with timeout */
3636 #define W                                       \
3637 do {                                            \
3638     timeout = vat_time_now (vam) + 1.0;         \
3639                                                 \
3640     while (vat_time_now (vam) < timeout) {      \
3641         if (vam->result_ready == 1) {           \
3642             return (vam->retval);               \
3643         }                                       \
3644     }                                           \
3645     return -99;                                 \
3646 } while(0);
3647
3648 /* W2: wait for results, with timeout */
3649 #define W2(body)                                \
3650 do {                                            \
3651     timeout = vat_time_now (vam) + 1.0;         \
3652                                                 \
3653     while (vat_time_now (vam) < timeout) {      \
3654         if (vam->result_ready == 1) {           \
3655           (body);                               \
3656           return (vam->retval);                 \
3657         }                                       \
3658     }                                           \
3659     return -99;                                 \
3660 } while(0);
3661
3662 /* W_L: wait for results, with timeout */
3663 #define W_L(body)                               \
3664 do {                                            \
3665     timeout = vat_time_now (vam) + 1.0;         \
3666                                                 \
3667     while (vat_time_now (vam) < timeout) {      \
3668         if (vam->result_ready == 1) {           \
3669           (body);                               \
3670           return (vam->retval);                 \
3671         }                                       \
3672     }                                           \
3673     vam->noprint_msg = 0;     \
3674     return -99;                                 \
3675 } while(0);
3676
3677 typedef struct
3678 {
3679   u8 *name;
3680   u32 value;
3681 } name_sort_t;
3682
3683
3684 #define STR_VTR_OP_CASE(op)     \
3685     case L2_VTR_ ## op:         \
3686         return "" # op;
3687
3688 static const char *
3689 str_vtr_op (u32 vtr_op)
3690 {
3691   switch (vtr_op)
3692     {
3693       STR_VTR_OP_CASE (DISABLED);
3694       STR_VTR_OP_CASE (PUSH_1);
3695       STR_VTR_OP_CASE (PUSH_2);
3696       STR_VTR_OP_CASE (POP_1);
3697       STR_VTR_OP_CASE (POP_2);
3698       STR_VTR_OP_CASE (TRANSLATE_1_1);
3699       STR_VTR_OP_CASE (TRANSLATE_1_2);
3700       STR_VTR_OP_CASE (TRANSLATE_2_1);
3701       STR_VTR_OP_CASE (TRANSLATE_2_2);
3702     }
3703
3704   return "UNKNOWN";
3705 }
3706
3707 static int
3708 dump_sub_interface_table (vat_main_t * vam)
3709 {
3710   const sw_interface_subif_t *sub = NULL;
3711
3712   if (vam->json_output)
3713     {
3714       clib_warning
3715         ("JSON output supported only for VPE API calls and dump_stats_table");
3716       return -99;
3717     }
3718
3719   fformat (vam->ofp,
3720            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3721            "Interface", "sw_if_index",
3722            "sub id", "dot1ad", "tags", "outer id",
3723            "inner id", "exact", "default", "outer any", "inner any");
3724
3725   vec_foreach (sub, vam->sw_if_subif_table)
3726   {
3727     fformat (vam->ofp,
3728              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3729              sub->interface_name,
3730              sub->sw_if_index,
3731              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3732              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3733              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3734              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3735     if (sub->vtr_op != L2_VTR_DISABLED)
3736       {
3737         fformat (vam->ofp,
3738                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3739                  "tag1: %d tag2: %d ]\n",
3740                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3741                  sub->vtr_tag1, sub->vtr_tag2);
3742       }
3743   }
3744
3745   return 0;
3746 }
3747
3748 static int
3749 name_sort_cmp (void *a1, void *a2)
3750 {
3751   name_sort_t *n1 = a1;
3752   name_sort_t *n2 = a2;
3753
3754   return strcmp ((char *) n1->name, (char *) n2->name);
3755 }
3756
3757 static int
3758 dump_interface_table (vat_main_t * vam)
3759 {
3760   hash_pair_t *p;
3761   name_sort_t *nses = 0, *ns;
3762
3763   if (vam->json_output)
3764     {
3765       clib_warning
3766         ("JSON output supported only for VPE API calls and dump_stats_table");
3767       return -99;
3768     }
3769
3770   /* *INDENT-OFF* */
3771   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3772   ({
3773     vec_add2 (nses, ns, 1);
3774     ns->name = (u8 *)(p->key);
3775     ns->value = (u32) p->value[0];
3776   }));
3777   /* *INDENT-ON* */
3778
3779   vec_sort_with_function (nses, name_sort_cmp);
3780
3781   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3782   vec_foreach (ns, nses)
3783   {
3784     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3785   }
3786   vec_free (nses);
3787   return 0;
3788 }
3789
3790 static int
3791 dump_ip_table (vat_main_t * vam, int is_ipv6)
3792 {
3793   const ip_details_t *det = NULL;
3794   const ip_address_details_t *address = NULL;
3795   u32 i = ~0;
3796
3797   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3798
3799   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3800   {
3801     i++;
3802     if (!det->present)
3803       {
3804         continue;
3805       }
3806     fformat (vam->ofp, "%-12d\n", i);
3807     fformat (vam->ofp,
3808              "            %-30s%-13s\n", "Address", "Prefix length");
3809     if (!det->addr)
3810       {
3811         continue;
3812       }
3813     vec_foreach (address, det->addr)
3814     {
3815       fformat (vam->ofp,
3816                "            %-30U%-13d\n",
3817                is_ipv6 ? format_ip6_address : format_ip4_address,
3818                address->ip, address->prefix_length);
3819     }
3820   }
3821
3822   return 0;
3823 }
3824
3825 static int
3826 dump_ipv4_table (vat_main_t * vam)
3827 {
3828   if (vam->json_output)
3829     {
3830       clib_warning
3831         ("JSON output supported only for VPE API calls and dump_stats_table");
3832       return -99;
3833     }
3834
3835   return dump_ip_table (vam, 0);
3836 }
3837
3838 static int
3839 dump_ipv6_table (vat_main_t * vam)
3840 {
3841   if (vam->json_output)
3842     {
3843       clib_warning
3844         ("JSON output supported only for VPE API calls and dump_stats_table");
3845       return -99;
3846     }
3847
3848   return dump_ip_table (vam, 1);
3849 }
3850
3851 static char *
3852 counter_type_to_str (u8 counter_type, u8 is_combined)
3853 {
3854   if (!is_combined)
3855     {
3856       switch (counter_type)
3857         {
3858         case VNET_INTERFACE_COUNTER_DROP:
3859           return "drop";
3860         case VNET_INTERFACE_COUNTER_PUNT:
3861           return "punt";
3862         case VNET_INTERFACE_COUNTER_IP4:
3863           return "ip4";
3864         case VNET_INTERFACE_COUNTER_IP6:
3865           return "ip6";
3866         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3867           return "rx-no-buf";
3868         case VNET_INTERFACE_COUNTER_RX_MISS:
3869           return "rx-miss";
3870         case VNET_INTERFACE_COUNTER_RX_ERROR:
3871           return "rx-error";
3872         case VNET_INTERFACE_COUNTER_TX_ERROR:
3873           return "tx-error";
3874         default:
3875           return "INVALID-COUNTER-TYPE";
3876         }
3877     }
3878   else
3879     {
3880       switch (counter_type)
3881         {
3882         case VNET_INTERFACE_COUNTER_RX:
3883           return "rx";
3884         case VNET_INTERFACE_COUNTER_TX:
3885           return "tx";
3886         default:
3887           return "INVALID-COUNTER-TYPE";
3888         }
3889     }
3890 }
3891
3892 static int
3893 dump_stats_table (vat_main_t * vam)
3894 {
3895   vat_json_node_t node;
3896   vat_json_node_t *msg_array;
3897   vat_json_node_t *msg;
3898   vat_json_node_t *counter_array;
3899   vat_json_node_t *counter;
3900   interface_counter_t c;
3901   u64 packets;
3902   ip4_fib_counter_t *c4;
3903   ip6_fib_counter_t *c6;
3904   int i, j;
3905
3906   if (!vam->json_output)
3907     {
3908       clib_warning ("dump_stats_table supported only in JSON format");
3909       return -99;
3910     }
3911
3912   vat_json_init_object (&node);
3913
3914   /* interface counters */
3915   msg_array = vat_json_object_add (&node, "interface_counters");
3916   vat_json_init_array (msg_array);
3917   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3918     {
3919       msg = vat_json_array_add (msg_array);
3920       vat_json_init_object (msg);
3921       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3922                                        (u8 *) counter_type_to_str (i, 0));
3923       vat_json_object_add_int (msg, "is_combined", 0);
3924       counter_array = vat_json_object_add (msg, "data");
3925       vat_json_init_array (counter_array);
3926       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3927         {
3928           packets = vam->simple_interface_counters[i][j];
3929           vat_json_array_add_uint (counter_array, packets);
3930         }
3931     }
3932   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3933     {
3934       msg = vat_json_array_add (msg_array);
3935       vat_json_init_object (msg);
3936       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3937                                        (u8 *) counter_type_to_str (i, 1));
3938       vat_json_object_add_int (msg, "is_combined", 1);
3939       counter_array = vat_json_object_add (msg, "data");
3940       vat_json_init_array (counter_array);
3941       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3942         {
3943           c = vam->combined_interface_counters[i][j];
3944           counter = vat_json_array_add (counter_array);
3945           vat_json_init_object (counter);
3946           vat_json_object_add_uint (counter, "packets", c.packets);
3947           vat_json_object_add_uint (counter, "bytes", c.bytes);
3948         }
3949     }
3950
3951   /* ip4 fib counters */
3952   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3953   vat_json_init_array (msg_array);
3954   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3955     {
3956       msg = vat_json_array_add (msg_array);
3957       vat_json_init_object (msg);
3958       vat_json_object_add_uint (msg, "vrf_id",
3959                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3960       counter_array = vat_json_object_add (msg, "c");
3961       vat_json_init_array (counter_array);
3962       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3963         {
3964           counter = vat_json_array_add (counter_array);
3965           vat_json_init_object (counter);
3966           c4 = &vam->ip4_fib_counters[i][j];
3967           vat_json_object_add_ip4 (counter, "address", c4->address);
3968           vat_json_object_add_uint (counter, "address_length",
3969                                     c4->address_length);
3970           vat_json_object_add_uint (counter, "packets", c4->packets);
3971           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3972         }
3973     }
3974
3975   /* ip6 fib counters */
3976   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3977   vat_json_init_array (msg_array);
3978   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3979     {
3980       msg = vat_json_array_add (msg_array);
3981       vat_json_init_object (msg);
3982       vat_json_object_add_uint (msg, "vrf_id",
3983                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3984       counter_array = vat_json_object_add (msg, "c");
3985       vat_json_init_array (counter_array);
3986       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3987         {
3988           counter = vat_json_array_add (counter_array);
3989           vat_json_init_object (counter);
3990           c6 = &vam->ip6_fib_counters[i][j];
3991           vat_json_object_add_ip6 (counter, "address", c6->address);
3992           vat_json_object_add_uint (counter, "address_length",
3993                                     c6->address_length);
3994           vat_json_object_add_uint (counter, "packets", c6->packets);
3995           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3996         }
3997     }
3998
3999   vat_json_print (vam->ofp, &node);
4000   vat_json_free (&node);
4001
4002   return 0;
4003 }
4004
4005 int
4006 exec (vat_main_t * vam)
4007 {
4008   api_main_t *am = &api_main;
4009   vl_api_cli_request_t *mp;
4010   f64 timeout;
4011   void *oldheap;
4012   u8 *cmd = 0;
4013   unformat_input_t *i = vam->input;
4014
4015   if (vec_len (i->buffer) == 0)
4016     return -1;
4017
4018   if (vam->exec_mode == 0 && unformat (i, "mode"))
4019     {
4020       vam->exec_mode = 1;
4021       return 0;
4022     }
4023   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4024     {
4025       vam->exec_mode = 0;
4026       return 0;
4027     }
4028
4029
4030   M (CLI_REQUEST, cli_request);
4031
4032   /*
4033    * Copy cmd into shared memory.
4034    * In order for the CLI command to work, it
4035    * must be a vector ending in \n, not a C-string ending
4036    * in \n\0.
4037    */
4038   pthread_mutex_lock (&am->vlib_rp->mutex);
4039   oldheap = svm_push_data_heap (am->vlib_rp);
4040
4041   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4042   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4043
4044   svm_pop_heap (oldheap);
4045   pthread_mutex_unlock (&am->vlib_rp->mutex);
4046
4047   mp->cmd_in_shmem = (u64) cmd;
4048   S;
4049   timeout = vat_time_now (vam) + 10.0;
4050
4051   while (vat_time_now (vam) < timeout)
4052     {
4053       if (vam->result_ready == 1)
4054         {
4055           u8 *free_me;
4056           if (vam->shmem_result != NULL)
4057             fformat (vam->ofp, "%s", vam->shmem_result);
4058           pthread_mutex_lock (&am->vlib_rp->mutex);
4059           oldheap = svm_push_data_heap (am->vlib_rp);
4060
4061           free_me = (u8 *) vam->shmem_result;
4062           vec_free (free_me);
4063
4064           svm_pop_heap (oldheap);
4065           pthread_mutex_unlock (&am->vlib_rp->mutex);
4066           return 0;
4067         }
4068     }
4069   return -99;
4070 }
4071
4072 static int
4073 api_create_loopback (vat_main_t * vam)
4074 {
4075   unformat_input_t *i = vam->input;
4076   vl_api_create_loopback_t *mp;
4077   f64 timeout;
4078   u8 mac_address[6];
4079   u8 mac_set = 0;
4080
4081   memset (mac_address, 0, sizeof (mac_address));
4082
4083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4084     {
4085       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4086         mac_set = 1;
4087       else
4088         break;
4089     }
4090
4091   /* Construct the API message */
4092   M (CREATE_LOOPBACK, create_loopback);
4093   if (mac_set)
4094     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4095
4096   S;
4097   W;
4098 }
4099
4100 static int
4101 api_delete_loopback (vat_main_t * vam)
4102 {
4103   unformat_input_t *i = vam->input;
4104   vl_api_delete_loopback_t *mp;
4105   f64 timeout;
4106   u32 sw_if_index = ~0;
4107
4108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4109     {
4110       if (unformat (i, "sw_if_index %d", &sw_if_index))
4111         ;
4112       else
4113         break;
4114     }
4115
4116   if (sw_if_index == ~0)
4117     {
4118       errmsg ("missing sw_if_index\n");
4119       return -99;
4120     }
4121
4122   /* Construct the API message */
4123   M (DELETE_LOOPBACK, delete_loopback);
4124   mp->sw_if_index = ntohl (sw_if_index);
4125
4126   S;
4127   W;
4128 }
4129
4130 static int
4131 api_want_stats (vat_main_t * vam)
4132 {
4133   unformat_input_t *i = vam->input;
4134   vl_api_want_stats_t *mp;
4135   f64 timeout;
4136   int enable = -1;
4137
4138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4139     {
4140       if (unformat (i, "enable"))
4141         enable = 1;
4142       else if (unformat (i, "disable"))
4143         enable = 0;
4144       else
4145         break;
4146     }
4147
4148   if (enable == -1)
4149     {
4150       errmsg ("missing enable|disable\n");
4151       return -99;
4152     }
4153
4154   M (WANT_STATS, want_stats);
4155   mp->enable_disable = enable;
4156
4157   S;
4158   W;
4159 }
4160
4161 static int
4162 api_want_interface_events (vat_main_t * vam)
4163 {
4164   unformat_input_t *i = vam->input;
4165   vl_api_want_interface_events_t *mp;
4166   f64 timeout;
4167   int enable = -1;
4168
4169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4170     {
4171       if (unformat (i, "enable"))
4172         enable = 1;
4173       else if (unformat (i, "disable"))
4174         enable = 0;
4175       else
4176         break;
4177     }
4178
4179   if (enable == -1)
4180     {
4181       errmsg ("missing enable|disable\n");
4182       return -99;
4183     }
4184
4185   M (WANT_INTERFACE_EVENTS, want_interface_events);
4186   mp->enable_disable = enable;
4187
4188   vam->interface_event_display = enable;
4189
4190   S;
4191   W;
4192 }
4193
4194
4195 /* Note: non-static, called once to set up the initial intfc table */
4196 int
4197 api_sw_interface_dump (vat_main_t * vam)
4198 {
4199   vl_api_sw_interface_dump_t *mp;
4200   f64 timeout;
4201   hash_pair_t *p;
4202   name_sort_t *nses = 0, *ns;
4203   sw_interface_subif_t *sub = NULL;
4204
4205   /* Toss the old name table */
4206   /* *INDENT-OFF* */
4207   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4208   ({
4209     vec_add2 (nses, ns, 1);
4210     ns->name = (u8 *)(p->key);
4211     ns->value = (u32) p->value[0];
4212   }));
4213   /* *INDENT-ON* */
4214
4215   hash_free (vam->sw_if_index_by_interface_name);
4216
4217   vec_foreach (ns, nses) vec_free (ns->name);
4218
4219   vec_free (nses);
4220
4221   vec_foreach (sub, vam->sw_if_subif_table)
4222   {
4223     vec_free (sub->interface_name);
4224   }
4225   vec_free (vam->sw_if_subif_table);
4226
4227   /* recreate the interface name hash table */
4228   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4229
4230   /* Get list of ethernets */
4231   M (SW_INTERFACE_DUMP, sw_interface_dump);
4232   mp->name_filter_valid = 1;
4233   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4234   S;
4235
4236   /* and local / loopback interfaces */
4237   M (SW_INTERFACE_DUMP, sw_interface_dump);
4238   mp->name_filter_valid = 1;
4239   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4240   S;
4241
4242
4243   /* and vxlan-gpe tunnel interfaces */
4244   M (SW_INTERFACE_DUMP, sw_interface_dump);
4245   mp->name_filter_valid = 1;
4246   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4247            sizeof (mp->name_filter) - 1);
4248   S;
4249
4250   /* and vxlan tunnel interfaces */
4251   M (SW_INTERFACE_DUMP, sw_interface_dump);
4252   mp->name_filter_valid = 1;
4253   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4254   S;
4255
4256   /* and host (af_packet) interfaces */
4257   M (SW_INTERFACE_DUMP, sw_interface_dump);
4258   mp->name_filter_valid = 1;
4259   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4260   S;
4261
4262   /* and l2tpv3 tunnel interfaces */
4263   M (SW_INTERFACE_DUMP, sw_interface_dump);
4264   mp->name_filter_valid = 1;
4265   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4266            sizeof (mp->name_filter) - 1);
4267   S;
4268
4269   /* and GRE tunnel interfaces */
4270   M (SW_INTERFACE_DUMP, sw_interface_dump);
4271   mp->name_filter_valid = 1;
4272   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4273   S;
4274
4275   /* Use a control ping for synchronization */
4276   {
4277     vl_api_control_ping_t *mp;
4278     M (CONTROL_PING, control_ping);
4279     S;
4280   }
4281   W;
4282 }
4283
4284 static int
4285 api_sw_interface_set_flags (vat_main_t * vam)
4286 {
4287   unformat_input_t *i = vam->input;
4288   vl_api_sw_interface_set_flags_t *mp;
4289   f64 timeout;
4290   u32 sw_if_index;
4291   u8 sw_if_index_set = 0;
4292   u8 admin_up = 0, link_up = 0;
4293
4294   /* Parse args required to build the message */
4295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4296     {
4297       if (unformat (i, "admin-up"))
4298         admin_up = 1;
4299       else if (unformat (i, "admin-down"))
4300         admin_up = 0;
4301       else if (unformat (i, "link-up"))
4302         link_up = 1;
4303       else if (unformat (i, "link-down"))
4304         link_up = 0;
4305       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4306         sw_if_index_set = 1;
4307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4308         sw_if_index_set = 1;
4309       else
4310         break;
4311     }
4312
4313   if (sw_if_index_set == 0)
4314     {
4315       errmsg ("missing interface name or sw_if_index\n");
4316       return -99;
4317     }
4318
4319   /* Construct the API message */
4320   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4321   mp->sw_if_index = ntohl (sw_if_index);
4322   mp->admin_up_down = admin_up;
4323   mp->link_up_down = link_up;
4324
4325   /* send it... */
4326   S;
4327
4328   /* Wait for a reply, return the good/bad news... */
4329   W;
4330 }
4331
4332 static int
4333 api_sw_interface_clear_stats (vat_main_t * vam)
4334 {
4335   unformat_input_t *i = vam->input;
4336   vl_api_sw_interface_clear_stats_t *mp;
4337   f64 timeout;
4338   u32 sw_if_index;
4339   u8 sw_if_index_set = 0;
4340
4341   /* Parse args required to build the message */
4342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4343     {
4344       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4345         sw_if_index_set = 1;
4346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4347         sw_if_index_set = 1;
4348       else
4349         break;
4350     }
4351
4352   /* Construct the API message */
4353   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4354
4355   if (sw_if_index_set == 1)
4356     mp->sw_if_index = ntohl (sw_if_index);
4357   else
4358     mp->sw_if_index = ~0;
4359
4360   /* send it... */
4361   S;
4362
4363   /* Wait for a reply, return the good/bad news... */
4364   W;
4365 }
4366
4367 static int
4368 api_sw_interface_add_del_address (vat_main_t * vam)
4369 {
4370   unformat_input_t *i = vam->input;
4371   vl_api_sw_interface_add_del_address_t *mp;
4372   f64 timeout;
4373   u32 sw_if_index;
4374   u8 sw_if_index_set = 0;
4375   u8 is_add = 1, del_all = 0;
4376   u32 address_length = 0;
4377   u8 v4_address_set = 0;
4378   u8 v6_address_set = 0;
4379   ip4_address_t v4address;
4380   ip6_address_t v6address;
4381
4382   /* Parse args required to build the message */
4383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4384     {
4385       if (unformat (i, "del-all"))
4386         del_all = 1;
4387       else if (unformat (i, "del"))
4388         is_add = 0;
4389       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4390         sw_if_index_set = 1;
4391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4392         sw_if_index_set = 1;
4393       else if (unformat (i, "%U/%d",
4394                          unformat_ip4_address, &v4address, &address_length))
4395         v4_address_set = 1;
4396       else if (unformat (i, "%U/%d",
4397                          unformat_ip6_address, &v6address, &address_length))
4398         v6_address_set = 1;
4399       else
4400         break;
4401     }
4402
4403   if (sw_if_index_set == 0)
4404     {
4405       errmsg ("missing interface name or sw_if_index\n");
4406       return -99;
4407     }
4408   if (v4_address_set && v6_address_set)
4409     {
4410       errmsg ("both v4 and v6 addresses set\n");
4411       return -99;
4412     }
4413   if (!v4_address_set && !v6_address_set && !del_all)
4414     {
4415       errmsg ("no addresses set\n");
4416       return -99;
4417     }
4418
4419   /* Construct the API message */
4420   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4421
4422   mp->sw_if_index = ntohl (sw_if_index);
4423   mp->is_add = is_add;
4424   mp->del_all = del_all;
4425   if (v6_address_set)
4426     {
4427       mp->is_ipv6 = 1;
4428       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4429     }
4430   else
4431     {
4432       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4433     }
4434   mp->address_length = address_length;
4435
4436   /* send it... */
4437   S;
4438
4439   /* Wait for a reply, return good/bad news  */
4440   W;
4441 }
4442
4443 static int
4444 api_sw_interface_set_table (vat_main_t * vam)
4445 {
4446   unformat_input_t *i = vam->input;
4447   vl_api_sw_interface_set_table_t *mp;
4448   f64 timeout;
4449   u32 sw_if_index, vrf_id = 0;
4450   u8 sw_if_index_set = 0;
4451   u8 is_ipv6 = 0;
4452
4453   /* Parse args required to build the message */
4454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4455     {
4456       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4457         sw_if_index_set = 1;
4458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4459         sw_if_index_set = 1;
4460       else if (unformat (i, "vrf %d", &vrf_id))
4461         ;
4462       else if (unformat (i, "ipv6"))
4463         is_ipv6 = 1;
4464       else
4465         break;
4466     }
4467
4468   if (sw_if_index_set == 0)
4469     {
4470       errmsg ("missing interface name or sw_if_index\n");
4471       return -99;
4472     }
4473
4474   /* Construct the API message */
4475   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4476
4477   mp->sw_if_index = ntohl (sw_if_index);
4478   mp->is_ipv6 = is_ipv6;
4479   mp->vrf_id = ntohl (vrf_id);
4480
4481   /* send it... */
4482   S;
4483
4484   /* Wait for a reply... */
4485   W;
4486 }
4487
4488 static int
4489 api_sw_interface_set_vpath (vat_main_t * vam)
4490 {
4491   unformat_input_t *i = vam->input;
4492   vl_api_sw_interface_set_vpath_t *mp;
4493   f64 timeout;
4494   u32 sw_if_index = 0;
4495   u8 sw_if_index_set = 0;
4496   u8 is_enable = 0;
4497
4498   /* Parse args required to build the message */
4499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4500     {
4501       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4502         sw_if_index_set = 1;
4503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4504         sw_if_index_set = 1;
4505       else if (unformat (i, "enable"))
4506         is_enable = 1;
4507       else if (unformat (i, "disable"))
4508         is_enable = 0;
4509       else
4510         break;
4511     }
4512
4513   if (sw_if_index_set == 0)
4514     {
4515       errmsg ("missing interface name or sw_if_index\n");
4516       return -99;
4517     }
4518
4519   /* Construct the API message */
4520   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4521
4522   mp->sw_if_index = ntohl (sw_if_index);
4523   mp->enable = is_enable;
4524
4525   /* send it... */
4526   S;
4527
4528   /* Wait for a reply... */
4529   W;
4530 }
4531
4532 static int
4533 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4534 {
4535   unformat_input_t *i = vam->input;
4536   vl_api_sw_interface_set_l2_xconnect_t *mp;
4537   f64 timeout;
4538   u32 rx_sw_if_index;
4539   u8 rx_sw_if_index_set = 0;
4540   u32 tx_sw_if_index;
4541   u8 tx_sw_if_index_set = 0;
4542   u8 enable = 1;
4543
4544   /* Parse args required to build the message */
4545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4546     {
4547       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4548         rx_sw_if_index_set = 1;
4549       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4550         tx_sw_if_index_set = 1;
4551       else if (unformat (i, "rx"))
4552         {
4553           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4554             {
4555               if (unformat (i, "%U", unformat_sw_if_index, vam,
4556                             &rx_sw_if_index))
4557                 rx_sw_if_index_set = 1;
4558             }
4559           else
4560             break;
4561         }
4562       else if (unformat (i, "tx"))
4563         {
4564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4565             {
4566               if (unformat (i, "%U", unformat_sw_if_index, vam,
4567                             &tx_sw_if_index))
4568                 tx_sw_if_index_set = 1;
4569             }
4570           else
4571             break;
4572         }
4573       else if (unformat (i, "enable"))
4574         enable = 1;
4575       else if (unformat (i, "disable"))
4576         enable = 0;
4577       else
4578         break;
4579     }
4580
4581   if (rx_sw_if_index_set == 0)
4582     {
4583       errmsg ("missing rx interface name or rx_sw_if_index\n");
4584       return -99;
4585     }
4586
4587   if (enable && (tx_sw_if_index_set == 0))
4588     {
4589       errmsg ("missing tx interface name or tx_sw_if_index\n");
4590       return -99;
4591     }
4592
4593   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4594
4595   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4596   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4597   mp->enable = enable;
4598
4599   S;
4600   W;
4601   /* NOTREACHED */
4602   return 0;
4603 }
4604
4605 static int
4606 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4607 {
4608   unformat_input_t *i = vam->input;
4609   vl_api_sw_interface_set_l2_bridge_t *mp;
4610   f64 timeout;
4611   u32 rx_sw_if_index;
4612   u8 rx_sw_if_index_set = 0;
4613   u32 bd_id;
4614   u8 bd_id_set = 0;
4615   u8 bvi = 0;
4616   u32 shg = 0;
4617   u8 enable = 1;
4618
4619   /* Parse args required to build the message */
4620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4621     {
4622       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4623         rx_sw_if_index_set = 1;
4624       else if (unformat (i, "bd_id %d", &bd_id))
4625         bd_id_set = 1;
4626       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4627         rx_sw_if_index_set = 1;
4628       else if (unformat (i, "shg %d", &shg))
4629         ;
4630       else if (unformat (i, "bvi"))
4631         bvi = 1;
4632       else if (unformat (i, "enable"))
4633         enable = 1;
4634       else if (unformat (i, "disable"))
4635         enable = 0;
4636       else
4637         break;
4638     }
4639
4640   if (rx_sw_if_index_set == 0)
4641     {
4642       errmsg ("missing rx interface name or sw_if_index\n");
4643       return -99;
4644     }
4645
4646   if (enable && (bd_id_set == 0))
4647     {
4648       errmsg ("missing bridge domain\n");
4649       return -99;
4650     }
4651
4652   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4653
4654   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4655   mp->bd_id = ntohl (bd_id);
4656   mp->shg = (u8) shg;
4657   mp->bvi = bvi;
4658   mp->enable = enable;
4659
4660   S;
4661   W;
4662   /* NOTREACHED */
4663   return 0;
4664 }
4665
4666 static int
4667 api_bridge_domain_dump (vat_main_t * vam)
4668 {
4669   unformat_input_t *i = vam->input;
4670   vl_api_bridge_domain_dump_t *mp;
4671   f64 timeout;
4672   u32 bd_id = ~0;
4673
4674   /* Parse args required to build the message */
4675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4676     {
4677       if (unformat (i, "bd_id %d", &bd_id))
4678         ;
4679       else
4680         break;
4681     }
4682
4683   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4684   mp->bd_id = ntohl (bd_id);
4685   S;
4686
4687   /* Use a control ping for synchronization */
4688   {
4689     vl_api_control_ping_t *mp;
4690     M (CONTROL_PING, control_ping);
4691     S;
4692   }
4693
4694   W;
4695   /* NOTREACHED */
4696   return 0;
4697 }
4698
4699 static int
4700 api_bridge_domain_add_del (vat_main_t * vam)
4701 {
4702   unformat_input_t *i = vam->input;
4703   vl_api_bridge_domain_add_del_t *mp;
4704   f64 timeout;
4705   u32 bd_id = ~0;
4706   u8 is_add = 1;
4707   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4708
4709   /* Parse args required to build the message */
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "bd_id %d", &bd_id))
4713         ;
4714       else if (unformat (i, "flood %d", &flood))
4715         ;
4716       else if (unformat (i, "uu-flood %d", &uu_flood))
4717         ;
4718       else if (unformat (i, "forward %d", &forward))
4719         ;
4720       else if (unformat (i, "learn %d", &learn))
4721         ;
4722       else if (unformat (i, "arp-term %d", &arp_term))
4723         ;
4724       else if (unformat (i, "del"))
4725         {
4726           is_add = 0;
4727           flood = uu_flood = forward = learn = 0;
4728         }
4729       else
4730         break;
4731     }
4732
4733   if (bd_id == ~0)
4734     {
4735       errmsg ("missing bridge domain\n");
4736       return -99;
4737     }
4738
4739   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4740
4741   mp->bd_id = ntohl (bd_id);
4742   mp->flood = flood;
4743   mp->uu_flood = uu_flood;
4744   mp->forward = forward;
4745   mp->learn = learn;
4746   mp->arp_term = arp_term;
4747   mp->is_add = is_add;
4748
4749   S;
4750   W;
4751   /* NOTREACHED */
4752   return 0;
4753 }
4754
4755 static int
4756 api_l2fib_add_del (vat_main_t * vam)
4757 {
4758   unformat_input_t *i = vam->input;
4759   vl_api_l2fib_add_del_t *mp;
4760   f64 timeout;
4761   u64 mac = 0;
4762   u8 mac_set = 0;
4763   u32 bd_id;
4764   u8 bd_id_set = 0;
4765   u32 sw_if_index;
4766   u8 sw_if_index_set = 0;
4767   u8 is_add = 1;
4768   u8 static_mac = 0;
4769   u8 filter_mac = 0;
4770   u8 bvi_mac = 0;
4771   int count = 1;
4772   f64 before = 0;
4773   int j;
4774
4775   /* Parse args required to build the message */
4776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4777     {
4778       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4779         mac_set = 1;
4780       else if (unformat (i, "bd_id %d", &bd_id))
4781         bd_id_set = 1;
4782       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4783         sw_if_index_set = 1;
4784       else if (unformat (i, "sw_if"))
4785         {
4786           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787             {
4788               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4789                 sw_if_index_set = 1;
4790             }
4791           else
4792             break;
4793         }
4794       else if (unformat (i, "static"))
4795         static_mac = 1;
4796       else if (unformat (i, "filter"))
4797         {
4798           filter_mac = 1;
4799           static_mac = 1;
4800         }
4801       else if (unformat (i, "bvi"))
4802         {
4803           bvi_mac = 1;
4804           static_mac = 1;
4805         }
4806       else if (unformat (i, "del"))
4807         is_add = 0;
4808       else if (unformat (i, "count %d", &count))
4809         ;
4810       else
4811         break;
4812     }
4813
4814   if (mac_set == 0)
4815     {
4816       errmsg ("missing mac address\n");
4817       return -99;
4818     }
4819
4820   if (bd_id_set == 0)
4821     {
4822       errmsg ("missing bridge domain\n");
4823       return -99;
4824     }
4825
4826   if (is_add && (sw_if_index_set == 0))
4827     {
4828       errmsg ("missing interface name or sw_if_index\n");
4829       return -99;
4830     }
4831
4832   if (count > 1)
4833     {
4834       /* Turn on async mode */
4835       vam->async_mode = 1;
4836       vam->async_errors = 0;
4837       before = vat_time_now (vam);
4838     }
4839
4840   for (j = 0; j < count; j++)
4841     {
4842       M (L2FIB_ADD_DEL, l2fib_add_del);
4843
4844       mp->mac = mac;
4845       mp->bd_id = ntohl (bd_id);
4846       mp->is_add = is_add;
4847
4848       if (is_add)
4849         {
4850           mp->sw_if_index = ntohl (sw_if_index);
4851           mp->static_mac = static_mac;
4852           mp->filter_mac = filter_mac;
4853           mp->bvi_mac = bvi_mac;
4854         }
4855       increment_mac_address (&mac);
4856       /* send it... */
4857       S;
4858     }
4859
4860   if (count > 1)
4861     {
4862       vl_api_control_ping_t *mp;
4863       f64 after;
4864
4865       /* Shut off async mode */
4866       vam->async_mode = 0;
4867
4868       M (CONTROL_PING, control_ping);
4869       S;
4870
4871       timeout = vat_time_now (vam) + 1.0;
4872       while (vat_time_now (vam) < timeout)
4873         if (vam->result_ready == 1)
4874           goto out;
4875       vam->retval = -99;
4876
4877     out:
4878       if (vam->retval == -99)
4879         errmsg ("timeout\n");
4880
4881       if (vam->async_errors > 0)
4882         {
4883           errmsg ("%d asynchronous errors\n", vam->async_errors);
4884           vam->retval = -98;
4885         }
4886       vam->async_errors = 0;
4887       after = vat_time_now (vam);
4888
4889       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4890                count, after - before, count / (after - before));
4891     }
4892   else
4893     {
4894       /* Wait for a reply... */
4895       W;
4896     }
4897   /* Return the good/bad news */
4898   return (vam->retval);
4899 }
4900
4901 static int
4902 api_l2_flags (vat_main_t * vam)
4903 {
4904   unformat_input_t *i = vam->input;
4905   vl_api_l2_flags_t *mp;
4906   f64 timeout;
4907   u32 sw_if_index;
4908   u32 feature_bitmap = 0;
4909   u8 sw_if_index_set = 0;
4910
4911   /* Parse args required to build the message */
4912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4913     {
4914       if (unformat (i, "sw_if_index %d", &sw_if_index))
4915         sw_if_index_set = 1;
4916       else if (unformat (i, "sw_if"))
4917         {
4918           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4919             {
4920               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4921                 sw_if_index_set = 1;
4922             }
4923           else
4924             break;
4925         }
4926       else if (unformat (i, "learn"))
4927         feature_bitmap |= L2INPUT_FEAT_LEARN;
4928       else if (unformat (i, "forward"))
4929         feature_bitmap |= L2INPUT_FEAT_FWD;
4930       else if (unformat (i, "flood"))
4931         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4932       else if (unformat (i, "uu-flood"))
4933         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4934       else
4935         break;
4936     }
4937
4938   if (sw_if_index_set == 0)
4939     {
4940       errmsg ("missing interface name or sw_if_index\n");
4941       return -99;
4942     }
4943
4944   M (L2_FLAGS, l2_flags);
4945
4946   mp->sw_if_index = ntohl (sw_if_index);
4947   mp->feature_bitmap = ntohl (feature_bitmap);
4948
4949   S;
4950   W;
4951   /* NOTREACHED */
4952   return 0;
4953 }
4954
4955 static int
4956 api_bridge_flags (vat_main_t * vam)
4957 {
4958   unformat_input_t *i = vam->input;
4959   vl_api_bridge_flags_t *mp;
4960   f64 timeout;
4961   u32 bd_id;
4962   u8 bd_id_set = 0;
4963   u8 is_set = 1;
4964   u32 flags = 0;
4965
4966   /* Parse args required to build the message */
4967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4968     {
4969       if (unformat (i, "bd_id %d", &bd_id))
4970         bd_id_set = 1;
4971       else if (unformat (i, "learn"))
4972         flags |= L2_LEARN;
4973       else if (unformat (i, "forward"))
4974         flags |= L2_FWD;
4975       else if (unformat (i, "flood"))
4976         flags |= L2_FLOOD;
4977       else if (unformat (i, "uu-flood"))
4978         flags |= L2_UU_FLOOD;
4979       else if (unformat (i, "arp-term"))
4980         flags |= L2_ARP_TERM;
4981       else if (unformat (i, "off"))
4982         is_set = 0;
4983       else if (unformat (i, "disable"))
4984         is_set = 0;
4985       else
4986         break;
4987     }
4988
4989   if (bd_id_set == 0)
4990     {
4991       errmsg ("missing bridge domain\n");
4992       return -99;
4993     }
4994
4995   M (BRIDGE_FLAGS, bridge_flags);
4996
4997   mp->bd_id = ntohl (bd_id);
4998   mp->feature_bitmap = ntohl (flags);
4999   mp->is_set = is_set;
5000
5001   S;
5002   W;
5003   /* NOTREACHED */
5004   return 0;
5005 }
5006
5007 static int
5008 api_bd_ip_mac_add_del (vat_main_t * vam)
5009 {
5010   unformat_input_t *i = vam->input;
5011   vl_api_bd_ip_mac_add_del_t *mp;
5012   f64 timeout;
5013   u32 bd_id;
5014   u8 is_ipv6 = 0;
5015   u8 is_add = 1;
5016   u8 bd_id_set = 0;
5017   u8 ip_set = 0;
5018   u8 mac_set = 0;
5019   ip4_address_t v4addr;
5020   ip6_address_t v6addr;
5021   u8 macaddr[6];
5022
5023
5024   /* Parse args required to build the message */
5025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5026     {
5027       if (unformat (i, "bd_id %d", &bd_id))
5028         {
5029           bd_id_set++;
5030         }
5031       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5032         {
5033           ip_set++;
5034         }
5035       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5036         {
5037           ip_set++;
5038           is_ipv6++;
5039         }
5040       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5041         {
5042           mac_set++;
5043         }
5044       else if (unformat (i, "del"))
5045         is_add = 0;
5046       else
5047         break;
5048     }
5049
5050   if (bd_id_set == 0)
5051     {
5052       errmsg ("missing bridge domain\n");
5053       return -99;
5054     }
5055   else if (ip_set == 0)
5056     {
5057       errmsg ("missing IP address\n");
5058       return -99;
5059     }
5060   else if (mac_set == 0)
5061     {
5062       errmsg ("missing MAC address\n");
5063       return -99;
5064     }
5065
5066   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5067
5068   mp->bd_id = ntohl (bd_id);
5069   mp->is_ipv6 = is_ipv6;
5070   mp->is_add = is_add;
5071   if (is_ipv6)
5072     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5073   else
5074     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5075   clib_memcpy (mp->mac_address, macaddr, 6);
5076   S;
5077   W;
5078   /* NOTREACHED */
5079   return 0;
5080 }
5081
5082 static int
5083 api_tap_connect (vat_main_t * vam)
5084 {
5085   unformat_input_t *i = vam->input;
5086   vl_api_tap_connect_t *mp;
5087   f64 timeout;
5088   u8 mac_address[6];
5089   u8 random_mac = 1;
5090   u8 name_set = 0;
5091   u8 *tap_name;
5092
5093   memset (mac_address, 0, sizeof (mac_address));
5094
5095   /* Parse args required to build the message */
5096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5097     {
5098       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5099         {
5100           random_mac = 0;
5101         }
5102       else if (unformat (i, "random-mac"))
5103         random_mac = 1;
5104       else if (unformat (i, "tapname %s", &tap_name))
5105         name_set = 1;
5106       else
5107         break;
5108     }
5109
5110   if (name_set == 0)
5111     {
5112       errmsg ("missing tap name\n");
5113       return -99;
5114     }
5115   if (vec_len (tap_name) > 63)
5116     {
5117       errmsg ("tap name too long\n");
5118     }
5119   vec_add1 (tap_name, 0);
5120
5121   /* Construct the API message */
5122   M (TAP_CONNECT, tap_connect);
5123
5124   mp->use_random_mac = random_mac;
5125   clib_memcpy (mp->mac_address, mac_address, 6);
5126   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5127   vec_free (tap_name);
5128
5129   /* send it... */
5130   S;
5131
5132   /* Wait for a reply... */
5133   W;
5134 }
5135
5136 static int
5137 api_tap_modify (vat_main_t * vam)
5138 {
5139   unformat_input_t *i = vam->input;
5140   vl_api_tap_modify_t *mp;
5141   f64 timeout;
5142   u8 mac_address[6];
5143   u8 random_mac = 1;
5144   u8 name_set = 0;
5145   u8 *tap_name;
5146   u32 sw_if_index = ~0;
5147   u8 sw_if_index_set = 0;
5148
5149   memset (mac_address, 0, sizeof (mac_address));
5150
5151   /* Parse args required to build the message */
5152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5153     {
5154       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5155         sw_if_index_set = 1;
5156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5157         sw_if_index_set = 1;
5158       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5159         {
5160           random_mac = 0;
5161         }
5162       else if (unformat (i, "random-mac"))
5163         random_mac = 1;
5164       else if (unformat (i, "tapname %s", &tap_name))
5165         name_set = 1;
5166       else
5167         break;
5168     }
5169
5170   if (sw_if_index_set == 0)
5171     {
5172       errmsg ("missing vpp interface name");
5173       return -99;
5174     }
5175   if (name_set == 0)
5176     {
5177       errmsg ("missing tap name\n");
5178       return -99;
5179     }
5180   if (vec_len (tap_name) > 63)
5181     {
5182       errmsg ("tap name too long\n");
5183     }
5184   vec_add1 (tap_name, 0);
5185
5186   /* Construct the API message */
5187   M (TAP_MODIFY, tap_modify);
5188
5189   mp->use_random_mac = random_mac;
5190   mp->sw_if_index = ntohl (sw_if_index);
5191   clib_memcpy (mp->mac_address, mac_address, 6);
5192   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5193   vec_free (tap_name);
5194
5195   /* send it... */
5196   S;
5197
5198   /* Wait for a reply... */
5199   W;
5200 }
5201
5202 static int
5203 api_tap_delete (vat_main_t * vam)
5204 {
5205   unformat_input_t *i = vam->input;
5206   vl_api_tap_delete_t *mp;
5207   f64 timeout;
5208   u32 sw_if_index = ~0;
5209   u8 sw_if_index_set = 0;
5210
5211   /* Parse args required to build the message */
5212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5213     {
5214       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5215         sw_if_index_set = 1;
5216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5217         sw_if_index_set = 1;
5218       else
5219         break;
5220     }
5221
5222   if (sw_if_index_set == 0)
5223     {
5224       errmsg ("missing vpp interface name");
5225       return -99;
5226     }
5227
5228   /* Construct the API message */
5229   M (TAP_DELETE, tap_delete);
5230
5231   mp->sw_if_index = ntohl (sw_if_index);
5232
5233   /* send it... */
5234   S;
5235
5236   /* Wait for a reply... */
5237   W;
5238 }
5239
5240 static int
5241 api_ip_add_del_route (vat_main_t * vam)
5242 {
5243   unformat_input_t *i = vam->input;
5244   vl_api_ip_add_del_route_t *mp;
5245   f64 timeout;
5246   u32 sw_if_index = ~0, vrf_id = 0;
5247   u8 sw_if_index_set = 0;
5248   u8 is_ipv6 = 0;
5249   u8 is_local = 0, is_drop = 0;
5250   u8 create_vrf_if_needed = 0;
5251   u8 is_add = 1;
5252   u8 next_hop_weight = 1;
5253   u8 not_last = 0;
5254   u8 is_multipath = 0;
5255   u8 address_set = 0;
5256   u8 address_length_set = 0;
5257   u32 lookup_in_vrf = 0;
5258   u32 resolve_attempts = 0;
5259   u32 dst_address_length = 0;
5260   u8 next_hop_set = 0;
5261   ip4_address_t v4_dst_address, v4_next_hop_address;
5262   ip6_address_t v6_dst_address, v6_next_hop_address;
5263   int count = 1;
5264   int j;
5265   f64 before = 0;
5266   u32 random_add_del = 0;
5267   u32 *random_vector = 0;
5268   uword *random_hash;
5269   u32 random_seed = 0xdeaddabe;
5270   u32 classify_table_index = ~0;
5271   u8 is_classify = 0;
5272
5273   /* Parse args required to build the message */
5274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275     {
5276       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5277         sw_if_index_set = 1;
5278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5279         sw_if_index_set = 1;
5280       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5281         {
5282           address_set = 1;
5283           is_ipv6 = 0;
5284         }
5285       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5286         {
5287           address_set = 1;
5288           is_ipv6 = 1;
5289         }
5290       else if (unformat (i, "/%d", &dst_address_length))
5291         {
5292           address_length_set = 1;
5293         }
5294
5295       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5296                                          &v4_next_hop_address))
5297         {
5298           next_hop_set = 1;
5299         }
5300       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5301                                          &v6_next_hop_address))
5302         {
5303           next_hop_set = 1;
5304         }
5305       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5306         ;
5307       else if (unformat (i, "weight %d", &next_hop_weight))
5308         ;
5309       else if (unformat (i, "drop"))
5310         {
5311           is_drop = 1;
5312         }
5313       else if (unformat (i, "local"))
5314         {
5315           is_local = 1;
5316         }
5317       else if (unformat (i, "classify %d", &classify_table_index))
5318         {
5319           is_classify = 1;
5320         }
5321       else if (unformat (i, "del"))
5322         is_add = 0;
5323       else if (unformat (i, "add"))
5324         is_add = 1;
5325       else if (unformat (i, "not-last"))
5326         not_last = 1;
5327       else if (unformat (i, "multipath"))
5328         is_multipath = 1;
5329       else if (unformat (i, "vrf %d", &vrf_id))
5330         ;
5331       else if (unformat (i, "create-vrf"))
5332         create_vrf_if_needed = 1;
5333       else if (unformat (i, "count %d", &count))
5334         ;
5335       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5336         ;
5337       else if (unformat (i, "random"))
5338         random_add_del = 1;
5339       else if (unformat (i, "seed %d", &random_seed))
5340         ;
5341       else
5342         {
5343           clib_warning ("parse error '%U'", format_unformat_error, i);
5344           return -99;
5345         }
5346     }
5347
5348   if (resolve_attempts > 0 && sw_if_index_set == 0)
5349     {
5350       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5351       return -99;
5352     }
5353
5354   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5355     {
5356       errmsg ("next hop / local / drop / classify not set\n");
5357       return -99;
5358     }
5359
5360   if (address_set == 0)
5361     {
5362       errmsg ("missing addresses\n");
5363       return -99;
5364     }
5365
5366   if (address_length_set == 0)
5367     {
5368       errmsg ("missing address length\n");
5369       return -99;
5370     }
5371
5372   /* Generate a pile of unique, random routes */
5373   if (random_add_del)
5374     {
5375       u32 this_random_address;
5376       random_hash = hash_create (count, sizeof (uword));
5377
5378       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5379       for (j = 0; j <= count; j++)
5380         {
5381           do
5382             {
5383               this_random_address = random_u32 (&random_seed);
5384               this_random_address =
5385                 clib_host_to_net_u32 (this_random_address);
5386             }
5387           while (hash_get (random_hash, this_random_address));
5388           vec_add1 (random_vector, this_random_address);
5389           hash_set (random_hash, this_random_address, 1);
5390         }
5391       hash_free (random_hash);
5392       v4_dst_address.as_u32 = random_vector[0];
5393     }
5394
5395   if (count > 1)
5396     {
5397       /* Turn on async mode */
5398       vam->async_mode = 1;
5399       vam->async_errors = 0;
5400       before = vat_time_now (vam);
5401     }
5402
5403   for (j = 0; j < count; j++)
5404     {
5405       /* Construct the API message */
5406       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5407
5408       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5409       mp->vrf_id = ntohl (vrf_id);
5410       if (resolve_attempts > 0)
5411         {
5412           mp->resolve_attempts = ntohl (resolve_attempts);
5413           mp->resolve_if_needed = 1;
5414         }
5415       mp->create_vrf_if_needed = create_vrf_if_needed;
5416
5417       mp->is_add = is_add;
5418       mp->is_drop = is_drop;
5419       mp->is_ipv6 = is_ipv6;
5420       mp->is_local = is_local;
5421       mp->is_classify = is_classify;
5422       mp->is_multipath = is_multipath;
5423       mp->not_last = not_last;
5424       mp->next_hop_weight = next_hop_weight;
5425       mp->dst_address_length = dst_address_length;
5426       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5427       mp->classify_table_index = ntohl (classify_table_index);
5428
5429       if (is_ipv6)
5430         {
5431           clib_memcpy (mp->dst_address, &v6_dst_address,
5432                        sizeof (v6_dst_address));
5433           if (next_hop_set)
5434             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5435                          sizeof (v6_next_hop_address));
5436           increment_v6_address (&v6_dst_address);
5437         }
5438       else
5439         {
5440           clib_memcpy (mp->dst_address, &v4_dst_address,
5441                        sizeof (v4_dst_address));
5442           if (next_hop_set)
5443             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5444                          sizeof (v4_next_hop_address));
5445           if (random_add_del)
5446             v4_dst_address.as_u32 = random_vector[j + 1];
5447           else
5448             increment_v4_address (&v4_dst_address);
5449         }
5450       /* send it... */
5451       S;
5452     }
5453
5454   /* When testing multiple add/del ops, use a control-ping to sync */
5455   if (count > 1)
5456     {
5457       vl_api_control_ping_t *mp;
5458       f64 after;
5459
5460       /* Shut off async mode */
5461       vam->async_mode = 0;
5462
5463       M (CONTROL_PING, control_ping);
5464       S;
5465
5466       timeout = vat_time_now (vam) + 1.0;
5467       while (vat_time_now (vam) < timeout)
5468         if (vam->result_ready == 1)
5469           goto out;
5470       vam->retval = -99;
5471
5472     out:
5473       if (vam->retval == -99)
5474         errmsg ("timeout\n");
5475
5476       if (vam->async_errors > 0)
5477         {
5478           errmsg ("%d asynchronous errors\n", vam->async_errors);
5479           vam->retval = -98;
5480         }
5481       vam->async_errors = 0;
5482       after = vat_time_now (vam);
5483
5484       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5485                count, after - before, count / (after - before));
5486     }
5487   else
5488     {
5489       /* Wait for a reply... */
5490       W;
5491     }
5492
5493   /* Return the good/bad news */
5494   return (vam->retval);
5495 }
5496
5497 static int
5498 api_proxy_arp_add_del (vat_main_t * vam)
5499 {
5500   unformat_input_t *i = vam->input;
5501   vl_api_proxy_arp_add_del_t *mp;
5502   f64 timeout;
5503   u32 vrf_id = 0;
5504   u8 is_add = 1;
5505   ip4_address_t lo, hi;
5506   u8 range_set = 0;
5507
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "vrf %d", &vrf_id))
5511         ;
5512       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5513                          unformat_ip4_address, &hi))
5514         range_set = 1;
5515       else if (unformat (i, "del"))
5516         is_add = 0;
5517       else
5518         {
5519           clib_warning ("parse error '%U'", format_unformat_error, i);
5520           return -99;
5521         }
5522     }
5523
5524   if (range_set == 0)
5525     {
5526       errmsg ("address range not set\n");
5527       return -99;
5528     }
5529
5530   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5531
5532   mp->vrf_id = ntohl (vrf_id);
5533   mp->is_add = is_add;
5534   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5535   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5536
5537   S;
5538   W;
5539   /* NOTREACHED */
5540   return 0;
5541 }
5542
5543 static int
5544 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5545 {
5546   unformat_input_t *i = vam->input;
5547   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5548   f64 timeout;
5549   u32 sw_if_index;
5550   u8 enable = 1;
5551   u8 sw_if_index_set = 0;
5552
5553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5554     {
5555       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5556         sw_if_index_set = 1;
5557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5558         sw_if_index_set = 1;
5559       else if (unformat (i, "enable"))
5560         enable = 1;
5561       else if (unformat (i, "disable"))
5562         enable = 0;
5563       else
5564         {
5565           clib_warning ("parse error '%U'", format_unformat_error, i);
5566           return -99;
5567         }
5568     }
5569
5570   if (sw_if_index_set == 0)
5571     {
5572       errmsg ("missing interface name or sw_if_index\n");
5573       return -99;
5574     }
5575
5576   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5577
5578   mp->sw_if_index = ntohl (sw_if_index);
5579   mp->enable_disable = enable;
5580
5581   S;
5582   W;
5583   /* NOTREACHED */
5584   return 0;
5585 }
5586
5587 static int
5588 api_mpls_add_del_decap (vat_main_t * vam)
5589 {
5590   unformat_input_t *i = vam->input;
5591   vl_api_mpls_add_del_decap_t *mp;
5592   f64 timeout;
5593   u32 rx_vrf_id = 0;
5594   u32 tx_vrf_id = 0;
5595   u32 label = 0;
5596   u8 is_add = 1;
5597   u8 s_bit = 1;
5598   u32 next_index = 1;
5599
5600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5601     {
5602       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5603         ;
5604       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5605         ;
5606       else if (unformat (i, "label %d", &label))
5607         ;
5608       else if (unformat (i, "next-index %d", &next_index))
5609         ;
5610       else if (unformat (i, "del"))
5611         is_add = 0;
5612       else if (unformat (i, "s-bit-clear"))
5613         s_bit = 0;
5614       else
5615         {
5616           clib_warning ("parse error '%U'", format_unformat_error, i);
5617           return -99;
5618         }
5619     }
5620
5621   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5622
5623   mp->rx_vrf_id = ntohl (rx_vrf_id);
5624   mp->tx_vrf_id = ntohl (tx_vrf_id);
5625   mp->label = ntohl (label);
5626   mp->next_index = ntohl (next_index);
5627   mp->s_bit = s_bit;
5628   mp->is_add = is_add;
5629
5630   S;
5631   W;
5632   /* NOTREACHED */
5633   return 0;
5634 }
5635
5636 static int
5637 api_mpls_add_del_encap (vat_main_t * vam)
5638 {
5639   unformat_input_t *i = vam->input;
5640   vl_api_mpls_add_del_encap_t *mp;
5641   f64 timeout;
5642   u32 vrf_id = 0;
5643   u32 *labels = 0;
5644   u32 label;
5645   ip4_address_t dst_address;
5646   u8 is_add = 1;
5647
5648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649     {
5650       if (unformat (i, "vrf %d", &vrf_id))
5651         ;
5652       else if (unformat (i, "label %d", &label))
5653         vec_add1 (labels, ntohl (label));
5654       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5655         ;
5656       else if (unformat (i, "del"))
5657         is_add = 0;
5658       else
5659         {
5660           clib_warning ("parse error '%U'", format_unformat_error, i);
5661           return -99;
5662         }
5663     }
5664
5665   if (vec_len (labels) == 0)
5666     {
5667       errmsg ("missing encap label stack\n");
5668       return -99;
5669     }
5670
5671   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5672       sizeof (u32) * vec_len (labels));
5673
5674   mp->vrf_id = ntohl (vrf_id);
5675   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5676   mp->is_add = is_add;
5677   mp->nlabels = vec_len (labels);
5678   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5679
5680   vec_free (labels);
5681
5682   S;
5683   W;
5684   /* NOTREACHED */
5685   return 0;
5686 }
5687
5688 static int
5689 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5690 {
5691   unformat_input_t *i = vam->input;
5692   vl_api_mpls_gre_add_del_tunnel_t *mp;
5693   f64 timeout;
5694   u32 inner_vrf_id = 0;
5695   u32 outer_vrf_id = 0;
5696   ip4_address_t src_address;
5697   ip4_address_t dst_address;
5698   ip4_address_t intfc_address;
5699   u32 tmp;
5700   u8 intfc_address_length = 0;
5701   u8 is_add = 1;
5702   u8 l2_only = 0;
5703
5704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5705     {
5706       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5707         ;
5708       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5709         ;
5710       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5711         ;
5712       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5713         ;
5714       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5715                          &intfc_address, &tmp))
5716         intfc_address_length = tmp;
5717       else if (unformat (i, "l2-only"))
5718         l2_only = 1;
5719       else if (unformat (i, "del"))
5720         is_add = 0;
5721       else
5722         {
5723           clib_warning ("parse error '%U'", format_unformat_error, i);
5724           return -99;
5725         }
5726     }
5727
5728   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5729
5730   mp->inner_vrf_id = ntohl (inner_vrf_id);
5731   mp->outer_vrf_id = ntohl (outer_vrf_id);
5732   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5733   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5734   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5735   mp->intfc_address_length = intfc_address_length;
5736   mp->l2_only = l2_only;
5737   mp->is_add = is_add;
5738
5739   S;
5740   W;
5741   /* NOTREACHED */
5742   return 0;
5743 }
5744
5745 static int
5746 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5747 {
5748   unformat_input_t *i = vam->input;
5749   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5750   f64 timeout;
5751   u32 inner_vrf_id = 0;
5752   ip4_address_t intfc_address;
5753   u8 dst_mac_address[6];
5754   int dst_set = 1;
5755   u32 tmp;
5756   u8 intfc_address_length = 0;
5757   u8 is_add = 1;
5758   u8 l2_only = 0;
5759   u32 tx_sw_if_index;
5760   int tx_sw_if_index_set = 0;
5761
5762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5763     {
5764       if (unformat (i, "vrf %d", &inner_vrf_id))
5765         ;
5766       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5767                          &intfc_address, &tmp))
5768         intfc_address_length = tmp;
5769       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5770         tx_sw_if_index_set = 1;
5771       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5772         tx_sw_if_index_set = 1;
5773       else if (unformat (i, "dst %U", unformat_ethernet_address,
5774                          dst_mac_address))
5775         dst_set = 1;
5776       else if (unformat (i, "l2-only"))
5777         l2_only = 1;
5778       else if (unformat (i, "del"))
5779         is_add = 0;
5780       else
5781         {
5782           clib_warning ("parse error '%U'", format_unformat_error, i);
5783           return -99;
5784         }
5785     }
5786
5787   if (!dst_set)
5788     {
5789       errmsg ("dst (mac address) not set\n");
5790       return -99;
5791     }
5792   if (!tx_sw_if_index_set)
5793     {
5794       errmsg ("tx-intfc not set\n");
5795       return -99;
5796     }
5797
5798   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5799
5800   mp->vrf_id = ntohl (inner_vrf_id);
5801   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5802   mp->adj_address_length = intfc_address_length;
5803   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5804                sizeof (dst_mac_address));
5805   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5806   mp->l2_only = l2_only;
5807   mp->is_add = is_add;
5808
5809   S;
5810   W;
5811   /* NOTREACHED */
5812   return 0;
5813 }
5814
5815 static int
5816 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5817 {
5818   unformat_input_t *i = vam->input;
5819   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5820   f64 timeout;
5821   u32 inner_vrf_id = 0;
5822   u32 outer_vrf_id = 0;
5823   ip4_address_t adj_address;
5824   int adj_address_set = 0;
5825   ip4_address_t next_hop_address;
5826   int next_hop_address_set = 0;
5827   u32 tmp;
5828   u8 adj_address_length = 0;
5829   u8 l2_only = 0;
5830   u8 is_add = 1;
5831   u32 resolve_attempts = 5;
5832   u8 resolve_if_needed = 1;
5833
5834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5835     {
5836       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5837         ;
5838       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5839         ;
5840       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5841                          &adj_address, &tmp))
5842         {
5843           adj_address_length = tmp;
5844           adj_address_set = 1;
5845         }
5846       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5847                          &next_hop_address))
5848         next_hop_address_set = 1;
5849       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5850         ;
5851       else if (unformat (i, "resolve-if-needed %d", &tmp))
5852         resolve_if_needed = tmp;
5853       else if (unformat (i, "l2-only"))
5854         l2_only = 1;
5855       else if (unformat (i, "del"))
5856         is_add = 0;
5857       else
5858         {
5859           clib_warning ("parse error '%U'", format_unformat_error, i);
5860           return -99;
5861         }
5862     }
5863
5864   if (!adj_address_set)
5865     {
5866       errmsg ("adjacency address/mask not set\n");
5867       return -99;
5868     }
5869   if (!next_hop_address_set)
5870     {
5871       errmsg ("ip4 next hop address (in outer fib) not set\n");
5872       return -99;
5873     }
5874
5875   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5876
5877   mp->inner_vrf_id = ntohl (inner_vrf_id);
5878   mp->outer_vrf_id = ntohl (outer_vrf_id);
5879   mp->resolve_attempts = ntohl (resolve_attempts);
5880   mp->resolve_if_needed = resolve_if_needed;
5881   mp->is_add = is_add;
5882   mp->l2_only = l2_only;
5883   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5884   mp->adj_address_length = adj_address_length;
5885   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5886                sizeof (next_hop_address));
5887
5888   S;
5889   W;
5890   /* NOTREACHED */
5891   return 0;
5892 }
5893
5894 static int
5895 api_sw_interface_set_unnumbered (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_unnumbered_t *mp;
5899   f64 timeout;
5900   u32 sw_if_index;
5901   u32 unnum_sw_index = ~0;
5902   u8 is_add = 1;
5903   u8 sw_if_index_set = 0;
5904
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5910         sw_if_index_set = 1;
5911       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5912         ;
5913       else if (unformat (i, "del"))
5914         is_add = 0;
5915       else
5916         {
5917           clib_warning ("parse error '%U'", format_unformat_error, i);
5918           return -99;
5919         }
5920     }
5921
5922   if (sw_if_index_set == 0)
5923     {
5924       errmsg ("missing interface name or sw_if_index\n");
5925       return -99;
5926     }
5927
5928   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5929
5930   mp->sw_if_index = ntohl (sw_if_index);
5931   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5932   mp->is_add = is_add;
5933
5934   S;
5935   W;
5936   /* NOTREACHED */
5937   return 0;
5938 }
5939
5940 static int
5941 api_ip_neighbor_add_del (vat_main_t * vam)
5942 {
5943   unformat_input_t *i = vam->input;
5944   vl_api_ip_neighbor_add_del_t *mp;
5945   f64 timeout;
5946   u32 sw_if_index;
5947   u8 sw_if_index_set = 0;
5948   u32 vrf_id = 0;
5949   u8 is_add = 1;
5950   u8 is_static = 0;
5951   u8 mac_address[6];
5952   u8 mac_set = 0;
5953   u8 v4_address_set = 0;
5954   u8 v6_address_set = 0;
5955   ip4_address_t v4address;
5956   ip6_address_t v6address;
5957
5958   memset (mac_address, 0, sizeof (mac_address));
5959
5960   /* Parse args required to build the message */
5961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5962     {
5963       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5964         {
5965           mac_set = 1;
5966         }
5967       else if (unformat (i, "del"))
5968         is_add = 0;
5969       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5970         sw_if_index_set = 1;
5971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5972         sw_if_index_set = 1;
5973       else if (unformat (i, "is_static"))
5974         is_static = 1;
5975       else if (unformat (i, "vrf %d", &vrf_id))
5976         ;
5977       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5978         v4_address_set = 1;
5979       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5980         v6_address_set = 1;
5981       else
5982         {
5983           clib_warning ("parse error '%U'", format_unformat_error, i);
5984           return -99;
5985         }
5986     }
5987
5988   if (sw_if_index_set == 0)
5989     {
5990       errmsg ("missing interface name or sw_if_index\n");
5991       return -99;
5992     }
5993   if (v4_address_set && v6_address_set)
5994     {
5995       errmsg ("both v4 and v6 addresses set\n");
5996       return -99;
5997     }
5998   if (!v4_address_set && !v6_address_set)
5999     {
6000       errmsg ("no address set\n");
6001       return -99;
6002     }
6003
6004   /* Construct the API message */
6005   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6006
6007   mp->sw_if_index = ntohl (sw_if_index);
6008   mp->is_add = is_add;
6009   mp->vrf_id = ntohl (vrf_id);
6010   mp->is_static = is_static;
6011   if (mac_set)
6012     clib_memcpy (mp->mac_address, mac_address, 6);
6013   if (v6_address_set)
6014     {
6015       mp->is_ipv6 = 1;
6016       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6017     }
6018   else
6019     {
6020       /* mp->is_ipv6 = 0; via memset in M macro above */
6021       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6022     }
6023
6024   /* send it... */
6025   S;
6026
6027   /* Wait for a reply, return good/bad news  */
6028   W;
6029
6030   /* NOTREACHED */
6031   return 0;
6032 }
6033
6034 static int
6035 api_reset_vrf (vat_main_t * vam)
6036 {
6037   unformat_input_t *i = vam->input;
6038   vl_api_reset_vrf_t *mp;
6039   f64 timeout;
6040   u32 vrf_id = 0;
6041   u8 is_ipv6 = 0;
6042   u8 vrf_id_set = 0;
6043
6044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6045     {
6046       if (unformat (i, "vrf %d", &vrf_id))
6047         vrf_id_set = 1;
6048       else if (unformat (i, "ipv6"))
6049         is_ipv6 = 1;
6050       else
6051         {
6052           clib_warning ("parse error '%U'", format_unformat_error, i);
6053           return -99;
6054         }
6055     }
6056
6057   if (vrf_id_set == 0)
6058     {
6059       errmsg ("missing vrf id\n");
6060       return -99;
6061     }
6062
6063   M (RESET_VRF, reset_vrf);
6064
6065   mp->vrf_id = ntohl (vrf_id);
6066   mp->is_ipv6 = is_ipv6;
6067
6068   S;
6069   W;
6070   /* NOTREACHED */
6071   return 0;
6072 }
6073
6074 static int
6075 api_create_vlan_subif (vat_main_t * vam)
6076 {
6077   unformat_input_t *i = vam->input;
6078   vl_api_create_vlan_subif_t *mp;
6079   f64 timeout;
6080   u32 sw_if_index;
6081   u8 sw_if_index_set = 0;
6082   u32 vlan_id;
6083   u8 vlan_id_set = 0;
6084
6085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6086     {
6087       if (unformat (i, "sw_if_index %d", &sw_if_index))
6088         sw_if_index_set = 1;
6089       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6090         sw_if_index_set = 1;
6091       else if (unformat (i, "vlan %d", &vlan_id))
6092         vlan_id_set = 1;
6093       else
6094         {
6095           clib_warning ("parse error '%U'", format_unformat_error, i);
6096           return -99;
6097         }
6098     }
6099
6100   if (sw_if_index_set == 0)
6101     {
6102       errmsg ("missing interface name or sw_if_index\n");
6103       return -99;
6104     }
6105
6106   if (vlan_id_set == 0)
6107     {
6108       errmsg ("missing vlan_id\n");
6109       return -99;
6110     }
6111   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6112
6113   mp->sw_if_index = ntohl (sw_if_index);
6114   mp->vlan_id = ntohl (vlan_id);
6115
6116   S;
6117   W;
6118   /* NOTREACHED */
6119   return 0;
6120 }
6121
6122 #define foreach_create_subif_bit                \
6123 _(no_tags)                                      \
6124 _(one_tag)                                      \
6125 _(two_tags)                                     \
6126 _(dot1ad)                                       \
6127 _(exact_match)                                  \
6128 _(default_sub)                                  \
6129 _(outer_vlan_id_any)                            \
6130 _(inner_vlan_id_any)
6131
6132 static int
6133 api_create_subif (vat_main_t * vam)
6134 {
6135   unformat_input_t *i = vam->input;
6136   vl_api_create_subif_t *mp;
6137   f64 timeout;
6138   u32 sw_if_index;
6139   u8 sw_if_index_set = 0;
6140   u32 sub_id;
6141   u8 sub_id_set = 0;
6142   u32 no_tags = 0;
6143   u32 one_tag = 0;
6144   u32 two_tags = 0;
6145   u32 dot1ad = 0;
6146   u32 exact_match = 0;
6147   u32 default_sub = 0;
6148   u32 outer_vlan_id_any = 0;
6149   u32 inner_vlan_id_any = 0;
6150   u32 tmp;
6151   u16 outer_vlan_id = 0;
6152   u16 inner_vlan_id = 0;
6153
6154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6155     {
6156       if (unformat (i, "sw_if_index %d", &sw_if_index))
6157         sw_if_index_set = 1;
6158       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6159         sw_if_index_set = 1;
6160       else if (unformat (i, "sub_id %d", &sub_id))
6161         sub_id_set = 1;
6162       else if (unformat (i, "outer_vlan_id %d", &tmp))
6163         outer_vlan_id = tmp;
6164       else if (unformat (i, "inner_vlan_id %d", &tmp))
6165         inner_vlan_id = tmp;
6166
6167 #define _(a) else if (unformat (i, #a)) a = 1 ;
6168       foreach_create_subif_bit
6169 #undef _
6170         else
6171         {
6172           clib_warning ("parse error '%U'", format_unformat_error, i);
6173           return -99;
6174         }
6175     }
6176
6177   if (sw_if_index_set == 0)
6178     {
6179       errmsg ("missing interface name or sw_if_index\n");
6180       return -99;
6181     }
6182
6183   if (sub_id_set == 0)
6184     {
6185       errmsg ("missing sub_id\n");
6186       return -99;
6187     }
6188   M (CREATE_SUBIF, create_subif);
6189
6190   mp->sw_if_index = ntohl (sw_if_index);
6191   mp->sub_id = ntohl (sub_id);
6192
6193 #define _(a) mp->a = a;
6194   foreach_create_subif_bit;
6195 #undef _
6196
6197   mp->outer_vlan_id = ntohs (outer_vlan_id);
6198   mp->inner_vlan_id = ntohs (inner_vlan_id);
6199
6200   S;
6201   W;
6202   /* NOTREACHED */
6203   return 0;
6204 }
6205
6206 static int
6207 api_oam_add_del (vat_main_t * vam)
6208 {
6209   unformat_input_t *i = vam->input;
6210   vl_api_oam_add_del_t *mp;
6211   f64 timeout;
6212   u32 vrf_id = 0;
6213   u8 is_add = 1;
6214   ip4_address_t src, dst;
6215   u8 src_set = 0;
6216   u8 dst_set = 0;
6217
6218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219     {
6220       if (unformat (i, "vrf %d", &vrf_id))
6221         ;
6222       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6223         src_set = 1;
6224       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6225         dst_set = 1;
6226       else if (unformat (i, "del"))
6227         is_add = 0;
6228       else
6229         {
6230           clib_warning ("parse error '%U'", format_unformat_error, i);
6231           return -99;
6232         }
6233     }
6234
6235   if (src_set == 0)
6236     {
6237       errmsg ("missing src addr\n");
6238       return -99;
6239     }
6240
6241   if (dst_set == 0)
6242     {
6243       errmsg ("missing dst addr\n");
6244       return -99;
6245     }
6246
6247   M (OAM_ADD_DEL, oam_add_del);
6248
6249   mp->vrf_id = ntohl (vrf_id);
6250   mp->is_add = is_add;
6251   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6252   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6253
6254   S;
6255   W;
6256   /* NOTREACHED */
6257   return 0;
6258 }
6259
6260 static int
6261 api_reset_fib (vat_main_t * vam)
6262 {
6263   unformat_input_t *i = vam->input;
6264   vl_api_reset_fib_t *mp;
6265   f64 timeout;
6266   u32 vrf_id = 0;
6267   u8 is_ipv6 = 0;
6268   u8 vrf_id_set = 0;
6269
6270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6271     {
6272       if (unformat (i, "vrf %d", &vrf_id))
6273         vrf_id_set = 1;
6274       else if (unformat (i, "ipv6"))
6275         is_ipv6 = 1;
6276       else
6277         {
6278           clib_warning ("parse error '%U'", format_unformat_error, i);
6279           return -99;
6280         }
6281     }
6282
6283   if (vrf_id_set == 0)
6284     {
6285       errmsg ("missing vrf id\n");
6286       return -99;
6287     }
6288
6289   M (RESET_FIB, reset_fib);
6290
6291   mp->vrf_id = ntohl (vrf_id);
6292   mp->is_ipv6 = is_ipv6;
6293
6294   S;
6295   W;
6296   /* NOTREACHED */
6297   return 0;
6298 }
6299
6300 static int
6301 api_dhcp_proxy_config (vat_main_t * vam)
6302 {
6303   unformat_input_t *i = vam->input;
6304   vl_api_dhcp_proxy_config_t *mp;
6305   f64 timeout;
6306   u32 vrf_id = 0;
6307   u8 is_add = 1;
6308   u8 insert_cid = 1;
6309   u8 v4_address_set = 0;
6310   u8 v6_address_set = 0;
6311   ip4_address_t v4address;
6312   ip6_address_t v6address;
6313   u8 v4_src_address_set = 0;
6314   u8 v6_src_address_set = 0;
6315   ip4_address_t v4srcaddress;
6316   ip6_address_t v6srcaddress;
6317
6318   /* Parse args required to build the message */
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "del"))
6322         is_add = 0;
6323       else if (unformat (i, "vrf %d", &vrf_id))
6324         ;
6325       else if (unformat (i, "insert-cid %d", &insert_cid))
6326         ;
6327       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6328         v4_address_set = 1;
6329       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6330         v6_address_set = 1;
6331       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6332         v4_src_address_set = 1;
6333       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6334         v6_src_address_set = 1;
6335       else
6336         break;
6337     }
6338
6339   if (v4_address_set && v6_address_set)
6340     {
6341       errmsg ("both v4 and v6 server addresses set\n");
6342       return -99;
6343     }
6344   if (!v4_address_set && !v6_address_set)
6345     {
6346       errmsg ("no server addresses set\n");
6347       return -99;
6348     }
6349
6350   if (v4_src_address_set && v6_src_address_set)
6351     {
6352       errmsg ("both v4 and v6  src addresses set\n");
6353       return -99;
6354     }
6355   if (!v4_src_address_set && !v6_src_address_set)
6356     {
6357       errmsg ("no src addresses set\n");
6358       return -99;
6359     }
6360
6361   if (!(v4_src_address_set && v4_address_set) &&
6362       !(v6_src_address_set && v6_address_set))
6363     {
6364       errmsg ("no matching server and src addresses set\n");
6365       return -99;
6366     }
6367
6368   /* Construct the API message */
6369   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6370
6371   mp->insert_circuit_id = insert_cid;
6372   mp->is_add = is_add;
6373   mp->vrf_id = ntohl (vrf_id);
6374   if (v6_address_set)
6375     {
6376       mp->is_ipv6 = 1;
6377       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6378       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6379     }
6380   else
6381     {
6382       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6383       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6384     }
6385
6386   /* send it... */
6387   S;
6388
6389   /* Wait for a reply, return good/bad news  */
6390   W;
6391   /* NOTREACHED */
6392   return 0;
6393 }
6394
6395 static int
6396 api_dhcp_proxy_config_2 (vat_main_t * vam)
6397 {
6398   unformat_input_t *i = vam->input;
6399   vl_api_dhcp_proxy_config_2_t *mp;
6400   f64 timeout;
6401   u32 rx_vrf_id = 0;
6402   u32 server_vrf_id = 0;
6403   u8 is_add = 1;
6404   u8 insert_cid = 1;
6405   u8 v4_address_set = 0;
6406   u8 v6_address_set = 0;
6407   ip4_address_t v4address;
6408   ip6_address_t v6address;
6409   u8 v4_src_address_set = 0;
6410   u8 v6_src_address_set = 0;
6411   ip4_address_t v4srcaddress;
6412   ip6_address_t v6srcaddress;
6413
6414   /* Parse args required to build the message */
6415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6416     {
6417       if (unformat (i, "del"))
6418         is_add = 0;
6419       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6420         ;
6421       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6422         ;
6423       else if (unformat (i, "insert-cid %d", &insert_cid))
6424         ;
6425       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6426         v4_address_set = 1;
6427       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6428         v6_address_set = 1;
6429       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6430         v4_src_address_set = 1;
6431       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6432         v6_src_address_set = 1;
6433       else
6434         break;
6435     }
6436
6437   if (v4_address_set && v6_address_set)
6438     {
6439       errmsg ("both v4 and v6 server addresses set\n");
6440       return -99;
6441     }
6442   if (!v4_address_set && !v6_address_set)
6443     {
6444       errmsg ("no server addresses set\n");
6445       return -99;
6446     }
6447
6448   if (v4_src_address_set && v6_src_address_set)
6449     {
6450       errmsg ("both v4 and v6  src addresses set\n");
6451       return -99;
6452     }
6453   if (!v4_src_address_set && !v6_src_address_set)
6454     {
6455       errmsg ("no src addresses set\n");
6456       return -99;
6457     }
6458
6459   if (!(v4_src_address_set && v4_address_set) &&
6460       !(v6_src_address_set && v6_address_set))
6461     {
6462       errmsg ("no matching server and src addresses set\n");
6463       return -99;
6464     }
6465
6466   /* Construct the API message */
6467   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6468
6469   mp->insert_circuit_id = insert_cid;
6470   mp->is_add = is_add;
6471   mp->rx_vrf_id = ntohl (rx_vrf_id);
6472   mp->server_vrf_id = ntohl (server_vrf_id);
6473   if (v6_address_set)
6474     {
6475       mp->is_ipv6 = 1;
6476       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6477       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6478     }
6479   else
6480     {
6481       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6482       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6483     }
6484
6485   /* send it... */
6486   S;
6487
6488   /* Wait for a reply, return good/bad news  */
6489   W;
6490   /* NOTREACHED */
6491   return 0;
6492 }
6493
6494 static int
6495 api_dhcp_proxy_set_vss (vat_main_t * vam)
6496 {
6497   unformat_input_t *i = vam->input;
6498   vl_api_dhcp_proxy_set_vss_t *mp;
6499   f64 timeout;
6500   u8 is_ipv6 = 0;
6501   u8 is_add = 1;
6502   u32 tbl_id;
6503   u8 tbl_id_set = 0;
6504   u32 oui;
6505   u8 oui_set = 0;
6506   u32 fib_id;
6507   u8 fib_id_set = 0;
6508
6509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510     {
6511       if (unformat (i, "tbl_id %d", &tbl_id))
6512         tbl_id_set = 1;
6513       if (unformat (i, "fib_id %d", &fib_id))
6514         fib_id_set = 1;
6515       if (unformat (i, "oui %d", &oui))
6516         oui_set = 1;
6517       else if (unformat (i, "ipv6"))
6518         is_ipv6 = 1;
6519       else if (unformat (i, "del"))
6520         is_add = 0;
6521       else
6522         {
6523           clib_warning ("parse error '%U'", format_unformat_error, i);
6524           return -99;
6525         }
6526     }
6527
6528   if (tbl_id_set == 0)
6529     {
6530       errmsg ("missing tbl id\n");
6531       return -99;
6532     }
6533
6534   if (fib_id_set == 0)
6535     {
6536       errmsg ("missing fib id\n");
6537       return -99;
6538     }
6539   if (oui_set == 0)
6540     {
6541       errmsg ("missing oui\n");
6542       return -99;
6543     }
6544
6545   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6546   mp->tbl_id = ntohl (tbl_id);
6547   mp->fib_id = ntohl (fib_id);
6548   mp->oui = ntohl (oui);
6549   mp->is_ipv6 = is_ipv6;
6550   mp->is_add = is_add;
6551
6552   S;
6553   W;
6554   /* NOTREACHED */
6555   return 0;
6556 }
6557
6558 static int
6559 api_dhcp_client_config (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_dhcp_client_config_t *mp;
6563   f64 timeout;
6564   u32 sw_if_index;
6565   u8 sw_if_index_set = 0;
6566   u8 is_add = 1;
6567   u8 *hostname = 0;
6568   u8 disable_event = 0;
6569
6570   /* Parse args required to build the message */
6571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572     {
6573       if (unformat (i, "del"))
6574         is_add = 0;
6575       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6576         sw_if_index_set = 1;
6577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6578         sw_if_index_set = 1;
6579       else if (unformat (i, "hostname %s", &hostname))
6580         ;
6581       else if (unformat (i, "disable_event"))
6582         disable_event = 1;
6583       else
6584         break;
6585     }
6586
6587   if (sw_if_index_set == 0)
6588     {
6589       errmsg ("missing interface name or sw_if_index\n");
6590       return -99;
6591     }
6592
6593   if (vec_len (hostname) > 63)
6594     {
6595       errmsg ("hostname too long\n");
6596     }
6597   vec_add1 (hostname, 0);
6598
6599   /* Construct the API message */
6600   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6601
6602   mp->sw_if_index = ntohl (sw_if_index);
6603   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6604   vec_free (hostname);
6605   mp->is_add = is_add;
6606   mp->want_dhcp_event = disable_event ? 0 : 1;
6607   mp->pid = getpid ();
6608
6609   /* send it... */
6610   S;
6611
6612   /* Wait for a reply, return good/bad news  */
6613   W;
6614   /* NOTREACHED */
6615   return 0;
6616 }
6617
6618 static int
6619 api_set_ip_flow_hash (vat_main_t * vam)
6620 {
6621   unformat_input_t *i = vam->input;
6622   vl_api_set_ip_flow_hash_t *mp;
6623   f64 timeout;
6624   u32 vrf_id = 0;
6625   u8 is_ipv6 = 0;
6626   u8 vrf_id_set = 0;
6627   u8 src = 0;
6628   u8 dst = 0;
6629   u8 sport = 0;
6630   u8 dport = 0;
6631   u8 proto = 0;
6632   u8 reverse = 0;
6633
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "vrf %d", &vrf_id))
6637         vrf_id_set = 1;
6638       else if (unformat (i, "ipv6"))
6639         is_ipv6 = 1;
6640       else if (unformat (i, "src"))
6641         src = 1;
6642       else if (unformat (i, "dst"))
6643         dst = 1;
6644       else if (unformat (i, "sport"))
6645         sport = 1;
6646       else if (unformat (i, "dport"))
6647         dport = 1;
6648       else if (unformat (i, "proto"))
6649         proto = 1;
6650       else if (unformat (i, "reverse"))
6651         reverse = 1;
6652
6653       else
6654         {
6655           clib_warning ("parse error '%U'", format_unformat_error, i);
6656           return -99;
6657         }
6658     }
6659
6660   if (vrf_id_set == 0)
6661     {
6662       errmsg ("missing vrf id\n");
6663       return -99;
6664     }
6665
6666   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6667   mp->src = src;
6668   mp->dst = dst;
6669   mp->sport = sport;
6670   mp->dport = dport;
6671   mp->proto = proto;
6672   mp->reverse = reverse;
6673   mp->vrf_id = ntohl (vrf_id);
6674   mp->is_ipv6 = is_ipv6;
6675
6676   S;
6677   W;
6678   /* NOTREACHED */
6679   return 0;
6680 }
6681
6682 static int
6683 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6684 {
6685   unformat_input_t *i = vam->input;
6686   vl_api_sw_interface_ip6_enable_disable_t *mp;
6687   f64 timeout;
6688   u32 sw_if_index;
6689   u8 sw_if_index_set = 0;
6690   u8 enable = 0;
6691
6692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6693     {
6694       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6695         sw_if_index_set = 1;
6696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6697         sw_if_index_set = 1;
6698       else if (unformat (i, "enable"))
6699         enable = 1;
6700       else if (unformat (i, "disable"))
6701         enable = 0;
6702       else
6703         {
6704           clib_warning ("parse error '%U'", format_unformat_error, i);
6705           return -99;
6706         }
6707     }
6708
6709   if (sw_if_index_set == 0)
6710     {
6711       errmsg ("missing interface name or sw_if_index\n");
6712       return -99;
6713     }
6714
6715   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6716
6717   mp->sw_if_index = ntohl (sw_if_index);
6718   mp->enable = enable;
6719
6720   S;
6721   W;
6722   /* NOTREACHED */
6723   return 0;
6724 }
6725
6726 static int
6727 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6728 {
6729   unformat_input_t *i = vam->input;
6730   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6731   f64 timeout;
6732   u32 sw_if_index;
6733   u8 sw_if_index_set = 0;
6734   u32 address_length = 0;
6735   u8 v6_address_set = 0;
6736   ip6_address_t v6address;
6737
6738   /* Parse args required to build the message */
6739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6740     {
6741       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6742         sw_if_index_set = 1;
6743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6744         sw_if_index_set = 1;
6745       else if (unformat (i, "%U/%d",
6746                          unformat_ip6_address, &v6address, &address_length))
6747         v6_address_set = 1;
6748       else
6749         break;
6750     }
6751
6752   if (sw_if_index_set == 0)
6753     {
6754       errmsg ("missing interface name or sw_if_index\n");
6755       return -99;
6756     }
6757   if (!v6_address_set)
6758     {
6759       errmsg ("no address set\n");
6760       return -99;
6761     }
6762
6763   /* Construct the API message */
6764   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6765      sw_interface_ip6_set_link_local_address);
6766
6767   mp->sw_if_index = ntohl (sw_if_index);
6768   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6769   mp->address_length = address_length;
6770
6771   /* send it... */
6772   S;
6773
6774   /* Wait for a reply, return good/bad news  */
6775   W;
6776
6777   /* NOTREACHED */
6778   return 0;
6779 }
6780
6781
6782 static int
6783 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6787   f64 timeout;
6788   u32 sw_if_index;
6789   u8 sw_if_index_set = 0;
6790   u32 address_length = 0;
6791   u8 v6_address_set = 0;
6792   ip6_address_t v6address;
6793   u8 use_default = 0;
6794   u8 no_advertise = 0;
6795   u8 off_link = 0;
6796   u8 no_autoconfig = 0;
6797   u8 no_onlink = 0;
6798   u8 is_no = 0;
6799   u32 val_lifetime = 0;
6800   u32 pref_lifetime = 0;
6801
6802   /* Parse args required to build the message */
6803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6804     {
6805       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6806         sw_if_index_set = 1;
6807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6808         sw_if_index_set = 1;
6809       else if (unformat (i, "%U/%d",
6810                          unformat_ip6_address, &v6address, &address_length))
6811         v6_address_set = 1;
6812       else if (unformat (i, "val_life %d", &val_lifetime))
6813         ;
6814       else if (unformat (i, "pref_life %d", &pref_lifetime))
6815         ;
6816       else if (unformat (i, "def"))
6817         use_default = 1;
6818       else if (unformat (i, "noadv"))
6819         no_advertise = 1;
6820       else if (unformat (i, "offl"))
6821         off_link = 1;
6822       else if (unformat (i, "noauto"))
6823         no_autoconfig = 1;
6824       else if (unformat (i, "nolink"))
6825         no_onlink = 1;
6826       else if (unformat (i, "isno"))
6827         is_no = 1;
6828       else
6829         {
6830           clib_warning ("parse error '%U'", format_unformat_error, i);
6831           return -99;
6832         }
6833     }
6834
6835   if (sw_if_index_set == 0)
6836     {
6837       errmsg ("missing interface name or sw_if_index\n");
6838       return -99;
6839     }
6840   if (!v6_address_set)
6841     {
6842       errmsg ("no address set\n");
6843       return -99;
6844     }
6845
6846   /* Construct the API message */
6847   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6848
6849   mp->sw_if_index = ntohl (sw_if_index);
6850   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6851   mp->address_length = address_length;
6852   mp->use_default = use_default;
6853   mp->no_advertise = no_advertise;
6854   mp->off_link = off_link;
6855   mp->no_autoconfig = no_autoconfig;
6856   mp->no_onlink = no_onlink;
6857   mp->is_no = is_no;
6858   mp->val_lifetime = ntohl (val_lifetime);
6859   mp->pref_lifetime = ntohl (pref_lifetime);
6860
6861   /* send it... */
6862   S;
6863
6864   /* Wait for a reply, return good/bad news  */
6865   W;
6866
6867   /* NOTREACHED */
6868   return 0;
6869 }
6870
6871 static int
6872 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6873 {
6874   unformat_input_t *i = vam->input;
6875   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6876   f64 timeout;
6877   u32 sw_if_index;
6878   u8 sw_if_index_set = 0;
6879   u8 suppress = 0;
6880   u8 managed = 0;
6881   u8 other = 0;
6882   u8 ll_option = 0;
6883   u8 send_unicast = 0;
6884   u8 cease = 0;
6885   u8 is_no = 0;
6886   u8 default_router = 0;
6887   u32 max_interval = 0;
6888   u32 min_interval = 0;
6889   u32 lifetime = 0;
6890   u32 initial_count = 0;
6891   u32 initial_interval = 0;
6892
6893
6894   /* Parse args required to build the message */
6895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6896     {
6897       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6900         sw_if_index_set = 1;
6901       else if (unformat (i, "maxint %d", &max_interval))
6902         ;
6903       else if (unformat (i, "minint %d", &min_interval))
6904         ;
6905       else if (unformat (i, "life %d", &lifetime))
6906         ;
6907       else if (unformat (i, "count %d", &initial_count))
6908         ;
6909       else if (unformat (i, "interval %d", &initial_interval))
6910         ;
6911       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6912         suppress = 1;
6913       else if (unformat (i, "managed"))
6914         managed = 1;
6915       else if (unformat (i, "other"))
6916         other = 1;
6917       else if (unformat (i, "ll"))
6918         ll_option = 1;
6919       else if (unformat (i, "send"))
6920         send_unicast = 1;
6921       else if (unformat (i, "cease"))
6922         cease = 1;
6923       else if (unformat (i, "isno"))
6924         is_no = 1;
6925       else if (unformat (i, "def"))
6926         default_router = 1;
6927       else
6928         {
6929           clib_warning ("parse error '%U'", format_unformat_error, i);
6930           return -99;
6931         }
6932     }
6933
6934   if (sw_if_index_set == 0)
6935     {
6936       errmsg ("missing interface name or sw_if_index\n");
6937       return -99;
6938     }
6939
6940   /* Construct the API message */
6941   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6942
6943   mp->sw_if_index = ntohl (sw_if_index);
6944   mp->max_interval = ntohl (max_interval);
6945   mp->min_interval = ntohl (min_interval);
6946   mp->lifetime = ntohl (lifetime);
6947   mp->initial_count = ntohl (initial_count);
6948   mp->initial_interval = ntohl (initial_interval);
6949   mp->suppress = suppress;
6950   mp->managed = managed;
6951   mp->other = other;
6952   mp->ll_option = ll_option;
6953   mp->send_unicast = send_unicast;
6954   mp->cease = cease;
6955   mp->is_no = is_no;
6956   mp->default_router = default_router;
6957
6958   /* send it... */
6959   S;
6960
6961   /* Wait for a reply, return good/bad news  */
6962   W;
6963
6964   /* NOTREACHED */
6965   return 0;
6966 }
6967
6968 static int
6969 api_set_arp_neighbor_limit (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_set_arp_neighbor_limit_t *mp;
6973   f64 timeout;
6974   u32 arp_nbr_limit;
6975   u8 limit_set = 0;
6976   u8 is_ipv6 = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6981         limit_set = 1;
6982       else if (unformat (i, "ipv6"))
6983         is_ipv6 = 1;
6984       else
6985         {
6986           clib_warning ("parse error '%U'", format_unformat_error, i);
6987           return -99;
6988         }
6989     }
6990
6991   if (limit_set == 0)
6992     {
6993       errmsg ("missing limit value\n");
6994       return -99;
6995     }
6996
6997   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6998
6999   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S;
7003   W;
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_l2_patch_add_del (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_l2_patch_add_del_t *mp;
7013   f64 timeout;
7014   u32 rx_sw_if_index;
7015   u8 rx_sw_if_index_set = 0;
7016   u32 tx_sw_if_index;
7017   u8 tx_sw_if_index_set = 0;
7018   u8 is_add = 1;
7019
7020   /* Parse args required to build the message */
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7024         rx_sw_if_index_set = 1;
7025       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7026         tx_sw_if_index_set = 1;
7027       else if (unformat (i, "rx"))
7028         {
7029           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7030             {
7031               if (unformat (i, "%U", unformat_sw_if_index, vam,
7032                             &rx_sw_if_index))
7033                 rx_sw_if_index_set = 1;
7034             }
7035           else
7036             break;
7037         }
7038       else if (unformat (i, "tx"))
7039         {
7040           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7041             {
7042               if (unformat (i, "%U", unformat_sw_if_index, vam,
7043                             &tx_sw_if_index))
7044                 tx_sw_if_index_set = 1;
7045             }
7046           else
7047             break;
7048         }
7049       else if (unformat (i, "del"))
7050         is_add = 0;
7051       else
7052         break;
7053     }
7054
7055   if (rx_sw_if_index_set == 0)
7056     {
7057       errmsg ("missing rx interface name or rx_sw_if_index\n");
7058       return -99;
7059     }
7060
7061   if (tx_sw_if_index_set == 0)
7062     {
7063       errmsg ("missing tx interface name or tx_sw_if_index\n");
7064       return -99;
7065     }
7066
7067   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7068
7069   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7070   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7071   mp->is_add = is_add;
7072
7073   S;
7074   W;
7075   /* NOTREACHED */
7076   return 0;
7077 }
7078
7079 static int
7080 api_trace_profile_add (vat_main_t * vam)
7081 {
7082   unformat_input_t *input = vam->input;
7083   vl_api_trace_profile_add_t *mp;
7084   f64 timeout;
7085   u32 id = 0;
7086   u32 trace_option_elts = 0;
7087   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7088   int has_pow_option = 0;
7089   int has_ppc_option = 0;
7090
7091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7094                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7095                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7096                     &node_id, &app_data))
7097         ;
7098       else if (unformat (input, "pow"))
7099         has_pow_option = 1;
7100       else if (unformat (input, "ppc encap"))
7101         has_ppc_option = PPC_ENCAP;
7102       else if (unformat (input, "ppc decap"))
7103         has_ppc_option = PPC_DECAP;
7104       else if (unformat (input, "ppc none"))
7105         has_ppc_option = PPC_NONE;
7106       else
7107         break;
7108     }
7109   M (TRACE_PROFILE_ADD, trace_profile_add);
7110   mp->id = htons (id);
7111   mp->trace_type = trace_type;
7112   mp->trace_num_elt = trace_option_elts;
7113   mp->trace_ppc = has_ppc_option;
7114   mp->trace_app_data = htonl (app_data);
7115   mp->pow_enable = has_pow_option;
7116   mp->trace_tsp = trace_tsp;
7117   mp->node_id = htonl (node_id);
7118
7119   S;
7120   W;
7121
7122   return (0);
7123
7124 }
7125
7126 static int
7127 api_trace_profile_apply (vat_main_t * vam)
7128 {
7129   unformat_input_t *input = vam->input;
7130   vl_api_trace_profile_apply_t *mp;
7131   f64 timeout;
7132   ip6_address_t addr;
7133   u32 mask_width = ~0;
7134   int is_add = 0;
7135   int is_pop = 0;
7136   int is_none = 0;
7137   u32 vrf_id = 0;
7138   u32 id = 0;
7139
7140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7141     {
7142       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7143         ;
7144       else if (unformat (input, "id %d", &id))
7145         ;
7146       else if (unformat (input, "vrf-id %d", &vrf_id))
7147         ;
7148       else if (unformat (input, "add"))
7149         is_add = 1;
7150       else if (unformat (input, "pop"))
7151         is_pop = 1;
7152       else if (unformat (input, "none"))
7153         is_none = 1;
7154       else
7155         break;
7156     }
7157
7158   if ((is_add + is_pop + is_none) != 1)
7159     {
7160       errmsg ("One of (add, pop, none) required");
7161       return -99;
7162     }
7163   if (mask_width == ~0)
7164     {
7165       errmsg ("<address>/<mask-width> required");
7166       return -99;
7167     }
7168   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7169   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7170   mp->id = htons (id);
7171   mp->prefix_length = htonl (mask_width);
7172   mp->vrf_id = htonl (vrf_id);
7173   if (is_add)
7174     mp->trace_op = IOAM_HBYH_ADD;
7175   else if (is_pop)
7176     mp->trace_op = IOAM_HBYH_POP;
7177   else
7178     mp->trace_op = IOAM_HBYH_MOD;
7179
7180   if (is_none)
7181     mp->enable = 0;
7182   else
7183     mp->enable = 1;
7184
7185   S;
7186   W;
7187
7188   return 0;
7189 }
7190
7191 static int
7192 api_trace_profile_del (vat_main_t * vam)
7193 {
7194   vl_api_trace_profile_del_t *mp;
7195   f64 timeout;
7196
7197   M (TRACE_PROFILE_DEL, trace_profile_del);
7198   S;
7199   W;
7200   return 0;
7201 }
7202
7203 static int
7204 api_sr_tunnel_add_del (vat_main_t * vam)
7205 {
7206   unformat_input_t *i = vam->input;
7207   vl_api_sr_tunnel_add_del_t *mp;
7208   f64 timeout;
7209   int is_del = 0;
7210   int pl_index;
7211   ip6_address_t src_address;
7212   int src_address_set = 0;
7213   ip6_address_t dst_address;
7214   u32 dst_mask_width;
7215   int dst_address_set = 0;
7216   u16 flags = 0;
7217   u32 rx_table_id = 0;
7218   u32 tx_table_id = 0;
7219   ip6_address_t *segments = 0;
7220   ip6_address_t *this_seg;
7221   ip6_address_t *tags = 0;
7222   ip6_address_t *this_tag;
7223   ip6_address_t next_address, tag;
7224   u8 *name = 0;
7225   u8 *policy_name = 0;
7226
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "del"))
7230         is_del = 1;
7231       else if (unformat (i, "name %s", &name))
7232         ;
7233       else if (unformat (i, "policy %s", &policy_name))
7234         ;
7235       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7236         ;
7237       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7238         ;
7239       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7240         src_address_set = 1;
7241       else if (unformat (i, "dst %U/%d",
7242                          unformat_ip6_address, &dst_address, &dst_mask_width))
7243         dst_address_set = 1;
7244       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7245         {
7246           vec_add2 (segments, this_seg, 1);
7247           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7248                        sizeof (*this_seg));
7249         }
7250       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7251         {
7252           vec_add2 (tags, this_tag, 1);
7253           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7254         }
7255       else if (unformat (i, "clean"))
7256         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7257       else if (unformat (i, "protected"))
7258         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7259       else if (unformat (i, "InPE %d", &pl_index))
7260         {
7261           if (pl_index <= 0 || pl_index > 4)
7262             {
7263             pl_index_range_error:
7264               errmsg ("pl index %d out of range\n", pl_index);
7265               return -99;
7266             }
7267           flags |=
7268             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7269         }
7270       else if (unformat (i, "EgPE %d", &pl_index))
7271         {
7272           if (pl_index <= 0 || pl_index > 4)
7273             goto pl_index_range_error;
7274           flags |=
7275             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7276         }
7277       else if (unformat (i, "OrgSrc %d", &pl_index))
7278         {
7279           if (pl_index <= 0 || pl_index > 4)
7280             goto pl_index_range_error;
7281           flags |=
7282             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7283         }
7284       else
7285         break;
7286     }
7287
7288   if (!src_address_set)
7289     {
7290       errmsg ("src address required\n");
7291       return -99;
7292     }
7293
7294   if (!dst_address_set)
7295     {
7296       errmsg ("dst address required\n");
7297       return -99;
7298     }
7299
7300   if (!segments)
7301     {
7302       errmsg ("at least one sr segment required\n");
7303       return -99;
7304     }
7305
7306   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7307       vec_len (segments) * sizeof (ip6_address_t)
7308       + vec_len (tags) * sizeof (ip6_address_t));
7309
7310   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7311   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7312   mp->dst_mask_width = dst_mask_width;
7313   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7314   mp->n_segments = vec_len (segments);
7315   mp->n_tags = vec_len (tags);
7316   mp->is_add = is_del == 0;
7317   clib_memcpy (mp->segs_and_tags, segments,
7318                vec_len (segments) * sizeof (ip6_address_t));
7319   clib_memcpy (mp->segs_and_tags +
7320                vec_len (segments) * sizeof (ip6_address_t), tags,
7321                vec_len (tags) * sizeof (ip6_address_t));
7322
7323   mp->outer_vrf_id = ntohl (rx_table_id);
7324   mp->inner_vrf_id = ntohl (tx_table_id);
7325   memcpy (mp->name, name, vec_len (name));
7326   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7327
7328   vec_free (segments);
7329   vec_free (tags);
7330
7331   S;
7332   W;
7333   /* NOTREACHED */
7334 }
7335
7336 static int
7337 api_sr_policy_add_del (vat_main_t * vam)
7338 {
7339   unformat_input_t *input = vam->input;
7340   vl_api_sr_policy_add_del_t *mp;
7341   f64 timeout;
7342   int is_del = 0;
7343   u8 *name = 0;
7344   u8 *tunnel_name = 0;
7345   u8 **tunnel_names = 0;
7346
7347   int name_set = 0;
7348   int tunnel_set = 0;
7349   int j = 0;
7350   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7351   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7352
7353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7354     {
7355       if (unformat (input, "del"))
7356         is_del = 1;
7357       else if (unformat (input, "name %s", &name))
7358         name_set = 1;
7359       else if (unformat (input, "tunnel %s", &tunnel_name))
7360         {
7361           if (tunnel_name)
7362             {
7363               vec_add1 (tunnel_names, tunnel_name);
7364               /* For serializer:
7365                  - length = #bytes to store in serial vector
7366                  - +1 = byte to store that length
7367                */
7368               tunnel_names_length += (vec_len (tunnel_name) + 1);
7369               tunnel_set = 1;
7370               tunnel_name = 0;
7371             }
7372         }
7373       else
7374         break;
7375     }
7376
7377   if (!name_set)
7378     {
7379       errmsg ("policy name required\n");
7380       return -99;
7381     }
7382
7383   if ((!tunnel_set) && (!is_del))
7384     {
7385       errmsg ("tunnel name required\n");
7386       return -99;
7387     }
7388
7389   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7390
7391
7392
7393   mp->is_add = !is_del;
7394
7395   memcpy (mp->name, name, vec_len (name));
7396   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7397   u8 *serial_orig = 0;
7398   vec_validate (serial_orig, tunnel_names_length);
7399   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7400   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7401
7402   for (j = 0; j < vec_len (tunnel_names); j++)
7403     {
7404       tun_name_len = vec_len (tunnel_names[j]);
7405       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7406       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7407       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7408       serial_orig += tun_name_len;      // Advance past the copy
7409     }
7410   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7411
7412   vec_free (tunnel_names);
7413   vec_free (tunnel_name);
7414
7415   S;
7416   W;
7417   /* NOTREACHED */
7418 }
7419
7420 static int
7421 api_sr_multicast_map_add_del (vat_main_t * vam)
7422 {
7423   unformat_input_t *input = vam->input;
7424   vl_api_sr_multicast_map_add_del_t *mp;
7425   f64 timeout;
7426   int is_del = 0;
7427   ip6_address_t multicast_address;
7428   u8 *policy_name = 0;
7429   int multicast_address_set = 0;
7430
7431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7432     {
7433       if (unformat (input, "del"))
7434         is_del = 1;
7435       else
7436         if (unformat
7437             (input, "address %U", unformat_ip6_address, &multicast_address))
7438         multicast_address_set = 1;
7439       else if (unformat (input, "sr-policy %s", &policy_name))
7440         ;
7441       else
7442         break;
7443     }
7444
7445   if (!is_del && !policy_name)
7446     {
7447       errmsg ("sr-policy name required\n");
7448       return -99;
7449     }
7450
7451
7452   if (!multicast_address_set)
7453     {
7454       errmsg ("address required\n");
7455       return -99;
7456     }
7457
7458   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7459
7460   mp->is_add = !is_del;
7461   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7462   clib_memcpy (mp->multicast_address, &multicast_address,
7463                sizeof (mp->multicast_address));
7464
7465
7466   vec_free (policy_name);
7467
7468   S;
7469   W;
7470   /* NOTREACHED */
7471 }
7472
7473
7474 #define foreach_ip4_proto_field                 \
7475 _(src_address)                                  \
7476 _(dst_address)                                  \
7477 _(tos)                                          \
7478 _(length)                                       \
7479 _(fragment_id)                                  \
7480 _(ttl)                                          \
7481 _(protocol)                                     \
7482 _(checksum)
7483
7484 uword
7485 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7486 {
7487   u8 **maskp = va_arg (*args, u8 **);
7488   u8 *mask = 0;
7489   u8 found_something = 0;
7490   ip4_header_t *ip;
7491
7492 #define _(a) u8 a=0;
7493   foreach_ip4_proto_field;
7494 #undef _
7495   u8 version = 0;
7496   u8 hdr_length = 0;
7497
7498
7499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (input, "version"))
7502         version = 1;
7503       else if (unformat (input, "hdr_length"))
7504         hdr_length = 1;
7505       else if (unformat (input, "src"))
7506         src_address = 1;
7507       else if (unformat (input, "dst"))
7508         dst_address = 1;
7509       else if (unformat (input, "proto"))
7510         protocol = 1;
7511
7512 #define _(a) else if (unformat (input, #a)) a=1;
7513       foreach_ip4_proto_field
7514 #undef _
7515         else
7516         break;
7517     }
7518
7519 #define _(a) found_something += a;
7520   foreach_ip4_proto_field;
7521 #undef _
7522
7523   if (found_something == 0)
7524     return 0;
7525
7526   vec_validate (mask, sizeof (*ip) - 1);
7527
7528   ip = (ip4_header_t *) mask;
7529
7530 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7531   foreach_ip4_proto_field;
7532 #undef _
7533
7534   ip->ip_version_and_header_length = 0;
7535
7536   if (version)
7537     ip->ip_version_and_header_length |= 0xF0;
7538
7539   if (hdr_length)
7540     ip->ip_version_and_header_length |= 0x0F;
7541
7542   *maskp = mask;
7543   return 1;
7544 }
7545
7546 #define foreach_ip6_proto_field                 \
7547 _(src_address)                                  \
7548 _(dst_address)                                  \
7549 _(payload_length)                               \
7550 _(hop_limit)                                    \
7551 _(protocol)
7552
7553 uword
7554 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7555 {
7556   u8 **maskp = va_arg (*args, u8 **);
7557   u8 *mask = 0;
7558   u8 found_something = 0;
7559   ip6_header_t *ip;
7560   u32 ip_version_traffic_class_and_flow_label;
7561
7562 #define _(a) u8 a=0;
7563   foreach_ip6_proto_field;
7564 #undef _
7565   u8 version = 0;
7566   u8 traffic_class = 0;
7567   u8 flow_label = 0;
7568
7569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (unformat (input, "version"))
7572         version = 1;
7573       else if (unformat (input, "traffic-class"))
7574         traffic_class = 1;
7575       else if (unformat (input, "flow-label"))
7576         flow_label = 1;
7577       else if (unformat (input, "src"))
7578         src_address = 1;
7579       else if (unformat (input, "dst"))
7580         dst_address = 1;
7581       else if (unformat (input, "proto"))
7582         protocol = 1;
7583
7584 #define _(a) else if (unformat (input, #a)) a=1;
7585       foreach_ip6_proto_field
7586 #undef _
7587         else
7588         break;
7589     }
7590
7591 #define _(a) found_something += a;
7592   foreach_ip6_proto_field;
7593 #undef _
7594
7595   if (found_something == 0)
7596     return 0;
7597
7598   vec_validate (mask, sizeof (*ip) - 1);
7599
7600   ip = (ip6_header_t *) mask;
7601
7602 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7603   foreach_ip6_proto_field;
7604 #undef _
7605
7606   ip_version_traffic_class_and_flow_label = 0;
7607
7608   if (version)
7609     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7610
7611   if (traffic_class)
7612     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7613
7614   if (flow_label)
7615     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7616
7617   ip->ip_version_traffic_class_and_flow_label =
7618     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7619
7620   *maskp = mask;
7621   return 1;
7622 }
7623
7624 uword
7625 unformat_l3_mask (unformat_input_t * input, va_list * args)
7626 {
7627   u8 **maskp = va_arg (*args, u8 **);
7628
7629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7630     {
7631       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7632         return 1;
7633       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7634         return 1;
7635       else
7636         break;
7637     }
7638   return 0;
7639 }
7640
7641 uword
7642 unformat_l2_mask (unformat_input_t * input, va_list * args)
7643 {
7644   u8 **maskp = va_arg (*args, u8 **);
7645   u8 *mask = 0;
7646   u8 src = 0;
7647   u8 dst = 0;
7648   u8 proto = 0;
7649   u8 tag1 = 0;
7650   u8 tag2 = 0;
7651   u8 ignore_tag1 = 0;
7652   u8 ignore_tag2 = 0;
7653   u8 cos1 = 0;
7654   u8 cos2 = 0;
7655   u8 dot1q = 0;
7656   u8 dot1ad = 0;
7657   int len = 14;
7658
7659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7660     {
7661       if (unformat (input, "src"))
7662         src = 1;
7663       else if (unformat (input, "dst"))
7664         dst = 1;
7665       else if (unformat (input, "proto"))
7666         proto = 1;
7667       else if (unformat (input, "tag1"))
7668         tag1 = 1;
7669       else if (unformat (input, "tag2"))
7670         tag2 = 1;
7671       else if (unformat (input, "ignore-tag1"))
7672         ignore_tag1 = 1;
7673       else if (unformat (input, "ignore-tag2"))
7674         ignore_tag2 = 1;
7675       else if (unformat (input, "cos1"))
7676         cos1 = 1;
7677       else if (unformat (input, "cos2"))
7678         cos2 = 1;
7679       else if (unformat (input, "dot1q"))
7680         dot1q = 1;
7681       else if (unformat (input, "dot1ad"))
7682         dot1ad = 1;
7683       else
7684         break;
7685     }
7686   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7687        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7688     return 0;
7689
7690   if (tag1 || ignore_tag1 || cos1 || dot1q)
7691     len = 18;
7692   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7693     len = 22;
7694
7695   vec_validate (mask, len - 1);
7696
7697   if (dst)
7698     memset (mask, 0xff, 6);
7699
7700   if (src)
7701     memset (mask + 6, 0xff, 6);
7702
7703   if (tag2 || dot1ad)
7704     {
7705       /* inner vlan tag */
7706       if (tag2)
7707         {
7708           mask[19] = 0xff;
7709           mask[18] = 0x0f;
7710         }
7711       if (cos2)
7712         mask[18] |= 0xe0;
7713       if (proto)
7714         mask[21] = mask[20] = 0xff;
7715       if (tag1)
7716         {
7717           mask[15] = 0xff;
7718           mask[14] = 0x0f;
7719         }
7720       if (cos1)
7721         mask[14] |= 0xe0;
7722       *maskp = mask;
7723       return 1;
7724     }
7725   if (tag1 | dot1q)
7726     {
7727       if (tag1)
7728         {
7729           mask[15] = 0xff;
7730           mask[14] = 0x0f;
7731         }
7732       if (cos1)
7733         mask[14] |= 0xe0;
7734       if (proto)
7735         mask[16] = mask[17] = 0xff;
7736
7737       *maskp = mask;
7738       return 1;
7739     }
7740   if (cos2)
7741     mask[18] |= 0xe0;
7742   if (cos1)
7743     mask[14] |= 0xe0;
7744   if (proto)
7745     mask[12] = mask[13] = 0xff;
7746
7747   *maskp = mask;
7748   return 1;
7749 }
7750
7751 uword
7752 unformat_classify_mask (unformat_input_t * input, va_list * args)
7753 {
7754   u8 **maskp = va_arg (*args, u8 **);
7755   u32 *skipp = va_arg (*args, u32 *);
7756   u32 *matchp = va_arg (*args, u32 *);
7757   u32 match;
7758   u8 *mask = 0;
7759   u8 *l2 = 0;
7760   u8 *l3 = 0;
7761   int i;
7762
7763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7764     {
7765       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7766         ;
7767       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7768         ;
7769       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7770         ;
7771       else
7772         break;
7773     }
7774
7775   if (mask || l2 || l3)
7776     {
7777       if (l2 || l3)
7778         {
7779           /* "With a free Ethernet header in every package" */
7780           if (l2 == 0)
7781             vec_validate (l2, 13);
7782           mask = l2;
7783           if (vec_len (l3))
7784             {
7785               vec_append (mask, l3);
7786               vec_free (l3);
7787             }
7788         }
7789
7790       /* Scan forward looking for the first significant mask octet */
7791       for (i = 0; i < vec_len (mask); i++)
7792         if (mask[i])
7793           break;
7794
7795       /* compute (skip, match) params */
7796       *skipp = i / sizeof (u32x4);
7797       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7798
7799       /* Pad mask to an even multiple of the vector size */
7800       while (vec_len (mask) % sizeof (u32x4))
7801         vec_add1 (mask, 0);
7802
7803       match = vec_len (mask) / sizeof (u32x4);
7804
7805       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7806         {
7807           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7808           if (*tmp || *(tmp + 1))
7809             break;
7810           match--;
7811         }
7812       if (match == 0)
7813         clib_warning ("BUG: match 0");
7814
7815       _vec_len (mask) = match * sizeof (u32x4);
7816
7817       *matchp = match;
7818       *maskp = mask;
7819
7820       return 1;
7821     }
7822
7823   return 0;
7824 }
7825
7826 #define foreach_l2_next                         \
7827 _(drop, DROP)                                   \
7828 _(ethernet, ETHERNET_INPUT)                     \
7829 _(ip4, IP4_INPUT)                               \
7830 _(ip6, IP6_INPUT)
7831
7832 uword
7833 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7834 {
7835   u32 *miss_next_indexp = va_arg (*args, u32 *);
7836   u32 next_index = 0;
7837   u32 tmp;
7838
7839 #define _(n,N) \
7840   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7841   foreach_l2_next;
7842 #undef _
7843
7844   if (unformat (input, "%d", &tmp))
7845     {
7846       next_index = tmp;
7847       goto out;
7848     }
7849
7850   return 0;
7851
7852 out:
7853   *miss_next_indexp = next_index;
7854   return 1;
7855 }
7856
7857 #define foreach_ip_next                         \
7858 _(miss, MISS)                                   \
7859 _(drop, DROP)                                   \
7860 _(local, LOCAL)                                 \
7861 _(rewrite, REWRITE)
7862
7863 uword
7864 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7865 {
7866   u32 *miss_next_indexp = va_arg (*args, u32 *);
7867   u32 next_index = 0;
7868   u32 tmp;
7869
7870 #define _(n,N) \
7871   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7872   foreach_ip_next;
7873 #undef _
7874
7875   if (unformat (input, "%d", &tmp))
7876     {
7877       next_index = tmp;
7878       goto out;
7879     }
7880
7881   return 0;
7882
7883 out:
7884   *miss_next_indexp = next_index;
7885   return 1;
7886 }
7887
7888 #define foreach_acl_next                        \
7889 _(deny, DENY)
7890
7891 uword
7892 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7893 {
7894   u32 *miss_next_indexp = va_arg (*args, u32 *);
7895   u32 next_index = 0;
7896   u32 tmp;
7897
7898 #define _(n,N) \
7899   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7900   foreach_acl_next;
7901 #undef _
7902
7903   if (unformat (input, "permit"))
7904     {
7905       next_index = ~0;
7906       goto out;
7907     }
7908   else if (unformat (input, "%d", &tmp))
7909     {
7910       next_index = tmp;
7911       goto out;
7912     }
7913
7914   return 0;
7915
7916 out:
7917   *miss_next_indexp = next_index;
7918   return 1;
7919 }
7920
7921 uword
7922 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7923 {
7924   u32 *r = va_arg (*args, u32 *);
7925
7926   if (unformat (input, "conform-color"))
7927     *r = POLICE_CONFORM;
7928   else if (unformat (input, "exceed-color"))
7929     *r = POLICE_EXCEED;
7930   else
7931     return 0;
7932
7933   return 1;
7934 }
7935
7936 static int
7937 api_classify_add_del_table (vat_main_t * vam)
7938 {
7939   unformat_input_t *i = vam->input;
7940   vl_api_classify_add_del_table_t *mp;
7941
7942   u32 nbuckets = 2;
7943   u32 skip = ~0;
7944   u32 match = ~0;
7945   int is_add = 1;
7946   u32 table_index = ~0;
7947   u32 next_table_index = ~0;
7948   u32 miss_next_index = ~0;
7949   u32 memory_size = 32 << 20;
7950   u8 *mask = 0;
7951   f64 timeout;
7952
7953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7954     {
7955       if (unformat (i, "del"))
7956         is_add = 0;
7957       else if (unformat (i, "buckets %d", &nbuckets))
7958         ;
7959       else if (unformat (i, "memory_size %d", &memory_size))
7960         ;
7961       else if (unformat (i, "skip %d", &skip))
7962         ;
7963       else if (unformat (i, "match %d", &match))
7964         ;
7965       else if (unformat (i, "table %d", &table_index))
7966         ;
7967       else if (unformat (i, "mask %U", unformat_classify_mask,
7968                          &mask, &skip, &match))
7969         ;
7970       else if (unformat (i, "next-table %d", &next_table_index))
7971         ;
7972       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7973                          &miss_next_index))
7974         ;
7975       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7976                          &miss_next_index))
7977         ;
7978       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7979                          &miss_next_index))
7980         ;
7981       else
7982         break;
7983     }
7984
7985   if (is_add && mask == 0)
7986     {
7987       errmsg ("Mask required\n");
7988       return -99;
7989     }
7990
7991   if (is_add && skip == ~0)
7992     {
7993       errmsg ("skip count required\n");
7994       return -99;
7995     }
7996
7997   if (is_add && match == ~0)
7998     {
7999       errmsg ("match count required\n");
8000       return -99;
8001     }
8002
8003   if (!is_add && table_index == ~0)
8004     {
8005       errmsg ("table index required for delete\n");
8006       return -99;
8007     }
8008
8009   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8010
8011   mp->is_add = is_add;
8012   mp->table_index = ntohl (table_index);
8013   mp->nbuckets = ntohl (nbuckets);
8014   mp->memory_size = ntohl (memory_size);
8015   mp->skip_n_vectors = ntohl (skip);
8016   mp->match_n_vectors = ntohl (match);
8017   mp->next_table_index = ntohl (next_table_index);
8018   mp->miss_next_index = ntohl (miss_next_index);
8019   clib_memcpy (mp->mask, mask, vec_len (mask));
8020
8021   vec_free (mask);
8022
8023   S;
8024   W;
8025   /* NOTREACHED */
8026 }
8027
8028 uword
8029 unformat_ip4_match (unformat_input_t * input, va_list * args)
8030 {
8031   u8 **matchp = va_arg (*args, u8 **);
8032   u8 *match = 0;
8033   ip4_header_t *ip;
8034   int version = 0;
8035   u32 version_val;
8036   int hdr_length = 0;
8037   u32 hdr_length_val;
8038   int src = 0, dst = 0;
8039   ip4_address_t src_val, dst_val;
8040   int proto = 0;
8041   u32 proto_val;
8042   int tos = 0;
8043   u32 tos_val;
8044   int length = 0;
8045   u32 length_val;
8046   int fragment_id = 0;
8047   u32 fragment_id_val;
8048   int ttl = 0;
8049   int ttl_val;
8050   int checksum = 0;
8051   u32 checksum_val;
8052
8053   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (input, "version %d", &version_val))
8056         version = 1;
8057       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8058         hdr_length = 1;
8059       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8060         src = 1;
8061       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8062         dst = 1;
8063       else if (unformat (input, "proto %d", &proto_val))
8064         proto = 1;
8065       else if (unformat (input, "tos %d", &tos_val))
8066         tos = 1;
8067       else if (unformat (input, "length %d", &length_val))
8068         length = 1;
8069       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8070         fragment_id = 1;
8071       else if (unformat (input, "ttl %d", &ttl_val))
8072         ttl = 1;
8073       else if (unformat (input, "checksum %d", &checksum_val))
8074         checksum = 1;
8075       else
8076         break;
8077     }
8078
8079   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8080       + ttl + checksum == 0)
8081     return 0;
8082
8083   /*
8084    * Aligned because we use the real comparison functions
8085    */
8086   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8087
8088   ip = (ip4_header_t *) match;
8089
8090   /* These are realistically matched in practice */
8091   if (src)
8092     ip->src_address.as_u32 = src_val.as_u32;
8093
8094   if (dst)
8095     ip->dst_address.as_u32 = dst_val.as_u32;
8096
8097   if (proto)
8098     ip->protocol = proto_val;
8099
8100
8101   /* These are not, but they're included for completeness */
8102   if (version)
8103     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8104
8105   if (hdr_length)
8106     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8107
8108   if (tos)
8109     ip->tos = tos_val;
8110
8111   if (length)
8112     ip->length = length_val;
8113
8114   if (ttl)
8115     ip->ttl = ttl_val;
8116
8117   if (checksum)
8118     ip->checksum = checksum_val;
8119
8120   *matchp = match;
8121   return 1;
8122 }
8123
8124 uword
8125 unformat_ip6_match (unformat_input_t * input, va_list * args)
8126 {
8127   u8 **matchp = va_arg (*args, u8 **);
8128   u8 *match = 0;
8129   ip6_header_t *ip;
8130   int version = 0;
8131   u32 version_val;
8132   u8 traffic_class = 0;
8133   u32 traffic_class_val = 0;
8134   u8 flow_label = 0;
8135   u8 flow_label_val;
8136   int src = 0, dst = 0;
8137   ip6_address_t src_val, dst_val;
8138   int proto = 0;
8139   u32 proto_val;
8140   int payload_length = 0;
8141   u32 payload_length_val;
8142   int hop_limit = 0;
8143   int hop_limit_val;
8144   u32 ip_version_traffic_class_and_flow_label;
8145
8146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8147     {
8148       if (unformat (input, "version %d", &version_val))
8149         version = 1;
8150       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8151         traffic_class = 1;
8152       else if (unformat (input, "flow_label %d", &flow_label_val))
8153         flow_label = 1;
8154       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8155         src = 1;
8156       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8157         dst = 1;
8158       else if (unformat (input, "proto %d", &proto_val))
8159         proto = 1;
8160       else if (unformat (input, "payload_length %d", &payload_length_val))
8161         payload_length = 1;
8162       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8163         hop_limit = 1;
8164       else
8165         break;
8166     }
8167
8168   if (version + traffic_class + flow_label + src + dst + proto +
8169       payload_length + hop_limit == 0)
8170     return 0;
8171
8172   /*
8173    * Aligned because we use the real comparison functions
8174    */
8175   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8176
8177   ip = (ip6_header_t *) match;
8178
8179   if (src)
8180     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8181
8182   if (dst)
8183     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8184
8185   if (proto)
8186     ip->protocol = proto_val;
8187
8188   ip_version_traffic_class_and_flow_label = 0;
8189
8190   if (version)
8191     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8192
8193   if (traffic_class)
8194     ip_version_traffic_class_and_flow_label |=
8195       (traffic_class_val & 0xFF) << 20;
8196
8197   if (flow_label)
8198     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8199
8200   ip->ip_version_traffic_class_and_flow_label =
8201     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8202
8203   if (payload_length)
8204     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8205
8206   if (hop_limit)
8207     ip->hop_limit = hop_limit_val;
8208
8209   *matchp = match;
8210   return 1;
8211 }
8212
8213 uword
8214 unformat_l3_match (unformat_input_t * input, va_list * args)
8215 {
8216   u8 **matchp = va_arg (*args, u8 **);
8217
8218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8219     {
8220       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8221         return 1;
8222       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8223         return 1;
8224       else
8225         break;
8226     }
8227   return 0;
8228 }
8229
8230 uword
8231 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8232 {
8233   u8 *tagp = va_arg (*args, u8 *);
8234   u32 tag;
8235
8236   if (unformat (input, "%d", &tag))
8237     {
8238       tagp[0] = (tag >> 8) & 0x0F;
8239       tagp[1] = tag & 0xFF;
8240       return 1;
8241     }
8242
8243   return 0;
8244 }
8245
8246 uword
8247 unformat_l2_match (unformat_input_t * input, va_list * args)
8248 {
8249   u8 **matchp = va_arg (*args, u8 **);
8250   u8 *match = 0;
8251   u8 src = 0;
8252   u8 src_val[6];
8253   u8 dst = 0;
8254   u8 dst_val[6];
8255   u8 proto = 0;
8256   u16 proto_val;
8257   u8 tag1 = 0;
8258   u8 tag1_val[2];
8259   u8 tag2 = 0;
8260   u8 tag2_val[2];
8261   int len = 14;
8262   u8 ignore_tag1 = 0;
8263   u8 ignore_tag2 = 0;
8264   u8 cos1 = 0;
8265   u8 cos2 = 0;
8266   u32 cos1_val = 0;
8267   u32 cos2_val = 0;
8268
8269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8270     {
8271       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8272         src = 1;
8273       else
8274         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8275         dst = 1;
8276       else if (unformat (input, "proto %U",
8277                          unformat_ethernet_type_host_byte_order, &proto_val))
8278         proto = 1;
8279       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8280         tag1 = 1;
8281       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8282         tag2 = 1;
8283       else if (unformat (input, "ignore-tag1"))
8284         ignore_tag1 = 1;
8285       else if (unformat (input, "ignore-tag2"))
8286         ignore_tag2 = 1;
8287       else if (unformat (input, "cos1 %d", &cos1_val))
8288         cos1 = 1;
8289       else if (unformat (input, "cos2 %d", &cos2_val))
8290         cos2 = 1;
8291       else
8292         break;
8293     }
8294   if ((src + dst + proto + tag1 + tag2 +
8295        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8296     return 0;
8297
8298   if (tag1 || ignore_tag1 || cos1)
8299     len = 18;
8300   if (tag2 || ignore_tag2 || cos2)
8301     len = 22;
8302
8303   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8304
8305   if (dst)
8306     clib_memcpy (match, dst_val, 6);
8307
8308   if (src)
8309     clib_memcpy (match + 6, src_val, 6);
8310
8311   if (tag2)
8312     {
8313       /* inner vlan tag */
8314       match[19] = tag2_val[1];
8315       match[18] = tag2_val[0];
8316       if (cos2)
8317         match[18] |= (cos2_val & 0x7) << 5;
8318       if (proto)
8319         {
8320           match[21] = proto_val & 0xff;
8321           match[20] = proto_val >> 8;
8322         }
8323       if (tag1)
8324         {
8325           match[15] = tag1_val[1];
8326           match[14] = tag1_val[0];
8327         }
8328       if (cos1)
8329         match[14] |= (cos1_val & 0x7) << 5;
8330       *matchp = match;
8331       return 1;
8332     }
8333   if (tag1)
8334     {
8335       match[15] = tag1_val[1];
8336       match[14] = tag1_val[0];
8337       if (proto)
8338         {
8339           match[17] = proto_val & 0xff;
8340           match[16] = proto_val >> 8;
8341         }
8342       if (cos1)
8343         match[14] |= (cos1_val & 0x7) << 5;
8344
8345       *matchp = match;
8346       return 1;
8347     }
8348   if (cos2)
8349     match[18] |= (cos2_val & 0x7) << 5;
8350   if (cos1)
8351     match[14] |= (cos1_val & 0x7) << 5;
8352   if (proto)
8353     {
8354       match[13] = proto_val & 0xff;
8355       match[12] = proto_val >> 8;
8356     }
8357
8358   *matchp = match;
8359   return 1;
8360 }
8361
8362
8363 uword
8364 unformat_classify_match (unformat_input_t * input, va_list * args)
8365 {
8366   u8 **matchp = va_arg (*args, u8 **);
8367   u32 skip_n_vectors = va_arg (*args, u32);
8368   u32 match_n_vectors = va_arg (*args, u32);
8369
8370   u8 *match = 0;
8371   u8 *l2 = 0;
8372   u8 *l3 = 0;
8373
8374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8375     {
8376       if (unformat (input, "hex %U", unformat_hex_string, &match))
8377         ;
8378       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8379         ;
8380       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8381         ;
8382       else
8383         break;
8384     }
8385
8386   if (match || l2 || l3)
8387     {
8388       if (l2 || l3)
8389         {
8390           /* "Win a free Ethernet header in every packet" */
8391           if (l2 == 0)
8392             vec_validate_aligned (l2, 13, sizeof (u32x4));
8393           match = l2;
8394           if (vec_len (l3))
8395             {
8396               vec_append_aligned (match, l3, sizeof (u32x4));
8397               vec_free (l3);
8398             }
8399         }
8400
8401       /* Make sure the vector is big enough even if key is all 0's */
8402       vec_validate_aligned
8403         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8404          sizeof (u32x4));
8405
8406       /* Set size, include skipped vectors */
8407       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8408
8409       *matchp = match;
8410
8411       return 1;
8412     }
8413
8414   return 0;
8415 }
8416
8417 static int
8418 api_classify_add_del_session (vat_main_t * vam)
8419 {
8420   unformat_input_t *i = vam->input;
8421   vl_api_classify_add_del_session_t *mp;
8422   int is_add = 1;
8423   u32 table_index = ~0;
8424   u32 hit_next_index = ~0;
8425   u32 opaque_index = ~0;
8426   u8 *match = 0;
8427   i32 advance = 0;
8428   f64 timeout;
8429   u32 skip_n_vectors = 0;
8430   u32 match_n_vectors = 0;
8431
8432   /*
8433    * Warning: you have to supply skip_n and match_n
8434    * because the API client cant simply look at the classify
8435    * table object.
8436    */
8437
8438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8439     {
8440       if (unformat (i, "del"))
8441         is_add = 0;
8442       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8443                          &hit_next_index))
8444         ;
8445       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8446                          &hit_next_index))
8447         ;
8448       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8449                          &hit_next_index))
8450         ;
8451       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8452         ;
8453       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8454         ;
8455       else if (unformat (i, "opaque-index %d", &opaque_index))
8456         ;
8457       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8458         ;
8459       else if (unformat (i, "match_n %d", &match_n_vectors))
8460         ;
8461       else if (unformat (i, "match %U", unformat_classify_match,
8462                          &match, skip_n_vectors, match_n_vectors))
8463         ;
8464       else if (unformat (i, "advance %d", &advance))
8465         ;
8466       else if (unformat (i, "table-index %d", &table_index))
8467         ;
8468       else
8469         break;
8470     }
8471
8472   if (table_index == ~0)
8473     {
8474       errmsg ("Table index required\n");
8475       return -99;
8476     }
8477
8478   if (is_add && match == 0)
8479     {
8480       errmsg ("Match value required\n");
8481       return -99;
8482     }
8483
8484   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8485
8486   mp->is_add = is_add;
8487   mp->table_index = ntohl (table_index);
8488   mp->hit_next_index = ntohl (hit_next_index);
8489   mp->opaque_index = ntohl (opaque_index);
8490   mp->advance = ntohl (advance);
8491   clib_memcpy (mp->match, match, vec_len (match));
8492   vec_free (match);
8493
8494   S;
8495   W;
8496   /* NOTREACHED */
8497 }
8498
8499 static int
8500 api_classify_set_interface_ip_table (vat_main_t * vam)
8501 {
8502   unformat_input_t *i = vam->input;
8503   vl_api_classify_set_interface_ip_table_t *mp;
8504   f64 timeout;
8505   u32 sw_if_index;
8506   int sw_if_index_set;
8507   u32 table_index = ~0;
8508   u8 is_ipv6 = 0;
8509
8510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8511     {
8512       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8513         sw_if_index_set = 1;
8514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8515         sw_if_index_set = 1;
8516       else if (unformat (i, "table %d", &table_index))
8517         ;
8518       else
8519         {
8520           clib_warning ("parse error '%U'", format_unformat_error, i);
8521           return -99;
8522         }
8523     }
8524
8525   if (sw_if_index_set == 0)
8526     {
8527       errmsg ("missing interface name or sw_if_index\n");
8528       return -99;
8529     }
8530
8531
8532   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8533
8534   mp->sw_if_index = ntohl (sw_if_index);
8535   mp->table_index = ntohl (table_index);
8536   mp->is_ipv6 = is_ipv6;
8537
8538   S;
8539   W;
8540   /* NOTREACHED */
8541   return 0;
8542 }
8543
8544 static int
8545 api_classify_set_interface_l2_tables (vat_main_t * vam)
8546 {
8547   unformat_input_t *i = vam->input;
8548   vl_api_classify_set_interface_l2_tables_t *mp;
8549   f64 timeout;
8550   u32 sw_if_index;
8551   int sw_if_index_set;
8552   u32 ip4_table_index = ~0;
8553   u32 ip6_table_index = ~0;
8554   u32 other_table_index = ~0;
8555
8556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8559         sw_if_index_set = 1;
8560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8561         sw_if_index_set = 1;
8562       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8563         ;
8564       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8565         ;
8566       else if (unformat (i, "other-table %d", &other_table_index))
8567         ;
8568       else
8569         {
8570           clib_warning ("parse error '%U'", format_unformat_error, i);
8571           return -99;
8572         }
8573     }
8574
8575   if (sw_if_index_set == 0)
8576     {
8577       errmsg ("missing interface name or sw_if_index\n");
8578       return -99;
8579     }
8580
8581
8582   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8583
8584   mp->sw_if_index = ntohl (sw_if_index);
8585   mp->ip4_table_index = ntohl (ip4_table_index);
8586   mp->ip6_table_index = ntohl (ip6_table_index);
8587   mp->other_table_index = ntohl (other_table_index);
8588
8589
8590   S;
8591   W;
8592   /* NOTREACHED */
8593   return 0;
8594 }
8595
8596 static int
8597 api_ipfix_enable (vat_main_t * vam)
8598 {
8599   unformat_input_t *i = vam->input;
8600   vl_api_ipfix_enable_t *mp;
8601   ip4_address_t collector_address;
8602   u8 collector_address_set = 0;
8603   u32 collector_port = ~0;
8604   ip4_address_t src_address;
8605   u8 src_address_set = 0;
8606   u32 vrf_id = ~0;
8607   u32 path_mtu = ~0;
8608   u32 template_interval = ~0;
8609   f64 timeout;
8610
8611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8612     {
8613       if (unformat (i, "collector_address %U", unformat_ip4_address,
8614                     &collector_address))
8615         collector_address_set = 1;
8616       else if (unformat (i, "collector_port %d", &collector_port))
8617         ;
8618       else if (unformat (i, "src_address %U", unformat_ip4_address,
8619                          &src_address))
8620         src_address_set = 1;
8621       else if (unformat (i, "vrf_id %d", &vrf_id))
8622         ;
8623       else if (unformat (i, "path_mtu %d", &path_mtu))
8624         ;
8625       else if (unformat (i, "template_interval %d", &template_interval))
8626         ;
8627       else
8628         break;
8629     }
8630
8631   if (collector_address_set == 0)
8632     {
8633       errmsg ("collector_address required\n");
8634       return -99;
8635     }
8636
8637   if (src_address_set == 0)
8638     {
8639       errmsg ("src_address required\n");
8640       return -99;
8641     }
8642
8643   M (IPFIX_ENABLE, ipfix_enable);
8644
8645   memcpy (mp->collector_address, collector_address.data,
8646           sizeof (collector_address.data));
8647   mp->collector_port = htons ((u16) collector_port);
8648   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8649   mp->vrf_id = htonl (vrf_id);
8650   mp->path_mtu = htonl (path_mtu);
8651   mp->template_interval = htonl (template_interval);
8652
8653   S;
8654   W;
8655   /* NOTREACHED */
8656 }
8657
8658 static int
8659 api_get_node_index (vat_main_t * vam)
8660 {
8661   unformat_input_t *i = vam->input;
8662   vl_api_get_node_index_t *mp;
8663   f64 timeout;
8664   u8 *name = 0;
8665
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "node %s", &name))
8669         ;
8670       else
8671         break;
8672     }
8673   if (name == 0)
8674     {
8675       errmsg ("node name required\n");
8676       return -99;
8677     }
8678   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8679     {
8680       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8681       return -99;
8682     }
8683
8684   M (GET_NODE_INDEX, get_node_index);
8685   clib_memcpy (mp->node_name, name, vec_len (name));
8686   vec_free (name);
8687
8688   S;
8689   W;
8690   /* NOTREACHED */
8691   return 0;
8692 }
8693
8694 static int
8695 api_get_next_index (vat_main_t * vam)
8696 {
8697   unformat_input_t *i = vam->input;
8698   vl_api_get_next_index_t *mp;
8699   f64 timeout;
8700   u8 *node_name = 0, *next_node_name = 0;
8701
8702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (i, "node-name %s", &node_name))
8705         ;
8706       else if (unformat (i, "next-node-name %s", &next_node_name))
8707         break;
8708     }
8709
8710   if (node_name == 0)
8711     {
8712       errmsg ("node name required\n");
8713       return -99;
8714     }
8715   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8716     {
8717       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8718       return -99;
8719     }
8720
8721   if (next_node_name == 0)
8722     {
8723       errmsg ("next node name required\n");
8724       return -99;
8725     }
8726   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8727     {
8728       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8729       return -99;
8730     }
8731
8732   M (GET_NEXT_INDEX, get_next_index);
8733   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8734   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8735   vec_free (node_name);
8736   vec_free (next_node_name);
8737
8738   S;
8739   W;
8740   /* NOTREACHED */
8741   return 0;
8742 }
8743
8744 static int
8745 api_add_node_next (vat_main_t * vam)
8746 {
8747   unformat_input_t *i = vam->input;
8748   vl_api_add_node_next_t *mp;
8749   f64 timeout;
8750   u8 *name = 0;
8751   u8 *next = 0;
8752
8753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8754     {
8755       if (unformat (i, "node %s", &name))
8756         ;
8757       else if (unformat (i, "next %s", &next))
8758         ;
8759       else
8760         break;
8761     }
8762   if (name == 0)
8763     {
8764       errmsg ("node name required\n");
8765       return -99;
8766     }
8767   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8768     {
8769       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8770       return -99;
8771     }
8772   if (next == 0)
8773     {
8774       errmsg ("next node required\n");
8775       return -99;
8776     }
8777   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8778     {
8779       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8780       return -99;
8781     }
8782
8783   M (ADD_NODE_NEXT, add_node_next);
8784   clib_memcpy (mp->node_name, name, vec_len (name));
8785   clib_memcpy (mp->next_name, next, vec_len (next));
8786   vec_free (name);
8787   vec_free (next);
8788
8789   S;
8790   W;
8791   /* NOTREACHED */
8792   return 0;
8793 }
8794
8795 static int
8796 api_l2tpv3_create_tunnel (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   ip6_address_t client_address, our_address;
8800   int client_address_set = 0;
8801   int our_address_set = 0;
8802   u32 local_session_id = 0;
8803   u32 remote_session_id = 0;
8804   u64 local_cookie = 0;
8805   u64 remote_cookie = 0;
8806   u8 l2_sublayer_present = 0;
8807   vl_api_l2tpv3_create_tunnel_t *mp;
8808   f64 timeout;
8809
8810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8811     {
8812       if (unformat (i, "client_address %U", unformat_ip6_address,
8813                     &client_address))
8814         client_address_set = 1;
8815       else if (unformat (i, "our_address %U", unformat_ip6_address,
8816                          &our_address))
8817         our_address_set = 1;
8818       else if (unformat (i, "local_session_id %d", &local_session_id))
8819         ;
8820       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8821         ;
8822       else if (unformat (i, "local_cookie %lld", &local_cookie))
8823         ;
8824       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8825         ;
8826       else if (unformat (i, "l2-sublayer-present"))
8827         l2_sublayer_present = 1;
8828       else
8829         break;
8830     }
8831
8832   if (client_address_set == 0)
8833     {
8834       errmsg ("client_address required\n");
8835       return -99;
8836     }
8837
8838   if (our_address_set == 0)
8839     {
8840       errmsg ("our_address required\n");
8841       return -99;
8842     }
8843
8844   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8845
8846   clib_memcpy (mp->client_address, client_address.as_u8,
8847                sizeof (mp->client_address));
8848
8849   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8850
8851   mp->local_session_id = ntohl (local_session_id);
8852   mp->remote_session_id = ntohl (remote_session_id);
8853   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8854   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8855   mp->l2_sublayer_present = l2_sublayer_present;
8856   mp->is_ipv6 = 1;
8857
8858   S;
8859   W;
8860   /* NOTREACHED */
8861   return 0;
8862 }
8863
8864 static int
8865 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8866 {
8867   unformat_input_t *i = vam->input;
8868   u32 sw_if_index;
8869   u8 sw_if_index_set = 0;
8870   u64 new_local_cookie = 0;
8871   u64 new_remote_cookie = 0;
8872   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8873   f64 timeout;
8874
8875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8876     {
8877       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8878         sw_if_index_set = 1;
8879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8880         sw_if_index_set = 1;
8881       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8882         ;
8883       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8884         ;
8885       else
8886         break;
8887     }
8888
8889   if (sw_if_index_set == 0)
8890     {
8891       errmsg ("missing interface name or sw_if_index\n");
8892       return -99;
8893     }
8894
8895   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8896
8897   mp->sw_if_index = ntohl (sw_if_index);
8898   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8899   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8900
8901   S;
8902   W;
8903   /* NOTREACHED */
8904   return 0;
8905 }
8906
8907 static int
8908 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8909 {
8910   unformat_input_t *i = vam->input;
8911   vl_api_l2tpv3_interface_enable_disable_t *mp;
8912   f64 timeout;
8913   u32 sw_if_index;
8914   u8 sw_if_index_set = 0;
8915   u8 enable_disable = 1;
8916
8917   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8918     {
8919       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8920         sw_if_index_set = 1;
8921       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8922         sw_if_index_set = 1;
8923       else if (unformat (i, "enable"))
8924         enable_disable = 1;
8925       else if (unformat (i, "disable"))
8926         enable_disable = 0;
8927       else
8928         break;
8929     }
8930
8931   if (sw_if_index_set == 0)
8932     {
8933       errmsg ("missing interface name or sw_if_index\n");
8934       return -99;
8935     }
8936
8937   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8938
8939   mp->sw_if_index = ntohl (sw_if_index);
8940   mp->enable_disable = enable_disable;
8941
8942   S;
8943   W;
8944   /* NOTREACHED */
8945   return 0;
8946 }
8947
8948 static int
8949 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_l2tpv3_set_lookup_key_t *mp;
8953   f64 timeout;
8954   u8 key = ~0;
8955
8956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8957     {
8958       if (unformat (i, "lookup_v6_src"))
8959         key = L2T_LOOKUP_SRC_ADDRESS;
8960       else if (unformat (i, "lookup_v6_dst"))
8961         key = L2T_LOOKUP_DST_ADDRESS;
8962       else if (unformat (i, "lookup_session_id"))
8963         key = L2T_LOOKUP_SESSION_ID;
8964       else
8965         break;
8966     }
8967
8968   if (key == (u8) ~ 0)
8969     {
8970       errmsg ("l2tp session lookup key unset\n");
8971       return -99;
8972     }
8973
8974   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8975
8976   mp->key = key;
8977
8978   S;
8979   W;
8980   /* NOTREACHED */
8981   return 0;
8982 }
8983
8984 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8985   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8986 {
8987   vat_main_t *vam = &vat_main;
8988
8989   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8990            format_ip6_address, mp->our_address,
8991            format_ip6_address, mp->client_address,
8992            clib_net_to_host_u32 (mp->sw_if_index));
8993
8994   fformat (vam->ofp,
8995            "   local cookies %016llx %016llx remote cookie %016llx\n",
8996            clib_net_to_host_u64 (mp->local_cookie[0]),
8997            clib_net_to_host_u64 (mp->local_cookie[1]),
8998            clib_net_to_host_u64 (mp->remote_cookie));
8999
9000   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9001            clib_net_to_host_u32 (mp->local_session_id),
9002            clib_net_to_host_u32 (mp->remote_session_id));
9003
9004   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9005            mp->l2_sublayer_present ? "preset" : "absent");
9006
9007 }
9008
9009 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9010   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9011 {
9012   vat_main_t *vam = &vat_main;
9013   vat_json_node_t *node = NULL;
9014   struct in6_addr addr;
9015
9016   if (VAT_JSON_ARRAY != vam->json_tree.type)
9017     {
9018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9019       vat_json_init_array (&vam->json_tree);
9020     }
9021   node = vat_json_array_add (&vam->json_tree);
9022
9023   vat_json_init_object (node);
9024
9025   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9026   vat_json_object_add_ip6 (node, "our_address", addr);
9027   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9028   vat_json_object_add_ip6 (node, "client_address", addr);
9029
9030   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9031   vat_json_init_array (lc);
9032   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9033   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9034   vat_json_object_add_uint (node, "remote_cookie",
9035                             clib_net_to_host_u64 (mp->remote_cookie));
9036
9037   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9038   vat_json_object_add_uint (node, "local_session_id",
9039                             clib_net_to_host_u32 (mp->local_session_id));
9040   vat_json_object_add_uint (node, "remote_session_id",
9041                             clib_net_to_host_u32 (mp->remote_session_id));
9042   vat_json_object_add_string_copy (node, "l2_sublayer",
9043                                    mp->l2_sublayer_present ? (u8 *) "present"
9044                                    : (u8 *) "absent");
9045 }
9046
9047 static int
9048 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9049 {
9050   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9051   f64 timeout;
9052
9053   /* Get list of l2tpv3-tunnel interfaces */
9054   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9055   S;
9056
9057   /* Use a control ping for synchronization */
9058   {
9059     vl_api_control_ping_t *mp;
9060     M (CONTROL_PING, control_ping);
9061     S;
9062   }
9063   W;
9064 }
9065
9066
9067 static void vl_api_sw_interface_tap_details_t_handler
9068   (vl_api_sw_interface_tap_details_t * mp)
9069 {
9070   vat_main_t *vam = &vat_main;
9071
9072   fformat (vam->ofp, "%-16s %d\n",
9073            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9074 }
9075
9076 static void vl_api_sw_interface_tap_details_t_handler_json
9077   (vl_api_sw_interface_tap_details_t * mp)
9078 {
9079   vat_main_t *vam = &vat_main;
9080   vat_json_node_t *node = NULL;
9081
9082   if (VAT_JSON_ARRAY != vam->json_tree.type)
9083     {
9084       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9085       vat_json_init_array (&vam->json_tree);
9086     }
9087   node = vat_json_array_add (&vam->json_tree);
9088
9089   vat_json_init_object (node);
9090   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9091   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9092 }
9093
9094 static int
9095 api_sw_interface_tap_dump (vat_main_t * vam)
9096 {
9097   vl_api_sw_interface_tap_dump_t *mp;
9098   f64 timeout;
9099
9100   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9101   /* Get list of tap interfaces */
9102   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9103   S;
9104
9105   /* Use a control ping for synchronization */
9106   {
9107     vl_api_control_ping_t *mp;
9108     M (CONTROL_PING, control_ping);
9109     S;
9110   }
9111   W;
9112 }
9113
9114 static uword unformat_vxlan_decap_next
9115   (unformat_input_t * input, va_list * args)
9116 {
9117   u32 *result = va_arg (*args, u32 *);
9118   u32 tmp;
9119
9120   if (unformat (input, "drop"))
9121     *result = VXLAN_INPUT_NEXT_DROP;
9122   else if (unformat (input, "ip4"))
9123     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9124   else if (unformat (input, "ip6"))
9125     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9126   else if (unformat (input, "l2"))
9127     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9128   else if (unformat (input, "%d", &tmp))
9129     *result = tmp;
9130   else
9131     return 0;
9132   return 1;
9133 }
9134
9135 static int
9136 api_vxlan_add_del_tunnel (vat_main_t * vam)
9137 {
9138   unformat_input_t *line_input = vam->input;
9139   vl_api_vxlan_add_del_tunnel_t *mp;
9140   f64 timeout;
9141   ip4_address_t src4, dst4;
9142   ip6_address_t src6, dst6;
9143   u8 is_add = 1;
9144   u8 ipv4_set = 0, ipv6_set = 0;
9145   u8 src_set = 0;
9146   u8 dst_set = 0;
9147   u32 encap_vrf_id = 0;
9148   u32 decap_next_index = ~0;
9149   u32 vni = 0;
9150
9151   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9152     {
9153       if (unformat (line_input, "del"))
9154         is_add = 0;
9155       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9156         {
9157           ipv4_set = 1;
9158           src_set = 1;
9159         }
9160       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9161         {
9162           ipv4_set = 1;
9163           dst_set = 1;
9164         }
9165       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9166         {
9167           ipv6_set = 1;
9168           src_set = 1;
9169         }
9170       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9171         {
9172           ipv6_set = 1;
9173           dst_set = 1;
9174         }
9175       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9176         ;
9177       else if (unformat (line_input, "decap-next %U",
9178                          unformat_vxlan_decap_next, &decap_next_index))
9179         ;
9180       else if (unformat (line_input, "vni %d", &vni))
9181         ;
9182       else
9183         {
9184           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9185           return -99;
9186         }
9187     }
9188
9189   if (src_set == 0)
9190     {
9191       errmsg ("tunnel src address not specified\n");
9192       return -99;
9193     }
9194   if (dst_set == 0)
9195     {
9196       errmsg ("tunnel dst address not specified\n");
9197       return -99;
9198     }
9199
9200   if (ipv4_set && ipv6_set)
9201     {
9202       errmsg ("both IPv4 and IPv6 addresses specified");
9203       return -99;
9204     }
9205
9206   if ((vni == 0) || (vni >> 24))
9207     {
9208       errmsg ("vni not specified or out of range\n");
9209       return -99;
9210     }
9211
9212   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9213
9214   if (ipv6_set)
9215     {
9216       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9217       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9218     }
9219   else
9220     {
9221       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9222       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9223     }
9224   mp->encap_vrf_id = ntohl (encap_vrf_id);
9225   mp->decap_next_index = ntohl (decap_next_index);
9226   mp->vni = ntohl (vni);
9227   mp->is_add = is_add;
9228   mp->is_ipv6 = ipv6_set;
9229
9230   S;
9231   W;
9232   /* NOTREACHED */
9233   return 0;
9234 }
9235
9236 static void vl_api_vxlan_tunnel_details_t_handler
9237   (vl_api_vxlan_tunnel_details_t * mp)
9238 {
9239   vat_main_t *vam = &vat_main;
9240
9241   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9242            ntohl (mp->sw_if_index),
9243            format_ip46_address, &(mp->src_address[0]),
9244            IP46_TYPE_ANY,
9245            format_ip46_address, &(mp->dst_address[0]),
9246            IP46_TYPE_ANY,
9247            ntohl (mp->encap_vrf_id),
9248            ntohl (mp->decap_next_index), ntohl (mp->vni));
9249 }
9250
9251 static void vl_api_vxlan_tunnel_details_t_handler_json
9252   (vl_api_vxlan_tunnel_details_t * mp)
9253 {
9254   vat_main_t *vam = &vat_main;
9255   vat_json_node_t *node = NULL;
9256   struct in_addr ip4;
9257   struct in6_addr ip6;
9258
9259   if (VAT_JSON_ARRAY != vam->json_tree.type)
9260     {
9261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9262       vat_json_init_array (&vam->json_tree);
9263     }
9264   node = vat_json_array_add (&vam->json_tree);
9265
9266   vat_json_init_object (node);
9267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9268   if (mp->is_ipv6)
9269     {
9270       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9271       vat_json_object_add_ip6 (node, "src_address", ip6);
9272       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9273       vat_json_object_add_ip6 (node, "dst_address", ip6);
9274     }
9275   else
9276     {
9277       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9278       vat_json_object_add_ip4 (node, "src_address", ip4);
9279       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9280       vat_json_object_add_ip4 (node, "dst_address", ip4);
9281     }
9282   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9283   vat_json_object_add_uint (node, "decap_next_index",
9284                             ntohl (mp->decap_next_index));
9285   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9286   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9287 }
9288
9289 static int
9290 api_vxlan_tunnel_dump (vat_main_t * vam)
9291 {
9292   unformat_input_t *i = vam->input;
9293   vl_api_vxlan_tunnel_dump_t *mp;
9294   f64 timeout;
9295   u32 sw_if_index;
9296   u8 sw_if_index_set = 0;
9297
9298   /* Parse args required to build the message */
9299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9300     {
9301       if (unformat (i, "sw_if_index %d", &sw_if_index))
9302         sw_if_index_set = 1;
9303       else
9304         break;
9305     }
9306
9307   if (sw_if_index_set == 0)
9308     {
9309       sw_if_index = ~0;
9310     }
9311
9312   if (!vam->json_output)
9313     {
9314       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9315                "sw_if_index", "src_address", "dst_address",
9316                "encap_vrf_id", "decap_next_index", "vni");
9317     }
9318
9319   /* Get list of vxlan-tunnel interfaces */
9320   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9321
9322   mp->sw_if_index = htonl (sw_if_index);
9323
9324   S;
9325
9326   /* Use a control ping for synchronization */
9327   {
9328     vl_api_control_ping_t *mp;
9329     M (CONTROL_PING, control_ping);
9330     S;
9331   }
9332   W;
9333 }
9334
9335 static int
9336 api_gre_add_del_tunnel (vat_main_t * vam)
9337 {
9338   unformat_input_t *line_input = vam->input;
9339   vl_api_gre_add_del_tunnel_t *mp;
9340   f64 timeout;
9341   ip4_address_t src4, dst4;
9342   u8 is_add = 1;
9343   u8 src_set = 0;
9344   u8 dst_set = 0;
9345   u32 outer_fib_id = 0;
9346
9347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9348     {
9349       if (unformat (line_input, "del"))
9350         is_add = 0;
9351       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9352         src_set = 1;
9353       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9354         dst_set = 1;
9355       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9356         ;
9357       else
9358         {
9359           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9360           return -99;
9361         }
9362     }
9363
9364   if (src_set == 0)
9365     {
9366       errmsg ("tunnel src address not specified\n");
9367       return -99;
9368     }
9369   if (dst_set == 0)
9370     {
9371       errmsg ("tunnel dst address not specified\n");
9372       return -99;
9373     }
9374
9375
9376   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9377
9378   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9379   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9380   mp->outer_fib_id = ntohl (outer_fib_id);
9381   mp->is_add = is_add;
9382
9383   S;
9384   W;
9385   /* NOTREACHED */
9386   return 0;
9387 }
9388
9389 static void vl_api_gre_tunnel_details_t_handler
9390   (vl_api_gre_tunnel_details_t * mp)
9391 {
9392   vat_main_t *vam = &vat_main;
9393
9394   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9395            ntohl (mp->sw_if_index),
9396            format_ip4_address, &mp->src_address,
9397            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9398 }
9399
9400 static void vl_api_gre_tunnel_details_t_handler_json
9401   (vl_api_gre_tunnel_details_t * mp)
9402 {
9403   vat_main_t *vam = &vat_main;
9404   vat_json_node_t *node = NULL;
9405   struct in_addr ip4;
9406
9407   if (VAT_JSON_ARRAY != vam->json_tree.type)
9408     {
9409       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9410       vat_json_init_array (&vam->json_tree);
9411     }
9412   node = vat_json_array_add (&vam->json_tree);
9413
9414   vat_json_init_object (node);
9415   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9416   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9417   vat_json_object_add_ip4 (node, "src_address", ip4);
9418   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9419   vat_json_object_add_ip4 (node, "dst_address", ip4);
9420   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9421 }
9422
9423 static int
9424 api_gre_tunnel_dump (vat_main_t * vam)
9425 {
9426   unformat_input_t *i = vam->input;
9427   vl_api_gre_tunnel_dump_t *mp;
9428   f64 timeout;
9429   u32 sw_if_index;
9430   u8 sw_if_index_set = 0;
9431
9432   /* Parse args required to build the message */
9433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (i, "sw_if_index %d", &sw_if_index))
9436         sw_if_index_set = 1;
9437       else
9438         break;
9439     }
9440
9441   if (sw_if_index_set == 0)
9442     {
9443       sw_if_index = ~0;
9444     }
9445
9446   if (!vam->json_output)
9447     {
9448       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9449                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9450     }
9451
9452   /* Get list of gre-tunnel interfaces */
9453   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9454
9455   mp->sw_if_index = htonl (sw_if_index);
9456
9457   S;
9458
9459   /* Use a control ping for synchronization */
9460   {
9461     vl_api_control_ping_t *mp;
9462     M (CONTROL_PING, control_ping);
9463     S;
9464   }
9465   W;
9466 }
9467
9468 static int
9469 api_l2_fib_clear_table (vat_main_t * vam)
9470 {
9471 //  unformat_input_t * i = vam->input;
9472   vl_api_l2_fib_clear_table_t *mp;
9473   f64 timeout;
9474
9475   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9476
9477   S;
9478   W;
9479   /* NOTREACHED */
9480   return 0;
9481 }
9482
9483 static int
9484 api_l2_interface_efp_filter (vat_main_t * vam)
9485 {
9486   unformat_input_t *i = vam->input;
9487   vl_api_l2_interface_efp_filter_t *mp;
9488   f64 timeout;
9489   u32 sw_if_index;
9490   u8 enable = 1;
9491   u8 sw_if_index_set = 0;
9492
9493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9494     {
9495       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9496         sw_if_index_set = 1;
9497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9498         sw_if_index_set = 1;
9499       else if (unformat (i, "enable"))
9500         enable = 1;
9501       else if (unformat (i, "disable"))
9502         enable = 0;
9503       else
9504         {
9505           clib_warning ("parse error '%U'", format_unformat_error, i);
9506           return -99;
9507         }
9508     }
9509
9510   if (sw_if_index_set == 0)
9511     {
9512       errmsg ("missing sw_if_index\n");
9513       return -99;
9514     }
9515
9516   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9517
9518   mp->sw_if_index = ntohl (sw_if_index);
9519   mp->enable_disable = enable;
9520
9521   S;
9522   W;
9523   /* NOTREACHED */
9524   return 0;
9525 }
9526
9527 #define foreach_vtr_op                          \
9528 _("disable",  L2_VTR_DISABLED)                  \
9529 _("push-1",  L2_VTR_PUSH_1)                     \
9530 _("push-2",  L2_VTR_PUSH_2)                     \
9531 _("pop-1",  L2_VTR_POP_1)                       \
9532 _("pop-2",  L2_VTR_POP_2)                       \
9533 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9534 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9535 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9536 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9537
9538 static int
9539 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9540 {
9541   unformat_input_t *i = vam->input;
9542   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9543   f64 timeout;
9544   u32 sw_if_index;
9545   u8 sw_if_index_set = 0;
9546   u8 vtr_op_set = 0;
9547   u32 vtr_op = 0;
9548   u32 push_dot1q = 1;
9549   u32 tag1 = ~0;
9550   u32 tag2 = ~0;
9551
9552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9553     {
9554       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "vtr_op %d", &vtr_op))
9559         vtr_op_set = 1;
9560 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9561       foreach_vtr_op
9562 #undef _
9563         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9564         ;
9565       else if (unformat (i, "tag1 %d", &tag1))
9566         ;
9567       else if (unformat (i, "tag2 %d", &tag2))
9568         ;
9569       else
9570         {
9571           clib_warning ("parse error '%U'", format_unformat_error, i);
9572           return -99;
9573         }
9574     }
9575
9576   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9577     {
9578       errmsg ("missing vtr operation or sw_if_index\n");
9579       return -99;
9580     }
9581
9582   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9583     mp->sw_if_index = ntohl (sw_if_index);
9584   mp->vtr_op = ntohl (vtr_op);
9585   mp->push_dot1q = ntohl (push_dot1q);
9586   mp->tag1 = ntohl (tag1);
9587   mp->tag2 = ntohl (tag2);
9588
9589   S;
9590   W;
9591   /* NOTREACHED */
9592   return 0;
9593 }
9594
9595 static int
9596 api_create_vhost_user_if (vat_main_t * vam)
9597 {
9598   unformat_input_t *i = vam->input;
9599   vl_api_create_vhost_user_if_t *mp;
9600   f64 timeout;
9601   u8 *file_name;
9602   u8 is_server = 0;
9603   u8 file_name_set = 0;
9604   u32 custom_dev_instance = ~0;
9605   u8 hwaddr[6];
9606   u8 use_custom_mac = 0;
9607
9608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9609     {
9610       if (unformat (i, "socket %s", &file_name))
9611         {
9612           file_name_set = 1;
9613         }
9614       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9615         ;
9616       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9617         use_custom_mac = 1;
9618       else if (unformat (i, "server"))
9619         is_server = 1;
9620       else
9621         break;
9622     }
9623
9624   if (file_name_set == 0)
9625     {
9626       errmsg ("missing socket file name\n");
9627       return -99;
9628     }
9629
9630   if (vec_len (file_name) > 255)
9631     {
9632       errmsg ("socket file name too long\n");
9633       return -99;
9634     }
9635   vec_add1 (file_name, 0);
9636
9637   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9638
9639   mp->is_server = is_server;
9640   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9641   vec_free (file_name);
9642   if (custom_dev_instance != ~0)
9643     {
9644       mp->renumber = 1;
9645       mp->custom_dev_instance = ntohl (custom_dev_instance);
9646     }
9647   mp->use_custom_mac = use_custom_mac;
9648   clib_memcpy (mp->mac_address, hwaddr, 6);
9649
9650   S;
9651   W;
9652   /* NOTREACHED */
9653   return 0;
9654 }
9655
9656 static int
9657 api_modify_vhost_user_if (vat_main_t * vam)
9658 {
9659   unformat_input_t *i = vam->input;
9660   vl_api_modify_vhost_user_if_t *mp;
9661   f64 timeout;
9662   u8 *file_name;
9663   u8 is_server = 0;
9664   u8 file_name_set = 0;
9665   u32 custom_dev_instance = ~0;
9666   u8 sw_if_index_set = 0;
9667   u32 sw_if_index = (u32) ~ 0;
9668
9669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9670     {
9671       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9672         sw_if_index_set = 1;
9673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9674         sw_if_index_set = 1;
9675       else if (unformat (i, "socket %s", &file_name))
9676         {
9677           file_name_set = 1;
9678         }
9679       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9680         ;
9681       else if (unformat (i, "server"))
9682         is_server = 1;
9683       else
9684         break;
9685     }
9686
9687   if (sw_if_index_set == 0)
9688     {
9689       errmsg ("missing sw_if_index or interface name\n");
9690       return -99;
9691     }
9692
9693   if (file_name_set == 0)
9694     {
9695       errmsg ("missing socket file name\n");
9696       return -99;
9697     }
9698
9699   if (vec_len (file_name) > 255)
9700     {
9701       errmsg ("socket file name too long\n");
9702       return -99;
9703     }
9704   vec_add1 (file_name, 0);
9705
9706   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9707
9708   mp->sw_if_index = ntohl (sw_if_index);
9709   mp->is_server = is_server;
9710   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9711   vec_free (file_name);
9712   if (custom_dev_instance != ~0)
9713     {
9714       mp->renumber = 1;
9715       mp->custom_dev_instance = ntohl (custom_dev_instance);
9716     }
9717
9718   S;
9719   W;
9720   /* NOTREACHED */
9721   return 0;
9722 }
9723
9724 static int
9725 api_delete_vhost_user_if (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_delete_vhost_user_if_t *mp;
9729   f64 timeout;
9730   u32 sw_if_index = ~0;
9731   u8 sw_if_index_set = 0;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9736         sw_if_index_set = 1;
9737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9738         sw_if_index_set = 1;
9739       else
9740         break;
9741     }
9742
9743   if (sw_if_index_set == 0)
9744     {
9745       errmsg ("missing sw_if_index or interface name\n");
9746       return -99;
9747     }
9748
9749
9750   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9751
9752   mp->sw_if_index = ntohl (sw_if_index);
9753
9754   S;
9755   W;
9756   /* NOTREACHED */
9757   return 0;
9758 }
9759
9760 static void vl_api_sw_interface_vhost_user_details_t_handler
9761   (vl_api_sw_interface_vhost_user_details_t * mp)
9762 {
9763   vat_main_t *vam = &vat_main;
9764
9765   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9766            (char *) mp->interface_name,
9767            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9768            clib_net_to_host_u64 (mp->features), mp->is_server,
9769            ntohl (mp->num_regions), (char *) mp->sock_filename);
9770   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9771 }
9772
9773 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9774   (vl_api_sw_interface_vhost_user_details_t * mp)
9775 {
9776   vat_main_t *vam = &vat_main;
9777   vat_json_node_t *node = NULL;
9778
9779   if (VAT_JSON_ARRAY != vam->json_tree.type)
9780     {
9781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9782       vat_json_init_array (&vam->json_tree);
9783     }
9784   node = vat_json_array_add (&vam->json_tree);
9785
9786   vat_json_init_object (node);
9787   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9788   vat_json_object_add_string_copy (node, "interface_name",
9789                                    mp->interface_name);
9790   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9791                             ntohl (mp->virtio_net_hdr_sz));
9792   vat_json_object_add_uint (node, "features",
9793                             clib_net_to_host_u64 (mp->features));
9794   vat_json_object_add_uint (node, "is_server", mp->is_server);
9795   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9796   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9797   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9798 }
9799
9800 static int
9801 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9802 {
9803   vl_api_sw_interface_vhost_user_dump_t *mp;
9804   f64 timeout;
9805   fformat (vam->ofp,
9806            "Interface name           idx hdr_sz features server regions filename\n");
9807
9808   /* Get list of vhost-user interfaces */
9809   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9810   S;
9811
9812   /* Use a control ping for synchronization */
9813   {
9814     vl_api_control_ping_t *mp;
9815     M (CONTROL_PING, control_ping);
9816     S;
9817   }
9818   W;
9819 }
9820
9821 static int
9822 api_show_version (vat_main_t * vam)
9823 {
9824   vl_api_show_version_t *mp;
9825   f64 timeout;
9826
9827   M (SHOW_VERSION, show_version);
9828
9829   S;
9830   W;
9831   /* NOTREACHED */
9832   return 0;
9833 }
9834
9835
9836 static int
9837 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9838 {
9839   unformat_input_t *line_input = vam->input;
9840   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9841   f64 timeout;
9842   ip4_address_t local4, remote4;
9843   ip6_address_t local6, remote6;
9844   u8 is_add = 1;
9845   u8 ipv4_set = 0, ipv6_set = 0;
9846   u8 local_set = 0;
9847   u8 remote_set = 0;
9848   u32 encap_vrf_id = 0;
9849   u32 decap_vrf_id = 0;
9850   u8 protocol = ~0;
9851   u32 vni;
9852   u8 vni_set = 0;
9853
9854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9855     {
9856       if (unformat (line_input, "del"))
9857         is_add = 0;
9858       else if (unformat (line_input, "local %U",
9859                          unformat_ip4_address, &local4))
9860         {
9861           local_set = 1;
9862           ipv4_set = 1;
9863         }
9864       else if (unformat (line_input, "remote %U",
9865                          unformat_ip4_address, &remote4))
9866         {
9867           remote_set = 1;
9868           ipv4_set = 1;
9869         }
9870       else if (unformat (line_input, "local %U",
9871                          unformat_ip6_address, &local6))
9872         {
9873           local_set = 1;
9874           ipv6_set = 1;
9875         }
9876       else if (unformat (line_input, "remote %U",
9877                          unformat_ip6_address, &remote6))
9878         {
9879           remote_set = 1;
9880           ipv6_set = 1;
9881         }
9882       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9883         ;
9884       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9885         ;
9886       else if (unformat (line_input, "vni %d", &vni))
9887         vni_set = 1;
9888       else if (unformat (line_input, "next-ip4"))
9889         protocol = 1;
9890       else if (unformat (line_input, "next-ip6"))
9891         protocol = 2;
9892       else if (unformat (line_input, "next-ethernet"))
9893         protocol = 3;
9894       else if (unformat (line_input, "next-nsh"))
9895         protocol = 4;
9896       else
9897         {
9898           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9899           return -99;
9900         }
9901     }
9902
9903   if (local_set == 0)
9904     {
9905       errmsg ("tunnel local address not specified\n");
9906       return -99;
9907     }
9908   if (remote_set == 0)
9909     {
9910       errmsg ("tunnel remote address not specified\n");
9911       return -99;
9912     }
9913   if (ipv4_set && ipv6_set)
9914     {
9915       errmsg ("both IPv4 and IPv6 addresses specified");
9916       return -99;
9917     }
9918
9919   if (vni_set == 0)
9920     {
9921       errmsg ("vni not specified\n");
9922       return -99;
9923     }
9924
9925   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9926
9927
9928   if (ipv6_set)
9929     {
9930       clib_memcpy (&mp->local, &local6, sizeof (local6));
9931       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9932     }
9933   else
9934     {
9935       clib_memcpy (&mp->local, &local4, sizeof (local4));
9936       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9937     }
9938
9939   mp->encap_vrf_id = ntohl (encap_vrf_id);
9940   mp->decap_vrf_id = ntohl (decap_vrf_id);
9941   mp->protocol = ntohl (protocol);
9942   mp->vni = ntohl (vni);
9943   mp->is_add = is_add;
9944   mp->is_ipv6 = ipv6_set;
9945
9946   S;
9947   W;
9948   /* NOTREACHED */
9949   return 0;
9950 }
9951
9952 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9953   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9954 {
9955   vat_main_t *vam = &vat_main;
9956
9957   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9958            ntohl (mp->sw_if_index),
9959            format_ip46_address, &(mp->local[0]),
9960            format_ip46_address, &(mp->remote[0]),
9961            ntohl (mp->vni),
9962            ntohl (mp->protocol),
9963            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9964 }
9965
9966 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9967   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9968 {
9969   vat_main_t *vam = &vat_main;
9970   vat_json_node_t *node = NULL;
9971   struct in_addr ip4;
9972   struct in6_addr ip6;
9973
9974   if (VAT_JSON_ARRAY != vam->json_tree.type)
9975     {
9976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9977       vat_json_init_array (&vam->json_tree);
9978     }
9979   node = vat_json_array_add (&vam->json_tree);
9980
9981   vat_json_init_object (node);
9982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9983   if (mp->is_ipv6)
9984     {
9985       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9986       vat_json_object_add_ip6 (node, "local", ip6);
9987       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9988       vat_json_object_add_ip6 (node, "remote", ip6);
9989     }
9990   else
9991     {
9992       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9993       vat_json_object_add_ip4 (node, "local", ip4);
9994       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9995       vat_json_object_add_ip4 (node, "remote", ip4);
9996     }
9997   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9998   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9999   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10000   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10001   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10002 }
10003
10004 static int
10005 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10006 {
10007   unformat_input_t *i = vam->input;
10008   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10009   f64 timeout;
10010   u32 sw_if_index;
10011   u8 sw_if_index_set = 0;
10012
10013   /* Parse args required to build the message */
10014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (i, "sw_if_index %d", &sw_if_index))
10017         sw_if_index_set = 1;
10018       else
10019         break;
10020     }
10021
10022   if (sw_if_index_set == 0)
10023     {
10024       sw_if_index = ~0;
10025     }
10026
10027   if (!vam->json_output)
10028     {
10029       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10030                "sw_if_index", "local", "remote", "vni",
10031                "protocol", "encap_vrf_id", "decap_vrf_id");
10032     }
10033
10034   /* Get list of vxlan-tunnel interfaces */
10035   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10036
10037   mp->sw_if_index = htonl (sw_if_index);
10038
10039   S;
10040
10041   /* Use a control ping for synchronization */
10042   {
10043     vl_api_control_ping_t *mp;
10044     M (CONTROL_PING, control_ping);
10045     S;
10046   }
10047   W;
10048 }
10049
10050 u8 *
10051 format_l2_fib_mac_address (u8 * s, va_list * args)
10052 {
10053   u8 *a = va_arg (*args, u8 *);
10054
10055   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10056                  a[2], a[3], a[4], a[5], a[6], a[7]);
10057 }
10058
10059 static void vl_api_l2_fib_table_entry_t_handler
10060   (vl_api_l2_fib_table_entry_t * mp)
10061 {
10062   vat_main_t *vam = &vat_main;
10063
10064   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10065            "       %d       %d     %d\n",
10066            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10067            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10068            mp->bvi_mac);
10069 }
10070
10071 static void vl_api_l2_fib_table_entry_t_handler_json
10072   (vl_api_l2_fib_table_entry_t * mp)
10073 {
10074   vat_main_t *vam = &vat_main;
10075   vat_json_node_t *node = NULL;
10076
10077   if (VAT_JSON_ARRAY != vam->json_tree.type)
10078     {
10079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10080       vat_json_init_array (&vam->json_tree);
10081     }
10082   node = vat_json_array_add (&vam->json_tree);
10083
10084   vat_json_init_object (node);
10085   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10086   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10087   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10088   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10089   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10090   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10091 }
10092
10093 static int
10094 api_l2_fib_table_dump (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_l2_fib_table_dump_t *mp;
10098   f64 timeout;
10099   u32 bd_id;
10100   u8 bd_id_set = 0;
10101
10102   /* Parse args required to build the message */
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "bd_id %d", &bd_id))
10106         bd_id_set = 1;
10107       else
10108         break;
10109     }
10110
10111   if (bd_id_set == 0)
10112     {
10113       errmsg ("missing bridge domain\n");
10114       return -99;
10115     }
10116
10117   fformat (vam->ofp,
10118            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10119
10120   /* Get list of l2 fib entries */
10121   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10122
10123   mp->bd_id = ntohl (bd_id);
10124   S;
10125
10126   /* Use a control ping for synchronization */
10127   {
10128     vl_api_control_ping_t *mp;
10129     M (CONTROL_PING, control_ping);
10130     S;
10131   }
10132   W;
10133 }
10134
10135
10136 static int
10137 api_interface_name_renumber (vat_main_t * vam)
10138 {
10139   unformat_input_t *line_input = vam->input;
10140   vl_api_interface_name_renumber_t *mp;
10141   u32 sw_if_index = ~0;
10142   f64 timeout;
10143   u32 new_show_dev_instance = ~0;
10144
10145   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10148                     &sw_if_index))
10149         ;
10150       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10151         ;
10152       else if (unformat (line_input, "new_show_dev_instance %d",
10153                          &new_show_dev_instance))
10154         ;
10155       else
10156         break;
10157     }
10158
10159   if (sw_if_index == ~0)
10160     {
10161       errmsg ("missing interface name or sw_if_index\n");
10162       return -99;
10163     }
10164
10165   if (new_show_dev_instance == ~0)
10166     {
10167       errmsg ("missing new_show_dev_instance\n");
10168       return -99;
10169     }
10170
10171   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10172
10173   mp->sw_if_index = ntohl (sw_if_index);
10174   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10175
10176   S;
10177   W;
10178 }
10179
10180 static int
10181 api_want_ip4_arp_events (vat_main_t * vam)
10182 {
10183   unformat_input_t *line_input = vam->input;
10184   vl_api_want_ip4_arp_events_t *mp;
10185   f64 timeout;
10186   ip4_address_t address;
10187   int address_set = 0;
10188   u32 enable_disable = 1;
10189
10190   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10191     {
10192       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10193         address_set = 1;
10194       else if (unformat (line_input, "del"))
10195         enable_disable = 0;
10196       else
10197         break;
10198     }
10199
10200   if (address_set == 0)
10201     {
10202       errmsg ("missing addresses\n");
10203       return -99;
10204     }
10205
10206   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10207   mp->enable_disable = enable_disable;
10208   mp->pid = getpid ();
10209   mp->address = address.as_u32;
10210
10211   S;
10212   W;
10213 }
10214
10215 static int
10216 api_input_acl_set_interface (vat_main_t * vam)
10217 {
10218   unformat_input_t *i = vam->input;
10219   vl_api_input_acl_set_interface_t *mp;
10220   f64 timeout;
10221   u32 sw_if_index;
10222   int sw_if_index_set;
10223   u32 ip4_table_index = ~0;
10224   u32 ip6_table_index = ~0;
10225   u32 l2_table_index = ~0;
10226   u8 is_add = 1;
10227
10228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10229     {
10230       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10231         sw_if_index_set = 1;
10232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10233         sw_if_index_set = 1;
10234       else if (unformat (i, "del"))
10235         is_add = 0;
10236       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10237         ;
10238       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10239         ;
10240       else if (unformat (i, "l2-table %d", &l2_table_index))
10241         ;
10242       else
10243         {
10244           clib_warning ("parse error '%U'", format_unformat_error, i);
10245           return -99;
10246         }
10247     }
10248
10249   if (sw_if_index_set == 0)
10250     {
10251       errmsg ("missing interface name or sw_if_index\n");
10252       return -99;
10253     }
10254
10255   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10256
10257   mp->sw_if_index = ntohl (sw_if_index);
10258   mp->ip4_table_index = ntohl (ip4_table_index);
10259   mp->ip6_table_index = ntohl (ip6_table_index);
10260   mp->l2_table_index = ntohl (l2_table_index);
10261   mp->is_add = is_add;
10262
10263   S;
10264   W;
10265   /* NOTREACHED */
10266   return 0;
10267 }
10268
10269 static int
10270 api_ip_address_dump (vat_main_t * vam)
10271 {
10272   unformat_input_t *i = vam->input;
10273   vl_api_ip_address_dump_t *mp;
10274   u32 sw_if_index = ~0;
10275   u8 sw_if_index_set = 0;
10276   u8 ipv4_set = 0;
10277   u8 ipv6_set = 0;
10278   f64 timeout;
10279
10280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10281     {
10282       if (unformat (i, "sw_if_index %d", &sw_if_index))
10283         sw_if_index_set = 1;
10284       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10285         sw_if_index_set = 1;
10286       else if (unformat (i, "ipv4"))
10287         ipv4_set = 1;
10288       else if (unformat (i, "ipv6"))
10289         ipv6_set = 1;
10290       else
10291         break;
10292     }
10293
10294   if (ipv4_set && ipv6_set)
10295     {
10296       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10297       return -99;
10298     }
10299
10300   if ((!ipv4_set) && (!ipv6_set))
10301     {
10302       errmsg ("no ipv4 nor ipv6 flag set\n");
10303       return -99;
10304     }
10305
10306   if (sw_if_index_set == 0)
10307     {
10308       errmsg ("missing interface name or sw_if_index\n");
10309       return -99;
10310     }
10311
10312   vam->current_sw_if_index = sw_if_index;
10313   vam->is_ipv6 = ipv6_set;
10314
10315   M (IP_ADDRESS_DUMP, ip_address_dump);
10316   mp->sw_if_index = ntohl (sw_if_index);
10317   mp->is_ipv6 = ipv6_set;
10318   S;
10319
10320   /* Use a control ping for synchronization */
10321   {
10322     vl_api_control_ping_t *mp;
10323     M (CONTROL_PING, control_ping);
10324     S;
10325   }
10326   W;
10327 }
10328
10329 static int
10330 api_ip_dump (vat_main_t * vam)
10331 {
10332   vl_api_ip_dump_t *mp;
10333   unformat_input_t *in = vam->input;
10334   int ipv4_set = 0;
10335   int ipv6_set = 0;
10336   int is_ipv6;
10337   f64 timeout;
10338   int i;
10339
10340   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10341     {
10342       if (unformat (in, "ipv4"))
10343         ipv4_set = 1;
10344       else if (unformat (in, "ipv6"))
10345         ipv6_set = 1;
10346       else
10347         break;
10348     }
10349
10350   if (ipv4_set && ipv6_set)
10351     {
10352       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10353       return -99;
10354     }
10355
10356   if ((!ipv4_set) && (!ipv6_set))
10357     {
10358       errmsg ("no ipv4 nor ipv6 flag set\n");
10359       return -99;
10360     }
10361
10362   is_ipv6 = ipv6_set;
10363   vam->is_ipv6 = is_ipv6;
10364
10365   /* free old data */
10366   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10367     {
10368       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10369     }
10370   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10371
10372   M (IP_DUMP, ip_dump);
10373   mp->is_ipv6 = ipv6_set;
10374   S;
10375
10376   /* Use a control ping for synchronization */
10377   {
10378     vl_api_control_ping_t *mp;
10379     M (CONTROL_PING, control_ping);
10380     S;
10381   }
10382   W;
10383 }
10384
10385 static int
10386 api_ipsec_spd_add_del (vat_main_t * vam)
10387 {
10388 #if DPDK > 0
10389   unformat_input_t *i = vam->input;
10390   vl_api_ipsec_spd_add_del_t *mp;
10391   f64 timeout;
10392   u32 spd_id = ~0;
10393   u8 is_add = 1;
10394
10395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10396     {
10397       if (unformat (i, "spd_id %d", &spd_id))
10398         ;
10399       else if (unformat (i, "del"))
10400         is_add = 0;
10401       else
10402         {
10403           clib_warning ("parse error '%U'", format_unformat_error, i);
10404           return -99;
10405         }
10406     }
10407   if (spd_id == ~0)
10408     {
10409       errmsg ("spd_id must be set\n");
10410       return -99;
10411     }
10412
10413   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10414
10415   mp->spd_id = ntohl (spd_id);
10416   mp->is_add = is_add;
10417
10418   S;
10419   W;
10420   /* NOTREACHED */
10421   return 0;
10422 #else
10423   clib_warning ("unsupported (no dpdk)");
10424   return -99;
10425 #endif
10426 }
10427
10428 static int
10429 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10430 {
10431 #if DPDK > 0
10432   unformat_input_t *i = vam->input;
10433   vl_api_ipsec_interface_add_del_spd_t *mp;
10434   f64 timeout;
10435   u32 sw_if_index;
10436   u8 sw_if_index_set = 0;
10437   u32 spd_id = (u32) ~ 0;
10438   u8 is_add = 1;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "del"))
10443         is_add = 0;
10444       else if (unformat (i, "spd_id %d", &spd_id))
10445         ;
10446       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10447         sw_if_index_set = 1;
10448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10449         sw_if_index_set = 1;
10450       else
10451         {
10452           clib_warning ("parse error '%U'", format_unformat_error, i);
10453           return -99;
10454         }
10455
10456     }
10457
10458   if (spd_id == (u32) ~ 0)
10459     {
10460       errmsg ("spd_id must be set\n");
10461       return -99;
10462     }
10463
10464   if (sw_if_index_set == 0)
10465     {
10466       errmsg ("missing interface name or sw_if_index\n");
10467       return -99;
10468     }
10469
10470   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10471
10472   mp->spd_id = ntohl (spd_id);
10473   mp->sw_if_index = ntohl (sw_if_index);
10474   mp->is_add = is_add;
10475
10476   S;
10477   W;
10478   /* NOTREACHED */
10479   return 0;
10480 #else
10481   clib_warning ("unsupported (no dpdk)");
10482   return -99;
10483 #endif
10484 }
10485
10486 static int
10487 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10488 {
10489 #if DPDK > 0
10490   unformat_input_t *i = vam->input;
10491   vl_api_ipsec_spd_add_del_entry_t *mp;
10492   f64 timeout;
10493   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10494   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10495   i32 priority = 0;
10496   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10497   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10498   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10499   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10500
10501   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10502   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10503   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10504   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10505   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10506   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "del"))
10511         is_add = 0;
10512       if (unformat (i, "outbound"))
10513         is_outbound = 1;
10514       if (unformat (i, "inbound"))
10515         is_outbound = 0;
10516       else if (unformat (i, "spd_id %d", &spd_id))
10517         ;
10518       else if (unformat (i, "sa_id %d", &sa_id))
10519         ;
10520       else if (unformat (i, "priority %d", &priority))
10521         ;
10522       else if (unformat (i, "protocol %d", &protocol))
10523         ;
10524       else if (unformat (i, "lport_start %d", &lport_start))
10525         ;
10526       else if (unformat (i, "lport_stop %d", &lport_stop))
10527         ;
10528       else if (unformat (i, "rport_start %d", &rport_start))
10529         ;
10530       else if (unformat (i, "rport_stop %d", &rport_stop))
10531         ;
10532       else
10533         if (unformat
10534             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10535         {
10536           is_ipv6 = 0;
10537           is_ip_any = 0;
10538         }
10539       else
10540         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10541         {
10542           is_ipv6 = 0;
10543           is_ip_any = 0;
10544         }
10545       else
10546         if (unformat
10547             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10548         {
10549           is_ipv6 = 0;
10550           is_ip_any = 0;
10551         }
10552       else
10553         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10554         {
10555           is_ipv6 = 0;
10556           is_ip_any = 0;
10557         }
10558       else
10559         if (unformat
10560             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10561         {
10562           is_ipv6 = 1;
10563           is_ip_any = 0;
10564         }
10565       else
10566         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10567         {
10568           is_ipv6 = 1;
10569           is_ip_any = 0;
10570         }
10571       else
10572         if (unformat
10573             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10574         {
10575           is_ipv6 = 1;
10576           is_ip_any = 0;
10577         }
10578       else
10579         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10580         {
10581           is_ipv6 = 1;
10582           is_ip_any = 0;
10583         }
10584       else
10585         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10586         {
10587           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10588             {
10589               clib_warning ("unsupported action: 'resolve'");
10590               return -99;
10591             }
10592         }
10593       else
10594         {
10595           clib_warning ("parse error '%U'", format_unformat_error, i);
10596           return -99;
10597         }
10598
10599     }
10600
10601   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10602
10603   mp->spd_id = ntohl (spd_id);
10604   mp->priority = ntohl (priority);
10605   mp->is_outbound = is_outbound;
10606
10607   mp->is_ipv6 = is_ipv6;
10608   if (is_ipv6 || is_ip_any)
10609     {
10610       clib_memcpy (mp->remote_address_start, &raddr6_start,
10611                    sizeof (ip6_address_t));
10612       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10613                    sizeof (ip6_address_t));
10614       clib_memcpy (mp->local_address_start, &laddr6_start,
10615                    sizeof (ip6_address_t));
10616       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10617                    sizeof (ip6_address_t));
10618     }
10619   else
10620     {
10621       clib_memcpy (mp->remote_address_start, &raddr4_start,
10622                    sizeof (ip4_address_t));
10623       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10624                    sizeof (ip4_address_t));
10625       clib_memcpy (mp->local_address_start, &laddr4_start,
10626                    sizeof (ip4_address_t));
10627       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10628                    sizeof (ip4_address_t));
10629     }
10630   mp->protocol = (u8) protocol;
10631   mp->local_port_start = ntohs ((u16) lport_start);
10632   mp->local_port_stop = ntohs ((u16) lport_stop);
10633   mp->remote_port_start = ntohs ((u16) rport_start);
10634   mp->remote_port_stop = ntohs ((u16) rport_stop);
10635   mp->policy = (u8) policy;
10636   mp->sa_id = ntohl (sa_id);
10637   mp->is_add = is_add;
10638   mp->is_ip_any = is_ip_any;
10639   S;
10640   W;
10641   /* NOTREACHED */
10642   return 0;
10643 #else
10644   clib_warning ("unsupported (no dpdk)");
10645   return -99;
10646 #endif
10647 }
10648
10649 static int
10650 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10651 {
10652 #if DPDK > 0
10653   unformat_input_t *i = vam->input;
10654   vl_api_ipsec_sad_add_del_entry_t *mp;
10655   f64 timeout;
10656   u32 sad_id = 0, spi = 0;
10657   u8 *ck = 0, *ik = 0;
10658   u8 is_add = 1;
10659
10660   u8 protocol = IPSEC_PROTOCOL_AH;
10661   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10662   u32 crypto_alg = 0, integ_alg = 0;
10663   ip4_address_t tun_src4;
10664   ip4_address_t tun_dst4;
10665   ip6_address_t tun_src6;
10666   ip6_address_t tun_dst6;
10667
10668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10669     {
10670       if (unformat (i, "del"))
10671         is_add = 0;
10672       else if (unformat (i, "sad_id %d", &sad_id))
10673         ;
10674       else if (unformat (i, "spi %d", &spi))
10675         ;
10676       else if (unformat (i, "esp"))
10677         protocol = IPSEC_PROTOCOL_ESP;
10678       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10679         {
10680           is_tunnel = 1;
10681           is_tunnel_ipv6 = 0;
10682         }
10683       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10684         {
10685           is_tunnel = 1;
10686           is_tunnel_ipv6 = 0;
10687         }
10688       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10689         {
10690           is_tunnel = 1;
10691           is_tunnel_ipv6 = 1;
10692         }
10693       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10694         {
10695           is_tunnel = 1;
10696           is_tunnel_ipv6 = 1;
10697         }
10698       else
10699         if (unformat
10700             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10701         {
10702           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10703               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10704             {
10705               clib_warning ("unsupported crypto-alg: '%U'",
10706                             format_ipsec_crypto_alg, crypto_alg);
10707               return -99;
10708             }
10709         }
10710       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10711         ;
10712       else
10713         if (unformat
10714             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10715         {
10716           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10717               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10718             {
10719               clib_warning ("unsupported integ-alg: '%U'",
10720                             format_ipsec_integ_alg, integ_alg);
10721               return -99;
10722             }
10723         }
10724       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10725         ;
10726       else
10727         {
10728           clib_warning ("parse error '%U'", format_unformat_error, i);
10729           return -99;
10730         }
10731
10732     }
10733
10734   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10735
10736   mp->sad_id = ntohl (sad_id);
10737   mp->is_add = is_add;
10738   mp->protocol = protocol;
10739   mp->spi = ntohl (spi);
10740   mp->is_tunnel = is_tunnel;
10741   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10742   mp->crypto_algorithm = crypto_alg;
10743   mp->integrity_algorithm = integ_alg;
10744   mp->crypto_key_length = vec_len (ck);
10745   mp->integrity_key_length = vec_len (ik);
10746
10747   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10748     mp->crypto_key_length = sizeof (mp->crypto_key);
10749
10750   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10751     mp->integrity_key_length = sizeof (mp->integrity_key);
10752
10753   if (ck)
10754     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10755   if (ik)
10756     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10757
10758   if (is_tunnel)
10759     {
10760       if (is_tunnel_ipv6)
10761         {
10762           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10763                        sizeof (ip6_address_t));
10764           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10765                        sizeof (ip6_address_t));
10766         }
10767       else
10768         {
10769           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10770                        sizeof (ip4_address_t));
10771           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10772                        sizeof (ip4_address_t));
10773         }
10774     }
10775
10776   S;
10777   W;
10778   /* NOTREACHED */
10779   return 0;
10780 #else
10781   clib_warning ("unsupported (no dpdk)");
10782   return -99;
10783 #endif
10784 }
10785
10786 static int
10787 api_ipsec_sa_set_key (vat_main_t * vam)
10788 {
10789 #if DPDK > 0
10790   unformat_input_t *i = vam->input;
10791   vl_api_ipsec_sa_set_key_t *mp;
10792   f64 timeout;
10793   u32 sa_id;
10794   u8 *ck = 0, *ik = 0;
10795
10796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (i, "sa_id %d", &sa_id))
10799         ;
10800       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10801         ;
10802       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10803         ;
10804       else
10805         {
10806           clib_warning ("parse error '%U'", format_unformat_error, i);
10807           return -99;
10808         }
10809     }
10810
10811   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10812
10813   mp->sa_id = ntohl (sa_id);
10814   mp->crypto_key_length = vec_len (ck);
10815   mp->integrity_key_length = vec_len (ik);
10816
10817   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10818     mp->crypto_key_length = sizeof (mp->crypto_key);
10819
10820   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10821     mp->integrity_key_length = sizeof (mp->integrity_key);
10822
10823   if (ck)
10824     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10825   if (ik)
10826     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10827
10828   S;
10829   W;
10830   /* NOTREACHED */
10831   return 0;
10832 #else
10833   clib_warning ("unsupported (no dpdk)");
10834   return -99;
10835 #endif
10836 }
10837
10838 static int
10839 api_ikev2_profile_add_del (vat_main_t * vam)
10840 {
10841 #if DPDK > 0
10842   unformat_input_t *i = vam->input;
10843   vl_api_ikev2_profile_add_del_t *mp;
10844   f64 timeout;
10845   u8 is_add = 1;
10846   u8 *name = 0;
10847
10848   const char *valid_chars = "a-zA-Z0-9_";
10849
10850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (i, "del"))
10853         is_add = 0;
10854       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10855         vec_add1 (name, 0);
10856       else
10857         {
10858           errmsg ("parse error '%U'", format_unformat_error, i);
10859           return -99;
10860         }
10861     }
10862
10863   if (!vec_len (name))
10864     {
10865       errmsg ("profile name must be specified");
10866       return -99;
10867     }
10868
10869   if (vec_len (name) > 64)
10870     {
10871       errmsg ("profile name too long");
10872       return -99;
10873     }
10874
10875   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10876
10877   clib_memcpy (mp->name, name, vec_len (name));
10878   mp->is_add = is_add;
10879   vec_free (name);
10880
10881   S;
10882   W;
10883   /* NOTREACHED */
10884   return 0;
10885 #else
10886   clib_warning ("unsupported (no dpdk)");
10887   return -99;
10888 #endif
10889 }
10890
10891 static int
10892 api_ikev2_profile_set_auth (vat_main_t * vam)
10893 {
10894 #if DPDK > 0
10895   unformat_input_t *i = vam->input;
10896   vl_api_ikev2_profile_set_auth_t *mp;
10897   f64 timeout;
10898   u8 *name = 0;
10899   u8 *data = 0;
10900   u32 auth_method = 0;
10901   u8 is_hex = 0;
10902
10903   const char *valid_chars = "a-zA-Z0-9_";
10904
10905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906     {
10907       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10908         vec_add1 (name, 0);
10909       else if (unformat (i, "auth_method %U",
10910                          unformat_ikev2_auth_method, &auth_method))
10911         ;
10912       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10913         is_hex = 1;
10914       else if (unformat (i, "auth_data %v", &data))
10915         ;
10916       else
10917         {
10918           errmsg ("parse error '%U'", format_unformat_error, i);
10919           return -99;
10920         }
10921     }
10922
10923   if (!vec_len (name))
10924     {
10925       errmsg ("profile name must be specified");
10926       return -99;
10927     }
10928
10929   if (vec_len (name) > 64)
10930     {
10931       errmsg ("profile name too long");
10932       return -99;
10933     }
10934
10935   if (!vec_len (data))
10936     {
10937       errmsg ("auth_data must be specified");
10938       return -99;
10939     }
10940
10941   if (!auth_method)
10942     {
10943       errmsg ("auth_method must be specified");
10944       return -99;
10945     }
10946
10947   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10948
10949   mp->is_hex = is_hex;
10950   mp->auth_method = (u8) auth_method;
10951   mp->data_len = vec_len (data);
10952   clib_memcpy (mp->name, name, vec_len (name));
10953   clib_memcpy (mp->data, data, vec_len (data));
10954   vec_free (name);
10955   vec_free (data);
10956
10957   S;
10958   W;
10959   /* NOTREACHED */
10960   return 0;
10961 #else
10962   clib_warning ("unsupported (no dpdk)");
10963   return -99;
10964 #endif
10965 }
10966
10967 static int
10968 api_ikev2_profile_set_id (vat_main_t * vam)
10969 {
10970 #if DPDK > 0
10971   unformat_input_t *i = vam->input;
10972   vl_api_ikev2_profile_set_id_t *mp;
10973   f64 timeout;
10974   u8 *name = 0;
10975   u8 *data = 0;
10976   u8 is_local = 0;
10977   u32 id_type = 0;
10978   ip4_address_t ip4;
10979
10980   const char *valid_chars = "a-zA-Z0-9_";
10981
10982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10985         vec_add1 (name, 0);
10986       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10987         ;
10988       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10989         {
10990           data = vec_new (u8, 4);
10991           clib_memcpy (data, ip4.as_u8, 4);
10992         }
10993       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10994         ;
10995       else if (unformat (i, "id_data %v", &data))
10996         ;
10997       else if (unformat (i, "local"))
10998         is_local = 1;
10999       else if (unformat (i, "remote"))
11000         is_local = 0;
11001       else
11002         {
11003           errmsg ("parse error '%U'", format_unformat_error, i);
11004           return -99;
11005         }
11006     }
11007
11008   if (!vec_len (name))
11009     {
11010       errmsg ("profile name must be specified");
11011       return -99;
11012     }
11013
11014   if (vec_len (name) > 64)
11015     {
11016       errmsg ("profile name too long");
11017       return -99;
11018     }
11019
11020   if (!vec_len (data))
11021     {
11022       errmsg ("id_data must be specified");
11023       return -99;
11024     }
11025
11026   if (!id_type)
11027     {
11028       errmsg ("id_type must be specified");
11029       return -99;
11030     }
11031
11032   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11033
11034   mp->is_local = is_local;
11035   mp->id_type = (u8) id_type;
11036   mp->data_len = vec_len (data);
11037   clib_memcpy (mp->name, name, vec_len (name));
11038   clib_memcpy (mp->data, data, vec_len (data));
11039   vec_free (name);
11040   vec_free (data);
11041
11042   S;
11043   W;
11044   /* NOTREACHED */
11045   return 0;
11046 #else
11047   clib_warning ("unsupported (no dpdk)");
11048   return -99;
11049 #endif
11050 }
11051
11052 static int
11053 api_ikev2_profile_set_ts (vat_main_t * vam)
11054 {
11055 #if DPDK > 0
11056   unformat_input_t *i = vam->input;
11057   vl_api_ikev2_profile_set_ts_t *mp;
11058   f64 timeout;
11059   u8 *name = 0;
11060   u8 is_local = 0;
11061   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11062   ip4_address_t start_addr, end_addr;
11063
11064   const char *valid_chars = "a-zA-Z0-9_";
11065
11066   start_addr.as_u32 = 0;
11067   end_addr.as_u32 = (u32) ~ 0;
11068
11069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11070     {
11071       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11072         vec_add1 (name, 0);
11073       else if (unformat (i, "protocol %d", &proto))
11074         ;
11075       else if (unformat (i, "start_port %d", &start_port))
11076         ;
11077       else if (unformat (i, "end_port %d", &end_port))
11078         ;
11079       else
11080         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11081         ;
11082       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11083         ;
11084       else if (unformat (i, "local"))
11085         is_local = 1;
11086       else if (unformat (i, "remote"))
11087         is_local = 0;
11088       else
11089         {
11090           errmsg ("parse error '%U'", format_unformat_error, i);
11091           return -99;
11092         }
11093     }
11094
11095   if (!vec_len (name))
11096     {
11097       errmsg ("profile name must be specified");
11098       return -99;
11099     }
11100
11101   if (vec_len (name) > 64)
11102     {
11103       errmsg ("profile name too long");
11104       return -99;
11105     }
11106
11107   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11108
11109   mp->is_local = is_local;
11110   mp->proto = (u8) proto;
11111   mp->start_port = (u16) start_port;
11112   mp->end_port = (u16) end_port;
11113   mp->start_addr = start_addr.as_u32;
11114   mp->end_addr = end_addr.as_u32;
11115   clib_memcpy (mp->name, name, vec_len (name));
11116   vec_free (name);
11117
11118   S;
11119   W;
11120   /* NOTREACHED */
11121   return 0;
11122 #else
11123   clib_warning ("unsupported (no dpdk)");
11124   return -99;
11125 #endif
11126 }
11127
11128 static int
11129 api_ikev2_set_local_key (vat_main_t * vam)
11130 {
11131 #if DPDK > 0
11132   unformat_input_t *i = vam->input;
11133   vl_api_ikev2_set_local_key_t *mp;
11134   f64 timeout;
11135   u8 *file = 0;
11136
11137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11138     {
11139       if (unformat (i, "file %v", &file))
11140         vec_add1 (file, 0);
11141       else
11142         {
11143           errmsg ("parse error '%U'", format_unformat_error, i);
11144           return -99;
11145         }
11146     }
11147
11148   if (!vec_len (file))
11149     {
11150       errmsg ("RSA key file must be specified");
11151       return -99;
11152     }
11153
11154   if (vec_len (file) > 256)
11155     {
11156       errmsg ("file name too long");
11157       return -99;
11158     }
11159
11160   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11161
11162   clib_memcpy (mp->key_file, file, vec_len (file));
11163   vec_free (file);
11164
11165   S;
11166   W;
11167   /* NOTREACHED */
11168   return 0;
11169 #else
11170   clib_warning ("unsupported (no dpdk)");
11171   return -99;
11172 #endif
11173 }
11174
11175 /*
11176  * MAP
11177  */
11178 static int
11179 api_map_add_domain (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_map_add_domain_t *mp;
11183   f64 timeout;
11184
11185   ip4_address_t ip4_prefix;
11186   ip6_address_t ip6_prefix;
11187   ip6_address_t ip6_src;
11188   u32 num_m_args = 0;
11189   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11190     0, psid_length = 0;
11191   u8 is_translation = 0;
11192   u32 mtu = 0;
11193   u32 ip6_src_len = 128;
11194
11195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11196     {
11197       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11198                     &ip4_prefix, &ip4_prefix_len))
11199         num_m_args++;
11200       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11201                          &ip6_prefix, &ip6_prefix_len))
11202         num_m_args++;
11203       else
11204         if (unformat
11205             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11206              &ip6_src_len))
11207         num_m_args++;
11208       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11209         num_m_args++;
11210       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11211         num_m_args++;
11212       else if (unformat (i, "psid-offset %d", &psid_offset))
11213         num_m_args++;
11214       else if (unformat (i, "psid-len %d", &psid_length))
11215         num_m_args++;
11216       else if (unformat (i, "mtu %d", &mtu))
11217         num_m_args++;
11218       else if (unformat (i, "map-t"))
11219         is_translation = 1;
11220       else
11221         {
11222           clib_warning ("parse error '%U'", format_unformat_error, i);
11223           return -99;
11224         }
11225     }
11226
11227   if (num_m_args != 6)
11228     {
11229       errmsg ("mandatory argument(s) missing\n");
11230       return -99;
11231     }
11232
11233   /* Construct the API message */
11234   M (MAP_ADD_DOMAIN, map_add_domain);
11235
11236   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11237   mp->ip4_prefix_len = ip4_prefix_len;
11238
11239   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11240   mp->ip6_prefix_len = ip6_prefix_len;
11241
11242   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11243   mp->ip6_src_prefix_len = ip6_src_len;
11244
11245   mp->ea_bits_len = ea_bits_len;
11246   mp->psid_offset = psid_offset;
11247   mp->psid_length = psid_length;
11248   mp->is_translation = is_translation;
11249   mp->mtu = htons (mtu);
11250
11251   /* send it... */
11252   S;
11253
11254   /* Wait for a reply, return good/bad news  */
11255   W;
11256 }
11257
11258 static int
11259 api_map_del_domain (vat_main_t * vam)
11260 {
11261   unformat_input_t *i = vam->input;
11262   vl_api_map_del_domain_t *mp;
11263   f64 timeout;
11264
11265   u32 num_m_args = 0;
11266   u32 index;
11267
11268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11269     {
11270       if (unformat (i, "index %d", &index))
11271         num_m_args++;
11272       else
11273         {
11274           clib_warning ("parse error '%U'", format_unformat_error, i);
11275           return -99;
11276         }
11277     }
11278
11279   if (num_m_args != 1)
11280     {
11281       errmsg ("mandatory argument(s) missing\n");
11282       return -99;
11283     }
11284
11285   /* Construct the API message */
11286   M (MAP_DEL_DOMAIN, map_del_domain);
11287
11288   mp->index = ntohl (index);
11289
11290   /* send it... */
11291   S;
11292
11293   /* Wait for a reply, return good/bad news  */
11294   W;
11295 }
11296
11297 static int
11298 api_map_add_del_rule (vat_main_t * vam)
11299 {
11300   unformat_input_t *i = vam->input;
11301   vl_api_map_add_del_rule_t *mp;
11302   f64 timeout;
11303   u8 is_add = 1;
11304   ip6_address_t ip6_dst;
11305   u32 num_m_args = 0, index, psid = 0;
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "index %d", &index))
11310         num_m_args++;
11311       else if (unformat (i, "psid %d", &psid))
11312         num_m_args++;
11313       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11314         num_m_args++;
11315       else if (unformat (i, "del"))
11316         {
11317           is_add = 0;
11318         }
11319       else
11320         {
11321           clib_warning ("parse error '%U'", format_unformat_error, i);
11322           return -99;
11323         }
11324     }
11325
11326   /* Construct the API message */
11327   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11328
11329   mp->index = ntohl (index);
11330   mp->is_add = is_add;
11331   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11332   mp->psid = ntohs (psid);
11333
11334   /* send it... */
11335   S;
11336
11337   /* Wait for a reply, return good/bad news  */
11338   W;
11339 }
11340
11341 static int
11342 api_map_domain_dump (vat_main_t * vam)
11343 {
11344   vl_api_map_domain_dump_t *mp;
11345   f64 timeout;
11346
11347   /* Construct the API message */
11348   M (MAP_DOMAIN_DUMP, map_domain_dump);
11349
11350   /* send it... */
11351   S;
11352
11353   /* Use a control ping for synchronization */
11354   {
11355     vl_api_control_ping_t *mp;
11356     M (CONTROL_PING, control_ping);
11357     S;
11358   }
11359   W;
11360 }
11361
11362 static int
11363 api_map_rule_dump (vat_main_t * vam)
11364 {
11365   unformat_input_t *i = vam->input;
11366   vl_api_map_rule_dump_t *mp;
11367   f64 timeout;
11368   u32 domain_index = ~0;
11369
11370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (i, "index %u", &domain_index))
11373         ;
11374       else
11375         break;
11376     }
11377
11378   if (domain_index == ~0)
11379     {
11380       clib_warning ("parse error: domain index expected");
11381       return -99;
11382     }
11383
11384   /* Construct the API message */
11385   M (MAP_RULE_DUMP, map_rule_dump);
11386
11387   mp->domain_index = htonl (domain_index);
11388
11389   /* send it... */
11390   S;
11391
11392   /* Use a control ping for synchronization */
11393   {
11394     vl_api_control_ping_t *mp;
11395     M (CONTROL_PING, control_ping);
11396     S;
11397   }
11398   W;
11399 }
11400
11401 static void vl_api_map_add_domain_reply_t_handler
11402   (vl_api_map_add_domain_reply_t * mp)
11403 {
11404   vat_main_t *vam = &vat_main;
11405   i32 retval = ntohl (mp->retval);
11406
11407   if (vam->async_mode)
11408     {
11409       vam->async_errors += (retval < 0);
11410     }
11411   else
11412     {
11413       vam->retval = retval;
11414       vam->result_ready = 1;
11415     }
11416 }
11417
11418 static void vl_api_map_add_domain_reply_t_handler_json
11419   (vl_api_map_add_domain_reply_t * mp)
11420 {
11421   vat_main_t *vam = &vat_main;
11422   vat_json_node_t node;
11423
11424   vat_json_init_object (&node);
11425   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11426   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11427
11428   vat_json_print (vam->ofp, &node);
11429   vat_json_free (&node);
11430
11431   vam->retval = ntohl (mp->retval);
11432   vam->result_ready = 1;
11433 }
11434
11435 static int
11436 api_get_first_msg_id (vat_main_t * vam)
11437 {
11438   vl_api_get_first_msg_id_t *mp;
11439   f64 timeout;
11440   unformat_input_t *i = vam->input;
11441   u8 *name;
11442   u8 name_set = 0;
11443
11444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11445     {
11446       if (unformat (i, "client %s", &name))
11447         name_set = 1;
11448       else
11449         break;
11450     }
11451
11452   if (name_set == 0)
11453     {
11454       errmsg ("missing client name\n");
11455       return -99;
11456     }
11457   vec_add1 (name, 0);
11458
11459   if (vec_len (name) > 63)
11460     {
11461       errmsg ("client name too long\n");
11462       return -99;
11463     }
11464
11465   M (GET_FIRST_MSG_ID, get_first_msg_id);
11466   clib_memcpy (mp->name, name, vec_len (name));
11467   S;
11468   W;
11469   /* NOTREACHED */
11470   return 0;
11471 }
11472
11473 static int
11474 api_cop_interface_enable_disable (vat_main_t * vam)
11475 {
11476   unformat_input_t *line_input = vam->input;
11477   vl_api_cop_interface_enable_disable_t *mp;
11478   f64 timeout;
11479   u32 sw_if_index = ~0;
11480   u8 enable_disable = 1;
11481
11482   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (line_input, "disable"))
11485         enable_disable = 0;
11486       if (unformat (line_input, "enable"))
11487         enable_disable = 1;
11488       else if (unformat (line_input, "%U", unformat_sw_if_index,
11489                          vam, &sw_if_index))
11490         ;
11491       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11492         ;
11493       else
11494         break;
11495     }
11496
11497   if (sw_if_index == ~0)
11498     {
11499       errmsg ("missing interface name or sw_if_index\n");
11500       return -99;
11501     }
11502
11503   /* Construct the API message */
11504   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11505   mp->sw_if_index = ntohl (sw_if_index);
11506   mp->enable_disable = enable_disable;
11507
11508   /* send it... */
11509   S;
11510   /* Wait for the reply */
11511   W;
11512 }
11513
11514 static int
11515 api_cop_whitelist_enable_disable (vat_main_t * vam)
11516 {
11517   unformat_input_t *line_input = vam->input;
11518   vl_api_cop_whitelist_enable_disable_t *mp;
11519   f64 timeout;
11520   u32 sw_if_index = ~0;
11521   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11522   u32 fib_id = 0;
11523
11524   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11525     {
11526       if (unformat (line_input, "ip4"))
11527         ip4 = 1;
11528       else if (unformat (line_input, "ip6"))
11529         ip6 = 1;
11530       else if (unformat (line_input, "default"))
11531         default_cop = 1;
11532       else if (unformat (line_input, "%U", unformat_sw_if_index,
11533                          vam, &sw_if_index))
11534         ;
11535       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11536         ;
11537       else if (unformat (line_input, "fib-id %d", &fib_id))
11538         ;
11539       else
11540         break;
11541     }
11542
11543   if (sw_if_index == ~0)
11544     {
11545       errmsg ("missing interface name or sw_if_index\n");
11546       return -99;
11547     }
11548
11549   /* Construct the API message */
11550   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11551   mp->sw_if_index = ntohl (sw_if_index);
11552   mp->fib_id = ntohl (fib_id);
11553   mp->ip4 = ip4;
11554   mp->ip6 = ip6;
11555   mp->default_cop = default_cop;
11556
11557   /* send it... */
11558   S;
11559   /* Wait for the reply */
11560   W;
11561 }
11562
11563 static int
11564 api_get_node_graph (vat_main_t * vam)
11565 {
11566   vl_api_get_node_graph_t *mp;
11567   f64 timeout;
11568
11569   M (GET_NODE_GRAPH, get_node_graph);
11570
11571   /* send it... */
11572   S;
11573   /* Wait for the reply */
11574   W;
11575 }
11576
11577 /* *INDENT-OFF* */
11578 /** Used for parsing LISP eids */
11579 typedef CLIB_PACKED(struct{
11580   u8 addr[16];   /**< eid address */
11581   u32 len;       /**< prefix length if IP */
11582   u8 type;      /**< type of eid */
11583 }) lisp_eid_vat_t;
11584 /* *INDENT-ON* */
11585
11586 static uword
11587 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11588 {
11589   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11590
11591   memset (a, 0, sizeof (a[0]));
11592
11593   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11594     {
11595       a->type = 0;              /* ipv4 type */
11596     }
11597   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11598     {
11599       a->type = 1;              /* ipv6 type */
11600     }
11601   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11602     {
11603       a->type = 2;              /* mac type */
11604     }
11605   else
11606     {
11607       return 0;
11608     }
11609
11610   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11611     {
11612       return 0;
11613     }
11614
11615   return 1;
11616 }
11617
11618 static int
11619 lisp_eid_size_vat (u8 type)
11620 {
11621   switch (type)
11622     {
11623     case 0:
11624       return 4;
11625     case 1:
11626       return 16;
11627     case 2:
11628       return 6;
11629     }
11630   return 0;
11631 }
11632
11633 static void
11634 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11635 {
11636   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11637 }
11638
11639 /* *INDENT-OFF* */
11640 /** Used for transferring locators via VPP API */
11641 typedef CLIB_PACKED(struct
11642 {
11643   u32 sw_if_index; /**< locator sw_if_index */
11644   u8 priority; /**< locator priority */
11645   u8 weight;   /**< locator weight */
11646 }) ls_locator_t;
11647 /* *INDENT-ON* */
11648
11649 static int
11650 api_lisp_add_del_locator_set (vat_main_t * vam)
11651 {
11652   unformat_input_t *input = vam->input;
11653   vl_api_lisp_add_del_locator_set_t *mp;
11654   f64 timeout = ~0;
11655   u8 is_add = 1;
11656   u8 *locator_set_name = NULL;
11657   u8 locator_set_name_set = 0;
11658   ls_locator_t locator, *locators = 0;
11659   u32 sw_if_index, priority, weight;
11660
11661   /* Parse args required to build the message */
11662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11663     {
11664       if (unformat (input, "del"))
11665         {
11666           is_add = 0;
11667         }
11668       else if (unformat (input, "locator-set %s", &locator_set_name))
11669         {
11670           locator_set_name_set = 1;
11671         }
11672       else if (unformat (input, "sw_if_index %u p %u w %u",
11673                          &sw_if_index, &priority, &weight))
11674         {
11675           locator.sw_if_index = htonl (sw_if_index);
11676           locator.priority = priority;
11677           locator.weight = weight;
11678           vec_add1 (locators, locator);
11679         }
11680       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11681                          vam, &sw_if_index, &priority, &weight))
11682         {
11683           locator.sw_if_index = htonl (sw_if_index);
11684           locator.priority = priority;
11685           locator.weight = weight;
11686           vec_add1 (locators, locator);
11687         }
11688       else
11689         break;
11690     }
11691
11692   if (locator_set_name_set == 0)
11693     {
11694       errmsg ("missing locator-set name");
11695       vec_free (locators);
11696       return -99;
11697     }
11698
11699   if (vec_len (locator_set_name) > 64)
11700     {
11701       errmsg ("locator-set name too long\n");
11702       vec_free (locator_set_name);
11703       vec_free (locators);
11704       return -99;
11705     }
11706   vec_add1 (locator_set_name, 0);
11707
11708   /* Construct the API message */
11709   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11710
11711   mp->is_add = is_add;
11712   clib_memcpy (mp->locator_set_name, locator_set_name,
11713                vec_len (locator_set_name));
11714   vec_free (locator_set_name);
11715
11716   mp->locator_num = vec_len (locators);
11717   if (locators)
11718     clib_memcpy (mp->locators, locators,
11719                  (sizeof (ls_locator_t) * vec_len (locators)));
11720   vec_free (locators);
11721
11722   /* send it... */
11723   S;
11724
11725   /* Wait for a reply... */
11726   W;
11727
11728   /* NOTREACHED */
11729   return 0;
11730 }
11731
11732 static int
11733 api_lisp_add_del_locator (vat_main_t * vam)
11734 {
11735   unformat_input_t *input = vam->input;
11736   vl_api_lisp_add_del_locator_t *mp;
11737   f64 timeout = ~0;
11738   u32 tmp_if_index = ~0;
11739   u32 sw_if_index = ~0;
11740   u8 sw_if_index_set = 0;
11741   u8 sw_if_index_if_name_set = 0;
11742   u32 priority = ~0;
11743   u8 priority_set = 0;
11744   u32 weight = ~0;
11745   u8 weight_set = 0;
11746   u8 is_add = 1;
11747   u8 *locator_set_name = NULL;
11748   u8 locator_set_name_set = 0;
11749
11750   /* Parse args required to build the message */
11751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11752     {
11753       if (unformat (input, "del"))
11754         {
11755           is_add = 0;
11756         }
11757       else if (unformat (input, "locator-set %s", &locator_set_name))
11758         {
11759           locator_set_name_set = 1;
11760         }
11761       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11762                          &tmp_if_index))
11763         {
11764           sw_if_index_if_name_set = 1;
11765           sw_if_index = tmp_if_index;
11766         }
11767       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11768         {
11769           sw_if_index_set = 1;
11770           sw_if_index = tmp_if_index;
11771         }
11772       else if (unformat (input, "p %d", &priority))
11773         {
11774           priority_set = 1;
11775         }
11776       else if (unformat (input, "w %d", &weight))
11777         {
11778           weight_set = 1;
11779         }
11780       else
11781         break;
11782     }
11783
11784   if (locator_set_name_set == 0)
11785     {
11786       errmsg ("missing locator-set name");
11787       return -99;
11788     }
11789
11790   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11791     {
11792       errmsg ("missing sw_if_index");
11793       vec_free (locator_set_name);
11794       return -99;
11795     }
11796
11797   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11798     {
11799       errmsg ("cannot use both params interface name and sw_if_index");
11800       vec_free (locator_set_name);
11801       return -99;
11802     }
11803
11804   if (priority_set == 0)
11805     {
11806       errmsg ("missing locator-set priority\n");
11807       vec_free (locator_set_name);
11808       return -99;
11809     }
11810
11811   if (weight_set == 0)
11812     {
11813       errmsg ("missing locator-set weight\n");
11814       vec_free (locator_set_name);
11815       return -99;
11816     }
11817
11818   if (vec_len (locator_set_name) > 64)
11819     {
11820       errmsg ("locator-set name too long\n");
11821       vec_free (locator_set_name);
11822       return -99;
11823     }
11824   vec_add1 (locator_set_name, 0);
11825
11826   /* Construct the API message */
11827   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11828
11829   mp->is_add = is_add;
11830   mp->sw_if_index = ntohl (sw_if_index);
11831   mp->priority = priority;
11832   mp->weight = weight;
11833   clib_memcpy (mp->locator_set_name, locator_set_name,
11834                vec_len (locator_set_name));
11835   vec_free (locator_set_name);
11836
11837   /* send it... */
11838   S;
11839
11840   /* Wait for a reply... */
11841   W;
11842
11843   /* NOTREACHED */
11844   return 0;
11845 }
11846
11847 static int
11848 api_lisp_add_del_local_eid (vat_main_t * vam)
11849 {
11850   unformat_input_t *input = vam->input;
11851   vl_api_lisp_add_del_local_eid_t *mp;
11852   f64 timeout = ~0;
11853   u8 is_add = 1;
11854   u8 eid_set = 0;
11855   lisp_eid_vat_t _eid, *eid = &_eid;
11856   u8 *locator_set_name = 0;
11857   u8 locator_set_name_set = 0;
11858   u32 vni = 0;
11859
11860   /* Parse args required to build the message */
11861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11862     {
11863       if (unformat (input, "del"))
11864         {
11865           is_add = 0;
11866         }
11867       else if (unformat (input, "vni %d", &vni))
11868         {
11869           ;
11870         }
11871       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11872         {
11873           eid_set = 1;
11874         }
11875       else if (unformat (input, "locator-set %s", &locator_set_name))
11876         {
11877           locator_set_name_set = 1;
11878         }
11879       else
11880         break;
11881     }
11882
11883   if (locator_set_name_set == 0)
11884     {
11885       errmsg ("missing locator-set name\n");
11886       return -99;
11887     }
11888
11889   if (0 == eid_set)
11890     {
11891       errmsg ("EID address not set!");
11892       vec_free (locator_set_name);
11893       return -99;
11894     }
11895
11896   if (vec_len (locator_set_name) > 64)
11897     {
11898       errmsg ("locator-set name too long\n");
11899       vec_free (locator_set_name);
11900       return -99;
11901     }
11902   vec_add1 (locator_set_name, 0);
11903
11904   /* Construct the API message */
11905   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11906
11907   mp->is_add = is_add;
11908   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11909   mp->eid_type = eid->type;
11910   mp->prefix_len = eid->len;
11911   mp->vni = clib_host_to_net_u32 (vni);
11912   clib_memcpy (mp->locator_set_name, locator_set_name,
11913                vec_len (locator_set_name));
11914
11915   vec_free (locator_set_name);
11916
11917   /* send it... */
11918   S;
11919
11920   /* Wait for a reply... */
11921   W;
11922
11923   /* NOTREACHED */
11924   return 0;
11925 }
11926
11927 /* *INDENT-OFF* */
11928 /** Used for transferring locators via VPP API */
11929 typedef CLIB_PACKED(struct
11930 {
11931   u8 is_ip4; /**< is locator an IPv4 address? */
11932   u8 priority; /**< locator priority */
11933   u8 weight;   /**< locator weight */
11934   u8 addr[16]; /**< IPv4/IPv6 address */
11935 }) rloc_t;
11936 /* *INDENT-ON* */
11937
11938 static int
11939 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11940 {
11941   unformat_input_t *input = vam->input;
11942   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11943   f64 timeout = ~0;
11944   u8 is_add = 1;
11945   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11946   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11947   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11948   u32 action = ~0, p, w;
11949   ip4_address_t rmt_rloc4, lcl_rloc4;
11950   ip6_address_t rmt_rloc6, lcl_rloc6;
11951   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11952
11953   memset (&rloc, 0, sizeof (rloc));
11954
11955   /* Parse args required to build the message */
11956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11957     {
11958       if (unformat (input, "del"))
11959         {
11960           is_add = 0;
11961         }
11962       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11963         {
11964           rmt_eid_set = 1;
11965         }
11966       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11967         {
11968           lcl_eid_set = 1;
11969         }
11970       else if (unformat (input, "p %d w %d", &p, &w))
11971         {
11972           if (!curr_rloc)
11973             {
11974               errmsg ("No RLOC configured for setting priority/weight!");
11975               return -99;
11976             }
11977           curr_rloc->priority = p;
11978           curr_rloc->weight = w;
11979         }
11980       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11981                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11982         {
11983           rloc.is_ip4 = 1;
11984
11985           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11986           rloc.priority = rloc.weight = 0;
11987           vec_add1 (lcl_locs, rloc);
11988
11989           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11990           vec_add1 (rmt_locs, rloc);
11991           /* priority and weight saved in rmt loc */
11992           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11993         }
11994       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11995                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11996         {
11997           rloc.is_ip4 = 0;
11998           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11999           rloc.priority = rloc.weight = 0;
12000           vec_add1 (lcl_locs, rloc);
12001
12002           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12003           vec_add1 (rmt_locs, rloc);
12004           /* priority and weight saved in rmt loc */
12005           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12006         }
12007       else if (unformat (input, "action %d", &action))
12008         {
12009           ;
12010         }
12011       else
12012         {
12013           clib_warning ("parse error '%U'", format_unformat_error, input);
12014           return -99;
12015         }
12016     }
12017
12018   if (!rmt_eid_set)
12019     {
12020       errmsg ("remote eid addresses not set\n");
12021       return -99;
12022     }
12023
12024   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12025     {
12026       errmsg ("eid types don't match\n");
12027       return -99;
12028     }
12029
12030   if (0 == rmt_locs && (u32) ~ 0 == action)
12031     {
12032       errmsg ("action not set for negative mapping\n");
12033       return -99;
12034     }
12035
12036   /* Construct the API message */
12037   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12038
12039   mp->is_add = is_add;
12040   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12041   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12042   mp->eid_type = rmt_eid->type;
12043   mp->rmt_len = rmt_eid->len;
12044   mp->lcl_len = lcl_eid->len;
12045   mp->action = action;
12046
12047   if (0 != rmt_locs && 0 != lcl_locs)
12048     {
12049       mp->loc_num = vec_len (rmt_locs);
12050       clib_memcpy (mp->lcl_locs, lcl_locs,
12051                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12052       clib_memcpy (mp->rmt_locs, rmt_locs,
12053                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12054     }
12055   vec_free (lcl_locs);
12056   vec_free (rmt_locs);
12057
12058   /* send it... */
12059   S;
12060
12061   /* Wait for a reply... */
12062   W;
12063
12064   /* NOTREACHED */
12065   return 0;
12066 }
12067
12068 static int
12069 api_lisp_add_del_map_resolver (vat_main_t * vam)
12070 {
12071   unformat_input_t *input = vam->input;
12072   vl_api_lisp_add_del_map_resolver_t *mp;
12073   f64 timeout = ~0;
12074   u8 is_add = 1;
12075   u8 ipv4_set = 0;
12076   u8 ipv6_set = 0;
12077   ip4_address_t ipv4;
12078   ip6_address_t ipv6;
12079
12080   /* Parse args required to build the message */
12081   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (input, "del"))
12084         {
12085           is_add = 0;
12086         }
12087       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12088         {
12089           ipv4_set = 1;
12090         }
12091       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12092         {
12093           ipv6_set = 1;
12094         }
12095       else
12096         break;
12097     }
12098
12099   if (ipv4_set && ipv6_set)
12100     {
12101       errmsg ("both eid v4 and v6 addresses set\n");
12102       return -99;
12103     }
12104
12105   if (!ipv4_set && !ipv6_set)
12106     {
12107       errmsg ("eid addresses not set\n");
12108       return -99;
12109     }
12110
12111   /* Construct the API message */
12112   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12113
12114   mp->is_add = is_add;
12115   if (ipv6_set)
12116     {
12117       mp->is_ipv6 = 1;
12118       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12119     }
12120   else
12121     {
12122       mp->is_ipv6 = 0;
12123       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12124     }
12125
12126   /* send it... */
12127   S;
12128
12129   /* Wait for a reply... */
12130   W;
12131
12132   /* NOTREACHED */
12133   return 0;
12134 }
12135
12136 static int
12137 api_lisp_gpe_enable_disable (vat_main_t * vam)
12138 {
12139   unformat_input_t *input = vam->input;
12140   vl_api_lisp_gpe_enable_disable_t *mp;
12141   f64 timeout = ~0;
12142   u8 is_set = 0;
12143   u8 is_en = 1;
12144
12145   /* Parse args required to build the message */
12146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12147     {
12148       if (unformat (input, "enable"))
12149         {
12150           is_set = 1;
12151           is_en = 1;
12152         }
12153       else if (unformat (input, "disable"))
12154         {
12155           is_set = 1;
12156           is_en = 0;
12157         }
12158       else
12159         break;
12160     }
12161
12162   if (is_set == 0)
12163     {
12164       errmsg ("Value not set\n");
12165       return -99;
12166     }
12167
12168   /* Construct the API message */
12169   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12170
12171   mp->is_en = is_en;
12172
12173   /* send it... */
12174   S;
12175
12176   /* Wait for a reply... */
12177   W;
12178
12179   /* NOTREACHED */
12180   return 0;
12181 }
12182
12183 static int
12184 api_lisp_enable_disable (vat_main_t * vam)
12185 {
12186   unformat_input_t *input = vam->input;
12187   vl_api_lisp_enable_disable_t *mp;
12188   f64 timeout = ~0;
12189   u8 is_set = 0;
12190   u8 is_en = 0;
12191
12192   /* Parse args required to build the message */
12193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12194     {
12195       if (unformat (input, "enable"))
12196         {
12197           is_set = 1;
12198           is_en = 1;
12199         }
12200       else if (unformat (input, "disable"))
12201         {
12202           is_set = 1;
12203         }
12204       else
12205         break;
12206     }
12207
12208   if (!is_set)
12209     {
12210       errmsg ("Value not set\n");
12211       return -99;
12212     }
12213
12214   /* Construct the API message */
12215   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12216
12217   mp->is_en = is_en;
12218
12219   /* send it... */
12220   S;
12221
12222   /* Wait for a reply... */
12223   W;
12224
12225   /* NOTREACHED */
12226   return 0;
12227 }
12228
12229 /**
12230  * Enable/disable LISP proxy ITR.
12231  *
12232  * @param vam vpp API test context
12233  * @return return code
12234  */
12235 static int
12236 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12237 {
12238   f64 timeout = ~0;
12239   u8 ls_name_set = 0;
12240   unformat_input_t *input = vam->input;
12241   vl_api_lisp_pitr_set_locator_set_t *mp;
12242   u8 is_add = 1;
12243   u8 *ls_name = 0;
12244
12245   /* Parse args required to build the message */
12246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (input, "del"))
12249         is_add = 0;
12250       else if (unformat (input, "locator-set %s", &ls_name))
12251         ls_name_set = 1;
12252       else
12253         {
12254           errmsg ("parse error '%U'", format_unformat_error, input);
12255           return -99;
12256         }
12257     }
12258
12259   if (!ls_name_set)
12260     {
12261       errmsg ("locator-set name not set!");
12262       return -99;
12263     }
12264
12265   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12266
12267   mp->is_add = is_add;
12268   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12269   vec_free (ls_name);
12270
12271   /* send */
12272   S;
12273
12274   /* wait for reply */
12275   W;
12276
12277   /* notreached */
12278   return 0;
12279 }
12280
12281 static int
12282 api_show_lisp_pitr (vat_main_t * vam)
12283 {
12284   vl_api_show_lisp_pitr_t *mp;
12285   f64 timeout = ~0;
12286
12287   if (!vam->json_output)
12288     {
12289       fformat (vam->ofp, "%=20s\n", "lisp status:");
12290     }
12291
12292   M (SHOW_LISP_PITR, show_lisp_pitr);
12293   /* send it... */
12294   S;
12295
12296   /* Wait for a reply... */
12297   W;
12298
12299   /* NOTREACHED */
12300   return 0;
12301 }
12302
12303 /**
12304  * Add/delete mapping between vni and vrf
12305  */
12306 static int
12307 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12308 {
12309   f64 timeout = ~0;
12310   unformat_input_t *input = vam->input;
12311   vl_api_lisp_eid_table_add_del_map_t *mp;
12312   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12313   u32 vni, vrf, bd_index;
12314
12315   /* Parse args required to build the message */
12316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12317     {
12318       if (unformat (input, "del"))
12319         is_add = 0;
12320       else if (unformat (input, "vrf %d", &vrf))
12321         vrf_set = 1;
12322       else if (unformat (input, "bd_index %d", &bd_index))
12323         bd_index_set = 1;
12324       else if (unformat (input, "vni %d", &vni))
12325         vni_set = 1;
12326       else
12327         break;
12328     }
12329
12330   if (!vni_set || (!vrf_set && !bd_index_set))
12331     {
12332       errmsg ("missing arguments!");
12333       return -99;
12334     }
12335
12336   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12337
12338   mp->is_add = is_add;
12339   mp->vni = htonl (vni);
12340   mp->dp_table = htonl (vrf);
12341   mp->is_l2 = bd_index_set;
12342
12343   /* send */
12344   S;
12345
12346   /* wait for reply */
12347   W;
12348
12349   /* notreached */
12350   return 0;
12351 }
12352
12353 /**
12354  * Add/del remote mapping to/from LISP control plane
12355  *
12356  * @param vam vpp API test context
12357  * @return return code
12358  */
12359 static int
12360 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12361 {
12362   unformat_input_t *input = vam->input;
12363   vl_api_lisp_add_del_remote_mapping_t *mp;
12364   f64 timeout = ~0;
12365   u32 vni = 0;
12366   //TODO: seid need remove
12367   lisp_eid_vat_t _eid, *eid = &_eid;
12368   lisp_eid_vat_t _seid, *seid = &_seid;
12369   u8 is_add = 1, del_all = 0, eid_set = 0;
12370   u32 action = ~0, p, w;
12371   ip4_address_t rloc4;
12372   ip6_address_t rloc6;
12373   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12374
12375   memset (&rloc, 0, sizeof (rloc));
12376
12377   /* Parse args required to build the message */
12378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12379     {
12380       if (unformat (input, "del-all"))
12381         {
12382           del_all = 1;
12383         }
12384       else if (unformat (input, "del"))
12385         {
12386           is_add = 0;
12387         }
12388       else if (unformat (input, "add"))
12389         {
12390           is_add = 1;
12391         }
12392       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12393         {
12394           eid_set = 1;
12395         }
12396       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12397         {
12398           //TODO: Need remove, but first must be remove from CSIT test
12399         }
12400       else if (unformat (input, "vni %d", &vni))
12401         {
12402           ;
12403         }
12404       else if (unformat (input, "p %d w %d", &p, &w))
12405         {
12406           if (!curr_rloc)
12407             {
12408               errmsg ("No RLOC configured for setting priority/weight!");
12409               return -99;
12410             }
12411           curr_rloc->priority = p;
12412           curr_rloc->weight = w;
12413         }
12414       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12415         {
12416           rloc.is_ip4 = 1;
12417           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12418           vec_add1 (rlocs, rloc);
12419           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12420         }
12421       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12422         {
12423           rloc.is_ip4 = 0;
12424           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12425           vec_add1 (rlocs, rloc);
12426           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12427         }
12428       else if (unformat (input, "action %d", &action))
12429         {
12430           ;
12431         }
12432       else
12433         {
12434           clib_warning ("parse error '%U'", format_unformat_error, input);
12435           return -99;
12436         }
12437     }
12438
12439   if (0 == eid_set)
12440     {
12441       errmsg ("missing params!");
12442       return -99;
12443     }
12444
12445   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12446     {
12447       errmsg ("no action set for negative map-reply!");
12448       return -99;
12449     }
12450
12451   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12452   mp->is_add = is_add;
12453   mp->vni = htonl (vni);
12454   mp->action = (u8) action;
12455   mp->eid_len = eid->len;
12456   mp->del_all = del_all;
12457   mp->eid_type = eid->type;
12458   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12459
12460   mp->rloc_num = vec_len (rlocs);
12461   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12462   vec_free (rlocs);
12463
12464   /* send it... */
12465   S;
12466
12467   /* Wait for a reply... */
12468   W;
12469
12470   /* NOTREACHED */
12471   return 0;
12472 }
12473
12474 /**
12475  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12476  * forwarding entries in data-plane accordingly.
12477  *
12478  * @param vam vpp API test context
12479  * @return return code
12480  */
12481 static int
12482 api_lisp_add_del_adjacency (vat_main_t * vam)
12483 {
12484   unformat_input_t *input = vam->input;
12485   vl_api_lisp_add_del_adjacency_t *mp;
12486   f64 timeout = ~0;
12487   u32 vni = 0;
12488   ip4_address_t seid4, deid4;
12489   ip6_address_t seid6, deid6;
12490   u8 deid_mac[6] = { 0 };
12491   u8 seid_mac[6] = { 0 };
12492   u8 deid_type, seid_type;
12493   u32 seid_len = 0, deid_len = 0, len;
12494   u8 is_add = 1;
12495
12496   seid_type = deid_type = (u8) ~ 0;
12497
12498   /* Parse args required to build the message */
12499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12500     {
12501       if (unformat (input, "del"))
12502         {
12503           is_add = 0;
12504         }
12505       else if (unformat (input, "add"))
12506         {
12507           is_add = 1;
12508         }
12509       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12510                          &deid4, &len))
12511         {
12512           deid_type = 0;        /* ipv4 */
12513           deid_len = len;
12514         }
12515       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12516                          &deid6, &len))
12517         {
12518           deid_type = 1;        /* ipv6 */
12519           deid_len = len;
12520         }
12521       else if (unformat (input, "deid %U", unformat_ethernet_address,
12522                          deid_mac))
12523         {
12524           deid_type = 2;        /* mac */
12525         }
12526       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12527                          &seid4, &len))
12528         {
12529           seid_type = 0;        /* ipv4 */
12530           seid_len = len;
12531         }
12532       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12533                          &seid6, &len))
12534         {
12535           seid_type = 1;        /* ipv6 */
12536           seid_len = len;
12537         }
12538       else if (unformat (input, "seid %U", unformat_ethernet_address,
12539                          seid_mac))
12540         {
12541           seid_type = 2;        /* mac */
12542         }
12543       else if (unformat (input, "vni %d", &vni))
12544         {
12545           ;
12546         }
12547       else
12548         {
12549           errmsg ("parse error '%U'", format_unformat_error, input);
12550           return -99;
12551         }
12552     }
12553
12554   if ((u8) ~ 0 == deid_type)
12555     {
12556       errmsg ("missing params!");
12557       return -99;
12558     }
12559
12560   if (seid_type != deid_type)
12561     {
12562       errmsg ("source and destination EIDs are of different types!");
12563       return -99;
12564     }
12565
12566   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12567   mp->is_add = is_add;
12568   mp->vni = htonl (vni);
12569   mp->seid_len = seid_len;
12570   mp->deid_len = deid_len;
12571   mp->eid_type = deid_type;
12572
12573   switch (mp->eid_type)
12574     {
12575     case 0:
12576       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12577       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12578       break;
12579     case 1:
12580       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12581       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12582       break;
12583     case 2:
12584       clib_memcpy (mp->seid, seid_mac, 6);
12585       clib_memcpy (mp->deid, deid_mac, 6);
12586       break;
12587     default:
12588       errmsg ("unknown EID type %d!", mp->eid_type);
12589       return 0;
12590     }
12591
12592   /* send it... */
12593   S;
12594
12595   /* Wait for a reply... */
12596   W;
12597
12598   /* NOTREACHED */
12599   return 0;
12600 }
12601
12602 static int
12603 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12604 {
12605   unformat_input_t *input = vam->input;
12606   vl_api_lisp_gpe_add_del_iface_t *mp;
12607   f64 timeout = ~0;
12608   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12609   u32 dp_table = 0, vni = 0;
12610
12611   /* Parse args required to build the message */
12612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12613     {
12614       if (unformat (input, "up"))
12615         {
12616           action_set = 1;
12617           is_add = 1;
12618         }
12619       else if (unformat (input, "down"))
12620         {
12621           action_set = 1;
12622           is_add = 0;
12623         }
12624       else if (unformat (input, "table_id %d", &dp_table))
12625         {
12626           dp_table_set = 1;
12627         }
12628       else if (unformat (input, "bd_id %d", &dp_table))
12629         {
12630           dp_table_set = 1;
12631           is_l2 = 1;
12632         }
12633       else if (unformat (input, "vni %d", &vni))
12634         {
12635           vni_set = 1;
12636         }
12637       else
12638         break;
12639     }
12640
12641   if (action_set == 0)
12642     {
12643       errmsg ("Action not set\n");
12644       return -99;
12645     }
12646   if (dp_table_set == 0 || vni_set == 0)
12647     {
12648       errmsg ("vni and dp_table must be set\n");
12649       return -99;
12650     }
12651
12652   /* Construct the API message */
12653   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12654
12655   mp->is_add = is_add;
12656   mp->dp_table = dp_table;
12657   mp->is_l2 = is_l2;
12658   mp->vni = vni;
12659
12660   /* send it... */
12661   S;
12662
12663   /* Wait for a reply... */
12664   W;
12665
12666   /* NOTREACHED */
12667   return 0;
12668 }
12669
12670 /**
12671  * Add/del map request itr rlocs from LISP control plane and updates
12672  *
12673  * @param vam vpp API test context
12674  * @return return code
12675  */
12676 static int
12677 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12678 {
12679   unformat_input_t *input = vam->input;
12680   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12681   f64 timeout = ~0;
12682   u8 *locator_set_name = 0;
12683   u8 locator_set_name_set = 0;
12684   u8 is_add = 1;
12685
12686   /* Parse args required to build the message */
12687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12688     {
12689       if (unformat (input, "del"))
12690         {
12691           is_add = 0;
12692         }
12693       else if (unformat (input, "%_%v%_", &locator_set_name))
12694         {
12695           locator_set_name_set = 1;
12696         }
12697       else
12698         {
12699           clib_warning ("parse error '%U'", format_unformat_error, input);
12700           return -99;
12701         }
12702     }
12703
12704   if (is_add && !locator_set_name_set)
12705     {
12706       errmsg ("itr-rloc is not set!");
12707       return -99;
12708     }
12709
12710   if (is_add && vec_len (locator_set_name) > 64)
12711     {
12712       errmsg ("itr-rloc locator-set name too long\n");
12713       vec_free (locator_set_name);
12714       return -99;
12715     }
12716
12717   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12718   mp->is_add = is_add;
12719   if (is_add)
12720     {
12721       clib_memcpy (mp->locator_set_name, locator_set_name,
12722                    vec_len (locator_set_name));
12723     }
12724   else
12725     {
12726       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12727     }
12728   vec_free (locator_set_name);
12729
12730   /* send it... */
12731   S;
12732
12733   /* Wait for a reply... */
12734   W;
12735
12736   /* NOTREACHED */
12737   return 0;
12738 }
12739
12740 static int
12741 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12742                             u8 filter)
12743 {
12744   vl_api_lisp_locator_dump_t *mp;
12745   f64 timeout = ~0;
12746
12747   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12748
12749   mp->locator_set_index = htonl (locator_set_index);
12750   mp->filter = filter;
12751
12752   /* send it... */
12753   S;
12754
12755   /* Use a control ping for synchronization */
12756   {
12757     vl_api_noprint_control_ping_t *mp;
12758     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12759     S;
12760   }
12761   /* Wait for a reply... */
12762   W;
12763 }
12764
12765 static inline void
12766 clean_locator_set_message (vat_main_t * vam)
12767 {
12768   locator_set_msg_t *ls = 0;
12769
12770   vec_foreach (ls, vam->locator_set_msg)
12771   {
12772     vec_free (ls->locator_set_name);
12773   }
12774
12775   vec_free (vam->locator_set_msg);
12776 }
12777
12778 static int
12779 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12780 {
12781   locator_set_msg_t *ls;
12782   locator_msg_t *loc;
12783   u8 *tmp_str = 0;
12784   int i = 0, ret = 0;
12785
12786   vec_foreach (ls, vam->locator_set_msg)
12787   {
12788     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12789     if (ret)
12790       {
12791         vec_free (vam->locator_msg);
12792         clean_locator_set_message (vam);
12793         return ret;
12794       }
12795
12796     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12797                       ls->locator_set_index,
12798                       vec_len (vam->locator_msg) ? "" : "\n");
12799     i = 0;
12800     vec_foreach (loc, vam->locator_msg)
12801     {
12802       if (i)
12803         {
12804           tmp_str = format (tmp_str, "%=37s", " ");
12805         }
12806       if (loc->local)
12807         {
12808           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12809                             loc->sw_if_index, loc->priority, loc->weight);
12810         }
12811       else
12812         {
12813           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12814                             loc->is_ipv6 ? format_ip6_address :
12815                             format_ip4_address,
12816                             loc->ip_address, loc->priority, loc->weight);
12817         }
12818       i++;
12819     }
12820
12821     fformat (vam->ofp, "%s", tmp_str);
12822     vec_free (tmp_str);
12823     vec_free (vam->locator_msg);
12824   }
12825
12826   clean_locator_set_message (vam);
12827
12828   return ret;
12829 }
12830
12831 static int
12832 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12833 {
12834   locator_set_msg_t *ls;
12835   locator_msg_t *loc;
12836   vat_json_node_t *node = NULL;
12837   vat_json_node_t *locator_array;
12838   vat_json_node_t *locator;
12839   struct in6_addr ip6;
12840   struct in_addr ip4;
12841   int ret = 0;
12842
12843   if (!vec_len (vam->locator_set_msg))
12844     {
12845       /* just print [] */
12846       vat_json_init_array (&vam->json_tree);
12847       vat_json_print (vam->ofp, &vam->json_tree);
12848       vam->json_tree.type = VAT_JSON_NONE;
12849       return ret;
12850     }
12851
12852   if (VAT_JSON_ARRAY != vam->json_tree.type)
12853     {
12854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12855       vat_json_init_array (&vam->json_tree);
12856     }
12857
12858   vec_foreach (ls, vam->locator_set_msg)
12859   {
12860     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12861     if (ret)
12862       {
12863         vec_free (ls->locator_set_name);
12864         vec_free (vam->locator_msg);
12865         vec_free (vam->locator_set_msg);
12866         vat_json_free (&vam->json_tree);
12867         vam->json_tree.type = VAT_JSON_NONE;
12868         return ret;
12869       }
12870
12871     node = vat_json_array_add (&vam->json_tree);
12872     vat_json_init_object (node);
12873
12874     vat_json_object_add_uint (node, "locator-set-index",
12875                               ls->locator_set_index);
12876     vat_json_object_add_string_copy (node, "locator-set",
12877                                      ls->locator_set_name);
12878     locator_array = vat_json_object_add_list (node, "locator");
12879     vec_foreach (loc, vam->locator_msg)
12880     {
12881       locator = vat_json_array_add (locator_array);
12882       vat_json_init_object (locator);
12883       if (loc->local)
12884         {
12885           vat_json_object_add_uint (locator, "locator-index",
12886                                     loc->sw_if_index);
12887         }
12888       else
12889         {
12890           if (loc->is_ipv6)
12891             {
12892               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12893               vat_json_object_add_ip6 (locator, "locator", ip6);
12894             }
12895           else
12896             {
12897               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12898               vat_json_object_add_ip4 (locator, "locator", ip4);
12899             }
12900         }
12901       vat_json_object_add_uint (locator, "priority", loc->priority);
12902       vat_json_object_add_uint (locator, "weight", loc->weight);
12903     }
12904
12905     vec_free (ls->locator_set_name);
12906     vec_free (vam->locator_msg);
12907   }
12908
12909   vat_json_print (vam->ofp, &vam->json_tree);
12910   vat_json_free (&vam->json_tree);
12911   vam->json_tree.type = VAT_JSON_NONE;
12912
12913   vec_free (vam->locator_set_msg);
12914
12915   return ret;
12916 }
12917
12918 static int
12919 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12920                                 u32 * locator_set_index)
12921 {
12922   locator_set_msg_t *ls;
12923   int ret = 0;
12924
12925   *locator_set_index = ~0;
12926
12927   if (!vec_len (vam->locator_set_msg))
12928     {
12929       return ret;
12930     }
12931
12932   vec_foreach (ls, vam->locator_set_msg)
12933   {
12934     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12935       {
12936         *locator_set_index = ls->locator_set_index;
12937         vec_free (vam->locator_set_msg);
12938         return ret;
12939       }
12940   }
12941
12942   vec_free (vam->locator_set_msg);
12943
12944   return ret;
12945 }
12946
12947 static int
12948 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12949                        u32 * locator_set_index)
12950 {
12951   vl_api_lisp_locator_set_dump_t *mp;
12952   f64 timeout = ~0;
12953
12954   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12955   /* send it... */
12956   S;
12957
12958   /* Use a control ping for synchronization */
12959   {
12960     vl_api_noprint_control_ping_t *mp;
12961     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12962     S;
12963   }
12964
12965   vam->noprint_msg = 1;
12966   /* Wait for a reply... */
12967   /* *INDENT-OFF* */
12968   W_L
12969   ({
12970     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12971     vam->noprint_msg = 0;
12972   });
12973   /* *INDENT-ON* */
12974
12975   /* NOTREACHED */
12976   return 0;
12977 }
12978
12979 static inline int
12980 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12981                    u8 filter)
12982 {
12983   int ret = 0;
12984
12985   ASSERT (vam);
12986
12987   if (!vam->json_output)
12988     {
12989       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12990                "locator", "priority", "weight");
12991     }
12992
12993   if (locator_set)
12994     {
12995       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
12996     }
12997
12998   if (!ret && ~0 == locator_set_index)
12999     {
13000       return -99;
13001     }
13002
13003   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13004
13005   return ret;
13006 }
13007
13008 static int
13009 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13010 {
13011   vl_api_lisp_locator_set_dump_t *mp;
13012   f64 timeout = ~0;
13013
13014   if (!vam->json_output)
13015     {
13016       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13017                "locator-set", "locator-set-index", "locator", "priority",
13018                "weight");
13019     }
13020
13021   vam->noprint_msg = 1;
13022
13023   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13024
13025   mp->filter = filter;
13026
13027   /* send it... */
13028   S;
13029
13030   /* Use a control ping for synchronization */
13031   {
13032     vl_api_noprint_control_ping_t *mp;
13033     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13034     S;
13035   }
13036
13037   /* Wait for a reply... */
13038   /* *INDENT-OFF* */
13039   W_L
13040   ({
13041     if (vam->noprint_msg)
13042       {
13043         if (!vam->json_output)
13044           {
13045             print_locator_in_locator_set(vam, filter);
13046           }
13047         else
13048           {
13049             json_locator_in_locator_set(vam, filter);
13050           }
13051       }
13052     vam->noprint_msg = 0;
13053   });
13054   /* *INDENT-ON* */
13055
13056   /* NOTREACHED */
13057   return 0;
13058 }
13059
13060 static int
13061 api_lisp_locator_set_dump (vat_main_t * vam)
13062 {
13063   unformat_input_t *input = vam->input;
13064   vam->noprint_msg = 0;
13065   u32 locator_set_index = ~0;
13066   u8 locator_set_index_set = 0;
13067   u8 *locator_set = 0;
13068   u8 locator_set_set = 0;
13069   u8 filter = 0;
13070   int ret = 0;
13071
13072   /* Parse args required to build the message */
13073   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13074     {
13075       if (unformat (input, "locator-set-index %u", &locator_set_index))
13076         {
13077           locator_set_index_set = 1;
13078         }
13079       else if (unformat (input, "locator-set %s", &locator_set))
13080         {
13081           locator_set_set = 1;
13082         }
13083       else if (unformat (input, "local"))
13084         {
13085           filter = 1;
13086         }
13087       else if (unformat (input, "remote"))
13088         {
13089           filter = 2;
13090         }
13091       else
13092         {
13093           break;
13094         }
13095     }
13096
13097   if (locator_set_index_set && locator_set_set)
13098     {
13099       errmsg ("use only input parameter!\n");
13100       return -99;
13101     }
13102
13103   if (locator_set_index_set || locator_set_set)
13104     {
13105       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13106     }
13107   else
13108     {
13109       ret = lisp_locator_set_dump (vam, filter);
13110     }
13111
13112   vec_free (locator_set);
13113
13114   return ret;
13115 }
13116
13117 static int
13118 api_lisp_eid_table_map_dump (vat_main_t * vam)
13119 {
13120   vl_api_lisp_eid_table_map_dump_t *mp;
13121   f64 timeout = ~0;
13122
13123   if (!vam->json_output)
13124     {
13125       fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
13126     }
13127
13128   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13129
13130   /* send it... */
13131   S;
13132
13133   /* Use a control ping for synchronization */
13134   {
13135     vl_api_control_ping_t *mp;
13136     M (CONTROL_PING, control_ping);
13137     S;
13138   }
13139   /* Wait for a reply... */
13140   W;
13141
13142   /* NOTREACHED */
13143   return 0;
13144 }
13145
13146 static int
13147 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13148 {
13149   vl_api_lisp_eid_table_vni_dump_t *mp;
13150   f64 timeout = ~0;
13151
13152   if (!vam->json_output)
13153     {
13154       fformat (vam->ofp, "VNI\n");
13155     }
13156
13157   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13158
13159   /* send it... */
13160   S;
13161
13162   /* Use a control ping for synchronization */
13163   {
13164     vl_api_control_ping_t *mp;
13165     M (CONTROL_PING, control_ping);
13166     S;
13167   }
13168   /* Wait for a reply... */
13169   W;
13170
13171   /* NOTREACHED */
13172   return 0;
13173 }
13174
13175 static int
13176 get_locator_set (vat_main_t * vam)
13177 {
13178   vl_api_lisp_locator_set_dump_t *mp;
13179   f64 timeout = ~0;
13180
13181   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13182   /* send it... */
13183   S;
13184
13185   /* Use a control ping for synchronization */
13186   {
13187     vl_api_noprint_control_ping_t *mp;
13188     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13189     S;
13190   }
13191
13192   /* Wait for a reply... */
13193   W;
13194
13195   /* NOTREACHED */
13196   return 0;
13197 }
13198
13199 static inline u8 *
13200 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13201                           int *ret)
13202 {
13203   u8 *(*format_eid) (u8 *, va_list *) = 0;
13204
13205   ASSERT (vam != NULL);
13206   ASSERT (eid_table != NULL);
13207
13208   if (ret)
13209     {
13210       *ret = 0;
13211     }
13212
13213   switch (eid_table->eid_type)
13214     {
13215     case 0:
13216     case 1:
13217       format_eid = (eid_table->eid_type ? format_ip6_address :
13218                     format_ip4_address);
13219       str = format (0, "[%d] %U/%d",
13220                     clib_net_to_host_u32 (eid_table->vni),
13221                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13222       break;
13223     case 2:
13224       str = format (0, "[%d] %U",
13225                     clib_net_to_host_u32 (eid_table->vni),
13226                     format_ethernet_address, eid_table->eid);
13227       break;
13228     default:
13229       errmsg ("unknown EID type %d!", eid_table->eid_type);
13230       if (ret)
13231         {
13232           *ret = -99;
13233         }
13234       return 0;
13235     }
13236
13237   return str;
13238 }
13239
13240 static inline u8 *
13241 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13242                                   eid_table_t * eid_table)
13243 {
13244   locator_set_msg_t *ls = 0;
13245
13246   ASSERT (vam != NULL);
13247   ASSERT (eid_table != NULL);
13248
13249   if (eid_table->is_local)
13250     {
13251       vec_foreach (ls, vam->locator_set_msg)
13252       {
13253         if (ls->locator_set_index == eid_table->locator_set_index)
13254           {
13255             str = format (0, "local(%s)", ls->locator_set_name);
13256             return str;
13257           }
13258       }
13259
13260       str = format (0, "local(N/A)");
13261     }
13262   else
13263     {
13264       str = format (0, "remote");
13265     }
13266
13267   return str;
13268 }
13269
13270 static inline u8 *
13271 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13272                               eid_table_t * eid_table)
13273 {
13274   locator_msg_t *loc = 0;
13275   int first_line = 1;
13276
13277   ASSERT (vam != NULL);
13278   ASSERT (eid_table != NULL);
13279
13280   vec_foreach (loc, vam->locator_msg)
13281   {
13282     if (!first_line)
13283       {
13284         if (loc->local)
13285           {
13286             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13287           }
13288         else
13289           {
13290             str = format (str, "%=55s%-U\n", " ",
13291                           loc->is_ipv6 ? format_ip6_address :
13292                           format_ip4_address, loc->ip_address);
13293           }
13294
13295         continue;
13296       }
13297
13298     if (loc->local)
13299       {
13300         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13301                       eid_table->ttl, eid_table->authoritative);
13302       }
13303     else
13304       {
13305         str = format (str, "%-30U%-20u%-u\n",
13306                       loc->is_ipv6 ? format_ip6_address :
13307                       format_ip4_address,
13308                       loc->ip_address, eid_table->ttl,
13309                       eid_table->authoritative);
13310       }
13311     first_line = 0;
13312   }
13313
13314   return str;
13315 }
13316
13317 static int
13318 print_lisp_eid_table_dump (vat_main_t * vam)
13319 {
13320   eid_table_t *eid_table = 0;
13321   u8 *tmp_str = 0, *tmp_str2 = 0;
13322   int ret = 0;
13323
13324   ASSERT (vam != NULL);
13325
13326   ret = get_locator_set (vam);
13327   if (ret)
13328     {
13329       vec_free (vam->eid_tables);
13330       return ret;
13331     }
13332
13333   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13334            "ttl", "authoritative");
13335
13336   vec_foreach (eid_table, vam->eid_tables)
13337   {
13338     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13339     if (ret)
13340       {
13341         vec_free (vam->locator_msg);
13342         clean_locator_set_message (vam);
13343         vec_free (vam->eid_tables);
13344         return ret;
13345       }
13346
13347     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13348     if (ret)
13349       {
13350         vec_free (vam->locator_msg);
13351         clean_locator_set_message (vam);
13352         vec_free (vam->eid_tables);
13353         return ret;
13354       }
13355
13356     tmp_str = format (0, "%-35s", tmp_str2);
13357     vec_free (tmp_str2);
13358
13359     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13360     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13361     vec_free (tmp_str2);
13362
13363     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13364     tmp_str = format (tmp_str, "%-s", tmp_str2);
13365     vec_free (tmp_str2);
13366
13367     fformat (vam->ofp, "%s", tmp_str);
13368     vec_free (tmp_str);
13369     vec_free (vam->locator_msg);
13370   }
13371
13372   clean_locator_set_message (vam);
13373   vec_free (vam->eid_tables);
13374
13375   return ret;
13376 }
13377
13378 static inline void
13379 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13380                                 eid_table_t * eid_table)
13381 {
13382   locator_set_msg_t *ls = 0;
13383   u8 *s = 0;
13384
13385   ASSERT (vam != NULL);
13386   ASSERT (node != NULL);
13387   ASSERT (eid_table != NULL);
13388
13389   if (eid_table->is_local)
13390     {
13391       vec_foreach (ls, vam->locator_set_msg)
13392       {
13393         if (ls->locator_set_index == eid_table->locator_set_index)
13394           {
13395             vat_json_object_add_string_copy (node, "locator-set",
13396                                              ls->locator_set_name);
13397             return;
13398           }
13399       }
13400
13401       s = format (0, "N/A");
13402       vec_add1 (s, 0);
13403       vat_json_object_add_string_copy (node, "locator-set", s);
13404       vec_free (s);
13405     }
13406   else
13407     {
13408       s = format (0, "remote");
13409       vec_add1 (s, 0);
13410       vat_json_object_add_string_copy (node, "locator-set", s);
13411       vec_free (s);
13412     }
13413 }
13414
13415 static inline int
13416 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13417                         eid_table_t * eid_table)
13418 {
13419   u8 *s = 0;
13420   struct in6_addr ip6;
13421   struct in_addr ip4;
13422
13423   ASSERT (vam != NULL);
13424   ASSERT (node != NULL);
13425   ASSERT (eid_table != NULL);
13426
13427   switch (eid_table->eid_type)
13428     {
13429     case 0:
13430       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13431       vat_json_object_add_ip4 (node, "eid", ip4);
13432       vat_json_object_add_uint (node, "eid-prefix-len",
13433                                 eid_table->eid_prefix_len);
13434       break;
13435     case 1:
13436       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13437       vat_json_object_add_ip6 (node, "eid", ip6);
13438       vat_json_object_add_uint (node, "eid-prefix-len",
13439                                 eid_table->eid_prefix_len);
13440       break;
13441     case 2:
13442       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13443       vec_add1 (s, 0);
13444       vat_json_object_add_string_copy (node, "eid", s);
13445       vec_free (s);
13446       break;
13447     default:
13448       errmsg ("unknown EID type %d!", eid_table->eid_type);
13449       return -99;
13450     }
13451
13452   return 0;
13453 }
13454
13455 static inline void
13456 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13457                             eid_table_t * eid_table)
13458 {
13459   locator_msg_t *loc = 0;
13460   vat_json_node_t *locator_array = 0;
13461   vat_json_node_t *locator = 0;
13462   struct in6_addr ip6;
13463   struct in_addr ip4;
13464
13465   ASSERT (vam != NULL);
13466   ASSERT (node != NULL);
13467   ASSERT (eid_table != NULL);
13468
13469   locator_array = vat_json_object_add_list (node, "locator");
13470   vec_foreach (loc, vam->locator_msg)
13471   {
13472     locator = vat_json_array_add (locator_array);
13473     vat_json_init_object (locator);
13474     if (loc->local)
13475       {
13476         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13477       }
13478     else
13479       {
13480         if (loc->is_ipv6)
13481           {
13482             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13483             vat_json_object_add_ip6 (locator, "locator", ip6);
13484           }
13485         else
13486           {
13487             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13488             vat_json_object_add_ip4 (locator, "locator", ip4);
13489           }
13490       }
13491   }
13492 }
13493
13494 static int
13495 json_lisp_eid_table_dump (vat_main_t * vam)
13496 {
13497   eid_table_t *eid_table;
13498   vat_json_node_t *node = 0;
13499   int ret = 0;
13500
13501   ASSERT (vam != NULL);
13502
13503   ret = get_locator_set (vam);
13504   if (ret)
13505     {
13506       vec_free (vam->eid_tables);
13507       return ret;
13508     }
13509
13510   if (!vec_len (vam->eid_tables))
13511     {
13512       /* just print [] */
13513       vat_json_init_array (&vam->json_tree);
13514       vat_json_print (vam->ofp, &vam->json_tree);
13515       vam->json_tree.type = VAT_JSON_NONE;
13516       return ret;
13517     }
13518
13519   if (VAT_JSON_ARRAY != vam->json_tree.type)
13520     {
13521       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13522       vat_json_init_array (&vam->json_tree);
13523     }
13524
13525   vec_foreach (eid_table, vam->eid_tables)
13526   {
13527     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13528     if (ret)
13529       {
13530         vec_free (vam->locator_msg);
13531         vec_free (vam->eid_tables);
13532         clean_locator_set_message (vam);
13533         vat_json_free (&vam->json_tree);
13534         vam->json_tree.type = VAT_JSON_NONE;
13535         return ret;
13536       }
13537
13538     node = vat_json_array_add (&vam->json_tree);
13539     vat_json_init_object (node);
13540
13541     vat_json_object_add_uint (node, "vni", eid_table->vni);
13542
13543     json_locator_set_for_eid_table (vam, node, eid_table);
13544     ret = json_eid_for_eid_table (vam, node, eid_table);
13545     if (ret)
13546       {
13547         vec_free (vam->locator_msg);
13548         vec_free (vam->eid_tables);
13549         clean_locator_set_message (vam);
13550         vat_json_free (&vam->json_tree);
13551         vam->json_tree.type = VAT_JSON_NONE;
13552         return ret;
13553       }
13554
13555     json_locator_for_eid_table (vam, node, eid_table);
13556
13557     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13558     vat_json_object_add_uint (node, "authoritative",
13559                               eid_table->authoritative);
13560
13561     vec_free (vam->locator_msg);
13562   }
13563
13564   vat_json_print (vam->ofp, &vam->json_tree);
13565   vat_json_free (&vam->json_tree);
13566   vam->json_tree.type = VAT_JSON_NONE;
13567
13568   clean_locator_set_message (vam);
13569   vec_free (vam->eid_tables);
13570
13571   return ret;
13572 }
13573
13574 static int
13575 api_lisp_eid_table_dump (vat_main_t * vam)
13576 {
13577   unformat_input_t *i = vam->input;
13578   vl_api_lisp_eid_table_dump_t *mp;
13579   f64 timeout = ~0;
13580   struct in_addr ip4;
13581   struct in6_addr ip6;
13582   u8 mac[6];
13583   u8 eid_type = ~0, eid_set = 0;
13584   u32 prefix_length = ~0, t, vni = 0;
13585   u8 filter = 0;
13586
13587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13588     {
13589       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13590         {
13591           eid_set = 1;
13592           eid_type = 0;
13593           prefix_length = t;
13594         }
13595       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13596         {
13597           eid_set = 1;
13598           eid_type = 1;
13599           prefix_length = t;
13600         }
13601       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13602         {
13603           eid_set = 1;
13604           eid_type = 2;
13605         }
13606       else if (unformat (i, "vni %d", &t))
13607         {
13608           vni = t;
13609         }
13610       else if (unformat (i, "local"))
13611         {
13612           filter = 1;
13613         }
13614       else if (unformat (i, "remote"))
13615         {
13616           filter = 2;
13617         }
13618       else
13619         {
13620           errmsg ("parse error '%U'", format_unformat_error, i);
13621           return -99;
13622         }
13623     }
13624
13625   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13626
13627   mp->filter = filter;
13628   if (eid_set)
13629     {
13630       mp->eid_set = 1;
13631       mp->vni = htonl (vni);
13632       mp->eid_type = eid_type;
13633       switch (eid_type)
13634         {
13635         case 0:
13636           mp->prefix_length = prefix_length;
13637           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13638           break;
13639         case 1:
13640           mp->prefix_length = prefix_length;
13641           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13642           break;
13643         case 2:
13644           clib_memcpy (mp->eid, mac, sizeof (mac));
13645           break;
13646         default:
13647           errmsg ("unknown EID type %d!", eid_type);
13648           return -99;
13649         }
13650     }
13651
13652   vam->noprint_msg = 1;
13653
13654   /* send it... */
13655   S;
13656
13657   /* Use a control ping for synchronization */
13658   {
13659     vl_api_noprint_control_ping_t *mp;
13660     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13661     S;
13662   }
13663
13664   /* Wait for a reply... */
13665   /* *INDENT-OFF* */
13666   W_L
13667   ({
13668     if (vam->noprint_msg)
13669       {
13670         if (!vam->json_output)
13671           {
13672             vam->retval = print_lisp_eid_table_dump(vam);
13673           }
13674         else
13675           {
13676             vam->retval = json_lisp_eid_table_dump(vam);
13677           }
13678       }
13679     vam->noprint_msg = 0;
13680   });
13681   /* *INDENT-ON* */
13682
13683   /* NOTREACHED */
13684   return 0;
13685 }
13686
13687 static int
13688 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13689 {
13690   vl_api_lisp_gpe_tunnel_dump_t *mp;
13691   f64 timeout = ~0;
13692
13693   if (!vam->json_output)
13694     {
13695       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13696                "%=16s%=16s%=16s%=16s%=16s\n",
13697                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13698                "Decap next", "Lisp version", "Flags", "Next protocol",
13699                "ver_res", "res", "iid");
13700     }
13701
13702   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13703   /* send it... */
13704   S;
13705
13706   /* Use a control ping for synchronization */
13707   {
13708     vl_api_control_ping_t *mp;
13709     M (CONTROL_PING, control_ping);
13710     S;
13711   }
13712   /* Wait for a reply... */
13713   W;
13714
13715   /* NOTREACHED */
13716   return 0;
13717 }
13718
13719 static int
13720 api_lisp_map_resolver_dump (vat_main_t * vam)
13721 {
13722   vl_api_lisp_map_resolver_dump_t *mp;
13723   f64 timeout = ~0;
13724
13725   if (!vam->json_output)
13726     {
13727       fformat (vam->ofp, "%=20s\n", "Map resolver");
13728     }
13729
13730   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13731   /* send it... */
13732   S;
13733
13734   /* Use a control ping for synchronization */
13735   {
13736     vl_api_control_ping_t *mp;
13737     M (CONTROL_PING, control_ping);
13738     S;
13739   }
13740   /* Wait for a reply... */
13741   W;
13742
13743   /* NOTREACHED */
13744   return 0;
13745 }
13746
13747 static int
13748 api_show_lisp_status (vat_main_t * vam)
13749 {
13750   vl_api_show_lisp_status_t *mp;
13751   f64 timeout = ~0;
13752
13753   if (!vam->json_output)
13754     {
13755       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13756     }
13757
13758   M (SHOW_LISP_STATUS, show_lisp_status);
13759   /* send it... */
13760   S;
13761   /* Wait for a reply... */
13762   W;
13763
13764   /* NOTREACHED */
13765   return 0;
13766 }
13767
13768 static int
13769 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13770 {
13771   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13772   f64 timeout = ~0;
13773
13774   if (!vam->json_output)
13775     {
13776       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13777     }
13778
13779   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13780   /* send it... */
13781   S;
13782   /* Wait for a reply... */
13783   W;
13784
13785   /* NOTREACHED */
13786   return 0;
13787 }
13788
13789 static int
13790 api_af_packet_create (vat_main_t * vam)
13791 {
13792   unformat_input_t *i = vam->input;
13793   vl_api_af_packet_create_t *mp;
13794   f64 timeout;
13795   u8 *host_if_name = 0;
13796   u8 hw_addr[6];
13797   u8 random_hw_addr = 1;
13798
13799   memset (hw_addr, 0, sizeof (hw_addr));
13800
13801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (i, "name %s", &host_if_name))
13804         vec_add1 (host_if_name, 0);
13805       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13806         random_hw_addr = 0;
13807       else
13808         break;
13809     }
13810
13811   if (!vec_len (host_if_name))
13812     {
13813       errmsg ("host-interface name must be specified");
13814       return -99;
13815     }
13816
13817   if (vec_len (host_if_name) > 64)
13818     {
13819       errmsg ("host-interface name too long");
13820       return -99;
13821     }
13822
13823   M (AF_PACKET_CREATE, af_packet_create);
13824
13825   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13826   clib_memcpy (mp->hw_addr, hw_addr, 6);
13827   mp->use_random_hw_addr = random_hw_addr;
13828   vec_free (host_if_name);
13829
13830   S;
13831   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13832   /* NOTREACHED */
13833   return 0;
13834 }
13835
13836 static int
13837 api_af_packet_delete (vat_main_t * vam)
13838 {
13839   unformat_input_t *i = vam->input;
13840   vl_api_af_packet_delete_t *mp;
13841   f64 timeout;
13842   u8 *host_if_name = 0;
13843
13844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13845     {
13846       if (unformat (i, "name %s", &host_if_name))
13847         vec_add1 (host_if_name, 0);
13848       else
13849         break;
13850     }
13851
13852   if (!vec_len (host_if_name))
13853     {
13854       errmsg ("host-interface name must be specified");
13855       return -99;
13856     }
13857
13858   if (vec_len (host_if_name) > 64)
13859     {
13860       errmsg ("host-interface name too long");
13861       return -99;
13862     }
13863
13864   M (AF_PACKET_DELETE, af_packet_delete);
13865
13866   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13867   vec_free (host_if_name);
13868
13869   S;
13870   W;
13871   /* NOTREACHED */
13872   return 0;
13873 }
13874
13875 static int
13876 api_policer_add_del (vat_main_t * vam)
13877 {
13878   unformat_input_t *i = vam->input;
13879   vl_api_policer_add_del_t *mp;
13880   f64 timeout;
13881   u8 is_add = 1;
13882   u8 *name = 0;
13883   u32 cir = 0;
13884   u32 eir = 0;
13885   u64 cb = 0;
13886   u64 eb = 0;
13887   u8 rate_type = 0;
13888   u8 round_type = 0;
13889   u8 type = 0;
13890   u8 color_aware = 0;
13891   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13892
13893   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13894   conform_action.dscp = 0;
13895   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13896   exceed_action.dscp = 0;
13897   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13898   violate_action.dscp = 0;
13899
13900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13901     {
13902       if (unformat (i, "del"))
13903         is_add = 0;
13904       else if (unformat (i, "name %s", &name))
13905         vec_add1 (name, 0);
13906       else if (unformat (i, "cir %u", &cir))
13907         ;
13908       else if (unformat (i, "eir %u", &eir))
13909         ;
13910       else if (unformat (i, "cb %u", &cb))
13911         ;
13912       else if (unformat (i, "eb %u", &eb))
13913         ;
13914       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13915                          &rate_type))
13916         ;
13917       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13918                          &round_type))
13919         ;
13920       else if (unformat (i, "type %U", unformat_policer_type, &type))
13921         ;
13922       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13923                          &conform_action))
13924         ;
13925       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13926                          &exceed_action))
13927         ;
13928       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13929                          &violate_action))
13930         ;
13931       else if (unformat (i, "color-aware"))
13932         color_aware = 1;
13933       else
13934         break;
13935     }
13936
13937   if (!vec_len (name))
13938     {
13939       errmsg ("policer name must be specified");
13940       return -99;
13941     }
13942
13943   if (vec_len (name) > 64)
13944     {
13945       errmsg ("policer name too long");
13946       return -99;
13947     }
13948
13949   M (POLICER_ADD_DEL, policer_add_del);
13950
13951   clib_memcpy (mp->name, name, vec_len (name));
13952   vec_free (name);
13953   mp->is_add = is_add;
13954   mp->cir = cir;
13955   mp->eir = eir;
13956   mp->cb = cb;
13957   mp->eb = eb;
13958   mp->rate_type = rate_type;
13959   mp->round_type = round_type;
13960   mp->type = type;
13961   mp->conform_action_type = conform_action.action_type;
13962   mp->conform_dscp = conform_action.dscp;
13963   mp->exceed_action_type = exceed_action.action_type;
13964   mp->exceed_dscp = exceed_action.dscp;
13965   mp->violate_action_type = violate_action.action_type;
13966   mp->violate_dscp = violate_action.dscp;
13967   mp->color_aware = color_aware;
13968
13969   S;
13970   W;
13971   /* NOTREACHED */
13972   return 0;
13973 }
13974
13975 static int
13976 api_policer_dump (vat_main_t * vam)
13977 {
13978   unformat_input_t *i = vam->input;
13979   vl_api_policer_dump_t *mp;
13980   f64 timeout = ~0;
13981   u8 *match_name = 0;
13982   u8 match_name_valid = 0;
13983
13984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13985     {
13986       if (unformat (i, "name %s", &match_name))
13987         {
13988           vec_add1 (match_name, 0);
13989           match_name_valid = 1;
13990         }
13991       else
13992         break;
13993     }
13994
13995   M (POLICER_DUMP, policer_dump);
13996   mp->match_name_valid = match_name_valid;
13997   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13998   vec_free (match_name);
13999   /* send it... */
14000   S;
14001
14002   /* Use a control ping for synchronization */
14003   {
14004     vl_api_control_ping_t *mp;
14005     M (CONTROL_PING, control_ping);
14006     S;
14007   }
14008   /* Wait for a reply... */
14009   W;
14010
14011   /* NOTREACHED */
14012   return 0;
14013 }
14014
14015 static int
14016 api_policer_classify_set_interface (vat_main_t * vam)
14017 {
14018   unformat_input_t *i = vam->input;
14019   vl_api_policer_classify_set_interface_t *mp;
14020   f64 timeout;
14021   u32 sw_if_index;
14022   int sw_if_index_set;
14023   u32 ip4_table_index = ~0;
14024   u32 ip6_table_index = ~0;
14025   u32 l2_table_index = ~0;
14026   u8 is_add = 1;
14027
14028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14029     {
14030       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14031         sw_if_index_set = 1;
14032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14033         sw_if_index_set = 1;
14034       else if (unformat (i, "del"))
14035         is_add = 0;
14036       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14037         ;
14038       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14039         ;
14040       else if (unformat (i, "l2-table %d", &l2_table_index))
14041         ;
14042       else
14043         {
14044           clib_warning ("parse error '%U'", format_unformat_error, i);
14045           return -99;
14046         }
14047     }
14048
14049   if (sw_if_index_set == 0)
14050     {
14051       errmsg ("missing interface name or sw_if_index\n");
14052       return -99;
14053     }
14054
14055   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14056
14057   mp->sw_if_index = ntohl (sw_if_index);
14058   mp->ip4_table_index = ntohl (ip4_table_index);
14059   mp->ip6_table_index = ntohl (ip6_table_index);
14060   mp->l2_table_index = ntohl (l2_table_index);
14061   mp->is_add = is_add;
14062
14063   S;
14064   W;
14065   /* NOTREACHED */
14066   return 0;
14067 }
14068
14069 static int
14070 api_policer_classify_dump (vat_main_t * vam)
14071 {
14072   unformat_input_t *i = vam->input;
14073   vl_api_policer_classify_dump_t *mp;
14074   f64 timeout = ~0;
14075   u8 type = POLICER_CLASSIFY_N_TABLES;
14076
14077   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14078     ;
14079   else
14080     {
14081       errmsg ("classify table type must be specified\n");
14082       return -99;
14083     }
14084
14085   if (!vam->json_output)
14086     {
14087       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14088     }
14089
14090   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14091   mp->type = type;
14092   /* send it... */
14093   S;
14094
14095   /* Use a control ping for synchronization */
14096   {
14097     vl_api_control_ping_t *mp;
14098     M (CONTROL_PING, control_ping);
14099     S;
14100   }
14101   /* Wait for a reply... */
14102   W;
14103
14104   /* NOTREACHED */
14105   return 0;
14106 }
14107
14108 static int
14109 api_netmap_create (vat_main_t * vam)
14110 {
14111   unformat_input_t *i = vam->input;
14112   vl_api_netmap_create_t *mp;
14113   f64 timeout;
14114   u8 *if_name = 0;
14115   u8 hw_addr[6];
14116   u8 random_hw_addr = 1;
14117   u8 is_pipe = 0;
14118   u8 is_master = 0;
14119
14120   memset (hw_addr, 0, sizeof (hw_addr));
14121
14122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14123     {
14124       if (unformat (i, "name %s", &if_name))
14125         vec_add1 (if_name, 0);
14126       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14127         random_hw_addr = 0;
14128       else if (unformat (i, "pipe"))
14129         is_pipe = 1;
14130       else if (unformat (i, "master"))
14131         is_master = 1;
14132       else if (unformat (i, "slave"))
14133         is_master = 0;
14134       else
14135         break;
14136     }
14137
14138   if (!vec_len (if_name))
14139     {
14140       errmsg ("interface name must be specified");
14141       return -99;
14142     }
14143
14144   if (vec_len (if_name) > 64)
14145     {
14146       errmsg ("interface name too long");
14147       return -99;
14148     }
14149
14150   M (NETMAP_CREATE, netmap_create);
14151
14152   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14153   clib_memcpy (mp->hw_addr, hw_addr, 6);
14154   mp->use_random_hw_addr = random_hw_addr;
14155   mp->is_pipe = is_pipe;
14156   mp->is_master = is_master;
14157   vec_free (if_name);
14158
14159   S;
14160   W;
14161   /* NOTREACHED */
14162   return 0;
14163 }
14164
14165 static int
14166 api_netmap_delete (vat_main_t * vam)
14167 {
14168   unformat_input_t *i = vam->input;
14169   vl_api_netmap_delete_t *mp;
14170   f64 timeout;
14171   u8 *if_name = 0;
14172
14173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14174     {
14175       if (unformat (i, "name %s", &if_name))
14176         vec_add1 (if_name, 0);
14177       else
14178         break;
14179     }
14180
14181   if (!vec_len (if_name))
14182     {
14183       errmsg ("interface name must be specified");
14184       return -99;
14185     }
14186
14187   if (vec_len (if_name) > 64)
14188     {
14189       errmsg ("interface name too long");
14190       return -99;
14191     }
14192
14193   M (NETMAP_DELETE, netmap_delete);
14194
14195   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14196   vec_free (if_name);
14197
14198   S;
14199   W;
14200   /* NOTREACHED */
14201   return 0;
14202 }
14203
14204 static void vl_api_mpls_gre_tunnel_details_t_handler
14205   (vl_api_mpls_gre_tunnel_details_t * mp)
14206 {
14207   vat_main_t *vam = &vat_main;
14208   i32 i;
14209   i32 len = ntohl (mp->nlabels);
14210
14211   if (mp->l2_only == 0)
14212     {
14213       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14214                ntohl (mp->tunnel_index),
14215                format_ip4_address, &mp->tunnel_src,
14216                format_ip4_address, &mp->tunnel_dst,
14217                format_ip4_address, &mp->intfc_address,
14218                ntohl (mp->mask_width));
14219       for (i = 0; i < len; i++)
14220         {
14221           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14222         }
14223       fformat (vam->ofp, "\n");
14224       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14225                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14226     }
14227   else
14228     {
14229       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14230                ntohl (mp->tunnel_index),
14231                format_ip4_address, &mp->tunnel_src,
14232                format_ip4_address, &mp->tunnel_dst,
14233                format_ip4_address, &mp->intfc_address);
14234       for (i = 0; i < len; i++)
14235         {
14236           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14237         }
14238       fformat (vam->ofp, "\n");
14239       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14240                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14241     }
14242 }
14243
14244 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14245   (vl_api_mpls_gre_tunnel_details_t * mp)
14246 {
14247   vat_main_t *vam = &vat_main;
14248   vat_json_node_t *node = NULL;
14249   struct in_addr ip4;
14250   i32 i;
14251   i32 len = ntohl (mp->nlabels);
14252
14253   if (VAT_JSON_ARRAY != vam->json_tree.type)
14254     {
14255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14256       vat_json_init_array (&vam->json_tree);
14257     }
14258   node = vat_json_array_add (&vam->json_tree);
14259
14260   vat_json_init_object (node);
14261   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14262   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14263   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14264   vat_json_object_add_uint (node, "inner_fib_index",
14265                             ntohl (mp->inner_fib_index));
14266   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14267   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14268   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14269   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14270   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14271   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14272   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14273   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14274   vat_json_object_add_uint (node, "outer_fib_index",
14275                             ntohl (mp->outer_fib_index));
14276   vat_json_object_add_uint (node, "label_count", len);
14277   for (i = 0; i < len; i++)
14278     {
14279       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14280     }
14281 }
14282
14283 static int
14284 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14285 {
14286   vl_api_mpls_gre_tunnel_dump_t *mp;
14287   f64 timeout;
14288   i32 index = -1;
14289
14290   /* Parse args required to build the message */
14291   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14292     {
14293       if (!unformat (vam->input, "tunnel_index %d", &index))
14294         {
14295           index = -1;
14296           break;
14297         }
14298     }
14299
14300   fformat (vam->ofp, "  tunnel_index %d\n", index);
14301
14302   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14303   mp->tunnel_index = htonl (index);
14304   S;
14305
14306   /* Use a control ping for synchronization */
14307   {
14308     vl_api_control_ping_t *mp;
14309     M (CONTROL_PING, control_ping);
14310     S;
14311   }
14312   W;
14313 }
14314
14315 static void vl_api_mpls_eth_tunnel_details_t_handler
14316   (vl_api_mpls_eth_tunnel_details_t * mp)
14317 {
14318   vat_main_t *vam = &vat_main;
14319   i32 i;
14320   i32 len = ntohl (mp->nlabels);
14321
14322   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14323            ntohl (mp->tunnel_index),
14324            format_ethernet_address, &mp->tunnel_dst_mac,
14325            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14326   for (i = 0; i < len; i++)
14327     {
14328       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14329     }
14330   fformat (vam->ofp, "\n");
14331   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14332            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14333 }
14334
14335 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14336   (vl_api_mpls_eth_tunnel_details_t * mp)
14337 {
14338   vat_main_t *vam = &vat_main;
14339   vat_json_node_t *node = NULL;
14340   struct in_addr ip4;
14341   i32 i;
14342   i32 len = ntohl (mp->nlabels);
14343
14344   if (VAT_JSON_ARRAY != vam->json_tree.type)
14345     {
14346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14347       vat_json_init_array (&vam->json_tree);
14348     }
14349   node = vat_json_array_add (&vam->json_tree);
14350
14351   vat_json_init_object (node);
14352   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14353   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14354   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14355   vat_json_object_add_uint (node, "inner_fib_index",
14356                             ntohl (mp->inner_fib_index));
14357   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14358   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14359   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14360   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14361   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14362                                    format (0, "%U", format_ethernet_address,
14363                                            &mp->tunnel_dst_mac));
14364   vat_json_object_add_uint (node, "tx_sw_if_index",
14365                             ntohl (mp->tx_sw_if_index));
14366   vat_json_object_add_uint (node, "label_count", len);
14367   for (i = 0; i < len; i++)
14368     {
14369       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14370     }
14371 }
14372
14373 static int
14374 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14375 {
14376   vl_api_mpls_eth_tunnel_dump_t *mp;
14377   f64 timeout;
14378   i32 index = -1;
14379
14380   /* Parse args required to build the message */
14381   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14382     {
14383       if (!unformat (vam->input, "tunnel_index %d", &index))
14384         {
14385           index = -1;
14386           break;
14387         }
14388     }
14389
14390   fformat (vam->ofp, "  tunnel_index %d\n", index);
14391
14392   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14393   mp->tunnel_index = htonl (index);
14394   S;
14395
14396   /* Use a control ping for synchronization */
14397   {
14398     vl_api_control_ping_t *mp;
14399     M (CONTROL_PING, control_ping);
14400     S;
14401   }
14402   W;
14403 }
14404
14405 static void vl_api_mpls_fib_encap_details_t_handler
14406   (vl_api_mpls_fib_encap_details_t * mp)
14407 {
14408   vat_main_t *vam = &vat_main;
14409   i32 i;
14410   i32 len = ntohl (mp->nlabels);
14411
14412   fformat (vam->ofp, "table %d, dest %U, label ",
14413            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14414   for (i = 0; i < len; i++)
14415     {
14416       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14417     }
14418   fformat (vam->ofp, "\n");
14419 }
14420
14421 static void vl_api_mpls_fib_encap_details_t_handler_json
14422   (vl_api_mpls_fib_encap_details_t * mp)
14423 {
14424   vat_main_t *vam = &vat_main;
14425   vat_json_node_t *node = NULL;
14426   i32 i;
14427   i32 len = ntohl (mp->nlabels);
14428   struct in_addr ip4;
14429
14430   if (VAT_JSON_ARRAY != vam->json_tree.type)
14431     {
14432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14433       vat_json_init_array (&vam->json_tree);
14434     }
14435   node = vat_json_array_add (&vam->json_tree);
14436
14437   vat_json_init_object (node);
14438   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14439   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14440   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14441   vat_json_object_add_ip4 (node, "dest", ip4);
14442   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14443   vat_json_object_add_uint (node, "label_count", len);
14444   for (i = 0; i < len; i++)
14445     {
14446       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14447     }
14448 }
14449
14450 static int
14451 api_mpls_fib_encap_dump (vat_main_t * vam)
14452 {
14453   vl_api_mpls_fib_encap_dump_t *mp;
14454   f64 timeout;
14455
14456   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14457   S;
14458
14459   /* Use a control ping for synchronization */
14460   {
14461     vl_api_control_ping_t *mp;
14462     M (CONTROL_PING, control_ping);
14463     S;
14464   }
14465   W;
14466 }
14467
14468 static void vl_api_mpls_fib_decap_details_t_handler
14469   (vl_api_mpls_fib_decap_details_t * mp)
14470 {
14471   vat_main_t *vam = &vat_main;
14472
14473   fformat (vam->ofp,
14474            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14475            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14476            ntohl (mp->label), ntohl (mp->s_bit));
14477 }
14478
14479 static void vl_api_mpls_fib_decap_details_t_handler_json
14480   (vl_api_mpls_fib_decap_details_t * mp)
14481 {
14482   vat_main_t *vam = &vat_main;
14483   vat_json_node_t *node = NULL;
14484   struct in_addr ip4;
14485
14486   if (VAT_JSON_ARRAY != vam->json_tree.type)
14487     {
14488       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14489       vat_json_init_array (&vam->json_tree);
14490     }
14491   node = vat_json_array_add (&vam->json_tree);
14492
14493   vat_json_init_object (node);
14494   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14495   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14496   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14497   vat_json_object_add_ip4 (node, "dest", ip4);
14498   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14499   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14500   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14501   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14502   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14503 }
14504
14505 static int
14506 api_mpls_fib_decap_dump (vat_main_t * vam)
14507 {
14508   vl_api_mpls_fib_decap_dump_t *mp;
14509   f64 timeout;
14510
14511   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14512   S;
14513
14514   /* Use a control ping for synchronization */
14515   {
14516     vl_api_control_ping_t *mp;
14517     M (CONTROL_PING, control_ping);
14518     S;
14519   }
14520   W;
14521 }
14522
14523 int
14524 api_classify_table_ids (vat_main_t * vam)
14525 {
14526   vl_api_classify_table_ids_t *mp;
14527   f64 timeout;
14528
14529   /* Construct the API message */
14530   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14531   mp->context = 0;
14532
14533   S;
14534   W;
14535   /* NOTREACHED */
14536   return 0;
14537 }
14538
14539 int
14540 api_classify_table_by_interface (vat_main_t * vam)
14541 {
14542   unformat_input_t *input = vam->input;
14543   vl_api_classify_table_by_interface_t *mp;
14544   f64 timeout;
14545
14546   u32 sw_if_index = ~0;
14547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14548     {
14549       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14550         ;
14551       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14552         ;
14553       else
14554         break;
14555     }
14556   if (sw_if_index == ~0)
14557     {
14558       errmsg ("missing interface name or sw_if_index\n");
14559       return -99;
14560     }
14561
14562   /* Construct the API message */
14563   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14564   mp->context = 0;
14565   mp->sw_if_index = ntohl (sw_if_index);
14566
14567   S;
14568   W;
14569   /* NOTREACHED */
14570   return 0;
14571 }
14572
14573 int
14574 api_classify_table_info (vat_main_t * vam)
14575 {
14576   unformat_input_t *input = vam->input;
14577   vl_api_classify_table_info_t *mp;
14578   f64 timeout;
14579
14580   u32 table_id = ~0;
14581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14582     {
14583       if (unformat (input, "table_id %d", &table_id))
14584         ;
14585       else
14586         break;
14587     }
14588   if (table_id == ~0)
14589     {
14590       errmsg ("missing table id\n");
14591       return -99;
14592     }
14593
14594   /* Construct the API message */
14595   M (CLASSIFY_TABLE_INFO, classify_table_info);
14596   mp->context = 0;
14597   mp->table_id = ntohl (table_id);
14598
14599   S;
14600   W;
14601   /* NOTREACHED */
14602   return 0;
14603 }
14604
14605 int
14606 api_classify_session_dump (vat_main_t * vam)
14607 {
14608   unformat_input_t *input = vam->input;
14609   vl_api_classify_session_dump_t *mp;
14610   f64 timeout;
14611
14612   u32 table_id = ~0;
14613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14614     {
14615       if (unformat (input, "table_id %d", &table_id))
14616         ;
14617       else
14618         break;
14619     }
14620   if (table_id == ~0)
14621     {
14622       errmsg ("missing table id\n");
14623       return -99;
14624     }
14625
14626   /* Construct the API message */
14627   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14628   mp->context = 0;
14629   mp->table_id = ntohl (table_id);
14630   S;
14631
14632   /* Use a control ping for synchronization */
14633   {
14634     vl_api_control_ping_t *mp;
14635     M (CONTROL_PING, control_ping);
14636     S;
14637   }
14638   W;
14639   /* NOTREACHED */
14640   return 0;
14641 }
14642
14643 static void
14644 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14645 {
14646   vat_main_t *vam = &vat_main;
14647
14648   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14649            "src_address %U, fib_index %u, path_mtu %u, "
14650            "template_interval %u\n",
14651            format_ip4_address, mp->collector_address,
14652            ntohs (mp->collector_port),
14653            format_ip4_address, mp->src_address,
14654            ntohl (mp->fib_index),
14655            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14656
14657   vam->retval = 0;
14658   vam->result_ready = 1;
14659 }
14660
14661 static void
14662 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14663 {
14664   vat_main_t *vam = &vat_main;
14665   vat_json_node_t node;
14666   struct in_addr collector_address;
14667   struct in_addr src_address;
14668
14669   vat_json_init_object (&node);
14670   clib_memcpy (&collector_address, &mp->collector_address,
14671                sizeof (collector_address));
14672   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14673   vat_json_object_add_uint (&node, "collector_port",
14674                             ntohs (mp->collector_port));
14675   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14676   vat_json_object_add_ip4 (&node, "src_address", src_address);
14677   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14678   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14679   vat_json_object_add_uint (&node, "template_interval",
14680                             ntohl (mp->template_interval));
14681
14682   vat_json_print (vam->ofp, &node);
14683   vat_json_free (&node);
14684   vam->retval = 0;
14685   vam->result_ready = 1;
14686 }
14687
14688 int
14689 api_ipfix_dump (vat_main_t * vam)
14690 {
14691   vl_api_ipfix_dump_t *mp;
14692   f64 timeout;
14693
14694   /* Construct the API message */
14695   M (IPFIX_DUMP, ipfix_dump);
14696   mp->context = 0;
14697
14698   S;
14699   W;
14700   /* NOTREACHED */
14701   return 0;
14702 }
14703
14704 int
14705 api_pg_create_interface (vat_main_t * vam)
14706 {
14707   unformat_input_t *input = vam->input;
14708   vl_api_pg_create_interface_t *mp;
14709   f64 timeout;
14710
14711   u32 if_id = ~0;
14712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14713     {
14714       if (unformat (input, "if_id %d", &if_id))
14715         ;
14716       else
14717         break;
14718     }
14719   if (if_id == ~0)
14720     {
14721       errmsg ("missing pg interface index\n");
14722       return -99;
14723     }
14724
14725   /* Construct the API message */
14726   M (PG_CREATE_INTERFACE, pg_create_interface);
14727   mp->context = 0;
14728   mp->interface_id = ntohl (if_id);
14729
14730   S;
14731   W;
14732   /* NOTREACHED */
14733   return 0;
14734 }
14735
14736 int
14737 api_pg_capture (vat_main_t * vam)
14738 {
14739   unformat_input_t *input = vam->input;
14740   vl_api_pg_capture_t *mp;
14741   f64 timeout;
14742
14743   u32 if_id = ~0;
14744   u8 enable = 1;
14745   u32 count = 1;
14746   u8 pcap_file_set = 0;
14747   u8 *pcap_file = 0;
14748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14749     {
14750       if (unformat (input, "if_id %d", &if_id))
14751         ;
14752       else if (unformat (input, "pcap %s", &pcap_file))
14753         pcap_file_set = 1;
14754       else if (unformat (input, "count %d", &count))
14755         ;
14756       else if (unformat (input, "disable"))
14757         enable = 0;
14758       else
14759         break;
14760     }
14761   if (if_id == ~0)
14762     {
14763       errmsg ("missing pg interface index\n");
14764       return -99;
14765     }
14766   if (pcap_file_set > 0)
14767     {
14768       if (vec_len (pcap_file) > 255)
14769         {
14770           errmsg ("pcap file name is too long\n");
14771           return -99;
14772         }
14773     }
14774
14775   u32 name_len = vec_len (pcap_file);
14776   /* Construct the API message */
14777   M (PG_CAPTURE, pg_capture);
14778   mp->context = 0;
14779   mp->interface_id = ntohl (if_id);
14780   mp->is_enabled = enable;
14781   mp->count = ntohl (count);
14782   mp->pcap_name_length = ntohl (name_len);
14783   if (pcap_file_set != 0)
14784     {
14785       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14786     }
14787   vec_free (pcap_file);
14788
14789   S;
14790   W;
14791   /* NOTREACHED */
14792   return 0;
14793 }
14794
14795 int
14796 api_pg_enable_disable (vat_main_t * vam)
14797 {
14798   unformat_input_t *input = vam->input;
14799   vl_api_pg_enable_disable_t *mp;
14800   f64 timeout;
14801
14802   u8 enable = 1;
14803   u8 stream_name_set = 0;
14804   u8 *stream_name = 0;
14805   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14806     {
14807       if (unformat (input, "stream %s", &stream_name))
14808         stream_name_set = 1;
14809       else if (unformat (input, "disable"))
14810         enable = 0;
14811       else
14812         break;
14813     }
14814
14815   if (stream_name_set > 0)
14816     {
14817       if (vec_len (stream_name) > 255)
14818         {
14819           errmsg ("stream name too long\n");
14820           return -99;
14821         }
14822     }
14823
14824   u32 name_len = vec_len (stream_name);
14825   /* Construct the API message */
14826   M (PG_ENABLE_DISABLE, pg_enable_disable);
14827   mp->context = 0;
14828   mp->is_enabled = enable;
14829   if (stream_name_set != 0)
14830     {
14831       mp->stream_name_length = ntohl (name_len);
14832       clib_memcpy (mp->stream_name, stream_name, name_len);
14833     }
14834   vec_free (stream_name);
14835
14836   S;
14837   W;
14838   /* NOTREACHED */
14839   return 0;
14840 }
14841
14842 int
14843 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14844 {
14845   unformat_input_t *input = vam->input;
14846   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14847   f64 timeout;
14848
14849   u16 *low_ports = 0;
14850   u16 *high_ports = 0;
14851   u16 this_low;
14852   u16 this_hi;
14853   ip4_address_t ip4_addr;
14854   ip6_address_t ip6_addr;
14855   u32 length;
14856   u32 tmp, tmp2;
14857   u8 prefix_set = 0;
14858   u32 vrf_id = ~0;
14859   u8 is_add = 1;
14860   u8 is_ipv6 = 0;
14861
14862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14863     {
14864       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14865         {
14866           prefix_set = 1;
14867         }
14868       else
14869         if (unformat
14870             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14871         {
14872           prefix_set = 1;
14873           is_ipv6 = 1;
14874         }
14875       else if (unformat (input, "vrf %d", &vrf_id))
14876         ;
14877       else if (unformat (input, "del"))
14878         is_add = 0;
14879       else if (unformat (input, "port %d", &tmp))
14880         {
14881           if (tmp == 0 || tmp > 65535)
14882             {
14883               errmsg ("port %d out of range", tmp);
14884               return -99;
14885             }
14886           this_low = tmp;
14887           this_hi = this_low + 1;
14888           vec_add1 (low_ports, this_low);
14889           vec_add1 (high_ports, this_hi);
14890         }
14891       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14892         {
14893           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14894             {
14895               errmsg ("incorrect range parameters\n");
14896               return -99;
14897             }
14898           this_low = tmp;
14899           /* Note: in debug CLI +1 is added to high before
14900              passing to real fn that does "the work"
14901              (ip_source_and_port_range_check_add_del).
14902              This fn is a wrapper around the binary API fn a
14903              control plane will call, which expects this increment
14904              to have occurred. Hence letting the binary API control
14905              plane fn do the increment for consistency between VAT
14906              and other control planes.
14907            */
14908           this_hi = tmp2;
14909           vec_add1 (low_ports, this_low);
14910           vec_add1 (high_ports, this_hi);
14911         }
14912       else
14913         break;
14914     }
14915
14916   if (prefix_set == 0)
14917     {
14918       errmsg ("<address>/<mask> not specified\n");
14919       return -99;
14920     }
14921
14922   if (vrf_id == ~0)
14923     {
14924       errmsg ("VRF ID required, not specified\n");
14925       return -99;
14926     }
14927
14928   if (vrf_id == 0)
14929     {
14930       errmsg
14931         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14932       return -99;
14933     }
14934
14935   if (vec_len (low_ports) == 0)
14936     {
14937       errmsg ("At least one port or port range required\n");
14938       return -99;
14939     }
14940
14941   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14942      ip_source_and_port_range_check_add_del);
14943
14944   mp->is_add = is_add;
14945
14946   if (is_ipv6)
14947     {
14948       mp->is_ipv6 = 1;
14949       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14950     }
14951   else
14952     {
14953       mp->is_ipv6 = 0;
14954       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14955     }
14956
14957   mp->mask_length = length;
14958   mp->number_of_ranges = vec_len (low_ports);
14959
14960   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14961   vec_free (low_ports);
14962
14963   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14964   vec_free (high_ports);
14965
14966   mp->vrf_id = ntohl (vrf_id);
14967
14968   S;
14969   W;
14970   /* NOTREACHED */
14971   return 0;
14972 }
14973
14974 int
14975 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14976 {
14977   unformat_input_t *input = vam->input;
14978   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14979   f64 timeout;
14980   u32 sw_if_index = ~0;
14981   int vrf_set = 0;
14982   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14983   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14984   u8 is_add = 1;
14985
14986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14987     {
14988       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14989         ;
14990       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14991         ;
14992       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14993         vrf_set = 1;
14994       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14995         vrf_set = 1;
14996       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14997         vrf_set = 1;
14998       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14999         vrf_set = 1;
15000       else if (unformat (input, "del"))
15001         is_add = 0;
15002       else
15003         break;
15004     }
15005
15006   if (sw_if_index == ~0)
15007     {
15008       errmsg ("Interface required but not specified\n");
15009       return -99;
15010     }
15011
15012   if (vrf_set == 0)
15013     {
15014       errmsg ("VRF ID required but not specified\n");
15015       return -99;
15016     }
15017
15018   if (tcp_out_vrf_id == 0
15019       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15020     {
15021       errmsg
15022         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15023       return -99;
15024     }
15025
15026   /* Construct the API message */
15027   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15028      ip_source_and_port_range_check_interface_add_del);
15029
15030   mp->sw_if_index = ntohl (sw_if_index);
15031   mp->is_add = is_add;
15032   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15033   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15034   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15035   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15036
15037   /* send it... */
15038   S;
15039
15040   /* Wait for a reply... */
15041   W;
15042 }
15043
15044 static int
15045 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15046 {
15047   unformat_input_t *i = vam->input;
15048   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15049   f64 timeout;
15050   u32 local_sa_id = 0;
15051   u32 remote_sa_id = 0;
15052   ip4_address_t src_address;
15053   ip4_address_t dst_address;
15054   u8 is_add = 1;
15055
15056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15057     {
15058       if (unformat (i, "local_sa %d", &local_sa_id))
15059         ;
15060       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15061         ;
15062       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15063         ;
15064       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15065         ;
15066       else if (unformat (i, "del"))
15067         is_add = 0;
15068       else
15069         {
15070           clib_warning ("parse error '%U'", format_unformat_error, i);
15071           return -99;
15072         }
15073     }
15074
15075   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15076
15077   mp->local_sa_id = ntohl (local_sa_id);
15078   mp->remote_sa_id = ntohl (remote_sa_id);
15079   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15080   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15081   mp->is_add = is_add;
15082
15083   S;
15084   W;
15085   /* NOTREACHED */
15086   return 0;
15087 }
15088
15089 static void vl_api_ipsec_gre_tunnel_details_t_handler
15090   (vl_api_ipsec_gre_tunnel_details_t * mp)
15091 {
15092   vat_main_t *vam = &vat_main;
15093
15094   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15095            ntohl (mp->sw_if_index),
15096            format_ip4_address, &mp->src_address,
15097            format_ip4_address, &mp->dst_address,
15098            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15099 }
15100
15101 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15102   (vl_api_ipsec_gre_tunnel_details_t * mp)
15103 {
15104   vat_main_t *vam = &vat_main;
15105   vat_json_node_t *node = NULL;
15106   struct in_addr ip4;
15107
15108   if (VAT_JSON_ARRAY != vam->json_tree.type)
15109     {
15110       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15111       vat_json_init_array (&vam->json_tree);
15112     }
15113   node = vat_json_array_add (&vam->json_tree);
15114
15115   vat_json_init_object (node);
15116   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15117   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15118   vat_json_object_add_ip4 (node, "src_address", ip4);
15119   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15120   vat_json_object_add_ip4 (node, "dst_address", ip4);
15121   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15122   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15123 }
15124
15125 static int
15126 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15127 {
15128   unformat_input_t *i = vam->input;
15129   vl_api_ipsec_gre_tunnel_dump_t *mp;
15130   f64 timeout;
15131   u32 sw_if_index;
15132   u8 sw_if_index_set = 0;
15133
15134   /* Parse args required to build the message */
15135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (i, "sw_if_index %d", &sw_if_index))
15138         sw_if_index_set = 1;
15139       else
15140         break;
15141     }
15142
15143   if (sw_if_index_set == 0)
15144     {
15145       sw_if_index = ~0;
15146     }
15147
15148   if (!vam->json_output)
15149     {
15150       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15151                "sw_if_index", "src_address", "dst_address",
15152                "local_sa_id", "remote_sa_id");
15153     }
15154
15155   /* Get list of gre-tunnel interfaces */
15156   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15157
15158   mp->sw_if_index = htonl (sw_if_index);
15159
15160   S;
15161
15162   /* Use a control ping for synchronization */
15163   {
15164     vl_api_control_ping_t *mp;
15165     M (CONTROL_PING, control_ping);
15166     S;
15167   }
15168   W;
15169 }
15170
15171 static int
15172 q_or_quit (vat_main_t * vam)
15173 {
15174   longjmp (vam->jump_buf, 1);
15175   return 0;                     /* not so much */
15176 }
15177
15178 static int
15179 q (vat_main_t * vam)
15180 {
15181   return q_or_quit (vam);
15182 }
15183
15184 static int
15185 quit (vat_main_t * vam)
15186 {
15187   return q_or_quit (vam);
15188 }
15189
15190 static int
15191 comment (vat_main_t * vam)
15192 {
15193   return 0;
15194 }
15195
15196 static int
15197 cmd_cmp (void *a1, void *a2)
15198 {
15199   u8 **c1 = a1;
15200   u8 **c2 = a2;
15201
15202   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15203 }
15204
15205 static int
15206 help (vat_main_t * vam)
15207 {
15208   u8 **cmds = 0;
15209   u8 *name = 0;
15210   hash_pair_t *p;
15211   unformat_input_t *i = vam->input;
15212   int j;
15213
15214   if (unformat (i, "%s", &name))
15215     {
15216       uword *hs;
15217
15218       vec_add1 (name, 0);
15219
15220       hs = hash_get_mem (vam->help_by_name, name);
15221       if (hs)
15222         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15223       else
15224         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15225       vec_free (name);
15226       return 0;
15227     }
15228
15229   fformat (vam->ofp, "Help is available for the following:\n");
15230
15231     /* *INDENT-OFF* */
15232     hash_foreach_pair (p, vam->function_by_name,
15233     ({
15234       vec_add1 (cmds, (u8 *)(p->key));
15235     }));
15236     /* *INDENT-ON* */
15237
15238   vec_sort_with_function (cmds, cmd_cmp);
15239
15240   for (j = 0; j < vec_len (cmds); j++)
15241     fformat (vam->ofp, "%s\n", cmds[j]);
15242
15243   vec_free (cmds);
15244   return 0;
15245 }
15246
15247 static int
15248 set (vat_main_t * vam)
15249 {
15250   u8 *name = 0, *value = 0;
15251   unformat_input_t *i = vam->input;
15252
15253   if (unformat (i, "%s", &name))
15254     {
15255       /* The input buffer is a vector, not a string. */
15256       value = vec_dup (i->buffer);
15257       vec_delete (value, i->index, 0);
15258       /* Almost certainly has a trailing newline */
15259       if (value[vec_len (value) - 1] == '\n')
15260         value[vec_len (value) - 1] = 0;
15261       /* Make sure it's a proper string, one way or the other */
15262       vec_add1 (value, 0);
15263       (void) clib_macro_set_value (&vam->macro_main,
15264                                    (char *) name, (char *) value);
15265     }
15266   else
15267     errmsg ("usage: set <name> <value>\n");
15268
15269   vec_free (name);
15270   vec_free (value);
15271   return 0;
15272 }
15273
15274 static int
15275 unset (vat_main_t * vam)
15276 {
15277   u8 *name = 0;
15278
15279   if (unformat (vam->input, "%s", &name))
15280     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15281       errmsg ("unset: %s wasn't set\n", name);
15282   vec_free (name);
15283   return 0;
15284 }
15285
15286 typedef struct
15287 {
15288   u8 *name;
15289   u8 *value;
15290 } macro_sort_t;
15291
15292
15293 static int
15294 macro_sort_cmp (void *a1, void *a2)
15295 {
15296   macro_sort_t *s1 = a1;
15297   macro_sort_t *s2 = a2;
15298
15299   return strcmp ((char *) (s1->name), (char *) (s2->name));
15300 }
15301
15302 static int
15303 dump_macro_table (vat_main_t * vam)
15304 {
15305   macro_sort_t *sort_me = 0, *sm;
15306   int i;
15307   hash_pair_t *p;
15308
15309     /* *INDENT-OFF* */
15310     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15311     ({
15312       vec_add2 (sort_me, sm, 1);
15313       sm->name = (u8 *)(p->key);
15314       sm->value = (u8 *) (p->value[0]);
15315     }));
15316     /* *INDENT-ON* */
15317
15318   vec_sort_with_function (sort_me, macro_sort_cmp);
15319
15320   if (vec_len (sort_me))
15321     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15322   else
15323     fformat (vam->ofp, "The macro table is empty...\n");
15324
15325   for (i = 0; i < vec_len (sort_me); i++)
15326     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15327   return 0;
15328 }
15329
15330 static int
15331 dump_node_table (vat_main_t * vam)
15332 {
15333   int i, j;
15334   vlib_node_t *node, *next_node;
15335
15336   if (vec_len (vam->graph_nodes) == 0)
15337     {
15338       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15339       return 0;
15340     }
15341
15342   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15343     {
15344       node = vam->graph_nodes[i];
15345       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15346       for (j = 0; j < vec_len (node->next_nodes); j++)
15347         {
15348           if (node->next_nodes[j] != ~0)
15349             {
15350               next_node = vam->graph_nodes[node->next_nodes[j]];
15351               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15352             }
15353         }
15354     }
15355   return 0;
15356 }
15357
15358 static int
15359 search_node_table (vat_main_t * vam)
15360 {
15361   unformat_input_t *line_input = vam->input;
15362   u8 *node_to_find;
15363   int j;
15364   vlib_node_t *node, *next_node;
15365   uword *p;
15366
15367   if (vam->graph_node_index_by_name == 0)
15368     {
15369       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15370       return 0;
15371     }
15372
15373   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15374     {
15375       if (unformat (line_input, "%s", &node_to_find))
15376         {
15377           vec_add1 (node_to_find, 0);
15378           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15379           if (p == 0)
15380             {
15381               fformat (vam->ofp, "%s not found...\n", node_to_find);
15382               goto out;
15383             }
15384           node = vam->graph_nodes[p[0]];
15385           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15386           for (j = 0; j < vec_len (node->next_nodes); j++)
15387             {
15388               if (node->next_nodes[j] != ~0)
15389                 {
15390                   next_node = vam->graph_nodes[node->next_nodes[j]];
15391                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15392                 }
15393             }
15394         }
15395
15396       else
15397         {
15398           clib_warning ("parse error '%U'", format_unformat_error,
15399                         line_input);
15400           return -99;
15401         }
15402
15403     out:
15404       vec_free (node_to_find);
15405
15406     }
15407
15408   return 0;
15409 }
15410
15411
15412 static int
15413 script (vat_main_t * vam)
15414 {
15415   u8 *s = 0;
15416   char *save_current_file;
15417   unformat_input_t save_input;
15418   jmp_buf save_jump_buf;
15419   u32 save_line_number;
15420
15421   FILE *new_fp, *save_ifp;
15422
15423   if (unformat (vam->input, "%s", &s))
15424     {
15425       new_fp = fopen ((char *) s, "r");
15426       if (new_fp == 0)
15427         {
15428           errmsg ("Couldn't open script file %s\n", s);
15429           vec_free (s);
15430           return -99;
15431         }
15432     }
15433   else
15434     {
15435       errmsg ("Missing script name\n");
15436       return -99;
15437     }
15438
15439   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15440   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15441   save_ifp = vam->ifp;
15442   save_line_number = vam->input_line_number;
15443   save_current_file = (char *) vam->current_file;
15444
15445   vam->input_line_number = 0;
15446   vam->ifp = new_fp;
15447   vam->current_file = s;
15448   do_one_file (vam);
15449
15450   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15451   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15452   vam->ifp = save_ifp;
15453   vam->input_line_number = save_line_number;
15454   vam->current_file = (u8 *) save_current_file;
15455   vec_free (s);
15456
15457   return 0;
15458 }
15459
15460 static int
15461 echo (vat_main_t * vam)
15462 {
15463   fformat (vam->ofp, "%v", vam->input->buffer);
15464   return 0;
15465 }
15466
15467 /* List of API message constructors, CLI names map to api_xxx */
15468 #define foreach_vpe_api_msg                                             \
15469 _(create_loopback,"[mac <mac-addr>]")                                   \
15470 _(sw_interface_dump,"")                                                 \
15471 _(sw_interface_set_flags,                                               \
15472   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15473 _(sw_interface_add_del_address,                                         \
15474   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15475 _(sw_interface_set_table,                                               \
15476   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15477 _(sw_interface_set_vpath,                                               \
15478   "<intfc> | sw_if_index <id> enable | disable")                        \
15479 _(sw_interface_set_l2_xconnect,                                         \
15480   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15481   "enable | disable")                                                   \
15482 _(sw_interface_set_l2_bridge,                                           \
15483   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15484   "[shg <split-horizon-group>] [bvi]\n"                                 \
15485   "enable | disable")                                                   \
15486 _(bridge_domain_add_del,                                                \
15487   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15488 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15489 _(l2fib_add_del,                                                        \
15490   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15491 _(l2_flags,                                                             \
15492   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15493 _(bridge_flags,                                                         \
15494   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15495 _(tap_connect,                                                          \
15496   "tapname <name> mac <mac-addr> | random-mac")                         \
15497 _(tap_modify,                                                           \
15498   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15499 _(tap_delete,                                                           \
15500   "<vpp-if-name> | sw_if_index <id>")                                   \
15501 _(sw_interface_tap_dump, "")                                            \
15502 _(ip_add_del_route,                                                     \
15503   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15504   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15505   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15506   "[multipath] [count <n>]")                                            \
15507 _(proxy_arp_add_del,                                                    \
15508   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15509 _(proxy_arp_intfc_enable_disable,                                       \
15510   "<intfc> | sw_if_index <id> enable | disable")                        \
15511 _(mpls_add_del_encap,                                                   \
15512   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15513 _(mpls_add_del_decap,                                                   \
15514   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15515 _(mpls_gre_add_del_tunnel,                                              \
15516   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15517   "adj <ip4-address>/<mask-width> [del]")                               \
15518 _(sw_interface_set_unnumbered,                                          \
15519   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15520 _(ip_neighbor_add_del,                                                  \
15521   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15522   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15523 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15524 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15525 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15526   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15527   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15528   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15529 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15530 _(reset_fib, "vrf <n> [ipv6]")                                          \
15531 _(dhcp_proxy_config,                                                    \
15532   "svr <v46-address> src <v46-address>\n"                               \
15533    "insert-cid <n> [del]")                                              \
15534 _(dhcp_proxy_config_2,                                                  \
15535   "svr <v46-address> src <v46-address>\n"                               \
15536    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15537 _(dhcp_proxy_set_vss,                                                   \
15538   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15539 _(dhcp_client_config,                                                   \
15540   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15541 _(set_ip_flow_hash,                                                     \
15542   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15543 _(sw_interface_ip6_enable_disable,                                      \
15544   "<intfc> | sw_if_index <id> enable | disable")                        \
15545 _(sw_interface_ip6_set_link_local_address,                              \
15546   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15547 _(sw_interface_ip6nd_ra_prefix,                                         \
15548   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15549   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15550   "[nolink] [isno]")                                                    \
15551 _(sw_interface_ip6nd_ra_config,                                         \
15552   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15553   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15554   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15555 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15556 _(l2_patch_add_del,                                                     \
15557   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15558   "enable | disable")                                                   \
15559 _(mpls_ethernet_add_del_tunnel,                                         \
15560   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15561   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15562 _(mpls_ethernet_add_del_tunnel_2,                                       \
15563   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15564   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15565 _(sr_tunnel_add_del,                                                    \
15566   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15567   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15568   "[policy <policy_name>]")                                             \
15569 _(sr_policy_add_del,                                                    \
15570   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15571 _(sr_multicast_map_add_del,                                             \
15572   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15573 _(classify_add_del_table,                                               \
15574   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15575   "[del] mask <mask-value>\n"                                           \
15576   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15577 _(classify_add_del_session,                                             \
15578   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15579   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15580   "  [l3 [ip4|ip6]]")                                                   \
15581 _(classify_set_interface_ip_table,                                      \
15582   "<intfc> | sw_if_index <nn> table <nn>")                              \
15583 _(classify_set_interface_l2_tables,                                     \
15584   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15585   "  [other-table <nn>]")                                               \
15586 _(get_node_index, "node <node-name")                                    \
15587 _(add_node_next, "node <node-name> next <next-node-name>")              \
15588 _(l2tpv3_create_tunnel,                                                 \
15589   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15590   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15591   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15592 _(l2tpv3_set_tunnel_cookies,                                            \
15593   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15594   "[new_remote_cookie <nn>]\n")                                         \
15595 _(l2tpv3_interface_enable_disable,                                      \
15596   "<intfc> | sw_if_index <nn> enable | disable")                        \
15597 _(l2tpv3_set_lookup_key,                                                \
15598   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15599 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15600 _(vxlan_add_del_tunnel,                                                 \
15601   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15602   " [decap-next l2|ip4|ip6] [del]")                                     \
15603 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15604 _(gre_add_del_tunnel,                                                   \
15605   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15606 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15607 _(l2_fib_clear_table, "")                                               \
15608 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15609 _(l2_interface_vlan_tag_rewrite,                                        \
15610   "<intfc> | sw_if_index <nn> \n"                                       \
15611   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15612   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15613 _(create_vhost_user_if,                                                 \
15614         "socket <filename> [server] [renumber <dev_instance>] "         \
15615         "[mac <mac_address>]")                                          \
15616 _(modify_vhost_user_if,                                                 \
15617         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15618         "[server] [renumber <dev_instance>]")                           \
15619 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15620 _(sw_interface_vhost_user_dump, "")                                     \
15621 _(show_version, "")                                                     \
15622 _(vxlan_gpe_add_del_tunnel,                                             \
15623   "local <addr> remote <addr> vni <nn>\n"                               \
15624     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15625   "[next-ethernet] [next-nsh]\n")                                       \
15626 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15627 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15628 _(interface_name_renumber,                                              \
15629   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15630 _(input_acl_set_interface,                                              \
15631   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15632   "  [l2-table <nn>] [del]")                                            \
15633 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15634 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15635 _(ip_dump, "ipv4 | ipv6")                                               \
15636 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15637 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15638   "  spid_id <n> ")                                                     \
15639 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15640   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15641   "  integ_alg <alg> integ_key <hex>")                                  \
15642 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15643   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15644   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15645   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15646 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15647 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15648 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15649   "(auth_data 0x<data> | auth_data <data>)")                            \
15650 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15651   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15652 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15653   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15654   "(local|remote)")                                                     \
15655 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15656 _(delete_loopback,"sw_if_index <nn>")                                   \
15657 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15658 _(map_add_domain,                                                       \
15659   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15660   "ip6-src <ip6addr> "                                                  \
15661   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15662 _(map_del_domain, "index <n>")                                          \
15663 _(map_add_del_rule,                                                     \
15664   "index <n> psid <n> dst <ip6addr> [del]")                             \
15665 _(map_domain_dump, "")                                                  \
15666 _(map_rule_dump, "index <map-domain>")                                  \
15667 _(want_interface_events,  "enable|disable")                             \
15668 _(want_stats,"enable|disable")                                          \
15669 _(get_first_msg_id, "client <name>")                                    \
15670 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15671 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15672   "fib-id <nn> [ip4][ip6][default]")                                    \
15673 _(get_node_graph, " ")                                                  \
15674 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15675 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15676   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15677   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15678 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15679   " vrf_id <nn>  add | pop | none")                                     \
15680 _(trace_profile_del, "")                                                \
15681 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15682                             " sw_if_index <sw_if_index> p <priority> "  \
15683                             "w <weight>] [del]")                        \
15684 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15685                         "iface <intf> | sw_if_index <sw_if_index> "     \
15686                         "p <priority> w <weight> [del]")                \
15687 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15688                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15689                           "locator-set <locator_name> [del]")           \
15690 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15691   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15692 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15693 _(lisp_gpe_enable_disable, "enable|disable")                            \
15694 _(lisp_enable_disable, "enable|disable")                                \
15695 _(lisp_gpe_add_del_iface, "up|down")                                    \
15696 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15697                                "rloc <locator> p <prio> "               \
15698                                "w <weight> [rloc <loc> ... ] "          \
15699                                "action <action> [del-all]")             \
15700 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15701                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15702                           "[rloc <loc> ... ] action <action>")          \
15703 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15704 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15705 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15706 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15707                          "locator-set <loc-set-name>] [local | remote]")\
15708 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15709                        "[local] | [remote]")                            \
15710 _(lisp_eid_table_map_dump, "")                                          \
15711 _(lisp_eid_table_vni_dump, "")                                          \
15712 _(lisp_gpe_tunnel_dump, "")                                             \
15713 _(lisp_map_resolver_dump, "")                                           \
15714 _(show_lisp_status, "")                                                 \
15715 _(lisp_get_map_request_itr_rlocs, "")                                   \
15716 _(show_lisp_pitr, "")                                                   \
15717 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15718 _(af_packet_delete, "name <host interface name>")                       \
15719 _(policer_add_del, "name <policer name> <params> [del]")                \
15720 _(policer_dump, "[name <policer name>]")                                \
15721 _(policer_classify_set_interface,                                       \
15722   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15723   "  [l2-table <nn>] [del]")                                            \
15724 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15725 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15726     "[master|slave]")                                                   \
15727 _(netmap_delete, "name <interface name>")                               \
15728 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15729 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15730 _(mpls_fib_encap_dump, "")                                              \
15731 _(mpls_fib_decap_dump, "")                                              \
15732 _(classify_table_ids, "")                                               \
15733 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15734 _(classify_table_info, "table_id <nn>")                                 \
15735 _(classify_session_dump, "table_id <nn>")                               \
15736 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15737                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15738                 "[template_interval <nn>]")                             \
15739 _(ipfix_dump, "")                                                       \
15740 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15741 _(pg_create_interface, "if_id <nn>")                                    \
15742 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15743 _(pg_enable_disable, "[stream <id>] disable")                           \
15744 _(ip_source_and_port_range_check_add_del,                               \
15745   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15746 _(ip_source_and_port_range_check_interface_add_del,                     \
15747   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15748   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15749 _(ipsec_gre_add_del_tunnel,                                             \
15750   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15751 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")
15752
15753 /* List of command functions, CLI names map directly to functions */
15754 #define foreach_cli_function                                    \
15755 _(comment, "usage: comment <ignore-rest-of-line>")              \
15756 _(dump_interface_table, "usage: dump_interface_table")          \
15757 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15758 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15759 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15760 _(dump_stats_table, "usage: dump_stats_table")                  \
15761 _(dump_macro_table, "usage: dump_macro_table ")                 \
15762 _(dump_node_table, "usage: dump_node_table")                    \
15763 _(echo, "usage: echo <message>")                                \
15764 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15765 _(help, "usage: help")                                          \
15766 _(q, "usage: quit")                                             \
15767 _(quit, "usage: quit")                                          \
15768 _(search_node_table, "usage: search_node_table <name>...")      \
15769 _(set, "usage: set <variable-name> <value>")                    \
15770 _(script, "usage: script <file-name>")                          \
15771 _(unset, "usage: unset <variable-name>")
15772
15773 #define _(N,n)                                  \
15774     static void vl_api_##n##_t_handler_uni      \
15775     (vl_api_##n##_t * mp)                       \
15776     {                                           \
15777         vat_main_t * vam = &vat_main;           \
15778         if (vam->json_output) {                 \
15779             vl_api_##n##_t_handler_json(mp);    \
15780         } else {                                \
15781             vl_api_##n##_t_handler(mp);         \
15782         }                                       \
15783     }
15784 foreach_vpe_api_reply_msg;
15785 #undef _
15786
15787 void
15788 vat_api_hookup (vat_main_t * vam)
15789 {
15790 #define _(N,n)                                                  \
15791     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15792                            vl_api_##n##_t_handler_uni,          \
15793                            vl_noop_handler,                     \
15794                            vl_api_##n##_t_endian,               \
15795                            vl_api_##n##_t_print,                \
15796                            sizeof(vl_api_##n##_t), 1);
15797   foreach_vpe_api_reply_msg;
15798 #undef _
15799
15800   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15801
15802   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15803
15804   vam->function_by_name = hash_create_string (0, sizeof (uword));
15805
15806   vam->help_by_name = hash_create_string (0, sizeof (uword));
15807
15808   /* API messages we can send */
15809 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15810   foreach_vpe_api_msg;
15811 #undef _
15812
15813   /* Help strings */
15814 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15815   foreach_vpe_api_msg;
15816 #undef _
15817
15818   /* CLI functions */
15819 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15820   foreach_cli_function;
15821 #undef _
15822
15823   /* Help strings */
15824 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15825   foreach_cli_function;
15826 #undef _
15827 }
15828
15829 #undef vl_api_version
15830 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15831 #include <vpp-api/vpe.api.h>
15832 #undef vl_api_version
15833
15834 void
15835 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15836 {
15837   /*
15838    * Send the main API signature in slot 0. This bit of code must
15839    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15840    */
15841   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15842 }
15843
15844 /*
15845  * fd.io coding-style-patch-verification: ON
15846  *
15847  * Local Variables:
15848  * eval: (c-set-style "gnu")
15849  * End:
15850  */