Edit eid table dump
[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/policer/xlate.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <sys/stat.h>
55
56 #define vl_typedefs             /* define message structures */
57 #include <vpp-api/vpe_all_api_h.h>
58 #undef vl_typedefs
59
60 /* declare message handlers for each api */
61
62 #define vl_endianfun             /* define message structures */
63 #include <vpp-api/vpe_all_api_h.h>
64 #undef vl_endianfun
65
66 /* instantiate all the print functions we know about */
67 #define vl_print(handle, ...)
68 #define vl_printfun
69 #include <vpp-api/vpe_all_api_h.h>
70 #undef vl_printfun
71
72 uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
73 {
74   vat_main_t * vam = va_arg (*args, vat_main_t *);
75   u32 * result = va_arg (*args, u32 *);
76   u8 * if_name;
77   uword * p;
78
79   if (!unformat (input, "%s", &if_name))
80       return 0;
81
82   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
83   if (p == 0)
84       return 0;
85   *result = p[0];
86   return 1;
87 }
88
89 /* Parse an IP4 address %d.%d.%d.%d. */
90 uword unformat_ip4_address (unformat_input_t * input, va_list * args)
91 {
92   u8 * result = va_arg (*args, u8 *);
93   unsigned a[4];
94
95   if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
96     return 0;
97
98   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
99     return 0;
100
101   result[0] = a[0];
102   result[1] = a[1];
103   result[2] = a[2];
104   result[3] = a[3];
105
106   return 1;
107 }
108
109
110 uword
111 unformat_ethernet_address (unformat_input_t * input, va_list * args)
112 {
113   u8 * result = va_arg (*args, u8 *);
114   u32 i, a[6];
115
116   if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
117                   &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
118     return 0;
119
120   /* Check range. */
121   for (i = 0; i < 6; i++)
122     if (a[i] >= (1 << 8))
123       return 0;
124
125   for (i = 0; i < 6; i++)
126     result[i] = a[i];
127
128   return 1;
129 }
130
131 /* Returns ethernet type as an int in host byte order. */
132 uword
133 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
134                                         va_list * args)
135 {
136   u16 * result = va_arg (*args, u16 *);
137   int type;
138
139   /* Numeric type. */
140   if (unformat (input, "0x%x", &type)
141       || unformat (input, "%d", &type))
142     {
143       if (type >= (1 << 16))
144         return 0;
145       *result = type;
146       return 1;
147     }
148   return 0;
149 }
150
151 /* Parse an IP6 address. */
152 uword unformat_ip6_address (unformat_input_t * input, va_list * args)
153 {
154   ip6_address_t * result = va_arg (*args, ip6_address_t *);
155   u16 hex_quads[8];
156   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
157   uword c, n_colon, double_colon_index;
158
159   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
160   double_colon_index = ARRAY_LEN (hex_quads);
161   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
162     {
163       hex_digit = 16;
164       if (c >= '0' && c <= '9')
165         hex_digit = c - '0';
166       else if (c >= 'a' && c <= 'f')
167         hex_digit = c + 10 - 'a';
168       else if (c >= 'A' && c <= 'F')
169         hex_digit = c + 10 - 'A';
170       else if (c == ':' && n_colon < 2)
171         n_colon++;
172       else
173         {
174           unformat_put_input (input);
175           break;
176         }
177
178       /* Too many hex quads. */
179       if (n_hex_quads >= ARRAY_LEN (hex_quads))
180         return 0;
181
182       if (hex_digit < 16)
183         {
184           hex_quad = (hex_quad << 4) | hex_digit;
185
186           /* Hex quad must fit in 16 bits. */
187           if (n_hex_digits >= 4)
188             return 0;
189
190           n_colon = 0;
191           n_hex_digits++;
192         }
193
194       /* Save position of :: */
195       if (n_colon == 2)
196         {
197           /* More than one :: ? */
198           if (double_colon_index < ARRAY_LEN (hex_quads))
199             return 0;
200           double_colon_index = n_hex_quads;
201         }
202
203       if (n_colon > 0 && n_hex_digits > 0)
204         {
205           hex_quads[n_hex_quads++] = hex_quad;
206           hex_quad = 0;
207           n_hex_digits = 0;
208         }
209     }
210
211   if (n_hex_digits > 0)
212     hex_quads[n_hex_quads++] = hex_quad;
213
214   {
215     word i;
216
217     /* Expand :: to appropriate number of zero hex quads. */
218     if (double_colon_index < ARRAY_LEN (hex_quads))
219       {
220         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
221
222         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
223           hex_quads[n_zero + i] = hex_quads[i];
224
225         for (i = 0; i < n_zero; i++)
226           hex_quads[double_colon_index + i] = 0;
227
228         n_hex_quads = ARRAY_LEN (hex_quads);
229       }
230
231     /* Too few hex quads given. */
232     if (n_hex_quads < ARRAY_LEN (hex_quads))
233       return 0;
234
235     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
236       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
237
238     return 1;
239   }
240 }
241
242 uword
243 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
244 {
245 #if DPDK > 0
246   u32 * r = va_arg (*args, u32 *);
247
248   if (0) ;
249 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
250   foreach_ipsec_policy_action
251 #undef _
252   else
253     return 0;
254   return 1;
255 #else
256   return 0;
257 #endif
258 }
259
260 uword
261 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
262 {
263 #if DPDK > 0
264   u32 * r = va_arg (*args, u32 *);
265
266   if (0) ;
267 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
268   foreach_ipsec_crypto_alg
269 #undef _
270   else
271     return 0;
272   return 1;
273 #else
274   return 0;
275 #endif
276 }
277
278 u8 *
279 format_ipsec_crypto_alg (u8 * s, va_list * args)
280 {
281 #if DPDK > 0
282   u32 i = va_arg (*args, u32);
283   u8 * t = 0;
284
285   switch (i)
286     {
287 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
288   foreach_ipsec_crypto_alg
289 #undef _
290       default:
291         return format (s, "unknown");
292     }
293   return format (s, "%s", t);
294 #else
295   return format (s, "Unimplemented");
296 #endif
297 }
298
299 uword
300 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
301 {
302 #if DPDK > 0
303   u32 * r = va_arg (*args, u32 *);
304
305   if (0) ;
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
307   foreach_ipsec_integ_alg
308 #undef _
309   else
310     return 0;
311   return 1;
312 #else
313   return 0;
314 #endif
315 }
316
317 u8 *
318 format_ipsec_integ_alg (u8 * s, va_list * args)
319 {
320 #if DPDK > 0
321   u32 i = va_arg (*args, u32);
322   u8 * t = 0;
323
324   switch (i)
325     {
326 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
327   foreach_ipsec_integ_alg
328 #undef _
329       default:
330         return format (s, "unknown");
331     }
332   return format (s, "%s", t);
333 #else
334   return format (s, "Unsupported");
335 #endif
336 }
337
338 uword
339 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
340 {
341 #if DPDK > 0
342   u32 * r = va_arg (*args, u32 *);
343
344   if (0) ;
345 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
346   foreach_ikev2_auth_method
347 #undef _
348   else
349     return 0;
350   return 1;
351 #else
352   return 0;
353 #endif
354 }
355
356 uword
357 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
358 {
359 #if DPDK > 0
360   u32 * r = va_arg (*args, u32 *);
361
362   if (0) ;
363 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
364   foreach_ikev2_id_type
365 #undef _
366   else
367     return 0;
368   return 1;
369 #else
370   return 0;
371 #endif
372 }
373
374 uword
375 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
376 {
377   u8 * r = va_arg (*args, u8 *);
378
379   if (unformat (input, "kbps"))
380     *r = SSE2_QOS_RATE_KBPS;
381   else if (unformat(input, "pps"))
382     *r = SSE2_QOS_RATE_PPS;
383   else
384     return 0;
385   return 1;
386 }
387
388 uword
389 unformat_policer_round_type (unformat_input_t * input, va_list * args)
390 {
391   u8 * r = va_arg (*args, u8 *);
392
393   if (unformat(input, "closest"))
394     *r = SSE2_QOS_ROUND_TO_CLOSEST;
395   else if (unformat (input, "up"))
396     *r = SSE2_QOS_ROUND_TO_UP;
397   else if (unformat (input, "down"))
398     *r = SSE2_QOS_ROUND_TO_DOWN;
399   else
400     return 0;
401   return 1;
402 }
403
404 uword
405 unformat_policer_type (unformat_input_t * input, va_list * args)
406 {
407   u8 * r = va_arg (*args, u8 *);
408
409   if (unformat (input, "1r2c"))
410     *r = SSE2_QOS_POLICER_TYPE_1R2C;
411   else if (unformat (input, "1r3c"))
412     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
413   else if (unformat (input, "2r3c-2698"))
414     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
415   else if (unformat (input, "2r3c-4115"))
416     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
417   else if (unformat (input, "2r3c-mef5cf1"))
418     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
419   else
420     return 0;
421   return 1;
422 }
423
424 uword
425 unformat_dscp (unformat_input_t * input, va_list * va)
426 {
427   u8 * r = va_arg (*va, u8 *);
428
429   if (0) ;
430 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
431       foreach_vnet_dscp
432 #undef _
433   else
434     return 0;
435   return 1;
436 }
437
438 uword
439 unformat_policer_action_type (unformat_input_t * input, va_list * va)
440 {
441   sse2_qos_pol_action_params_st * a
442     = va_arg (*va, sse2_qos_pol_action_params_st *);
443
444   if (unformat (input, "drop"))
445     a->action_type = SSE2_QOS_ACTION_DROP;
446   else if (unformat (input, "transmit"))
447     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
448   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
449     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
450   else
451     return 0;
452   return 1;
453 }
454
455 uword
456 unformat_classify_table_type (unformat_input_t * input, va_list * va)
457 {
458   u32 * r = va_arg (*va, u32 *);
459   u32 tid;
460
461   if (unformat (input, "ip4"))
462     tid = POLICER_CLASSIFY_TABLE_IP4;
463   else if (unformat (input, "ip6"))
464     tid = POLICER_CLASSIFY_TABLE_IP6;
465   else if (unformat (input, "l2"))
466     tid = POLICER_CLASSIFY_TABLE_L2;
467   else
468     return 0;
469
470   *r = tid;
471   return 1;
472 }
473
474 u8 * format_ip4_address (u8 * s, va_list * args)
475 {
476   u8 * a = va_arg (*args, u8 *);
477   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
478 }
479
480 u8 * format_ip6_address (u8 * s, va_list * args)
481 {
482     ip6_address_t * a = va_arg (*args, ip6_address_t *);
483     u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
484
485     i_max_n_zero = ARRAY_LEN (a->as_u16);
486     max_n_zeros = 0;
487     i_first_zero = i_max_n_zero;
488     n_zeros = 0;
489     for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
490       {
491         u32 is_zero = a->as_u16[i] == 0;
492         if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
493           {
494             i_first_zero = i;
495             n_zeros = 0;
496           }
497         n_zeros += is_zero;
498         if ((! is_zero && n_zeros > max_n_zeros)
499             || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
500           {
501             i_max_n_zero = i_first_zero;
502             max_n_zeros = n_zeros;
503             i_first_zero = ARRAY_LEN (a->as_u16);
504             n_zeros = 0;
505           }
506       }
507
508     last_double_colon = 0;
509     for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
510       {
511         if (i == i_max_n_zero && max_n_zeros > 1)
512           {
513             s = format (s, "::");
514             i += max_n_zeros - 1;
515             last_double_colon = 1;
516           }
517         else
518           {
519             s = format (s, "%s%x",
520                         (last_double_colon || i == 0) ? "" : ":",
521                         clib_net_to_host_u16 (a->as_u16[i]));
522             last_double_colon = 0;
523           }
524       }
525
526     return s;
527 }
528
529 /* Format an IP46 address. */
530 u8 * format_ip46_address (u8 * s, va_list * args)
531 {
532   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
533   ip46_type_t type = va_arg (*args, ip46_type_t);
534   int is_ip4 = 1;
535
536   switch (type)
537     {
538       case IP46_TYPE_ANY:
539        is_ip4 = ip46_address_is_ip4(ip46);
540        break;
541       case IP46_TYPE_IP4:
542        is_ip4 = 1;
543        break;
544       case IP46_TYPE_IP6:
545        is_ip4 = 0;
546        break;
547     }
548
549   return is_ip4 ?
550       format(s, "%U", format_ip4_address, &ip46->ip4):
551       format(s, "%U", format_ip6_address, &ip46->ip6);
552 }
553
554 u8 * format_ethernet_address (u8 * s, va_list * args)
555 {
556   u8 * a = va_arg (*args, u8 *);
557
558   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
559                  a[0], a[1], a[2], a[3], a[4], a[5]);
560 }
561
562 void increment_v4_address (ip4_address_t * a)
563 {
564     u32 v;
565
566     v = ntohl(a->as_u32) + 1;
567     a->as_u32 = ntohl(v);
568 }
569
570 void increment_v6_address (ip6_address_t * a)
571 {
572     u64 v0, v1;
573
574     v0 = clib_net_to_host_u64 (a->as_u64[0]);
575     v1 = clib_net_to_host_u64 (a->as_u64[1]);
576
577     v1 += 1;
578     if (v1 == 0)
579         v0 += 1;
580     a->as_u64[0] = clib_net_to_host_u64 (v0);
581     a->as_u64[1] = clib_net_to_host_u64 (v1);
582 }
583
584 void increment_mac_address (u64 *mac)
585 {
586     u64 tmp = *mac;
587
588     tmp = clib_net_to_host_u64(tmp);
589     tmp += 1<<16; /* skip unused (least significant) octets */
590     tmp = clib_host_to_net_u64 (tmp);
591     *mac = tmp;
592 }
593
594 static void vl_api_create_loopback_reply_t_handler
595 (vl_api_create_loopback_reply_t * mp)
596 {
597     vat_main_t * vam = &vat_main;
598     i32 retval = ntohl(mp->retval);
599
600     vam->retval = retval;
601     vam->regenerate_interface_table = 1;
602     vam->sw_if_index = ntohl (mp->sw_if_index);
603     vam->result_ready = 1;
604 }
605
606 static void vl_api_create_loopback_reply_t_handler_json
607 (vl_api_create_loopback_reply_t * mp)
608 {
609     vat_main_t * vam = &vat_main;
610     vat_json_node_t node;
611
612     vat_json_init_object(&node);
613     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
614     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
615
616     vat_json_print(vam->ofp, &node);
617     vat_json_free(&node);
618     vam->retval = ntohl(mp->retval);
619     vam->result_ready = 1;
620 }
621
622 static void vl_api_af_packet_create_reply_t_handler
623 (vl_api_af_packet_create_reply_t * mp)
624 {
625     vat_main_t * vam = &vat_main;
626     i32 retval = ntohl(mp->retval);
627
628     vam->retval = retval;
629     vam->regenerate_interface_table = 1;
630     vam->sw_if_index = ntohl (mp->sw_if_index);
631     vam->result_ready = 1;
632 }
633
634 static void vl_api_af_packet_create_reply_t_handler_json
635 (vl_api_af_packet_create_reply_t * mp)
636 {
637     vat_main_t * vam = &vat_main;
638     vat_json_node_t node;
639
640     vat_json_init_object(&node);
641     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
642     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
643
644     vat_json_print(vam->ofp, &node);
645     vat_json_free(&node);
646
647     vam->retval = ntohl(mp->retval);
648     vam->result_ready = 1;
649 }
650
651 static void vl_api_create_vlan_subif_reply_t_handler
652 (vl_api_create_vlan_subif_reply_t * mp)
653 {
654     vat_main_t * vam = &vat_main;
655     i32 retval = ntohl(mp->retval);
656
657     vam->retval = retval;
658     vam->regenerate_interface_table = 1;
659     vam->sw_if_index = ntohl (mp->sw_if_index);
660     vam->result_ready = 1;
661 }
662
663 static void vl_api_create_vlan_subif_reply_t_handler_json
664 (vl_api_create_vlan_subif_reply_t * mp)
665 {
666     vat_main_t * vam = &vat_main;
667     vat_json_node_t node;
668
669     vat_json_init_object(&node);
670     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
671     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
672
673     vat_json_print(vam->ofp, &node);
674     vat_json_free(&node);
675
676     vam->retval = ntohl(mp->retval);
677     vam->result_ready = 1;
678 }
679
680 static void vl_api_create_subif_reply_t_handler
681 (vl_api_create_subif_reply_t * mp)
682 {
683     vat_main_t * vam = &vat_main;
684     i32 retval = ntohl(mp->retval);
685
686     vam->retval = retval;
687     vam->regenerate_interface_table = 1;
688     vam->sw_if_index = ntohl (mp->sw_if_index);
689     vam->result_ready = 1;
690 }
691
692 static void vl_api_create_subif_reply_t_handler_json
693 (vl_api_create_subif_reply_t * mp)
694 {
695     vat_main_t * vam = &vat_main;
696     vat_json_node_t node;
697
698     vat_json_init_object(&node);
699     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
700     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
701
702     vat_json_print(vam->ofp, &node);
703     vat_json_free(&node);
704
705     vam->retval = ntohl(mp->retval);
706     vam->result_ready = 1;
707 }
708
709 static void vl_api_interface_name_renumber_reply_t_handler
710 (vl_api_interface_name_renumber_reply_t * mp)
711 {
712     vat_main_t * vam = &vat_main;
713     i32 retval = ntohl(mp->retval);
714
715     vam->retval = retval;
716     vam->regenerate_interface_table = 1;
717     vam->result_ready = 1;
718 }
719
720 static void vl_api_interface_name_renumber_reply_t_handler_json
721 (vl_api_interface_name_renumber_reply_t * mp)
722 {
723     vat_main_t * vam = &vat_main;
724     vat_json_node_t node;
725
726     vat_json_init_object(&node);
727     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
728
729     vat_json_print(vam->ofp, &node);
730     vat_json_free(&node);
731
732     vam->retval = ntohl(mp->retval);
733     vam->result_ready = 1;
734 }
735
736 /*
737  * Special-case: build the interface table, maintain
738  * the next loopback sw_if_index vbl.
739  */
740 static void vl_api_sw_interface_details_t_handler
741 (vl_api_sw_interface_details_t * mp)
742 {
743     vat_main_t * vam = &vat_main;
744     u8 * s = format (0, "%s%c", mp->interface_name, 0);
745
746     hash_set_mem (vam->sw_if_index_by_interface_name, s,
747                   ntohl(mp->sw_if_index));
748
749     /* In sub interface case, fill the sub interface table entry */
750     if (mp->sw_if_index != mp->sup_sw_if_index) {
751         sw_interface_subif_t * sub = NULL;
752
753         vec_add2(vam->sw_if_subif_table, sub, 1);
754
755         vec_validate(sub->interface_name, strlen((char *)s) + 1);
756         strncpy((char *)sub->interface_name, (char *)s,
757                 vec_len(sub->interface_name));
758         sub->sw_if_index = ntohl(mp->sw_if_index);
759         sub->sub_id = ntohl(mp->sub_id);
760
761         sub->sub_dot1ad = mp->sub_dot1ad;
762         sub->sub_number_of_tags = mp->sub_number_of_tags;
763         sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
764         sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
765         sub->sub_exact_match = mp->sub_exact_match;
766         sub->sub_default = mp->sub_default;
767         sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768         sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770         /* vlan tag rewrite */
771         sub->vtr_op = ntohl(mp->vtr_op);
772         sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
773         sub->vtr_tag1 = ntohl(mp->vtr_tag1);
774         sub->vtr_tag2 = ntohl(mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779 (vl_api_sw_interface_details_t * mp)
780 {
781     vat_main_t * vam = &vat_main;
782     vat_json_node_t *node = NULL;
783
784     if (VAT_JSON_ARRAY != vam->json_tree.type) {
785         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
786         vat_json_init_array(&vam->json_tree);
787     }
788     node = vat_json_array_add(&vam->json_tree);
789
790     vat_json_init_object(node);
791     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
792     vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
793     vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
794     vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
795     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
796     vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
797     vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
798     vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
799     vat_json_object_add_uint(node, "link_speed", mp->link_speed);
800     vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
801     vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
802     vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
803     vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
804     vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
805     vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
806     vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
807     vat_json_object_add_uint(node, "sub_default", mp->sub_default);
808     vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
809     vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
810     vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
811     vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
812     vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
813     vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
814 }
815
816 static void vl_api_sw_interface_set_flags_t_handler
817 (vl_api_sw_interface_set_flags_t * mp)
818 {
819     vat_main_t * vam = &vat_main;
820     if (vam->interface_event_display)
821         errmsg ("interface flags: sw_if_index %d %s %s\n",
822                 ntohl(mp->sw_if_index),
823                 mp->admin_up_down ? "admin-up" : "admin-down",
824                 mp->link_up_down  ? "link-up"  : "link-down");
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler_json
828 (vl_api_sw_interface_set_flags_t * mp)
829 {
830     /* JSON output not supported */
831 }
832
833 static void vl_api_cli_reply_t_handler
834 (vl_api_cli_reply_t * mp)
835 {
836     vat_main_t * vam = &vat_main;
837     i32 retval = ntohl(mp->retval);
838
839     vam->retval = retval;
840     vam->shmem_result = (u8 *) mp->reply_in_shmem;
841     vam->result_ready = 1;
842 }
843
844 static void vl_api_cli_reply_t_handler_json
845 (vl_api_cli_reply_t * mp)
846 {
847     vat_main_t * vam = &vat_main;
848     vat_json_node_t node;
849     api_main_t * am = &api_main;
850     void * oldheap;
851     u8 * reply;
852
853     vat_json_init_object(&node);
854     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
855     vat_json_object_add_uint(&node, "reply_in_shmem",
856                              ntohl(mp->reply_in_shmem));
857     /* Toss the shared-memory original... */
858     pthread_mutex_lock (&am->vlib_rp->mutex);
859     oldheap = svm_push_data_heap (am->vlib_rp);
860
861     reply = (u8 *)(mp->reply_in_shmem);
862     vec_free (reply);
863
864     svm_pop_heap (oldheap);
865     pthread_mutex_unlock (&am->vlib_rp->mutex);
866
867     vat_json_print(vam->ofp, &node);
868     vat_json_free(&node);
869
870     vam->retval = ntohl(mp->retval);
871     vam->result_ready = 1;
872 }
873
874 static void vl_api_classify_add_del_table_reply_t_handler
875 (vl_api_classify_add_del_table_reply_t * mp)
876 {
877     vat_main_t * vam = &vat_main;
878     i32 retval = ntohl(mp->retval);
879     if (vam->async_mode) {
880         vam->async_errors += (retval < 0);
881     } else {
882         vam->retval = retval;
883         if (retval == 0 &&
884             ((mp->new_table_index != 0xFFFFFFFF) ||
885              (mp->skip_n_vectors != 0xFFFFFFFF) ||
886              (mp->match_n_vectors != 0xFFFFFFFF)))
887             /*
888              * Note: this is just barely thread-safe, depends on
889              * the main thread spinning waiting for an answer...
890              */
891             errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
892                     ntohl(mp->new_table_index),
893                     ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
894         vam->result_ready = 1;
895     }
896 }
897
898 static void vl_api_classify_add_del_table_reply_t_handler_json
899 (vl_api_classify_add_del_table_reply_t * mp)
900 {
901     vat_main_t * vam = &vat_main;
902     vat_json_node_t node;
903
904     vat_json_init_object(&node);
905     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
906     vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
907     vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
908     vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
909
910     vat_json_print(vam->ofp, &node);
911     vat_json_free(&node);
912
913     vam->retval = ntohl(mp->retval);
914     vam->result_ready = 1;
915 }
916
917 static void vl_api_get_node_index_reply_t_handler
918 (vl_api_get_node_index_reply_t * mp)
919 {
920     vat_main_t * vam = &vat_main;
921     i32 retval = ntohl(mp->retval);
922     if (vam->async_mode) {
923         vam->async_errors += (retval < 0);
924     } else {
925         vam->retval = retval;
926         if (retval == 0)
927             errmsg ("node index %d\n", ntohl(mp->node_index));
928         vam->result_ready = 1;
929     }
930 }
931
932 static void vl_api_get_node_index_reply_t_handler_json
933 (vl_api_get_node_index_reply_t * mp)
934 {
935     vat_main_t * vam = &vat_main;
936     vat_json_node_t node;
937
938     vat_json_init_object(&node);
939     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
940     vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
941
942     vat_json_print(vam->ofp, &node);
943     vat_json_free(&node);
944
945     vam->retval = ntohl(mp->retval);
946     vam->result_ready = 1;
947 }
948
949 static void vl_api_get_next_index_reply_t_handler
950 (vl_api_get_next_index_reply_t * mp)
951 {
952     vat_main_t * vam = &vat_main;
953     i32 retval = ntohl(mp->retval);
954     if (vam->async_mode) {
955         vam->async_errors += (retval < 0);
956     } else {
957         vam->retval = retval;
958         if (retval == 0)
959             errmsg ("next node index %d\n", ntohl(mp->next_index));
960         vam->result_ready = 1;
961     }
962 }
963
964 static void vl_api_get_next_index_reply_t_handler_json
965 (vl_api_get_next_index_reply_t * mp)
966 {
967     vat_main_t * vam = &vat_main;
968     vat_json_node_t node;
969
970     vat_json_init_object(&node);
971     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
972     vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
973
974     vat_json_print(vam->ofp, &node);
975     vat_json_free(&node);
976
977     vam->retval = ntohl(mp->retval);
978     vam->result_ready = 1;
979 }
980
981 static void vl_api_add_node_next_reply_t_handler
982 (vl_api_add_node_next_reply_t * mp)
983 {
984     vat_main_t * vam = &vat_main;
985     i32 retval = ntohl(mp->retval);
986     if (vam->async_mode) {
987         vam->async_errors += (retval < 0);
988     } else {
989         vam->retval = retval;
990         if (retval == 0)
991             errmsg ("next index %d\n", ntohl(mp->next_index));
992         vam->result_ready = 1;
993     }
994 }
995
996 static void vl_api_add_node_next_reply_t_handler_json
997 (vl_api_add_node_next_reply_t * mp)
998 {
999     vat_main_t * vam = &vat_main;
1000     vat_json_node_t node;
1001
1002     vat_json_init_object(&node);
1003     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1004     vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
1005
1006     vat_json_print(vam->ofp, &node);
1007     vat_json_free(&node);
1008
1009     vam->retval = ntohl(mp->retval);
1010     vam->result_ready = 1;
1011 }
1012
1013 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1014 (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1015 {
1016     vat_main_t * vam = &vat_main;
1017     i32 retval = ntohl(mp->retval);
1018     u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
1019
1020     if (retval >= 0 && sw_if_index != (u32)~0) {
1021         errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1022     }
1023     vam->retval = retval;
1024     vam->result_ready = 1;
1025 }
1026
1027 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1028 (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1029 {
1030     vat_main_t * vam = &vat_main;
1031     vat_json_node_t node;
1032
1033     vat_json_init_object(&node);
1034     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1035     vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1036
1037     vat_json_print(vam->ofp, &node);
1038     vat_json_free(&node);
1039
1040     vam->retval = ntohl(mp->retval);
1041     vam->result_ready = 1;
1042 }
1043
1044
1045 static void vl_api_show_version_reply_t_handler
1046 (vl_api_show_version_reply_t * mp)
1047 {
1048     vat_main_t * vam = &vat_main;
1049     i32 retval = ntohl(mp->retval);
1050
1051     if (retval >= 0) {
1052         errmsg ("        program: %s\n", mp->program);
1053         errmsg ("        version: %s\n", mp->version);
1054         errmsg ("     build date: %s\n", mp->build_date);
1055         errmsg ("build directory: %s\n", mp->build_directory);
1056     }
1057     vam->retval = retval;
1058     vam->result_ready = 1;
1059 }
1060
1061 static void vl_api_show_version_reply_t_handler_json
1062 (vl_api_show_version_reply_t * mp)
1063 {
1064     vat_main_t * vam = &vat_main;
1065     vat_json_node_t node;
1066
1067     vat_json_init_object(&node);
1068     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1069     vat_json_object_add_string_copy(&node, "program", mp->program);
1070     vat_json_object_add_string_copy(&node, "version", mp->version);
1071     vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
1072     vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
1073
1074     vat_json_print(vam->ofp, &node);
1075     vat_json_free(&node);
1076
1077     vam->retval = ntohl(mp->retval);
1078     vam->result_ready = 1;
1079 }
1080
1081 static void vl_api_ip4_arp_event_t_handler
1082 (vl_api_ip4_arp_event_t * mp)
1083 {
1084     vat_main_t * vam = &vat_main;
1085     errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1086             format_ip4_address, &mp->address,
1087             format_ethernet_address, mp->new_mac, mp->sw_if_index);
1088 }
1089
1090 static void vl_api_ip4_arp_event_t_handler_json
1091 (vl_api_ip4_arp_event_t * mp)
1092 {
1093     /* JSON output not supported */
1094 }
1095
1096 /*
1097  * Special-case: build the bridge domain table, maintain
1098  * the next bd id vbl.
1099  */
1100 static void vl_api_bridge_domain_details_t_handler
1101 (vl_api_bridge_domain_details_t * mp)
1102 {
1103     vat_main_t * vam = &vat_main;
1104     u32 n_sw_ifs =  ntohl (mp->n_sw_ifs);
1105
1106     fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1107              " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1108
1109     fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1110              ntohl (mp->bd_id), mp->learn, mp->forward,
1111              mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1112
1113     if (n_sw_ifs)
1114         fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1115                  "Interface Name");
1116 }
1117
1118 static void vl_api_bridge_domain_details_t_handler_json
1119 (vl_api_bridge_domain_details_t * mp)
1120 {
1121     vat_main_t * vam = &vat_main;
1122     vat_json_node_t *node, *array = NULL;
1123
1124     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1125         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1126         vat_json_init_array(&vam->json_tree);
1127     }
1128     node = vat_json_array_add(&vam->json_tree);
1129
1130     vat_json_init_object(node);
1131     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1132     vat_json_object_add_uint(node, "flood", mp->flood);
1133     vat_json_object_add_uint(node, "forward", mp->forward);
1134     vat_json_object_add_uint(node, "learn", mp->learn);
1135     vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1136     vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1137     array = vat_json_object_add(node, "sw_if");
1138     vat_json_init_array(array);
1139 }
1140
1141 /*
1142  * Special-case: build the bridge domain sw if table.
1143  */
1144 static void vl_api_bridge_domain_sw_if_details_t_handler
1145 (vl_api_bridge_domain_sw_if_details_t * mp)
1146 {
1147     vat_main_t * vam = &vat_main;
1148     hash_pair_t * p;
1149     u8 * sw_if_name = 0;
1150     u32 sw_if_index;
1151
1152     sw_if_index = ntohl (mp->sw_if_index);
1153     hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1154     ({
1155         if ((u32) p->value[0] == sw_if_index) {
1156             sw_if_name = (u8 *)(p->key);
1157             break;
1158         }
1159     }));
1160
1161     fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1162              mp->shg, sw_if_name ? (char *)sw_if_name :
1163              "sw_if_index not found!");
1164 }
1165
1166 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1167 (vl_api_bridge_domain_sw_if_details_t * mp)
1168 {
1169     vat_main_t * vam = &vat_main;
1170     vat_json_node_t *node = NULL;
1171     uword last_index = 0;
1172
1173     ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1174     ASSERT(vec_len(vam->json_tree.array) >= 1);
1175     last_index = vec_len(vam->json_tree.array) - 1;
1176     node = &vam->json_tree.array[last_index];
1177     node = vat_json_object_get_element(node, "sw_if");
1178     ASSERT(NULL != node);
1179     node = vat_json_array_add(node);
1180
1181     vat_json_init_object(node);
1182     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1183     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1184     vat_json_object_add_uint(node, "shg", mp->shg);
1185 }
1186
1187 static void vl_api_control_ping_reply_t_handler
1188 (vl_api_control_ping_reply_t * mp)
1189 {
1190     vat_main_t * vam = &vat_main;
1191     i32 retval = ntohl(mp->retval);
1192     if (vam->async_mode) {
1193         vam->async_errors += (retval < 0);
1194     } else {
1195         vam->retval = retval;
1196         vam->result_ready = 1;
1197     }
1198 }
1199
1200 static void vl_api_control_ping_reply_t_handler_json
1201 (vl_api_control_ping_reply_t * mp)
1202 {
1203     vat_main_t * vam = &vat_main;
1204     i32 retval = ntohl(mp->retval);
1205
1206     if (VAT_JSON_NONE != vam->json_tree.type) {
1207         vat_json_print(vam->ofp, &vam->json_tree);
1208         vat_json_free(&vam->json_tree);
1209         vam->json_tree.type = VAT_JSON_NONE;
1210     } else {
1211         /* just print [] */
1212         vat_json_init_array(&vam->json_tree);
1213         vat_json_print(vam->ofp, &vam->json_tree);
1214         vam->json_tree.type = VAT_JSON_NONE;
1215     }
1216
1217     vam->retval = retval;
1218     vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_noprint_control_ping_reply_t_handler
1222 (vl_api_noprint_control_ping_reply_t * mp)
1223 {
1224     vat_main_t * vam = &vat_main;
1225     i32 retval = ntohl(mp->retval);
1226     if (vam->async_mode) {
1227         vam->async_errors += (retval < 0);
1228     } else {
1229         vam->retval = retval;
1230         vam->result_ready = 1;
1231     }
1232 }
1233
1234 static void vl_api_noprint_control_ping_reply_t_handler_json
1235 (vl_api_noprint_control_ping_reply_t * mp)
1236 {
1237     vat_main_t * vam = &vat_main;
1238     i32 retval = ntohl(mp->retval);
1239
1240     if (vam->noprint_msg) {
1241       vam->retval = retval;
1242       vam->result_ready = 1;
1243       return;
1244     }
1245
1246     if (VAT_JSON_NONE != vam->json_tree.type) {
1247         vat_json_print(vam->ofp, &vam->json_tree);
1248         vat_json_free(&vam->json_tree);
1249         vam->json_tree.type = VAT_JSON_NONE;
1250     } else {
1251         /* just print [] */
1252         vat_json_init_array(&vam->json_tree);
1253         vat_json_print(vam->ofp, &vam->json_tree);
1254         vam->json_tree.type = VAT_JSON_NONE;
1255     }
1256
1257     vam->retval = retval;
1258     vam->result_ready = 1;
1259 }
1260
1261 static void vl_api_l2_flags_reply_t_handler
1262 (vl_api_l2_flags_reply_t * mp)
1263 {
1264     vat_main_t * vam = &vat_main;
1265     i32 retval = ntohl(mp->retval);
1266     if (vam->async_mode) {
1267         vam->async_errors += (retval < 0);
1268     } else {
1269         vam->retval = retval;
1270         vam->result_ready = 1;
1271     }
1272 }
1273
1274 static void vl_api_l2_flags_reply_t_handler_json
1275 (vl_api_l2_flags_reply_t * mp)
1276 {
1277     vat_main_t * vam = &vat_main;
1278     vat_json_node_t node;
1279
1280     vat_json_init_object(&node);
1281     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1282     vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1283
1284     vat_json_print(vam->ofp, &node);
1285     vat_json_free(&node);
1286
1287     vam->retval = ntohl(mp->retval);
1288     vam->result_ready = 1;
1289 }
1290
1291 static void vl_api_bridge_flags_reply_t_handler
1292 (vl_api_bridge_flags_reply_t * mp)
1293 {
1294     vat_main_t * vam = &vat_main;
1295     i32 retval = ntohl(mp->retval);
1296     if (vam->async_mode) {
1297         vam->async_errors += (retval < 0);
1298     } else {
1299         vam->retval = retval;
1300         vam->result_ready = 1;
1301     }
1302 }
1303
1304 static void vl_api_bridge_flags_reply_t_handler_json
1305 (vl_api_bridge_flags_reply_t * mp)
1306 {
1307     vat_main_t * vam = &vat_main;
1308     vat_json_node_t node;
1309
1310     vat_json_init_object(&node);
1311     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1312     vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1313
1314     vat_json_print(vam->ofp, &node);
1315     vat_json_free(&node);
1316
1317     vam->retval = ntohl(mp->retval);
1318     vam->result_ready = 1;
1319 }
1320
1321 static void vl_api_tap_connect_reply_t_handler
1322 (vl_api_tap_connect_reply_t * mp)
1323 {
1324     vat_main_t * vam = &vat_main;
1325     i32 retval = ntohl(mp->retval);
1326     if (vam->async_mode) {
1327         vam->async_errors += (retval < 0);
1328     } else {
1329         vam->retval = retval;
1330         vam->sw_if_index = ntohl (mp->sw_if_index);
1331         vam->result_ready = 1;
1332     }
1333
1334 }
1335
1336 static void vl_api_tap_connect_reply_t_handler_json
1337 (vl_api_tap_connect_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, "sw_if_index", ntohl(mp->sw_if_index));
1345
1346     vat_json_print(vam->ofp, &node);
1347     vat_json_free(&node);
1348
1349     vam->retval = ntohl(mp->retval);
1350     vam->result_ready = 1;
1351
1352 }
1353
1354 static void vl_api_tap_modify_reply_t_handler
1355 (vl_api_tap_modify_reply_t * mp)
1356 {
1357     vat_main_t * vam = &vat_main;
1358     i32 retval = ntohl(mp->retval);
1359     if (vam->async_mode) {
1360         vam->async_errors += (retval < 0);
1361     } else {
1362         vam->retval = retval;
1363         vam->sw_if_index = ntohl (mp->sw_if_index);
1364         vam->result_ready = 1;
1365     }
1366 }
1367
1368 static void vl_api_tap_modify_reply_t_handler_json
1369 (vl_api_tap_modify_reply_t * mp)
1370 {
1371     vat_main_t * vam = &vat_main;
1372     vat_json_node_t node;
1373
1374     vat_json_init_object(&node);
1375     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1376     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1377
1378     vat_json_print(vam->ofp, &node);
1379     vat_json_free(&node);
1380
1381     vam->retval = ntohl(mp->retval);
1382     vam->result_ready = 1;
1383 }
1384
1385 static void vl_api_tap_delete_reply_t_handler
1386 (vl_api_tap_delete_reply_t * mp)
1387 {
1388     vat_main_t * vam = &vat_main;
1389     i32 retval = ntohl(mp->retval);
1390     if (vam->async_mode) {
1391         vam->async_errors += (retval < 0);
1392     } else {
1393         vam->retval = retval;
1394         vam->result_ready = 1;
1395     }
1396 }
1397
1398 static void vl_api_tap_delete_reply_t_handler_json
1399 (vl_api_tap_delete_reply_t * mp)
1400 {
1401     vat_main_t * vam = &vat_main;
1402     vat_json_node_t node;
1403
1404     vat_json_init_object(&node);
1405     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1406
1407     vat_json_print(vam->ofp, &node);
1408     vat_json_free(&node);
1409
1410     vam->retval = ntohl(mp->retval);
1411     vam->result_ready = 1;
1412 }
1413
1414 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1415 (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1416 {
1417     vat_main_t * vam = &vat_main;
1418     i32 retval = ntohl(mp->retval);
1419     if (vam->async_mode) {
1420         vam->async_errors += (retval < 0);
1421     } else {
1422         vam->retval = retval;
1423         vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1428 (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1429 {
1430     vat_main_t * vam = &vat_main;
1431     vat_json_node_t node;
1432
1433     vat_json_init_object(&node);
1434     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1435     vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1436
1437     vat_json_print(vam->ofp, &node);
1438     vat_json_free(&node);
1439
1440     vam->retval = ntohl(mp->retval);
1441     vam->result_ready = 1;
1442 }
1443
1444 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1445 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1446 {
1447     vat_main_t * vam = &vat_main;
1448     i32 retval = ntohl(mp->retval);
1449     if (vam->async_mode) {
1450         vam->async_errors += (retval < 0);
1451     } else {
1452         vam->retval = retval;
1453         vam->sw_if_index = ntohl (mp->sw_if_index);
1454         vam->result_ready = 1;
1455     }
1456 }
1457
1458 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1459 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1460 {
1461     vat_main_t * vam = &vat_main;
1462     vat_json_node_t node;
1463
1464     vat_json_init_object(&node);
1465     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1466     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1467
1468     vat_json_print(vam->ofp, &node);
1469     vat_json_free(&node);
1470
1471     vam->retval = ntohl(mp->retval);
1472     vam->result_ready = 1;
1473 }
1474
1475 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1476 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1477 {
1478     vat_main_t * vam = &vat_main;
1479     i32 retval = ntohl(mp->retval);
1480     if (vam->async_mode) {
1481         vam->async_errors += (retval < 0);
1482     } else {
1483         vam->retval = retval;
1484         vam->sw_if_index = ntohl (mp->sw_if_index);
1485         vam->result_ready = 1;
1486     }
1487 }
1488
1489 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1490 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1491 {
1492     vat_main_t * vam = &vat_main;
1493     vat_json_node_t node;
1494
1495     vat_json_init_object(&node);
1496     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1497     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1498
1499     vat_json_print(vam->ofp, &node);
1500     vat_json_free(&node);
1501
1502     vam->retval = ntohl(mp->retval);
1503     vam->result_ready = 1;
1504 }
1505
1506 static void vl_api_gre_add_del_tunnel_reply_t_handler
1507 (vl_api_gre_add_del_tunnel_reply_t * mp)
1508 {
1509     vat_main_t * vam = &vat_main;
1510     i32 retval = ntohl(mp->retval);
1511     if (vam->async_mode) {
1512         vam->async_errors += (retval < 0);
1513     } else {
1514         vam->retval = retval;
1515         vam->sw_if_index = ntohl (mp->sw_if_index);
1516         vam->result_ready = 1;
1517     }
1518 }
1519
1520 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1521 (vl_api_gre_add_del_tunnel_reply_t * mp)
1522 {
1523     vat_main_t * vam = &vat_main;
1524     vat_json_node_t node;
1525
1526     vat_json_init_object(&node);
1527     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1528     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1529
1530     vat_json_print(vam->ofp, &node);
1531     vat_json_free(&node);
1532
1533     vam->retval = ntohl(mp->retval);
1534     vam->result_ready = 1;
1535 }
1536
1537 static void vl_api_create_vhost_user_if_reply_t_handler
1538 (vl_api_create_vhost_user_if_reply_t * mp)
1539 {
1540     vat_main_t * vam = &vat_main;
1541     i32 retval = ntohl(mp->retval);
1542     if (vam->async_mode) {
1543         vam->async_errors += (retval < 0);
1544     } else {
1545         vam->retval = retval;
1546         vam->sw_if_index = ntohl (mp->sw_if_index);
1547         vam->result_ready = 1;
1548     }
1549 }
1550
1551 static void vl_api_create_vhost_user_if_reply_t_handler_json
1552 (vl_api_create_vhost_user_if_reply_t * mp)
1553 {
1554     vat_main_t * vam = &vat_main;
1555     vat_json_node_t node;
1556
1557     vat_json_init_object(&node);
1558     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1559     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1560
1561     vat_json_print(vam->ofp, &node);
1562     vat_json_free(&node);
1563
1564     vam->retval = ntohl(mp->retval);
1565     vam->result_ready = 1;
1566 }
1567
1568 static void vl_api_ip_address_details_t_handler
1569 (vl_api_ip_address_details_t * mp)
1570 {
1571     vat_main_t * vam = &vat_main;
1572     static ip_address_details_t empty_ip_address_details = {{0}};
1573     ip_address_details_t * address = NULL;
1574     ip_details_t * current_ip_details = NULL;
1575     ip_details_t * details = NULL;
1576
1577     details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1578
1579     if (!details || vam->current_sw_if_index >= vec_len(details)
1580             || !details[vam->current_sw_if_index].present) {
1581         errmsg ("ip address details arrived but not stored\n");
1582         errmsg ("ip_dump should be called first\n");
1583         return;
1584     }
1585
1586     current_ip_details = vec_elt_at_index(details,
1587             vam->current_sw_if_index);
1588
1589 #define addresses (current_ip_details->addr)
1590
1591     vec_validate_init_empty(addresses, vec_len(addresses),
1592             empty_ip_address_details);
1593
1594     address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1595
1596     clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
1597     address->prefix_length = mp->prefix_length;
1598 #undef addresses
1599 }
1600
1601 static void vl_api_ip_address_details_t_handler_json
1602 (vl_api_ip_address_details_t * mp)
1603 {
1604     vat_main_t * vam = &vat_main;
1605     vat_json_node_t *node = NULL;
1606     struct in6_addr ip6;
1607     struct in_addr ip4;
1608
1609     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1610         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1611         vat_json_init_array(&vam->json_tree);
1612     }
1613     node = vat_json_array_add(&vam->json_tree);
1614
1615     vat_json_init_object(node);
1616     if (vam->is_ipv6) {
1617         clib_memcpy(&ip6, mp->ip, sizeof(ip6));
1618         vat_json_object_add_ip6(node, "ip",  ip6);
1619     } else {
1620         clib_memcpy(&ip4, mp->ip, sizeof(ip4));
1621         vat_json_object_add_ip4(node, "ip", ip4);
1622     }
1623     vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1624 }
1625
1626 static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1627 {
1628     vat_main_t * vam = &vat_main;
1629     static ip_details_t empty_ip_details = {0};
1630     ip_details_t * ip = NULL;
1631     u32 sw_if_index = ~0;
1632
1633     sw_if_index = ntohl(mp->sw_if_index);
1634
1635     vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1636             sw_if_index, empty_ip_details);
1637
1638     ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1639             sw_if_index);
1640
1641     ip->present = 1;
1642 }
1643
1644 static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1645 {
1646     vat_main_t * vam = &vat_main;
1647
1648     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1649         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1650         vat_json_init_array(&vam->json_tree);
1651     }
1652     vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1653 }
1654
1655 static void vl_api_map_domain_details_t_handler_json
1656 (vl_api_map_domain_details_t * mp)
1657 {
1658     vat_json_node_t * node = NULL;
1659     vat_main_t * vam = &vat_main;
1660     struct in6_addr ip6;
1661     struct in_addr ip4;
1662
1663     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1664         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1665         vat_json_init_array(&vam->json_tree);
1666     }
1667
1668     node = vat_json_array_add(&vam->json_tree);
1669     vat_json_init_object(node);
1670
1671     vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
1672     clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
1673     vat_json_object_add_ip6(node, "ip6_prefix", ip6);
1674     clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
1675     vat_json_object_add_ip4(node, "ip4_prefix", ip4);
1676     clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
1677     vat_json_object_add_ip6(node, "ip6_src", ip6);
1678     vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1679     vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1680     vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1681     vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1682     vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1683     vat_json_object_add_int(node, "psid_length", mp->psid_length);
1684     vat_json_object_add_uint(node, "flags", mp->flags);
1685     vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1686     vat_json_object_add_int(node, "is_translation", mp->is_translation);
1687 }
1688
1689 static void vl_api_map_domain_details_t_handler
1690 (vl_api_map_domain_details_t * mp)
1691 {
1692     vat_main_t * vam = &vat_main;
1693
1694     if (mp->is_translation) {
1695         fformat(vam->ofp,  "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1696                   format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1697                   format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1698                   format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1699     } else {
1700         fformat(vam->ofp,  "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1701                   format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1702                   format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1703                   format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1704     }
1705     fformat(vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1706             mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1707 }
1708
1709 static void vl_api_map_rule_details_t_handler_json
1710 (vl_api_map_rule_details_t * mp)
1711 {
1712     struct in6_addr ip6;
1713     vat_json_node_t * node = NULL;
1714     vat_main_t * vam = &vat_main;
1715
1716     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1717         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1718         vat_json_init_array(&vam->json_tree);
1719     }
1720
1721     node = vat_json_array_add(&vam->json_tree);
1722     vat_json_init_object(node);
1723
1724     vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
1725     clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
1726     vat_json_object_add_ip6(node, "ip6_dst", ip6);
1727 }
1728
1729 static void vl_api_map_rule_details_t_handler
1730 (vl_api_map_rule_details_t * mp)
1731 {
1732     vat_main_t * vam = &vat_main;
1733     fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1734             format_ip6_address, mp->ip6_dst);
1735 }
1736
1737 static void vl_api_dhcp_compl_event_t_handler
1738 (vl_api_dhcp_compl_event_t * mp)
1739 {
1740     vat_main_t * vam = &vat_main;
1741     errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1742             "router_addr %U host_mac %U\n",
1743             mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1744             format_ip4_address, &mp->host_address,
1745             format_ip4_address, &mp->router_address,
1746             format_ethernet_address, mp->host_mac);
1747 }
1748
1749 static void vl_api_dhcp_compl_event_t_handler_json
1750 (vl_api_dhcp_compl_event_t * mp)
1751 {
1752     /* JSON output not supported */
1753 }
1754
1755 static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1756                                           u32 counter)
1757 {
1758     vat_main_t * vam = &vat_main;
1759     static u64 default_counter = 0;
1760
1761     vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1762     vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1763                             sw_if_index, default_counter);
1764     vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1765 }
1766
1767 static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1768                                             interface_counter_t counter)
1769 {
1770     vat_main_t * vam = &vat_main;
1771     static interface_counter_t default_counter = {0, };
1772
1773     vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1774     vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1775                             sw_if_index, default_counter);
1776     vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1777 }
1778
1779 static void vl_api_vnet_interface_counters_t_handler
1780 (vl_api_vnet_interface_counters_t *mp)
1781 {
1782     /* not supported */
1783 }
1784
1785 static void vl_api_vnet_interface_counters_t_handler_json
1786 (vl_api_vnet_interface_counters_t *mp)
1787 {
1788     interface_counter_t counter;
1789     vlib_counter_t *v;
1790     u64 *v_packets;
1791     u64 packets;
1792     u32 count;
1793     u32 first_sw_if_index;
1794     int i;
1795
1796     count = ntohl(mp->count);
1797     first_sw_if_index = ntohl(mp->first_sw_if_index);
1798
1799     if (!mp->is_combined) {
1800         v_packets = (u64*)&mp->data;
1801         for (i = 0; i < count; i++) {
1802             packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1803             set_simple_interface_counter(mp->vnet_counter_type,
1804                     first_sw_if_index + i, packets);
1805             v_packets++;
1806         }
1807     } else {
1808         v = (vlib_counter_t*)&mp->data;
1809         for (i = 0; i < count; i++) {
1810             counter.packets = clib_net_to_host_u64(
1811                     clib_mem_unaligned(&v->packets, u64));
1812             counter.bytes = clib_net_to_host_u64(
1813                     clib_mem_unaligned(&v->bytes, u64));
1814             set_combined_interface_counter(mp->vnet_counter_type,
1815                     first_sw_if_index + i, counter);
1816             v++;
1817         }
1818     }
1819 }
1820
1821 static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1822 {
1823     vat_main_t * vam = &vat_main;
1824     u32 i;
1825
1826     for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1827         if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1828             return i;
1829         }
1830     }
1831     return ~0;
1832 }
1833
1834 static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1835 {
1836     vat_main_t * vam = &vat_main;
1837     u32 i;
1838
1839     for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1840         if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1841             return i;
1842         }
1843     }
1844     return ~0;
1845 }
1846
1847 static void vl_api_vnet_ip4_fib_counters_t_handler
1848 (vl_api_vnet_ip4_fib_counters_t *mp)
1849 {
1850     /* not supported */
1851 }
1852
1853 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1854 (vl_api_vnet_ip4_fib_counters_t *mp)
1855 {
1856     vat_main_t * vam = &vat_main;
1857     vl_api_ip4_fib_counter_t *v;
1858     ip4_fib_counter_t *counter;
1859     struct in_addr ip4;
1860     u32 vrf_id;
1861     u32 vrf_index;
1862     u32 count;
1863     int i;
1864
1865     vrf_id = ntohl(mp->vrf_id);
1866     vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1867     if (~0 == vrf_index) {
1868         vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1869         vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1870         vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1871         vec_validate(vam->ip4_fib_counters, vrf_index);
1872         vam->ip4_fib_counters[vrf_index] = NULL;
1873     }
1874
1875     vec_free(vam->ip4_fib_counters[vrf_index]);
1876     v = (vl_api_ip4_fib_counter_t*)&mp->c;
1877     count = ntohl(mp->count);
1878     for (i = 0; i < count; i++) {
1879         vec_validate(vam->ip4_fib_counters[vrf_index], i);
1880         counter = &vam->ip4_fib_counters[vrf_index][i];
1881         clib_memcpy(&ip4, &v->address, sizeof(ip4));
1882         counter->address = ip4;
1883         counter->address_length = v->address_length;
1884         counter->packets = clib_net_to_host_u64(v->packets);
1885         counter->bytes = clib_net_to_host_u64(v->bytes);
1886         v++;
1887     }
1888 }
1889
1890 static void vl_api_vnet_ip6_fib_counters_t_handler
1891 (vl_api_vnet_ip6_fib_counters_t *mp)
1892 {
1893     /* not supported */
1894 }
1895
1896 static void vl_api_vnet_ip6_fib_counters_t_handler_json
1897 (vl_api_vnet_ip6_fib_counters_t *mp)
1898 {
1899     vat_main_t * vam = &vat_main;
1900     vl_api_ip6_fib_counter_t *v;
1901     ip6_fib_counter_t *counter;
1902     struct in6_addr ip6;
1903     u32 vrf_id;
1904     u32 vrf_index;
1905     u32 count;
1906     int i;
1907
1908     vrf_id = ntohl(mp->vrf_id);
1909     vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1910     if (~0 == vrf_index) {
1911         vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1912         vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1913         vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1914         vec_validate(vam->ip6_fib_counters, vrf_index);
1915         vam->ip6_fib_counters[vrf_index] = NULL;
1916     }
1917
1918     vec_free(vam->ip6_fib_counters[vrf_index]);
1919     v = (vl_api_ip6_fib_counter_t*)&mp->c;
1920     count = ntohl(mp->count);
1921     for (i = 0; i < count; i++) {
1922         vec_validate(vam->ip6_fib_counters[vrf_index], i);
1923         counter = &vam->ip6_fib_counters[vrf_index][i];
1924         clib_memcpy(&ip6, &v->address, sizeof(ip6));
1925         counter->address = ip6;
1926         counter->address_length = v->address_length;
1927         counter->packets = clib_net_to_host_u64(v->packets);
1928         counter->bytes = clib_net_to_host_u64(v->bytes);
1929         v++;
1930     }
1931 }
1932
1933 static void vl_api_get_first_msg_id_reply_t_handler
1934 (vl_api_get_first_msg_id_reply_t * mp)
1935 {
1936     vat_main_t * vam = &vat_main;
1937     i32 retval = ntohl(mp->retval);
1938
1939     if (vam->async_mode) {
1940         vam->async_errors += (retval < 0);
1941     } else {
1942         vam->retval = retval;
1943         vam->result_ready = 1;
1944     }
1945     if (retval >= 0) {
1946         errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1947     }
1948 }
1949
1950 static void vl_api_get_first_msg_id_reply_t_handler_json
1951 (vl_api_get_first_msg_id_reply_t * mp)
1952 {
1953     vat_main_t * vam = &vat_main;
1954     vat_json_node_t node;
1955
1956     vat_json_init_object(&node);
1957     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1958     vat_json_object_add_uint(&node, "first_msg_id",
1959                              (uint) ntohs(mp->first_msg_id));
1960
1961     vat_json_print(vam->ofp, &node);
1962     vat_json_free(&node);
1963
1964     vam->retval = ntohl(mp->retval);
1965     vam->result_ready = 1;
1966 }
1967
1968 static void vl_api_get_node_graph_reply_t_handler
1969 (vl_api_get_node_graph_reply_t * mp)
1970 {
1971     vat_main_t * vam = &vat_main;
1972     api_main_t * am = &api_main;
1973     i32 retval = ntohl(mp->retval);
1974     u8 * pvt_copy, * reply;
1975     void * oldheap;
1976     vlib_node_t * node;
1977     int i;
1978
1979     if (vam->async_mode) {
1980         vam->async_errors += (retval < 0);
1981     } else {
1982         vam->retval = retval;
1983         vam->result_ready = 1;
1984     }
1985
1986     /* "Should never happen..." */
1987     if (retval != 0)
1988         return;
1989
1990     reply = (u8 *)(mp->reply_in_shmem);
1991     pvt_copy = vec_dup (reply);
1992
1993     /* Toss the shared-memory original... */
1994     pthread_mutex_lock (&am->vlib_rp->mutex);
1995     oldheap = svm_push_data_heap (am->vlib_rp);
1996
1997     vec_free (reply);
1998
1999     svm_pop_heap (oldheap);
2000     pthread_mutex_unlock (&am->vlib_rp->mutex);
2001
2002     if (vam->graph_nodes) {
2003         hash_free (vam->graph_node_index_by_name);
2004
2005         for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2006             node = vam->graph_nodes[i];
2007             vec_free (node->name);
2008             vec_free (node->next_nodes);
2009             vec_free (node);
2010         }
2011         vec_free(vam->graph_nodes);
2012     }
2013
2014     vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
2015     vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2016     vec_free (pvt_copy);
2017
2018     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
2019         node = vam->graph_nodes[i];
2020         hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2021     }
2022 }
2023
2024 static void vl_api_get_node_graph_reply_t_handler_json
2025 (vl_api_get_node_graph_reply_t * mp)
2026 {
2027     vat_main_t * vam = &vat_main;
2028     api_main_t * am = &api_main;
2029     void * oldheap;
2030     vat_json_node_t node;
2031     u8 * reply;
2032
2033     /* $$$$ make this real? */
2034     vat_json_init_object(&node);
2035     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2036     vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
2037
2038     reply = (u8 *)(mp->reply_in_shmem);
2039
2040     /* Toss the shared-memory original... */
2041     pthread_mutex_lock (&am->vlib_rp->mutex);
2042     oldheap = svm_push_data_heap (am->vlib_rp);
2043
2044     vec_free (reply);
2045
2046     svm_pop_heap (oldheap);
2047     pthread_mutex_unlock (&am->vlib_rp->mutex);
2048
2049     vat_json_print(vam->ofp, &node);
2050     vat_json_free(&node);
2051
2052     vam->retval = ntohl(mp->retval);
2053     vam->result_ready = 1;
2054 }
2055
2056 static void
2057 vl_api_lisp_locator_details_t_handler (
2058     vl_api_lisp_locator_details_t *mp)
2059 {
2060     vat_main_t *vam = &vat_main;
2061     locator_msg_t loc;
2062     u8 * tmp_str = 0;
2063
2064     memset(&loc, 0, sizeof(loc));
2065     if (vam->noprint_msg) {
2066       loc.local = mp->local;
2067       loc.priority = mp->priority;
2068       loc.weight = mp->weight;
2069       if (loc.local) {
2070         loc.sw_if_index = ntohl(mp->sw_if_index);
2071       } else {
2072         loc.is_ipv6 = mp->is_ipv6;
2073         clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2074       }
2075       vec_add1(vam->locator_msg, loc);
2076     } else {
2077       if (mp->local) {
2078         tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
2079                          ntohl(mp->sw_if_index),
2080                          mp->priority,
2081                          mp->weight);
2082       } else {
2083         tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
2084                          mp->is_ipv6 ? format_ip6_address :
2085                          format_ip4_address,
2086                          mp->ip_address,
2087                          mp->priority,
2088                          mp->weight);
2089       }
2090
2091       fformat(vam->ofp, "%s", tmp_str);
2092
2093       vec_free(tmp_str);
2094     }
2095 }
2096
2097 static void
2098 vl_api_lisp_locator_details_t_handler_json (
2099     vl_api_lisp_locator_details_t *mp)
2100 {
2101     vat_main_t *vam = &vat_main;
2102     vat_json_node_t *node = NULL;
2103     locator_msg_t loc;
2104     struct in6_addr ip6;
2105     struct in_addr ip4;
2106
2107     memset(&loc, 0, sizeof(loc));
2108     if (vam->noprint_msg) {
2109         loc.local = mp->local;
2110         loc.priority = mp->priority;
2111         loc.weight = mp->weight;
2112         if (loc.local) {
2113             loc.sw_if_index = ntohl(mp->sw_if_index);
2114         } else {
2115             loc.is_ipv6 = mp->is_ipv6;
2116             clib_memcpy(loc.ip_address, mp->ip_address, sizeof(loc.ip_address));
2117         }
2118         vec_add1(vam->locator_msg, loc);
2119         return;
2120     }
2121
2122     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2123         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2124         vat_json_init_array(&vam->json_tree);
2125     }
2126     node = vat_json_array_add(&vam->json_tree);
2127
2128     vat_json_init_object(node);
2129
2130     if (mp->local) {
2131         vat_json_object_add_uint(node, "locator_index", ntohl(mp->sw_if_index));
2132     } else {
2133       if (mp->is_ipv6) {
2134         clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2135         vat_json_object_add_ip6(node, "locator", ip6);
2136       } else {
2137         clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2138         vat_json_object_add_ip4(node, "locator", ip4);
2139       }
2140     }
2141     vat_json_object_add_uint(node, "priority", mp->priority);
2142     vat_json_object_add_uint(node, "weight", mp->weight);
2143 }
2144
2145 static void
2146 vl_api_lisp_locator_set_details_t_handler (
2147     vl_api_lisp_locator_set_details_t *mp)
2148 {
2149     vat_main_t *vam = &vat_main;
2150     locator_set_msg_t ls;
2151
2152     ls.locator_set_index = ntohl(mp->locator_set_index);
2153     ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2154     vec_add1(vam->locator_set_msg, ls);
2155 }
2156
2157 static void
2158 vl_api_lisp_locator_set_details_t_handler_json (
2159     vl_api_lisp_locator_set_details_t *mp)
2160 {
2161     vat_main_t *vam = &vat_main;
2162     locator_set_msg_t ls;
2163
2164     ls.locator_set_index = ntohl(mp->locator_set_index);
2165     ls.locator_set_name = format(0, "%s", mp->locator_set_name);
2166     vec_add1(vam->locator_set_msg, ls);
2167 }
2168
2169 static void
2170 vl_api_lisp_eid_table_details_t_handler (
2171     vl_api_lisp_eid_table_details_t * mp)
2172 {
2173     vat_main_t *vam = &vat_main;
2174     eid_table_t eid_table;
2175
2176     memset(&eid_table, 0, sizeof(eid_table));
2177     eid_table.is_local = mp->is_local;
2178     eid_table.locator_set_index = mp->locator_set_index;
2179     eid_table.eid_type = mp->eid_type;
2180     eid_table.vni = mp->vni;
2181     eid_table.eid_prefix_len = mp->eid_prefix_len;
2182     eid_table.ttl = mp->ttl;
2183     eid_table.authoritative = mp->authoritative;
2184     clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2185     vec_add1(vam->eid_tables, eid_table);
2186 }
2187
2188 static void
2189 vl_api_lisp_eid_table_details_t_handler_json (
2190     vl_api_lisp_eid_table_details_t * mp)
2191 {
2192     vat_main_t *vam = &vat_main;
2193     eid_table_t eid_table;
2194
2195     memset(&eid_table, 0, sizeof(eid_table));
2196     eid_table.is_local = mp->is_local;
2197     eid_table.locator_set_index = mp->locator_set_index;
2198     eid_table.eid_type = mp->eid_type;
2199     eid_table.vni = mp->vni;
2200     eid_table.eid_prefix_len = mp->eid_prefix_len;
2201     eid_table.ttl = mp->ttl;
2202     eid_table.authoritative = mp->authoritative;
2203     clib_memcpy(eid_table.eid, mp->eid, sizeof(eid_table.eid));
2204     vec_add1(vam->eid_tables, eid_table);
2205 }
2206
2207 static void
2208 vl_api_lisp_eid_table_map_details_t_handler (
2209     vl_api_lisp_eid_table_map_details_t *mp)
2210 {
2211     vat_main_t *vam = &vat_main;
2212
2213     u8 * line = format(0, "%=10d%=10d",
2214                        clib_net_to_host_u32 (mp->vni),
2215                        clib_net_to_host_u32 (mp->vrf));
2216     fformat(vam->ofp, "%v\n", line);
2217     vec_free(line);
2218 }
2219
2220 static void
2221 vl_api_lisp_eid_table_map_details_t_handler_json (
2222     vl_api_lisp_eid_table_map_details_t *mp)
2223 {
2224     vat_main_t *vam = &vat_main;
2225     vat_json_node_t *node = NULL;
2226
2227     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2228         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2229         vat_json_init_array(&vam->json_tree);
2230     }
2231     node = vat_json_array_add(&vam->json_tree);
2232     vat_json_init_object(node);
2233     vat_json_object_add_uint(node, "vrf", clib_net_to_host_u32 (mp->vrf));
2234     vat_json_object_add_uint(node, "vni", clib_net_to_host_u32 (mp->vni));
2235 }
2236
2237
2238
2239 static u8 *
2240 format_decap_next (u8 * s, va_list * args)
2241 {
2242   u32 next_index = va_arg (*args, u32);
2243
2244   switch (next_index)
2245     {
2246     case LISP_GPE_INPUT_NEXT_DROP:
2247       return format (s, "drop");
2248     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2249       return format (s, "ip4");
2250     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2251       return format (s, "ip6");
2252     default:
2253       return format (s, "unknown %d", next_index);
2254     }
2255   return s;
2256 }
2257
2258 static void
2259 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2260 {
2261     vat_main_t *vam = &vat_main;
2262     u8 *iid_str;
2263     u8 *flag_str = NULL;
2264
2265     iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2266
2267 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2268   foreach_lisp_gpe_flag_bit;
2269 #undef _
2270
2271     fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2272             "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2273             mp->tunnels,
2274             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2275             mp->source_ip,
2276             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2277             mp->destination_ip,
2278             ntohl(mp->encap_fib_id),
2279             ntohl(mp->decap_fib_id),
2280             format_decap_next, ntohl(mp->dcap_next),
2281             mp->ver_res >> 6,
2282             flag_str,
2283             mp->next_protocol,
2284             mp->ver_res,
2285             mp->res,
2286             iid_str);
2287
2288     vec_free(iid_str);
2289 }
2290
2291 static void
2292 vl_api_lisp_gpe_tunnel_details_t_handler_json (
2293     vl_api_lisp_gpe_tunnel_details_t *mp)
2294 {
2295     vat_main_t *vam = &vat_main;
2296     vat_json_node_t *node = NULL;
2297     struct in6_addr ip6;
2298     struct in_addr ip4;
2299     u8 *next_decap_str;
2300
2301     next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2302
2303     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2304         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2305         vat_json_init_array(&vam->json_tree);
2306     }
2307     node = vat_json_array_add(&vam->json_tree);
2308
2309     vat_json_init_object(node);
2310     vat_json_object_add_uint(node, "tunel", mp->tunnels);
2311     if (mp->is_ipv6) {
2312         clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
2313         vat_json_object_add_ip6(node, "source address", ip6);
2314         clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
2315         vat_json_object_add_ip6(node, "destination address", ip6);
2316     } else {
2317         clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
2318         vat_json_object_add_ip4(node, "source address", ip4);
2319         clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
2320         vat_json_object_add_ip4(node, "destination address", ip4);
2321     }
2322     vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2323     vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2324     vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2325     vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2326     vat_json_object_add_uint(node, "flags", mp->flags);
2327     vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2328     vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2329     vat_json_object_add_uint(node, "res", mp->res);
2330     vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2331
2332     vec_free(next_decap_str);
2333 }
2334
2335 static void
2336 vl_api_lisp_map_resolver_details_t_handler (
2337     vl_api_lisp_map_resolver_details_t *mp)
2338 {
2339     vat_main_t *vam = &vat_main;
2340
2341     fformat(vam->ofp, "%=20U\n",
2342             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2343             mp->ip_address);
2344 }
2345
2346 static void
2347 vl_api_lisp_map_resolver_details_t_handler_json (
2348     vl_api_lisp_map_resolver_details_t *mp)
2349 {
2350     vat_main_t *vam = &vat_main;
2351     vat_json_node_t *node = NULL;
2352     struct in6_addr ip6;
2353     struct in_addr ip4;
2354
2355     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2356         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2357         vat_json_init_array(&vam->json_tree);
2358     }
2359     node = vat_json_array_add(&vam->json_tree);
2360
2361     vat_json_init_object(node);
2362     if (mp->is_ipv6) {
2363         clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2364         vat_json_object_add_ip6(node, "map resolver", ip6);
2365     } else {
2366         clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2367         vat_json_object_add_ip4(node, "map resolver", ip4);
2368     }
2369 }
2370
2371 static void
2372 vl_api_show_lisp_status_reply_t_handler
2373 (vl_api_show_lisp_status_reply_t * mp)
2374 {
2375     vat_main_t *vam = &vat_main;
2376     i32 retval = ntohl(mp->retval);
2377
2378     if (0 <= retval) {
2379       fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2380               mp->feature_status ? "enabled" : "disabled",
2381               mp->gpe_status ? "enabled" : "disabled");
2382     }
2383
2384     vam->retval = retval;
2385     vam->result_ready = 1;
2386 }
2387
2388 static void
2389 vl_api_show_lisp_status_reply_t_handler_json
2390 (vl_api_show_lisp_status_reply_t *mp)
2391 {
2392     vat_main_t *vam = &vat_main;
2393     vat_json_node_t node;
2394     u8 * gpe_status = NULL;
2395     u8 * feature_status = NULL;
2396
2397     gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2398     feature_status = format (0, "%s",
2399                             mp->feature_status ? "enabled" : "disabled");
2400     vec_add1 (gpe_status, 0);
2401     vec_add1 (feature_status, 0);
2402
2403     vat_json_init_object(&node);
2404     vat_json_object_add_string_copy(&node, "gpe_status", gpe_status);
2405     vat_json_object_add_string_copy(&node, "feature_status", feature_status);
2406
2407     vec_free (gpe_status);
2408     vec_free (feature_status);
2409
2410     vat_json_print(vam->ofp, &node);
2411     vat_json_free(&node);
2412
2413     vam->retval = ntohl(mp->retval);
2414     vam->result_ready = 1;
2415 }
2416
2417 static void
2418 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler (
2419     vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2420 {
2421     vat_main_t * vam = &vat_main;
2422     i32 retval = ntohl(mp->retval);
2423
2424     if (retval >= 0) {
2425       fformat(vam->ofp, "%=20s\n",
2426               mp->locator_set_name);
2427     }
2428
2429     vam->retval = retval;
2430     vam->result_ready = 1;
2431 }
2432
2433 static void
2434 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json (
2435     vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2436 {
2437     vat_main_t * vam = &vat_main;
2438     vat_json_node_t * node = NULL;
2439
2440     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2441         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2442         vat_json_init_array(&vam->json_tree);
2443     }
2444     node = vat_json_array_add(&vam->json_tree);
2445
2446     vat_json_init_object(node);
2447     vat_json_object_add_string_copy(node, "itr-rlocs", mp->locator_set_name);
2448
2449     vat_json_print(vam->ofp, node);
2450     vat_json_free(node);
2451
2452     vam->retval = ntohl(mp->retval);
2453     vam->result_ready = 1;
2454 }
2455
2456 static void
2457 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2458 {
2459     vat_main_t *vam = &vat_main;
2460     i32 retval = ntohl(mp->retval);
2461
2462     if (0 <= retval) {
2463       fformat(vam->ofp, "%-20s%-16s\n",
2464               mp->status ? "enabled" : "disabled",
2465               mp->status ? (char *) mp->locator_set_name : "");
2466     }
2467
2468     vam->retval = retval;
2469     vam->result_ready = 1;
2470 }
2471
2472 static void
2473 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t * mp)
2474 {
2475     vat_main_t *vam = &vat_main;
2476     vat_json_node_t node;
2477     u8 * status = 0;
2478
2479     status = format (0, "%s", mp->status ? "enabled" : "disabled");
2480     vec_add1 (status, 0);
2481
2482     vat_json_init_object(&node);
2483     vat_json_object_add_string_copy(&node, "status", status);
2484     if (mp->status) {
2485       vat_json_object_add_string_copy(&node, "locator_set", mp->locator_set_name);
2486     }
2487
2488     vec_free (status);
2489
2490     vat_json_print(vam->ofp, &node);
2491     vat_json_free(&node);
2492
2493     vam->retval = ntohl(mp->retval);
2494     vam->result_ready = 1;
2495 }
2496
2497 static u8 * format_policer_type (u8 * s, va_list * va)
2498 {
2499     u32 i = va_arg (*va, u32);
2500
2501     if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2502         s = format (s, "1r2c");
2503     else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2504         s = format (s, "1r3c");
2505     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2506         s = format (s, "2r3c-2698");
2507     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2508         s = format (s, "2r3c-4115");
2509     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2510         s = format (s, "2r3c-mef5cf1");
2511     else
2512         s = format (s, "ILLEGAL");
2513     return s;
2514 }
2515
2516 static u8 * format_policer_rate_type (u8 * s, va_list * va)
2517 {
2518     u32 i = va_arg (*va, u32);
2519
2520     if (i == SSE2_QOS_RATE_KBPS)
2521         s = format (s, "kbps");
2522     else if (i == SSE2_QOS_RATE_PPS)
2523         s = format(s, "pps");
2524     else
2525         s = format (s, "ILLEGAL");
2526     return s;
2527 }
2528
2529 static u8 * format_policer_round_type (u8 * s, va_list * va)
2530 {
2531     u32 i = va_arg (*va, u32);
2532
2533     if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2534         s = format(s, "closest");
2535     else if (i == SSE2_QOS_ROUND_TO_UP)
2536         s = format (s, "up");
2537     else if (i == SSE2_QOS_ROUND_TO_DOWN)
2538         s = format (s, "down");
2539     else
2540         s = format (s, "ILLEGAL");
2541   return s;
2542 }
2543
2544 static u8 * format_policer_action_type (u8 * s, va_list * va)
2545 {
2546     u32 i = va_arg (*va, u32);
2547
2548     if (i == SSE2_QOS_ACTION_DROP)
2549         s = format (s, "drop");
2550     else if (i == SSE2_QOS_ACTION_TRANSMIT)
2551         s = format (s, "transmit");
2552     else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2553         s = format (s, "mark-and-transmit");
2554     else
2555         s = format (s, "ILLEGAL");
2556     return s;
2557 }
2558
2559 static u8 * format_dscp (u8 * s, va_list * va)
2560 {
2561   u32 i = va_arg (*va, u32);
2562   char * t = 0;
2563
2564   switch (i) {
2565   #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2566     foreach_vnet_dscp
2567   #undef _
2568     default:
2569       return format (s, "ILLEGAL");
2570   }
2571   s = format (s, "%s", t);
2572   return s;
2573 }
2574
2575 static void vl_api_policer_details_t_handler
2576 (vl_api_policer_details_t * mp)
2577 {
2578     vat_main_t * vam = &vat_main;
2579     u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2580
2581     if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2582         conform_dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2583     else
2584         conform_dscp_str = format(0, "");
2585
2586     if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2587         exceed_dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2588     else
2589         exceed_dscp_str = format(0, "");
2590
2591     if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2592         violate_dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2593     else
2594         violate_dscp_str = format(0, "");
2595
2596     fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2597              "rate type %U, round type %U, %s rate, %s color-aware, "
2598              "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2599              "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2600              "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2601              mp->name,
2602              format_policer_type, mp->type,
2603              ntohl(mp->cir),
2604              ntohl(mp->eir),
2605              clib_net_to_host_u64(mp->cb),
2606              clib_net_to_host_u64(mp->eb),
2607              format_policer_rate_type, mp->rate_type,
2608              format_policer_round_type, mp->round_type,
2609              mp->single_rate ? "single" : "dual",
2610              mp->color_aware ? "is" : "not",
2611              ntohl(mp->cir_tokens_per_period),
2612              ntohl(mp->pir_tokens_per_period),
2613              ntohl(mp->scale),
2614              ntohl(mp->current_limit),
2615              ntohl(mp->current_bucket),
2616              ntohl(mp->extended_limit),
2617              ntohl(mp->extended_bucket),
2618              clib_net_to_host_u64(mp->last_update_time),
2619              format_policer_action_type, mp->conform_action_type,
2620              conform_dscp_str,
2621              format_policer_action_type, mp->exceed_action_type,
2622              exceed_dscp_str,
2623              format_policer_action_type, mp->violate_action_type,
2624              violate_dscp_str);
2625
2626     vec_free(conform_dscp_str);
2627     vec_free(exceed_dscp_str);
2628     vec_free(violate_dscp_str);
2629 }
2630
2631 static void vl_api_policer_details_t_handler_json
2632 (vl_api_policer_details_t * mp)
2633 {
2634     vat_main_t * vam = &vat_main;
2635     vat_json_node_t *node;
2636     u8 *rate_type_str, *round_type_str, *type_str;
2637     u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2638
2639     rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2640     round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2641     type_str = format(0, "%U", format_policer_type, mp->type);
2642     conform_action_str = format(0, "%U", format_policer_action_type,
2643                                 mp->conform_action_type);
2644     exceed_action_str = format(0, "%U", format_policer_action_type,
2645                                 mp->exceed_action_type);
2646     violate_action_str = format(0, "%U", format_policer_action_type,
2647                                 mp->violate_action_type);
2648
2649     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2650         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2651         vat_json_init_array(&vam->json_tree);
2652     }
2653     node = vat_json_array_add(&vam->json_tree);
2654
2655     vat_json_init_object(node);
2656     vat_json_object_add_string_copy(node, "name", mp->name);
2657     vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2658     vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2659     vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2660     vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2661     vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2662     vat_json_object_add_string_copy(node, "round_type", round_type_str);
2663     vat_json_object_add_string_copy(node, "type", type_str);
2664     vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2665     vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2666     vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2667     vat_json_object_add_uint(node, "cir_tokens_per_period",
2668                              ntohl(mp->cir_tokens_per_period));
2669     vat_json_object_add_uint(node, "eir_tokens_per_period",
2670                              ntohl(mp->pir_tokens_per_period));
2671     vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2672     vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2673     vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2674     vat_json_object_add_uint(node, "extended_bucket",
2675                              ntohl(mp->extended_bucket));
2676     vat_json_object_add_uint(node, "last_update_time",
2677                              ntohl(mp->last_update_time));
2678     vat_json_object_add_string_copy(node, "conform_action", conform_action_str);
2679     if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2680         u8 *dscp_str = format(0, "%U", format_dscp, mp->conform_dscp);
2681         vat_json_object_add_string_copy(node, "conform_dscp", dscp_str);
2682         vec_free(dscp_str);
2683     }
2684     vat_json_object_add_string_copy(node, "exceed_action", exceed_action_str);
2685     if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2686         u8 *dscp_str = format(0, "%U", format_dscp, mp->exceed_dscp);
2687         vat_json_object_add_string_copy(node, "exceed_dscp", dscp_str);
2688         vec_free(dscp_str);
2689     }
2690     vat_json_object_add_string_copy(node, "violate_action", violate_action_str);
2691     if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) {
2692         u8 *dscp_str = format(0, "%U", format_dscp, mp->violate_dscp);
2693         vat_json_object_add_string_copy(node, "violate_dscp", dscp_str);
2694         vec_free(dscp_str);
2695     }
2696
2697     vec_free(rate_type_str);
2698     vec_free(round_type_str);
2699     vec_free(type_str);
2700     vec_free(conform_action_str);
2701     vec_free(exceed_action_str);
2702     vec_free(violate_action_str);
2703 }
2704
2705 static void vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t * mp)
2706 {
2707     vat_main_t * vam = &vat_main;
2708     int i, count = ntohl(mp->count);
2709
2710     if (count>0)
2711         fformat (vam->ofp, "classify table ids (%d) : ", count);
2712     for (i = 0; i < count; i++)
2713     {
2714         fformat (vam->ofp, "%d", ntohl(mp->ids[i]));
2715         fformat (vam->ofp, (i<count-1)?",":"\n");
2716     }
2717     vam->retval = ntohl(mp->retval);
2718     vam->result_ready = 1;
2719 }
2720
2721 static void vl_api_classify_table_ids_reply_t_handler_json (vl_api_classify_table_ids_reply_t * mp)
2722 {
2723     vat_main_t * vam = &vat_main;
2724     int i, count = ntohl(mp->count);
2725
2726     if (count>0) {
2727         vat_json_node_t node;
2728
2729         vat_json_init_object(&node);
2730             for (i = 0; i < count; i++)
2731             {
2732                 vat_json_object_add_uint(&node, "table_id", ntohl(mp->ids[i]));
2733             }
2734             vat_json_print(vam->ofp, &node);
2735             vat_json_free(&node);
2736     }
2737     vam->retval = ntohl(mp->retval);
2738     vam->result_ready = 1;
2739 }
2740
2741 static void vl_api_classify_table_by_interface_reply_t_handler (vl_api_classify_table_by_interface_reply_t * mp)
2742 {
2743     vat_main_t * vam = &vat_main;
2744     u32 table_id;
2745
2746     table_id = ntohl(mp->l2_table_id);
2747     if (table_id != ~0)
2748         fformat (vam->ofp, "l2 table id : %d\n", table_id);
2749     else
2750         fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2751     table_id = ntohl(mp->ip4_table_id);
2752     if (table_id != ~0)
2753         fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2754     else
2755         fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2756     table_id = ntohl(mp->ip6_table_id);
2757     if (table_id != ~0)
2758         fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2759     else
2760         fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2761     vam->retval = ntohl(mp->retval);
2762     vam->result_ready = 1;
2763 }
2764
2765 static void vl_api_classify_table_by_interface_reply_t_handler_json (vl_api_classify_table_by_interface_reply_t * mp)
2766 {
2767     vat_main_t * vam = &vat_main;
2768     vat_json_node_t node;
2769
2770     vat_json_init_object(&node);
2771
2772     vat_json_object_add_int(&node, "l2_table_id", ntohl(mp->l2_table_id));
2773     vat_json_object_add_int(&node, "ip4_table_id", ntohl(mp->ip4_table_id));
2774     vat_json_object_add_int(&node, "ip6_table_id", ntohl(mp->ip6_table_id));
2775
2776     vat_json_print(vam->ofp, &node);
2777     vat_json_free(&node);
2778
2779     vam->retval = ntohl(mp->retval);
2780     vam->result_ready = 1;
2781 }
2782
2783 static void vl_api_policer_add_del_reply_t_handler
2784 (vl_api_policer_add_del_reply_t * mp)
2785 {
2786     vat_main_t * vam = &vat_main;
2787     i32 retval = ntohl(mp->retval);
2788     if (vam->async_mode) {
2789         vam->async_errors += (retval < 0);
2790     } else {
2791         vam->retval = retval;
2792         vam->result_ready = 1;
2793         if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2794             /*
2795              * Note: this is just barely thread-safe, depends on
2796              * the main thread spinning waiting for an answer...
2797              */
2798             errmsg ("policer index %d\n", ntohl(mp->policer_index));
2799     }
2800 }
2801
2802 static void vl_api_policer_add_del_reply_t_handler_json
2803 (vl_api_policer_add_del_reply_t * mp)
2804 {
2805     vat_main_t * vam = &vat_main;
2806     vat_json_node_t node;
2807
2808     vat_json_init_object(&node);
2809     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
2810     vat_json_object_add_uint(&node, "policer_index", ntohl(mp->policer_index));
2811
2812     vat_json_print(vam->ofp, &node);
2813     vat_json_free(&node);
2814
2815     vam->retval = ntohl(mp->retval);
2816     vam->result_ready = 1;
2817 }
2818
2819 /* Format hex dump. */
2820 u8 * format_hex_bytes (u8 * s, va_list * va)
2821 {
2822     u8 * bytes = va_arg (*va, u8 *);
2823     int n_bytes = va_arg (*va, int);
2824     uword i;
2825
2826     /* Print short or long form depending on byte count. */
2827     uword short_form = n_bytes <= 32;
2828     uword indent = format_get_indent (s);
2829
2830     if (n_bytes == 0)
2831         return s;
2832
2833     for (i = 0; i < n_bytes; i++)
2834     {
2835         if (! short_form && (i % 32) == 0)
2836             s = format (s, "%08x: ", i);
2837         s = format (s, "%02x", bytes[i]);
2838         if (! short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
2839             s = format (s, "\n%U", format_white_space, indent);
2840     }
2841
2842     return s;
2843 }
2844
2845 static void vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t * mp)
2846 {
2847     vat_main_t * vam = &vat_main;
2848     i32 retval = ntohl(mp->retval);
2849     if (retval == 0) {
2850         fformat (vam->ofp, "classify table info :\n");
2851         fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n", ntohl(mp->active_sessions), ntohl(mp->next_table_index), ntohl(mp->miss_next_index));
2852         fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n", ntohl(mp->nbuckets), ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
2853         fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask, ntohl(mp->mask_length));
2854     }
2855     vam->retval = retval;
2856     vam->result_ready = 1;
2857 }
2858
2859 static void vl_api_classify_table_info_reply_t_handler_json (vl_api_classify_table_info_reply_t * mp)
2860 {
2861     vat_main_t * vam = &vat_main;
2862     vat_json_node_t node;
2863
2864     i32 retval = ntohl(mp->retval);
2865     if (retval == 0) {
2866         vat_json_init_object(&node);
2867
2868         vat_json_object_add_int(&node, "sessions", ntohl(mp->active_sessions));
2869         vat_json_object_add_int(&node, "nexttbl", ntohl(mp->next_table_index));
2870         vat_json_object_add_int(&node, "nextnode", ntohl(mp->miss_next_index));
2871         vat_json_object_add_int(&node, "nbuckets", ntohl(mp->nbuckets));
2872         vat_json_object_add_int(&node, "skip", ntohl(mp->skip_n_vectors));
2873         vat_json_object_add_int(&node, "match", ntohl(mp->match_n_vectors));
2874         u8 * s = format (0, "%U%c",format_hex_bytes, mp->mask, ntohl(mp->mask_length), 0);
2875         vat_json_object_add_string_copy(&node, "mask", s);
2876
2877         vat_json_print(vam->ofp, &node);
2878         vat_json_free(&node);
2879     }
2880     vam->retval = ntohl(mp->retval);
2881     vam->result_ready = 1;
2882 }
2883
2884 static void vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t * mp)
2885 {
2886     vat_main_t * vam = &vat_main;
2887
2888     fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ", ntohl(mp->hit_next_index), ntohl(mp->advance), ntohl(mp->opaque_index));
2889     fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match, ntohl(mp->match_length));
2890 }
2891
2892 static void vl_api_classify_session_details_t_handler_json (vl_api_classify_session_details_t * mp)
2893 {
2894     vat_main_t * vam = &vat_main;
2895     vat_json_node_t *node = NULL;
2896
2897     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2898         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2899         vat_json_init_array(&vam->json_tree);
2900     }
2901     node = vat_json_array_add(&vam->json_tree);
2902
2903     vat_json_init_object(node);
2904     vat_json_object_add_int(node, "next_index", ntohl(mp->hit_next_index));
2905     vat_json_object_add_int(node, "advance", ntohl(mp->advance));
2906     vat_json_object_add_int(node, "opaque", ntohl(mp->opaque_index));
2907     u8 * s = format (0, "%U%c",format_hex_bytes, mp->match, ntohl(mp->match_length), 0);
2908     vat_json_object_add_string_copy(node, "match", s);
2909 }
2910
2911 static void vl_api_pg_create_interface_reply_t_handler
2912 (vl_api_pg_create_interface_reply_t * mp)
2913 {
2914     vat_main_t * vam = &vat_main;
2915
2916     vam->retval = ntohl(mp->retval);
2917     vam->result_ready = 1;
2918 }
2919
2920 static void vl_api_pg_create_interface_reply_t_handler_json
2921 (vl_api_pg_create_interface_reply_t * mp)
2922 {
2923     vat_main_t * vam = &vat_main;
2924     vat_json_node_t node;
2925
2926     i32 retval = ntohl(mp->retval);
2927     if (retval == 0) {
2928         vat_json_init_object(&node);
2929
2930         vat_json_object_add_int(&node, "sw_if_index", ntohl(mp->sw_if_index));
2931
2932         vat_json_print(vam->ofp, &node);
2933         vat_json_free(&node);
2934     }
2935     vam->retval = ntohl(mp->retval);
2936     vam->result_ready = 1;
2937 }
2938
2939 static void vl_api_policer_classify_details_t_handler
2940 (vl_api_policer_classify_details_t * mp)
2941 {
2942     vat_main_t * vam = &vat_main;
2943
2944     fformat (vam->ofp, "%10d%20d\n", ntohl(mp->sw_if_index),
2945              ntohl(mp->table_index));
2946 }
2947
2948 static void vl_api_policer_classify_details_t_handler_json
2949 (vl_api_policer_classify_details_t * mp)
2950 {
2951     vat_main_t * vam = &vat_main;
2952     vat_json_node_t * node;
2953
2954     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2955         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2956         vat_json_init_array(&vam->json_tree);
2957     }
2958     node = vat_json_array_add(&vam->json_tree);
2959
2960     vat_json_init_object(node);
2961     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
2962     vat_json_object_add_uint(node, "table_index", ntohl(mp->table_index));
2963 }
2964
2965
2966 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2967 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2968 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2969 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2970
2971 /*
2972  * Generate boilerplate reply handlers, which
2973  * dig the return value out of the xxx_reply_t API message,
2974  * stick it into vam->retval, and set vam->result_ready
2975  *
2976  * Could also do this by pointing N message decode slots at
2977  * a single function, but that could break in subtle ways.
2978  */
2979
2980 #define foreach_standard_reply_retval_handler           \
2981 _(sw_interface_set_flags_reply)                         \
2982 _(sw_interface_add_del_address_reply)                   \
2983 _(sw_interface_set_table_reply)                         \
2984 _(sw_interface_set_vpath_reply)                         \
2985 _(sw_interface_set_l2_bridge_reply)                     \
2986 _(bridge_domain_add_del_reply)                          \
2987 _(sw_interface_set_l2_xconnect_reply)                   \
2988 _(l2fib_add_del_reply)                                  \
2989 _(ip_add_del_route_reply)                               \
2990 _(proxy_arp_add_del_reply)                              \
2991 _(proxy_arp_intfc_enable_disable_reply)                 \
2992 _(mpls_add_del_encap_reply)                             \
2993 _(mpls_add_del_decap_reply)                             \
2994 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
2995 _(sw_interface_set_unnumbered_reply)                    \
2996 _(ip_neighbor_add_del_reply)                            \
2997 _(reset_vrf_reply)                                      \
2998 _(oam_add_del_reply)                                    \
2999 _(reset_fib_reply)                                      \
3000 _(dhcp_proxy_config_reply)                              \
3001 _(dhcp_proxy_config_2_reply)                            \
3002 _(dhcp_proxy_set_vss_reply)                             \
3003 _(dhcp_client_config_reply)                             \
3004 _(set_ip_flow_hash_reply)                               \
3005 _(sw_interface_ip6_enable_disable_reply)                \
3006 _(sw_interface_ip6_set_link_local_address_reply)        \
3007 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3008 _(sw_interface_ip6nd_ra_config_reply)                   \
3009 _(set_arp_neighbor_limit_reply)                         \
3010 _(l2_patch_add_del_reply)                               \
3011 _(sr_tunnel_add_del_reply)                              \
3012 _(sr_policy_add_del_reply)                              \
3013 _(sr_multicast_map_add_del_reply)                       \
3014 _(classify_add_del_session_reply)                       \
3015 _(classify_set_interface_ip_table_reply)                \
3016 _(classify_set_interface_l2_tables_reply)               \
3017 _(l2tpv3_set_tunnel_cookies_reply)                      \
3018 _(l2tpv3_interface_enable_disable_reply)                \
3019 _(l2tpv3_set_lookup_key_reply)                          \
3020 _(l2_fib_clear_table_reply)                             \
3021 _(l2_interface_efp_filter_reply)                        \
3022 _(l2_interface_vlan_tag_rewrite_reply)                  \
3023 _(modify_vhost_user_if_reply)                           \
3024 _(delete_vhost_user_if_reply)                           \
3025 _(want_ip4_arp_events_reply)                            \
3026 _(input_acl_set_interface_reply)                        \
3027 _(ipsec_spd_add_del_reply)                              \
3028 _(ipsec_interface_add_del_spd_reply)                    \
3029 _(ipsec_spd_add_del_entry_reply)                        \
3030 _(ipsec_sad_add_del_entry_reply)                        \
3031 _(ipsec_sa_set_key_reply)                               \
3032 _(ikev2_profile_add_del_reply)                          \
3033 _(ikev2_profile_set_auth_reply)                         \
3034 _(ikev2_profile_set_id_reply)                           \
3035 _(ikev2_profile_set_ts_reply)                           \
3036 _(ikev2_set_local_key_reply)                            \
3037 _(delete_loopback_reply)                                \
3038 _(bd_ip_mac_add_del_reply)                              \
3039 _(map_del_domain_reply)                                 \
3040 _(map_add_del_rule_reply)                               \
3041 _(want_interface_events_reply)                          \
3042 _(want_stats_reply)                                     \
3043 _(cop_interface_enable_disable_reply)                   \
3044 _(cop_whitelist_enable_disable_reply)                   \
3045 _(sw_interface_clear_stats_reply)                       \
3046 _(trace_profile_add_reply)                              \
3047 _(trace_profile_apply_reply)                            \
3048 _(trace_profile_del_reply)                              \
3049 _(lisp_add_del_locator_set_reply)                       \
3050 _(lisp_add_del_locator_reply)                           \
3051 _(lisp_add_del_local_eid_reply)                         \
3052 _(lisp_add_del_remote_mapping_reply)                    \
3053 _(lisp_add_del_adjacency_reply)                         \
3054 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3055 _(lisp_add_del_map_resolver_reply)                      \
3056 _(lisp_gpe_enable_disable_reply)                        \
3057 _(lisp_gpe_add_del_iface_reply)                         \
3058 _(lisp_enable_disable_reply)                            \
3059 _(lisp_pitr_set_locator_set_reply)                      \
3060 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3061 _(lisp_eid_table_add_del_map_reply)                     \
3062 _(vxlan_gpe_add_del_tunnel_reply)                       \
3063 _(af_packet_delete_reply)                               \
3064 _(policer_classify_set_interface_reply)                 \
3065 _(netmap_create_reply)                                  \
3066 _(netmap_delete_reply)                                  \
3067 _(ipfix_enable_reply)                                   \
3068 _(pg_capture_reply)                                     \
3069 _(pg_enable_disable_reply)
3070
3071 #define _(n)                                    \
3072     static void vl_api_##n##_t_handler          \
3073     (vl_api_##n##_t * mp)                       \
3074     {                                           \
3075         vat_main_t * vam = &vat_main;           \
3076         i32 retval = ntohl(mp->retval);         \
3077         if (vam->async_mode) {                  \
3078             vam->async_errors += (retval < 0);  \
3079         } else {                                \
3080             vam->retval = retval;               \
3081             vam->result_ready = 1;              \
3082         }                                       \
3083     }
3084 foreach_standard_reply_retval_handler;
3085 #undef _
3086
3087 #define _(n)                                    \
3088     static void vl_api_##n##_t_handler_json     \
3089     (vl_api_##n##_t * mp)                       \
3090     {                                           \
3091         vat_main_t * vam = &vat_main;           \
3092         vat_json_node_t node;                   \
3093         vat_json_init_object(&node);            \
3094         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3095         vat_json_print(vam->ofp, &node);        \
3096         vam->retval = ntohl(mp->retval);        \
3097         vam->result_ready = 1;                  \
3098     }
3099 foreach_standard_reply_retval_handler;
3100 #undef _
3101
3102 /*
3103  * Table of message reply handlers, must include boilerplate handlers
3104  * we just generated
3105  */
3106
3107 #define foreach_vpe_api_reply_msg                                       \
3108 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3109 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3110 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3111 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3112 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3113 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3114 _(CLI_REPLY, cli_reply)                                                 \
3115 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3116   sw_interface_add_del_address_reply)                                   \
3117 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3118 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3119 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3120   sw_interface_set_l2_xconnect_reply)                                   \
3121 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3122   sw_interface_set_l2_bridge_reply)                                     \
3123 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3124 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3125 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3126 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3127 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3128 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3129 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3130 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3131 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3132 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3133 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3134 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3135 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3136   proxy_arp_intfc_enable_disable_reply)                                 \
3137 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3138 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3139 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3140 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3141   mpls_ethernet_add_del_tunnel_reply)                                   \
3142 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3143   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3144 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3145   sw_interface_set_unnumbered_reply)                                    \
3146 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3147 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3148 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3149 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3150 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3151 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3152 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3153 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3154 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3155 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3156 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3157 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3158   sw_interface_ip6_enable_disable_reply)                                \
3159 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3160   sw_interface_ip6_set_link_local_address_reply)                        \
3161 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3162   sw_interface_ip6nd_ra_prefix_reply)                                   \
3163 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3164   sw_interface_ip6nd_ra_config_reply)                                   \
3165 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3166 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3167 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3168 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3169 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3170 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3171 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3172 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3173 classify_set_interface_ip_table_reply)                                  \
3174 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3175   classify_set_interface_l2_tables_reply)                               \
3176 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3177 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3178 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3179 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3180 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3181   l2tpv3_interface_enable_disable_reply)                                \
3182 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3183 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3184 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3185 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3186 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3187 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3188 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3189 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3190 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3191 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3192 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3193 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3194 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3195 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3196 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3197 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3198 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3199 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3200 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3201 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3202 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3203 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3204 _(IP_DETAILS, ip_details)                                               \
3205 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3206 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3207 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3208 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3209 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3210 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3211 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3212 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3213 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3214 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3215 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3216 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3217 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3218 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3219 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3220 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3221 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3222 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3223 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3224 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3225 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3226 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3227 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3228 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3229 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3230 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3231 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3232 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3233 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3234 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3235 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3236 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3237 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3238 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3239 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3240 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3241 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3242 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3243 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3244 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3245 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3246 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3247 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3248 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3249 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3250 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3251 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3252 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3253 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3254 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3255 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3256   lisp_add_del_map_request_itr_rlocs_reply)                             \
3257 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3258   lisp_get_map_request_itr_rlocs_reply)                                 \
3259 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3260 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3261 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3262 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3263 _(POLICER_DETAILS, policer_details)                                     \
3264 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3265 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3266 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3267 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3268 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3269 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3270 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3271 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3272 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3273 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3274 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3275 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3276 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3277 _(IPFIX_DETAILS, ipfix_details)                                         \
3278 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3279 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3280 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3281 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)
3282
3283 /* M: construct, but don't yet send a message */
3284
3285 #define M(T,t)                                  \
3286 do {                                            \
3287     vam->result_ready = 0;                      \
3288     mp = vl_msg_api_alloc(sizeof(*mp));         \
3289     memset (mp, 0, sizeof (*mp));               \
3290     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3291     mp->client_index = vam->my_client_index;    \
3292 } while(0);
3293
3294 #define M2(T,t,n)                               \
3295 do {                                            \
3296     vam->result_ready = 0;                      \
3297     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3298     memset (mp, 0, sizeof (*mp));               \
3299     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3300     mp->client_index = vam->my_client_index;    \
3301 } while(0);
3302
3303
3304 /* S: send a message */
3305 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3306
3307 /* W: wait for results, with timeout */
3308 #define W                                       \
3309 do {                                            \
3310     timeout = vat_time_now (vam) + 1.0;         \
3311                                                 \
3312     while (vat_time_now (vam) < timeout) {      \
3313         if (vam->result_ready == 1) {           \
3314             return (vam->retval);               \
3315         }                                       \
3316     }                                           \
3317     return -99;                                 \
3318 } while(0);
3319
3320 /* W2: wait for results, with timeout */
3321 #define W2(body)                                \
3322 do {                                            \
3323     timeout = vat_time_now (vam) + 1.0;         \
3324                                                 \
3325     while (vat_time_now (vam) < timeout) {      \
3326         if (vam->result_ready == 1) {           \
3327           (body);                               \
3328           return (vam->retval);                 \
3329         }                                       \
3330     }                                           \
3331     return -99;                                 \
3332 } while(0);
3333
3334 /* W_L: wait for results, with timeout */
3335 #define W_L(body)                               \
3336 do {                                            \
3337     timeout = vat_time_now (vam) + 1.0;         \
3338                                                 \
3339     while (vat_time_now (vam) < timeout) {      \
3340         if (vam->result_ready == 1) {           \
3341           (body);                               \
3342           return (vam->retval);                 \
3343         }                                       \
3344     }                                           \
3345     vam->noprint_msg = 0;     \
3346     return -99;                                 \
3347 } while(0);
3348
3349 typedef struct {
3350     u8 * name;
3351     u32 value;
3352 } name_sort_t;
3353
3354
3355 #define STR_VTR_OP_CASE(op)     \
3356     case L2_VTR_ ## op:         \
3357         return "" # op;
3358
3359 static const char *str_vtr_op(u32 vtr_op)
3360 {
3361     switch(vtr_op) {
3362         STR_VTR_OP_CASE(DISABLED);
3363         STR_VTR_OP_CASE(PUSH_1);
3364         STR_VTR_OP_CASE(PUSH_2);
3365         STR_VTR_OP_CASE(POP_1);
3366         STR_VTR_OP_CASE(POP_2);
3367         STR_VTR_OP_CASE(TRANSLATE_1_1);
3368         STR_VTR_OP_CASE(TRANSLATE_1_2);
3369         STR_VTR_OP_CASE(TRANSLATE_2_1);
3370         STR_VTR_OP_CASE(TRANSLATE_2_2);
3371     }
3372
3373     return "UNKNOWN";
3374 }
3375
3376 static int dump_sub_interface_table (vat_main_t * vam)
3377 {
3378     const sw_interface_subif_t * sub = NULL;
3379
3380     if (vam->json_output) {
3381         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3382         return -99;
3383     }
3384
3385     fformat (vam->ofp,
3386              "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3387              "Interface", "sw_if_index",
3388              "sub id", "dot1ad", "tags", "outer id",
3389              "inner id", "exact", "default",
3390              "outer any", "inner any");
3391
3392     vec_foreach (sub, vam->sw_if_subif_table) {
3393         fformat (vam->ofp,
3394                  "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3395                  sub->interface_name,
3396                  sub->sw_if_index,
3397                  sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3398                  sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3399                  sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3400                  sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3401         if (sub->vtr_op != L2_VTR_DISABLED) {
3402             fformat (vam->ofp,
3403                      "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3404                      "tag1: %d tag2: %d ]\n",
3405                      str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
3406                      sub->vtr_tag1, sub->vtr_tag2);
3407         }
3408     }
3409
3410     return 0;
3411 }
3412
3413 static int name_sort_cmp (void * a1, void * a2)
3414 {
3415   name_sort_t * n1 = a1;
3416   name_sort_t * n2 = a2;
3417
3418   return strcmp ((char *)n1->name, (char *)n2->name);
3419 }
3420
3421 static int dump_interface_table (vat_main_t * vam)
3422 {
3423     hash_pair_t * p;
3424     name_sort_t * nses = 0, * ns;
3425
3426     if (vam->json_output) {
3427         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3428         return -99;
3429     }
3430
3431     hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3432     ({
3433         vec_add2 (nses, ns, 1);
3434         ns->name = (u8 *)(p->key);
3435         ns->value = (u32) p->value[0];
3436     }));
3437
3438     vec_sort_with_function (nses, name_sort_cmp);
3439
3440     fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3441     vec_foreach (ns, nses) {
3442         fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3443     }
3444     vec_free (nses);
3445     return 0;
3446 }
3447
3448 static int dump_ip_table (vat_main_t * vam, int is_ipv6)
3449 {
3450     const ip_details_t * det = NULL;
3451     const ip_address_details_t * address = NULL;
3452     u32 i = ~0;
3453
3454     fformat (vam->ofp,
3455              "%-12s\n",
3456              "sw_if_index");
3457
3458     if (0 == vam) {
3459         return 0;
3460     }
3461
3462     vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
3463         i++;
3464         if (!det->present) {
3465             continue;
3466         }
3467         fformat (vam->ofp,
3468                  "%-12d\n",
3469                  i);
3470         fformat (vam->ofp,
3471                  "            %-30s%-13s\n",
3472                  "Address", "Prefix length");
3473         if (!det->addr) {
3474             continue;
3475         }
3476         vec_foreach (address, det->addr) {
3477             fformat (vam->ofp,
3478                      "            %-30U%-13d\n",
3479                      is_ipv6 ? format_ip6_address : format_ip4_address,
3480                      address->ip,
3481                      address->prefix_length);
3482         }
3483     }
3484
3485     return 0;
3486 }
3487
3488 static int dump_ipv4_table (vat_main_t * vam)
3489 {
3490     if (vam->json_output) {
3491         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3492         return -99;
3493     }
3494
3495     return dump_ip_table (vam, 0);
3496 }
3497
3498 static int dump_ipv6_table (vat_main_t * vam)
3499 {
3500     if (vam->json_output) {
3501         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
3502         return -99;
3503     }
3504
3505     return dump_ip_table (vam, 1);
3506 }
3507
3508 static char* counter_type_to_str (u8 counter_type, u8 is_combined)
3509 {
3510     if (!is_combined) {
3511         switch(counter_type) {
3512         case VNET_INTERFACE_COUNTER_DROP:
3513             return "drop";
3514         case VNET_INTERFACE_COUNTER_PUNT:
3515             return "punt";
3516         case VNET_INTERFACE_COUNTER_IP4:
3517             return "ip4";
3518         case VNET_INTERFACE_COUNTER_IP6:
3519             return "ip6";
3520         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3521             return "rx-no-buf";
3522         case VNET_INTERFACE_COUNTER_RX_MISS:
3523             return "rx-miss";
3524         case VNET_INTERFACE_COUNTER_RX_ERROR:
3525             return "rx-error";
3526         case VNET_INTERFACE_COUNTER_TX_ERROR:
3527             return "tx-error";
3528         default:
3529             return "INVALID-COUNTER-TYPE";
3530         }
3531     } else {
3532         switch(counter_type) {
3533         case VNET_INTERFACE_COUNTER_RX:
3534             return "rx";
3535         case VNET_INTERFACE_COUNTER_TX:
3536             return "tx";
3537         default:
3538             return "INVALID-COUNTER-TYPE";
3539         }
3540     }
3541 }
3542
3543 static int dump_stats_table (vat_main_t * vam)
3544 {
3545     vat_json_node_t node;
3546     vat_json_node_t *msg_array;
3547     vat_json_node_t *msg;
3548     vat_json_node_t *counter_array;
3549     vat_json_node_t *counter;
3550     interface_counter_t c;
3551     u64 packets;
3552     ip4_fib_counter_t *c4;
3553     ip6_fib_counter_t *c6;
3554     int i, j;
3555
3556     if (!vam->json_output) {
3557         clib_warning ("dump_stats_table supported only in JSON format");
3558         return -99;
3559     }
3560
3561     vat_json_init_object(&node);
3562
3563     /* interface counters */
3564     msg_array = vat_json_object_add(&node, "interface_counters");
3565     vat_json_init_array(msg_array);
3566     for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
3567         msg = vat_json_array_add(msg_array);
3568         vat_json_init_object(msg);
3569         vat_json_object_add_string_copy(msg, "vnet_counter_type",
3570                 (u8*)counter_type_to_str(i, 0));
3571         vat_json_object_add_int(msg, "is_combined", 0);
3572         counter_array = vat_json_object_add(msg, "data");
3573         vat_json_init_array(counter_array);
3574         for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
3575             packets = vam->simple_interface_counters[i][j];
3576             vat_json_array_add_uint(counter_array, packets);
3577         }
3578     }
3579     for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
3580         msg = vat_json_array_add(msg_array);
3581         vat_json_init_object(msg);
3582         vat_json_object_add_string_copy(msg, "vnet_counter_type",
3583                 (u8*)counter_type_to_str(i, 1));
3584         vat_json_object_add_int(msg, "is_combined", 1);
3585         counter_array = vat_json_object_add(msg, "data");
3586         vat_json_init_array(counter_array);
3587         for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
3588             c = vam->combined_interface_counters[i][j];
3589             counter = vat_json_array_add(counter_array);
3590             vat_json_init_object(counter);
3591             vat_json_object_add_uint(counter, "packets", c.packets);
3592             vat_json_object_add_uint(counter, "bytes", c.bytes);
3593         }
3594     }
3595
3596     /* ip4 fib counters */
3597     msg_array = vat_json_object_add(&node, "ip4_fib_counters");
3598     vat_json_init_array(msg_array);
3599     for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
3600         msg = vat_json_array_add(msg_array);
3601         vat_json_init_object(msg);
3602         vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
3603         counter_array = vat_json_object_add(msg, "c");
3604         vat_json_init_array(counter_array);
3605         for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
3606             counter = vat_json_array_add(counter_array);
3607             vat_json_init_object(counter);
3608             c4 = &vam->ip4_fib_counters[i][j];
3609             vat_json_object_add_ip4(counter, "address", c4->address);
3610             vat_json_object_add_uint(counter, "address_length", c4->address_length);
3611             vat_json_object_add_uint(counter, "packets", c4->packets);
3612             vat_json_object_add_uint(counter, "bytes", c4->bytes);
3613         }
3614     }
3615
3616     /* ip6 fib counters */
3617     msg_array = vat_json_object_add(&node, "ip6_fib_counters");
3618     vat_json_init_array(msg_array);
3619     for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
3620         msg = vat_json_array_add(msg_array);
3621         vat_json_init_object(msg);
3622         vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
3623         counter_array = vat_json_object_add(msg, "c");
3624         vat_json_init_array(counter_array);
3625         for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
3626             counter = vat_json_array_add(counter_array);
3627             vat_json_init_object(counter);
3628             c6 = &vam->ip6_fib_counters[i][j];
3629             vat_json_object_add_ip6(counter, "address", c6->address);
3630             vat_json_object_add_uint(counter, "address_length", c6->address_length);
3631             vat_json_object_add_uint(counter, "packets", c6->packets);
3632             vat_json_object_add_uint(counter, "bytes", c6->bytes);
3633         }
3634     }
3635
3636     vat_json_print(vam->ofp, &node);
3637     vat_json_free(&node);
3638
3639     return 0;
3640 }
3641
3642 int exec (vat_main_t * vam)
3643 {
3644     api_main_t * am = &api_main;
3645     vl_api_cli_request_t *mp;
3646     f64 timeout;
3647     void * oldheap;
3648     u8 * cmd = 0;
3649     unformat_input_t * i = vam->input;
3650
3651     if (vec_len(i->buffer) == 0)
3652         return -1;
3653
3654     if (vam->exec_mode == 0 && unformat (i, "mode")) {
3655         vam->exec_mode = 1;
3656         return 0;
3657     }
3658     if (vam->exec_mode == 1 &&
3659         (unformat (i, "exit") || unformat (i, "quit"))) {
3660         vam->exec_mode = 0;
3661         return 0;
3662     }
3663
3664
3665     M(CLI_REQUEST, cli_request);
3666
3667     /*
3668      * Copy cmd into shared memory.
3669      * In order for the CLI command to work, it
3670      * must be a vector ending in \n, not a C-string ending
3671      * in \n\0.
3672      */
3673     pthread_mutex_lock (&am->vlib_rp->mutex);
3674     oldheap = svm_push_data_heap (am->vlib_rp);
3675
3676     vec_validate (cmd, vec_len(vam->input->buffer)-1);
3677     clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
3678
3679     svm_pop_heap (oldheap);
3680     pthread_mutex_unlock (&am->vlib_rp->mutex);
3681
3682     mp->cmd_in_shmem = (u64) cmd;
3683     S;
3684     timeout = vat_time_now (vam) + 10.0;
3685
3686     while (vat_time_now (vam) < timeout) {
3687         if (vam->result_ready == 1) {
3688             u8 * free_me;
3689             if (vam->shmem_result != NULL)
3690                 fformat (vam->ofp, "%s", vam->shmem_result);
3691             pthread_mutex_lock (&am->vlib_rp->mutex);
3692             oldheap = svm_push_data_heap (am->vlib_rp);
3693
3694             free_me = (u8 *)vam->shmem_result;
3695             vec_free (free_me);
3696
3697             svm_pop_heap (oldheap);
3698             pthread_mutex_unlock (&am->vlib_rp->mutex);
3699             return 0;
3700         }
3701     }
3702     return -99;
3703 }
3704
3705 static int api_create_loopback (vat_main_t * vam)
3706 {
3707     unformat_input_t * i = vam->input;
3708     vl_api_create_loopback_t *mp;
3709     f64 timeout;
3710     u8 mac_address[6];
3711     u8 mac_set = 0;
3712
3713     memset (mac_address, 0, sizeof (mac_address));
3714
3715     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3716       {
3717         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3718             mac_set = 1;
3719         else
3720           break;
3721       }
3722
3723     /* Construct the API message */
3724     M(CREATE_LOOPBACK, create_loopback);
3725     if (mac_set)
3726         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3727
3728     S; W;
3729 }
3730
3731 static int api_delete_loopback (vat_main_t * vam)
3732 {
3733     unformat_input_t * i = vam->input;
3734     vl_api_delete_loopback_t *mp;
3735     f64 timeout;
3736     u32 sw_if_index = ~0;
3737
3738     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3739       {
3740         if (unformat (i, "sw_if_index %d", &sw_if_index))
3741           ;
3742         else
3743           break;
3744       }
3745
3746     if (sw_if_index == ~0)
3747       {
3748         errmsg ("missing sw_if_index\n");
3749         return -99;
3750       }
3751
3752     /* Construct the API message */
3753     M(DELETE_LOOPBACK, delete_loopback);
3754     mp->sw_if_index = ntohl (sw_if_index);
3755
3756     S; W;
3757 }
3758
3759 static int api_want_stats (vat_main_t * vam)
3760 {
3761     unformat_input_t * i = vam->input;
3762     vl_api_want_stats_t * mp;
3763     f64 timeout;
3764     int enable = -1;
3765
3766     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3767       {
3768         if (unformat (i, "enable"))
3769           enable = 1;
3770         else if (unformat (i, "disable"))
3771           enable = 0;
3772         else
3773           break;
3774       }
3775
3776     if (enable == -1)
3777       {
3778         errmsg ("missing enable|disable\n");
3779         return -99;
3780       }
3781
3782     M(WANT_STATS, want_stats);
3783     mp->enable_disable = enable;
3784
3785     S; W;
3786 }
3787
3788 static int api_want_interface_events (vat_main_t * vam)
3789 {
3790     unformat_input_t * i = vam->input;
3791     vl_api_want_interface_events_t * mp;
3792     f64 timeout;
3793     int enable = -1;
3794
3795     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3796       {
3797         if (unformat (i, "enable"))
3798           enable = 1;
3799         else if (unformat (i, "disable"))
3800           enable = 0;
3801         else
3802           break;
3803       }
3804
3805     if (enable == -1)
3806       {
3807         errmsg ("missing enable|disable\n");
3808         return -99;
3809       }
3810
3811     M(WANT_INTERFACE_EVENTS, want_interface_events);
3812     mp->enable_disable = enable;
3813
3814     vam->interface_event_display = enable;
3815
3816     S; W;
3817 }
3818
3819
3820 /* Note: non-static, called once to set up the initial intfc table */
3821 int api_sw_interface_dump (vat_main_t * vam)
3822 {
3823     vl_api_sw_interface_dump_t *mp;
3824     f64 timeout;
3825     hash_pair_t * p;
3826     name_sort_t * nses = 0, * ns;
3827     sw_interface_subif_t * sub = NULL;
3828
3829     /* Toss the old name table */
3830     hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3831     ({
3832         vec_add2 (nses, ns, 1);
3833         ns->name = (u8 *)(p->key);
3834         ns->value = (u32) p->value[0];
3835     }));
3836
3837     hash_free (vam->sw_if_index_by_interface_name);
3838
3839     vec_foreach (ns, nses)
3840         vec_free (ns->name);
3841
3842     vec_free (nses);
3843
3844     vec_foreach (sub, vam->sw_if_subif_table) {
3845         vec_free (sub->interface_name);
3846     }
3847     vec_free (vam->sw_if_subif_table);
3848
3849     /* recreate the interface name hash table */
3850     vam->sw_if_index_by_interface_name
3851         = hash_create_string (0, sizeof(uword));
3852
3853     /* Get list of ethernets */
3854     M(SW_INTERFACE_DUMP, sw_interface_dump);
3855     mp->name_filter_valid = 1;
3856     strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
3857     S;
3858
3859     /* and local / loopback interfaces */
3860     M(SW_INTERFACE_DUMP, sw_interface_dump);
3861     mp->name_filter_valid = 1;
3862     strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
3863     S;
3864
3865
3866     /* and vxlan-gpe tunnel interfaces */
3867     M(SW_INTERFACE_DUMP, sw_interface_dump);
3868     mp->name_filter_valid = 1;
3869     strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3870     S;
3871
3872     /* and vxlan tunnel interfaces */
3873     M(SW_INTERFACE_DUMP, sw_interface_dump);
3874     mp->name_filter_valid = 1;
3875     strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
3876     S;
3877
3878     /* and host (af_packet) interfaces */
3879     M(SW_INTERFACE_DUMP, sw_interface_dump);
3880     mp->name_filter_valid = 1;
3881     strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
3882     S;
3883
3884     /* and l2tpv3 tunnel interfaces */
3885     M(SW_INTERFACE_DUMP, sw_interface_dump);
3886     mp->name_filter_valid = 1;
3887     strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
3888     S;
3889
3890     /* and GRE tunnel interfaces */
3891     M(SW_INTERFACE_DUMP, sw_interface_dump);
3892     mp->name_filter_valid = 1;
3893     strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3894     S;
3895
3896     /* Use a control ping for synchronization */
3897     {
3898         vl_api_control_ping_t * mp;
3899         M(CONTROL_PING, control_ping);
3900         S;
3901     }
3902     W;
3903 }
3904
3905 static int api_sw_interface_set_flags (vat_main_t * vam)
3906 {
3907     unformat_input_t * i = vam->input;
3908     vl_api_sw_interface_set_flags_t *mp;
3909     f64 timeout;
3910     u32 sw_if_index;
3911     u8 sw_if_index_set = 0;
3912     u8 admin_up = 0, link_up = 0;
3913
3914     /* Parse args required to build the message */
3915     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3916         if (unformat (i, "admin-up"))
3917             admin_up = 1;
3918         else if (unformat (i, "admin-down"))
3919             admin_up = 0;
3920         else if (unformat (i, "link-up"))
3921             link_up = 1;
3922         else if (unformat (i, "link-down"))
3923             link_up = 0;
3924         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3925             sw_if_index_set = 1;
3926         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3927             sw_if_index_set = 1;
3928         else
3929             break;
3930     }
3931
3932     if (sw_if_index_set == 0) {
3933         errmsg ("missing interface name or sw_if_index\n");
3934         return -99;
3935     }
3936
3937     /* Construct the API message */
3938     M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3939     mp->sw_if_index = ntohl (sw_if_index);
3940     mp->admin_up_down = admin_up;
3941     mp->link_up_down = link_up;
3942
3943     /* send it... */
3944     S;
3945
3946     /* Wait for a reply, return the good/bad news... */
3947     W;
3948 }
3949
3950 static int api_sw_interface_clear_stats (vat_main_t * vam)
3951 {
3952     unformat_input_t * i = vam->input;
3953     vl_api_sw_interface_clear_stats_t *mp;
3954     f64 timeout;
3955     u32 sw_if_index;
3956     u8 sw_if_index_set = 0;
3957
3958     /* Parse args required to build the message */
3959     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3960         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3961             sw_if_index_set = 1;
3962         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3963             sw_if_index_set = 1;
3964         else
3965             break;
3966     }
3967
3968     /* Construct the API message */
3969     M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3970
3971     if (sw_if_index_set == 1)
3972         mp->sw_if_index = ntohl (sw_if_index);
3973     else
3974         mp->sw_if_index = ~0;
3975
3976     /* send it... */
3977     S;
3978
3979     /* Wait for a reply, return the good/bad news... */
3980     W;
3981 }
3982
3983 static int api_sw_interface_add_del_address (vat_main_t * vam)
3984 {
3985     unformat_input_t * i = vam->input;
3986     vl_api_sw_interface_add_del_address_t *mp;
3987     f64 timeout;
3988     u32 sw_if_index;
3989     u8 sw_if_index_set = 0;
3990     u8 is_add = 1, del_all = 0;
3991     u32 address_length = 0;
3992     u8 v4_address_set = 0;
3993     u8 v6_address_set = 0;
3994     ip4_address_t v4address;
3995     ip6_address_t v6address;
3996
3997     /* Parse args required to build the message */
3998     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3999         if (unformat (i, "del-all"))
4000             del_all = 1;
4001         else if (unformat (i, "del"))
4002             is_add = 0;
4003         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4004             sw_if_index_set = 1;
4005         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4006             sw_if_index_set = 1;
4007         else if (unformat (i, "%U/%d",
4008                            unformat_ip4_address, &v4address,
4009                            &address_length))
4010             v4_address_set = 1;
4011         else if (unformat (i, "%U/%d",
4012                            unformat_ip6_address, &v6address,
4013                            &address_length))
4014             v6_address_set = 1;
4015         else
4016             break;
4017     }
4018
4019     if (sw_if_index_set == 0) {
4020         errmsg ("missing interface name or sw_if_index\n");
4021         return -99;
4022     }
4023     if (v4_address_set && v6_address_set) {
4024         errmsg ("both v4 and v6 addresses set\n");
4025         return -99;
4026     }
4027     if (!v4_address_set && !v6_address_set && !del_all) {
4028         errmsg ("no addresses set\n");
4029         return -99;
4030     }
4031
4032     /* Construct the API message */
4033     M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4034
4035     mp->sw_if_index = ntohl (sw_if_index);
4036     mp->is_add = is_add;
4037     mp->del_all = del_all;
4038     if (v6_address_set) {
4039         mp->is_ipv6 = 1;
4040         clib_memcpy (mp->address, &v6address, sizeof (v6address));
4041     } else {
4042         clib_memcpy (mp->address, &v4address, sizeof (v4address));
4043     }
4044     mp->address_length = address_length;
4045
4046     /* send it... */
4047     S;
4048
4049     /* Wait for a reply, return good/bad news  */
4050     W;
4051 }
4052
4053 static int api_sw_interface_set_table (vat_main_t * vam)
4054 {
4055     unformat_input_t * i = vam->input;
4056     vl_api_sw_interface_set_table_t *mp;
4057     f64 timeout;
4058     u32 sw_if_index, vrf_id = 0;
4059     u8 sw_if_index_set = 0;
4060     u8 is_ipv6 = 0;
4061
4062     /* Parse args required to build the message */
4063     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4064         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4065             sw_if_index_set = 1;
4066         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4067             sw_if_index_set = 1;
4068         else if (unformat (i, "vrf %d", &vrf_id))
4069             ;
4070         else if (unformat (i, "ipv6"))
4071             is_ipv6 = 1;
4072         else
4073             break;
4074     }
4075
4076     if (sw_if_index_set == 0) {
4077         errmsg ("missing interface name or sw_if_index\n");
4078         return -99;
4079     }
4080
4081     /* Construct the API message */
4082     M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4083
4084     mp->sw_if_index = ntohl (sw_if_index);
4085     mp->is_ipv6 = is_ipv6;
4086     mp->vrf_id = ntohl (vrf_id);
4087
4088     /* send it... */
4089     S;
4090
4091     /* Wait for a reply... */
4092     W;
4093 }
4094
4095 static int api_sw_interface_set_vpath (vat_main_t * vam)
4096 {
4097     unformat_input_t * i = vam->input;
4098     vl_api_sw_interface_set_vpath_t *mp;
4099     f64 timeout;
4100     u32 sw_if_index = 0;
4101     u8 sw_if_index_set = 0;
4102     u8 is_enable = 0;
4103
4104     /* Parse args required to build the message */
4105     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4106         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4107             sw_if_index_set = 1;
4108         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4109             sw_if_index_set = 1;
4110         else if (unformat (i, "enable"))
4111             is_enable = 1;
4112         else if (unformat (i, "disable"))
4113             is_enable = 0;
4114         else
4115             break;
4116     }
4117
4118     if (sw_if_index_set == 0) {
4119         errmsg ("missing interface name or sw_if_index\n");
4120         return -99;
4121     }
4122
4123     /* Construct the API message */
4124     M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4125
4126     mp->sw_if_index = ntohl (sw_if_index);
4127     mp->enable = is_enable;
4128
4129     /* send it... */
4130     S;
4131
4132     /* Wait for a reply... */
4133     W;
4134 }
4135
4136 static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4137 {
4138     unformat_input_t * i = vam->input;
4139     vl_api_sw_interface_set_l2_xconnect_t *mp;
4140     f64 timeout;
4141     u32 rx_sw_if_index;
4142     u8 rx_sw_if_index_set = 0;
4143     u32 tx_sw_if_index;
4144     u8 tx_sw_if_index_set = 0;
4145     u8 enable = 1;
4146
4147     /* Parse args required to build the message */
4148     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4149         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4150             rx_sw_if_index_set = 1;
4151         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4152             tx_sw_if_index_set = 1;
4153         else if (unformat (i, "rx")) {
4154             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4155                 if (unformat (i, "%U", unformat_sw_if_index, vam,
4156                               &rx_sw_if_index))
4157                     rx_sw_if_index_set = 1;
4158             } else
4159                 break;
4160         } else if (unformat (i, "tx")) {
4161             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4162                 if (unformat (i, "%U", unformat_sw_if_index, vam,
4163                               &tx_sw_if_index))
4164                     tx_sw_if_index_set = 1;
4165             } else
4166                 break;
4167         } else if (unformat (i, "enable"))
4168             enable = 1;
4169         else if (unformat (i, "disable"))
4170             enable = 0;
4171         else
4172             break;
4173     }
4174
4175     if (rx_sw_if_index_set == 0) {
4176         errmsg ("missing rx interface name or rx_sw_if_index\n");
4177         return -99;
4178     }
4179
4180     if (enable && (tx_sw_if_index_set == 0)) {
4181         errmsg ("missing tx interface name or tx_sw_if_index\n");
4182         return -99;
4183     }
4184
4185     M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4186
4187     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4188     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4189     mp->enable = enable;
4190
4191     S; W;
4192     /* NOTREACHED */
4193     return 0;
4194 }
4195
4196 static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
4197 {
4198     unformat_input_t * i = vam->input;
4199     vl_api_sw_interface_set_l2_bridge_t *mp;
4200     f64 timeout;
4201     u32 rx_sw_if_index;
4202     u8 rx_sw_if_index_set = 0;
4203     u32 bd_id;
4204     u8 bd_id_set = 0;
4205     u8 bvi = 0;
4206     u32 shg = 0;
4207     u8 enable = 1;
4208
4209     /* Parse args required to build the message */
4210     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4211         if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4212             rx_sw_if_index_set = 1;
4213         else if (unformat (i, "bd_id %d", &bd_id))
4214             bd_id_set = 1;
4215         else if (unformat (i, "%U", unformat_sw_if_index, vam,
4216                            &rx_sw_if_index))
4217             rx_sw_if_index_set = 1;
4218         else if (unformat (i, "shg %d", &shg))
4219             ;
4220         else if (unformat (i, "bvi"))
4221             bvi = 1;
4222         else if (unformat (i, "enable"))
4223             enable = 1;
4224         else if (unformat (i, "disable"))
4225             enable = 0;
4226         else
4227             break;
4228     }
4229
4230     if (rx_sw_if_index_set == 0) {
4231         errmsg ("missing rx interface name or sw_if_index\n");
4232         return -99;
4233     }
4234
4235     if (enable && (bd_id_set == 0)) {
4236         errmsg ("missing bridge domain\n");
4237         return -99;
4238     }
4239
4240     M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4241
4242     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
4243     mp->bd_id = ntohl(bd_id);
4244     mp->shg = (u8)shg;
4245     mp->bvi = bvi;
4246     mp->enable = enable;
4247
4248     S; W;
4249     /* NOTREACHED */
4250     return 0;
4251 }
4252
4253 static int api_bridge_domain_dump (vat_main_t * vam)
4254 {
4255     unformat_input_t * i = vam->input;
4256     vl_api_bridge_domain_dump_t *mp;
4257     f64 timeout;
4258     u32 bd_id = ~0;
4259
4260     /* Parse args required to build the message */
4261     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4262         if (unformat (i, "bd_id %d", &bd_id))
4263             ;
4264         else
4265             break;
4266     }
4267
4268     M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4269     mp->bd_id = ntohl(bd_id);
4270     S;
4271
4272     /* Use a control ping for synchronization */
4273     {
4274         vl_api_control_ping_t * mp;
4275         M(CONTROL_PING, control_ping);
4276         S;
4277     }
4278
4279     W;
4280     /* NOTREACHED */
4281     return 0;
4282 }
4283
4284 static int api_bridge_domain_add_del (vat_main_t * vam)
4285 {
4286     unformat_input_t * i = vam->input;
4287     vl_api_bridge_domain_add_del_t *mp;
4288     f64 timeout;
4289     u32 bd_id = ~0;
4290     u8 is_add = 1;
4291     u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4292
4293     /* Parse args required to build the message */
4294     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4295         if (unformat (i, "bd_id %d", &bd_id))
4296             ;
4297         else if (unformat (i, "flood %d", &flood))
4298              ;
4299         else if (unformat (i, "uu-flood %d", &uu_flood))
4300              ;
4301         else if (unformat (i, "forward %d", &forward))
4302              ;
4303         else if (unformat (i, "learn %d", &learn))
4304              ;
4305         else if (unformat (i, "arp-term %d", &arp_term))
4306              ;
4307         else if (unformat (i, "del")) {
4308              is_add = 0;
4309              flood = uu_flood = forward = learn = 0;
4310         }
4311         else
4312             break;
4313     }
4314
4315     if (bd_id == ~0) {
4316         errmsg ("missing bridge domain\n");
4317         return -99;
4318     }
4319
4320     M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4321
4322     mp->bd_id = ntohl(bd_id);
4323     mp->flood = flood;
4324     mp->uu_flood = uu_flood;
4325     mp->forward = forward;
4326     mp->learn = learn;
4327     mp->arp_term = arp_term;
4328     mp->is_add = is_add;
4329
4330     S; W;
4331     /* NOTREACHED */
4332     return 0;
4333 }
4334
4335 static int api_l2fib_add_del (vat_main_t * vam)
4336 {
4337     unformat_input_t * i = vam->input;
4338     vl_api_l2fib_add_del_t *mp;
4339     f64 timeout;
4340     u64 mac = 0;
4341     u8 mac_set = 0;
4342     u32 bd_id;
4343     u8 bd_id_set = 0;
4344     u32 sw_if_index;
4345     u8 sw_if_index_set = 0;
4346     u8 is_add = 1;
4347     u8 static_mac = 0;
4348     u8 filter_mac = 0;
4349     u8 bvi_mac = 0;
4350     int count = 1;
4351     f64 before = 0;
4352     int j;
4353
4354     /* Parse args required to build the message */
4355     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4356         if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4357             mac_set = 1;
4358         else if (unformat (i, "bd_id %d", &bd_id))
4359             bd_id_set = 1;
4360         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4361             sw_if_index_set = 1;
4362         else if (unformat (i, "sw_if")) {
4363             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4364                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4365                     sw_if_index_set = 1;
4366             } else
4367                 break;
4368         } else if (unformat (i, "static"))
4369             static_mac = 1;
4370         else if (unformat (i, "filter")) {
4371             filter_mac = 1;
4372             static_mac = 1;
4373         } else if (unformat (i, "bvi")) {
4374             bvi_mac = 1;
4375             static_mac = 1;
4376         } else if (unformat (i, "del"))
4377             is_add = 0;
4378         else if (unformat (i, "count %d", &count))
4379             ;
4380         else
4381             break;
4382     }
4383
4384     if (mac_set == 0) {
4385         errmsg ("missing mac address\n");
4386         return -99;
4387     }
4388
4389     if (bd_id_set == 0) {
4390         errmsg ("missing bridge domain\n");
4391         return -99;
4392     }
4393
4394     if (is_add && (sw_if_index_set == 0)) {
4395         errmsg ("missing interface name or sw_if_index\n");
4396         return -99;
4397     }
4398
4399     if (count > 1) {
4400         /* Turn on async mode */
4401         vam->async_mode = 1;
4402         vam->async_errors = 0;
4403         before = vat_time_now(vam);
4404     }
4405
4406     for (j = 0; j < count; j++) {
4407         M(L2FIB_ADD_DEL, l2fib_add_del);
4408
4409         mp->mac = mac;
4410         mp->bd_id = ntohl(bd_id);
4411         mp->is_add = is_add;
4412
4413         if (is_add) {
4414             mp->sw_if_index = ntohl(sw_if_index);
4415             mp->static_mac = static_mac;
4416             mp->filter_mac = filter_mac;
4417             mp->bvi_mac = bvi_mac;
4418         }
4419         increment_mac_address (&mac);
4420         /* send it... */
4421         S;
4422     }
4423
4424     if (count > 1) {
4425         vl_api_control_ping_t * mp;
4426         f64 after;
4427
4428         /* Shut off async mode */
4429         vam->async_mode = 0;
4430
4431         M(CONTROL_PING, control_ping);
4432         S;
4433
4434         timeout = vat_time_now(vam) + 1.0;
4435         while (vat_time_now (vam) < timeout)
4436             if (vam->result_ready == 1)
4437                 goto out;
4438         vam->retval = -99;
4439
4440     out:
4441         if (vam->retval == -99)
4442             errmsg ("timeout\n");
4443
4444         if (vam->async_errors > 0) {
4445             errmsg ("%d asynchronous errors\n", vam->async_errors);
4446             vam->retval = -98;
4447         }
4448         vam->async_errors = 0;
4449         after = vat_time_now(vam);
4450
4451         fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4452                 count, after - before, count / (after - before));
4453     } else {
4454         /* Wait for a reply... */
4455         W;
4456     }
4457     /* Return the good/bad news */
4458     return (vam->retval);
4459 }
4460
4461 static int api_l2_flags (vat_main_t * vam)
4462 {
4463     unformat_input_t * i = vam->input;
4464     vl_api_l2_flags_t *mp;
4465     f64 timeout;
4466     u32 sw_if_index;
4467     u32 feature_bitmap = 0;
4468     u8 sw_if_index_set = 0;
4469
4470     /* Parse args required to build the message */
4471     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4472         if (unformat (i, "sw_if_index %d", &sw_if_index))
4473             sw_if_index_set = 1;
4474         else if (unformat (i, "sw_if")) {
4475             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4476                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4477                     sw_if_index_set = 1;
4478             } else
4479                 break;
4480         } else if (unformat (i, "learn"))
4481             feature_bitmap |= L2INPUT_FEAT_LEARN;
4482         else if (unformat (i, "forward"))
4483             feature_bitmap |= L2INPUT_FEAT_FWD;
4484         else if (unformat (i, "flood"))
4485             feature_bitmap |= L2INPUT_FEAT_FLOOD;
4486         else if (unformat (i, "uu-flood"))
4487             feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4488         else
4489             break;
4490     }
4491
4492     if (sw_if_index_set == 0) {
4493         errmsg ("missing interface name or sw_if_index\n");
4494         return -99;
4495     }
4496
4497     M(L2_FLAGS, l2_flags);
4498
4499     mp->sw_if_index = ntohl(sw_if_index);
4500     mp->feature_bitmap = ntohl(feature_bitmap);
4501
4502     S; W;
4503     /* NOTREACHED */
4504     return 0;
4505 }
4506
4507 static int api_bridge_flags (vat_main_t * vam)
4508 {
4509     unformat_input_t * i = vam->input;
4510     vl_api_bridge_flags_t *mp;
4511     f64 timeout;
4512     u32 bd_id;
4513     u8 bd_id_set = 0;
4514     u8 is_set = 1;
4515     u32 flags = 0;
4516
4517     /* Parse args required to build the message */
4518     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4519         if (unformat (i, "bd_id %d", &bd_id))
4520             bd_id_set = 1;
4521         else if (unformat (i, "learn"))
4522             flags |= L2_LEARN;
4523         else if (unformat (i, "forward"))
4524             flags |= L2_FWD;
4525         else if (unformat (i, "flood"))
4526             flags |= L2_FLOOD;
4527         else if (unformat (i, "uu-flood"))
4528             flags |= L2_UU_FLOOD;
4529         else if (unformat (i, "arp-term"))
4530             flags |= L2_ARP_TERM;
4531         else if (unformat (i, "off"))
4532             is_set = 0;
4533         else if (unformat (i, "disable"))
4534             is_set = 0;
4535         else
4536             break;
4537     }
4538
4539     if (bd_id_set == 0) {
4540         errmsg ("missing bridge domain\n");
4541         return -99;
4542     }
4543
4544     M(BRIDGE_FLAGS, bridge_flags);
4545
4546     mp->bd_id = ntohl(bd_id);
4547     mp->feature_bitmap = ntohl(flags);
4548     mp->is_set = is_set;
4549
4550     S; W;
4551     /* NOTREACHED */
4552     return 0;
4553 }
4554
4555 static int api_bd_ip_mac_add_del (vat_main_t * vam)
4556 {
4557     unformat_input_t * i = vam->input;
4558     vl_api_bd_ip_mac_add_del_t *mp;
4559     f64 timeout;
4560     u32 bd_id;
4561     u8 is_ipv6 = 0;
4562     u8 is_add = 1;
4563     u8 bd_id_set = 0;
4564     u8 ip_set = 0;
4565     u8 mac_set = 0;
4566     ip4_address_t v4addr;
4567     ip6_address_t v6addr;
4568     u8 macaddr[6];
4569
4570
4571     /* Parse args required to build the message */
4572     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4573         if (unformat (i, "bd_id %d", &bd_id)) {
4574             bd_id_set++;
4575         } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
4576             ip_set++;
4577         } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
4578             ip_set++;
4579             is_ipv6++;
4580         } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
4581             mac_set++;
4582         } else if (unformat (i, "del"))
4583             is_add = 0;
4584         else
4585             break;
4586     }
4587
4588     if (bd_id_set == 0) {
4589         errmsg ("missing bridge domain\n");
4590         return -99;
4591     } else if (ip_set == 0) {
4592         errmsg ("missing IP address\n");
4593         return -99;
4594     } else if (mac_set == 0) {
4595         errmsg ("missing MAC address\n");
4596         return -99;
4597     }
4598
4599     M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
4600
4601     mp->bd_id = ntohl(bd_id);
4602     mp->is_ipv6 = is_ipv6;
4603     mp->is_add = is_add;
4604     if (is_ipv6)
4605          clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
4606     else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
4607     clib_memcpy (mp->mac_address, macaddr, 6);
4608     S; W;
4609     /* NOTREACHED */
4610     return 0;
4611 }
4612
4613 static int api_tap_connect (vat_main_t * vam)
4614 {
4615     unformat_input_t * i = vam->input;
4616     vl_api_tap_connect_t *mp;
4617     f64 timeout;
4618     u8 mac_address[6];
4619     u8 random_mac = 1;
4620     u8 name_set = 0;
4621     u8 * tap_name;
4622
4623     memset (mac_address, 0, sizeof (mac_address));
4624
4625     /* Parse args required to build the message */
4626     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4627         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4628             random_mac = 0;
4629         }
4630         else if (unformat (i, "random-mac"))
4631             random_mac = 1;
4632         else if (unformat (i, "tapname %s", &tap_name))
4633             name_set = 1;
4634         else
4635             break;
4636     }
4637
4638     if (name_set == 0) {
4639         errmsg ("missing tap name\n");
4640         return -99;
4641     }
4642     if (vec_len (tap_name) > 63) {
4643         errmsg ("tap name too long\n");
4644     }
4645     vec_add1 (tap_name, 0);
4646
4647     /* Construct the API message */
4648     M(TAP_CONNECT, tap_connect);
4649
4650     mp->use_random_mac = random_mac;
4651     clib_memcpy (mp->mac_address, mac_address, 6);
4652     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
4653     vec_free (tap_name);
4654
4655     /* send it... */
4656     S;
4657
4658     /* Wait for a reply... */
4659     W;
4660 }
4661
4662 static int api_tap_modify (vat_main_t * vam)
4663 {
4664     unformat_input_t * i = vam->input;
4665     vl_api_tap_modify_t *mp;
4666     f64 timeout;
4667     u8 mac_address[6];
4668     u8 random_mac = 1;
4669     u8 name_set = 0;
4670     u8 * tap_name;
4671     u32 sw_if_index = ~0;
4672     u8 sw_if_index_set = 0;
4673
4674     memset (mac_address, 0, sizeof (mac_address));
4675
4676     /* Parse args required to build the message */
4677     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4678         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4679             sw_if_index_set = 1;
4680         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4681             sw_if_index_set = 1;
4682         else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4683             random_mac = 0;
4684         }
4685         else if (unformat (i, "random-mac"))
4686             random_mac = 1;
4687         else if (unformat (i, "tapname %s", &tap_name))
4688             name_set = 1;
4689         else
4690             break;
4691     }
4692
4693     if (sw_if_index_set == 0) {
4694         errmsg ("missing vpp interface name");
4695         return -99;
4696     }
4697     if (name_set == 0) {
4698         errmsg ("missing tap name\n");
4699         return -99;
4700     }
4701     if (vec_len (tap_name) > 63) {
4702         errmsg ("tap name too long\n");
4703     }
4704     vec_add1 (tap_name, 0);
4705
4706     /* Construct the API message */
4707     M(TAP_MODIFY, tap_modify);
4708
4709     mp->use_random_mac = random_mac;
4710     mp->sw_if_index = ntohl(sw_if_index);
4711     clib_memcpy (mp->mac_address, mac_address, 6);
4712     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
4713     vec_free (tap_name);
4714
4715     /* send it... */
4716     S;
4717
4718     /* Wait for a reply... */
4719     W;
4720 }
4721
4722 static int api_tap_delete (vat_main_t * vam)
4723 {
4724     unformat_input_t * i = vam->input;
4725     vl_api_tap_delete_t *mp;
4726     f64 timeout;
4727     u32 sw_if_index = ~0;
4728     u8 sw_if_index_set = 0;
4729
4730     /* Parse args required to build the message */
4731     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4732         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4733             sw_if_index_set = 1;
4734         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4735             sw_if_index_set = 1;
4736         else
4737             break;
4738     }
4739
4740     if (sw_if_index_set == 0) {
4741         errmsg ("missing vpp interface name");
4742         return -99;
4743     }
4744
4745     /* Construct the API message */
4746     M(TAP_DELETE, tap_delete);
4747
4748     mp->sw_if_index = ntohl(sw_if_index);
4749
4750     /* send it... */
4751     S;
4752
4753     /* Wait for a reply... */
4754     W;
4755 }
4756
4757 static int api_ip_add_del_route (vat_main_t * vam)
4758 {
4759     unformat_input_t * i = vam->input;
4760     vl_api_ip_add_del_route_t *mp;
4761     f64 timeout;
4762     u32 sw_if_index = ~0, vrf_id = 0;
4763     u8 sw_if_index_set = 0;
4764     u8 is_ipv6 = 0;
4765     u8 is_local = 0, is_drop = 0;
4766     u8 create_vrf_if_needed = 0;
4767     u8 is_add = 1;
4768     u8 next_hop_weight = 1;
4769     u8 not_last = 0;
4770     u8 is_multipath = 0;
4771     u8 address_set = 0;
4772     u8 address_length_set = 0;
4773     u32 lookup_in_vrf = 0;
4774     u32 resolve_attempts = 0;
4775     u32 dst_address_length = 0;
4776     u8 next_hop_set = 0;
4777     ip4_address_t v4_dst_address, v4_next_hop_address;
4778     ip6_address_t v6_dst_address, v6_next_hop_address;
4779     int count = 1;
4780     int j;
4781     f64 before = 0;
4782     u32 random_add_del = 0;
4783     u32 * random_vector = 0;
4784     uword * random_hash;
4785     u32 random_seed = 0xdeaddabe;
4786     u32 classify_table_index = ~0;
4787     u8 is_classify = 0;
4788
4789     /* Parse args required to build the message */
4790     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4791         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4792             sw_if_index_set = 1;
4793         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4794             sw_if_index_set = 1;
4795         else if (unformat (i, "%U", unformat_ip4_address,
4796                            &v4_dst_address)) {
4797             address_set = 1;
4798             is_ipv6 = 0;
4799         }
4800         else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4801             address_set = 1;
4802             is_ipv6 = 1;
4803         }
4804         else if (unformat (i, "/%d", &dst_address_length)) {
4805             address_length_set = 1;
4806         }
4807
4808         else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
4809                                            &v4_next_hop_address)) {
4810             next_hop_set = 1;
4811         }
4812         else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
4813                                            &v6_next_hop_address)) {
4814             next_hop_set = 1;
4815         }
4816         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4817             ;
4818         else if (unformat (i, "weight %d", &next_hop_weight))
4819             ;
4820         else if (unformat (i, "drop")) {
4821             is_drop = 1;
4822         } else if (unformat (i, "local")) {
4823             is_local = 1;
4824         } else if (unformat (i, "classify %d", &classify_table_index)) {
4825             is_classify = 1;
4826         } else if (unformat (i, "del"))
4827             is_add = 0;
4828         else if (unformat (i, "add"))
4829             is_add = 1;
4830         else if (unformat (i, "not-last"))
4831             not_last = 1;
4832         else if (unformat (i, "multipath"))
4833             is_multipath = 1;
4834         else if (unformat (i, "vrf %d", &vrf_id))
4835             ;
4836         else if (unformat (i, "create-vrf"))
4837             create_vrf_if_needed = 1;
4838         else if (unformat (i, "count %d", &count))
4839             ;
4840         else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4841             ;
4842         else if (unformat (i, "random"))
4843             random_add_del = 1;
4844         else if (unformat (i, "seed %d", &random_seed))
4845             ;
4846         else {
4847             clib_warning ("parse error '%U'", format_unformat_error, i);
4848             return -99;
4849         }
4850     }
4851
4852     if (resolve_attempts > 0 && sw_if_index_set == 0) {
4853         errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4854         return -99;
4855     }
4856
4857     if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4858         errmsg ("next hop / local / drop / classify not set\n");
4859         return -99;
4860     }
4861
4862     if (address_set == 0) {
4863         errmsg ("missing addresses\n");
4864         return -99;
4865     }
4866
4867     if (address_length_set == 0) {
4868         errmsg ("missing address length\n");
4869         return -99;
4870     }
4871
4872     /* Generate a pile of unique, random routes */
4873     if (random_add_del) {
4874         u32 this_random_address;
4875         random_hash = hash_create (count, sizeof(uword));
4876
4877         hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4878         for (j = 0; j <= count; j++) {
4879             do {
4880                 this_random_address = random_u32 (&random_seed);
4881                 this_random_address =
4882                     clib_host_to_net_u32 (this_random_address);
4883             } while (hash_get (random_hash, this_random_address));
4884             vec_add1 (random_vector, this_random_address);
4885             hash_set (random_hash, this_random_address, 1);
4886         }
4887         hash_free (random_hash);
4888         v4_dst_address.as_u32 = random_vector[0];
4889     }
4890
4891     if (count > 1) {
4892         /* Turn on async mode */
4893         vam->async_mode = 1;
4894         vam->async_errors = 0;
4895         before = vat_time_now(vam);
4896     }
4897
4898     for (j = 0; j < count; j++) {
4899         /* Construct the API message */
4900         M(IP_ADD_DEL_ROUTE, ip_add_del_route);
4901
4902         mp->next_hop_sw_if_index = ntohl (sw_if_index);
4903         mp->vrf_id = ntohl (vrf_id);
4904         if (resolve_attempts > 0) {
4905             mp->resolve_attempts = ntohl (resolve_attempts);
4906             mp->resolve_if_needed = 1;
4907         }
4908         mp->create_vrf_if_needed = create_vrf_if_needed;
4909
4910         mp->is_add = is_add;
4911         mp->is_drop = is_drop;
4912         mp->is_ipv6 = is_ipv6;
4913         mp->is_local = is_local;
4914         mp->is_classify = is_classify;
4915         mp->is_multipath = is_multipath;
4916         mp->not_last = not_last;
4917         mp->next_hop_weight = next_hop_weight;
4918         mp->dst_address_length = dst_address_length;
4919         mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4920         mp->classify_table_index = ntohl(classify_table_index);
4921
4922         if (is_ipv6){
4923             clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
4924             if (next_hop_set)
4925                 clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
4926                         sizeof (v6_next_hop_address));
4927             increment_v6_address (&v6_dst_address);
4928         } else {
4929             clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
4930             if (next_hop_set)
4931                 clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
4932                         sizeof (v4_next_hop_address));
4933             if (random_add_del)
4934                 v4_dst_address.as_u32 = random_vector[j+1];
4935             else
4936                 increment_v4_address (&v4_dst_address);
4937         }
4938         /* send it... */
4939         S;
4940     }
4941
4942     /* When testing multiple add/del ops, use a control-ping to sync */
4943     if (count > 1) {
4944         vl_api_control_ping_t * mp;
4945         f64 after;
4946
4947         /* Shut off async mode */
4948         vam->async_mode = 0;
4949
4950         M(CONTROL_PING, control_ping);
4951         S;
4952
4953         timeout = vat_time_now(vam) + 1.0;
4954         while (vat_time_now (vam) < timeout)
4955             if (vam->result_ready == 1)
4956                 goto out;
4957         vam->retval = -99;
4958
4959     out:
4960         if (vam->retval == -99)
4961             errmsg ("timeout\n");
4962
4963         if (vam->async_errors > 0) {
4964             errmsg ("%d asynchronous errors\n", vam->async_errors);
4965             vam->retval = -98;
4966         }
4967         vam->async_errors = 0;
4968         after = vat_time_now(vam);
4969
4970         fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4971                 count, after - before, count / (after - before));
4972     } else {
4973         /* Wait for a reply... */
4974         W;
4975     }
4976
4977     /* Return the good/bad news */
4978     return (vam->retval);
4979 }
4980
4981 static int api_proxy_arp_add_del (vat_main_t * vam)
4982 {
4983     unformat_input_t * i = vam->input;
4984     vl_api_proxy_arp_add_del_t *mp;
4985     f64 timeout;
4986     u32 vrf_id = 0;
4987     u8 is_add = 1;
4988     ip4_address_t lo, hi;
4989     u8 range_set = 0;
4990
4991     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4992         if (unformat (i, "vrf %d", &vrf_id))
4993             ;
4994         else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
4995                            unformat_ip4_address, &hi))
4996             range_set = 1;
4997         else if (unformat (i, "del"))
4998             is_add = 0;
4999         else {
5000             clib_warning ("parse error '%U'", format_unformat_error, i);
5001             return -99;
5002         }
5003     }
5004
5005     if (range_set == 0) {
5006         errmsg ("address range not set\n");
5007         return -99;
5008     }
5009
5010     M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5011
5012     mp->vrf_id = ntohl(vrf_id);
5013     mp->is_add = is_add;
5014     clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
5015     clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
5016
5017     S; W;
5018     /* NOTREACHED */
5019     return 0;
5020 }
5021
5022 static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5023 {
5024     unformat_input_t * i = vam->input;
5025     vl_api_proxy_arp_intfc_enable_disable_t *mp;
5026     f64 timeout;
5027     u32 sw_if_index;
5028     u8 enable = 1;
5029     u8 sw_if_index_set = 0;
5030
5031     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5032         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5033             sw_if_index_set = 1;
5034         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5035             sw_if_index_set = 1;
5036         else if (unformat (i, "enable"))
5037             enable = 1;
5038         else if (unformat (i, "disable"))
5039             enable = 0;
5040         else {
5041             clib_warning ("parse error '%U'", format_unformat_error, i);
5042             return -99;
5043         }
5044     }
5045
5046     if (sw_if_index_set == 0) {
5047         errmsg ("missing interface name or sw_if_index\n");
5048         return -99;
5049     }
5050
5051     M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5052
5053     mp->sw_if_index = ntohl(sw_if_index);
5054     mp->enable_disable = enable;
5055
5056     S; W;
5057     /* NOTREACHED */
5058     return 0;
5059 }
5060
5061 static int api_mpls_add_del_decap (vat_main_t * vam)
5062 {
5063     unformat_input_t * i = vam->input;
5064     vl_api_mpls_add_del_decap_t *mp;
5065     f64 timeout;
5066     u32 rx_vrf_id = 0;
5067     u32 tx_vrf_id = 0;
5068     u32 label = 0;
5069     u8 is_add = 1;
5070     u8 s_bit = 1;
5071     u32 next_index = 1;
5072
5073     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5074         if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5075             ;
5076         else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5077             ;
5078         else if (unformat (i, "label %d", &label))
5079             ;
5080         else if (unformat (i, "next-index %d", &next_index))
5081             ;
5082         else if (unformat (i, "del"))
5083             is_add = 0;
5084         else if (unformat (i, "s-bit-clear"))
5085             s_bit = 0;
5086         else {
5087             clib_warning ("parse error '%U'", format_unformat_error, i);
5088             return -99;
5089         }
5090     }
5091
5092     M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5093
5094     mp->rx_vrf_id = ntohl(rx_vrf_id);
5095     mp->tx_vrf_id = ntohl(tx_vrf_id);
5096     mp->label = ntohl(label);
5097     mp->next_index = ntohl(next_index);
5098     mp->s_bit = s_bit;
5099     mp->is_add = is_add;
5100
5101     S; W;
5102     /* NOTREACHED */
5103     return 0;
5104 }
5105
5106 static int api_mpls_add_del_encap (vat_main_t * vam)
5107 {
5108     unformat_input_t * i = vam->input;
5109     vl_api_mpls_add_del_encap_t *mp;
5110     f64 timeout;
5111     u32 vrf_id = 0;
5112     u32 *labels = 0;
5113     u32 label;
5114     ip4_address_t dst_address;
5115     u8 is_add = 1;
5116
5117     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5118         if (unformat (i, "vrf %d", &vrf_id))
5119             ;
5120         else if (unformat (i, "label %d", &label))
5121             vec_add1 (labels, ntohl(label));
5122         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5123             ;
5124         else if (unformat (i, "del"))
5125             is_add = 0;
5126         else {
5127             clib_warning ("parse error '%U'", format_unformat_error, i);
5128             return -99;
5129         }
5130     }
5131
5132     if (vec_len (labels) == 0) {
5133         errmsg ("missing encap label stack\n");
5134         return -99;
5135     }
5136
5137     M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5138        sizeof (u32) * vec_len (labels));
5139
5140     mp->vrf_id = ntohl(vrf_id);
5141     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
5142     mp->is_add = is_add;
5143     mp->nlabels = vec_len (labels);
5144     clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
5145
5146     vec_free(labels);
5147
5148     S; W;
5149     /* NOTREACHED */
5150     return 0;
5151 }
5152
5153 static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5154 {
5155     unformat_input_t * i = vam->input;
5156     vl_api_mpls_gre_add_del_tunnel_t *mp;
5157     f64 timeout;
5158     u32 inner_vrf_id = 0;
5159     u32 outer_vrf_id = 0;
5160     ip4_address_t src_address;
5161     ip4_address_t dst_address;
5162     ip4_address_t intfc_address;
5163     u32 tmp;
5164     u8 intfc_address_length = 0;
5165     u8 is_add = 1;
5166     u8 l2_only = 0;
5167
5168     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5169         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5170             ;
5171         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5172             ;
5173         else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5174             ;
5175         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5176             ;
5177         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5178                            &intfc_address, &tmp))
5179             intfc_address_length = tmp;
5180         else if (unformat (i, "l2-only"))
5181             l2_only = 1;
5182         else if (unformat (i, "del"))
5183             is_add = 0;
5184         else {
5185             clib_warning ("parse error '%U'", format_unformat_error, i);
5186             return -99;
5187         }
5188     }
5189
5190     M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5191
5192     mp->inner_vrf_id = ntohl(inner_vrf_id);
5193     mp->outer_vrf_id = ntohl(outer_vrf_id);
5194     clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
5195     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
5196     clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
5197     mp->intfc_address_length = intfc_address_length;
5198     mp->l2_only = l2_only;
5199     mp->is_add = is_add;
5200
5201     S; W;
5202     /* NOTREACHED */
5203     return 0;
5204 }
5205
5206 static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5207 {
5208     unformat_input_t * i = vam->input;
5209     vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5210     f64 timeout;
5211     u32 inner_vrf_id = 0;
5212     ip4_address_t intfc_address;
5213     u8 dst_mac_address[6];
5214     int dst_set = 1;
5215     u32 tmp;
5216     u8 intfc_address_length = 0;
5217     u8 is_add = 1;
5218     u8 l2_only = 0;
5219     u32 tx_sw_if_index;
5220     int tx_sw_if_index_set = 0;
5221
5222     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5223         if (unformat (i, "vrf %d", &inner_vrf_id))
5224             ;
5225         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5226                            &intfc_address, &tmp))
5227             intfc_address_length = tmp;
5228         else if (unformat (i, "%U",
5229                            unformat_sw_if_index, vam, &tx_sw_if_index))
5230             tx_sw_if_index_set = 1;
5231         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5232             tx_sw_if_index_set = 1;
5233         else if (unformat (i, "dst %U", unformat_ethernet_address,
5234                            dst_mac_address))
5235             dst_set = 1;
5236         else if (unformat (i, "l2-only"))
5237             l2_only = 1;
5238         else if (unformat (i, "del"))
5239             is_add = 0;
5240         else {
5241             clib_warning ("parse error '%U'", format_unformat_error, i);
5242             return -99;
5243         }
5244     }
5245
5246     if (!dst_set) {
5247         errmsg ("dst (mac address) not set\n");
5248         return -99;
5249     }
5250     if (!tx_sw_if_index_set) {
5251         errmsg ("tx-intfc not set\n");
5252         return -99;
5253     }
5254
5255     M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5256
5257     mp->vrf_id = ntohl(inner_vrf_id);
5258     clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5259     mp->adj_address_length = intfc_address_length;
5260     clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
5261     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5262     mp->l2_only = l2_only;
5263     mp->is_add = is_add;
5264
5265     S; W;
5266     /* NOTREACHED */
5267     return 0;
5268 }
5269
5270 static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5271 {
5272     unformat_input_t * i = vam->input;
5273     vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5274     f64 timeout;
5275     u32 inner_vrf_id = 0;
5276     u32 outer_vrf_id = 0;
5277     ip4_address_t adj_address;
5278     int adj_address_set = 0;
5279     ip4_address_t next_hop_address;
5280     int next_hop_address_set = 0;
5281     u32 tmp;
5282     u8 adj_address_length = 0;
5283     u8 l2_only = 0;
5284     u8 is_add = 1;
5285     u32 resolve_attempts = 5;
5286     u8 resolve_if_needed = 1;
5287
5288     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5289         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5290             ;
5291         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5292             ;
5293         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5294                            &adj_address, &tmp)) {
5295             adj_address_length = tmp;
5296             adj_address_set = 1;
5297         }
5298         else if (unformat (i, "next-hop %U", unformat_ip4_address,
5299                            &next_hop_address))
5300             next_hop_address_set = 1;
5301         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5302             ;
5303         else if (unformat (i, "resolve-if-needed %d", &tmp))
5304             resolve_if_needed = tmp;
5305         else if (unformat (i, "l2-only"))
5306             l2_only = 1;
5307         else if (unformat (i, "del"))
5308             is_add = 0;
5309         else {
5310             clib_warning ("parse error '%U'", format_unformat_error, i);
5311             return -99;
5312         }
5313     }
5314
5315     if (!adj_address_set) {
5316         errmsg ("adjacency address/mask not set\n");
5317         return -99;
5318     }
5319     if (!next_hop_address_set) {
5320         errmsg ("ip4 next hop address (in outer fib) not set\n");
5321         return -99;
5322     }
5323
5324     M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5325
5326     mp->inner_vrf_id = ntohl(inner_vrf_id);
5327     mp->outer_vrf_id = ntohl(outer_vrf_id);
5328     mp->resolve_attempts = ntohl(resolve_attempts);
5329     mp->resolve_if_needed = resolve_if_needed;
5330     mp->is_add = is_add;
5331     mp->l2_only = l2_only;
5332     clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5333     mp->adj_address_length = adj_address_length;
5334     clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5335             sizeof (next_hop_address));
5336
5337     S; W;
5338     /* NOTREACHED */
5339     return 0;
5340 }
5341
5342 static int api_sw_interface_set_unnumbered (vat_main_t * vam)
5343 {
5344     unformat_input_t * i = vam->input;
5345     vl_api_sw_interface_set_unnumbered_t *mp;
5346     f64 timeout;
5347     u32 sw_if_index;
5348     u32 unnum_sw_index;
5349     u8  is_add = 1;
5350     u8 sw_if_index_set = 0;
5351
5352     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5353         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5354             sw_if_index_set = 1;
5355         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5356             sw_if_index_set = 1;
5357         else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5358             ;
5359         else if (unformat (i, "del"))
5360             is_add = 0;
5361         else {
5362             clib_warning ("parse error '%U'", format_unformat_error, i);
5363             return -99;
5364         }
5365     }
5366
5367     if (sw_if_index_set == 0) {
5368         errmsg ("missing interface name or sw_if_index\n");
5369         return -99;
5370     }
5371
5372     M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5373
5374     mp->sw_if_index = ntohl(sw_if_index);
5375     mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
5376     mp->is_add = is_add;
5377
5378     S; W;
5379     /* NOTREACHED */
5380     return 0;
5381 }
5382
5383 static int api_ip_neighbor_add_del (vat_main_t * vam)
5384 {
5385     unformat_input_t * i = vam->input;
5386     vl_api_ip_neighbor_add_del_t *mp;
5387     f64 timeout;
5388     u32 sw_if_index;
5389     u8 sw_if_index_set = 0;
5390     u32 vrf_id = 0;
5391     u8 is_add = 1;
5392     u8 is_static = 0;
5393     u8 mac_address[6];
5394     u8 mac_set = 0;
5395     u8 v4_address_set = 0;
5396     u8 v6_address_set = 0;
5397     ip4_address_t v4address;
5398     ip6_address_t v6address;
5399
5400     memset (mac_address, 0, sizeof (mac_address));
5401
5402     /* Parse args required to build the message */
5403     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5404         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
5405             mac_set = 1;
5406         }
5407         else if (unformat (i, "del"))
5408             is_add = 0;
5409         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5410             sw_if_index_set = 1;
5411         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5412             sw_if_index_set = 1;
5413         else if (unformat (i, "is_static"))
5414             is_static = 1;
5415         else if (unformat (i, "vrf %d", &vrf_id))
5416             ;
5417         else if (unformat (i, "dst %U",
5418                            unformat_ip4_address, &v4address))
5419                 v4_address_set = 1;
5420         else if (unformat (i, "dst %U",
5421                            unformat_ip6_address, &v6address))
5422                 v6_address_set = 1;
5423         else {
5424             clib_warning ("parse error '%U'", format_unformat_error, i);
5425             return -99;
5426         }
5427     }
5428
5429     if (sw_if_index_set == 0) {
5430         errmsg ("missing interface name or sw_if_index\n");
5431         return -99;
5432     }
5433     if (v4_address_set && v6_address_set) {
5434         errmsg ("both v4 and v6 addresses set\n");
5435         return -99;
5436     }
5437     if (!v4_address_set && !v6_address_set) {
5438         errmsg ("no address set\n");
5439         return -99;
5440     }
5441
5442     /* Construct the API message */
5443     M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5444
5445     mp->sw_if_index = ntohl (sw_if_index);
5446     mp->is_add = is_add;
5447     mp->vrf_id = ntohl (vrf_id);
5448     mp->is_static = is_static;
5449     if (mac_set)
5450         clib_memcpy (mp->mac_address, mac_address, 6);
5451     if (v6_address_set) {
5452         mp->is_ipv6 = 1;
5453         clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
5454     } else {
5455         /* mp->is_ipv6 = 0; via memset in M macro above */
5456         clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
5457     }
5458
5459     /* send it... */
5460     S;
5461
5462     /* Wait for a reply, return good/bad news  */
5463     W;
5464
5465     /* NOTREACHED */
5466     return 0;
5467 }
5468
5469 static int api_reset_vrf (vat_main_t * vam)
5470 {
5471     unformat_input_t * i = vam->input;
5472     vl_api_reset_vrf_t *mp;
5473     f64 timeout;
5474     u32 vrf_id = 0;
5475     u8 is_ipv6 = 0;
5476     u8 vrf_id_set = 0;
5477
5478     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5479         if (unformat (i, "vrf %d", &vrf_id))
5480             vrf_id_set = 1;
5481         else if (unformat (i, "ipv6"))
5482             is_ipv6 = 1;
5483         else {
5484             clib_warning ("parse error '%U'", format_unformat_error, i);
5485             return -99;
5486         }
5487     }
5488
5489     if (vrf_id_set == 0) {
5490         errmsg ("missing vrf id\n");
5491         return -99;
5492     }
5493
5494     M(RESET_VRF, reset_vrf);
5495
5496     mp->vrf_id = ntohl(vrf_id);
5497     mp->is_ipv6 = is_ipv6;
5498
5499     S; W;
5500     /* NOTREACHED */
5501     return 0;
5502 }
5503
5504 static int api_create_vlan_subif (vat_main_t * vam)
5505 {
5506     unformat_input_t * i = vam->input;
5507     vl_api_create_vlan_subif_t *mp;
5508     f64 timeout;
5509     u32 sw_if_index;
5510     u8  sw_if_index_set = 0;
5511     u32 vlan_id;
5512     u8  vlan_id_set = 0;
5513
5514     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5515         if (unformat (i, "sw_if_index %d", &sw_if_index))
5516             sw_if_index_set = 1;
5517         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5518             sw_if_index_set = 1;
5519         else if (unformat (i, "vlan %d", &vlan_id))
5520             vlan_id_set = 1;
5521         else {
5522             clib_warning ("parse error '%U'", format_unformat_error, i);
5523             return -99;
5524         }
5525     }
5526
5527     if (sw_if_index_set == 0) {
5528         errmsg ("missing interface name or sw_if_index\n");
5529         return -99;
5530     }
5531
5532     if (vlan_id_set == 0) {
5533         errmsg ("missing vlan_id\n");
5534         return -99;
5535     }
5536     M(CREATE_VLAN_SUBIF, create_vlan_subif);
5537
5538     mp->sw_if_index = ntohl(sw_if_index);
5539     mp->vlan_id = ntohl(vlan_id);
5540
5541     S; W;
5542     /* NOTREACHED */
5543     return 0;
5544 }
5545
5546 #define foreach_create_subif_bit                \
5547 _(no_tags)                                      \
5548 _(one_tag)                                      \
5549 _(two_tags)                                     \
5550 _(dot1ad)                                       \
5551 _(exact_match)                                  \
5552 _(default_sub)                                  \
5553 _(outer_vlan_id_any)                            \
5554 _(inner_vlan_id_any)
5555
5556 static int api_create_subif (vat_main_t * vam)
5557 {
5558     unformat_input_t * i = vam->input;
5559     vl_api_create_subif_t *mp;
5560     f64 timeout;
5561     u32 sw_if_index;
5562     u8  sw_if_index_set = 0;
5563     u32 sub_id;
5564     u8  sub_id_set = 0;
5565     u32 no_tags = 0;
5566     u32 one_tag = 0;
5567     u32 two_tags = 0;
5568     u32 dot1ad = 0;
5569     u32 exact_match = 0;
5570     u32 default_sub = 0;
5571     u32 outer_vlan_id_any = 0;
5572     u32 inner_vlan_id_any = 0;
5573     u32 tmp;
5574     u16 outer_vlan_id = 0;
5575     u16 inner_vlan_id = 0;
5576
5577     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5578         if (unformat (i, "sw_if_index %d", &sw_if_index))
5579             sw_if_index_set = 1;
5580         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5581             sw_if_index_set = 1;
5582         else if (unformat (i, "sub_id %d", &sub_id))
5583             sub_id_set = 1;
5584         else if (unformat (i, "outer_vlan_id %d", &tmp))
5585             outer_vlan_id = tmp;
5586         else if (unformat (i, "inner_vlan_id %d", &tmp))
5587             inner_vlan_id = tmp;
5588
5589 #define _(a) else if (unformat (i, #a)) a = 1 ;
5590         foreach_create_subif_bit
5591 #undef _
5592
5593         else {
5594             clib_warning ("parse error '%U'", format_unformat_error, i);
5595             return -99;
5596         }
5597     }
5598
5599     if (sw_if_index_set == 0) {
5600         errmsg ("missing interface name or sw_if_index\n");
5601         return -99;
5602     }
5603
5604     if (sub_id_set == 0) {
5605         errmsg ("missing sub_id\n");
5606         return -99;
5607     }
5608     M(CREATE_SUBIF, create_subif);
5609
5610     mp->sw_if_index = ntohl(sw_if_index);
5611     mp->sub_id = ntohl(sub_id);
5612
5613 #define _(a) mp->a = a;
5614     foreach_create_subif_bit;
5615 #undef _
5616
5617     mp->outer_vlan_id = ntohs (outer_vlan_id);
5618     mp->inner_vlan_id = ntohs (inner_vlan_id);
5619
5620     S; W;
5621     /* NOTREACHED */
5622     return 0;
5623 }
5624
5625 static int api_oam_add_del (vat_main_t * vam)
5626 {
5627     unformat_input_t * i = vam->input;
5628     vl_api_oam_add_del_t *mp;
5629     f64 timeout;
5630     u32 vrf_id = 0;
5631     u8 is_add = 1;
5632     ip4_address_t src, dst;
5633     u8 src_set = 0;
5634     u8 dst_set = 0;
5635
5636     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5637         if (unformat (i, "vrf %d", &vrf_id))
5638             ;
5639         else if (unformat (i, "src %U", unformat_ip4_address, &src))
5640             src_set = 1;
5641         else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
5642             dst_set = 1;
5643         else if (unformat (i, "del"))
5644             is_add = 0;
5645         else {
5646             clib_warning ("parse error '%U'", format_unformat_error, i);
5647             return -99;
5648         }
5649     }
5650
5651     if (src_set == 0) {
5652         errmsg ("missing src addr\n");
5653         return -99;
5654     }
5655
5656     if (dst_set == 0) {
5657         errmsg ("missing dst addr\n");
5658         return -99;
5659     }
5660
5661     M(OAM_ADD_DEL, oam_add_del);
5662
5663     mp->vrf_id = ntohl(vrf_id);
5664     mp->is_add = is_add;
5665     clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
5666     clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
5667
5668     S; W;
5669     /* NOTREACHED */
5670     return 0;
5671 }
5672
5673 static int api_reset_fib (vat_main_t * vam)
5674 {
5675     unformat_input_t * i = vam->input;
5676     vl_api_reset_fib_t *mp;
5677     f64 timeout;
5678     u32 vrf_id = 0;
5679     u8 is_ipv6 = 0;
5680     u8 vrf_id_set = 0;
5681
5682     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5683         if (unformat (i, "vrf %d", &vrf_id))
5684             vrf_id_set = 1;
5685         else if (unformat (i, "ipv6"))
5686             is_ipv6 = 1;
5687         else {
5688             clib_warning ("parse error '%U'", format_unformat_error, i);
5689             return -99;
5690         }
5691     }
5692
5693     if (vrf_id_set == 0) {
5694         errmsg ("missing vrf id\n");
5695         return -99;
5696     }
5697
5698     M(RESET_FIB, reset_fib);
5699
5700     mp->vrf_id = ntohl(vrf_id);
5701     mp->is_ipv6 = is_ipv6;
5702
5703     S; W;
5704     /* NOTREACHED */
5705     return 0;
5706 }
5707
5708 static int api_dhcp_proxy_config (vat_main_t * vam)
5709 {
5710     unformat_input_t * i = vam->input;
5711     vl_api_dhcp_proxy_config_t *mp;
5712     f64 timeout;
5713     u32 vrf_id = 0;
5714     u8 is_add = 1;
5715     u8 insert_cid = 1;
5716     u8 v4_address_set = 0;
5717     u8 v6_address_set = 0;
5718     ip4_address_t v4address;
5719     ip6_address_t v6address;
5720     u8 v4_src_address_set = 0;
5721     u8 v6_src_address_set = 0;
5722     ip4_address_t v4srcaddress;
5723     ip6_address_t v6srcaddress;
5724
5725     /* Parse args required to build the message */
5726     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5727         if (unformat (i, "del"))
5728             is_add = 0;
5729         else if (unformat (i, "vrf %d", &vrf_id))
5730             ;
5731         else if (unformat (i, "insert-cid %d", &insert_cid))
5732             ;
5733         else if (unformat (i, "svr %U",
5734                            unformat_ip4_address, &v4address))
5735                 v4_address_set = 1;
5736         else if (unformat (i, "svr %U",
5737                            unformat_ip6_address, &v6address))
5738                 v6_address_set = 1;
5739         else if (unformat (i, "src %U",
5740                            unformat_ip4_address, &v4srcaddress))
5741                 v4_src_address_set = 1;
5742         else if (unformat (i, "src %U",
5743                            unformat_ip6_address, &v6srcaddress))
5744                 v6_src_address_set = 1;
5745         else
5746             break;
5747     }
5748
5749     if (v4_address_set && v6_address_set) {
5750         errmsg ("both v4 and v6 server addresses set\n");
5751         return -99;
5752     }
5753     if (!v4_address_set && !v6_address_set) {
5754         errmsg ("no server addresses set\n");
5755         return -99;
5756     }
5757
5758     if (v4_src_address_set && v6_src_address_set) {
5759         errmsg ("both v4 and v6  src addresses set\n");
5760         return -99;
5761     }
5762     if (!v4_src_address_set && !v6_src_address_set) {
5763         errmsg ("no src addresses set\n");
5764         return -99;
5765     }
5766
5767     if (!(v4_src_address_set && v4_address_set) &&
5768         !(v6_src_address_set && v6_address_set)) {
5769         errmsg ("no matching server and src addresses set\n");
5770         return -99;
5771     }
5772
5773     /* Construct the API message */
5774     M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
5775
5776     mp->insert_circuit_id = insert_cid;
5777     mp->is_add = is_add;
5778     mp->vrf_id = ntohl (vrf_id);
5779     if (v6_address_set) {
5780         mp->is_ipv6 = 1;
5781         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5782         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
5783     } else {
5784         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5785         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
5786     }
5787
5788     /* send it... */
5789     S;
5790
5791     /* Wait for a reply, return good/bad news  */
5792     W;
5793     /* NOTREACHED */
5794     return 0;
5795 }
5796
5797 static int api_dhcp_proxy_config_2 (vat_main_t * vam)
5798 {
5799     unformat_input_t * i = vam->input;
5800     vl_api_dhcp_proxy_config_2_t *mp;
5801     f64 timeout;
5802     u32 rx_vrf_id = 0;
5803     u32 server_vrf_id = 0;
5804     u8 is_add = 1;
5805     u8 insert_cid = 1;
5806     u8 v4_address_set = 0;
5807     u8 v6_address_set = 0;
5808     ip4_address_t v4address;
5809     ip6_address_t v6address;
5810     u8 v4_src_address_set = 0;
5811     u8 v6_src_address_set = 0;
5812     ip4_address_t v4srcaddress;
5813     ip6_address_t v6srcaddress;
5814
5815     /* Parse args required to build the message */
5816     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5817         if (unformat (i, "del"))
5818             is_add = 0;
5819         else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5820             ;
5821         else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5822             ;
5823         else if (unformat (i, "insert-cid %d", &insert_cid))
5824             ;
5825         else if (unformat (i, "svr %U",
5826                            unformat_ip4_address, &v4address))
5827                 v4_address_set = 1;
5828         else if (unformat (i, "svr %U",
5829                            unformat_ip6_address, &v6address))
5830                 v6_address_set = 1;
5831         else if (unformat (i, "src %U",
5832                            unformat_ip4_address, &v4srcaddress))
5833                 v4_src_address_set = 1;
5834         else if (unformat (i, "src %U",
5835                            unformat_ip6_address, &v6srcaddress))
5836                 v6_src_address_set = 1;
5837         else
5838             break;
5839     }
5840
5841     if (v4_address_set && v6_address_set) {
5842         errmsg ("both v4 and v6 server addresses set\n");
5843         return -99;
5844     }
5845     if (!v4_address_set && !v6_address_set) {
5846         errmsg ("no server addresses set\n");
5847         return -99;
5848     }
5849
5850     if (v4_src_address_set && v6_src_address_set) {
5851         errmsg ("both v4 and v6  src addresses set\n");
5852         return -99;
5853     }
5854     if (!v4_src_address_set && !v6_src_address_set) {
5855         errmsg ("no src addresses set\n");
5856         return -99;
5857     }
5858
5859     if (!(v4_src_address_set && v4_address_set) &&
5860         !(v6_src_address_set && v6_address_set)) {
5861         errmsg ("no matching server and src addresses set\n");
5862         return -99;
5863     }
5864
5865     /* Construct the API message */
5866     M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5867
5868     mp->insert_circuit_id = insert_cid;
5869     mp->is_add = is_add;
5870     mp->rx_vrf_id = ntohl (rx_vrf_id);
5871     mp->server_vrf_id = ntohl (server_vrf_id);
5872     if (v6_address_set) {
5873         mp->is_ipv6 = 1;
5874         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5875         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
5876     } else {
5877         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5878         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
5879     }
5880
5881     /* send it... */
5882     S;
5883
5884     /* Wait for a reply, return good/bad news  */
5885     W;
5886     /* NOTREACHED */
5887     return 0;
5888 }
5889
5890 static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5891 {
5892     unformat_input_t * i = vam->input;
5893     vl_api_dhcp_proxy_set_vss_t *mp;
5894     f64 timeout;
5895     u8  is_ipv6 = 0;
5896     u8  is_add = 1;
5897     u32 tbl_id;
5898     u8  tbl_id_set = 0;
5899     u32 oui;
5900     u8  oui_set = 0;
5901     u32 fib_id;
5902     u8  fib_id_set = 0;
5903
5904     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5905         if (unformat (i, "tbl_id %d", &tbl_id))
5906             tbl_id_set = 1;
5907         if (unformat (i, "fib_id %d", &fib_id))
5908             fib_id_set = 1;
5909         if (unformat (i, "oui %d", &oui))
5910             oui_set = 1;
5911         else if (unformat (i, "ipv6"))
5912             is_ipv6 = 1;
5913         else if (unformat (i, "del"))
5914             is_add = 0;
5915         else {
5916             clib_warning ("parse error '%U'", format_unformat_error, i);
5917             return -99;
5918         }
5919     }
5920
5921     if (tbl_id_set == 0) {
5922         errmsg ("missing tbl id\n");
5923         return -99;
5924     }
5925
5926     if (fib_id_set == 0) {
5927         errmsg ("missing fib id\n");
5928         return -99;
5929     }
5930     if (oui_set == 0) {
5931         errmsg ("missing oui\n");
5932         return -99;
5933     }
5934
5935     M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5936     mp->tbl_id = ntohl(tbl_id);
5937     mp->fib_id = ntohl(fib_id);
5938     mp->oui = ntohl(oui);
5939     mp->is_ipv6 = is_ipv6;
5940     mp->is_add = is_add;
5941
5942     S; W;
5943     /* NOTREACHED */
5944     return 0;
5945 }
5946
5947 static int api_dhcp_client_config (vat_main_t * vam)
5948 {
5949     unformat_input_t * i = vam->input;
5950     vl_api_dhcp_client_config_t *mp;
5951     f64 timeout;
5952     u32 sw_if_index;
5953     u8 sw_if_index_set = 0;
5954     u8 is_add = 1;
5955     u8 * hostname = 0;
5956     u8 disable_event = 0;
5957
5958     /* Parse args required to build the message */
5959     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5960         if (unformat (i, "del"))
5961             is_add = 0;
5962         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5963             sw_if_index_set = 1;
5964         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5965             sw_if_index_set = 1;
5966         else if (unformat (i, "hostname %s", &hostname))
5967             ;
5968         else if (unformat (i, "disable_event"))
5969             disable_event = 1;
5970         else
5971             break;
5972     }
5973
5974     if (sw_if_index_set == 0) {
5975         errmsg ("missing interface name or sw_if_index\n");
5976         return -99;
5977     }
5978
5979     if (vec_len (hostname) > 63) {
5980         errmsg ("hostname too long\n");
5981     }
5982     vec_add1 (hostname, 0);
5983
5984     /* Construct the API message */
5985     M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5986
5987     mp->sw_if_index = ntohl (sw_if_index);
5988     clib_memcpy (mp->hostname, hostname, vec_len (hostname));
5989     vec_free (hostname);
5990     mp->is_add = is_add;
5991     mp->want_dhcp_event = disable_event ? 0 : 1;
5992     mp->pid = getpid();
5993
5994     /* send it... */
5995     S;
5996
5997     /* Wait for a reply, return good/bad news  */
5998     W;
5999     /* NOTREACHED */
6000     return 0;
6001 }
6002
6003 static int api_set_ip_flow_hash (vat_main_t * vam)
6004 {
6005     unformat_input_t * i = vam->input;
6006     vl_api_set_ip_flow_hash_t *mp;
6007     f64 timeout;
6008     u32 vrf_id = 0;
6009     u8 is_ipv6 = 0;
6010     u8 vrf_id_set = 0;
6011     u8 src = 0;
6012     u8 dst = 0;
6013     u8 sport = 0;
6014     u8 dport = 0;
6015     u8 proto = 0;
6016     u8 reverse = 0;
6017
6018     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6019         if (unformat (i, "vrf %d", &vrf_id))
6020             vrf_id_set = 1;
6021         else if (unformat (i, "ipv6"))
6022             is_ipv6 = 1;
6023         else if (unformat (i, "src"))
6024             src = 1;
6025         else if (unformat (i, "dst"))
6026             dst = 1;
6027         else if (unformat (i, "sport"))
6028             sport = 1;
6029         else if (unformat (i, "dport"))
6030             dport = 1;
6031         else if (unformat (i, "proto"))
6032             proto = 1;
6033         else if (unformat (i, "reverse"))
6034             reverse = 1;
6035
6036         else {
6037             clib_warning ("parse error '%U'", format_unformat_error, i);
6038             return -99;
6039         }
6040     }
6041
6042     if (vrf_id_set == 0) {
6043         errmsg ("missing vrf id\n");
6044         return -99;
6045     }
6046
6047     M(SET_IP_FLOW_HASH, set_ip_flow_hash);
6048     mp->src = src;
6049     mp->dst = dst;
6050     mp->sport = sport;
6051     mp->dport = dport;
6052     mp->proto = proto;
6053     mp->reverse = reverse;
6054     mp->vrf_id = ntohl(vrf_id);
6055     mp->is_ipv6 = is_ipv6;
6056
6057     S; W;
6058     /* NOTREACHED */
6059     return 0;
6060 }
6061
6062 static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6063 {
6064     unformat_input_t * i = vam->input;
6065     vl_api_sw_interface_ip6_enable_disable_t *mp;
6066     f64 timeout;
6067     u32 sw_if_index;
6068     u8  sw_if_index_set = 0;
6069     u8  enable = 0;
6070
6071     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6072         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6073             sw_if_index_set = 1;
6074         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6075             sw_if_index_set = 1;
6076         else if (unformat (i, "enable"))
6077             enable = 1;
6078         else if (unformat (i, "disable"))
6079             enable = 0;
6080         else {
6081             clib_warning ("parse error '%U'", format_unformat_error, i);
6082             return -99;
6083         }
6084     }
6085
6086     if (sw_if_index_set == 0) {
6087         errmsg ("missing interface name or sw_if_index\n");
6088         return -99;
6089     }
6090
6091     M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6092
6093     mp->sw_if_index = ntohl(sw_if_index);
6094     mp->enable = enable;
6095
6096     S; W;
6097     /* NOTREACHED */
6098     return 0;
6099 }
6100
6101 static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6102 {
6103     unformat_input_t * i = vam->input;
6104     vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6105     f64 timeout;
6106     u32 sw_if_index;
6107     u8 sw_if_index_set = 0;
6108     u32 address_length = 0;
6109     u8 v6_address_set = 0;
6110     ip6_address_t v6address;
6111
6112     /* Parse args required to build the message */
6113     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6114         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6115             sw_if_index_set = 1;
6116         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6117             sw_if_index_set = 1;
6118         else if (unformat (i, "%U/%d",
6119                            unformat_ip6_address, &v6address,
6120                            &address_length))
6121             v6_address_set = 1;
6122         else
6123             break;
6124     }
6125
6126     if (sw_if_index_set == 0) {
6127         errmsg ("missing interface name or sw_if_index\n");
6128         return -99;
6129     }
6130     if (!v6_address_set) {
6131         errmsg ("no address set\n");
6132         return -99;
6133     }
6134
6135     /* Construct the API message */
6136     M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
6137       sw_interface_ip6_set_link_local_address);
6138
6139     mp->sw_if_index = ntohl (sw_if_index);
6140     clib_memcpy (mp->address, &v6address, sizeof (v6address));
6141     mp->address_length = address_length;
6142
6143     /* send it... */
6144     S;
6145
6146     /* Wait for a reply, return good/bad news  */
6147     W;
6148
6149     /* NOTREACHED */
6150     return 0;
6151 }
6152
6153
6154 static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6155 {
6156     unformat_input_t * i = vam->input;
6157     vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6158     f64 timeout;
6159     u32 sw_if_index;
6160     u8 sw_if_index_set = 0;
6161     u32 address_length = 0;
6162     u8 v6_address_set = 0;
6163     ip6_address_t v6address;
6164     u8 use_default = 0;
6165     u8 no_advertise = 0;
6166     u8 off_link = 0;
6167     u8 no_autoconfig = 0;
6168     u8 no_onlink = 0;
6169     u8 is_no = 0;
6170     u32 val_lifetime = 0;
6171     u32 pref_lifetime = 0;
6172
6173     /* Parse args required to build the message */
6174     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6175         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6176             sw_if_index_set = 1;
6177         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6178             sw_if_index_set = 1;
6179         else if (unformat (i, "%U/%d",
6180                            unformat_ip6_address, &v6address,
6181                            &address_length))
6182             v6_address_set = 1;
6183         else if (unformat (i, "val_life %d", &val_lifetime))
6184             ;
6185         else if (unformat (i, "pref_life %d", &pref_lifetime))
6186             ;
6187         else if (unformat (i, "def"))
6188             use_default = 1;
6189         else if (unformat (i, "noadv"))
6190             no_advertise = 1;
6191         else if (unformat (i, "offl"))
6192             off_link = 1;
6193         else if (unformat (i, "noauto"))
6194             no_autoconfig = 1;
6195         else if (unformat (i, "nolink"))
6196             no_onlink = 1;
6197         else if (unformat (i, "isno"))
6198             is_no = 1;
6199         else {
6200             clib_warning ("parse error '%U'", format_unformat_error, i);
6201             return -99;
6202         }
6203     }
6204
6205     if (sw_if_index_set == 0) {
6206         errmsg ("missing interface name or sw_if_index\n");
6207         return -99;
6208     }
6209     if (!v6_address_set) {
6210         errmsg ("no address set\n");
6211         return -99;
6212     }
6213
6214     /* Construct the API message */
6215     M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6216
6217     mp->sw_if_index = ntohl (sw_if_index);
6218     clib_memcpy (mp->address, &v6address, sizeof (v6address));
6219     mp->address_length = address_length;
6220     mp->use_default = use_default;
6221     mp->no_advertise = no_advertise;
6222     mp->off_link = off_link;
6223     mp->no_autoconfig = no_autoconfig;
6224     mp->no_onlink = no_onlink;
6225     mp->is_no = is_no;
6226     mp->val_lifetime = ntohl(val_lifetime);
6227     mp->pref_lifetime = ntohl(pref_lifetime);
6228
6229     /* send it... */
6230     S;
6231
6232     /* Wait for a reply, return good/bad news  */
6233     W;
6234
6235     /* NOTREACHED */
6236     return 0;
6237 }
6238
6239 static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6240 {
6241     unformat_input_t * i = vam->input;
6242     vl_api_sw_interface_ip6nd_ra_config_t *mp;
6243     f64 timeout;
6244     u32 sw_if_index;
6245     u8 sw_if_index_set = 0;
6246     u8 suppress = 0;
6247     u8 managed = 0;
6248     u8 other = 0;
6249     u8 ll_option = 0;
6250     u8 send_unicast = 0;
6251     u8 cease = 0;
6252     u8 is_no = 0;
6253     u8 default_router = 0;
6254     u32 max_interval = 0;
6255     u32 min_interval = 0;
6256     u32 lifetime = 0;
6257     u32 initial_count = 0;
6258     u32 initial_interval = 0;
6259
6260
6261     /* Parse args required to build the message */
6262     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6263         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6264             sw_if_index_set = 1;
6265         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6266             sw_if_index_set = 1;
6267         else if (unformat (i, "maxint %d", &max_interval))
6268             ;
6269         else if (unformat (i, "minint %d", &min_interval))
6270             ;
6271         else if (unformat (i, "life %d", &lifetime))
6272             ;
6273         else if (unformat (i, "count %d", &initial_count))
6274             ;
6275         else if (unformat (i, "interval %d", &initial_interval))
6276             ;
6277         else if (unformat (i, "suppress") || unformat (i, "surpress"))
6278             suppress = 1;
6279         else if (unformat (i, "managed"))
6280             managed = 1;
6281         else if (unformat (i, "other"))
6282             other = 1;
6283         else if (unformat (i, "ll"))
6284             ll_option = 1;
6285         else if (unformat (i, "send"))
6286             send_unicast = 1;
6287         else if (unformat (i, "cease"))
6288             cease = 1;
6289         else if (unformat (i, "isno"))
6290             is_no = 1;
6291         else if (unformat (i, "def"))
6292             default_router = 1;
6293         else {
6294             clib_warning ("parse error '%U'", format_unformat_error, i);
6295             return -99;
6296         }
6297     }
6298
6299     if (sw_if_index_set == 0) {
6300         errmsg ("missing interface name or sw_if_index\n");
6301         return -99;
6302     }
6303
6304     /* Construct the API message */
6305     M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6306
6307     mp->sw_if_index = ntohl (sw_if_index);
6308     mp->max_interval = ntohl(max_interval);
6309     mp->min_interval = ntohl(min_interval);
6310     mp->lifetime = ntohl(lifetime);
6311     mp->initial_count = ntohl(initial_count);
6312     mp->initial_interval = ntohl(initial_interval);
6313     mp->suppress = suppress;
6314     mp->managed = managed;
6315     mp->other = other;
6316     mp->ll_option = ll_option;
6317     mp->send_unicast = send_unicast;
6318     mp->cease = cease;
6319     mp->is_no = is_no;
6320     mp->default_router = default_router;
6321
6322     /* send it... */
6323     S;
6324
6325     /* Wait for a reply, return good/bad news  */
6326     W;
6327
6328     /* NOTREACHED */
6329     return 0;
6330 }
6331
6332 static int api_set_arp_neighbor_limit (vat_main_t * vam)
6333 {
6334     unformat_input_t * i = vam->input;
6335     vl_api_set_arp_neighbor_limit_t *mp;
6336     f64 timeout;
6337     u32 arp_nbr_limit;
6338     u8 limit_set = 0;
6339     u8 is_ipv6 = 0;
6340
6341     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6342         if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6343             limit_set = 1;
6344         else if (unformat (i, "ipv6"))
6345             is_ipv6 = 1;
6346         else {
6347             clib_warning ("parse error '%U'", format_unformat_error, i);
6348             return -99;
6349         }
6350     }
6351
6352     if (limit_set == 0) {
6353         errmsg ("missing limit value\n");
6354         return -99;
6355     }
6356
6357     M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6358
6359     mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
6360     mp->is_ipv6 = is_ipv6;
6361
6362     S; W;
6363     /* NOTREACHED */
6364     return 0;
6365 }
6366
6367 static int api_l2_patch_add_del (vat_main_t * vam)
6368 {
6369     unformat_input_t * i = vam->input;
6370     vl_api_l2_patch_add_del_t *mp;
6371     f64 timeout;
6372     u32 rx_sw_if_index;
6373     u8 rx_sw_if_index_set = 0;
6374     u32 tx_sw_if_index;
6375     u8 tx_sw_if_index_set = 0;
6376     u8 is_add = 1;
6377
6378     /* Parse args required to build the message */
6379     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6380         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6381             rx_sw_if_index_set = 1;
6382         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6383             tx_sw_if_index_set = 1;
6384         else if (unformat (i, "rx")) {
6385             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6386                 if (unformat (i, "%U", unformat_sw_if_index, vam,
6387                               &rx_sw_if_index))
6388                     rx_sw_if_index_set = 1;
6389             } else
6390                 break;
6391         } else if (unformat (i, "tx")) {
6392             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6393                 if (unformat (i, "%U", unformat_sw_if_index, vam,
6394                               &tx_sw_if_index))
6395                     tx_sw_if_index_set = 1;
6396             } else
6397                 break;
6398         } else if (unformat (i, "del"))
6399             is_add = 0;
6400         else
6401             break;
6402     }
6403
6404     if (rx_sw_if_index_set == 0) {
6405         errmsg ("missing rx interface name or rx_sw_if_index\n");
6406         return -99;
6407     }
6408
6409     if (tx_sw_if_index_set == 0) {
6410         errmsg ("missing tx interface name or tx_sw_if_index\n");
6411         return -99;
6412     }
6413
6414     M(L2_PATCH_ADD_DEL, l2_patch_add_del);
6415
6416     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
6417     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
6418     mp->is_add = is_add;
6419
6420     S; W;
6421     /* NOTREACHED */
6422     return 0;
6423 }
6424 static int api_trace_profile_add (vat_main_t *vam)
6425 {
6426    unformat_input_t * input = vam->input;
6427    vl_api_trace_profile_add_t *mp;
6428    f64 timeout;
6429    u32 id = 0;
6430    u32 trace_option_elts = 0;
6431    u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
6432    int has_pow_option = 0;
6433    int has_ppc_option = 0;
6434
6435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6436     {
6437       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
6438                            "trace-tsp %d node-id 0x%x app-data 0x%x",
6439                     &id, &trace_type, &trace_option_elts, &trace_tsp,
6440                       &node_id, &app_data))
6441             ;
6442       else if (unformat (input, "pow"))
6443         has_pow_option = 1;
6444       else if (unformat (input, "ppc encap"))
6445         has_ppc_option = PPC_ENCAP;
6446       else if (unformat (input, "ppc decap"))
6447         has_ppc_option = PPC_DECAP;
6448       else if (unformat (input, "ppc none"))
6449         has_ppc_option = PPC_NONE;
6450       else
6451         break;
6452     }
6453   M(TRACE_PROFILE_ADD, trace_profile_add);
6454   mp->id = htons(id);
6455   mp->trace_type = trace_type;
6456   mp->trace_num_elt = trace_option_elts;
6457   mp->trace_ppc = has_ppc_option;
6458   mp->trace_app_data = htonl(app_data);
6459   mp->pow_enable = has_pow_option;
6460   mp->trace_tsp = trace_tsp;
6461   mp->node_id = htonl(node_id);
6462
6463   S; W;
6464
6465   return(0);
6466
6467 }
6468 static int api_trace_profile_apply (vat_main_t *vam)
6469 {
6470   unformat_input_t * input = vam->input;
6471   vl_api_trace_profile_apply_t *mp;
6472   f64 timeout;
6473   ip6_address_t addr;
6474   u32 mask_width = ~0;
6475   int is_add = 0;
6476   int is_pop = 0;
6477   int is_none = 0;
6478   u32 vrf_id = 0;
6479   u32 id = 0;
6480
6481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (input, "%U/%d",
6484                     unformat_ip6_address, &addr, &mask_width))
6485         ;
6486       else if (unformat (input, "id %d", &id))
6487         ;
6488       else if (unformat (input, "vrf-id %d", &vrf_id))
6489         ;
6490       else if (unformat (input, "add"))
6491         is_add = 1;
6492       else if (unformat (input, "pop"))
6493         is_pop = 1;
6494       else if (unformat (input, "none"))
6495         is_none = 1;
6496       else
6497         break;
6498     }
6499
6500   if ((is_add + is_pop + is_none) != 1) {
6501     errmsg("One of (add, pop, none) required");
6502     return -99;
6503   }
6504   if (mask_width == ~0) {
6505     errmsg("<address>/<mask-width> required");
6506     return -99;
6507   }
6508   M(TRACE_PROFILE_APPLY, trace_profile_apply);
6509   clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
6510   mp->id = htons(id);
6511   mp->prefix_length = htonl(mask_width);
6512   mp->vrf_id = htonl(vrf_id);
6513   if (is_add)
6514     mp->trace_op = IOAM_HBYH_ADD;
6515   else if (is_pop)
6516     mp->trace_op = IOAM_HBYH_POP;
6517   else
6518     mp->trace_op = IOAM_HBYH_MOD;
6519
6520   if(is_none)
6521     mp->enable = 0;
6522   else
6523     mp->enable = 1;
6524
6525   S; W;
6526
6527   return 0;
6528 }
6529
6530 static int api_trace_profile_del (vat_main_t *vam)
6531 {
6532    vl_api_trace_profile_del_t *mp;
6533    f64 timeout;
6534
6535    M(TRACE_PROFILE_DEL, trace_profile_del);
6536    S; W;
6537    return 0;
6538 }
6539
6540 static int api_sr_tunnel_add_del (vat_main_t * vam)
6541 {
6542   unformat_input_t * i = vam->input;
6543   vl_api_sr_tunnel_add_del_t *mp;
6544   f64 timeout;
6545   int is_del = 0;
6546   int pl_index;
6547   ip6_address_t src_address;
6548   int src_address_set = 0;
6549   ip6_address_t dst_address;
6550   u32 dst_mask_width;
6551   int dst_address_set = 0;
6552   u16 flags = 0;
6553   u32 rx_table_id = 0;
6554   u32 tx_table_id = 0;
6555   ip6_address_t * segments = 0;
6556   ip6_address_t * this_seg;
6557   ip6_address_t * tags = 0;
6558   ip6_address_t * this_tag;
6559   ip6_address_t next_address, tag;
6560   u8 * name = 0;
6561   u8 * policy_name = 0;
6562
6563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6564     {
6565       if (unformat (i, "del"))
6566         is_del = 1;
6567       else if (unformat (i, "name %s", &name))
6568             ;
6569       else if (unformat (i, "policy %s", &policy_name))
6570             ;
6571       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
6572         ;
6573       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
6574         ;
6575       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
6576         src_address_set = 1;
6577       else if (unformat (i, "dst %U/%d",
6578                          unformat_ip6_address, &dst_address,
6579                          &dst_mask_width))
6580         dst_address_set = 1;
6581       else if (unformat (i, "next %U", unformat_ip6_address,
6582                          &next_address))
6583         {
6584           vec_add2 (segments, this_seg, 1);
6585           clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
6586         }
6587       else if (unformat (i, "tag %U", unformat_ip6_address,
6588                          &tag))
6589         {
6590           vec_add2 (tags, this_tag, 1);
6591           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
6592         }
6593       else if (unformat (i, "clean"))
6594         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
6595       else if (unformat (i, "protected"))
6596         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
6597       else if (unformat (i, "InPE %d", &pl_index))
6598         {
6599           if (pl_index <= 0 || pl_index > 4)
6600             {
6601             pl_index_range_error:
6602               errmsg ("pl index %d out of range\n", pl_index);
6603               return -99;
6604             }
6605           flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
6606         }
6607       else if (unformat (i, "EgPE %d", &pl_index))
6608         {
6609           if (pl_index <= 0 || pl_index > 4)
6610             goto pl_index_range_error;
6611           flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
6612         }
6613       else if (unformat (i, "OrgSrc %d", &pl_index))
6614         {
6615           if (pl_index <= 0 || pl_index > 4)
6616             goto pl_index_range_error;
6617           flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
6618         }
6619       else
6620         break;
6621     }
6622
6623   if (!src_address_set)
6624     {
6625       errmsg ("src address required\n");
6626       return -99;
6627     }
6628
6629   if (!dst_address_set)
6630     {
6631       errmsg ("dst address required\n");
6632       return -99;
6633     }
6634
6635   if (!segments)
6636     {
6637       errmsg ("at least one sr segment required\n");
6638       return -99;
6639     }
6640
6641   M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
6642      vec_len(segments) * sizeof (ip6_address_t)
6643      + vec_len(tags) * sizeof (ip6_address_t));
6644
6645   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
6646   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
6647   mp->dst_mask_width = dst_mask_width;
6648   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
6649   mp->n_segments = vec_len (segments);
6650   mp->n_tags = vec_len (tags);
6651   mp->is_add = is_del == 0;
6652   clib_memcpy (mp->segs_and_tags, segments,
6653           vec_len(segments)* sizeof (ip6_address_t));
6654   clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
6655           tags, vec_len(tags)* sizeof (ip6_address_t));
6656
6657   mp->outer_vrf_id = ntohl (rx_table_id);
6658   mp->inner_vrf_id = ntohl (tx_table_id);
6659   memcpy (mp->name, name, vec_len(name));
6660   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6661
6662   vec_free (segments);
6663   vec_free (tags);
6664
6665   S; W;
6666   /* NOTREACHED */
6667 }
6668
6669 static int api_sr_policy_add_del (vat_main_t * vam)
6670 {
6671   unformat_input_t * input = vam->input;
6672   vl_api_sr_policy_add_del_t *mp;
6673   f64 timeout;
6674   int is_del = 0;
6675   u8 * name = 0;
6676   u8 * tunnel_name = 0;
6677   u8 ** tunnel_names = 0;
6678
6679   int name_set = 0 ;
6680   int tunnel_set = 0;
6681   int j = 0;
6682   int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
6683   int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
6684
6685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6686     {
6687       if (unformat (input, "del"))
6688         is_del = 1;
6689       else if (unformat (input, "name %s", &name))
6690         name_set = 1;
6691       else if (unformat (input, "tunnel %s", &tunnel_name))
6692         {
6693           if (tunnel_name)
6694             {
6695               vec_add1 (tunnel_names, tunnel_name);
6696               /* For serializer:
6697                  - length = #bytes to store in serial vector
6698                  - +1 = byte to store that length
6699               */
6700               tunnel_names_length += (vec_len (tunnel_name) + 1);
6701               tunnel_set = 1;
6702               tunnel_name = 0;
6703             }
6704         }
6705       else
6706         break;
6707     }
6708
6709   if (!name_set)
6710     {
6711       errmsg ("policy name required\n");
6712       return -99;
6713     }
6714
6715   if ((!tunnel_set) && (!is_del))
6716     {
6717       errmsg ("tunnel name required\n");
6718       return -99;
6719     }
6720
6721   M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
6722
6723
6724
6725   mp->is_add = !is_del;
6726
6727   memcpy (mp->name, name, vec_len(name));
6728   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
6729   u8 * serial_orig = 0;
6730   vec_validate (serial_orig, tunnel_names_length);
6731   *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
6732   serial_orig += 1; // Move along one byte to store the length of first tunnel_name
6733
6734   for (j=0; j < vec_len(tunnel_names); j++)
6735     {
6736       tun_name_len = vec_len (tunnel_names[j]);
6737       *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
6738       serial_orig += 1; // Move along one byte to store the actual tunnel name
6739       memcpy (serial_orig, tunnel_names[j], tun_name_len);
6740       serial_orig += tun_name_len; // Advance past the copy
6741     }
6742   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
6743
6744   vec_free (tunnel_names);
6745   vec_free (tunnel_name);
6746
6747   S; W;
6748   /* NOTREACHED */
6749 }
6750
6751 static int api_sr_multicast_map_add_del (vat_main_t * vam)
6752 {
6753   unformat_input_t * input = vam->input;
6754   vl_api_sr_multicast_map_add_del_t *mp;
6755   f64 timeout;
6756   int is_del = 0;
6757   ip6_address_t multicast_address;
6758   u8 * policy_name = 0;
6759   int multicast_address_set = 0;
6760
6761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (input, "del"))
6764         is_del = 1;
6765       else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
6766         multicast_address_set = 1;
6767       else if (unformat (input, "sr-policy %s", &policy_name))
6768         ;
6769       else
6770         break;
6771     }
6772
6773   if (!is_del && !policy_name)
6774     {
6775       errmsg ("sr-policy name required\n");
6776       return -99;
6777     }
6778
6779
6780   if (!multicast_address_set)
6781     {
6782       errmsg ("address required\n");
6783       return -99;
6784     }
6785
6786   M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
6787
6788   mp->is_add = !is_del;
6789   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6790   clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
6791
6792
6793   vec_free (policy_name);
6794
6795   S; W;
6796   /* NOTREACHED */
6797 }
6798
6799
6800 #define foreach_ip4_proto_field                 \
6801 _(src_address)                                  \
6802 _(dst_address)                                  \
6803 _(tos)                                          \
6804 _(length)                                       \
6805 _(fragment_id)                                  \
6806 _(ttl)                                          \
6807 _(protocol)                                     \
6808 _(checksum)
6809
6810 uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6811 {
6812   u8 ** maskp = va_arg (*args, u8 **);
6813   u8 * mask = 0;
6814   u8 found_something = 0;
6815   ip4_header_t * ip;
6816
6817 #define _(a) u8 a=0;
6818   foreach_ip4_proto_field;
6819 #undef _
6820   u8 version = 0;
6821   u8 hdr_length = 0;
6822
6823
6824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6825     {
6826       if (unformat (input, "version"))
6827         version = 1;
6828       else if (unformat (input, "hdr_length"))
6829         hdr_length = 1;
6830       else if (unformat (input, "src"))
6831         src_address = 1;
6832       else if (unformat (input, "dst"))
6833         dst_address = 1;
6834       else if (unformat (input, "proto"))
6835         protocol = 1;
6836
6837 #define _(a) else if (unformat (input, #a)) a=1;
6838       foreach_ip4_proto_field
6839 #undef _
6840       else
6841         break;
6842     }
6843
6844 #define _(a) found_something += a;
6845   foreach_ip4_proto_field;
6846 #undef _
6847
6848   if (found_something == 0)
6849     return 0;
6850
6851   vec_validate (mask, sizeof (*ip) - 1);
6852
6853   ip = (ip4_header_t *) mask;
6854
6855 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6856   foreach_ip4_proto_field;
6857 #undef _
6858
6859   ip->ip_version_and_header_length = 0;
6860
6861   if (version)
6862     ip->ip_version_and_header_length |= 0xF0;
6863
6864   if (hdr_length)
6865     ip->ip_version_and_header_length |= 0x0F;
6866
6867   *maskp = mask;
6868   return 1;
6869 }
6870
6871 #define foreach_ip6_proto_field                 \
6872 _(src_address)                                  \
6873 _(dst_address)                                  \
6874 _(payload_length)                               \
6875 _(hop_limit)                                    \
6876 _(protocol)
6877
6878 uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6879 {
6880   u8 ** maskp = va_arg (*args, u8 **);
6881   u8 * mask = 0;
6882   u8 found_something = 0;
6883   ip6_header_t * ip;
6884   u32 ip_version_traffic_class_and_flow_label;
6885
6886 #define _(a) u8 a=0;
6887   foreach_ip6_proto_field;
6888 #undef _
6889   u8 version = 0;
6890   u8 traffic_class = 0;
6891   u8 flow_label = 0;
6892
6893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (input, "version"))
6896         version = 1;
6897       else if (unformat (input, "traffic-class"))
6898         traffic_class = 1;
6899       else if (unformat (input, "flow-label"))
6900         flow_label = 1;
6901       else if (unformat (input, "src"))
6902         src_address = 1;
6903       else if (unformat (input, "dst"))
6904         dst_address = 1;
6905       else if (unformat (input, "proto"))
6906         protocol = 1;
6907
6908 #define _(a) else if (unformat (input, #a)) a=1;
6909       foreach_ip6_proto_field
6910 #undef _
6911       else
6912         break;
6913     }
6914
6915 #define _(a) found_something += a;
6916   foreach_ip6_proto_field;
6917 #undef _
6918
6919   if (found_something == 0)
6920     return 0;
6921
6922   vec_validate (mask, sizeof (*ip) - 1);
6923
6924   ip = (ip6_header_t *) mask;
6925
6926 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6927   foreach_ip6_proto_field;
6928 #undef _
6929
6930   ip_version_traffic_class_and_flow_label = 0;
6931
6932   if (version)
6933     ip_version_traffic_class_and_flow_label |= 0xF0000000;
6934
6935   if (traffic_class)
6936     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6937
6938   if (flow_label)
6939     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6940
6941   ip->ip_version_traffic_class_and_flow_label =
6942     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6943
6944   *maskp = mask;
6945   return 1;
6946 }
6947
6948 uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6949 {
6950   u8 ** maskp = va_arg (*args, u8 **);
6951
6952   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6953     if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6954       return 1;
6955     else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6956       return 1;
6957     else
6958       break;
6959   }
6960   return 0;
6961 }
6962
6963 uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6964 {
6965   u8 ** maskp = va_arg (*args, u8 **);
6966   u8 * mask = 0;
6967   u8 src = 0;
6968   u8 dst = 0;
6969   u8 proto = 0;
6970   u8 tag1 = 0;
6971   u8 tag2 = 0;
6972   u8 ignore_tag1 = 0;
6973   u8 ignore_tag2 = 0;
6974   u8 cos1 = 0;
6975   u8 cos2 = 0;
6976   u8 dot1q = 0;
6977   u8 dot1ad = 0;
6978   int len = 14;
6979
6980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6981     if (unformat (input, "src"))
6982       src = 1;
6983     else if (unformat (input, "dst"))
6984       dst = 1;
6985     else if (unformat (input, "proto"))
6986       proto = 1;
6987     else if (unformat (input, "tag1"))
6988       tag1 = 1;
6989     else if (unformat (input, "tag2"))
6990       tag2 = 1;
6991     else if (unformat (input, "ignore-tag1"))
6992       ignore_tag1 = 1;
6993     else if (unformat (input, "ignore-tag2"))
6994       ignore_tag2 = 1;
6995     else if (unformat (input, "cos1"))
6996       cos1 = 1;
6997     else if (unformat (input, "cos2"))
6998       cos2 = 1;
6999     else if (unformat (input, "dot1q"))
7000       dot1q = 1;
7001     else if (unformat (input, "dot1ad"))
7002       dot1ad = 1;
7003     else
7004       break;
7005   }
7006   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7007       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7008     return 0;
7009
7010   if (tag1 || ignore_tag1 || cos1 || dot1q)
7011     len = 18;
7012   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7013     len = 22;
7014
7015   vec_validate (mask, len-1);
7016
7017   if (dst)
7018     memset (mask, 0xff, 6);
7019
7020   if (src)
7021     memset (mask + 6, 0xff, 6);
7022
7023   if (tag2 || dot1ad)
7024     {
7025       /* inner vlan tag */
7026       if (tag2)
7027         {
7028           mask[19] = 0xff;
7029           mask[18] = 0x0f;
7030         }
7031       if (cos2)
7032         mask[18] |= 0xe0;
7033       if (proto)
7034           mask[21] = mask [20] = 0xff;
7035       if (tag1)
7036         {
7037           mask [15] = 0xff;
7038           mask [14] = 0x0f;
7039         }
7040       if (cos1)
7041         mask[14] |= 0xe0;
7042       *maskp = mask;
7043       return 1;
7044     }
7045   if (tag1 | dot1q)
7046     {
7047       if (tag1)
7048         {
7049           mask [15] = 0xff;
7050           mask [14] = 0x0f;
7051         }
7052       if (cos1)
7053         mask[14] |= 0xe0;
7054       if (proto)
7055           mask[16] = mask [17] = 0xff;
7056
7057       *maskp = mask;
7058       return 1;
7059     }
7060   if (cos2)
7061     mask[18] |= 0xe0;
7062   if (cos1)
7063     mask[14] |= 0xe0;
7064   if (proto)
7065     mask[12] = mask [13] = 0xff;
7066
7067   *maskp = mask;
7068   return 1;
7069 }
7070
7071 uword unformat_classify_mask (unformat_input_t * input, va_list * args)
7072 {
7073   u8 ** maskp = va_arg (*args, u8 **);
7074   u32 * skipp = va_arg (*args, u32 *);
7075   u32 * matchp = va_arg (*args, u32 *);
7076   u32 match;
7077   u8 * mask = 0;
7078   u8 * l2 = 0;
7079   u8 * l3 = 0;
7080   int i;
7081
7082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7083     if (unformat (input, "hex %U", unformat_hex_string, &mask))
7084       ;
7085     else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7086       ;
7087     else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7088       ;
7089     else
7090       break;
7091   }
7092
7093   if (mask || l2 || l3)
7094     {
7095       if (l2 || l3)
7096         {
7097           /* "With a free Ethernet header in every package" */
7098           if (l2 == 0)
7099             vec_validate (l2, 13);
7100           mask = l2;
7101           vec_append (mask, l3);
7102           vec_free (l3);
7103         }
7104
7105       /* Scan forward looking for the first significant mask octet */
7106       for (i = 0; i < vec_len (mask); i++)
7107         if (mask[i])
7108           break;
7109
7110       /* compute (skip, match) params */
7111       *skipp = i / sizeof(u32x4);
7112       vec_delete (mask, *skipp * sizeof(u32x4), 0);
7113
7114       /* Pad mask to an even multiple of the vector size */
7115       while (vec_len (mask) % sizeof (u32x4))
7116         vec_add1 (mask, 0);
7117
7118       match = vec_len (mask) / sizeof (u32x4);
7119
7120       for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
7121         {
7122           u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
7123           if (*tmp || *(tmp+1))
7124             break;
7125           match--;
7126         }
7127       if (match == 0)
7128         clib_warning ("BUG: match 0");
7129
7130       _vec_len (mask) = match * sizeof(u32x4);
7131
7132       *matchp = match;
7133       *maskp = mask;
7134
7135       return 1;
7136     }
7137
7138   return 0;
7139 }
7140
7141 #define foreach_l2_next                         \
7142 _(drop, DROP)                                   \
7143 _(ethernet, ETHERNET_INPUT)                     \
7144 _(ip4, IP4_INPUT)                               \
7145 _(ip6, IP6_INPUT)
7146
7147 uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
7148 {
7149   u32 * miss_next_indexp = va_arg (*args, u32 *);
7150   u32 next_index = 0;
7151   u32 tmp;
7152
7153 #define _(n,N) \
7154   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7155   foreach_l2_next;
7156 #undef _
7157
7158   if (unformat (input, "%d", &tmp))
7159     {
7160       next_index = tmp;
7161       goto out;
7162     }
7163
7164   return 0;
7165
7166  out:
7167   *miss_next_indexp = next_index;
7168   return 1;
7169 }
7170
7171 #define foreach_ip_next                         \
7172 _(miss, MISS)                                   \
7173 _(drop, DROP)                                   \
7174 _(local, LOCAL)                                 \
7175 _(rewrite, REWRITE)
7176
7177 uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
7178 {
7179   u32 * miss_next_indexp = va_arg (*args, u32 *);
7180   u32 next_index = 0;
7181   u32 tmp;
7182
7183 #define _(n,N) \
7184   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7185   foreach_ip_next;
7186 #undef _
7187
7188   if (unformat (input, "%d", &tmp))
7189     {
7190       next_index = tmp;
7191       goto out;
7192     }
7193
7194   return 0;
7195
7196  out:
7197   *miss_next_indexp = next_index;
7198   return 1;
7199 }
7200
7201 #define foreach_acl_next                        \
7202 _(deny, DENY)
7203
7204 uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
7205 {
7206   u32 * miss_next_indexp = va_arg (*args, u32 *);
7207   u32 next_index = 0;
7208   u32 tmp;
7209
7210 #define _(n,N) \
7211   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7212   foreach_acl_next;
7213 #undef _
7214
7215   if (unformat (input, "permit"))
7216     {
7217       next_index = ~0;
7218       goto out;
7219     }
7220   else if (unformat (input, "%d", &tmp))
7221     {
7222       next_index = tmp;
7223       goto out;
7224     }
7225
7226   return 0;
7227
7228  out:
7229   *miss_next_indexp = next_index;
7230   return 1;
7231 }
7232
7233 uword unformat_policer_precolor (unformat_input_t * input, va_list * args)
7234 {
7235   u32 * r = va_arg (*args, u32 *);
7236
7237   if (unformat (input, "conform-color"))
7238     *r = POLICE_CONFORM;
7239   else if (unformat (input, "exceed-color"))
7240     *r = POLICE_EXCEED;
7241   else
7242     return 0;
7243
7244   return 1;
7245 }
7246
7247 static int api_classify_add_del_table (vat_main_t * vam)
7248 {
7249   unformat_input_t * i = vam->input;
7250   vl_api_classify_add_del_table_t *mp;
7251
7252   u32 nbuckets = 2;
7253   u32 skip = ~0;
7254   u32 match = ~0;
7255   int is_add = 1;
7256   u32 table_index = ~0;
7257   u32 next_table_index = ~0;
7258   u32 miss_next_index = ~0;
7259   u32 memory_size = 32<<20;
7260   u8 * mask = 0;
7261   f64 timeout;
7262
7263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7264     if (unformat (i, "del"))
7265       is_add = 0;
7266     else if (unformat (i, "buckets %d", &nbuckets))
7267       ;
7268     else if (unformat (i, "memory_size %d", &memory_size))
7269       ;
7270     else if (unformat (i, "skip %d", &skip))
7271       ;
7272     else if (unformat (i, "match %d", &match))
7273       ;
7274     else if (unformat (i, "table %d", &table_index))
7275       ;
7276     else if (unformat (i, "mask %U", unformat_classify_mask,
7277                        &mask, &skip, &match))
7278       ;
7279     else if (unformat (i, "next-table %d", &next_table_index))
7280       ;
7281     else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7282                        &miss_next_index))
7283       ;
7284     else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7285                        &miss_next_index))
7286       ;
7287     else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7288                        &miss_next_index))
7289       ;
7290     else
7291       break;
7292   }
7293
7294   if (is_add && mask == 0) {
7295       errmsg ("Mask required\n");
7296       return -99;
7297   }
7298
7299   if (is_add && skip == ~0) {
7300       errmsg ("skip count required\n");
7301       return -99;
7302   }
7303
7304   if (is_add && match == ~0) {
7305       errmsg ("match count required\n");
7306       return -99;
7307   }
7308
7309   if (!is_add && table_index == ~0) {
7310       errmsg ("table index required for delete\n");
7311       return -99;
7312   }
7313
7314   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
7315       vec_len(mask));
7316
7317   mp->is_add = is_add;
7318   mp->table_index = ntohl(table_index);
7319   mp->nbuckets = ntohl(nbuckets);
7320   mp->memory_size = ntohl(memory_size);
7321   mp->skip_n_vectors = ntohl(skip);
7322   mp->match_n_vectors = ntohl(match);
7323   mp->next_table_index = ntohl(next_table_index);
7324   mp->miss_next_index = ntohl(miss_next_index);
7325   clib_memcpy (mp->mask, mask, vec_len(mask));
7326
7327   vec_free(mask);
7328
7329   S; W;
7330   /* NOTREACHED */
7331 }
7332
7333 uword unformat_ip4_match (unformat_input_t * input, va_list * args)
7334 {
7335   u8 ** matchp = va_arg (*args, u8 **);
7336   u8 * match = 0;
7337   ip4_header_t * ip;
7338   int version = 0;
7339   u32 version_val;
7340   int hdr_length = 0;
7341   u32 hdr_length_val;
7342   int src = 0, dst = 0;
7343   ip4_address_t src_val, dst_val;
7344   int proto = 0;
7345   u32 proto_val;
7346   int tos = 0;
7347   u32 tos_val;
7348   int length = 0;
7349   u32 length_val;
7350   int fragment_id = 0;
7351   u32 fragment_id_val;
7352   int ttl = 0;
7353   int ttl_val;
7354   int checksum = 0;
7355   u32 checksum_val;
7356
7357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7358     {
7359       if (unformat (input, "version %d", &version_val))
7360         version = 1;
7361       else if (unformat (input, "hdr_length %d", &hdr_length_val))
7362         hdr_length = 1;
7363       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
7364         src = 1;
7365       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
7366         dst = 1;
7367       else if (unformat (input, "proto %d", &proto_val))
7368         proto = 1;
7369       else if (unformat (input, "tos %d", &tos_val))
7370         tos = 1;
7371       else if (unformat (input, "length %d", &length_val))
7372         length = 1;
7373       else if (unformat (input, "fragment_id %d", &fragment_id_val))
7374         fragment_id = 1;
7375       else if (unformat (input, "ttl %d", &ttl_val))
7376         ttl = 1;
7377       else if (unformat (input, "checksum %d", &checksum_val))
7378         checksum = 1;
7379       else
7380         break;
7381     }
7382
7383   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
7384       + ttl + checksum == 0)
7385     return 0;
7386
7387   /*
7388    * Aligned because we use the real comparison functions
7389    */
7390   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
7391
7392   ip = (ip4_header_t *) match;
7393
7394   /* These are realistically matched in practice */
7395   if (src)
7396     ip->src_address.as_u32 = src_val.as_u32;
7397
7398   if (dst)
7399     ip->dst_address.as_u32 = dst_val.as_u32;
7400
7401   if (proto)
7402     ip->protocol = proto_val;
7403
7404
7405   /* These are not, but they're included for completeness */
7406   if (version)
7407     ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
7408
7409   if (hdr_length)
7410     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
7411
7412   if (tos)
7413     ip->tos = tos_val;
7414
7415   if (length)
7416     ip->length = length_val;
7417
7418   if (ttl)
7419     ip->ttl = ttl_val;
7420
7421   if (checksum)
7422     ip->checksum = checksum_val;
7423
7424   *matchp = match;
7425   return 1;
7426 }
7427
7428 uword unformat_ip6_match (unformat_input_t * input, va_list * args)
7429 {
7430   u8 ** matchp = va_arg (*args, u8 **);
7431   u8 * match = 0;
7432   ip6_header_t * ip;
7433   int version = 0;
7434   u32 version_val;
7435   u8  traffic_class;
7436   u32 traffic_class_val;
7437   u8  flow_label;
7438   u8  flow_label_val;
7439   int src = 0, dst = 0;
7440   ip6_address_t src_val, dst_val;
7441   int proto = 0;
7442   u32 proto_val;
7443   int payload_length = 0;
7444   u32 payload_length_val;
7445   int hop_limit = 0;
7446   int hop_limit_val;
7447   u32 ip_version_traffic_class_and_flow_label;
7448
7449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (input, "version %d", &version_val))
7452         version = 1;
7453       else if (unformat (input, "traffic_class %d", &traffic_class_val))
7454         traffic_class = 1;
7455       else if (unformat (input, "flow_label %d", &flow_label_val))
7456         flow_label = 1;
7457       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
7458         src = 1;
7459       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
7460         dst = 1;
7461       else if (unformat (input, "proto %d", &proto_val))
7462         proto = 1;
7463       else if (unformat (input, "payload_length %d", &payload_length_val))
7464         payload_length = 1;
7465       else if (unformat (input, "hop_limit %d", &hop_limit_val))
7466         hop_limit = 1;
7467       else
7468         break;
7469     }
7470
7471   if (version + traffic_class + flow_label + src + dst + proto +
7472       payload_length + hop_limit == 0)
7473     return 0;
7474
7475   /*
7476    * Aligned because we use the real comparison functions
7477    */
7478   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
7479
7480   ip = (ip6_header_t *) match;
7481
7482   if (src)
7483     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
7484
7485   if (dst)
7486     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
7487
7488   if (proto)
7489     ip->protocol = proto_val;
7490
7491   ip_version_traffic_class_and_flow_label = 0;
7492
7493   if (version)
7494     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
7495
7496   if (traffic_class)
7497     ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
7498
7499   if (flow_label)
7500     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
7501
7502   ip->ip_version_traffic_class_and_flow_label =
7503     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7504
7505   if (payload_length)
7506     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
7507
7508   if (hop_limit)
7509     ip->hop_limit = hop_limit_val;
7510
7511   *matchp = match;
7512   return 1;
7513 }
7514
7515 uword unformat_l3_match (unformat_input_t * input, va_list * args)
7516 {
7517   u8 ** matchp = va_arg (*args, u8 **);
7518
7519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7520     if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
7521       return 1;
7522     else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
7523       return 1;
7524     else
7525       break;
7526   }
7527   return 0;
7528 }
7529
7530 uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
7531 {
7532   u8 * tagp = va_arg (*args, u8 *);
7533   u32 tag;
7534
7535   if (unformat(input, "%d", &tag))
7536     {
7537       tagp[0] = (tag>>8) & 0x0F;
7538       tagp[1] = tag & 0xFF;
7539       return 1;
7540     }
7541
7542   return 0;
7543 }
7544
7545 uword unformat_l2_match (unformat_input_t * input, va_list * args)
7546 {
7547   u8 ** matchp = va_arg (*args, u8 **);
7548   u8 * match = 0;
7549   u8 src = 0;
7550   u8 src_val[6];
7551   u8 dst = 0;
7552   u8 dst_val[6];
7553   u8 proto = 0;
7554   u16 proto_val;
7555   u8 tag1 = 0;
7556   u8 tag1_val [2];
7557   u8 tag2 = 0;
7558   u8 tag2_val [2];
7559   int len = 14;
7560   u8 ignore_tag1 = 0;
7561   u8 ignore_tag2 = 0;
7562   u8 cos1 = 0;
7563   u8 cos2 = 0;
7564   u32 cos1_val = 0;
7565   u32 cos2_val = 0;
7566
7567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7568     if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
7569       src = 1;
7570     else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
7571       dst = 1;
7572     else if (unformat (input, "proto %U",
7573                        unformat_ethernet_type_host_byte_order, &proto_val))
7574       proto = 1;
7575     else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
7576       tag1 = 1;
7577     else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
7578       tag2 = 1;
7579     else if (unformat (input, "ignore-tag1"))
7580       ignore_tag1 = 1;
7581     else if (unformat (input, "ignore-tag2"))
7582       ignore_tag2 = 1;
7583     else if (unformat (input, "cos1 %d", &cos1_val))
7584       cos1 = 1;
7585     else if (unformat (input, "cos2 %d", &cos2_val))
7586       cos2 = 1;
7587     else
7588       break;
7589   }
7590   if ((src + dst + proto + tag1 + tag2 +
7591       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7592     return 0;
7593
7594   if (tag1 || ignore_tag1 || cos1)
7595     len = 18;
7596   if (tag2 || ignore_tag2 || cos2)
7597     len = 22;
7598
7599   vec_validate_aligned (match, len-1, sizeof(u32x4));
7600
7601   if (dst)
7602     clib_memcpy (match, dst_val, 6);
7603
7604   if (src)
7605     clib_memcpy (match + 6, src_val, 6);
7606
7607   if (tag2)
7608     {
7609       /* inner vlan tag */
7610       match[19] = tag2_val[1];
7611       match[18] = tag2_val[0];
7612       if (cos2)
7613         match [18] |= (cos2_val & 0x7) << 5;
7614       if (proto)
7615         {
7616           match[21] = proto_val & 0xff;
7617           match[20] = proto_val >> 8;
7618         }
7619       if (tag1)
7620         {
7621           match [15] = tag1_val[1];
7622           match [14] = tag1_val[0];
7623         }
7624       if (cos1)
7625         match [14] |= (cos1_val & 0x7) << 5;
7626       *matchp = match;
7627       return 1;
7628     }
7629   if (tag1)
7630     {
7631       match [15] = tag1_val[1];
7632       match [14] = tag1_val[0];
7633       if (proto)
7634         {
7635           match[17] = proto_val & 0xff;
7636           match[16] = proto_val >> 8;
7637         }
7638       if (cos1)
7639         match [14] |= (cos1_val & 0x7) << 5;
7640
7641       *matchp = match;
7642       return 1;
7643     }
7644   if (cos2)
7645     match [18] |= (cos2_val & 0x7) << 5;
7646   if (cos1)
7647     match [14] |= (cos1_val & 0x7) << 5;
7648   if (proto)
7649     {
7650       match[13] = proto_val & 0xff;
7651       match[12] = proto_val >> 8;
7652     }
7653
7654   *matchp = match;
7655   return 1;
7656 }
7657
7658
7659 uword unformat_classify_match (unformat_input_t * input, va_list * args)
7660 {
7661   u8 ** matchp = va_arg (*args, u8 **);
7662   u32 skip_n_vectors = va_arg (*args, u32);
7663   u32 match_n_vectors = va_arg (*args, u32);
7664
7665   u8 * match = 0;
7666   u8 * l2 = 0;
7667   u8 * l3 = 0;
7668
7669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
7670     if (unformat (input, "hex %U", unformat_hex_string, &match))
7671       ;
7672     else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
7673       ;
7674     else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
7675       ;
7676     else
7677       break;
7678   }
7679
7680   if (match || l2 || l3)
7681     {
7682       if (l2 || l3)
7683         {
7684           /* "Win a free Ethernet header in every packet" */
7685           if (l2 == 0)
7686             vec_validate_aligned (l2, 13, sizeof(u32x4));
7687           match = l2;
7688           vec_append_aligned (match, l3, sizeof(u32x4));
7689           vec_free (l3);
7690         }
7691
7692       /* Make sure the vector is big enough even if key is all 0's */
7693       vec_validate_aligned
7694           (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
7695            sizeof(u32x4));
7696
7697       /* Set size, include skipped vectors*/
7698       _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
7699
7700       *matchp = match;
7701
7702       return 1;
7703     }
7704
7705   return 0;
7706 }
7707
7708 static int api_classify_add_del_session (vat_main_t * vam)
7709 {
7710     unformat_input_t * i = vam->input;
7711     vl_api_classify_add_del_session_t *mp;
7712     int is_add = 1;
7713     u32 table_index = ~0;
7714     u32 hit_next_index = ~0;
7715     u32 opaque_index = ~0;
7716     u8 * match = 0;
7717     i32 advance = 0;
7718     f64 timeout;
7719     u32 skip_n_vectors = 0;
7720     u32 match_n_vectors = 0;
7721
7722     /*
7723      * Warning: you have to supply skip_n and match_n
7724      * because the API client cant simply look at the classify
7725      * table object.
7726      */
7727
7728     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7729         if (unformat (i, "del"))
7730             is_add = 0;
7731         else if (unformat (i, "hit-next %U", unformat_ip_next_index,
7732                            &hit_next_index))
7733             ;
7734         else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
7735                            &hit_next_index))
7736             ;
7737         else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
7738                            &hit_next_index))
7739             ;
7740         else if (unformat (i, "policer-hit-next %d", &hit_next_index))
7741             ;
7742         else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
7743             ;
7744         else if (unformat (i, "opaque-index %d", &opaque_index))
7745             ;
7746         else if (unformat (i, "skip_n %d", &skip_n_vectors))
7747             ;
7748         else if (unformat (i, "match_n %d", &match_n_vectors))
7749             ;
7750         else if (unformat (i, "match %U", unformat_classify_match,
7751                            &match, skip_n_vectors, match_n_vectors))
7752             ;
7753         else if (unformat (i, "advance %d", &advance))
7754             ;
7755         else if (unformat (i, "table-index %d", &table_index))
7756             ;
7757         else
7758             break;
7759     }
7760
7761     if (table_index == ~0) {
7762         errmsg ("Table index required\n");
7763         return -99;
7764     }
7765
7766     if (is_add && match == 0) {
7767         errmsg ("Match value required\n");
7768         return -99;
7769     }
7770
7771     M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
7772         vec_len(match));
7773
7774     mp->is_add = is_add;
7775     mp->table_index = ntohl(table_index);
7776     mp->hit_next_index = ntohl(hit_next_index);
7777     mp->opaque_index = ntohl(opaque_index);
7778     mp->advance = ntohl(advance);
7779     clib_memcpy (mp->match, match, vec_len(match));
7780     vec_free(match);
7781
7782     S; W;
7783     /* NOTREACHED */
7784 }
7785
7786 static int api_classify_set_interface_ip_table (vat_main_t * vam)
7787 {
7788     unformat_input_t * i = vam->input;
7789     vl_api_classify_set_interface_ip_table_t *mp;
7790     f64 timeout;
7791     u32 sw_if_index;
7792     int sw_if_index_set;
7793     u32 table_index = ~0;
7794     u8  is_ipv6 = 0;
7795
7796     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7797         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7798             sw_if_index_set = 1;
7799         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7800             sw_if_index_set = 1;
7801         else if (unformat (i, "table %d", &table_index))
7802             ;
7803         else {
7804             clib_warning ("parse error '%U'", format_unformat_error, i);
7805             return -99;
7806         }
7807     }
7808
7809     if (sw_if_index_set == 0) {
7810         errmsg ("missing interface name or sw_if_index\n");
7811         return -99;
7812     }
7813
7814
7815     M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
7816
7817     mp->sw_if_index = ntohl(sw_if_index);
7818     mp->table_index = ntohl(table_index);
7819     mp->is_ipv6 = is_ipv6;
7820
7821     S; W;
7822     /* NOTREACHED */
7823     return 0;
7824 }
7825
7826 static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7827 {
7828     unformat_input_t * i = vam->input;
7829     vl_api_classify_set_interface_l2_tables_t *mp;
7830     f64 timeout;
7831     u32 sw_if_index;
7832     int sw_if_index_set;
7833     u32 ip4_table_index = ~0;
7834     u32 ip6_table_index = ~0;
7835     u32 other_table_index = ~0;
7836
7837     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7838         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7839             sw_if_index_set = 1;
7840         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7841             sw_if_index_set = 1;
7842         else if (unformat (i, "ip4-table %d", &ip4_table_index))
7843             ;
7844         else if (unformat (i, "ip6-table %d", &ip6_table_index))
7845             ;
7846         else if (unformat (i, "other-table %d", &other_table_index))
7847             ;
7848         else {
7849             clib_warning ("parse error '%U'", format_unformat_error, i);
7850             return -99;
7851         }
7852     }
7853
7854     if (sw_if_index_set == 0) {
7855         errmsg ("missing interface name or sw_if_index\n");
7856         return -99;
7857     }
7858
7859
7860     M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7861
7862     mp->sw_if_index = ntohl(sw_if_index);
7863     mp->ip4_table_index = ntohl(ip4_table_index);
7864     mp->ip6_table_index = ntohl(ip6_table_index);
7865     mp->other_table_index = ntohl(other_table_index);
7866
7867
7868     S; W;
7869     /* NOTREACHED */
7870     return 0;
7871 }
7872
7873 static int api_ipfix_enable (vat_main_t * vam)
7874 {
7875     unformat_input_t * i = vam->input;
7876     vl_api_ipfix_enable_t *mp;
7877     ip4_address_t collector_address;
7878     u8 collector_address_set = 0;
7879     u32 collector_port = ~0;
7880     ip4_address_t src_address;
7881     u8 src_address_set = 0;
7882     u32 vrf_id = ~0;
7883     u32 path_mtu = ~0;
7884     u32 template_interval = ~0;
7885     f64 timeout;
7886
7887     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7888         if (unformat (i, "collector_address %U", unformat_ip4_address,
7889             &collector_address))
7890             collector_address_set = 1;
7891         else if (unformat (i, "collector_port %d", &collector_port))
7892             ;
7893         else if (unformat (i, "src_address %U", unformat_ip4_address,
7894                  &src_address))
7895             src_address_set = 1;
7896         else if (unformat (i, "vrf_id %d", &vrf_id))
7897             ;
7898         else if (unformat (i, "path_mtu %d", &path_mtu))
7899             ;
7900         else if (unformat (i, "template_interval %d", &template_interval))
7901             ;
7902         else
7903             break;
7904     }
7905
7906     if (collector_address_set == 0) {
7907         errmsg ("collector_address required\n");
7908         return -99;
7909     }
7910
7911     if (src_address_set == 0) {
7912         errmsg ("src_address required\n");
7913         return -99;
7914     }
7915
7916     M (IPFIX_ENABLE, ipfix_enable);
7917
7918     memcpy(mp->collector_address, collector_address.data,
7919            sizeof(collector_address.data));
7920     mp->collector_port = htons((u16)collector_port);
7921     memcpy(mp->src_address, src_address.data,
7922            sizeof(src_address.data));
7923     mp->vrf_id = htonl(vrf_id);
7924     mp->path_mtu = htonl(path_mtu);
7925     mp->template_interval = htonl(template_interval);
7926
7927     S; W;
7928     /* NOTREACHED */
7929 }
7930
7931 static int api_get_node_index (vat_main_t * vam)
7932 {
7933     unformat_input_t * i = vam->input;
7934     vl_api_get_node_index_t * mp;
7935     f64 timeout;
7936     u8 * name = 0;
7937
7938     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7939         if (unformat (i, "node %s", &name))
7940             ;
7941         else
7942             break;
7943     }
7944     if (name == 0) {
7945         errmsg ("node name required\n");
7946         return -99;
7947     }
7948     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7949         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7950         return -99;
7951     }
7952
7953     M(GET_NODE_INDEX, get_node_index);
7954     clib_memcpy (mp->node_name, name, vec_len(name));
7955     vec_free(name);
7956
7957     S; W;
7958     /* NOTREACHED */
7959     return 0;
7960 }
7961
7962 static int api_get_next_index (vat_main_t * vam)
7963 {
7964     unformat_input_t * i = vam->input;
7965     vl_api_get_next_index_t * mp;
7966     f64 timeout;
7967     u8 * node_name = 0, * next_node_name = 0;
7968
7969     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7970         if (unformat (i, "node-name %s", &node_name))
7971             ;
7972         else if (unformat (i, "next-node-name %s", &next_node_name))
7973             break;
7974     }
7975
7976     if (node_name == 0) {
7977         errmsg ("node name required\n");
7978         return -99;
7979     }
7980     if (vec_len (node_name) >= ARRAY_LEN(mp->node_name)) {
7981         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7982         return -99;
7983     }
7984
7985     if (next_node_name == 0) {
7986         errmsg ("next node name required\n");
7987         return -99;
7988     }
7989     if (vec_len (next_node_name) >= ARRAY_LEN(mp->next_name)) {
7990         errmsg ("next node name too long, max %d\n", ARRAY_LEN(mp->next_name));
7991         return -99;
7992     }
7993
7994     M(GET_NEXT_INDEX, get_next_index);
7995     clib_memcpy (mp->node_name, node_name, vec_len(node_name));
7996     clib_memcpy (mp->next_name, next_node_name, vec_len(next_node_name));
7997     vec_free(node_name);
7998     vec_free(next_node_name);
7999
8000     S; W;
8001     /* NOTREACHED */
8002     return 0;
8003 }
8004
8005 static int api_add_node_next (vat_main_t * vam)
8006 {
8007     unformat_input_t * i = vam->input;
8008     vl_api_add_node_next_t * mp;
8009     f64 timeout;
8010     u8 * name = 0;
8011     u8 * next = 0;
8012
8013     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8014         if (unformat (i, "node %s", &name))
8015             ;
8016         else if (unformat (i, "next %s", &next))
8017             ;
8018         else
8019             break;
8020     }
8021     if (name == 0) {
8022         errmsg ("node name required\n");
8023         return -99;
8024     }
8025     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
8026         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
8027         return -99;
8028     }
8029     if (next == 0) {
8030         errmsg ("next node required\n");
8031         return -99;
8032     }
8033     if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
8034         errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
8035         return -99;
8036     }
8037
8038     M(ADD_NODE_NEXT, add_node_next);
8039     clib_memcpy (mp->node_name, name, vec_len(name));
8040     clib_memcpy (mp->next_name, next, vec_len(next));
8041     vec_free(name);
8042     vec_free(next);
8043
8044     S; W;
8045     /* NOTREACHED */
8046     return 0;
8047 }
8048
8049 static int api_l2tpv3_create_tunnel (vat_main_t * vam)
8050 {
8051     unformat_input_t * i = vam->input;
8052     ip6_address_t client_address, our_address;
8053     int client_address_set = 0;
8054     int our_address_set = 0;
8055     u32 local_session_id = 0;
8056     u32 remote_session_id = 0;
8057     u64 local_cookie = 0;
8058     u64 remote_cookie = 0;
8059     u8 l2_sublayer_present = 0;
8060     vl_api_l2tpv3_create_tunnel_t * mp;
8061     f64 timeout;
8062
8063     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8064         if (unformat (i, "client_address %U", unformat_ip6_address,
8065                       &client_address))
8066             client_address_set = 1;
8067         else if (unformat (i, "our_address %U", unformat_ip6_address,
8068                            &our_address))
8069             our_address_set = 1;
8070         else if (unformat (i, "local_session_id %d", &local_session_id))
8071             ;
8072         else if (unformat (i, "remote_session_id %d", &remote_session_id))
8073             ;
8074         else if (unformat (i, "local_cookie %lld", &local_cookie))
8075             ;
8076         else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8077             ;
8078         else if (unformat (i, "l2-sublayer-present"))
8079             l2_sublayer_present = 1;
8080         else
8081             break;
8082     }
8083
8084     if (client_address_set == 0) {
8085         errmsg ("client_address required\n");
8086         return -99;
8087     }
8088
8089     if (our_address_set == 0) {
8090         errmsg ("our_address required\n");
8091         return -99;
8092     }
8093
8094     M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8095
8096     clib_memcpy (mp->client_address, client_address.as_u8,
8097             sizeof (mp->client_address));
8098
8099     clib_memcpy (mp->our_address, our_address.as_u8,
8100             sizeof (mp->our_address));
8101
8102     mp->local_session_id = ntohl (local_session_id);
8103     mp->remote_session_id = ntohl (remote_session_id);
8104     mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8105     mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8106     mp->l2_sublayer_present = l2_sublayer_present;
8107     mp->is_ipv6 = 1;
8108
8109     S; W;
8110     /* NOTREACHED */
8111     return 0;
8112 }
8113
8114 static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8115 {
8116     unformat_input_t * i = vam->input;
8117     u32 sw_if_index;
8118     u8  sw_if_index_set = 0;
8119     u64 new_local_cookie = 0;
8120     u64 new_remote_cookie = 0;
8121     vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8122     f64 timeout;
8123
8124     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8125         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8126             sw_if_index_set = 1;
8127         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8128             sw_if_index_set = 1;
8129         else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8130             ;
8131         else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8132             ;
8133         else
8134             break;
8135     }
8136
8137     if (sw_if_index_set == 0) {
8138         errmsg ("missing interface name or sw_if_index\n");
8139         return -99;
8140     }
8141
8142     M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8143
8144     mp->sw_if_index = ntohl(sw_if_index);
8145     mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8146     mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8147
8148     S; W;
8149     /* NOTREACHED */
8150     return 0;
8151 }
8152
8153 static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8154 {
8155     unformat_input_t * i = vam->input;
8156     vl_api_l2tpv3_interface_enable_disable_t *mp;
8157     f64 timeout;
8158     u32 sw_if_index;
8159     u8  sw_if_index_set = 0;
8160     u8  enable_disable = 1;
8161
8162     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8163         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8164             sw_if_index_set = 1;
8165         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8166             sw_if_index_set = 1;
8167         else if (unformat (i, "enable"))
8168             enable_disable = 1;
8169         else if (unformat (i, "disable"))
8170             enable_disable = 0;
8171         else
8172             break;
8173     }
8174
8175     if (sw_if_index_set == 0) {
8176         errmsg ("missing interface name or sw_if_index\n");
8177         return -99;
8178     }
8179
8180     M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8181
8182     mp->sw_if_index = ntohl(sw_if_index);
8183     mp->enable_disable = enable_disable;
8184
8185     S; W;
8186     /* NOTREACHED */
8187     return 0;
8188 }
8189
8190 static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
8191 {
8192     unformat_input_t * i = vam->input;
8193     vl_api_l2tpv3_set_lookup_key_t * mp;
8194     f64 timeout;
8195     u8 key = ~0;
8196
8197     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8198         if (unformat (i, "lookup_v6_src"))
8199             key = L2T_LOOKUP_SRC_ADDRESS;
8200         else if (unformat (i, "lookup_v6_dst"))
8201             key = L2T_LOOKUP_DST_ADDRESS;
8202         else if (unformat (i, "lookup_session_id"))
8203             key = L2T_LOOKUP_SESSION_ID;
8204         else
8205             break;
8206     }
8207
8208     if (key == (u8) ~0) {
8209         errmsg ("l2tp session lookup key unset\n");
8210         return -99;
8211     }
8212
8213     M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8214
8215     mp->key = key;
8216
8217     S; W;
8218     /* NOTREACHED */
8219     return 0;
8220 }
8221
8222 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8223 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8224 {
8225     vat_main_t * vam = &vat_main;
8226
8227     fformat(vam->ofp,  "* %U (our) %U (client) (sw_if_index %d)\n",
8228               format_ip6_address, mp->our_address,
8229               format_ip6_address, mp->client_address,
8230               clib_net_to_host_u32(mp->sw_if_index));
8231
8232     fformat (vam->ofp, "   local cookies %016llx %016llx remote cookie %016llx\n",
8233               clib_net_to_host_u64 (mp->local_cookie[0]),
8234               clib_net_to_host_u64 (mp->local_cookie[1]),
8235               clib_net_to_host_u64 (mp->remote_cookie));
8236
8237     fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
8238               clib_net_to_host_u32 (mp->local_session_id),
8239               clib_net_to_host_u32 (mp->remote_session_id));
8240
8241     fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
8242               mp->l2_sublayer_present ? "preset" : "absent");
8243
8244 }
8245
8246 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8247 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8248 {
8249     vat_main_t * vam = &vat_main;
8250     vat_json_node_t *node = NULL;
8251     struct in6_addr addr;
8252
8253     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8254         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8255         vat_json_init_array(&vam->json_tree);
8256     }
8257     node = vat_json_array_add(&vam->json_tree);
8258
8259     vat_json_init_object(node);
8260
8261     clib_memcpy(&addr, mp->our_address, sizeof(addr));
8262     vat_json_object_add_ip6(node, "our_address", addr);
8263     clib_memcpy(&addr, mp->client_address, sizeof(addr));
8264     vat_json_object_add_ip6(node, "client_address", addr);
8265
8266     vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
8267     vat_json_init_array(lc);
8268     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
8269     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
8270     vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
8271
8272     printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
8273     vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
8274     vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
8275     vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
8276             (u8*)"present" : (u8*)"absent");
8277 }
8278
8279 static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
8280 {
8281     vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
8282     f64 timeout;
8283
8284     /* Get list of l2tpv3-tunnel interfaces */
8285     M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
8286     S;
8287
8288     /* Use a control ping for synchronization */
8289     {
8290         vl_api_control_ping_t * mp;
8291         M(CONTROL_PING, control_ping);
8292         S;
8293     }
8294     W;
8295 }
8296
8297
8298 static void vl_api_sw_interface_tap_details_t_handler
8299 (vl_api_sw_interface_tap_details_t * mp)
8300 {
8301     vat_main_t * vam = &vat_main;
8302
8303     fformat(vam->ofp,  "%-16s %d\n",
8304               mp->dev_name,
8305               clib_net_to_host_u32(mp->sw_if_index));
8306 }
8307
8308 static void vl_api_sw_interface_tap_details_t_handler_json
8309 (vl_api_sw_interface_tap_details_t * mp)
8310 {
8311     vat_main_t * vam = &vat_main;
8312     vat_json_node_t *node = NULL;
8313
8314     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8315         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8316         vat_json_init_array(&vam->json_tree);
8317     }
8318     node = vat_json_array_add(&vam->json_tree);
8319
8320     vat_json_init_object(node);
8321     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8322     vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
8323 }
8324
8325 static int api_sw_interface_tap_dump (vat_main_t * vam)
8326 {
8327     vl_api_sw_interface_tap_dump_t *mp;
8328     f64 timeout;
8329
8330     fformat(vam->ofp,  "\n%-16s %s\n", "dev_name", "sw_if_index");
8331     /* Get list of tap interfaces */
8332     M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
8333     S;
8334
8335     /* Use a control ping for synchronization */
8336     {
8337         vl_api_control_ping_t * mp;
8338         M(CONTROL_PING, control_ping);
8339         S;
8340     }
8341     W;
8342 }
8343
8344 static uword unformat_vxlan_decap_next
8345 (unformat_input_t * input, va_list * args)
8346 {
8347   u32 * result = va_arg (*args, u32 *);
8348   u32 tmp;
8349
8350   if (unformat (input, "drop"))
8351     *result = VXLAN_INPUT_NEXT_DROP;
8352   else if (unformat (input, "ip4"))
8353     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
8354   else if (unformat (input, "ip6"))
8355     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
8356   else if (unformat (input, "l2"))
8357     *result = VXLAN_INPUT_NEXT_L2_INPUT;
8358   else if (unformat (input, "%d", &tmp))
8359     *result = tmp;
8360   else
8361     return 0;
8362   return 1;
8363 }
8364
8365 static int api_vxlan_add_del_tunnel (vat_main_t * vam)
8366 {
8367     unformat_input_t * line_input = vam->input;
8368     vl_api_vxlan_add_del_tunnel_t *mp;
8369     f64 timeout;
8370     ip4_address_t src4, dst4;
8371     ip6_address_t src6, dst6;
8372     u8 is_add = 1;
8373     u8 ipv4_set = 0, ipv6_set = 0;
8374     u8 src_set = 0;
8375     u8 dst_set = 0;
8376     u32 encap_vrf_id = 0;
8377     u32 decap_next_index = ~0;
8378     u32 vni = 0;
8379
8380     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8381         if (unformat (line_input, "del"))
8382             is_add = 0;
8383         else if (unformat (line_input, "src %U",
8384                            unformat_ip4_address, &src4))
8385           {
8386             ipv4_set = 1;
8387             src_set = 1;
8388           }
8389         else if (unformat (line_input, "dst %U",
8390                            unformat_ip4_address, &dst4))
8391           {
8392             ipv4_set = 1;
8393             dst_set = 1;
8394           }
8395         else if (unformat (line_input, "src %U",
8396                            unformat_ip6_address, &src6))
8397           {
8398             ipv6_set = 1;
8399             src_set = 1;
8400           }
8401         else if (unformat (line_input, "dst %U",
8402                            unformat_ip6_address, &dst6))
8403           {
8404             ipv6_set = 1;
8405             dst_set = 1;
8406           }
8407         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8408             ;
8409         else if (unformat (line_input, "decap-next %U",
8410                            unformat_vxlan_decap_next, &decap_next_index))
8411             ;
8412         else if (unformat (line_input, "vni %d", &vni))
8413             ;
8414         else {
8415             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8416             return -99;
8417         }
8418     }
8419
8420     if (src_set == 0) {
8421         errmsg ("tunnel src address not specified\n");
8422         return -99;
8423     }
8424     if (dst_set == 0) {
8425         errmsg ("tunnel dst address not specified\n");
8426         return -99;
8427     }
8428
8429     if (ipv4_set && ipv6_set) {
8430         errmsg ("both IPv4 and IPv6 addresses specified");
8431         return -99;
8432     }
8433
8434     if ((vni == 0) || (vni>>24)) {
8435         errmsg ("vni not specified or out of range\n");
8436         return -99;
8437     }
8438
8439     M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
8440
8441     if (ipv6_set) {
8442         clib_memcpy(&mp->src_address, &src6, sizeof(src6));
8443         clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
8444     } else {
8445         clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8446         clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
8447     }
8448     mp->encap_vrf_id = ntohl(encap_vrf_id);
8449     mp->decap_next_index = ntohl(decap_next_index);
8450     mp->vni = ntohl(vni);
8451     mp->is_add = is_add;
8452     mp->is_ipv6 = ipv6_set;
8453
8454     S; W;
8455     /* NOTREACHED */
8456     return 0;
8457 }
8458
8459 static void vl_api_vxlan_tunnel_details_t_handler
8460 (vl_api_vxlan_tunnel_details_t * mp)
8461 {
8462     vat_main_t * vam = &vat_main;
8463
8464     fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
8465             ntohl(mp->sw_if_index),
8466             format_ip46_address, &(mp->src_address[0]),
8467             IP46_TYPE_ANY,
8468             format_ip46_address, &(mp->dst_address[0]),
8469             IP46_TYPE_ANY,
8470             ntohl(mp->encap_vrf_id),
8471             ntohl(mp->decap_next_index),
8472             ntohl(mp->vni));
8473 }
8474
8475 static void vl_api_vxlan_tunnel_details_t_handler_json
8476 (vl_api_vxlan_tunnel_details_t * mp)
8477 {
8478     vat_main_t * vam = &vat_main;
8479     vat_json_node_t *node = NULL;
8480     struct in_addr ip4;
8481     struct in6_addr ip6;
8482
8483     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8484         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8485         vat_json_init_array(&vam->json_tree);
8486     }
8487     node = vat_json_array_add(&vam->json_tree);
8488
8489     vat_json_init_object(node);
8490     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8491     if (mp->is_ipv6) {
8492         clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
8493         vat_json_object_add_ip6(node, "src_address", ip6);
8494         clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
8495         vat_json_object_add_ip6(node, "dst_address", ip6);
8496     } else {
8497         clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
8498         vat_json_object_add_ip4(node, "src_address", ip4);
8499         clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
8500         vat_json_object_add_ip4(node, "dst_address", ip4);
8501     }
8502     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8503     vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
8504     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
8505     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
8506 }
8507
8508 static int api_vxlan_tunnel_dump (vat_main_t * vam)
8509 {
8510     unformat_input_t * i = vam->input;
8511     vl_api_vxlan_tunnel_dump_t *mp;
8512     f64 timeout;
8513     u32 sw_if_index;
8514     u8 sw_if_index_set = 0;
8515
8516     /* Parse args required to build the message */
8517     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8518         if (unformat (i, "sw_if_index %d", &sw_if_index))
8519             sw_if_index_set = 1;
8520         else
8521             break;
8522     }
8523
8524     if (sw_if_index_set == 0) {
8525         sw_if_index = ~0;
8526     }
8527
8528     if (!vam->json_output) {
8529         fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
8530                 "sw_if_index", "src_address", "dst_address",
8531                 "encap_vrf_id", "decap_next_index", "vni");
8532     }
8533
8534     /* Get list of vxlan-tunnel interfaces */
8535     M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
8536
8537     mp->sw_if_index = htonl(sw_if_index);
8538
8539     S;
8540
8541     /* Use a control ping for synchronization */
8542     {
8543         vl_api_control_ping_t * mp;
8544         M(CONTROL_PING, control_ping);
8545         S;
8546     }
8547     W;
8548 }
8549
8550 static int api_gre_add_del_tunnel (vat_main_t * vam)
8551 {
8552     unformat_input_t * line_input = vam->input;
8553     vl_api_gre_add_del_tunnel_t *mp;
8554     f64 timeout;
8555     ip4_address_t src4, dst4;
8556     u8 is_add = 1;
8557     u8 src_set = 0;
8558     u8 dst_set = 0;
8559     u32 outer_fib_id = 0;
8560
8561     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8562         if (unformat (line_input, "del"))
8563             is_add = 0;
8564         else if (unformat (line_input, "src %U",
8565                            unformat_ip4_address, &src4))
8566             src_set = 1;
8567         else if (unformat (line_input, "dst %U",
8568                            unformat_ip4_address, &dst4))
8569             dst_set = 1;
8570         else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
8571             ;
8572         else {
8573             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8574             return -99;
8575         }
8576     }
8577
8578     if (src_set == 0) {
8579         errmsg ("tunnel src address not specified\n");
8580         return -99;
8581     }
8582     if (dst_set == 0) {
8583         errmsg ("tunnel dst address not specified\n");
8584         return -99;
8585     }
8586
8587
8588     M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
8589
8590     clib_memcpy(&mp->src_address, &src4, sizeof(src4));
8591     clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
8592     mp->outer_fib_id = ntohl(outer_fib_id);
8593     mp->is_add = is_add;
8594
8595     S; W;
8596     /* NOTREACHED */
8597     return 0;
8598 }
8599
8600 static void vl_api_gre_tunnel_details_t_handler
8601 (vl_api_gre_tunnel_details_t * mp)
8602 {
8603     vat_main_t * vam = &vat_main;
8604
8605     fformat(vam->ofp, "%11d%15U%15U%14d\n",
8606             ntohl(mp->sw_if_index),
8607             format_ip4_address, &mp->src_address,
8608             format_ip4_address, &mp->dst_address,
8609             ntohl(mp->outer_fib_id));
8610 }
8611
8612 static void vl_api_gre_tunnel_details_t_handler_json
8613 (vl_api_gre_tunnel_details_t * mp)
8614 {
8615     vat_main_t * vam = &vat_main;
8616     vat_json_node_t *node = NULL;
8617     struct in_addr ip4;
8618
8619     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8620         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8621         vat_json_init_array(&vam->json_tree);
8622     }
8623     node = vat_json_array_add(&vam->json_tree);
8624
8625     vat_json_init_object(node);
8626     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8627     clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
8628     vat_json_object_add_ip4(node, "src_address", ip4);
8629     clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
8630     vat_json_object_add_ip4(node, "dst_address", ip4);
8631     vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_fib_id));
8632 }
8633
8634 static int api_gre_tunnel_dump (vat_main_t * vam)
8635 {
8636     unformat_input_t * i = vam->input;
8637     vl_api_gre_tunnel_dump_t *mp;
8638     f64 timeout;
8639     u32 sw_if_index;
8640     u8 sw_if_index_set = 0;
8641
8642     /* Parse args required to build the message */
8643     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8644         if (unformat (i, "sw_if_index %d", &sw_if_index))
8645             sw_if_index_set = 1;
8646         else
8647             break;
8648     }
8649
8650     if (sw_if_index_set == 0) {
8651         sw_if_index = ~0;
8652     }
8653
8654     if (!vam->json_output) {
8655         fformat(vam->ofp, "%11s%15s%15s%14s\n",
8656                 "sw_if_index", "src_address", "dst_address",
8657                 "outer_fib_id");
8658     }
8659
8660     /* Get list of gre-tunnel interfaces */
8661     M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
8662
8663     mp->sw_if_index = htonl(sw_if_index);
8664
8665     S;
8666
8667     /* Use a control ping for synchronization */
8668     {
8669         vl_api_control_ping_t * mp;
8670         M(CONTROL_PING, control_ping);
8671         S;
8672     }
8673     W;
8674 }
8675
8676 static int api_l2_fib_clear_table (vat_main_t * vam)
8677 {
8678 //  unformat_input_t * i = vam->input;
8679     vl_api_l2_fib_clear_table_t *mp;
8680     f64 timeout;
8681
8682     M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
8683
8684     S; W;
8685     /* NOTREACHED */
8686     return 0;
8687 }
8688
8689 static int api_l2_interface_efp_filter (vat_main_t * vam)
8690 {
8691     unformat_input_t * i = vam->input;
8692     vl_api_l2_interface_efp_filter_t *mp;
8693     f64 timeout;
8694     u32 sw_if_index;
8695     u8 enable = 1;
8696     u8 sw_if_index_set = 0;
8697
8698     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8699         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8700             sw_if_index_set = 1;
8701         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8702             sw_if_index_set = 1;
8703         else if (unformat (i, "enable"))
8704             enable = 1;
8705         else if (unformat (i, "disable"))
8706             enable = 0;
8707         else {
8708             clib_warning ("parse error '%U'", format_unformat_error, i);
8709             return -99;
8710         }
8711     }
8712
8713     if (sw_if_index_set == 0) {
8714         errmsg ("missing sw_if_index\n");
8715         return -99;
8716     }
8717
8718     M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
8719
8720     mp->sw_if_index = ntohl(sw_if_index);
8721     mp->enable_disable = enable;
8722
8723     S; W;
8724     /* NOTREACHED */
8725     return 0;
8726 }
8727
8728 #define foreach_vtr_op                          \
8729 _("disable",  L2_VTR_DISABLED)                  \
8730 _("push-1",  L2_VTR_PUSH_1)                     \
8731 _("push-2",  L2_VTR_PUSH_2)                     \
8732 _("pop-1",  L2_VTR_POP_1)                       \
8733 _("pop-2",  L2_VTR_POP_2)                       \
8734 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
8735 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
8736 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
8737 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
8738
8739 static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
8740 {
8741     unformat_input_t * i = vam->input;
8742     vl_api_l2_interface_vlan_tag_rewrite_t *mp;
8743     f64 timeout;
8744     u32 sw_if_index;
8745     u8 sw_if_index_set = 0;
8746     u8 vtr_op_set = 0;
8747     u32 vtr_op = 0;
8748     u32 push_dot1q = 1;
8749     u32 tag1 = ~0;
8750     u32 tag2 = ~0;
8751
8752     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8753         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8754             sw_if_index_set = 1;
8755         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8756             sw_if_index_set = 1;
8757         else if (unformat (i, "vtr_op %d", &vtr_op))
8758             vtr_op_set = 1;
8759 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
8760         foreach_vtr_op
8761 #undef _
8762
8763         else if (unformat (i, "push_dot1q %d", &push_dot1q))
8764             ;
8765         else if (unformat (i, "tag1 %d", &tag1))
8766             ;
8767         else if (unformat (i, "tag2 %d", &tag2))
8768             ;
8769         else {
8770             clib_warning ("parse error '%U'", format_unformat_error, i);
8771             return -99;
8772         }
8773     }
8774
8775     if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
8776         errmsg ("missing vtr operation or sw_if_index\n");
8777         return -99;
8778     }
8779
8780     M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
8781
8782     mp->sw_if_index = ntohl(sw_if_index);
8783     mp->vtr_op = ntohl(vtr_op);
8784     mp->push_dot1q = ntohl(push_dot1q);
8785     mp->tag1 = ntohl(tag1);
8786     mp->tag2 = ntohl(tag2);
8787
8788     S; W;
8789     /* NOTREACHED */
8790     return 0;
8791 }
8792
8793 static int api_create_vhost_user_if (vat_main_t * vam)
8794 {
8795     unformat_input_t * i = vam->input;
8796     vl_api_create_vhost_user_if_t *mp;
8797     f64 timeout;
8798     u8 * file_name;
8799     u8 is_server = 0;
8800     u8 file_name_set = 0;
8801     u32 custom_dev_instance = ~0;
8802     u8 hwaddr[6];
8803     u8 use_custom_mac = 0;
8804
8805     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8806       if (unformat (i, "socket %s", &file_name)) {
8807         file_name_set = 1;
8808       }
8809       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8810         ;
8811       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
8812         use_custom_mac = 1;
8813       else if (unformat (i, "server"))
8814         is_server = 1;
8815       else
8816         break;
8817     }
8818
8819     if (file_name_set == 0) {
8820       errmsg ("missing socket file name\n");
8821       return -99;
8822     }
8823
8824     if (vec_len (file_name) > 255) {
8825       errmsg ("socket file name too long\n");
8826       return -99;
8827     }
8828     vec_add1 (file_name, 0);
8829
8830     M(CREATE_VHOST_USER_IF, create_vhost_user_if);
8831
8832     mp->is_server = is_server;
8833     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
8834     vec_free(file_name);
8835     if (custom_dev_instance != ~0) {
8836         mp->renumber = 1;
8837         mp->custom_dev_instance = ntohl(custom_dev_instance);
8838     }
8839     mp->use_custom_mac = use_custom_mac;
8840     clib_memcpy(mp->mac_address, hwaddr, 6);
8841
8842     S; W;
8843     /* NOTREACHED */
8844     return 0;
8845 }
8846
8847 static int api_modify_vhost_user_if (vat_main_t * vam)
8848 {
8849     unformat_input_t * i = vam->input;
8850     vl_api_modify_vhost_user_if_t *mp;
8851     f64 timeout;
8852     u8 * file_name;
8853     u8 is_server = 0;
8854     u8 file_name_set = 0;
8855     u32 custom_dev_instance = ~0;
8856     u8 sw_if_index_set = 0;
8857     u32 sw_if_index = (u32)~0;
8858
8859     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8860       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8861           sw_if_index_set = 1;
8862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8863           sw_if_index_set = 1;
8864       else if (unformat (i, "socket %s", &file_name)) {
8865         file_name_set = 1;
8866       }
8867       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8868         ;
8869       else if (unformat (i, "server"))
8870         is_server = 1;
8871       else
8872         break;
8873     }
8874
8875     if (sw_if_index_set == 0) {
8876        errmsg ("missing sw_if_index or interface name\n");
8877        return -99;
8878     }
8879
8880     if (file_name_set == 0) {
8881       errmsg ("missing socket file name\n");
8882       return -99;
8883     }
8884
8885     if (vec_len (file_name) > 255) {
8886       errmsg ("socket file name too long\n");
8887       return -99;
8888     }
8889     vec_add1 (file_name, 0);
8890
8891     M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
8892
8893     mp->sw_if_index = ntohl(sw_if_index);
8894     mp->is_server = is_server;
8895     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
8896     vec_free(file_name);
8897     if (custom_dev_instance != ~0) {
8898         mp->renumber = 1;
8899         mp->custom_dev_instance = ntohl(custom_dev_instance);
8900     }
8901
8902     S; W;
8903     /* NOTREACHED */
8904     return 0;
8905 }
8906
8907 static int api_delete_vhost_user_if (vat_main_t * vam)
8908 {
8909     unformat_input_t * i = vam->input;
8910     vl_api_delete_vhost_user_if_t *mp;
8911     f64 timeout;
8912     u32 sw_if_index = ~0;
8913     u8 sw_if_index_set = 0;
8914
8915     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8916       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8917           sw_if_index_set = 1;
8918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8919           sw_if_index_set = 1;
8920       else
8921         break;
8922     }
8923
8924     if (sw_if_index_set == 0) {
8925        errmsg ("missing sw_if_index or interface name\n");
8926        return -99;
8927     }
8928
8929
8930     M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8931
8932     mp->sw_if_index = ntohl(sw_if_index);
8933
8934     S; W;
8935     /* NOTREACHED */
8936     return 0;
8937 }
8938
8939 static void vl_api_sw_interface_vhost_user_details_t_handler
8940 (vl_api_sw_interface_vhost_user_details_t * mp)
8941 {
8942     vat_main_t * vam = &vat_main;
8943
8944     fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8945             (char *)mp->interface_name,
8946             ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8947             clib_net_to_host_u64(mp->features), mp->is_server,
8948             ntohl(mp->num_regions), (char *)mp->sock_filename);
8949     fformat(vam->ofp, "    Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8950 }
8951
8952 static void vl_api_sw_interface_vhost_user_details_t_handler_json
8953 (vl_api_sw_interface_vhost_user_details_t * mp)
8954 {
8955     vat_main_t * vam = &vat_main;
8956     vat_json_node_t *node = NULL;
8957
8958     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8959         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8960         vat_json_init_array(&vam->json_tree);
8961     }
8962     node = vat_json_array_add(&vam->json_tree);
8963
8964     vat_json_init_object(node);
8965     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8966     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8967     vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8968     vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8969     vat_json_object_add_uint(node, "is_server", mp->is_server);
8970     vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8971     vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8972     vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8973 }
8974
8975 static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8976 {
8977     vl_api_sw_interface_vhost_user_dump_t *mp;
8978     f64 timeout;
8979     fformat(vam->ofp, "Interface name           idx hdr_sz features server regions filename\n");
8980
8981     /* Get list of vhost-user interfaces */
8982     M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8983     S;
8984
8985     /* Use a control ping for synchronization */
8986     {
8987         vl_api_control_ping_t * mp;
8988         M(CONTROL_PING, control_ping);
8989         S;
8990     }
8991     W;
8992 }
8993
8994 static int api_show_version (vat_main_t * vam)
8995 {
8996     vl_api_show_version_t *mp;
8997     f64 timeout;
8998
8999     M(SHOW_VERSION, show_version);
9000
9001     S; W;
9002     /* NOTREACHED */
9003     return 0;
9004 }
9005
9006
9007 static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9008 {
9009     unformat_input_t * line_input = vam->input;
9010     vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9011     f64 timeout;
9012     ip4_address_t local4, remote4;
9013     ip6_address_t local6, remote6;
9014     u8 is_add = 1;
9015     u8 ipv4_set = 0, ipv6_set = 0;
9016     u8 local_set = 0;
9017     u8 remote_set = 0;
9018     u32 encap_vrf_id = 0;
9019     u32 decap_vrf_id = 0;
9020     u8 protocol = ~0;
9021     u32 vni;
9022     u8 vni_set = 0;
9023
9024     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9025         if (unformat (line_input, "del"))
9026             is_add = 0;
9027         else if (unformat (line_input, "local %U",
9028                            unformat_ip4_address, &local4))
9029         {
9030             local_set = 1;
9031             ipv4_set = 1;
9032         }
9033         else if (unformat (line_input, "remote %U",
9034                            unformat_ip4_address, &remote4))
9035         {
9036             remote_set = 1;
9037             ipv4_set = 1;
9038         }
9039         else if (unformat (line_input, "local %U",
9040                            unformat_ip6_address, &local6))
9041         {
9042             local_set = 1;
9043             ipv6_set = 1;
9044         }
9045         else if (unformat (line_input, "remote %U",
9046                            unformat_ip6_address, &remote6))
9047         {
9048             remote_set = 1;
9049             ipv6_set = 1;
9050         }
9051         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9052             ;
9053         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9054             ;
9055         else if (unformat (line_input, "vni %d", &vni))
9056             vni_set = 1;
9057         else if (unformat(line_input, "next-ip4"))
9058             protocol = 1;
9059         else if (unformat(line_input, "next-ip6"))
9060             protocol = 2;
9061         else if (unformat(line_input, "next-ethernet"))
9062             protocol = 3;
9063         else if (unformat(line_input, "next-nsh"))
9064             protocol = 4;
9065         else {
9066             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9067             return -99;
9068         }
9069     }
9070
9071     if (local_set == 0) {
9072         errmsg ("tunnel local address not specified\n");
9073         return -99;
9074     }
9075     if (remote_set == 0) {
9076         errmsg ("tunnel remote address not specified\n");
9077         return -99;
9078     }
9079     if (ipv4_set && ipv6_set) {
9080         errmsg ("both IPv4 and IPv6 addresses specified");
9081         return -99;
9082     }
9083
9084     if (vni_set == 0) {
9085         errmsg ("vni not specified\n");
9086         return -99;
9087     }
9088
9089     M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9090
9091
9092     if (ipv6_set) {
9093         clib_memcpy(&mp->local, &local6, sizeof(local6));
9094         clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
9095     } else {
9096         clib_memcpy(&mp->local, &local4, sizeof(local4));
9097         clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
9098     }
9099
9100     mp->encap_vrf_id = ntohl(encap_vrf_id);
9101     mp->decap_vrf_id = ntohl(decap_vrf_id);
9102     mp->protocol = ntohl(protocol);
9103     mp->vni = ntohl(vni);
9104     mp->is_add = is_add;
9105     mp->is_ipv6 = ipv6_set;
9106
9107     S; W;
9108     /* NOTREACHED */
9109     return 0;
9110 }
9111
9112 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9113 (vl_api_vxlan_gpe_tunnel_details_t * mp)
9114 {
9115     vat_main_t * vam = &vat_main;
9116
9117     fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9118             ntohl(mp->sw_if_index),
9119             format_ip46_address, &(mp->local[0]),
9120             format_ip46_address, &(mp->remote[0]),
9121                         ntohl(mp->vni),
9122             ntohl(mp->protocol),
9123             ntohl(mp->encap_vrf_id),
9124             ntohl(mp->decap_vrf_id));
9125 }
9126
9127 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9128 (vl_api_vxlan_gpe_tunnel_details_t * mp)
9129 {
9130     vat_main_t * vam = &vat_main;
9131     vat_json_node_t *node = NULL;
9132     struct in_addr ip4;
9133     struct in6_addr ip6;
9134
9135     if (VAT_JSON_ARRAY != vam->json_tree.type) {
9136         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9137         vat_json_init_array(&vam->json_tree);
9138     }
9139     node = vat_json_array_add(&vam->json_tree);
9140
9141     vat_json_init_object(node);
9142     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9143     if (mp->is_ipv6) {
9144         clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
9145         vat_json_object_add_ip6(node, "local", ip6);
9146         clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
9147         vat_json_object_add_ip6(node, "remote", ip6);
9148     } else {
9149         clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
9150         vat_json_object_add_ip4(node, "local", ip4);
9151         clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
9152         vat_json_object_add_ip4(node, "remote", ip4);
9153     }
9154     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
9155     vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
9156     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
9157     vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
9158     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9159 }
9160
9161 static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9162 {
9163     unformat_input_t * i = vam->input;
9164     vl_api_vxlan_gpe_tunnel_dump_t *mp;
9165     f64 timeout;
9166     u32 sw_if_index;
9167     u8 sw_if_index_set = 0;
9168
9169     /* Parse args required to build the message */
9170     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9171         if (unformat (i, "sw_if_index %d", &sw_if_index))
9172             sw_if_index_set = 1;
9173         else
9174             break;
9175     }
9176
9177     if (sw_if_index_set == 0) {
9178         sw_if_index = ~0;
9179     }
9180
9181     if (!vam->json_output) {
9182         fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
9183                 "sw_if_index", "local", "remote", "vni",
9184                                 "protocol","encap_vrf_id", "decap_vrf_id");
9185     }
9186
9187     /* Get list of vxlan-tunnel interfaces */
9188     M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
9189
9190     mp->sw_if_index = htonl(sw_if_index);
9191
9192     S;
9193
9194     /* Use a control ping for synchronization */
9195     {
9196         vl_api_control_ping_t * mp;
9197         M(CONTROL_PING, control_ping);
9198         S;
9199     }
9200     W;
9201 }
9202
9203 u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
9204 {
9205   u8 * a = va_arg (*args, u8 *);
9206
9207   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
9208                  a[2], a[3], a[4], a[5], a[6], a[7]);
9209 }
9210
9211 static void vl_api_l2_fib_table_entry_t_handler
9212 (vl_api_l2_fib_table_entry_t * mp)
9213 {
9214     vat_main_t * vam = &vat_main;
9215
9216     fformat(vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
9217             "       %d       %d     %d\n",
9218             ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
9219             ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
9220             mp->bvi_mac);
9221 }
9222
9223 static void vl_api_l2_fib_table_entry_t_handler_json
9224 (vl_api_l2_fib_table_entry_t * mp)
9225 {
9226     vat_main_t * vam = &vat_main;
9227     vat_json_node_t *node = NULL;
9228
9229     if (VAT_JSON_ARRAY != vam->json_tree.type) {
9230         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
9231         vat_json_init_array(&vam->json_tree);
9232     }
9233     node = vat_json_array_add(&vam->json_tree);
9234
9235     vat_json_init_object(node);
9236     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
9237     vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
9238     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
9239     vat_json_object_add_uint(node, "static_mac", mp->static_mac);
9240     vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
9241     vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
9242 }
9243
9244 static int api_l2_fib_table_dump (vat_main_t * vam)
9245 {
9246     unformat_input_t * i = vam->input;
9247     vl_api_l2_fib_table_dump_t *mp;
9248     f64 timeout;
9249     u32 bd_id;
9250     u8 bd_id_set = 0;
9251
9252     /* Parse args required to build the message */
9253     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9254         if (unformat (i, "bd_id %d", &bd_id))
9255             bd_id_set = 1;
9256         else
9257             break;
9258     }
9259
9260     if (bd_id_set == 0) {
9261         errmsg ("missing bridge domain\n");
9262         return -99;
9263     }
9264
9265     fformat(vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
9266
9267     /* Get list of l2 fib entries */
9268     M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
9269
9270     mp->bd_id = ntohl(bd_id);
9271     S;
9272
9273     /* Use a control ping for synchronization */
9274     {
9275         vl_api_control_ping_t * mp;
9276         M(CONTROL_PING, control_ping);
9277         S;
9278     }
9279     W;
9280 }
9281
9282
9283 static int
9284 api_interface_name_renumber (vat_main_t * vam)
9285 {
9286     unformat_input_t * line_input = vam->input;
9287     vl_api_interface_name_renumber_t *mp;
9288     u32 sw_if_index = ~0;
9289     f64 timeout;
9290     u32 new_show_dev_instance = ~0;
9291
9292     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9293         if (unformat (line_input, "%U", unformat_sw_if_index, vam,
9294                       &sw_if_index))
9295             ;
9296         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9297             ;
9298         else if (unformat (line_input, "new_show_dev_instance %d",
9299                            &new_show_dev_instance))
9300             ;
9301         else
9302             break;
9303     }
9304
9305     if (sw_if_index == ~0) {
9306         errmsg ("missing interface name or sw_if_index\n");
9307         return -99;
9308     }
9309
9310     if (new_show_dev_instance == ~0) {
9311         errmsg ("missing new_show_dev_instance\n");
9312         return -99;
9313     }
9314
9315     M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
9316
9317     mp->sw_if_index = ntohl (sw_if_index);
9318     mp->new_show_dev_instance = ntohl (new_show_dev_instance);
9319
9320     S; W;
9321 }
9322
9323 static int
9324 api_want_ip4_arp_events (vat_main_t * vam)
9325 {
9326     unformat_input_t * line_input = vam->input;
9327     vl_api_want_ip4_arp_events_t * mp;
9328     f64 timeout;
9329     ip4_address_t address;
9330     int address_set = 0;
9331     u32 enable_disable = 1;
9332
9333     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9334         if (unformat (line_input, "address %U",
9335                       unformat_ip4_address, &address))
9336             address_set = 1;
9337         else if (unformat (line_input, "del"))
9338             enable_disable = 0;
9339         else
9340             break;
9341     }
9342
9343     if (address_set == 0) {
9344         errmsg ("missing addresses\n");
9345         return -99;
9346     }
9347
9348     M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
9349     mp->enable_disable = enable_disable;
9350     mp->pid = getpid();
9351     mp->address = address.as_u32;
9352
9353     S; W;
9354 }
9355
9356 static int api_input_acl_set_interface (vat_main_t * vam)
9357 {
9358     unformat_input_t * i = vam->input;
9359     vl_api_input_acl_set_interface_t *mp;
9360     f64 timeout;
9361     u32 sw_if_index;
9362     int sw_if_index_set;
9363     u32 ip4_table_index = ~0;
9364     u32 ip6_table_index = ~0;
9365     u32 l2_table_index = ~0;
9366     u8 is_add = 1;
9367
9368     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9369         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9370             sw_if_index_set = 1;
9371         else if (unformat (i, "sw_if_index %d", &sw_if_index))
9372             sw_if_index_set = 1;
9373         else if (unformat (i, "del"))
9374             is_add = 0;
9375         else if (unformat (i, "ip4-table %d", &ip4_table_index))
9376             ;
9377         else if (unformat (i, "ip6-table %d", &ip6_table_index))
9378             ;
9379         else if (unformat (i, "l2-table %d", &l2_table_index))
9380             ;
9381         else {
9382             clib_warning ("parse error '%U'", format_unformat_error, i);
9383             return -99;
9384         }
9385     }
9386
9387     if (sw_if_index_set == 0) {
9388         errmsg ("missing interface name or sw_if_index\n");
9389         return -99;
9390     }
9391
9392     M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
9393
9394     mp->sw_if_index = ntohl(sw_if_index);
9395     mp->ip4_table_index = ntohl(ip4_table_index);
9396     mp->ip6_table_index = ntohl(ip6_table_index);
9397     mp->l2_table_index = ntohl(l2_table_index);
9398     mp->is_add = is_add;
9399
9400     S; W;
9401     /* NOTREACHED */
9402     return 0;
9403 }
9404
9405 static int
9406 api_ip_address_dump (vat_main_t * vam)
9407 {
9408     unformat_input_t * i = vam->input;
9409     vl_api_ip_address_dump_t * mp;
9410     u32 sw_if_index = ~0;
9411     u8 sw_if_index_set = 0;
9412     u8 ipv4_set = 0;
9413     u8 ipv6_set = 0;
9414     f64 timeout;
9415
9416     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9417         if (unformat (i, "sw_if_index %d", &sw_if_index))
9418             sw_if_index_set = 1;
9419         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9420             sw_if_index_set = 1;
9421         else if (unformat (i, "ipv4"))
9422             ipv4_set = 1;
9423         else if (unformat (i, "ipv6"))
9424             ipv6_set = 1;
9425         else
9426             break;
9427     }
9428
9429     if (ipv4_set && ipv6_set) {
9430         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9431         return -99;
9432     }
9433
9434     if ((!ipv4_set) && (!ipv6_set)) {
9435         errmsg ("no ipv4 nor ipv6 flag set\n");
9436         return -99;
9437     }
9438
9439     if (sw_if_index_set == 0) {
9440         errmsg ("missing interface name or sw_if_index\n");
9441         return -99;
9442     }
9443
9444     vam->current_sw_if_index = sw_if_index;
9445     vam->is_ipv6 = ipv6_set;
9446
9447     M(IP_ADDRESS_DUMP, ip_address_dump);
9448     mp->sw_if_index = ntohl(sw_if_index);
9449     mp->is_ipv6 = ipv6_set;
9450     S;
9451
9452     /* Use a control ping for synchronization */
9453     {
9454         vl_api_control_ping_t * mp;
9455         M(CONTROL_PING, control_ping);
9456         S;
9457     }
9458     W;
9459 }
9460
9461 static int
9462 api_ip_dump (vat_main_t * vam)
9463 {
9464     vl_api_ip_dump_t * mp;
9465     unformat_input_t * in = vam->input;
9466     int ipv4_set = 0;
9467     int ipv6_set = 0;
9468     int is_ipv6;
9469     f64 timeout;
9470     int i;
9471
9472     while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
9473         if (unformat (in, "ipv4"))
9474             ipv4_set = 1;
9475         else if (unformat (in, "ipv6"))
9476             ipv6_set = 1;
9477         else
9478             break;
9479     }
9480
9481     if (ipv4_set && ipv6_set) {
9482         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
9483         return -99;
9484     }
9485
9486     if ((!ipv4_set) && (!ipv6_set)) {
9487         errmsg ("no ipv4 nor ipv6 flag set\n");
9488         return -99;
9489     }
9490
9491     is_ipv6 = ipv6_set;
9492     vam->is_ipv6 = is_ipv6;
9493
9494     /* free old data */
9495     for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
9496         vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
9497     }
9498     vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
9499
9500     M(IP_DUMP, ip_dump);
9501     mp->is_ipv6 = ipv6_set;
9502     S;
9503
9504     /* Use a control ping for synchronization */
9505     {
9506         vl_api_control_ping_t * mp;
9507         M(CONTROL_PING, control_ping);
9508         S;
9509     }
9510     W;
9511 }
9512
9513 static int
9514 api_ipsec_spd_add_del (vat_main_t * vam)
9515 {
9516 #if DPDK > 0
9517     unformat_input_t * i = vam->input;
9518     vl_api_ipsec_spd_add_del_t *mp;
9519     f64 timeout;
9520     u32 spd_id = ~0;
9521     u8 is_add = 1;
9522
9523     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9524         if (unformat (i, "spd_id %d", &spd_id))
9525             ;
9526         else if (unformat (i, "del"))
9527             is_add = 0;
9528         else {
9529             clib_warning ("parse error '%U'", format_unformat_error, i);
9530             return -99;
9531         }
9532     }
9533     if (spd_id == ~0) {
9534         errmsg ("spd_id must be set\n");
9535         return -99;
9536     }
9537
9538     M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
9539
9540     mp->spd_id = ntohl(spd_id);
9541     mp->is_add = is_add;
9542
9543     S; W;
9544     /* NOTREACHED */
9545     return 0;
9546 #else
9547     clib_warning ("unsupported (no dpdk)");
9548     return -99;
9549 #endif
9550 }
9551
9552 static int
9553 api_ipsec_interface_add_del_spd (vat_main_t * vam)
9554 {
9555 #if DPDK > 0
9556     unformat_input_t * i = vam->input;
9557     vl_api_ipsec_interface_add_del_spd_t *mp;
9558     f64 timeout;
9559     u32 sw_if_index;
9560     u8 sw_if_index_set = 0;
9561     u32 spd_id = (u32) ~0;
9562     u8 is_add = 1;
9563
9564     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9565         if (unformat (i, "del"))
9566             is_add = 0;
9567         else if (unformat (i, "spd_id %d", &spd_id))
9568             ;
9569         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9570             sw_if_index_set = 1;
9571         else if (unformat (i, "sw_if_index %d", &sw_if_index))
9572             sw_if_index_set = 1;
9573         else {
9574             clib_warning ("parse error '%U'", format_unformat_error, i);
9575             return -99;
9576         }
9577
9578     }
9579
9580     if (spd_id == (u32) ~0) {
9581         errmsg ("spd_id must be set\n");
9582         return -99;
9583     }
9584
9585     if (sw_if_index_set == 0) {
9586         errmsg ("missing interface name or sw_if_index\n");
9587         return -99;
9588     }
9589
9590     M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
9591
9592     mp->spd_id = ntohl(spd_id);
9593     mp->sw_if_index = ntohl (sw_if_index);
9594     mp->is_add = is_add;
9595
9596     S; W;
9597     /* NOTREACHED */
9598     return 0;
9599 #else
9600     clib_warning ("unsupported (no dpdk)");
9601     return -99;
9602 #endif
9603 }
9604
9605 static int
9606 api_ipsec_spd_add_del_entry (vat_main_t * vam)
9607 {
9608 #if DPDK > 0
9609     unformat_input_t * i = vam->input;
9610     vl_api_ipsec_spd_add_del_entry_t *mp;
9611     f64 timeout;
9612     u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
9613     u32 spd_id, sa_id, protocol = 0, policy = 0;
9614     i32 priority;
9615     u32 rport_start = 0, rport_stop = (u32) ~0;
9616     u32 lport_start = 0, lport_stop = (u32) ~0;
9617     ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
9618     ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
9619
9620     laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
9621     laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
9622     laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
9623     laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
9624     laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
9625     laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
9626
9627     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9628         if (unformat (i, "del"))
9629             is_add = 0;
9630         if (unformat (i, "outbound"))
9631             is_outbound = 1;
9632         if (unformat (i, "inbound"))
9633             is_outbound = 0;
9634         else if (unformat (i, "spd_id %d", &spd_id))
9635             ;
9636         else if (unformat (i, "sa_id %d", &sa_id))
9637             ;
9638         else if (unformat (i, "priority %d", &priority))
9639             ;
9640         else if (unformat (i, "protocol %d", &protocol))
9641             ;
9642         else if (unformat (i, "lport_start %d", &lport_start))
9643             ;
9644         else if (unformat (i, "lport_stop %d", &lport_stop))
9645             ;
9646         else if (unformat (i, "rport_start %d", &rport_start))
9647             ;
9648         else if (unformat (i, "rport_stop %d", &rport_stop))
9649             ;
9650         else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
9651           {
9652             is_ipv6 = 0;
9653             is_ip_any =0;
9654           }
9655         else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
9656           {
9657             is_ipv6 = 0;
9658             is_ip_any = 0;
9659           }
9660         else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
9661           {
9662             is_ipv6 = 0;
9663             is_ip_any = 0;
9664           }
9665         else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
9666           {
9667             is_ipv6 = 0;
9668             is_ip_any = 0;
9669           }
9670         else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
9671           {
9672             is_ipv6 = 1;
9673             is_ip_any = 0;
9674           }
9675         else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
9676           {
9677             is_ipv6 = 1;
9678             is_ip_any = 0;
9679           }
9680         else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
9681           {
9682             is_ipv6 = 1;
9683             is_ip_any = 0;
9684           }
9685         else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
9686           {
9687             is_ipv6 = 1;
9688             is_ip_any = 0;
9689           }
9690         else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
9691           {
9692             if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
9693                 clib_warning ("unsupported action: 'resolve'");
9694                 return -99;
9695             }
9696           }
9697         else {
9698             clib_warning ("parse error '%U'", format_unformat_error, i);
9699             return -99;
9700         }
9701
9702     }
9703
9704     M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
9705
9706     mp->spd_id = ntohl(spd_id);
9707     mp->priority = ntohl(priority);
9708     mp->is_outbound = is_outbound;
9709
9710     mp->is_ipv6 = is_ipv6;
9711     if (is_ipv6 || is_ip_any) {
9712         clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
9713         clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
9714         clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
9715         clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
9716     } else {
9717         clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
9718         clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
9719         clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
9720         clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
9721     }
9722     mp->protocol = (u8) protocol;
9723     mp->local_port_start = ntohs((u16) lport_start);
9724     mp->local_port_stop = ntohs((u16) lport_stop);
9725     mp->remote_port_start = ntohs((u16) rport_start);
9726     mp->remote_port_stop = ntohs((u16) rport_stop);
9727     mp->policy = (u8) policy;
9728     mp->sa_id = ntohl(sa_id);
9729     mp->is_add = is_add;
9730     mp->is_ip_any = is_ip_any;
9731     S; W;
9732     /* NOTREACHED */
9733     return 0;
9734 #else
9735     clib_warning ("unsupported (no dpdk)");
9736     return -99;
9737 #endif
9738 }
9739
9740 static int
9741 api_ipsec_sad_add_del_entry (vat_main_t * vam)
9742 {
9743 #if DPDK > 0
9744     unformat_input_t * i = vam->input;
9745     vl_api_ipsec_sad_add_del_entry_t *mp;
9746     f64 timeout;
9747     u32 sad_id, spi;
9748     u8 * ck = 0, * ik = 0;
9749     u8 is_add = 1;
9750
9751     u8 protocol = IPSEC_PROTOCOL_AH;
9752     u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
9753     u32 crypto_alg = 0, integ_alg = 0;
9754     ip4_address_t tun_src4;
9755     ip4_address_t tun_dst4;
9756     ip6_address_t tun_src6;
9757     ip6_address_t tun_dst6;
9758
9759     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9760         if (unformat (i, "del"))
9761             is_add = 0;
9762         else if (unformat (i, "sad_id %d", &sad_id))
9763             ;
9764         else if (unformat (i, "spi %d", &spi))
9765             ;
9766         else if (unformat (i, "esp"))
9767             protocol = IPSEC_PROTOCOL_ESP;
9768         else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
9769             is_tunnel = 1;
9770             is_tunnel_ipv6 = 0;
9771         }
9772         else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
9773             is_tunnel = 1;
9774             is_tunnel_ipv6 = 0;
9775         }
9776         else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
9777             is_tunnel = 1;
9778             is_tunnel_ipv6 = 1;
9779         }
9780         else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
9781             is_tunnel = 1;
9782             is_tunnel_ipv6 = 1;
9783         }
9784         else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
9785             if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
9786                 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9787                 clib_warning ("unsupported crypto-alg: '%U'",
9788                               format_ipsec_crypto_alg, crypto_alg);
9789                 return -99;
9790             }
9791         }
9792         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9793             ;
9794         else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
9795             if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
9796                 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
9797                 clib_warning ("unsupported integ-alg: '%U'",
9798                               format_ipsec_integ_alg, integ_alg);
9799                 return -99;
9800             }
9801         }
9802         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9803             ;
9804         else {
9805             clib_warning ("parse error '%U'", format_unformat_error, i);
9806             return -99;
9807         }
9808
9809     }
9810
9811     M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
9812
9813     mp->sad_id = ntohl(sad_id);
9814     mp->is_add = is_add;
9815     mp->protocol = protocol;
9816     mp->spi = ntohl(spi);
9817     mp->is_tunnel = is_tunnel;
9818     mp->is_tunnel_ipv6 = is_tunnel_ipv6;
9819     mp->crypto_algorithm = crypto_alg;
9820     mp->integrity_algorithm = integ_alg;
9821     mp->crypto_key_length = vec_len(ck);
9822     mp->integrity_key_length = vec_len(ik);
9823
9824     if (mp->crypto_key_length > sizeof(mp->crypto_key))
9825       mp->crypto_key_length = sizeof(mp->crypto_key);
9826
9827     if (mp->integrity_key_length > sizeof(mp->integrity_key))
9828       mp->integrity_key_length = sizeof(mp->integrity_key);
9829
9830     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9831     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
9832
9833     if (is_tunnel) {
9834       if (is_tunnel_ipv6) {
9835         clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9836         clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
9837       } else {
9838         clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9839         clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
9840       }
9841     }
9842
9843     S; W;
9844     /* NOTREACHED */
9845     return 0;
9846 #else
9847     clib_warning ("unsupported (no dpdk)");
9848     return -99;
9849 #endif
9850 }
9851
9852 static int
9853 api_ipsec_sa_set_key (vat_main_t * vam)
9854 {
9855 #if DPDK > 0
9856     unformat_input_t * i = vam->input;
9857     vl_api_ipsec_sa_set_key_t *mp;
9858     f64 timeout;
9859     u32 sa_id;
9860     u8 * ck = 0, * ik = 0;
9861
9862     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9863         if (unformat (i, "sa_id %d", &sa_id))
9864             ;
9865         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9866             ;
9867         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9868             ;
9869         else {
9870             clib_warning ("parse error '%U'", format_unformat_error, i);
9871             return -99;
9872         }
9873     }
9874
9875     M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9876
9877     mp->sa_id = ntohl(sa_id);
9878     mp->crypto_key_length = vec_len(ck);
9879     mp->integrity_key_length = vec_len(ik);
9880
9881     if (mp->crypto_key_length > sizeof(mp->crypto_key))
9882       mp->crypto_key_length = sizeof(mp->crypto_key);
9883
9884     if (mp->integrity_key_length > sizeof(mp->integrity_key))
9885       mp->integrity_key_length = sizeof(mp->integrity_key);
9886
9887     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9888     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
9889
9890     S; W;
9891     /* NOTREACHED */
9892     return 0;
9893 #else
9894     clib_warning ("unsupported (no dpdk)");
9895     return -99;
9896 #endif
9897 }
9898
9899 static int
9900 api_ikev2_profile_add_del (vat_main_t * vam)
9901 {
9902 #if DPDK > 0
9903     unformat_input_t * i = vam->input;
9904     vl_api_ikev2_profile_add_del_t * mp;
9905     f64 timeout;
9906     u8 is_add = 1;
9907     u8 * name = 0;
9908
9909     const char * valid_chars = "a-zA-Z0-9_";
9910
9911     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9912         if (unformat (i, "del"))
9913             is_add = 0;
9914         else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9915             vec_add1 (name, 0);
9916         else {
9917             errmsg ("parse error '%U'", format_unformat_error, i);
9918             return -99;
9919         }
9920     }
9921
9922     if (!vec_len (name)) {
9923         errmsg ("profile name must be specified");
9924         return -99;
9925     }
9926
9927     if (vec_len (name) > 64) {
9928         errmsg ("profile name too long");
9929         return -99;
9930     }
9931
9932     M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9933
9934     clib_memcpy(mp->name, name, vec_len (name));
9935     mp->is_add = is_add;
9936     vec_free (name);
9937
9938     S; W;
9939     /* NOTREACHED */
9940     return 0;
9941 #else
9942     clib_warning ("unsupported (no dpdk)");
9943     return -99;
9944 #endif
9945 }
9946
9947 static int
9948 api_ikev2_profile_set_auth (vat_main_t * vam)
9949 {
9950 #if DPDK > 0
9951     unformat_input_t * i = vam->input;
9952     vl_api_ikev2_profile_set_auth_t * mp;
9953     f64 timeout;
9954     u8 * name = 0;
9955     u8 * data = 0;
9956     u32 auth_method = 0;
9957     u8 is_hex = 0;
9958
9959     const char * valid_chars = "a-zA-Z0-9_";
9960
9961     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9962         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9963             vec_add1 (name, 0);
9964         else if (unformat (i, "auth_method %U",
9965                            unformat_ikev2_auth_method, &auth_method))
9966             ;
9967         else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9968             is_hex = 1;
9969         else if (unformat (i, "auth_data %v", &data))
9970             ;
9971         else {
9972             errmsg ("parse error '%U'", format_unformat_error, i);
9973             return -99;
9974         }
9975     }
9976
9977     if (!vec_len (name)) {
9978         errmsg ("profile name must be specified");
9979         return -99;
9980     }
9981
9982     if (vec_len (name) > 64) {
9983         errmsg ("profile name too long");
9984         return -99;
9985     }
9986
9987     if (!vec_len(data)) {
9988         errmsg ("auth_data must be specified");
9989         return -99;
9990     }
9991
9992     if (!auth_method) {
9993         errmsg ("auth_method must be specified");
9994         return -99;
9995     }
9996
9997     M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9998
9999     mp->is_hex = is_hex;
10000     mp->auth_method = (u8) auth_method;
10001     mp->data_len = vec_len (data);
10002     clib_memcpy (mp->name, name, vec_len (name));
10003     clib_memcpy (mp->data, data, vec_len (data));
10004     vec_free (name);
10005     vec_free (data);
10006
10007     S; W;
10008     /* NOTREACHED */
10009     return 0;
10010 #else
10011     clib_warning ("unsupported (no dpdk)");
10012     return -99;
10013 #endif
10014 }
10015
10016 static int
10017 api_ikev2_profile_set_id (vat_main_t * vam)
10018 {
10019 #if DPDK > 0
10020     unformat_input_t * i = vam->input;
10021     vl_api_ikev2_profile_set_id_t * mp;
10022     f64 timeout;
10023     u8 * name = 0;
10024     u8 * data = 0;
10025     u8 is_local = 0;
10026     u32 id_type = 0;
10027     ip4_address_t ip4;
10028
10029     const char * valid_chars = "a-zA-Z0-9_";
10030
10031     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10032         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10033             vec_add1 (name, 0);
10034         else if (unformat (i, "id_type %U",
10035                            unformat_ikev2_id_type, &id_type))
10036             ;
10037         else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10038           {
10039             data = vec_new(u8, 4);
10040             clib_memcpy(data, ip4.as_u8, 4);
10041           }
10042         else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10043             ;
10044         else if (unformat (i, "id_data %v", &data))
10045             ;
10046         else if (unformat (i, "local"))
10047             is_local = 1;
10048         else if (unformat (i, "remote"))
10049             is_local = 0;
10050         else {
10051             errmsg ("parse error '%U'", format_unformat_error, i);
10052             return -99;
10053         }
10054     }
10055
10056     if (!vec_len (name)) {
10057         errmsg ("profile name must be specified");
10058         return -99;
10059     }
10060
10061     if (vec_len (name) > 64) {
10062         errmsg ("profile name too long");
10063         return -99;
10064     }
10065
10066     if (!vec_len(data)) {
10067         errmsg ("id_data must be specified");
10068         return -99;
10069     }
10070
10071     if (!id_type) {
10072         errmsg ("id_type must be specified");
10073         return -99;
10074     }
10075
10076     M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
10077
10078     mp->is_local = is_local;
10079     mp->id_type = (u8) id_type;
10080     mp->data_len = vec_len (data);
10081     clib_memcpy (mp->name, name, vec_len (name));
10082     clib_memcpy (mp->data, data, vec_len (data));
10083     vec_free (name);
10084     vec_free (data);
10085
10086     S; W;
10087     /* NOTREACHED */
10088     return 0;
10089 #else
10090     clib_warning ("unsupported (no dpdk)");
10091     return -99;
10092 #endif
10093 }
10094
10095 static int
10096 api_ikev2_profile_set_ts (vat_main_t * vam)
10097 {
10098 #if DPDK > 0
10099     unformat_input_t * i = vam->input;
10100     vl_api_ikev2_profile_set_ts_t * mp;
10101     f64 timeout;
10102     u8 * name = 0;
10103     u8 is_local = 0;
10104     u32 proto = 0, start_port = 0, end_port = (u32) ~0;
10105     ip4_address_t start_addr, end_addr;
10106
10107     const char * valid_chars = "a-zA-Z0-9_";
10108
10109     start_addr.as_u32 = 0;
10110     end_addr.as_u32 = (u32) ~0;
10111
10112     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10113         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10114             vec_add1 (name, 0);
10115         else if (unformat (i, "protocol %d", &proto))
10116             ;
10117         else if (unformat (i, "start_port %d", &start_port))
10118             ;
10119         else if (unformat (i, "end_port %d", &end_port))
10120             ;
10121         else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
10122             ;
10123         else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
10124             ;
10125         else if (unformat (i, "local"))
10126             is_local = 1;
10127         else if (unformat (i, "remote"))
10128             is_local = 0;
10129         else {
10130             errmsg ("parse error '%U'", format_unformat_error, i);
10131             return -99;
10132         }
10133     }
10134
10135     if (!vec_len (name)) {
10136         errmsg ("profile name must be specified");
10137         return -99;
10138     }
10139
10140     if (vec_len (name) > 64) {
10141         errmsg ("profile name too long");
10142         return -99;
10143     }
10144
10145     M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
10146
10147     mp->is_local = is_local;
10148     mp->proto = (u8) proto;
10149     mp->start_port = (u16) start_port;
10150     mp->end_port = (u16) end_port;
10151     mp->start_addr = start_addr.as_u32;
10152     mp->end_addr = end_addr.as_u32;
10153     clib_memcpy (mp->name, name, vec_len (name));
10154     vec_free (name);
10155
10156     S; W;
10157     /* NOTREACHED */
10158     return 0;
10159 #else
10160     clib_warning ("unsupported (no dpdk)");
10161     return -99;
10162 #endif
10163 }
10164
10165 static int
10166 api_ikev2_set_local_key (vat_main_t * vam)
10167 {
10168 #if DPDK > 0
10169     unformat_input_t * i = vam->input;
10170     vl_api_ikev2_set_local_key_t * mp;
10171     f64 timeout;
10172     u8 * file = 0;
10173
10174     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10175         if (unformat (i, "file %v", &file))
10176             vec_add1 (file, 0);
10177         else {
10178             errmsg ("parse error '%U'", format_unformat_error, i);
10179             return -99;
10180         }
10181     }
10182
10183     if (!vec_len (file)) {
10184         errmsg ("RSA key file must be specified");
10185         return -99;
10186     }
10187
10188     if (vec_len (file) > 256) {
10189         errmsg ("file name too long");
10190         return -99;
10191     }
10192
10193     M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
10194
10195     clib_memcpy (mp->key_file, file, vec_len (file));
10196     vec_free (file);
10197
10198     S; W;
10199     /* NOTREACHED */
10200     return 0;
10201 #else
10202     clib_warning ("unsupported (no dpdk)");
10203     return -99;
10204 #endif
10205 }
10206
10207 /*
10208  * MAP
10209  */
10210 static int api_map_add_domain (vat_main_t * vam)
10211 {
10212   unformat_input_t *i = vam->input;
10213   vl_api_map_add_domain_t *mp;
10214   f64 timeout;
10215
10216   ip4_address_t ip4_prefix;
10217   ip6_address_t ip6_prefix;
10218   ip6_address_t ip6_src;
10219   u32 num_m_args = 0;
10220   u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
10221     psid_length;
10222   u8 is_translation = 0;
10223   u32 mtu = 0;
10224   u8 ip6_src_len = 128;
10225
10226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10227     if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
10228                   &ip4_prefix, &ip4_prefix_len))
10229       num_m_args++;
10230     else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
10231                        &ip6_prefix, &ip6_prefix_len))
10232       num_m_args++;
10233     else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
10234       num_m_args++;
10235     else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
10236       num_m_args++;
10237     else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
10238       num_m_args++;
10239     else if (unformat (i, "psid-offset %d", &psid_offset))
10240       num_m_args++;
10241     else if (unformat (i, "psid-len %d", &psid_length))
10242       num_m_args++;
10243     else if (unformat (i, "mtu %d", &mtu))
10244       num_m_args++;
10245     else if (unformat (i, "map-t"))
10246       is_translation = 1;
10247     else {
10248       clib_warning ("parse error '%U'", format_unformat_error, i);
10249       return -99;
10250     }
10251   }
10252
10253   if (num_m_args != 6) {
10254     errmsg("mandatory argument(s) missing\n");
10255     return -99;
10256   }
10257
10258   /* Construct the API message */
10259   M(MAP_ADD_DOMAIN, map_add_domain);
10260
10261   clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
10262   mp->ip4_prefix_len = ip4_prefix_len;
10263
10264   clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
10265   mp->ip6_prefix_len = ip6_prefix_len;
10266
10267   clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
10268   mp->ip6_src_prefix_len = ip6_src_len;
10269
10270   mp->ea_bits_len = ea_bits_len;
10271   mp->psid_offset = psid_offset;
10272   mp->psid_length = psid_length;
10273   mp->is_translation = is_translation;
10274   mp->mtu = htons(mtu);
10275
10276   /* send it... */
10277   S;
10278
10279   /* Wait for a reply, return good/bad news  */
10280   W;
10281 }
10282
10283 static int api_map_del_domain (vat_main_t * vam)
10284 {
10285   unformat_input_t *i = vam->input;
10286   vl_api_map_del_domain_t *mp;
10287   f64 timeout;
10288
10289   u32 num_m_args = 0;
10290   u32 index;
10291
10292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10293     if (unformat (i, "index %d", &index))
10294       num_m_args++;
10295     else {
10296       clib_warning ("parse error '%U'", format_unformat_error, i);
10297       return -99;
10298     }
10299   }
10300
10301   if (num_m_args != 1) {
10302     errmsg("mandatory argument(s) missing\n");
10303     return -99;
10304   }
10305
10306   /* Construct the API message */
10307   M(MAP_DEL_DOMAIN, map_del_domain);
10308
10309   mp->index = ntohl(index);
10310
10311   /* send it... */
10312   S;
10313
10314   /* Wait for a reply, return good/bad news  */
10315   W;
10316 }
10317
10318 static int api_map_add_del_rule (vat_main_t * vam)
10319 {
10320   unformat_input_t *i = vam->input;
10321   vl_api_map_add_del_rule_t *mp;
10322   f64 timeout;
10323   u8 is_add = 1;
10324   ip6_address_t ip6_dst;
10325   u32 num_m_args = 0, index, psid;
10326
10327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10328     if (unformat (i, "index %d", &index))
10329       num_m_args++;
10330     else if (unformat (i, "psid %d", &psid))
10331       num_m_args++;
10332     else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
10333       num_m_args++;
10334     else if (unformat (i, "del")) {
10335       is_add = 0;
10336     } else {
10337       clib_warning ("parse error '%U'", format_unformat_error, i);
10338       return -99;
10339     }
10340   }
10341
10342   /* Construct the API message */
10343   M(MAP_ADD_DEL_RULE, map_add_del_rule);
10344
10345   mp->index = ntohl(index);
10346   mp->is_add = is_add;
10347   clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
10348   mp->psid = ntohs(psid);
10349
10350   /* send it... */
10351   S;
10352
10353   /* Wait for a reply, return good/bad news  */
10354   W;
10355 }
10356
10357 static int api_map_domain_dump (vat_main_t * vam)
10358 {
10359     vl_api_map_domain_dump_t *mp;
10360     f64 timeout;
10361
10362     /* Construct the API message */
10363     M(MAP_DOMAIN_DUMP, map_domain_dump);
10364
10365     /* send it... */
10366     S;
10367
10368     /* Use a control ping for synchronization */
10369     {
10370         vl_api_control_ping_t * mp;
10371         M(CONTROL_PING, control_ping);
10372         S;
10373     }
10374     W;
10375 }
10376
10377 static int api_map_rule_dump (vat_main_t * vam)
10378 {
10379     unformat_input_t *i = vam->input;
10380     vl_api_map_rule_dump_t *mp;
10381     f64 timeout;
10382     u32 domain_index = ~0;
10383
10384     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10385         if (unformat (i, "index %u", &domain_index))
10386             ;
10387         else
10388             break;
10389     }
10390
10391     if (domain_index == ~0) {
10392         clib_warning("parse error: domain index expected");
10393         return -99;
10394     }
10395
10396     /* Construct the API message */
10397     M(MAP_RULE_DUMP, map_rule_dump);
10398
10399     mp->domain_index = htonl(domain_index);
10400
10401     /* send it... */
10402     S;
10403
10404     /* Use a control ping for synchronization */
10405     {
10406         vl_api_control_ping_t * mp;
10407         M(CONTROL_PING, control_ping);
10408         S;
10409     }
10410     W;
10411 }
10412
10413 static void vl_api_map_add_domain_reply_t_handler
10414 (vl_api_map_add_domain_reply_t * mp)
10415 {
10416   vat_main_t * vam = &vat_main;
10417   i32 retval = ntohl(mp->retval);
10418
10419   if (vam->async_mode) {
10420       vam->async_errors += (retval < 0);
10421   } else {
10422       vam->retval = retval;
10423       vam->result_ready = 1;
10424   }
10425 }
10426
10427 static void vl_api_map_add_domain_reply_t_handler_json
10428 (vl_api_map_add_domain_reply_t * mp)
10429 {
10430   vat_main_t * vam = &vat_main;
10431   vat_json_node_t node;
10432
10433   vat_json_init_object(&node);
10434   vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
10435   vat_json_object_add_uint(&node, "index", ntohl(mp->index));
10436
10437   vat_json_print(vam->ofp, &node);
10438   vat_json_free(&node);
10439
10440   vam->retval = ntohl(mp->retval);
10441   vam->result_ready = 1;
10442 }
10443
10444 static int
10445 api_get_first_msg_id (vat_main_t * vam)
10446 {
10447     vl_api_get_first_msg_id_t * mp;
10448     f64 timeout;
10449     unformat_input_t * i = vam->input;
10450     u8 * name;
10451     u8 name_set = 0;
10452
10453     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10454         if (unformat (i, "client %s", &name))
10455             name_set = 1;
10456         else
10457             break;
10458     }
10459
10460     if (name_set == 0) {
10461         errmsg ("missing client name\n");
10462         return -99;
10463     }
10464     vec_add1 (name, 0);
10465
10466     if (vec_len (name) > 63) {
10467         errmsg ("client name too long\n");
10468         return -99;
10469     }
10470
10471     M(GET_FIRST_MSG_ID, get_first_msg_id);
10472     clib_memcpy (mp->name, name, vec_len(name));
10473     S; W;
10474     /* NOTREACHED */
10475     return 0;
10476 }
10477
10478 static int api_cop_interface_enable_disable (vat_main_t * vam)
10479 {
10480     unformat_input_t * line_input = vam->input;
10481     vl_api_cop_interface_enable_disable_t * mp;
10482     f64 timeout;
10483     u32 sw_if_index = ~0;
10484     u8 enable_disable = 1;
10485
10486     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10487         if (unformat (line_input, "disable"))
10488             enable_disable = 0;
10489         if (unformat (line_input, "enable"))
10490             enable_disable = 1;
10491         else if (unformat (line_input, "%U", unformat_sw_if_index,
10492                            vam, &sw_if_index))
10493             ;
10494         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10495             ;
10496         else
10497             break;
10498     }
10499
10500     if (sw_if_index == ~0) {
10501         errmsg ("missing interface name or sw_if_index\n");
10502         return -99;
10503     }
10504
10505     /* Construct the API message */
10506     M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
10507     mp->sw_if_index = ntohl(sw_if_index);
10508     mp->enable_disable = enable_disable;
10509
10510     /* send it... */
10511     S;
10512     /* Wait for the reply */
10513     W;
10514 }
10515
10516 static int api_cop_whitelist_enable_disable (vat_main_t * vam)
10517 {
10518     unformat_input_t * line_input = vam->input;
10519     vl_api_cop_whitelist_enable_disable_t * mp;
10520     f64 timeout;
10521     u32 sw_if_index = ~0;
10522     u8 ip4=0, ip6=0, default_cop=0;
10523     u32 fib_id;
10524
10525     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10526         if (unformat (line_input, "ip4"))
10527             ip4 = 1;
10528         else if (unformat (line_input, "ip6"))
10529             ip6 = 1;
10530         else if (unformat (line_input, "default"))
10531             default_cop = 1;
10532         else if (unformat (line_input, "%U", unformat_sw_if_index,
10533                            vam, &sw_if_index))
10534             ;
10535         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10536             ;
10537         else if (unformat (line_input, "fib-id %d", &fib_id))
10538             ;
10539         else
10540             break;
10541     }
10542
10543     if (sw_if_index == ~0) {
10544         errmsg ("missing interface name or sw_if_index\n");
10545         return -99;
10546     }
10547
10548     /* Construct the API message */
10549     M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
10550     mp->sw_if_index = ntohl(sw_if_index);
10551     mp->fib_id = ntohl(fib_id);
10552     mp->ip4 = ip4;
10553     mp->ip6 = ip6;
10554     mp->default_cop = default_cop;
10555
10556     /* send it... */
10557     S;
10558     /* Wait for the reply */
10559     W;
10560 }
10561
10562 static int api_get_node_graph (vat_main_t * vam)
10563 {
10564     vl_api_get_node_graph_t * mp;
10565     f64 timeout;
10566
10567     M(GET_NODE_GRAPH, get_node_graph);
10568
10569     /* send it... */
10570     S;
10571     /* Wait for the reply */
10572     W;
10573 }
10574
10575 /** Used for transferring locators via VPP API */
10576 typedef CLIB_PACKED(struct
10577 {
10578     u32 sw_if_index; /**< locator sw_if_index */
10579     u8 priority; /**< locator priority */
10580     u8 weight;   /**< locator weight */
10581 }) ls_locator_t;
10582
10583 static int
10584 api_lisp_add_del_locator_set(vat_main_t * vam)
10585 {
10586     unformat_input_t * input = vam->input;
10587     vl_api_lisp_add_del_locator_set_t *mp;
10588     f64 timeout = ~0;
10589     u8  is_add = 1;
10590     u8 *locator_set_name = NULL;
10591     u8  locator_set_name_set = 0;
10592     ls_locator_t locator, * locators = 0;
10593     u32 sw_if_index, priority, weight;
10594
10595     /* Parse args required to build the message */
10596     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10597         if (unformat(input, "del")) {
10598             is_add = 0;
10599         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10600             locator_set_name_set = 1;
10601         } else if (unformat(input, "sw_if_index %u p %u w %u",
10602                             &sw_if_index, &priority, &weight)) {
10603             locator.sw_if_index = htonl(sw_if_index);
10604             locator.priority = priority;
10605             locator.weight = weight;
10606             vec_add1(locators, locator);
10607         } else if (unformat(input, "iface %U p %u w %u", unformat_sw_if_index,
10608                             vam, &sw_if_index, &priority, &weight)) {
10609             locator.sw_if_index = htonl(sw_if_index);
10610             locator.priority = priority;
10611             locator.weight = weight;
10612             vec_add1(locators, locator);
10613         } else
10614             break;
10615     }
10616
10617     if (locator_set_name_set == 0) {
10618         errmsg ("missing locator-set name");
10619         vec_free(locators);
10620         return -99;
10621     }
10622
10623     if (vec_len(locator_set_name) > 64) {
10624         errmsg ("locator-set name too long\n");
10625         vec_free(locator_set_name);
10626         vec_free(locators);
10627         return -99;
10628     }
10629     vec_add1(locator_set_name, 0);
10630
10631     /* Construct the API message */
10632     M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
10633
10634     mp->is_add = is_add;
10635     clib_memcpy(mp->locator_set_name, locator_set_name,
10636            vec_len(locator_set_name));
10637     vec_free(locator_set_name);
10638
10639     mp->locator_num = vec_len (locators);
10640     clib_memcpy (mp->locators, locators,
10641                  (sizeof (ls_locator_t) * vec_len (locators)));
10642     vec_free (locators);
10643
10644     /* send it... */
10645     S;
10646
10647     /* Wait for a reply... */
10648     W;
10649
10650     /* NOTREACHED */
10651     return 0;
10652 }
10653
10654 static int
10655 api_lisp_add_del_locator(vat_main_t * vam)
10656 {
10657     unformat_input_t * input = vam->input;
10658     vl_api_lisp_add_del_locator_t *mp;
10659     f64 timeout = ~0;
10660     u32 tmp_if_index = ~0;
10661     u32 sw_if_index = ~0;
10662     u8  sw_if_index_set = 0;
10663     u8  sw_if_index_if_name_set = 0;
10664     u32  priority = ~0;
10665     u8  priority_set = 0;
10666     u32  weight = ~0;
10667     u8  weight_set = 0;
10668     u8  is_add = 1;
10669     u8  *locator_set_name = NULL;
10670     u8  locator_set_name_set = 0;
10671
10672     /* Parse args required to build the message */
10673     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10674         if (unformat(input, "del")) {
10675             is_add = 0;
10676         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10677             locator_set_name_set = 1;
10678         } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
10679             &tmp_if_index)) {
10680             sw_if_index_if_name_set = 1;
10681             sw_if_index = tmp_if_index;
10682         } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
10683             sw_if_index_set = 1;
10684             sw_if_index = tmp_if_index;
10685         } else if (unformat(input, "p %d", &priority)) {
10686             priority_set = 1;
10687         } else if (unformat(input, "w %d", &weight)) {
10688             weight_set = 1;
10689         } else
10690             break;
10691     }
10692
10693     if (locator_set_name_set == 0) {
10694         errmsg ("missing locator-set name");
10695         return -99;
10696     }
10697
10698     if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
10699         errmsg ("missing sw_if_index");
10700         vec_free(locator_set_name);
10701         return -99;
10702     }
10703
10704     if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
10705         errmsg ("cannot use both params interface name and sw_if_index");
10706         vec_free(locator_set_name);
10707         return -99;
10708     }
10709
10710     if (priority_set == 0) {
10711         errmsg ("missing locator-set priority\n");
10712         vec_free(locator_set_name);
10713         return -99;
10714     }
10715
10716     if (weight_set == 0) {
10717         errmsg ("missing locator-set weight\n");
10718         vec_free(locator_set_name);
10719         return -99;
10720     }
10721
10722     if (vec_len(locator_set_name) > 64) {
10723         errmsg ("locator-set name too long\n");
10724         vec_free(locator_set_name);
10725         return -99;
10726     }
10727     vec_add1(locator_set_name, 0);
10728
10729     /* Construct the API message */
10730     M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
10731
10732     mp->is_add = is_add;
10733     mp->sw_if_index = ntohl(sw_if_index);
10734     mp->priority = priority;
10735     mp->weight = weight;
10736     clib_memcpy(mp->locator_set_name, locator_set_name,
10737            vec_len(locator_set_name));
10738     vec_free(locator_set_name);
10739
10740     /* send it... */
10741     S;
10742
10743     /* Wait for a reply... */
10744     W;
10745
10746     /* NOTREACHED */
10747     return 0;
10748 }
10749
10750 static int
10751 api_lisp_add_del_local_eid(vat_main_t * vam)
10752 {
10753     unformat_input_t * input = vam->input;
10754     vl_api_lisp_add_del_local_eid_t *mp;
10755     f64 timeout = ~0;
10756     u8 is_add = 1;
10757     u8 eidv4_set = 0;
10758     u8 eidv6_set = 0;
10759     u8 eid_type = (u8)~0;
10760     ip4_address_t eidv4;
10761     ip6_address_t eidv6;
10762     u8 mac[6] = {0};
10763     u32 tmp_eid_lenght = ~0;
10764     u8 eid_lenght = ~0;
10765     u8 *locator_set_name = NULL;
10766     u8 locator_set_name_set = 0;
10767     u32 vni = 0;
10768
10769     /* Parse args required to build the message */
10770     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10771         if (unformat(input, "del")) {
10772             is_add = 0;
10773         } else if (unformat(input, "vni %d", &vni)) {
10774             ;
10775         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10776             &eidv4, &tmp_eid_lenght)) {
10777             eid_lenght = tmp_eid_lenght;
10778             eidv4_set = 1;
10779             eid_type = 0; /* ipv4 type */
10780         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10781             &eidv6, &tmp_eid_lenght)) {
10782             eid_lenght = tmp_eid_lenght;
10783             eidv6_set = 1;
10784             eid_type = 1; /* ipv6 type */
10785         } else if (unformat(input, "eid %U", unformat_ethernet_address, mac)) {
10786             eid_type = 2; /* mac type */
10787         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
10788             locator_set_name_set = 1;
10789         } else
10790             break;
10791     }
10792
10793     if (locator_set_name_set == 0) {
10794         errmsg ("missing locator-set name\n");
10795         return -99;
10796     }
10797
10798     if ((u8)~0 == eid_type) {
10799         errmsg ("EID address not set!");
10800         vec_free(locator_set_name);
10801         return -99;
10802     }
10803
10804     if (vec_len(locator_set_name) > 64) {
10805         errmsg ("locator-set name too long\n");
10806         vec_free(locator_set_name);
10807         return -99;
10808     }
10809     vec_add1(locator_set_name, 0);
10810
10811     if (eidv4_set && eidv6_set) {
10812         errmsg ("both eid v4 and v6 addresses set\n");
10813         vec_free(locator_set_name);
10814         return -99;
10815     }
10816
10817     if (eidv4_set && eid_lenght > 32) {
10818         errmsg ("eid prefix to big\n");
10819         vec_free(locator_set_name);
10820         return -99;
10821     }
10822
10823     if (eidv6_set && eid_lenght > 128) {
10824         errmsg ("eid prefix to big\n");
10825         vec_free(locator_set_name);
10826         return -99;
10827     }
10828
10829     /* Construct the API message */
10830     M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
10831
10832     mp->is_add = is_add;
10833     switch (eid_type) {
10834     case 0: /* ipv4 */
10835       clib_memcpy (mp->eid, &eidv4, sizeof(eidv4));
10836       break;
10837     case 1: /* ipv6 */
10838       clib_memcpy (mp->eid, &eidv6, sizeof(eidv6));
10839       break;
10840     case 2: /* mac */
10841       clib_memcpy (mp->eid, mac, 6);
10842       break;
10843     }
10844     mp->eid_type = eid_type;
10845     mp->prefix_len = eid_lenght;
10846     mp->vni = clib_host_to_net_u32(vni);
10847     clib_memcpy(mp->locator_set_name, locator_set_name,
10848            vec_len(locator_set_name));
10849     vec_free(locator_set_name);
10850
10851     /* send it... */
10852     S;
10853
10854     /* Wait for a reply... */
10855     W;
10856
10857     /* NOTREACHED */
10858     return 0;
10859 }
10860
10861 static int
10862 api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
10863 {
10864     unformat_input_t * input = vam->input;
10865     vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
10866     f64 timeout = ~0;
10867     u8 is_add = 1;
10868     u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
10869     u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
10870     ip4_address_t eidv4, slocv4, dlocv4;
10871     ip6_address_t eidv6, slocv6, dlocv6;
10872     u32 tmp_eid_lenght = ~0;
10873     u8 eid_lenght = ~0;
10874
10875     /* Parse args required to build the message */
10876     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10877         if (unformat(input, "del")) {
10878             is_add = 0;
10879         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10880                             &eidv4, &tmp_eid_lenght)) {
10881             eid_lenght = tmp_eid_lenght;
10882             eidv4_set = 1;
10883         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10884                             &eidv6, &tmp_eid_lenght)) {
10885             eid_lenght = tmp_eid_lenght;
10886             eidv6_set = 1;
10887         } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
10888             slocv4_set = 1;
10889         } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
10890             slocv6_set = 1;
10891         } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
10892             dlocv4_set = 1;
10893         } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
10894             dlocv6_set = 1;
10895         } else
10896             break;
10897     }
10898
10899     if (eidv4_set && eidv6_set) {
10900         errmsg ("both eid v4 and v6 addresses set\n");
10901         return -99;
10902     }
10903
10904     if (!eidv4_set && !eidv6_set) {
10905         errmsg ("eid addresses not set\n");
10906         return -99;
10907     }
10908
10909     if (slocv4_set && slocv6_set) {
10910         errmsg ("both source v4 and v6 addresses set\n");
10911         return -99;
10912     }
10913
10914     if (!slocv4_set && !slocv6_set) {
10915         errmsg ("source addresses not set\n");
10916         return -99;
10917     }
10918
10919     if (dlocv4_set && dlocv6_set) {
10920         errmsg ("both destination v4 and v6 addresses set\n");
10921         return -99;
10922     }
10923
10924     if (dlocv4_set && dlocv6_set) {
10925         errmsg ("destination addresses not set\n");
10926         return -99;
10927     }
10928
10929     if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10930         errmsg ("mixing type of source and destination address\n");
10931         return -99;
10932     }
10933
10934     /* Construct the API message */
10935     M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10936
10937     mp->is_add = is_add;
10938     if (eidv6_set) {
10939         mp->eid_is_ipv6 = 1;
10940         clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
10941     } else {
10942         mp->eid_is_ipv6 = 0;
10943         clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
10944     }
10945     mp->eid_prefix_len = eid_lenght;
10946     if (slocv6_set) {
10947         mp->address_is_ipv6 = 1;
10948         clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10949         clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
10950     } else {
10951         mp->address_is_ipv6 = 0;
10952         clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10953         clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
10954     }
10955
10956     /* send it... */
10957     S;
10958
10959     /* Wait for a reply... */
10960     W;
10961
10962     /* NOTREACHED */
10963     return 0;
10964 }
10965
10966 static int
10967 api_lisp_add_del_map_resolver(vat_main_t * vam)
10968 {
10969     unformat_input_t * input = vam->input;
10970     vl_api_lisp_add_del_map_resolver_t *mp;
10971     f64 timeout = ~0;
10972     u8 is_add = 1;
10973     u8 ipv4_set = 0;
10974     u8 ipv6_set = 0;
10975     ip4_address_t ipv4;
10976     ip6_address_t ipv6;
10977
10978     /* Parse args required to build the message */
10979     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10980         if (unformat(input, "del")) {
10981             is_add = 0;
10982         } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10983             ipv4_set = 1;
10984         } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10985             ipv6_set = 1;
10986         } else
10987             break;
10988     }
10989
10990     if (ipv4_set && ipv6_set) {
10991         errmsg ("both eid v4 and v6 addresses set\n");
10992         return -99;
10993     }
10994
10995     if (!ipv4_set && !ipv6_set) {
10996         errmsg ("eid addresses not set\n");
10997         return -99;
10998     }
10999
11000     /* Construct the API message */
11001     M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
11002
11003     mp->is_add = is_add;
11004     if (ipv6_set) {
11005         mp->is_ipv6 = 1;
11006         clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
11007     } else {
11008         mp->is_ipv6 = 0;
11009         clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
11010     }
11011
11012     /* send it... */
11013     S;
11014
11015     /* Wait for a reply... */
11016     W;
11017
11018     /* NOTREACHED */
11019     return 0;
11020 }
11021
11022 static int
11023 api_lisp_gpe_enable_disable (vat_main_t * vam)
11024 {
11025   unformat_input_t * input = vam->input;
11026   vl_api_lisp_gpe_enable_disable_t *mp;
11027   f64 timeout = ~0;
11028   u8 is_set = 0;
11029   u8 is_en = 1;
11030
11031   /* Parse args required to build the message */
11032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11033       if (unformat(input, "enable")) {
11034           is_set = 1;
11035           is_en = 1;
11036       } else if (unformat(input, "disable")) {
11037           is_set = 1;
11038           is_en = 0;
11039       } else
11040           break;
11041   }
11042
11043   if (is_set == 0) {
11044       errmsg("Value not set\n");
11045       return -99;
11046   }
11047
11048   /* Construct the API message */
11049   M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
11050
11051   mp->is_en = is_en;
11052
11053   /* send it... */
11054   S;
11055
11056   /* Wait for a reply... */
11057   W;
11058
11059   /* NOTREACHED */
11060   return 0;
11061 }
11062
11063 static int
11064 api_lisp_enable_disable (vat_main_t * vam)
11065 {
11066   unformat_input_t * input = vam->input;
11067   vl_api_lisp_enable_disable_t *mp;
11068   f64 timeout = ~0;
11069   u8 is_set = 0;
11070   u8 is_en = 0;
11071
11072   /* Parse args required to build the message */
11073   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11074     {
11075       if (unformat (input, "enable"))
11076         {
11077           is_set = 1;
11078           is_en = 1;
11079         }
11080       else if (unformat (input, "disable"))
11081         {
11082           is_set = 1;
11083         }
11084       else
11085           break;
11086     }
11087
11088   if (!is_set)
11089     {
11090       errmsg ("Value not set\n");
11091       return -99;
11092     }
11093
11094   /* Construct the API message */
11095   M(LISP_ENABLE_DISABLE, lisp_enable_disable);
11096
11097   mp->is_en = is_en;
11098
11099   /* send it... */
11100   S;
11101
11102   /* Wait for a reply... */
11103   W;
11104
11105   /* NOTREACHED */
11106   return 0;
11107 }
11108
11109 /** Used for transferring locators via VPP API */
11110 typedef CLIB_PACKED(struct
11111 {
11112     u8 is_ip4; /**< is locator an IPv4 address? */
11113     u8 priority; /**< locator priority */
11114     u8 weight;   /**< locator weight */
11115     u8 addr[16]; /**< IPv4/IPv6 address */
11116 }) rloc_t;
11117
11118 /**
11119  * Enable/disable LISP proxy ITR.
11120  *
11121  * @param vam vpp API test context
11122  * @return return code
11123  */
11124 static int
11125 api_lisp_pitr_set_locator_set (vat_main_t * vam)
11126 {
11127   f64 timeout = ~0;
11128   u8 ls_name_set = 0;
11129   unformat_input_t * input = vam->input;
11130   vl_api_lisp_pitr_set_locator_set_t * mp;
11131   u8 is_add = 1;
11132   u8 * ls_name = 0;
11133
11134   /* Parse args required to build the message */
11135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (input, "del"))
11138         is_add = 0;
11139       else if (unformat (input, "locator-set %s", &ls_name))
11140         ls_name_set = 1;
11141       else
11142         {
11143           errmsg ("parse error '%U'", format_unformat_error, input);
11144           return -99;
11145         }
11146     }
11147
11148   if (!ls_name_set)
11149     {
11150       errmsg ("locator-set name not set!");
11151       return -99;
11152     }
11153
11154   M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
11155
11156   mp->is_add = is_add;
11157   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
11158   vec_free (ls_name);
11159
11160   /* send */
11161   S;
11162
11163   /* wait for reply */
11164   W;
11165
11166   /* notreached*/
11167   return 0;
11168 }
11169
11170 static int
11171 api_show_lisp_pitr (vat_main_t * vam)
11172 {
11173     vl_api_show_lisp_pitr_t *mp;
11174     f64 timeout = ~0;
11175
11176     if (!vam->json_output) {
11177         fformat(vam->ofp, "%=20s\n",
11178                 "lisp status:");
11179     }
11180
11181     M(SHOW_LISP_PITR, show_lisp_pitr);
11182     /* send it... */
11183     S;
11184
11185     /* Wait for a reply... */
11186     W;
11187
11188     /* NOTREACHED */
11189     return 0;
11190 }
11191
11192 /**
11193  * Add/delete mapping between vni and vrf
11194  */
11195 static int
11196 api_lisp_eid_table_add_del_map (vat_main_t * vam)
11197 {
11198   f64 timeout = ~0;
11199   unformat_input_t * input = vam->input;
11200   vl_api_lisp_eid_table_add_del_map_t *mp;
11201   u8 is_add = 1, vni_set = 0, vrf_set = 0;
11202   u32 vni, vrf;
11203
11204   /* Parse args required to build the message */
11205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11206     {
11207       if (unformat (input, "del"))
11208         is_add = 0;
11209       else if (unformat(input, "vrf %d", &vrf))
11210         vrf_set = 1;
11211       else if (unformat(input, "vni %d", &vni))
11212         vni_set = 1;
11213       else
11214         break;
11215     }
11216
11217   if (!vni_set || !vrf_set)
11218     {
11219       errmsg ("missing arguments!");
11220       return -99;
11221     }
11222
11223   M(LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
11224
11225   mp->is_add = is_add;
11226   mp->vni = htonl (vni);
11227   mp->vrf = htonl (vrf);
11228
11229   /* send */
11230   S;
11231
11232   /* wait for reply */
11233   W;
11234
11235   /* notreached*/
11236   return 0;
11237 }
11238
11239 /**
11240  * Add/del remote mapping to/from LISP control plane
11241  *
11242  * @param vam vpp API test context
11243  * @return return code
11244  */
11245 static int
11246 api_lisp_add_del_remote_mapping (vat_main_t * vam)
11247 {
11248     unformat_input_t * input = vam->input;
11249     vl_api_lisp_add_del_remote_mapping_t *mp;
11250     f64 timeout = ~0;
11251     u32 vni = 0;
11252     //TODO: seid need remove
11253     ip4_address_t seid4, eid4, rloc4;
11254     ip6_address_t seid6, eid6, rloc6;
11255     u8 eid_mac[6] = {0};
11256     u8 seid_mac[6] = {0};
11257     u8 eid_type;
11258     u32 eid_len = 0, len;
11259     u8 is_add = 1, del_all = 0;
11260     u32 action = ~0, p, w;
11261     rloc_t * rlocs = 0, rloc, * curr_rloc = 0;
11262
11263     eid_type = (u8)~0;
11264
11265     /* Parse args required to build the message */
11266     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11267         if (unformat(input, "del-all")) {
11268             del_all = 1;
11269         } else if (unformat(input, "del")) {
11270             is_add = 0;
11271         } else if (unformat(input, "add")) {
11272             is_add = 1;
11273         } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
11274                             &eid4, &len)) {
11275             eid_type = 0; /* ipv4 */
11276             if (32 < len) {
11277               clib_warning ("Deid prefix length to big, %d!", len);
11278               return -99;
11279             }
11280             eid_len = len;
11281         } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
11282                             &eid6, &len)) {
11283             eid_type = 1; /* ipv6 */
11284             if (128 < len) {
11285               clib_warning ("Deid prefix length to big, %d!", len);
11286               return -99;
11287             }
11288             eid_len = len;
11289         } else if (unformat(input, "deid %U", unformat_ethernet_address,
11290                             eid_mac)) {
11291             eid_type = 2; /* mac */
11292             //TODO: Need remove, but first must be remove from CSIT test
11293         } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
11294                             &seid4, &len)) {
11295         } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
11296                             &seid6, &len)) {
11297           ;
11298         } else if (unformat(input, "seid %U", unformat_ethernet_address,
11299                             seid_mac)) {
11300           ;
11301         } else if (unformat(input, "vni %d", &vni)) {
11302             ;
11303         } else if (unformat(input, "p %d w %d", &p, &w)) {
11304             if (!curr_rloc) {
11305               errmsg ("No RLOC configured for setting priority/weight!");
11306               return -99;
11307             }
11308             curr_rloc->priority = p;
11309             curr_rloc->weight = w;
11310         } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
11311             rloc.is_ip4 = 1;
11312             clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
11313             vec_add1 (rlocs, rloc);
11314             curr_rloc = &rlocs[vec_len (rlocs) - 1];
11315         } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
11316             rloc.is_ip4 = 0;
11317             clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
11318             vec_add1 (rlocs, rloc);
11319             curr_rloc = &rlocs[vec_len (rlocs) - 1];
11320         } else if (unformat(input, "action %d", &action)) {
11321             ;
11322         } else {
11323             clib_warning ("parse error '%U'", format_unformat_error, input);
11324             return -99;
11325         }
11326     }
11327
11328     if ((u8)~0 == eid_type) {
11329         errmsg ("missing params!");
11330         return -99;
11331     }
11332
11333     if (is_add && (~0 == action)
11334         && 0 == vec_len (rlocs)) {
11335           errmsg ("no action set for negative map-reply!");
11336           return -99;
11337     }
11338
11339     M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
11340     mp->is_add = is_add;
11341     mp->vni = htonl (vni);
11342     mp->action = (u8) action;
11343     mp->eid_len = eid_len;
11344     mp->del_all = del_all;
11345     mp->eid_type = eid_type;
11346
11347     switch (mp->eid_type) {
11348     case 0:
11349         clib_memcpy (mp->eid, &eid4, sizeof (eid4));
11350         break;
11351     case 1:
11352         clib_memcpy (mp->eid, &eid6, sizeof (eid6));
11353         break;
11354     case 2:
11355         clib_memcpy (mp->eid, eid_mac, 6);
11356         break;
11357     default:
11358         errmsg ("unknown EID type %d!", mp->eid_type);
11359         return 0;
11360     }
11361
11362     mp->rloc_num = vec_len (rlocs);
11363     clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
11364     vec_free (rlocs);
11365
11366     /* send it... */
11367     S;
11368
11369     /* Wait for a reply... */
11370     W;
11371
11372     /* NOTREACHED */
11373     return 0;
11374 }
11375
11376 /**
11377  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
11378  * forwarding entries in data-plane accordingly.
11379  *
11380  * @param vam vpp API test context
11381  * @return return code
11382  */
11383 static int
11384 api_lisp_add_del_adjacency (vat_main_t * vam)
11385 {
11386     unformat_input_t * input = vam->input;
11387     vl_api_lisp_add_del_adjacency_t *mp;
11388     f64 timeout = ~0;
11389     u32 vni = 0;
11390     ip4_address_t seid4, deid4;
11391     ip6_address_t seid6, deid6;
11392     u8 deid_mac[6] = {0};
11393     u8 seid_mac[6] = {0};
11394     u8 deid_type, seid_type;
11395     u32 seid_len = 0, deid_len = 0, len;
11396     u8 is_add = 1;
11397
11398     seid_type = deid_type =  (u8)~0;
11399
11400     /* Parse args required to build the message */
11401     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11402         if (unformat(input, "del")) {
11403             is_add = 0;
11404         } else if (unformat(input, "add")) {
11405             is_add = 1;
11406         } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
11407                             &deid4, &len)) {
11408             deid_type = 0; /* ipv4 */
11409             deid_len = len;
11410         } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
11411                             &deid6, &len)) {
11412             deid_type = 1; /* ipv6 */
11413             deid_len = len;
11414         } else if (unformat(input, "deid %U", unformat_ethernet_address,
11415                             deid_mac)) {
11416             deid_type = 2; /* mac */
11417         } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
11418                             &seid4, &len)) {
11419             seid_type = 0; /* ipv4 */
11420             seid_len = len;
11421         } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
11422                             &seid6, &len)) {
11423             seid_type = 1; /* ipv6 */
11424             seid_len = len;
11425         } else if (unformat(input, "seid %U", unformat_ethernet_address,
11426                             seid_mac)) {
11427             seid_type = 2; /* mac */
11428         } else if (unformat(input, "vni %d", &vni)) {
11429             ;
11430         } else {
11431             errmsg ("parse error '%U'", format_unformat_error, input);
11432             return -99;
11433         }
11434     }
11435
11436     if ((u8)~0 == deid_type) {
11437         errmsg ("missing params!");
11438         return -99;
11439     }
11440
11441     if (seid_type != deid_type) {
11442         errmsg ("source and destination EIDs are of different types!");
11443         return -99;
11444     }
11445
11446     M(LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
11447     mp->is_add = is_add;
11448     mp->vni = htonl (vni);
11449     mp->seid_len = seid_len;
11450     mp->deid_len = deid_len;
11451     mp->eid_type = deid_type;
11452
11453     switch (mp->eid_type) {
11454     case 0:
11455         clib_memcpy (mp->seid, &seid4, sizeof (seid4));
11456         clib_memcpy (mp->deid, &deid4, sizeof (deid4));
11457         break;
11458     case 1:
11459         clib_memcpy (mp->seid, &seid6, sizeof (seid6));
11460         clib_memcpy (mp->deid, &deid6, sizeof (deid6));
11461         break;
11462     case 2:
11463         clib_memcpy (mp->seid, seid_mac, 6);
11464         clib_memcpy (mp->deid, deid_mac, 6);
11465         break;
11466     default:
11467         errmsg ("unknown EID type %d!", mp->eid_type);
11468         return 0;
11469     }
11470
11471     /* send it... */
11472     S;
11473
11474     /* Wait for a reply... */
11475     W;
11476
11477     /* NOTREACHED */
11478     return 0;
11479 }
11480
11481 static int
11482 api_lisp_gpe_add_del_iface(vat_main_t * vam)
11483 {
11484     unformat_input_t * input = vam->input;
11485     vl_api_lisp_gpe_add_del_iface_t *mp;
11486     f64 timeout = ~0;
11487     u8 is_set = 0;
11488     u8 is_add = 1;
11489     u32 table_id, vni;
11490
11491     /* Parse args required to build the message */
11492     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11493         if (unformat(input, "up")) {
11494             is_set = 1;
11495             is_add = 1;
11496         } else if (unformat(input, "down")) {
11497             is_set = 1;
11498             is_add = 0;
11499         } else if (unformat(input, "table_id %d", &table_id)) {
11500             ;
11501         } else if (unformat(input, "vni %d", &vni)) {
11502             ;
11503         } else
11504             break;
11505     }
11506
11507     if (is_set == 0) {
11508         errmsg("Value not set\n");
11509         return -99;
11510     }
11511
11512     /* Construct the API message */
11513     M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
11514
11515     mp->is_add = is_add;
11516     mp->table_id = table_id;
11517     mp->vni = vni;
11518
11519     /* send it... */
11520     S;
11521
11522     /* Wait for a reply... */
11523     W;
11524
11525     /* NOTREACHED */
11526     return 0;
11527 }
11528
11529 /**
11530  * Add/del map request itr rlocs from LISP control plane and updates
11531  *
11532  * @param vam vpp API test context
11533  * @return return code
11534  */
11535 static int
11536 api_lisp_add_del_map_request_itr_rlocs(vat_main_t * vam)
11537 {
11538     unformat_input_t * input = vam->input;
11539     vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
11540     f64 timeout = ~0;
11541     u8 *locator_set_name = 0;
11542     u8  locator_set_name_set = 0;
11543     u8 is_add = 1;
11544
11545     /* Parse args required to build the message */
11546     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11547         if (unformat(input, "del")) {
11548             is_add = 0;
11549         } else if (unformat(input, "%_%v%_", &locator_set_name)) {
11550             locator_set_name_set = 1;
11551         } else {
11552             clib_warning ("parse error '%U'", format_unformat_error, input);
11553             return -99;
11554         }
11555     }
11556
11557     if (is_add && !locator_set_name_set) {
11558         errmsg ("itr-rloc is not set!");
11559         return -99;
11560     }
11561
11562     if (is_add && vec_len(locator_set_name) > 64) {
11563         errmsg ("itr-rloc locator-set name too long\n");
11564         vec_free(locator_set_name);
11565         return -99;
11566     }
11567
11568     M(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
11569     mp->is_add = is_add;
11570     if (is_add) {
11571       clib_memcpy (mp->locator_set_name , locator_set_name,
11572                    vec_len(locator_set_name));
11573     } else {
11574       memset(mp->locator_set_name, 0, sizeof(mp->locator_set_name));
11575     }
11576     vec_free (locator_set_name);
11577
11578     /* send it... */
11579     S;
11580
11581     /* Wait for a reply... */
11582     W;
11583
11584     /* NOTREACHED */
11585     return 0;
11586 }
11587
11588 static int
11589 lisp_locator_dump_send_msg(vat_main_t * vam, u32 locator_set_index, u8 filter)
11590 {
11591     vl_api_lisp_locator_dump_t *mp;
11592     f64 timeout = ~0;
11593
11594     M(LISP_LOCATOR_DUMP, lisp_locator_dump);
11595
11596     mp->locator_set_index = htonl(locator_set_index);
11597     mp->filter = filter;
11598
11599     /* send it... */
11600     S;
11601
11602     /* Use a control ping for synchronization */
11603     {
11604       vl_api_noprint_control_ping_t * mp;
11605       M(NOPRINT_CONTROL_PING, noprint_control_ping);
11606       S;
11607     }
11608     /* Wait for a reply... */
11609     W;
11610 }
11611
11612 static inline void
11613 clean_locator_set_message(vat_main_t * vam)
11614 {
11615     locator_set_msg_t * ls = 0;
11616
11617     vec_foreach (ls, vam->locator_set_msg) {
11618         vec_free(ls->locator_set_name);
11619     }
11620
11621     vec_free(vam->locator_set_msg);
11622 }
11623
11624 static int
11625 print_locator_in_locator_set(vat_main_t * vam, u8 filter)
11626 {
11627     locator_set_msg_t * ls;
11628     locator_msg_t * loc;
11629     u8 * tmp_str = 0;
11630     int i = 0, ret = 0;
11631
11632     vec_foreach(ls, vam->locator_set_msg) {
11633         ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11634         if (ret) {
11635             vec_free(vam->locator_msg);
11636             clean_locator_set_message(vam);
11637             return ret;
11638         }
11639
11640         tmp_str = format(0, "%=20s%=16d%s", ls->locator_set_name,
11641                          ls->locator_set_index,
11642                          vec_len(vam->locator_msg) ? "" : "\n");
11643         i = 0;
11644         vec_foreach(loc, vam->locator_msg) {
11645             if (i) {
11646                 tmp_str = format(tmp_str, "%=37s", " ");
11647             }
11648             if (loc->local) {
11649                 tmp_str = format(tmp_str, "%=16d%=16d%=16d\n",
11650                                  loc->sw_if_index,
11651                                  loc->priority,
11652                                  loc->weight);
11653             } else {
11654                 tmp_str = format(tmp_str, "%=16U%=16d%=16d\n",
11655                                  loc->is_ipv6 ? format_ip6_address :
11656                                  format_ip4_address,
11657                                  loc->ip_address,
11658                                  loc->priority,
11659                                  loc->weight);
11660             }
11661             i++;
11662         }
11663
11664         fformat(vam->ofp, "%s", tmp_str);
11665         vec_free(tmp_str);
11666         vec_free(vam->locator_msg);
11667     }
11668
11669     clean_locator_set_message(vam);
11670
11671     return ret;
11672 }
11673
11674 static int
11675 json_locator_in_locator_set(vat_main_t * vam, u8 filter)
11676 {
11677     locator_set_msg_t * ls;
11678     locator_msg_t * loc;
11679     vat_json_node_t * node = NULL;
11680     vat_json_node_t * locator_array;
11681     vat_json_node_t * locator;
11682     struct in6_addr ip6;
11683     struct in_addr ip4;
11684     int ret = 0;
11685
11686     if (!vec_len(vam->locator_set_msg)) {
11687         /* just print [] */
11688         vat_json_init_array(&vam->json_tree);
11689         vat_json_print(vam->ofp, &vam->json_tree);
11690         vam->json_tree.type = VAT_JSON_NONE;
11691         return ret;
11692     }
11693
11694     if (VAT_JSON_ARRAY != vam->json_tree.type) {
11695       ASSERT(VAT_JSON_NONE == vam->json_tree.type);
11696       vat_json_init_array(&vam->json_tree);
11697     }
11698
11699     vec_foreach(ls, vam->locator_set_msg) {
11700         ret = lisp_locator_dump_send_msg(vam, ls->locator_set_index, filter);
11701         if (ret) {
11702             vec_free(ls->locator_set_name);
11703             vec_free(vam->locator_msg);
11704             vec_free(vam->locator_set_msg);
11705             vat_json_free(&vam->json_tree);
11706             vam->json_tree.type = VAT_JSON_NONE;
11707             return ret;
11708         }
11709
11710         node = vat_json_array_add(&vam->json_tree);
11711         vat_json_init_object(node);
11712
11713         vat_json_object_add_uint(node, "locator-set-index",
11714                                  ls->locator_set_index);
11715         vat_json_object_add_string_copy(node, "locator-set",
11716                                         ls->locator_set_name);
11717         locator_array = vat_json_object_add_list(node, "locator");
11718         vec_foreach(loc, vam->locator_msg) {
11719             locator = vat_json_array_add(locator_array);
11720             vat_json_init_object(locator);
11721             if (loc->local) {
11722                 vat_json_object_add_uint(locator, "locator-index",
11723                                          loc->sw_if_index);
11724             } else {
11725                 if (loc->is_ipv6) {
11726                     clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
11727                     vat_json_object_add_ip6(locator, "locator", ip6);
11728                 } else {
11729                     clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
11730                     vat_json_object_add_ip4(locator, "locator", ip4);
11731                 }
11732             }
11733             vat_json_object_add_uint(locator, "priority", loc->priority);
11734             vat_json_object_add_uint(locator, "weight", loc->weight);
11735         }
11736
11737         vec_free(ls->locator_set_name);
11738         vec_free(vam->locator_msg);
11739     }
11740
11741     vat_json_print(vam->ofp, &vam->json_tree);
11742     vat_json_free(&vam->json_tree);
11743     vam->json_tree.type = VAT_JSON_NONE;
11744
11745     vec_free(vam->locator_set_msg);
11746
11747     return ret;
11748 }
11749
11750 static int
11751 get_locator_set_index_from_msg(vat_main_t * vam, u8 * locator_set,
11752                                u32 * locator_set_index)
11753 {
11754     locator_set_msg_t * ls;
11755     int ret = 0;
11756
11757     * locator_set_index = ~0;
11758
11759     if (!vec_len(vam->locator_set_msg)) {
11760       return ret;
11761     }
11762
11763     vec_foreach(ls, vam->locator_set_msg) {
11764         if (!strcmp((char *) locator_set, (char *) ls->locator_set_name)) {
11765             * locator_set_index = ls->locator_set_index;
11766             vec_free(vam->locator_set_msg);
11767             return ret;
11768         }
11769     }
11770
11771     vec_free(vam->locator_set_msg);
11772
11773     return ret;
11774 }
11775
11776 static int
11777 get_locator_set_index(vat_main_t * vam, u8 * locator_set,
11778                       u32 * locator_set_index)
11779 {
11780     vl_api_lisp_locator_set_dump_t *mp;
11781     f64 timeout = ~0;
11782
11783     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11784     /* send it... */
11785     S;
11786
11787    /* Use a control ping for synchronization */
11788    {
11789      vl_api_noprint_control_ping_t * mp;
11790      M(NOPRINT_CONTROL_PING, noprint_control_ping);
11791      S;
11792    }
11793
11794    vam->noprint_msg = 1;
11795     /* Wait for a reply... */
11796     W_L({
11797       get_locator_set_index_from_msg(vam, locator_set, locator_set_index);
11798       vam->noprint_msg = 0;
11799     })
11800
11801     /* NOTREACHED */
11802     return 0;
11803 }
11804
11805 static inline int
11806 lisp_locator_dump(vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
11807                   u8 filter)
11808 {
11809     int ret = 0;
11810
11811     ASSERT(vam);
11812
11813     if (!vam->json_output) {
11814       fformat(vam->ofp, "%=20s%=16s%=16s\n",
11815               "locator", "priority", "weight");
11816     }
11817
11818     if (locator_set) {
11819       ret = get_locator_set_index(vam, locator_set, &locator_set_index);
11820     }
11821
11822     if (!ret && ~0 == locator_set_index) {
11823       return -99;
11824     }
11825
11826     ret = lisp_locator_dump_send_msg(vam, locator_set_index, filter);
11827
11828     return ret;
11829 }
11830
11831 static int
11832 lisp_locator_set_dump(vat_main_t * vam, u8 filter)
11833 {
11834     vl_api_lisp_locator_set_dump_t *mp;
11835     f64 timeout = ~0;
11836
11837     if (!vam->json_output) {
11838         fformat(vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
11839                 "locator-set", "locator-set-index", "locator", "priority",
11840                 "weight");
11841     }
11842
11843     vam->noprint_msg = 1;
11844
11845     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11846
11847     mp->filter = filter;
11848
11849     /* send it... */
11850     S;
11851
11852    /* Use a control ping for synchronization */
11853    {
11854      vl_api_noprint_control_ping_t * mp;
11855      M(NOPRINT_CONTROL_PING, noprint_control_ping);
11856      S;
11857    }
11858
11859     /* Wait for a reply... */
11860     W_L({
11861       if (vam->noprint_msg) {
11862           if (!vam->json_output) {
11863               print_locator_in_locator_set(vam, filter);
11864           } else {
11865               json_locator_in_locator_set(vam, filter);
11866           }
11867       }
11868
11869       vam->noprint_msg = 0;
11870     });
11871
11872     /* NOTREACHED */
11873     return 0;
11874 }
11875
11876 static int
11877 api_lisp_locator_set_dump(vat_main_t *vam)
11878 {
11879     unformat_input_t * input = vam->input;
11880     vam->noprint_msg = 0;
11881     u32 locator_set_index = ~0;
11882     u8 locator_set_index_set = 0;
11883     u8 * locator_set = 0;
11884     u8 locator_set_set = 0;
11885     u8 filter = 0;
11886     int ret = 0;
11887
11888     /* Parse args required to build the message */
11889     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
11890         if (unformat(input, "locator-set-index %u", &locator_set_index)) {
11891             locator_set_index_set = 1;
11892         } else if (unformat(input, "locator-set %s", &locator_set)) {
11893             locator_set_set = 1;
11894         } else if (unformat(input, "local")) {
11895             filter = 1;
11896         } else if (unformat(input, "remote")) {
11897             filter = 2;
11898         } else {
11899             break;
11900         }
11901     }
11902
11903     if (locator_set_index_set && locator_set_set) {
11904         errmsg ("use only input parameter!\n");
11905         return -99;
11906     }
11907
11908     if (locator_set_index_set || locator_set_set) {
11909         ret = lisp_locator_dump(vam, locator_set_index, locator_set, filter);
11910     } else {
11911         ret = lisp_locator_set_dump(vam, filter);
11912     }
11913
11914     vec_free(locator_set);
11915
11916     return ret;
11917 }
11918
11919 static int
11920 api_lisp_eid_table_map_dump(vat_main_t *vam)
11921 {
11922     vl_api_lisp_eid_table_map_dump_t *mp;
11923     f64 timeout = ~0;
11924
11925     if (!vam->json_output) {
11926         fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
11927     }
11928
11929     M(LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
11930
11931     /* send it... */
11932     S;
11933
11934     /* Use a control ping for synchronization */
11935     {
11936         vl_api_control_ping_t * mp;
11937         M(CONTROL_PING, control_ping);
11938         S;
11939     }
11940     /* Wait for a reply... */
11941     W;
11942
11943     /* NOTREACHED */
11944     return 0;
11945 }
11946
11947 static int
11948 get_locator_set(vat_main_t * vam)
11949 {
11950     vl_api_lisp_locator_set_dump_t *mp;
11951     f64 timeout = ~0;
11952
11953     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
11954     /* send it... */
11955     S;
11956
11957    /* Use a control ping for synchronization */
11958    {
11959      vl_api_noprint_control_ping_t * mp;
11960      M(NOPRINT_CONTROL_PING, noprint_control_ping);
11961      S;
11962    }
11963
11964     /* Wait for a reply... */
11965     W;
11966
11967     /* NOTREACHED */
11968     return 0;
11969 }
11970
11971 static inline u8 *
11972 format_eid_for_eid_table(vat_main_t *vam, u8 * str, eid_table_t * eid_table,
11973                          int *ret)
11974 {
11975     u8 * (*format_eid)(u8 *, va_list *) = 0;
11976
11977     ASSERT(vam != NULL);
11978     ASSERT(eid_table != NULL);
11979
11980     if (ret) {
11981         *ret = 0;
11982     }
11983
11984     switch (eid_table->eid_type)
11985     {
11986       case 0:
11987       case 1:
11988         format_eid = (eid_table->eid_type ? format_ip6_address :
11989           format_ip4_address);
11990         str = format(0, "[%d] %U/%d",
11991                           clib_net_to_host_u32 (eid_table->vni),
11992                           format_eid, eid_table->eid, eid_table->eid_prefix_len);
11993         break;
11994       case 2:
11995         str = format(0, "[%d] %U",
11996                           clib_net_to_host_u32 (eid_table->vni),
11997                           format_ethernet_address, eid_table->eid);
11998         break;
11999       default:
12000         errmsg ("unknown EID type %d!", eid_table->eid_type);
12001         if (ret) {
12002             *ret = -99;
12003         }
12004         return 0;
12005     }
12006
12007     return str;
12008 }
12009
12010 static inline u8 *
12011 format_locator_set_for_eid_table(vat_main_t * vam, u8 * str,
12012                                  eid_table_t * eid_table)
12013 {
12014     locator_set_msg_t * ls = 0;
12015
12016     ASSERT(vam != NULL);
12017     ASSERT(eid_table != NULL);
12018
12019     if (eid_table->is_local) {
12020         vec_foreach (ls, vam->locator_set_msg) {
12021             if (ls->locator_set_index == eid_table->locator_set_index) {
12022                 str = format(0, "local(%s)", ls->locator_set_name);
12023                 return str;
12024             }
12025         }
12026
12027         str = format(0, "local(N/A)");
12028     } else {
12029         str = format(0, "remote");
12030     }
12031
12032     return str;
12033 }
12034
12035 static inline u8 *
12036 format_locator_for_eid_table(vat_main_t * vam, u8 * str,
12037                              eid_table_t * eid_table)
12038 {
12039     locator_msg_t * loc = 0;
12040     int first_line = 1;
12041
12042     ASSERT(vam != NULL);
12043     ASSERT(eid_table != NULL);
12044
12045     vec_foreach(loc, vam->locator_msg) {
12046         if (!first_line) {
12047             if (loc->local) {
12048                 str = format(str, "%-55s%-d\n", " ", loc->sw_if_index);
12049             } else {
12050                 str = format(str, "%=55s%-U\n", " ",
12051                              loc->is_ipv6 ? format_ip6_address :
12052                              format_ip4_address,
12053                                loc->ip_address);
12054             }
12055
12056             continue;
12057         }
12058
12059         if (loc->local) {
12060             str = format(str, "%-30d%-20u%-u\n", loc->sw_if_index,
12061                          eid_table->ttl, eid_table->authoritative);
12062         } else {
12063             str = format(str, "%-30U%-20u%-u\n",
12064                          loc->is_ipv6 ? format_ip6_address :
12065                          format_ip4_address,
12066                          loc->ip_address, eid_table->ttl,
12067                          eid_table->authoritative);
12068         }
12069         first_line = 0;
12070     }
12071
12072     return str;
12073 }
12074
12075 static int
12076 print_lisp_eid_table_dump(vat_main_t * vam)
12077 {
12078     eid_table_t * eid_table = 0;
12079     u8 * tmp_str = 0, * tmp_str2 = 0;
12080     int ret = 0;
12081
12082     ASSERT(vam != NULL);
12083
12084     ret = get_locator_set(vam);
12085     if (ret) {
12086         vec_free(vam->eid_tables);
12087         return ret;
12088     }
12089
12090     fformat(vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
12091                                                    "ttl", "authoritative");
12092
12093     vec_foreach(eid_table, vam->eid_tables) {
12094         ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12095         if (ret) {
12096           vec_free(vam->locator_msg);
12097           clean_locator_set_message(vam);
12098           vec_free(vam->eid_tables);
12099           return ret;
12100         }
12101
12102         tmp_str2 = format_eid_for_eid_table(vam, tmp_str2, eid_table, &ret);
12103         if (ret) {
12104           vec_free(vam->locator_msg);
12105           clean_locator_set_message(vam);
12106           vec_free(vam->eid_tables);
12107           return ret;
12108         }
12109
12110         tmp_str = format(0, "%-35s", tmp_str2);
12111         vec_free(tmp_str2);
12112
12113         tmp_str2 = format_locator_set_for_eid_table(vam, tmp_str2, eid_table);
12114         tmp_str = format(tmp_str, "%-20s", tmp_str2);
12115         vec_free(tmp_str2);
12116
12117         tmp_str2 = format_locator_for_eid_table(vam, tmp_str2, eid_table);
12118         tmp_str = format(tmp_str, "%-s", tmp_str2);
12119         vec_free(tmp_str2);
12120
12121         fformat(vam->ofp, "%s", tmp_str);
12122         vec_free(tmp_str);
12123         vec_free(vam->locator_msg);
12124     }
12125
12126     clean_locator_set_message(vam);
12127     vec_free(vam->eid_tables);
12128
12129     return ret;
12130 }
12131
12132 static inline void
12133 json_locator_set_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12134                                eid_table_t * eid_table)
12135 {
12136     locator_set_msg_t * ls = 0;
12137     u8 * s = 0;
12138
12139     ASSERT(vam != NULL);
12140     ASSERT(node != NULL);
12141     ASSERT(eid_table != NULL);
12142
12143     if (eid_table->is_local) {
12144         vec_foreach (ls, vam->locator_set_msg) {
12145             if (ls->locator_set_index == eid_table->locator_set_index) {
12146                 vat_json_object_add_string_copy(node, "locator-set",
12147                                                 ls->locator_set_name);
12148                 return;
12149             }
12150         }
12151
12152         s = format(0, "N/A");
12153         vec_add1(s, 0);
12154         vat_json_object_add_string_copy(node, "locator-set", s);
12155         vec_free(s);
12156     } else {
12157         s = format(0, "remote");
12158         vec_add1(s, 0);
12159         vat_json_object_add_string_copy(node, "locator-set", s);
12160         vec_free(s);
12161     }
12162 }
12163
12164 static inline int
12165 json_eid_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12166                        eid_table_t * eid_table)
12167 {
12168     u8 * s = 0;
12169     struct in6_addr ip6;
12170     struct in_addr ip4;
12171
12172     ASSERT(vam != NULL);
12173     ASSERT(node != NULL);
12174     ASSERT(eid_table != NULL);
12175
12176     switch (eid_table->eid_type)
12177     {
12178       case 0:
12179         clib_memcpy(&ip4, eid_table->eid, sizeof(ip4));
12180         vat_json_object_add_ip4(node, "eid", ip4);
12181         vat_json_object_add_uint(node, "eid-prefix-len",
12182                                  eid_table->eid_prefix_len);
12183         break;
12184       case 1:
12185         clib_memcpy(&ip6, eid_table->eid, sizeof(ip6));
12186         vat_json_object_add_ip6(node, "eid", ip6);
12187         vat_json_object_add_uint(node, "eid-prefix-len",
12188                                  eid_table->eid_prefix_len);
12189         break;
12190       case 2:
12191         s = format (0, "%U", format_ethernet_address, eid_table->eid);
12192         vec_add1(s, 0);
12193         vat_json_object_add_string_copy(node, "eid", s);
12194         vec_free(s);
12195         break;
12196       default:
12197         errmsg ("unknown EID type %d!", eid_table->eid_type);
12198         return -99;
12199     }
12200
12201     return 0;
12202 }
12203
12204 static inline void
12205 json_locator_for_eid_table(vat_main_t * vam, vat_json_node_t * node,
12206                            eid_table_t * eid_table)
12207 {
12208     locator_msg_t * loc = 0;
12209     vat_json_node_t * locator_array = 0;
12210     vat_json_node_t * locator = 0;
12211     struct in6_addr ip6;
12212     struct in_addr ip4;
12213
12214     ASSERT(vam != NULL);
12215     ASSERT(node != NULL);
12216     ASSERT(eid_table != NULL);
12217
12218     locator_array = vat_json_object_add_list(node, "locator");
12219     vec_foreach(loc, vam->locator_msg) {
12220         locator = vat_json_array_add(locator_array);
12221         vat_json_init_object(locator);
12222         if (loc->local) {
12223             vat_json_object_add_uint(locator, "locator-index",
12224                                      loc->sw_if_index);
12225         } else {
12226             if (loc->is_ipv6) {
12227                 clib_memcpy(&ip6, loc->ip_address, sizeof(ip6));
12228                 vat_json_object_add_ip6(locator, "locator", ip6);
12229             } else {
12230                 clib_memcpy(&ip4, loc->ip_address, sizeof(ip4));
12231                 vat_json_object_add_ip4(locator, "locator", ip4);
12232             }
12233         }
12234     }
12235 }
12236
12237 static int
12238 json_lisp_eid_table_dump(vat_main_t * vam)
12239 {
12240     eid_table_t * eid_table;
12241     vat_json_node_t * node = 0;
12242     int ret = 0;
12243
12244     ASSERT(vam != NULL);
12245
12246     ret = get_locator_set(vam);
12247     if (ret) {
12248         vec_free(vam->eid_tables);
12249         return ret;
12250     }
12251
12252     if (!vec_len(vam->eid_tables)) {
12253         /* just print [] */
12254         vat_json_init_array(&vam->json_tree);
12255         vat_json_print(vam->ofp, &vam->json_tree);
12256         vam->json_tree.type = VAT_JSON_NONE;
12257         return ret;
12258     }
12259
12260     if (VAT_JSON_ARRAY != vam->json_tree.type) {
12261       ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12262       vat_json_init_array(&vam->json_tree);
12263     }
12264
12265     vec_foreach(eid_table, vam->eid_tables) {
12266         ret = lisp_locator_dump_send_msg(vam, eid_table->locator_set_index, 0);
12267         if (ret) {
12268             vec_free(vam->locator_msg);
12269             vec_free(vam->eid_tables);
12270             clean_locator_set_message(vam);
12271             vat_json_free(&vam->json_tree);
12272             vam->json_tree.type = VAT_JSON_NONE;
12273             return ret;
12274         }
12275
12276         node = vat_json_array_add(&vam->json_tree);
12277         vat_json_init_object(node);
12278
12279         vat_json_object_add_uint(node, "vni", eid_table->vni);
12280
12281         json_locator_set_for_eid_table(vam, node, eid_table);
12282         ret = json_eid_for_eid_table(vam, node, eid_table);
12283         if (ret) {
12284             vec_free(vam->locator_msg);
12285             vec_free(vam->eid_tables);
12286             clean_locator_set_message(vam);
12287             vat_json_free(&vam->json_tree);
12288             vam->json_tree.type = VAT_JSON_NONE;
12289             return ret;
12290         }
12291
12292         json_locator_for_eid_table(vam, node, eid_table);
12293
12294         vat_json_object_add_uint(node, "ttl", eid_table->ttl);
12295         vat_json_object_add_uint(node, "authoritative",
12296                                 eid_table->authoritative);
12297
12298         vec_free(vam->locator_msg);
12299     }
12300
12301     vat_json_print(vam->ofp, &vam->json_tree);
12302     vat_json_free(&vam->json_tree);
12303     vam->json_tree.type = VAT_JSON_NONE;
12304
12305     clean_locator_set_message(vam);
12306     vec_free(vam->eid_tables);
12307
12308     return ret;
12309 }
12310
12311 static int
12312 api_lisp_eid_table_dump(vat_main_t *vam)
12313 {
12314     unformat_input_t * i = vam->input;
12315     vl_api_lisp_eid_table_dump_t *mp;
12316     f64 timeout = ~0;
12317     struct in_addr ip4;
12318     struct in6_addr ip6;
12319     u8 mac[6];
12320     u8 eid_type = ~0, eid_set = 0;
12321     u32 prefix_length = ~0, t, vni = 0;
12322     u8 filter = 0;
12323
12324     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12325         if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t)) {
12326             eid_set = 1;
12327             eid_type = 0;
12328             prefix_length = t;
12329         } else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t)) {
12330             eid_set = 1;
12331             eid_type = 1;
12332             prefix_length = t;
12333         } else if (unformat (i, "eid %U", unformat_ethernet_address, mac)) {
12334             eid_set = 1;
12335             eid_type = 2;
12336         } else if (unformat (i, "vni %d", &t)) {
12337             vni = t;
12338         } else if (unformat (i, "local")) {
12339             filter = 1;
12340         } else if (unformat (i, "remote")) {
12341             filter = 2;
12342         } else {
12343             errmsg ("parse error '%U'", format_unformat_error, i);
12344             return -99;
12345         }
12346     }
12347
12348     M(LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
12349
12350     mp->filter = filter;
12351     if (eid_set) {
12352         mp->eid_set = 1;
12353         mp->vni = htonl (vni);
12354         mp->eid_type = eid_type;
12355         switch (eid_type) {
12356         case 0:
12357             mp->prefix_length = prefix_length;
12358             clib_memcpy (mp->eid, &ip4, sizeof (ip4));
12359             break;
12360         case 1:
12361             mp->prefix_length = prefix_length;
12362             clib_memcpy (mp->eid, &ip6, sizeof (ip6));
12363             break;
12364         case 2:
12365             clib_memcpy (mp->eid, mac, sizeof (mac));
12366             break;
12367         default:
12368             errmsg ("unknown EID type %d!", eid_type);
12369             return -99;
12370         }
12371     }
12372
12373     vam->noprint_msg = 1;
12374
12375     /* send it... */
12376     S;
12377
12378     /* Use a control ping for synchronization */
12379     {
12380         vl_api_noprint_control_ping_t * mp;
12381         M(NOPRINT_CONTROL_PING, noprint_control_ping);
12382         S;
12383     }
12384
12385     /* Wait for a reply... */
12386     W_L({
12387       if (vam->noprint_msg) {
12388           if (!vam->json_output) {
12389               vam->retval = print_lisp_eid_table_dump(vam);
12390           } else {
12391               vam->retval = json_lisp_eid_table_dump(vam);
12392           }
12393       }
12394
12395       vam->noprint_msg = 0;
12396     });
12397
12398     /* NOTREACHED */
12399     return 0;
12400 }
12401
12402 static int
12403 api_lisp_gpe_tunnel_dump(vat_main_t *vam)
12404 {
12405     vl_api_lisp_gpe_tunnel_dump_t *mp;
12406     f64 timeout = ~0;
12407
12408     if (!vam->json_output) {
12409         fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
12410                 "%=16s%=16s%=16s%=16s%=16s\n",
12411                 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
12412                 "Decap next", "Lisp version", "Flags", "Next protocol",
12413                 "ver_res", "res", "iid");
12414     }
12415
12416     M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
12417     /* send it... */
12418     S;
12419
12420     /* Use a control ping for synchronization */
12421     {
12422         vl_api_control_ping_t * mp;
12423         M(CONTROL_PING, control_ping);
12424         S;
12425     }
12426     /* Wait for a reply... */
12427     W;
12428
12429     /* NOTREACHED */
12430     return 0;
12431 }
12432
12433 static int
12434 api_lisp_map_resolver_dump(vat_main_t *vam)
12435 {
12436     vl_api_lisp_map_resolver_dump_t *mp;
12437     f64 timeout = ~0;
12438
12439     if (!vam->json_output) {
12440         fformat(vam->ofp, "%=20s\n",
12441                 "Map resolver");
12442     }
12443
12444     M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
12445     /* send it... */
12446     S;
12447
12448     /* Use a control ping for synchronization */
12449     {
12450         vl_api_control_ping_t * mp;
12451         M(CONTROL_PING, control_ping);
12452         S;
12453     }
12454     /* Wait for a reply... */
12455     W;
12456
12457     /* NOTREACHED */
12458     return 0;
12459 }
12460
12461 static int
12462 api_show_lisp_status(vat_main_t *vam)
12463 {
12464     vl_api_show_lisp_status_t *mp;
12465     f64 timeout = ~0;
12466
12467     if (!vam->json_output) {
12468         fformat(vam->ofp, "%-20s%-16s\n",
12469                 "lisp status", "locator-set");
12470     }
12471
12472     M(SHOW_LISP_STATUS, show_lisp_status);
12473     /* send it... */
12474     S;
12475     /* Wait for a reply... */
12476     W;
12477
12478     /* NOTREACHED */
12479     return 0;
12480 }
12481
12482 static int
12483 api_lisp_get_map_request_itr_rlocs(vat_main_t *vam)
12484 {
12485     vl_api_lisp_get_map_request_itr_rlocs_t *mp;
12486     f64 timeout = ~0;
12487
12488     if (!vam->json_output) {
12489         fformat(vam->ofp, "%=20s\n",
12490                 "itr-rlocs:");
12491     }
12492
12493     M(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
12494     /* send it... */
12495     S;
12496     /* Wait for a reply... */
12497     W;
12498
12499     /* NOTREACHED */
12500     return 0;
12501 }
12502
12503 static int
12504 api_af_packet_create (vat_main_t * vam)
12505 {
12506     unformat_input_t * i = vam->input;
12507     vl_api_af_packet_create_t * mp;
12508     f64 timeout;
12509     u8 * host_if_name = 0;
12510     u8 hw_addr[6];
12511     u8 random_hw_addr = 1;
12512
12513     memset (hw_addr, 0, sizeof (hw_addr));
12514
12515     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12516         if (unformat (i, "name %s", &host_if_name))
12517             vec_add1 (host_if_name, 0);
12518         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12519             random_hw_addr = 0;
12520         else
12521           break;
12522     }
12523
12524     if (!vec_len (host_if_name)) {
12525         errmsg ("host-interface name must be specified");
12526         return -99;
12527     }
12528
12529     if (vec_len (host_if_name) > 64) {
12530         errmsg ("host-interface name too long");
12531         return -99;
12532     }
12533
12534     M(AF_PACKET_CREATE, af_packet_create);
12535
12536     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12537     clib_memcpy (mp->hw_addr, hw_addr, 6);
12538     mp->use_random_hw_addr = random_hw_addr;
12539     vec_free (host_if_name);
12540
12541     S; W2(fprintf(vam->ofp," new sw_if_index = %d ", vam->sw_if_index));
12542     /* NOTREACHED */
12543     return 0;
12544 }
12545
12546 static int
12547 api_af_packet_delete (vat_main_t * vam)
12548 {
12549     unformat_input_t * i = vam->input;
12550     vl_api_af_packet_delete_t * mp;
12551     f64 timeout;
12552     u8 * host_if_name = 0;
12553
12554     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12555         if (unformat (i, "name %s", &host_if_name))
12556             vec_add1 (host_if_name, 0);
12557         else
12558           break;
12559     }
12560
12561     if (!vec_len (host_if_name)) {
12562         errmsg ("host-interface name must be specified");
12563         return -99;
12564     }
12565
12566     if (vec_len (host_if_name) > 64) {
12567         errmsg ("host-interface name too long");
12568         return -99;
12569     }
12570
12571     M(AF_PACKET_DELETE, af_packet_delete);
12572
12573     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
12574     vec_free (host_if_name);
12575
12576     S; W;
12577     /* NOTREACHED */
12578     return 0;
12579 }
12580
12581 static int
12582 api_policer_add_del (vat_main_t * vam)
12583 {
12584     unformat_input_t * i = vam->input;
12585     vl_api_policer_add_del_t * mp;
12586     f64 timeout;
12587     u8 is_add = 1;
12588     u8 * name = 0;
12589     u32 cir = 0;
12590     u32 eir = 0;
12591     u64 cb = 0;
12592     u64 eb = 0;
12593     u8 rate_type = 0;
12594     u8 round_type = 0;
12595     u8 type = 0;
12596     u8 color_aware = 0;
12597     sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
12598
12599     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12600         if (unformat (i, "del"))
12601             is_add = 0;
12602         else if (unformat (i, "name %s", &name))
12603             vec_add1 (name, 0);
12604         else if (unformat (i, "cir %u", &cir))
12605             ;
12606         else if (unformat (i, "eir %u", &eir))
12607             ;
12608         else if (unformat (i, "cb %u", &cb))
12609             ;
12610         else if (unformat (i, "eb %u", &eb))
12611             ;
12612         else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
12613                            &rate_type))
12614             ;
12615         else if (unformat (i, "round_type %U", unformat_policer_round_type,
12616                            &round_type))
12617             ;
12618         else if (unformat (i, "type %U", unformat_policer_type, &type))
12619             ;
12620         else if (unformat (i, "conform_action %U", unformat_policer_action_type,
12621                            &conform_action))
12622             ;
12623         else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
12624                            &exceed_action))
12625             ;
12626         else if (unformat (i, "violate_action %U", unformat_policer_action_type,
12627                            &violate_action))
12628             ;
12629         else if (unformat (i, "color-aware"))
12630             color_aware = 1;
12631         else
12632           break;
12633     }
12634
12635     if (!vec_len (name)) {
12636         errmsg ("policer name must be specified");
12637         return -99;
12638     }
12639
12640     if (vec_len (name) > 64) {
12641         errmsg ("policer name too long");
12642         return -99;
12643     }
12644
12645     M(POLICER_ADD_DEL, policer_add_del);
12646
12647     clib_memcpy (mp->name, name, vec_len (name));
12648     vec_free (name);
12649     mp->is_add = is_add;
12650     mp->cir = cir;
12651     mp->eir = eir;
12652     mp->cb = cb;
12653     mp->eb = eb;
12654     mp->rate_type = rate_type;
12655     mp->round_type = round_type;
12656     mp->type = type;
12657     mp->conform_action_type = conform_action.action_type;
12658     mp->conform_dscp = conform_action.dscp;
12659     mp->exceed_action_type = exceed_action.action_type;
12660     mp->exceed_dscp = exceed_action.dscp;
12661     mp->violate_action_type = violate_action.action_type;
12662     mp->violate_dscp = violate_action.dscp;
12663     mp->color_aware = color_aware;
12664
12665     S; W;
12666     /* NOTREACHED */
12667     return 0;
12668 }
12669
12670 static int
12671 api_policer_dump(vat_main_t *vam)
12672 {
12673     unformat_input_t * i = vam->input;
12674     vl_api_policer_dump_t *mp;
12675     f64 timeout = ~0;
12676     u8 *match_name = 0;
12677     u8 match_name_valid = 0;
12678
12679     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12680         if (unformat (i, "name %s", &match_name)) {
12681             vec_add1 (match_name, 0);
12682             match_name_valid = 1;
12683         } else
12684             break;
12685     }
12686
12687     M(POLICER_DUMP, policer_dump);
12688     mp->match_name_valid = match_name_valid;
12689     clib_memcpy (mp->match_name, match_name, vec_len (match_name));
12690     vec_free (match_name);
12691     /* send it... */
12692     S;
12693
12694     /* Use a control ping for synchronization */
12695     {
12696         vl_api_control_ping_t * mp;
12697         M(CONTROL_PING, control_ping);
12698         S;
12699     }
12700     /* Wait for a reply... */
12701     W;
12702
12703     /* NOTREACHED */
12704     return 0;
12705 }
12706
12707 static int
12708 api_policer_classify_set_interface (vat_main_t * vam)
12709 {
12710     unformat_input_t * i = vam->input;
12711     vl_api_policer_classify_set_interface_t *mp;
12712     f64 timeout;
12713     u32 sw_if_index;
12714     int sw_if_index_set;
12715     u32 ip4_table_index = ~0;
12716     u32 ip6_table_index = ~0;
12717     u32 l2_table_index = ~0;
12718     u8 is_add = 1;
12719
12720     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12721         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
12722             sw_if_index_set = 1;
12723         else if (unformat (i, "sw_if_index %d", &sw_if_index))
12724             sw_if_index_set = 1;
12725         else if (unformat (i, "del"))
12726             is_add = 0;
12727         else if (unformat (i, "ip4-table %d", &ip4_table_index))
12728             ;
12729         else if (unformat (i, "ip6-table %d", &ip6_table_index))
12730             ;
12731         else if (unformat (i, "l2-table %d", &l2_table_index))
12732             ;
12733         else {
12734             clib_warning ("parse error '%U'", format_unformat_error, i);
12735             return -99;
12736         }
12737     }
12738
12739     if (sw_if_index_set == 0) {
12740         errmsg ("missing interface name or sw_if_index\n");
12741         return -99;
12742     }
12743
12744     M(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
12745
12746     mp->sw_if_index = ntohl(sw_if_index);
12747     mp->ip4_table_index = ntohl(ip4_table_index);
12748     mp->ip6_table_index = ntohl(ip6_table_index);
12749     mp->l2_table_index = ntohl(l2_table_index);
12750     mp->is_add = is_add;
12751
12752     S; W;
12753     /* NOTREACHED */
12754     return 0;
12755 }
12756
12757 static int
12758 api_policer_classify_dump(vat_main_t *vam)
12759 {
12760     unformat_input_t * i = vam->input;
12761     vl_api_policer_classify_dump_t *mp;
12762     f64 timeout = ~0;
12763     u8 type = POLICER_CLASSIFY_N_TABLES;
12764
12765     if (unformat (i, "type %U", unformat_classify_table_type, &type))
12766         ;
12767     else {
12768         errmsg ("classify table type must be specified\n");
12769         return -99;
12770     }
12771
12772     if (!vam->json_output) {
12773         fformat(vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
12774     }
12775
12776     M(POLICER_CLASSIFY_DUMP, policer_classify_dump);
12777     mp->type = type;
12778     /* send it... */
12779     S;
12780
12781     /* Use a control ping for synchronization */
12782     {
12783         vl_api_control_ping_t * mp;
12784         M(CONTROL_PING, control_ping);
12785         S;
12786     }
12787     /* Wait for a reply... */
12788     W;
12789
12790     /* NOTREACHED */
12791     return 0;
12792 }
12793
12794 static int
12795 api_netmap_create (vat_main_t * vam)
12796 {
12797     unformat_input_t * i = vam->input;
12798     vl_api_netmap_create_t * mp;
12799     f64 timeout;
12800     u8 * if_name = 0;
12801     u8 hw_addr[6];
12802     u8 random_hw_addr = 1;
12803     u8 is_pipe = 0;
12804     u8 is_master = 0;
12805
12806     memset (hw_addr, 0, sizeof (hw_addr));
12807
12808     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12809         if (unformat (i, "name %s", &if_name))
12810             vec_add1 (if_name, 0);
12811         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
12812             random_hw_addr = 0;
12813         else if (unformat (i, "pipe"))
12814             is_pipe = 1;
12815         else if (unformat (i, "master"))
12816             is_master = 1;
12817         else if (unformat (i, "slave"))
12818             is_master = 0;
12819         else
12820           break;
12821     }
12822
12823     if (!vec_len (if_name)) {
12824         errmsg ("interface name must be specified");
12825         return -99;
12826     }
12827
12828     if (vec_len (if_name) > 64) {
12829         errmsg ("interface name too long");
12830         return -99;
12831     }
12832
12833     M(NETMAP_CREATE, netmap_create);
12834
12835     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
12836     clib_memcpy (mp->hw_addr, hw_addr, 6);
12837     mp->use_random_hw_addr = random_hw_addr;
12838     mp->is_pipe = is_pipe;
12839     mp->is_master = is_master;
12840     vec_free (if_name);
12841
12842     S; W;
12843     /* NOTREACHED */
12844     return 0;
12845 }
12846
12847 static int
12848 api_netmap_delete (vat_main_t * vam)
12849 {
12850     unformat_input_t * i = vam->input;
12851     vl_api_netmap_delete_t * mp;
12852     f64 timeout;
12853     u8 * if_name = 0;
12854
12855     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
12856         if (unformat (i, "name %s", &if_name))
12857             vec_add1 (if_name, 0);
12858         else
12859             break;
12860     }
12861
12862     if (!vec_len (if_name)) {
12863         errmsg ("interface name must be specified");
12864         return -99;
12865     }
12866
12867     if (vec_len (if_name) > 64) {
12868         errmsg ("interface name too long");
12869         return -99;
12870     }
12871
12872     M(NETMAP_DELETE, netmap_delete);
12873
12874     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
12875     vec_free (if_name);
12876
12877     S; W;
12878     /* NOTREACHED */
12879     return 0;
12880 }
12881
12882 static void vl_api_mpls_gre_tunnel_details_t_handler
12883 (vl_api_mpls_gre_tunnel_details_t * mp)
12884 {
12885     vat_main_t * vam = &vat_main;
12886     i32 i;
12887     i32 len = ntohl(mp->nlabels);
12888
12889     if (mp->l2_only == 0) {
12890         fformat(vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
12891                 ntohl(mp->tunnel_index),
12892                 format_ip4_address, &mp->tunnel_src,
12893                 format_ip4_address, &mp->tunnel_dst,
12894                 format_ip4_address, &mp->intfc_address,
12895                 ntohl(mp->mask_width));
12896         for (i = 0; i < len; i++) {
12897             fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12898         }
12899         fformat(vam->ofp, "\n");
12900         fformat(vam->ofp, "      inner fib index %d, outer fib index %d\n",
12901                 ntohl(mp->inner_fib_index), ntohl(mp->outer_fib_index));
12902     } else {
12903         fformat(vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
12904                 ntohl(mp->tunnel_index),
12905                 format_ip4_address, &mp->tunnel_src,
12906                 format_ip4_address, &mp->tunnel_dst,
12907                 format_ip4_address, &mp->intfc_address);
12908         for (i = 0; i < len; i++) {
12909             fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12910         }
12911         fformat(vam->ofp, "\n");
12912         fformat(vam->ofp, "      l2 interface %d, outer fib index %d\n",
12913                 ntohl(mp->hw_if_index), ntohl(mp->outer_fib_index));
12914     }
12915 }
12916
12917 static void vl_api_mpls_gre_tunnel_details_t_handler_json
12918 (vl_api_mpls_gre_tunnel_details_t * mp)
12919 {
12920     vat_main_t * vam = &vat_main;
12921     vat_json_node_t *node = NULL;
12922     struct in_addr ip4;
12923     i32 i;
12924     i32 len = ntohl(mp->nlabels);
12925
12926     if (VAT_JSON_ARRAY != vam->json_tree.type) {
12927         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
12928         vat_json_init_array(&vam->json_tree);
12929     }
12930     node = vat_json_array_add(&vam->json_tree);
12931
12932     vat_json_init_object(node);
12933     vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
12934     clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
12935     vat_json_object_add_ip4(node, "intfc_address", ip4);
12936     vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
12937     vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
12938     vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
12939     vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
12940     vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
12941     clib_memcpy(&ip4, &(mp->tunnel_src), sizeof(ip4));
12942     vat_json_object_add_ip4(node, "tunnel_src", ip4);
12943     clib_memcpy(&ip4, &(mp->tunnel_dst), sizeof(ip4));
12944     vat_json_object_add_ip4(node, "tunnel_dst", ip4);
12945     vat_json_object_add_uint(node, "outer_fib_index", ntohl(mp->outer_fib_index));
12946     vat_json_object_add_uint(node, "label_count", len);
12947     for (i = 0; i < len; i++) {
12948         vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
12949     }
12950 }
12951
12952 static int api_mpls_gre_tunnel_dump (vat_main_t * vam)
12953 {
12954     vl_api_mpls_gre_tunnel_dump_t *mp;
12955     f64 timeout;
12956     i32 index = -1;
12957
12958     /* Parse args required to build the message */
12959     while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
12960         if (!unformat (vam->input, "tunnel_index %d", &index)) {
12961             index = -1;
12962             break;
12963         }
12964     }
12965
12966     fformat(vam->ofp, "  tunnel_index %d\n", index);
12967
12968     M(MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
12969     mp->tunnel_index = htonl(index);
12970     S;
12971
12972     /* Use a control ping for synchronization */
12973     {
12974         vl_api_control_ping_t * mp;
12975         M(CONTROL_PING, control_ping);
12976         S;
12977     }
12978     W;
12979 }
12980
12981 static void vl_api_mpls_eth_tunnel_details_t_handler
12982 (vl_api_mpls_eth_tunnel_details_t * mp)
12983 {
12984     vat_main_t * vam = &vat_main;
12985     i32 i;
12986     i32 len = ntohl(mp->nlabels);
12987
12988     fformat(vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
12989             ntohl(mp->tunnel_index),
12990             format_ethernet_address, &mp->tunnel_dst_mac,
12991             format_ip4_address, &mp->intfc_address,
12992             ntohl(mp->mask_width));
12993     for (i = 0; i < len; i++) {
12994         fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
12995     }
12996     fformat(vam->ofp, "\n");
12997     fformat(vam->ofp, "      tx on %d, rx fib index %d\n",
12998             ntohl(mp->tx_sw_if_index),
12999             ntohl(mp->inner_fib_index));
13000 }
13001
13002 static void vl_api_mpls_eth_tunnel_details_t_handler_json
13003 (vl_api_mpls_eth_tunnel_details_t * mp)
13004 {
13005     vat_main_t * vam = &vat_main;
13006     vat_json_node_t *node = NULL;
13007     struct in_addr ip4;
13008     i32 i;
13009     i32 len = ntohl(mp->nlabels);
13010
13011     if (VAT_JSON_ARRAY != vam->json_tree.type) {
13012         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13013         vat_json_init_array(&vam->json_tree);
13014     }
13015     node = vat_json_array_add(&vam->json_tree);
13016
13017     vat_json_init_object(node);
13018     vat_json_object_add_uint(node, "tunnel_index", ntohl(mp->tunnel_index));
13019     clib_memcpy(&ip4, &(mp->intfc_address), sizeof(ip4));
13020     vat_json_object_add_ip4(node, "intfc_address", ip4);
13021     vat_json_object_add_uint(node, "inner_fib_index", ntohl(mp->inner_fib_index));
13022     vat_json_object_add_uint(node, "mask_width", ntohl(mp->mask_width));
13023     vat_json_object_add_uint(node, "encap_index", ntohl(mp->encap_index));
13024     vat_json_object_add_uint(node, "hw_if_index", ntohl(mp->hw_if_index));
13025     vat_json_object_add_uint(node, "l2_only", ntohl(mp->l2_only));
13026     vat_json_object_add_string_copy(node, "tunnel_dst_mac",
13027             format(0, "%U", format_ethernet_address, &mp->tunnel_dst_mac));
13028     vat_json_object_add_uint(node, "tx_sw_if_index", ntohl(mp->tx_sw_if_index));
13029     vat_json_object_add_uint(node, "label_count", len);
13030     for (i = 0; i < len; i++) {
13031         vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13032     }
13033 }
13034
13035 static int api_mpls_eth_tunnel_dump (vat_main_t * vam)
13036 {
13037     vl_api_mpls_eth_tunnel_dump_t *mp;
13038     f64 timeout;
13039     i32 index = -1;
13040
13041     /* Parse args required to build the message */
13042     while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT) {
13043         if (!unformat (vam->input, "tunnel_index %d", &index)) {
13044             index = -1;
13045             break;
13046         }
13047     }
13048
13049     fformat(vam->ofp, "  tunnel_index %d\n", index);
13050
13051     M(MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
13052     mp->tunnel_index = htonl(index);
13053     S;
13054
13055     /* Use a control ping for synchronization */
13056     {
13057         vl_api_control_ping_t * mp;
13058         M(CONTROL_PING, control_ping);
13059         S;
13060     }
13061     W;
13062 }
13063
13064 static void vl_api_mpls_fib_encap_details_t_handler
13065 (vl_api_mpls_fib_encap_details_t * mp)
13066 {
13067     vat_main_t * vam = &vat_main;
13068     i32 i;
13069     i32 len = ntohl(mp->nlabels);
13070
13071     fformat(vam->ofp, "table %d, dest %U, label ",
13072             ntohl(mp->fib_index),
13073             format_ip4_address, &mp->dest,
13074             len);
13075     for (i = 0; i < len; i++) {
13076         fformat(vam->ofp, "%u ", ntohl(mp->labels[i]));
13077     }
13078     fformat(vam->ofp, "\n");
13079 }
13080
13081 static void vl_api_mpls_fib_encap_details_t_handler_json
13082 (vl_api_mpls_fib_encap_details_t * mp)
13083 {
13084     vat_main_t * vam = &vat_main;
13085     vat_json_node_t *node = NULL;
13086     i32 i;
13087     i32 len = ntohl(mp->nlabels);
13088     struct in_addr ip4;
13089
13090     if (VAT_JSON_ARRAY != vam->json_tree.type) {
13091         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13092         vat_json_init_array(&vam->json_tree);
13093     }
13094     node = vat_json_array_add(&vam->json_tree);
13095
13096     vat_json_init_object(node);
13097     vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13098     vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13099     clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13100     vat_json_object_add_ip4(node, "dest", ip4);
13101     vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13102     vat_json_object_add_uint(node, "label_count", len);
13103     for (i = 0; i < len; i++) {
13104         vat_json_object_add_uint(node, "label", ntohl(mp->labels[i]));
13105     }
13106 }
13107
13108 static int api_mpls_fib_encap_dump (vat_main_t * vam)
13109 {
13110     vl_api_mpls_fib_encap_dump_t *mp;
13111     f64 timeout;
13112
13113     M(MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
13114     S;
13115
13116     /* Use a control ping for synchronization */
13117     {
13118         vl_api_control_ping_t * mp;
13119         M(CONTROL_PING, control_ping);
13120         S;
13121     }
13122     W;
13123 }
13124
13125 static void vl_api_mpls_fib_decap_details_t_handler
13126 (vl_api_mpls_fib_decap_details_t * mp)
13127 {
13128     vat_main_t * vam = &vat_main;
13129
13130     fformat(vam->ofp, "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
13131             ntohl(mp->rx_table_id),
13132             ntohl(mp->tx_table_id),
13133             mp->swif_tag,
13134             ntohl(mp->label),
13135             ntohl(mp->s_bit));
13136 }
13137
13138 static void vl_api_mpls_fib_decap_details_t_handler_json
13139 (vl_api_mpls_fib_decap_details_t * mp)
13140 {
13141     vat_main_t * vam = &vat_main;
13142     vat_json_node_t *node = NULL;
13143     struct in_addr ip4;
13144
13145     if (VAT_JSON_ARRAY != vam->json_tree.type) {
13146         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
13147         vat_json_init_array(&vam->json_tree);
13148     }
13149     node = vat_json_array_add(&vam->json_tree);
13150
13151     vat_json_init_object(node);
13152     vat_json_object_add_uint(node, "table", ntohl(mp->fib_index));
13153     vat_json_object_add_uint(node, "entry_index", ntohl(mp->entry_index));
13154     clib_memcpy(&ip4, &(mp->dest), sizeof(ip4));
13155     vat_json_object_add_ip4(node, "dest", ip4);
13156     vat_json_object_add_uint(node, "s_bit", ntohl(mp->s_bit));
13157     vat_json_object_add_uint(node, "label", ntohl(mp->label));
13158     vat_json_object_add_uint(node, "rx_table_id", ntohl(mp->rx_table_id));
13159     vat_json_object_add_uint(node, "tx_table_id", ntohl(mp->tx_table_id));
13160     vat_json_object_add_string_copy(node, "swif_tag", mp->swif_tag);
13161 }
13162
13163 static int api_mpls_fib_decap_dump (vat_main_t * vam)
13164 {
13165     vl_api_mpls_fib_decap_dump_t *mp;
13166     f64 timeout;
13167
13168     M(MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
13169     S;
13170
13171     /* Use a control ping for synchronization */
13172     {
13173         vl_api_control_ping_t * mp;
13174         M(CONTROL_PING, control_ping);
13175         S;
13176     }
13177     W;
13178 }
13179
13180 int api_classify_table_ids (vat_main_t *vam)
13181 {
13182     vl_api_classify_table_ids_t *mp;
13183     f64 timeout;
13184
13185     /* Construct the API message */
13186     M(CLASSIFY_TABLE_IDS, classify_table_ids);
13187     mp->context = 0;
13188
13189     S; W;
13190     /* NOTREACHED */
13191     return 0;
13192 }
13193
13194 int api_classify_table_by_interface (vat_main_t *vam)
13195 {
13196     unformat_input_t * input = vam->input;
13197     vl_api_classify_table_by_interface_t *mp;
13198     f64 timeout;
13199
13200     u32 sw_if_index = ~0;
13201     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13202         if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
13203             ;
13204         else if (unformat (input, "sw_if_index %d", &sw_if_index))
13205             ;
13206         else
13207             break;
13208     }
13209     if (sw_if_index == ~0) {
13210         errmsg ("missing interface name or sw_if_index\n");
13211         return -99;
13212     }
13213
13214     /* Construct the API message */
13215     M(CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
13216     mp->context = 0;
13217     mp->sw_if_index = ntohl(sw_if_index);
13218
13219     S; W;
13220     /* NOTREACHED */
13221     return 0;
13222 }
13223
13224 int api_classify_table_info (vat_main_t *vam)
13225 {
13226     unformat_input_t * input = vam->input;
13227     vl_api_classify_table_info_t *mp;
13228     f64 timeout;
13229
13230     u32 table_id = ~0;
13231     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13232         if (unformat (input, "table_id %d", &table_id))
13233             ;
13234         else
13235             break;
13236     }
13237     if (table_id == ~0) {
13238         errmsg ("missing table id\n");
13239         return -99;
13240     }
13241
13242     /* Construct the API message */
13243     M(CLASSIFY_TABLE_INFO, classify_table_info);
13244     mp->context = 0;
13245     mp->table_id = ntohl(table_id);
13246
13247     S; W;
13248     /* NOTREACHED */
13249     return 0;
13250 }
13251
13252 int api_classify_session_dump (vat_main_t *vam)
13253 {
13254     unformat_input_t * input = vam->input;
13255     vl_api_classify_session_dump_t *mp;
13256     f64 timeout;
13257
13258     u32 table_id = ~0;
13259     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13260         if (unformat (input, "table_id %d", &table_id))
13261             ;
13262         else
13263             break;
13264     }
13265     if (table_id == ~0) {
13266         errmsg ("missing table id\n");
13267         return -99;
13268     }
13269
13270     /* Construct the API message */
13271     M(CLASSIFY_SESSION_DUMP, classify_session_dump);
13272     mp->context = 0;
13273     mp->table_id = ntohl(table_id);
13274     S;
13275
13276     /* Use a control ping for synchronization */
13277     {
13278         vl_api_control_ping_t * mp;
13279         M(CONTROL_PING, control_ping);
13280         S;
13281     }
13282     W;
13283     /* NOTREACHED */
13284     return 0;
13285 }
13286
13287 static void vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
13288 {
13289     vat_main_t * vam = &vat_main;
13290
13291     fformat(vam->ofp, "collector_address %U, collector_port %d, "
13292                       "src_address %U, fib_index %u, path_mtu %u, "
13293                       "template_interval %u\n",
13294             format_ip4_address, mp->collector_address,
13295             ntohs(mp->collector_port),
13296             format_ip4_address, mp->src_address,
13297             ntohl(mp->fib_index),
13298             ntohl(mp->path_mtu),
13299             ntohl(mp->template_interval));
13300
13301     vam->retval = 0;
13302     vam->result_ready = 1;
13303 }
13304
13305 static void vl_api_ipfix_details_t_handler_json
13306 (vl_api_ipfix_details_t * mp)
13307 {
13308     vat_main_t * vam = &vat_main;
13309     vat_json_node_t node;
13310     struct in_addr collector_address;
13311     struct in_addr src_address;
13312
13313     vat_json_init_object(&node);
13314     clib_memcpy(&collector_address, &mp->collector_address,
13315                 sizeof(collector_address));
13316     vat_json_object_add_ip4(&node, "collector_address", collector_address);
13317     vat_json_object_add_uint(&node, "collector_port",
13318                              ntohs(mp->collector_port));
13319     clib_memcpy(&src_address, &mp->src_address, sizeof(src_address));
13320     vat_json_object_add_ip4(&node, "src_address", src_address);
13321     vat_json_object_add_uint(&node, "fib_index", ntohl(mp->fib_index));
13322     vat_json_object_add_uint(&node, "path_mtu", ntohl(mp->path_mtu));
13323     vat_json_object_add_uint(&node, "template_interval",
13324                              ntohl(mp->template_interval));
13325
13326     vat_json_print(vam->ofp, &node);
13327     vat_json_free(&node);
13328     vam->retval = 0;
13329     vam->result_ready = 1;
13330 }
13331
13332 int api_ipfix_dump (vat_main_t *vam)
13333 {
13334     vl_api_ipfix_dump_t *mp;
13335     f64 timeout;
13336
13337     /* Construct the API message */
13338     M(IPFIX_DUMP, ipfix_dump);
13339     mp->context = 0;
13340
13341     S; W;
13342     /* NOTREACHED */
13343     return 0;
13344 }
13345
13346 int api_pg_create_interface (vat_main_t *vam)
13347 {
13348     unformat_input_t * input = vam->input;
13349     vl_api_pg_create_interface_t *mp;
13350     f64 timeout;
13351
13352     u32 if_id = ~0;
13353     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13354         if (unformat (input, "if_id %d", &if_id))
13355             ;
13356         else
13357             break;
13358     }
13359     if (if_id == ~0) {
13360         errmsg ("missing pg interface index\n");
13361         return -99;
13362     }
13363
13364     /* Construct the API message */
13365     M(PG_CREATE_INTERFACE, pg_create_interface);
13366     mp->context = 0;
13367     mp->interface_id = ntohl(if_id);
13368
13369     S; W;
13370     /* NOTREACHED */
13371     return 0;
13372 }
13373
13374 int api_pg_capture (vat_main_t *vam)
13375 {
13376     unformat_input_t * input = vam->input;
13377     vl_api_pg_capture_t *mp;
13378     f64 timeout;
13379
13380     u32 if_id = ~0;
13381     u8 enable = 1;
13382     u32 count = 1;
13383     u8 pcap_file_set = 0;
13384     u8 * pcap_file = 0;
13385     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13386         if (unformat (input, "if_id %d", &if_id))
13387             ;
13388         else if (unformat (input, "pcap %s", &pcap_file))
13389             pcap_file_set = 1;
13390         else if (unformat (input, "count %d", &count))
13391             ;
13392         else if (unformat (input, "disable"))
13393             enable = 0;
13394         else
13395             break;
13396     }
13397     if (if_id == ~0) {
13398         errmsg ("missing pg interface index\n");
13399         return -99;
13400     }
13401     if (pcap_file_set>0) {
13402         if (vec_len (pcap_file) > 255) {
13403             errmsg ("pcap file name is too long\n");
13404             return -99;
13405         }
13406     }
13407
13408     u32 name_len = vec_len(pcap_file);
13409     /* Construct the API message */
13410     M(PG_CAPTURE, pg_capture);
13411     mp->context = 0;
13412     mp->interface_id = ntohl(if_id);
13413     mp->is_enabled = enable;
13414     mp->count = ntohl(count);
13415     mp->pcap_name_length = ntohl(name_len);
13416     if (pcap_file_set != 0) {
13417         clib_memcpy(mp->pcap_file_name, pcap_file, name_len);
13418     }
13419     vec_free(pcap_file);
13420
13421     S; W;
13422     /* NOTREACHED */
13423     return 0;
13424 }
13425
13426 int api_pg_enable_disable (vat_main_t *vam)
13427 {
13428     unformat_input_t * input = vam->input;
13429     vl_api_pg_enable_disable_t *mp;
13430     f64 timeout;
13431
13432     u8 enable = 1;
13433     u8 stream_name_set = 0;
13434     u8 * stream_name = 0;
13435     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
13436         if (unformat (input, "stream %s", &stream_name))
13437             stream_name_set = 1;
13438         else if (unformat (input, "disable"))
13439             enable = 0;
13440         else
13441             break;
13442     }
13443
13444     if (stream_name_set>0) {
13445         if (vec_len (stream_name) > 255) {
13446             errmsg ("stream name too long\n");
13447             return -99;
13448         }
13449     }
13450
13451     u32 name_len = vec_len(stream_name);
13452     /* Construct the API message */
13453     M(PG_ENABLE_DISABLE, pg_enable_disable);
13454     mp->context = 0;
13455     mp->is_enabled = enable;
13456     if (stream_name_set != 0) {
13457         mp->stream_name_length = ntohl(name_len);
13458         clib_memcpy(mp->stream_name, stream_name, name_len);
13459     }
13460     vec_free(stream_name);
13461
13462     S; W;
13463     /* NOTREACHED */
13464     return 0;
13465 }
13466
13467 static int q_or_quit (vat_main_t * vam)
13468 {
13469     longjmp (vam->jump_buf, 1);
13470     return 0; /* not so much */
13471 }
13472 static int q (vat_main_t * vam) {return q_or_quit (vam);}
13473 static int quit (vat_main_t * vam) {return q_or_quit (vam);}
13474
13475 static int comment (vat_main_t * vam)
13476 {
13477     return 0;
13478 }
13479
13480 static int cmd_cmp (void * a1, void * a2)
13481 {
13482   u8 ** c1 = a1;
13483   u8 ** c2 = a2;
13484
13485   return strcmp ((char *)(c1[0]), (char *)(c2[0]));
13486 }
13487
13488 static int help (vat_main_t * vam)
13489 {
13490     u8 ** cmds = 0;
13491     u8 * name = 0;
13492     hash_pair_t * p;
13493     unformat_input_t * i = vam->input;
13494     int j;
13495
13496     if (unformat (i, "%s", &name)) {
13497         uword *hs;
13498
13499         vec_add1(name, 0);
13500
13501         hs = hash_get_mem (vam->help_by_name, name);
13502         if (hs)
13503             fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
13504         else
13505             fformat (vam->ofp, "No such msg / command '%s'\n", name);
13506         vec_free(name);
13507         return 0;
13508     }
13509
13510     fformat(vam->ofp, "Help is available for the following:\n");
13511
13512     hash_foreach_pair (p, vam->function_by_name,
13513     ({
13514         vec_add1 (cmds, (u8 *)(p->key));
13515     }));
13516
13517     vec_sort_with_function (cmds, cmd_cmp);
13518
13519     for (j = 0; j < vec_len(cmds); j++)
13520         fformat (vam->ofp, "%s\n", cmds[j]);
13521
13522     vec_free (cmds);
13523     return 0;
13524 }
13525
13526 static int set (vat_main_t * vam)
13527 {
13528     u8 * name = 0, * value = 0;
13529     unformat_input_t * i = vam->input;
13530
13531     if (unformat (i, "%s", &name)) {
13532         /* The input buffer is a vector, not a string. */
13533         value = vec_dup (i->buffer);
13534         vec_delete (value, i->index, 0);
13535         /* Almost certainly has a trailing newline */
13536         if (value[vec_len(value)-1] == '\n')
13537             value[vec_len(value)-1] = 0;
13538         /* Make sure it's a proper string, one way or the other */
13539         vec_add1 (value, 0);
13540         (void) clib_macro_set_value (&vam->macro_main,
13541                                      (char *)name, (char *)value);
13542     }
13543     else
13544         errmsg ("usage: set <name> <value>\n");
13545
13546     vec_free (name);
13547     vec_free (value);
13548     return 0;
13549 }
13550
13551 static int unset (vat_main_t * vam)
13552 {
13553     u8 * name = 0;
13554
13555     if (unformat (vam->input, "%s", &name))
13556         if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
13557             errmsg ("unset: %s wasn't set\n", name);
13558     vec_free (name);
13559     return 0;
13560 }
13561
13562 typedef struct {
13563     u8 * name;
13564     u8 * value;
13565 } macro_sort_t;
13566
13567
13568 static int macro_sort_cmp (void * a1, void * a2)
13569 {
13570   macro_sort_t * s1 = a1;
13571   macro_sort_t * s2 = a2;
13572
13573   return strcmp ((char *)(s1->name), (char *)(s2->name));
13574 }
13575
13576 static int dump_macro_table (vat_main_t * vam)
13577 {
13578     macro_sort_t * sort_me = 0, * sm;
13579     int i;
13580     hash_pair_t * p;
13581
13582     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
13583     ({
13584         vec_add2 (sort_me, sm, 1);
13585         sm->name = (u8 *)(p->key);
13586         sm->value = (u8 *) (p->value[0]);
13587     }));
13588
13589     vec_sort_with_function (sort_me, macro_sort_cmp);
13590
13591     if (vec_len(sort_me))
13592         fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
13593     else
13594         fformat (vam->ofp, "The macro table is empty...\n");
13595
13596     for (i = 0; i < vec_len (sort_me); i++)
13597         fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
13598                  sort_me[i].value);
13599     return 0;
13600 }
13601
13602 static int dump_node_table (vat_main_t * vam)
13603 {
13604     int i, j;
13605     vlib_node_t * node, * next_node;
13606
13607     if (vec_len (vam->graph_nodes) == 0) {
13608         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13609         return 0;
13610     }
13611
13612     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
13613         node = vam->graph_nodes[i];
13614         fformat (vam->ofp, "[%d] %s\n", i, node->name);
13615         for (j = 0; j < vec_len (node->next_nodes); j++) {
13616             if (node->next_nodes[j] != ~0) {
13617                 next_node = vam->graph_nodes[node->next_nodes[j]];
13618                 fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
13619             }
13620         }
13621     }
13622     return 0;
13623 }
13624
13625 static int search_node_table (vat_main_t * vam)
13626 {
13627     unformat_input_t * line_input = vam->input;
13628     u8 * node_to_find;
13629     int j;
13630     vlib_node_t * node, * next_node;
13631     uword * p;
13632
13633     if (vam->graph_node_index_by_name == 0) {
13634         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
13635         return 0;
13636     }
13637
13638     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
13639         if (unformat (line_input, "%s", &node_to_find)) {
13640             vec_add1 (node_to_find, 0);
13641             p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
13642             if (p == 0) {
13643                 fformat (vam->ofp, "%s not found...\n", node_to_find);
13644                 goto out;
13645             }
13646             node = vam->graph_nodes[p[0]];
13647             fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
13648             for (j = 0; j < vec_len (node->next_nodes); j++) {
13649                 if (node->next_nodes[j] != ~0) {
13650                     next_node = vam->graph_nodes[node->next_nodes[j]];
13651                     fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
13652                 }
13653             }
13654         }
13655
13656         else {
13657             clib_warning ("parse error '%U'", format_unformat_error,
13658                           line_input);
13659             return -99;
13660         }
13661
13662     out:
13663         vec_free(node_to_find);
13664
13665     }
13666
13667     return 0;
13668 }
13669
13670
13671 static int script (vat_main_t * vam)
13672 {
13673     u8 * s = 0;
13674     char * save_current_file;
13675     unformat_input_t save_input;
13676     jmp_buf save_jump_buf;
13677     u32 save_line_number;
13678
13679     FILE * new_fp, * save_ifp;
13680
13681     if (unformat (vam->input, "%s", &s)) {
13682         new_fp = fopen ((char *)s, "r");
13683         if (new_fp == 0) {
13684             errmsg ("Couldn't open script file %s\n", s);
13685             vec_free (s);
13686             return -99;
13687         }
13688     } else {
13689         errmsg ("Missing script name\n");
13690         return -99;
13691     }
13692
13693     clib_memcpy (&save_input, &vam->input, sizeof (save_input));
13694     clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
13695     save_ifp = vam->ifp;
13696     save_line_number = vam->input_line_number;
13697     save_current_file = (char *) vam->current_file;
13698
13699     vam->input_line_number = 0;
13700     vam->ifp = new_fp;
13701     vam->current_file = s;
13702     do_one_file (vam);
13703
13704     clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
13705     clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
13706     vam->ifp = save_ifp;
13707     vam->input_line_number = save_line_number;
13708     vam->current_file = (u8 *) save_current_file;
13709     vec_free (s);
13710
13711     return 0;
13712 }
13713
13714 static int echo (vat_main_t * vam)
13715 {
13716     fformat (vam->ofp, "%v", vam->input->buffer);
13717     return 0;
13718 }
13719
13720 /* List of API message constructors, CLI names map to api_xxx */
13721 #define foreach_vpe_api_msg                                             \
13722 _(create_loopback,"[mac <mac-addr>]")                                   \
13723 _(sw_interface_dump,"")                                                 \
13724 _(sw_interface_set_flags,                                               \
13725   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
13726 _(sw_interface_add_del_address,                                         \
13727   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
13728 _(sw_interface_set_table,                                               \
13729   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
13730 _(sw_interface_set_vpath,                                               \
13731   "<intfc> | sw_if_index <id> enable | disable")                        \
13732 _(sw_interface_set_l2_xconnect,                                         \
13733   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13734   "enable | disable")                                                   \
13735 _(sw_interface_set_l2_bridge,                                           \
13736   "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n"         \
13737   "[shg <split-horizon-group>] [bvi]\n"                                 \
13738   "enable | disable")                                                   \
13739 _(bridge_domain_add_del,                                                \
13740   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
13741 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
13742 _(l2fib_add_del,                                                        \
13743   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
13744 _(l2_flags,                                                             \
13745   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
13746 _(bridge_flags,                                                         \
13747   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
13748 _(tap_connect,                                                          \
13749   "tapname <name> mac <mac-addr> | random-mac")                         \
13750 _(tap_modify,                                                           \
13751   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
13752 _(tap_delete,                                                           \
13753   "<vpp-if-name> | sw_if_index <id>")                                   \
13754 _(sw_interface_tap_dump, "")                                            \
13755 _(ip_add_del_route,                                                     \
13756   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
13757   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
13758   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
13759   "[multipath] [count <n>]")                                            \
13760 _(proxy_arp_add_del,                                                    \
13761   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
13762 _(proxy_arp_intfc_enable_disable,                                       \
13763   "<intfc> | sw_if_index <id> enable | disable")                        \
13764 _(mpls_add_del_encap,                                                   \
13765   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
13766 _(mpls_add_del_decap,                                                   \
13767   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
13768 _(mpls_gre_add_del_tunnel,                                              \
13769   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
13770   "adj <ip4-address>/<mask-width> [del]")                               \
13771 _(sw_interface_set_unnumbered,                                          \
13772   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
13773 _(ip_neighbor_add_del,                                                  \
13774   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
13775   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
13776 _(reset_vrf, "vrf <id> [ipv6]")                                         \
13777 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
13778 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
13779   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
13780   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
13781   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
13782 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
13783 _(reset_fib, "vrf <n> [ipv6]")                                          \
13784 _(dhcp_proxy_config,                                                    \
13785   "svr <v46-address> src <v46-address>\n"                               \
13786    "insert-cid <n> [del]")                                              \
13787 _(dhcp_proxy_config_2,                                                  \
13788   "svr <v46-address> src <v46-address>\n"                               \
13789    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
13790 _(dhcp_proxy_set_vss,                                                   \
13791   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
13792 _(dhcp_client_config,                                                   \
13793   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
13794 _(set_ip_flow_hash,                                                     \
13795   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
13796 _(sw_interface_ip6_enable_disable,                                      \
13797   "<intfc> | sw_if_index <id> enable | disable")                        \
13798 _(sw_interface_ip6_set_link_local_address,                              \
13799   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
13800 _(sw_interface_ip6nd_ra_prefix,                                         \
13801   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
13802   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
13803   "[nolink] [isno]")                                                    \
13804 _(sw_interface_ip6nd_ra_config,                                         \
13805   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
13806   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
13807   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
13808 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
13809 _(l2_patch_add_del,                                                     \
13810   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
13811   "enable | disable")                                                   \
13812 _(mpls_ethernet_add_del_tunnel,                                         \
13813   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
13814   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
13815 _(mpls_ethernet_add_del_tunnel_2,                                       \
13816   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
13817   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
13818 _(sr_tunnel_add_del,                                                    \
13819   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
13820   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
13821   "[policy <policy_name>]")                                             \
13822 _(sr_policy_add_del,                                                    \
13823   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
13824 _(sr_multicast_map_add_del,                                             \
13825   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
13826 _(classify_add_del_table,                                               \
13827   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
13828   "[del] mask <mask-value>\n"                                           \
13829   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
13830 _(classify_add_del_session,                                             \
13831   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
13832   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
13833   "  [l3 [ip4|ip6]]")                                                   \
13834 _(classify_set_interface_ip_table,                                      \
13835   "<intfc> | sw_if_index <nn> table <nn>")                              \
13836 _(classify_set_interface_l2_tables,                                     \
13837   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
13838   "  [other-table <nn>]")                                               \
13839 _(get_node_index, "node <node-name")                                    \
13840 _(add_node_next, "node <node-name> next <next-node-name>")              \
13841 _(l2tpv3_create_tunnel,                                                 \
13842   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
13843   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
13844   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
13845 _(l2tpv3_set_tunnel_cookies,                                            \
13846   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
13847   "[new_remote_cookie <nn>]\n")                                         \
13848 _(l2tpv3_interface_enable_disable,                                      \
13849   "<intfc> | sw_if_index <nn> enable | disable")                        \
13850 _(l2tpv3_set_lookup_key,                                                \
13851   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
13852 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
13853 _(vxlan_add_del_tunnel,                                                 \
13854   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
13855   " [decap-next l2|ip4|ip6] [del]")                                     \
13856 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
13857 _(gre_add_del_tunnel,                                                   \
13858   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
13859 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
13860 _(l2_fib_clear_table, "")                                               \
13861 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
13862 _(l2_interface_vlan_tag_rewrite,                                        \
13863   "<intfc> | sw_if_index <nn> \n"                                       \
13864   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
13865   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
13866 _(create_vhost_user_if,                                                 \
13867         "socket <filename> [server] [renumber <dev_instance>] "         \
13868         "[mac <mac_address>]")                                          \
13869 _(modify_vhost_user_if,                                                 \
13870         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
13871         "[server] [renumber <dev_instance>]")                           \
13872 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
13873 _(sw_interface_vhost_user_dump, "")                                     \
13874 _(show_version, "")                                                     \
13875 _(vxlan_gpe_add_del_tunnel,                                             \
13876   "local <addr> remote <addr> vni <nn>\n"                               \
13877     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
13878   "[next-ethernet] [next-nsh]\n")                                       \
13879 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
13880 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
13881 _(interface_name_renumber,                                              \
13882   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
13883 _(input_acl_set_interface,                                              \
13884   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
13885   "  [l2-table <nn>] [del]")                                            \
13886 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
13887 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
13888 _(ip_dump, "ipv4 | ipv6")                                               \
13889 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
13890 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
13891   "  spid_id <n> ")                                                     \
13892 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
13893   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
13894   "  integ_alg <alg> integ_key <hex>")                                  \
13895 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
13896   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
13897   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
13898   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
13899 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
13900 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
13901 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
13902   "(auth_data 0x<data> | auth_data <data>)")                            \
13903 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
13904   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
13905 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
13906   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
13907   "(local|remote)")                                                     \
13908 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
13909 _(delete_loopback,"sw_if_index <nn>")                                   \
13910 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
13911 _(map_add_domain,                                                       \
13912   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
13913   "ip6-src <ip6addr> "                                                  \
13914   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
13915 _(map_del_domain, "index <n>")                                          \
13916 _(map_add_del_rule,                                                     \
13917   "index <n> psid <n> dst <ip6addr> [del]")                             \
13918 _(map_domain_dump, "")                                                  \
13919 _(map_rule_dump, "index <map-domain>")                                  \
13920 _(want_interface_events,  "enable|disable")                             \
13921 _(want_stats,"enable|disable")                                          \
13922 _(get_first_msg_id, "client <name>")                                    \
13923 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
13924 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
13925   "fib-id <nn> [ip4][ip6][default]")                                    \
13926 _(get_node_graph, " ")                                                  \
13927 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
13928 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
13929   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
13930   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
13931 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
13932   " vrf_id <nn>  add | pop | none")                                     \
13933 _(trace_profile_del, "")                                                \
13934 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
13935                             " sw_if_index <sw_if_index> p <priority> "  \
13936                             "w <weight>] [del]")                        \
13937 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
13938                         "iface <intf> | sw_if_index <sw_if_index> "     \
13939                         "p <priority> w <weight> [del]")                \
13940 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
13941                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
13942                           "locator-set <locator_name> [del]")           \
13943 _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
13944     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
13945 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
13946 _(lisp_gpe_enable_disable, "enable|disable")                            \
13947 _(lisp_enable_disable, "enable|disable")                                \
13948 _(lisp_gpe_add_del_iface, "up|down")                                    \
13949 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
13950                                "rloc <locator> p <prio> "               \
13951                                "w <weight> [rloc <loc> ... ] "          \
13952                                "action <action> [del-all]")             \
13953 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
13954                           "<src-eid> rloc <locator> p <prio> w <weight>"\
13955                           "[rloc <loc> ... ] action <action>")          \
13956 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
13957 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
13958 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
13959 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
13960                          "locator-set <loc-set-name>] [local | remote]")\
13961 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
13962                        "[local] | [remote]")                            \
13963 _(lisp_eid_table_map_dump, "")                                          \
13964 _(lisp_gpe_tunnel_dump, "")                                             \
13965 _(lisp_map_resolver_dump, "")                                           \
13966 _(show_lisp_status, "")                                                 \
13967 _(lisp_get_map_request_itr_rlocs, "")                                   \
13968 _(show_lisp_pitr, "")                                                   \
13969 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
13970 _(af_packet_delete, "name <host interface name>")                       \
13971 _(policer_add_del, "name <policer name> <params> [del]")                \
13972 _(policer_dump, "[name <policer name>]")                                \
13973 _(policer_classify_set_interface,                                       \
13974   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
13975   "  [l2-table <nn>] [del]")                                            \
13976 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
13977 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
13978     "[master|slave]")                                                   \
13979 _(netmap_delete, "name <interface name>")                               \
13980 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
13981 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
13982 _(mpls_fib_encap_dump, "")                                              \
13983 _(mpls_fib_decap_dump, "")                                              \
13984 _(classify_table_ids, "")                                               \
13985 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
13986 _(classify_table_info, "table_id <nn>")                                 \
13987 _(classify_session_dump, "table_id <nn>")                               \
13988 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
13989                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
13990                 "[template_interval <nn>]")                             \
13991 _(ipfix_dump, "")                                                       \
13992 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
13993 _(pg_create_interface, "if_id <nn>")                                    \
13994 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
13995 _(pg_enable_disable, "[stream <id>] disable")
13996
13997 /* List of command functions, CLI names map directly to functions */
13998 #define foreach_cli_function                                    \
13999 _(comment, "usage: comment <ignore-rest-of-line>")              \
14000 _(dump_interface_table, "usage: dump_interface_table")          \
14001 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
14002 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
14003 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
14004 _(dump_stats_table, "usage: dump_stats_table")                  \
14005 _(dump_macro_table, "usage: dump_macro_table ")                 \
14006 _(dump_node_table, "usage: dump_node_table")                    \
14007 _(echo, "usage: echo <message>")                                \
14008 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
14009 _(help, "usage: help")                                          \
14010 _(q, "usage: quit")                                             \
14011 _(quit, "usage: quit")                                          \
14012 _(search_node_table, "usage: search_node_table <name>...")      \
14013 _(set, "usage: set <variable-name> <value>")                    \
14014 _(script, "usage: script <file-name>")                          \
14015 _(unset, "usage: unset <variable-name>")
14016
14017 #define _(N,n)                                  \
14018     static void vl_api_##n##_t_handler_uni      \
14019     (vl_api_##n##_t * mp)                       \
14020     {                                           \
14021         vat_main_t * vam = &vat_main;           \
14022         if (vam->json_output) {                 \
14023             vl_api_##n##_t_handler_json(mp);    \
14024         } else {                                \
14025             vl_api_##n##_t_handler(mp);         \
14026         }                                       \
14027     }
14028 foreach_vpe_api_reply_msg;
14029 #undef _
14030
14031 void vat_api_hookup (vat_main_t *vam)
14032 {
14033 #define _(N,n)                                                  \
14034     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
14035                            vl_api_##n##_t_handler_uni,          \
14036                            vl_noop_handler,                     \
14037                            vl_api_##n##_t_endian,               \
14038                            vl_api_##n##_t_print,                \
14039                            sizeof(vl_api_##n##_t), 1);
14040     foreach_vpe_api_reply_msg;
14041 #undef _
14042
14043     vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
14044
14045     vam->sw_if_index_by_interface_name =
14046         hash_create_string (0, sizeof (uword));
14047
14048     vam->function_by_name =
14049         hash_create_string (0, sizeof(uword));
14050
14051     vam->help_by_name =
14052         hash_create_string (0, sizeof(uword));
14053
14054     /* API messages we can send */
14055 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
14056     foreach_vpe_api_msg;
14057 #undef _
14058
14059     /* Help strings */
14060 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14061     foreach_vpe_api_msg;
14062 #undef _
14063
14064     /* CLI functions */
14065 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
14066     foreach_cli_function;
14067 #undef _
14068
14069     /* Help strings */
14070 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14071     foreach_cli_function;
14072 #undef _
14073 }
14074
14075 #undef vl_api_version
14076 #define vl_api_version(n,v) static u32 vpe_api_version = v;
14077 #include <vpp-api/vpe.api.h>
14078 #undef vl_api_version
14079
14080 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp)
14081 {
14082     /*
14083      * Send the main API signature in slot 0. This bit of code must
14084      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
14085      */
14086     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
14087 }