bfafc5bcac13b7d75dad9a1a9ebc453a833c7c1a
[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 <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 #if DPDK > 0
38 #include <vnet/ipsec/ipsec.h>
39 #include <vnet/ipsec/ikev2.h>
40 #else
41 #include <inttypes.h>
42 #endif
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/policer/xlate.h>
47
48 #include "vat/json_format.h"
49
50 #define vl_typedefs             /* define message structures */
51 #include <api/vpe_all_api_h.h> 
52 #undef vl_typedefs
53
54 /* declare message handlers for each api */
55
56 #define vl_endianfun             /* define message structures */
57 #include <api/vpe_all_api_h.h> 
58 #undef vl_endianfun
59
60 /* instantiate all the print functions we know about */
61 #define vl_print(handle, ...)
62 #define vl_printfun
63 #include <api/vpe_all_api_h.h>
64 #undef vl_printfun
65
66 uword unformat_sw_if_index (unformat_input_t * input, va_list * args)
67 {
68   vat_main_t * vam = va_arg (*args, vat_main_t *);
69   u32 * result = va_arg (*args, u32 *);
70   u8 * if_name;
71   uword * p;
72
73   if (!unformat (input, "%s", &if_name))
74       return 0;
75
76   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
77   if (p == 0)
78       return 0;
79   *result = p[0];
80   return 1;
81 }
82
83 /* Parse an IP4 address %d.%d.%d.%d. */
84 uword unformat_ip4_address (unformat_input_t * input, va_list * args)
85 {
86   u8 * result = va_arg (*args, u8 *);
87   unsigned a[4];
88
89   if (! unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
90     return 0;
91
92   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
93     return 0;
94
95   result[0] = a[0];
96   result[1] = a[1];
97   result[2] = a[2];
98   result[3] = a[3];
99
100   return 1;
101 }
102
103
104 uword
105 unformat_ethernet_address (unformat_input_t * input, va_list * args)
106 {
107   u8 * result = va_arg (*args, u8 *);
108   u32 i, a[6];
109
110   if (! unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
111                   &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
112     return 0;
113
114   /* Check range. */
115   for (i = 0; i < 6; i++)
116     if (a[i] >= (1 << 8))
117       return 0;
118
119   for (i = 0; i < 6; i++)
120     result[i] = a[i];
121
122   return 1;
123 }
124
125 /* Returns ethernet type as an int in host byte order. */
126 uword
127 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
128                                         va_list * args)
129 {
130   u16 * result = va_arg (*args, u16 *);
131   int type;
132
133   /* Numeric type. */
134   if (unformat (input, "0x%x", &type)
135       || unformat (input, "%d", &type))
136     {
137       if (type >= (1 << 16))
138         return 0;
139       *result = type;
140       return 1;
141     }
142   return 0;
143 }
144
145 /* Parse an IP6 address. */
146 uword unformat_ip6_address (unformat_input_t * input, va_list * args)
147 {
148   ip6_address_t * result = va_arg (*args, ip6_address_t *);
149   u16 hex_quads[8];
150   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
151   uword c, n_colon, double_colon_index;
152
153   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
154   double_colon_index = ARRAY_LEN (hex_quads);
155   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
156     {
157       hex_digit = 16;
158       if (c >= '0' && c <= '9')
159         hex_digit = c - '0';
160       else if (c >= 'a' && c <= 'f')
161         hex_digit = c + 10 - 'a';
162       else if (c >= 'A' && c <= 'F')
163         hex_digit = c + 10 - 'A';
164       else if (c == ':' && n_colon < 2)
165         n_colon++;
166       else
167         {
168           unformat_put_input (input);
169           break;
170         }
171
172       /* Too many hex quads. */
173       if (n_hex_quads >= ARRAY_LEN (hex_quads))
174         return 0;
175
176       if (hex_digit < 16)
177         {
178           hex_quad = (hex_quad << 4) | hex_digit;
179
180           /* Hex quad must fit in 16 bits. */
181           if (n_hex_digits >= 4)
182             return 0;
183
184           n_colon = 0;
185           n_hex_digits++;
186         }
187       
188       /* Save position of :: */
189       if (n_colon == 2)
190         {
191           /* More than one :: ? */
192           if (double_colon_index < ARRAY_LEN (hex_quads))
193             return 0;
194           double_colon_index = n_hex_quads;
195         }
196
197       if (n_colon > 0 && n_hex_digits > 0)
198         {
199           hex_quads[n_hex_quads++] = hex_quad;
200           hex_quad = 0;
201           n_hex_digits = 0;
202         }
203     }
204
205   if (n_hex_digits > 0)
206     hex_quads[n_hex_quads++] = hex_quad;
207
208   {
209     word i;
210
211     /* Expand :: to appropriate number of zero hex quads. */
212     if (double_colon_index < ARRAY_LEN (hex_quads))
213       {
214         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
215
216         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
217           hex_quads[n_zero + i] = hex_quads[i];
218
219         for (i = 0; i < n_zero; i++)
220           hex_quads[double_colon_index + i] = 0;
221
222         n_hex_quads = ARRAY_LEN (hex_quads);
223       }
224
225     /* Too few hex quads given. */
226     if (n_hex_quads < ARRAY_LEN (hex_quads))
227       return 0;
228
229     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
230       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
231
232     return 1;
233   }
234 }
235
236 uword
237 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
238 {
239 #if DPDK > 0
240   u32 * r = va_arg (*args, u32 *);
241
242   if (0) ;
243 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
244   foreach_ipsec_policy_action
245 #undef _
246   else
247     return 0;
248   return 1;
249 #else
250   return 0;
251 #endif
252 }
253
254 uword
255 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
256 {
257 #if DPDK > 0
258   u32 * r = va_arg (*args, u32 *);
259
260   if (0) ;
261 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
262   foreach_ipsec_crypto_alg
263 #undef _
264   else
265     return 0;
266   return 1;
267 #else
268   return 0;
269 #endif
270 }
271
272 u8 *
273 format_ipsec_crypto_alg (u8 * s, va_list * args)
274 {
275 #if DPDK > 0
276   u32 i = va_arg (*args, u32);
277   u8 * t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282   foreach_ipsec_crypto_alg
283 #undef _
284       default:
285         return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 #else
289   return format (s, "Unimplemented");
290 #endif
291 }
292
293 uword
294 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
295 {
296 #if DPDK > 0
297   u32 * r = va_arg (*args, u32 *);
298
299   if (0) ;
300 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
301   foreach_ipsec_integ_alg
302 #undef _
303   else
304     return 0;
305   return 1;
306 #else
307   return 0;
308 #endif
309 }
310
311 u8 *
312 format_ipsec_integ_alg (u8 * s, va_list * args)
313 {
314 #if DPDK > 0
315   u32 i = va_arg (*args, u32);
316   u8 * t = 0;
317
318   switch (i)
319     {
320 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
321   foreach_ipsec_integ_alg
322 #undef _
323       default:
324         return format (s, "unknown");
325     }
326   return format (s, "%s", t);
327 #else
328   return format (s, "Unsupported");
329 #endif
330 }
331
332 uword
333 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
334 {
335 #if DPDK > 0
336   u32 * r = va_arg (*args, u32 *);
337
338   if (0) ;
339 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
340   foreach_ikev2_auth_method
341 #undef _
342   else
343     return 0;
344   return 1;
345 #else
346   return 0;
347 #endif
348 }
349
350 uword
351 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
352 {
353 #if DPDK > 0
354   u32 * r = va_arg (*args, u32 *);
355
356   if (0) ;
357 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
358   foreach_ikev2_id_type
359 #undef _
360   else
361     return 0;
362   return 1;
363 #else
364   return 0;
365 #endif
366 }
367
368 uword
369 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
370 {
371   u8 * r = va_arg (*args, u8 *);
372
373   if (unformat (input, "kbps"))
374     *r = SSE2_QOS_RATE_KBPS;
375   else if (unformat(input, "pps"))
376     *r = SSE2_QOS_RATE_PPS;
377   else
378     return 0;
379   return 1;
380 }
381
382 uword
383 unformat_policer_round_type (unformat_input_t * input, va_list * args)
384 {
385   u8 * r = va_arg (*args, u8 *);
386
387   if (unformat(input, "closest"))
388     *r = SSE2_QOS_ROUND_TO_CLOSEST;
389   else if (unformat (input, "up"))
390     *r = SSE2_QOS_ROUND_TO_UP;
391   else if (unformat (input, "down"))
392     *r = SSE2_QOS_ROUND_TO_DOWN;
393   else
394     return 0;
395   return 1;
396 }
397
398 uword
399 unformat_policer_type (unformat_input_t * input, va_list * args)
400 {
401   u8 * r = va_arg (*args, u8 *);
402
403   if (unformat (input, "1r2c"))
404     *r = SSE2_QOS_POLICER_TYPE_1R2C;
405   else if (unformat (input, "1r3c"))
406     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
407   else if (unformat (input, "2r3c-2698"))
408     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
409   else if (unformat (input, "2r3c-4115"))
410     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
411   else if (unformat (input, "2r3c-mef5cf1"))
412     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
413   else
414     return 0;
415   return 1;
416 }
417
418 u8 * format_ip4_address (u8 * s, va_list * args)
419 {
420   u8 * a = va_arg (*args, u8 *);
421   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
422 }
423
424 u8 * format_ip6_address (u8 * s, va_list * args)
425 {
426     ip6_address_t * a = va_arg (*args, ip6_address_t *);
427     u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
428
429     i_max_n_zero = ARRAY_LEN (a->as_u16);
430     max_n_zeros = 0;
431     i_first_zero = i_max_n_zero;
432     n_zeros = 0;
433     for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
434       {
435         u32 is_zero = a->as_u16[i] == 0;
436         if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
437           {
438             i_first_zero = i;
439             n_zeros = 0;
440           }
441         n_zeros += is_zero;
442         if ((! is_zero && n_zeros > max_n_zeros)
443             || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
444           {
445             i_max_n_zero = i_first_zero;
446             max_n_zeros = n_zeros;
447             i_first_zero = ARRAY_LEN (a->as_u16);
448             n_zeros = 0;
449           }
450       }
451
452     last_double_colon = 0;
453     for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
454       {
455         if (i == i_max_n_zero && max_n_zeros > 1)
456           {
457             s = format (s, "::");
458             i += max_n_zeros - 1;
459             last_double_colon = 1;
460           }
461         else
462           {
463             s = format (s, "%s%x",
464                         (last_double_colon || i == 0) ? "" : ":",
465                         clib_net_to_host_u16 (a->as_u16[i]));
466             last_double_colon = 0;
467           }
468       }
469
470     return s;
471 }
472
473 /* Format an IP46 address. */
474 u8 * format_ip46_address (u8 * s, va_list * args)
475 {
476   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
477   ip46_type_t type = va_arg (*args, ip46_type_t);
478   int is_ip4 = 1;
479
480   switch (type)
481     {
482       case IP46_TYPE_ANY:
483        is_ip4 = ip46_address_is_ip4(ip46);
484        break;
485       case IP46_TYPE_IP4:
486        is_ip4 = 1;
487        break;
488       case IP46_TYPE_IP6:
489        is_ip4 = 0;
490        break;
491     }
492
493   return is_ip4 ?
494       format(s, "%U", format_ip4_address, &ip46->ip4):
495       format(s, "%U", format_ip6_address, &ip46->ip6);
496 }
497
498 u8 * format_ethernet_address (u8 * s, va_list * args)
499 {
500   u8 * a = va_arg (*args, u8 *);
501
502   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
503                  a[0], a[1], a[2], a[3], a[4], a[5]);
504 }
505
506 void increment_v4_address (ip4_address_t * a)
507 {
508     u32 v;
509
510     v = ntohl(a->as_u32) + 1;
511     a->as_u32 = ntohl(v);
512 }
513
514 void increment_v6_address (ip6_address_t * a)
515 {
516     u64 v0, v1;
517
518     v0 = clib_net_to_host_u64 (a->as_u64[0]);
519     v1 = clib_net_to_host_u64 (a->as_u64[1]);
520
521     v1 += 1;
522     if (v1 == 0)
523         v0 += 1;
524     a->as_u64[0] = clib_net_to_host_u64 (v0);
525     a->as_u64[1] = clib_net_to_host_u64 (v1);
526 }
527
528
529 static void vl_api_create_loopback_reply_t_handler 
530 (vl_api_create_loopback_reply_t * mp)
531 {
532     vat_main_t * vam = &vat_main;
533     i32 retval = ntohl(mp->retval);
534
535     vam->retval = retval;
536     vam->regenerate_interface_table = 1;
537     vam->sw_if_index = ntohl (mp->sw_if_index);
538     vam->result_ready = 1;
539 }
540
541 static void vl_api_create_loopback_reply_t_handler_json
542 (vl_api_create_loopback_reply_t * mp)
543 {
544     vat_main_t * vam = &vat_main;
545     vat_json_node_t node;
546
547     vat_json_init_object(&node);
548     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
549     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
550
551     vat_json_print(vam->ofp, &node);
552     vat_json_free(&node);
553     vam->retval = ntohl(mp->retval);
554     vam->result_ready = 1;
555 }
556
557 static void vl_api_af_packet_create_reply_t_handler 
558 (vl_api_af_packet_create_reply_t * mp)
559 {
560     vat_main_t * vam = &vat_main;
561     i32 retval = ntohl(mp->retval);
562
563     vam->retval = retval;
564     vam->regenerate_interface_table = 1;
565     vam->sw_if_index = ntohl (mp->sw_if_index);
566     vam->result_ready = 1;
567 }
568
569 static void vl_api_af_packet_create_reply_t_handler_json
570 (vl_api_af_packet_create_reply_t * mp)
571 {
572     vat_main_t * vam = &vat_main;
573     vat_json_node_t node;
574
575     vat_json_init_object(&node);
576     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
577     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
578
579     vat_json_print(vam->ofp, &node);
580     vat_json_free(&node);
581
582     vam->retval = ntohl(mp->retval);
583     vam->result_ready = 1;
584 }
585
586 static void vl_api_create_vlan_subif_reply_t_handler 
587 (vl_api_create_vlan_subif_reply_t * mp)
588 {
589     vat_main_t * vam = &vat_main;
590     i32 retval = ntohl(mp->retval);
591
592     vam->retval = retval;
593     vam->regenerate_interface_table = 1;
594     vam->sw_if_index = ntohl (mp->sw_if_index);
595     vam->result_ready = 1;
596 }
597
598 static void vl_api_create_vlan_subif_reply_t_handler_json
599 (vl_api_create_vlan_subif_reply_t * mp)
600 {
601     vat_main_t * vam = &vat_main;
602     vat_json_node_t node;
603
604     vat_json_init_object(&node);
605     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
606     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
607
608     vat_json_print(vam->ofp, &node);
609     vat_json_free(&node);
610
611     vam->retval = ntohl(mp->retval);
612     vam->result_ready = 1;
613 }
614
615 static void vl_api_create_subif_reply_t_handler 
616 (vl_api_create_subif_reply_t * mp)
617 {
618     vat_main_t * vam = &vat_main;
619     i32 retval = ntohl(mp->retval);
620
621     vam->retval = retval;
622     vam->regenerate_interface_table = 1;
623     vam->sw_if_index = ntohl (mp->sw_if_index);
624     vam->result_ready = 1;
625 }
626
627 static void vl_api_create_subif_reply_t_handler_json
628 (vl_api_create_subif_reply_t * mp)
629 {
630     vat_main_t * vam = &vat_main;
631     vat_json_node_t node;
632
633     vat_json_init_object(&node);
634     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
635     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
636
637     vat_json_print(vam->ofp, &node);
638     vat_json_free(&node);
639
640     vam->retval = ntohl(mp->retval);
641     vam->result_ready = 1;
642 }
643
644 static void vl_api_interface_name_renumber_reply_t_handler 
645 (vl_api_interface_name_renumber_reply_t * mp)
646 {
647     vat_main_t * vam = &vat_main;
648     i32 retval = ntohl(mp->retval);
649
650     vam->retval = retval;
651     vam->regenerate_interface_table = 1;
652     vam->result_ready = 1;
653 }
654
655 static void vl_api_interface_name_renumber_reply_t_handler_json
656 (vl_api_interface_name_renumber_reply_t * mp)
657 {
658     vat_main_t * vam = &vat_main;
659     vat_json_node_t node;
660
661     vat_json_init_object(&node);
662     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
663
664     vat_json_print(vam->ofp, &node);
665     vat_json_free(&node);
666
667     vam->retval = ntohl(mp->retval);
668     vam->result_ready = 1;
669 }
670
671 /* 
672  * Special-case: build the interface table, maintain
673  * the next loopback sw_if_index vbl.
674  */
675 static void vl_api_sw_interface_details_t_handler
676 (vl_api_sw_interface_details_t * mp)
677 {
678     vat_main_t * vam = &vat_main;
679     u8 * s = format (0, "%s%c", mp->interface_name, 0);
680
681     hash_set_mem (vam->sw_if_index_by_interface_name, s, 
682                   ntohl(mp->sw_if_index));
683
684     /* In sub interface case, fill the sub interface table entry */
685     if (mp->sw_if_index != mp->sup_sw_if_index) {
686         sw_interface_subif_t * sub = NULL;
687
688         vec_add2(vam->sw_if_subif_table, sub, 1);
689
690         vec_validate(sub->interface_name, strlen((char *)s) + 1);
691         strncpy((char *)sub->interface_name, (char *)s,
692                 vec_len(sub->interface_name));
693         sub->sw_if_index = ntohl(mp->sw_if_index);
694         sub->sub_id = ntohl(mp->sub_id);
695
696         sub->sub_dot1ad = mp->sub_dot1ad;
697         sub->sub_number_of_tags = mp->sub_number_of_tags;
698         sub->sub_outer_vlan_id = ntohs(mp->sub_outer_vlan_id);
699         sub->sub_inner_vlan_id = ntohs(mp->sub_inner_vlan_id);
700         sub->sub_exact_match = mp->sub_exact_match;
701         sub->sub_default = mp->sub_default;
702         sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
703         sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
704
705         /* vlan tag rewrite */
706         sub->vtr_op = ntohl(mp->vtr_op);
707         sub->vtr_push_dot1q = ntohl(mp->vtr_push_dot1q);
708         sub->vtr_tag1 = ntohl(mp->vtr_tag1);
709         sub->vtr_tag2 = ntohl(mp->vtr_tag2);
710     }
711 }
712
713 static void vl_api_sw_interface_details_t_handler_json
714 (vl_api_sw_interface_details_t * mp)
715 {
716     vat_main_t * vam = &vat_main;
717     vat_json_node_t *node = NULL;
718
719     if (VAT_JSON_ARRAY != vam->json_tree.type) {
720         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
721         vat_json_init_array(&vam->json_tree);
722     }
723     node = vat_json_array_add(&vam->json_tree);
724
725     vat_json_init_object(node);
726     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
727     vat_json_object_add_uint(node, "sup_sw_if_index", ntohl(mp->sup_sw_if_index));
728     vat_json_object_add_uint(node, "l2_address_length", ntohl(mp->l2_address_length));
729     vat_json_object_add_bytes(node, "l2_address", mp->l2_address, sizeof(mp->l2_address));
730     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
731     vat_json_object_add_uint(node, "admin_up_down", mp->admin_up_down);
732     vat_json_object_add_uint(node, "link_up_down", mp->link_up_down);
733     vat_json_object_add_uint(node, "link_duplex", mp->link_duplex);
734     vat_json_object_add_uint(node, "link_speed", mp->link_speed);
735     vat_json_object_add_uint(node, "mtu", ntohs(mp->link_mtu));
736     vat_json_object_add_uint(node, "sub_id", ntohl(mp->sub_id));
737     vat_json_object_add_uint(node, "sub_dot1ad", mp->sub_dot1ad);
738     vat_json_object_add_uint(node, "sub_number_of_tags", mp->sub_number_of_tags);
739     vat_json_object_add_uint(node, "sub_outer_vlan_id", ntohs(mp->sub_outer_vlan_id));
740     vat_json_object_add_uint(node, "sub_inner_vlan_id", ntohs(mp->sub_inner_vlan_id));
741     vat_json_object_add_uint(node, "sub_exact_match", mp->sub_exact_match);
742     vat_json_object_add_uint(node, "sub_default", mp->sub_default);
743     vat_json_object_add_uint(node, "sub_outer_vlan_id_any", mp->sub_outer_vlan_id_any);
744     vat_json_object_add_uint(node, "sub_inner_vlan_id_any", mp->sub_inner_vlan_id_any);
745     vat_json_object_add_uint(node, "vtr_op", ntohl(mp->vtr_op));
746     vat_json_object_add_uint(node, "vtr_push_dot1q", ntohl(mp->vtr_push_dot1q));
747     vat_json_object_add_uint(node, "vtr_tag1", ntohl(mp->vtr_tag1));
748     vat_json_object_add_uint(node, "vtr_tag2", ntohl(mp->vtr_tag2));
749 }
750
751 static void vl_api_sw_interface_set_flags_t_handler
752 (vl_api_sw_interface_set_flags_t * mp)
753 {
754     vat_main_t * vam = &vat_main;
755     if (vam->interface_event_display)
756         errmsg ("interface flags: sw_if_index %d %s %s\n",
757                 ntohl(mp->sw_if_index),
758                 mp->admin_up_down ? "admin-up" : "admin-down",
759                 mp->link_up_down  ? "link-up"  : "link-down");
760 }
761
762 static void vl_api_sw_interface_set_flags_t_handler_json
763 (vl_api_sw_interface_set_flags_t * mp)
764 {
765     /* JSON output not supported */
766 }
767
768 static void vl_api_cli_reply_t_handler
769 (vl_api_cli_reply_t * mp)
770 {
771     vat_main_t * vam = &vat_main;
772     i32 retval = ntohl(mp->retval);
773
774     vam->retval = retval;
775     vam->shmem_result = (u8 *) mp->reply_in_shmem;
776     vam->result_ready = 1;
777 }
778
779 static void vl_api_cli_reply_t_handler_json
780 (vl_api_cli_reply_t * mp)
781 {
782     vat_main_t * vam = &vat_main;
783     vat_json_node_t node;
784     api_main_t * am = &api_main;
785     void * oldheap;
786     u8 * reply;
787
788     vat_json_init_object(&node);
789     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
790     vat_json_object_add_uint(&node, "reply_in_shmem", 
791                              ntohl(mp->reply_in_shmem));
792     /* Toss the shared-memory original... */
793     pthread_mutex_lock (&am->vlib_rp->mutex);
794     oldheap = svm_push_data_heap (am->vlib_rp);
795
796     reply = (u8 *)(mp->reply_in_shmem);
797     vec_free (reply);
798     
799     svm_pop_heap (oldheap);
800     pthread_mutex_unlock (&am->vlib_rp->mutex);
801
802     vat_json_print(vam->ofp, &node);
803     vat_json_free(&node);
804
805     vam->retval = ntohl(mp->retval);
806     vam->result_ready = 1;
807 }
808
809 static void vl_api_classify_add_del_table_reply_t_handler
810 (vl_api_classify_add_del_table_reply_t * mp)
811 {
812     vat_main_t * vam = &vat_main;
813     i32 retval = ntohl(mp->retval);
814     if (vam->async_mode) {
815         vam->async_errors += (retval < 0);
816     } else {
817         vam->retval = retval;
818         if (retval == 0 && 
819             ((mp->new_table_index != 0xFFFFFFFF) ||
820              (mp->skip_n_vectors != 0xFFFFFFFF) ||
821              (mp->match_n_vectors != 0xFFFFFFFF)))
822             /* 
823              * Note: this is just barely thread-safe, depends on
824              * the main thread spinning waiting for an answer...
825              */
826             errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
827                     ntohl(mp->new_table_index),
828                     ntohl(mp->skip_n_vectors), ntohl(mp->match_n_vectors));
829         vam->result_ready = 1;
830     }
831 }
832
833 static void vl_api_classify_add_del_table_reply_t_handler_json
834 (vl_api_classify_add_del_table_reply_t * mp)
835 {
836     vat_main_t * vam = &vat_main;
837     vat_json_node_t node;
838
839     vat_json_init_object(&node);
840     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
841     vat_json_object_add_uint(&node, "new_table_index", ntohl(mp->new_table_index));
842     vat_json_object_add_uint(&node, "skip_n_vectors", ntohl(mp->skip_n_vectors));
843     vat_json_object_add_uint(&node, "match_n_vectors", ntohl(mp->match_n_vectors));
844
845     vat_json_print(vam->ofp, &node);
846     vat_json_free(&node);
847
848     vam->retval = ntohl(mp->retval);
849     vam->result_ready = 1;
850 }
851
852 static void vl_api_get_node_index_reply_t_handler
853 (vl_api_get_node_index_reply_t * mp)
854 {
855     vat_main_t * vam = &vat_main;
856     i32 retval = ntohl(mp->retval);
857     if (vam->async_mode) {
858         vam->async_errors += (retval < 0);
859     } else {
860         vam->retval = retval;
861         if (retval == 0)
862             errmsg ("node index %d\n", ntohl(mp->node_index));
863         vam->result_ready = 1;
864     }
865 }
866
867 static void vl_api_get_node_index_reply_t_handler_json
868 (vl_api_get_node_index_reply_t * mp)
869 {
870     vat_main_t * vam = &vat_main;
871     vat_json_node_t node;
872
873     vat_json_init_object(&node);
874     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
875     vat_json_object_add_uint(&node, "node_index", ntohl(mp->node_index));
876
877     vat_json_print(vam->ofp, &node);
878     vat_json_free(&node);
879
880     vam->retval = ntohl(mp->retval);
881     vam->result_ready = 1;
882 }
883
884 static void vl_api_add_node_next_reply_t_handler
885 (vl_api_add_node_next_reply_t * mp)
886 {
887     vat_main_t * vam = &vat_main;
888     i32 retval = ntohl(mp->retval);
889     if (vam->async_mode) {
890         vam->async_errors += (retval < 0);
891     } else {
892         vam->retval = retval;
893         if (retval == 0)
894             errmsg ("next index %d\n", ntohl(mp->next_index));
895         vam->result_ready = 1;
896     }
897 }
898
899 static void vl_api_add_node_next_reply_t_handler_json
900 (vl_api_add_node_next_reply_t * mp)
901 {
902     vat_main_t * vam = &vat_main;
903     vat_json_node_t node;
904
905     vat_json_init_object(&node);
906     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
907     vat_json_object_add_uint(&node, "next_index", ntohl(mp->next_index));
908
909     vat_json_print(vam->ofp, &node);
910     vat_json_free(&node);
911
912     vam->retval = ntohl(mp->retval);
913     vam->result_ready = 1;
914 }
915
916 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler 
917 (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
918 {
919     vat_main_t * vam = &vat_main;
920     i32 retval = ntohl(mp->retval);
921     u32 sw_if_index = ntohl(mp->tunnel_sw_if_index);
922
923     if (retval >= 0 && sw_if_index != (u32)~0) {
924         errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
925     }
926     vam->retval = retval;
927     vam->result_ready = 1;
928 }
929
930 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
931 (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
932 {
933     vat_main_t * vam = &vat_main;
934     vat_json_node_t node;
935
936     vat_json_init_object(&node);
937     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
938     vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
939
940     vat_json_print(vam->ofp, &node);
941     vat_json_free(&node);
942
943     vam->retval = ntohl(mp->retval);
944     vam->result_ready = 1;
945 }
946
947
948 static void vl_api_show_version_reply_t_handler 
949 (vl_api_show_version_reply_t * mp)
950 {
951     vat_main_t * vam = &vat_main;
952     i32 retval = ntohl(mp->retval);
953
954     if (retval >= 0) {
955         errmsg ("        program: %s\n", mp->program);
956         errmsg ("        version: %s\n", mp->version);
957         errmsg ("     build date: %s\n", mp->build_date);
958         errmsg ("build directory: %s\n", mp->build_directory);
959     }
960     vam->retval = retval;
961     vam->result_ready = 1;
962 }
963
964 static void vl_api_show_version_reply_t_handler_json
965 (vl_api_show_version_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_string_copy(&node, "program", mp->program);
973     vat_json_object_add_string_copy(&node, "version", mp->version);
974     vat_json_object_add_string_copy(&node, "build_date", mp->build_date);
975     vat_json_object_add_string_copy(&node, "build_directory", mp->build_directory);
976
977     vat_json_print(vam->ofp, &node);
978     vat_json_free(&node);
979
980     vam->retval = ntohl(mp->retval);
981     vam->result_ready = 1;
982 }
983
984 static void vl_api_ip4_arp_event_t_handler 
985 (vl_api_ip4_arp_event_t * mp)
986 {
987     vat_main_t * vam = &vat_main;
988     errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
989             format_ip4_address, &mp->address,
990             format_ethernet_address, mp->new_mac, mp->sw_if_index);
991 }
992
993 static void vl_api_ip4_arp_event_t_handler_json
994 (vl_api_ip4_arp_event_t * mp)
995 {
996     /* JSON output not supported */
997 }
998
999 /* 
1000  * Special-case: build the bridge domain table, maintain
1001  * the next bd id vbl.
1002  */
1003 static void vl_api_bridge_domain_details_t_handler
1004 (vl_api_bridge_domain_details_t * mp)
1005 {
1006     vat_main_t * vam = &vat_main;
1007     u32 n_sw_ifs =  ntohl (mp->n_sw_ifs);
1008
1009     fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1010              " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1011
1012     fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1013              ntohl (mp->bd_id), mp->learn, mp->forward,
1014              mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1015
1016     if (n_sw_ifs)
1017         fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1018                  "Interface Name");
1019 }
1020
1021 static void vl_api_bridge_domain_details_t_handler_json
1022 (vl_api_bridge_domain_details_t * mp)
1023 {
1024     vat_main_t * vam = &vat_main;
1025     vat_json_node_t *node, *array = NULL;
1026
1027     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1028         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1029         vat_json_init_array(&vam->json_tree);
1030     }
1031     node = vat_json_array_add(&vam->json_tree);
1032
1033     vat_json_init_object(node);
1034     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1035     vat_json_object_add_uint(node, "flood", mp->flood);
1036     vat_json_object_add_uint(node, "forward", mp->forward);
1037     vat_json_object_add_uint(node, "learn", mp->learn);
1038     vat_json_object_add_uint(node, "bvi_sw_if_index", ntohl(mp->bvi_sw_if_index));
1039     vat_json_object_add_uint(node, "n_sw_ifs", ntohl(mp->n_sw_ifs));
1040     array = vat_json_object_add(node, "sw_if");
1041     vat_json_init_array(array);
1042 }
1043
1044 /* 
1045  * Special-case: build the bridge domain sw if table.
1046  */
1047 static void vl_api_bridge_domain_sw_if_details_t_handler
1048 (vl_api_bridge_domain_sw_if_details_t * mp)
1049 {
1050     vat_main_t * vam = &vat_main;
1051     hash_pair_t * p;
1052     u8 * sw_if_name = 0;
1053     u32 sw_if_index;
1054
1055     sw_if_index = ntohl (mp->sw_if_index);
1056     hash_foreach_pair (p, vam->sw_if_index_by_interface_name, 
1057     ({
1058         if ((u32) p->value[0] == sw_if_index) {
1059             sw_if_name = (u8 *)(p->key);
1060             break;
1061         }
1062     }));
1063    
1064     fformat (vam->ofp, "%7d     %3d  %s", sw_if_index, 
1065              mp->shg, sw_if_name ? (char *)sw_if_name : 
1066              "sw_if_index not found!");
1067 }
1068
1069 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1070 (vl_api_bridge_domain_sw_if_details_t * mp)
1071 {
1072     vat_main_t * vam = &vat_main;
1073     vat_json_node_t *node = NULL;
1074     uword last_index = 0;
1075
1076     ASSERT(VAT_JSON_ARRAY == vam->json_tree.type);
1077     ASSERT(vec_len(vam->json_tree.array) >= 1);
1078     last_index = vec_len(vam->json_tree.array) - 1;
1079     node = &vam->json_tree.array[last_index];
1080     node = vat_json_object_get_element(node, "sw_if");
1081     ASSERT(NULL != node);
1082     node = vat_json_array_add(node);
1083
1084     vat_json_init_object(node);
1085     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
1086     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
1087     vat_json_object_add_uint(node, "shg", mp->shg);
1088 }
1089
1090 static void vl_api_control_ping_reply_t_handler
1091 (vl_api_control_ping_reply_t * mp)
1092 {
1093     vat_main_t * vam = &vat_main;
1094     i32 retval = ntohl(mp->retval);
1095     if (vam->async_mode) {
1096         vam->async_errors += (retval < 0);
1097     } else {
1098         vam->retval = retval;
1099         vam->result_ready = 1;
1100     }
1101 }
1102
1103 static void vl_api_control_ping_reply_t_handler_json
1104 (vl_api_control_ping_reply_t * mp)
1105 {
1106     vat_main_t * vam = &vat_main;
1107     i32 retval = ntohl(mp->retval);
1108
1109     if (VAT_JSON_NONE != vam->json_tree.type) {
1110         vat_json_print(vam->ofp, &vam->json_tree);
1111         vat_json_free(&vam->json_tree);
1112         vam->json_tree.type = VAT_JSON_NONE;
1113     } else {
1114         /* just print [] */
1115         vat_json_init_array(&vam->json_tree);
1116         vat_json_print(vam->ofp, &vam->json_tree);
1117         vam->json_tree.type = VAT_JSON_NONE;
1118     }
1119
1120     vam->retval = retval;
1121     vam->result_ready = 1;
1122 }
1123
1124 static void vl_api_l2_flags_reply_t_handler
1125 (vl_api_l2_flags_reply_t * mp)
1126 {
1127     vat_main_t * vam = &vat_main;
1128     i32 retval = ntohl(mp->retval);
1129     if (vam->async_mode) {
1130         vam->async_errors += (retval < 0);
1131     } else {
1132         vam->retval = retval;
1133         vam->result_ready = 1;
1134     }
1135 }
1136
1137 static void vl_api_l2_flags_reply_t_handler_json
1138 (vl_api_l2_flags_reply_t * mp)
1139 {
1140     vat_main_t * vam = &vat_main;
1141     vat_json_node_t node;
1142
1143     vat_json_init_object(&node);
1144     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1145     vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1146
1147     vat_json_print(vam->ofp, &node);
1148     vat_json_free(&node);
1149
1150     vam->retval = ntohl(mp->retval);
1151     vam->result_ready = 1;
1152 }
1153
1154 static void vl_api_bridge_flags_reply_t_handler
1155 (vl_api_bridge_flags_reply_t * mp)
1156 {
1157     vat_main_t * vam = &vat_main;
1158     i32 retval = ntohl(mp->retval);
1159     if (vam->async_mode) {
1160         vam->async_errors += (retval < 0);
1161     } else {
1162         vam->retval = retval;
1163         vam->result_ready = 1;
1164     }
1165 }
1166
1167 static void vl_api_bridge_flags_reply_t_handler_json
1168 (vl_api_bridge_flags_reply_t * mp)
1169 {
1170     vat_main_t * vam = &vat_main;
1171     vat_json_node_t node;
1172
1173     vat_json_init_object(&node);
1174     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1175     vat_json_object_add_uint(&node, "resulting_feature_bitmap", ntohl(mp->resulting_feature_bitmap));
1176
1177     vat_json_print(vam->ofp, &node);
1178     vat_json_free(&node);
1179
1180     vam->retval = ntohl(mp->retval);
1181     vam->result_ready = 1;
1182 }
1183
1184 static void vl_api_tap_connect_reply_t_handler
1185 (vl_api_tap_connect_reply_t * mp)
1186 {
1187     vat_main_t * vam = &vat_main;
1188     i32 retval = ntohl(mp->retval);
1189     if (vam->async_mode) {
1190         vam->async_errors += (retval < 0);
1191     } else {
1192         vam->retval = retval;
1193         vam->sw_if_index = ntohl (mp->sw_if_index);
1194         vam->result_ready = 1;
1195     }
1196     
1197 }
1198
1199 static void vl_api_tap_connect_reply_t_handler_json
1200 (vl_api_tap_connect_reply_t * mp)
1201 {
1202     vat_main_t * vam = &vat_main;
1203     vat_json_node_t node;
1204
1205     vat_json_init_object(&node);
1206     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1207     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1208
1209     vat_json_print(vam->ofp, &node);
1210     vat_json_free(&node);
1211
1212     vam->retval = ntohl(mp->retval);
1213     vam->result_ready = 1;
1214     
1215 }
1216
1217 static void vl_api_tap_modify_reply_t_handler
1218 (vl_api_tap_modify_reply_t * mp)
1219 {
1220     vat_main_t * vam = &vat_main;
1221     i32 retval = ntohl(mp->retval);
1222     if (vam->async_mode) {
1223         vam->async_errors += (retval < 0);
1224     } else {
1225         vam->retval = retval;
1226         vam->sw_if_index = ntohl (mp->sw_if_index);
1227         vam->result_ready = 1;
1228     }
1229 }
1230
1231 static void vl_api_tap_modify_reply_t_handler_json
1232 (vl_api_tap_modify_reply_t * mp)
1233 {
1234     vat_main_t * vam = &vat_main;
1235     vat_json_node_t node;
1236
1237     vat_json_init_object(&node);
1238     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1239     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1240
1241     vat_json_print(vam->ofp, &node);
1242     vat_json_free(&node);
1243
1244     vam->retval = ntohl(mp->retval);
1245     vam->result_ready = 1;
1246 }
1247
1248 static void vl_api_tap_delete_reply_t_handler
1249 (vl_api_tap_delete_reply_t * mp)
1250 {
1251     vat_main_t * vam = &vat_main;
1252     i32 retval = ntohl(mp->retval);
1253     if (vam->async_mode) {
1254         vam->async_errors += (retval < 0);
1255     } else {
1256         vam->retval = retval;
1257         vam->result_ready = 1;
1258     }
1259 }
1260
1261 static void vl_api_tap_delete_reply_t_handler_json
1262 (vl_api_tap_delete_reply_t * mp)
1263 {
1264     vat_main_t * vam = &vat_main;
1265     vat_json_node_t node;
1266
1267     vat_json_init_object(&node);
1268     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1269
1270     vat_json_print(vam->ofp, &node);
1271     vat_json_free(&node);
1272
1273     vam->retval = ntohl(mp->retval);
1274     vam->result_ready = 1;
1275 }
1276
1277 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1278 (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1279 {
1280     vat_main_t * vam = &vat_main;
1281     i32 retval = ntohl(mp->retval);
1282     if (vam->async_mode) {
1283         vam->async_errors += (retval < 0);
1284     } else {
1285         vam->retval = retval;
1286         vam->result_ready = 1;
1287     }
1288 }
1289
1290 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1291 (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1292 {
1293     vat_main_t * vam = &vat_main;
1294     vat_json_node_t node;
1295
1296     vat_json_init_object(&node);
1297     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1298     vat_json_object_add_uint(&node, "tunnel_sw_if_index", ntohl(mp->tunnel_sw_if_index));
1299
1300     vat_json_print(vam->ofp, &node);
1301     vat_json_free(&node);
1302
1303     vam->retval = ntohl(mp->retval);
1304     vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1308 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1309 {
1310     vat_main_t * vam = &vat_main;
1311     i32 retval = ntohl(mp->retval);
1312     if (vam->async_mode) {
1313         vam->async_errors += (retval < 0);
1314     } else {
1315         vam->retval = retval;
1316         vam->sw_if_index = ntohl (mp->sw_if_index);
1317         vam->result_ready = 1;
1318     }
1319 }
1320
1321 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1322 (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1323 {
1324     vat_main_t * vam = &vat_main;
1325     vat_json_node_t node;
1326
1327     vat_json_init_object(&node);
1328     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1329     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1330
1331     vat_json_print(vam->ofp, &node);
1332     vat_json_free(&node);
1333
1334     vam->retval = ntohl(mp->retval);
1335     vam->result_ready = 1;
1336 }
1337
1338 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1339 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1340 {
1341     vat_main_t * vam = &vat_main;
1342     i32 retval = ntohl(mp->retval);
1343     if (vam->async_mode) {
1344         vam->async_errors += (retval < 0);
1345     } else {
1346         vam->retval = retval;
1347         vam->sw_if_index = ntohl (mp->sw_if_index);
1348         vam->result_ready = 1;
1349     }
1350 }
1351
1352 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1353 (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1354 {
1355     vat_main_t * vam = &vat_main;
1356     vat_json_node_t node;
1357
1358     vat_json_init_object(&node);
1359     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1360     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1361
1362     vat_json_print(vam->ofp, &node);
1363     vat_json_free(&node);
1364
1365     vam->retval = ntohl(mp->retval);
1366     vam->result_ready = 1;
1367 }
1368
1369 static void vl_api_gre_add_del_tunnel_reply_t_handler
1370 (vl_api_gre_add_del_tunnel_reply_t * mp)
1371 {
1372     vat_main_t * vam = &vat_main;
1373     i32 retval = ntohl(mp->retval);
1374     if (vam->async_mode) {
1375         vam->async_errors += (retval < 0);
1376     } else {
1377         vam->retval = retval;
1378         vam->sw_if_index = ntohl (mp->sw_if_index);
1379         vam->result_ready = 1;
1380     }
1381 }
1382
1383 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1384 (vl_api_gre_add_del_tunnel_reply_t * mp)
1385 {
1386     vat_main_t * vam = &vat_main;
1387     vat_json_node_t node;
1388
1389     vat_json_init_object(&node);
1390     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1391     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1392
1393     vat_json_print(vam->ofp, &node);
1394     vat_json_free(&node);
1395
1396     vam->retval = ntohl(mp->retval);
1397     vam->result_ready = 1;
1398 }
1399
1400 static void vl_api_create_vhost_user_if_reply_t_handler
1401 (vl_api_create_vhost_user_if_reply_t * mp)
1402 {
1403     vat_main_t * vam = &vat_main;
1404     i32 retval = ntohl(mp->retval);
1405     if (vam->async_mode) {
1406         vam->async_errors += (retval < 0);
1407     } else {
1408         vam->retval = retval;
1409         vam->sw_if_index = ntohl (mp->sw_if_index);
1410         vam->result_ready = 1;
1411     }
1412 }
1413
1414 static void vl_api_create_vhost_user_if_reply_t_handler_json
1415 (vl_api_create_vhost_user_if_reply_t * mp)
1416 {
1417     vat_main_t * vam = &vat_main;
1418     vat_json_node_t node;
1419
1420     vat_json_init_object(&node);
1421     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1422     vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
1423
1424     vat_json_print(vam->ofp, &node);
1425     vat_json_free(&node);
1426
1427     vam->retval = ntohl(mp->retval);
1428     vam->result_ready = 1;
1429 }
1430
1431 static void vl_api_ip_address_details_t_handler
1432 (vl_api_ip_address_details_t * mp)
1433 {
1434     vat_main_t * vam = &vat_main;
1435     static ip_address_details_t empty_ip_address_details = {{0}};
1436     ip_address_details_t * address = NULL;
1437     ip_details_t * current_ip_details = NULL;
1438     ip_details_t * details = NULL;
1439
1440     details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1441
1442     if (!details || vam->current_sw_if_index >= vec_len(details)
1443             || !details[vam->current_sw_if_index].present) {
1444         errmsg ("ip address details arrived but not stored\n");
1445         errmsg ("ip_dump should be called first\n");
1446         return;
1447     }
1448
1449     current_ip_details = vec_elt_at_index(details,
1450             vam->current_sw_if_index);
1451
1452 #define addresses (current_ip_details->addr)
1453
1454     vec_validate_init_empty(addresses, vec_len(addresses),
1455             empty_ip_address_details);
1456
1457     address = vec_elt_at_index(addresses, vec_len(addresses) - 1);
1458
1459     clib_memcpy(&address->ip, &mp->ip, sizeof(address->ip));
1460     address->prefix_length = mp->prefix_length;
1461 #undef addresses
1462 }
1463
1464 static void vl_api_ip_address_details_t_handler_json
1465 (vl_api_ip_address_details_t * mp)
1466 {
1467     vat_main_t * vam = &vat_main;
1468     vat_json_node_t *node = NULL;
1469     struct in6_addr ip6;
1470     struct in_addr ip4;
1471
1472     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1473         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1474         vat_json_init_array(&vam->json_tree);
1475     }
1476     node = vat_json_array_add(&vam->json_tree);
1477
1478     vat_json_init_object(node);
1479     if (vam->is_ipv6) {
1480         clib_memcpy(&ip6, mp->ip, sizeof(ip6));
1481         vat_json_object_add_ip6(node, "ip",  ip6);
1482     } else {
1483         clib_memcpy(&ip4, mp->ip, sizeof(ip4));
1484         vat_json_object_add_ip4(node, "ip", ip4);
1485     }
1486     vat_json_object_add_uint(node, "prefix_length", mp->prefix_length);
1487 }
1488
1489 static void vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1490 {
1491     vat_main_t * vam = &vat_main;
1492     static ip_details_t empty_ip_details = {0};
1493     ip_details_t * ip = NULL;
1494     u32 sw_if_index = ~0;
1495
1496     sw_if_index = ntohl(mp->sw_if_index);
1497
1498     vec_validate_init_empty(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1499             sw_if_index, empty_ip_details);
1500
1501     ip = vec_elt_at_index(vam->ip_details_by_sw_if_index[vam->is_ipv6],
1502             sw_if_index);
1503
1504     ip->present = 1;
1505 }
1506
1507 static void vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1508 {
1509     vat_main_t * vam = &vat_main;
1510
1511     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1512         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1513         vat_json_init_array(&vam->json_tree);
1514     }
1515     vat_json_array_add_uint(&vam->json_tree, clib_net_to_host_u32(mp->sw_if_index));
1516 }
1517
1518 static void vl_api_map_domain_details_t_handler_json
1519 (vl_api_map_domain_details_t * mp)
1520 {
1521     vat_json_node_t * node = NULL;
1522     vat_main_t * vam = &vat_main;
1523     struct in6_addr ip6;
1524     struct in_addr ip4;
1525
1526     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1527         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1528         vat_json_init_array(&vam->json_tree);
1529     }
1530
1531     node = vat_json_array_add(&vam->json_tree);
1532     vat_json_init_object(node);
1533
1534     vat_json_object_add_uint(node, "domain_index", clib_net_to_host_u32(mp->domain_index));
1535     clib_memcpy(&ip6, mp->ip6_prefix, sizeof(ip6));
1536     vat_json_object_add_ip6(node, "ip6_prefix", ip6);
1537     clib_memcpy(&ip4, mp->ip4_prefix, sizeof(ip4));
1538     vat_json_object_add_ip4(node, "ip4_prefix", ip4);
1539     clib_memcpy(&ip6, mp->ip6_src, sizeof(ip6));
1540     vat_json_object_add_ip6(node, "ip6_src", ip6);
1541     vat_json_object_add_int(node, "ip6_prefix_len", mp->ip6_prefix_len);
1542     vat_json_object_add_int(node, "ip4_prefix_len", mp->ip4_prefix_len);
1543     vat_json_object_add_int(node, "ip6_src_len", mp->ip6_src_len);
1544     vat_json_object_add_int(node, "ea_bits_len", mp->ea_bits_len);
1545     vat_json_object_add_int(node, "psid_offset", mp->psid_offset);
1546     vat_json_object_add_int(node, "psid_length", mp->psid_length);
1547     vat_json_object_add_uint(node, "flags", mp->flags);
1548     vat_json_object_add_uint(node, "mtu", clib_net_to_host_u16(mp->mtu));
1549     vat_json_object_add_int(node, "is_translation", mp->is_translation);
1550 }
1551
1552 static void vl_api_map_domain_details_t_handler
1553 (vl_api_map_domain_details_t * mp)
1554 {
1555     vat_main_t * vam = &vat_main;
1556
1557     if (mp->is_translation) {
1558         fformat(vam->ofp,  "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1559                   format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1560                   format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1561                   format_ip6_address, mp->ip6_src, mp->ip6_src_len, clib_net_to_host_u32(mp->domain_index));
1562     } else {
1563         fformat(vam->ofp,  "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1564                   format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1565                   format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1566                   format_ip6_address, mp->ip6_src, clib_net_to_host_u32(mp->domain_index));
1567     }
1568     fformat(vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1569             mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu, mp->is_translation? "map-t":"");
1570 }
1571
1572 static void vl_api_map_rule_details_t_handler_json
1573 (vl_api_map_rule_details_t * mp)
1574 {
1575     struct in6_addr ip6;
1576     vat_json_node_t * node = NULL;
1577     vat_main_t * vam = &vat_main;
1578
1579     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1580         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1581         vat_json_init_array(&vam->json_tree);
1582     }
1583
1584     node = vat_json_array_add(&vam->json_tree);
1585     vat_json_init_object(node);
1586
1587     vat_json_object_add_uint(node, "psid", clib_net_to_host_u16(mp->psid));
1588     clib_memcpy(&ip6, mp->ip6_dst, sizeof(ip6));
1589     vat_json_object_add_ip6(node, "ip6_dst", ip6);
1590 }
1591
1592 static void vl_api_map_rule_details_t_handler
1593 (vl_api_map_rule_details_t * mp)
1594 {
1595     vat_main_t * vam = &vat_main;
1596     fformat(vam->ofp, " %d (psid) %U (ip6-dst)\n", clib_net_to_host_u16(mp->psid),
1597             format_ip6_address, mp->ip6_dst);
1598 }
1599
1600 static void vl_api_dhcp_compl_event_t_handler
1601 (vl_api_dhcp_compl_event_t * mp)
1602 {
1603     vat_main_t * vam = &vat_main;
1604     errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1605             "router_addr %U host_mac %U\n",
1606             mp->pid, mp->is_ipv6 ? "ipv6":"ipv4", mp->hostname,
1607             format_ip4_address, &mp->host_address,
1608             format_ip4_address, &mp->router_address,
1609             format_ethernet_address, mp->host_mac);
1610 }
1611
1612 static void vl_api_dhcp_compl_event_t_handler_json
1613 (vl_api_dhcp_compl_event_t * mp)
1614 {
1615     /* JSON output not supported */
1616 }
1617
1618 static void set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1619                                           u32 counter)
1620 {
1621     vat_main_t * vam = &vat_main;
1622     static u64 default_counter = 0;
1623
1624     vec_validate_init_empty(vam->simple_interface_counters, vnet_counter_type, NULL);
1625     vec_validate_init_empty(vam->simple_interface_counters[vnet_counter_type],
1626                             sw_if_index, default_counter);
1627     vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1628 }
1629
1630 static void set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1631                                             interface_counter_t counter)
1632 {
1633     vat_main_t * vam = &vat_main;
1634     static interface_counter_t default_counter = {0, };
1635
1636     vec_validate_init_empty(vam->combined_interface_counters, vnet_counter_type, NULL);
1637     vec_validate_init_empty(vam->combined_interface_counters[vnet_counter_type],
1638                             sw_if_index, default_counter);
1639     vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1640 }
1641
1642 static void vl_api_vnet_interface_counters_t_handler
1643 (vl_api_vnet_interface_counters_t *mp)
1644 {
1645     /* not supported */
1646 }
1647
1648 static void vl_api_vnet_interface_counters_t_handler_json
1649 (vl_api_vnet_interface_counters_t *mp)
1650 {
1651     interface_counter_t counter;
1652     vlib_counter_t *v;
1653     u64 *v_packets;
1654     u64 packets;
1655     u32 count;
1656     u32 first_sw_if_index;
1657     int i;
1658
1659     count = ntohl(mp->count);
1660     first_sw_if_index = ntohl(mp->first_sw_if_index);
1661
1662     if (!mp->is_combined) {
1663         v_packets = (u64*)&mp->data;
1664         for (i = 0; i < count; i++) {
1665             packets = clib_net_to_host_u64(clib_mem_unaligned(v_packets, u64));
1666             set_simple_interface_counter(mp->vnet_counter_type,
1667                     first_sw_if_index + i, packets);
1668             v_packets++;
1669         }
1670     } else {
1671         v = (vlib_counter_t*)&mp->data;
1672         for (i = 0; i < count; i++) {
1673             counter.packets = clib_net_to_host_u64(
1674                     clib_mem_unaligned(&v->packets, u64));
1675             counter.bytes = clib_net_to_host_u64(
1676                     clib_mem_unaligned(&v->bytes, u64));
1677             set_combined_interface_counter(mp->vnet_counter_type,
1678                     first_sw_if_index + i, counter);
1679             v++;
1680         }
1681     }
1682 }
1683
1684 static u32 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1685 {
1686     vat_main_t * vam = &vat_main;
1687     u32 i;
1688
1689     for (i = 0; i < vec_len(vam->ip4_fib_counters_vrf_id_by_index); i++) {
1690         if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id) {
1691             return i;
1692         }
1693     }
1694     return ~0;
1695 }
1696
1697 static u32 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1698 {
1699     vat_main_t * vam = &vat_main;
1700     u32 i;
1701
1702     for (i = 0; i < vec_len(vam->ip6_fib_counters_vrf_id_by_index); i++) {
1703         if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id) {
1704             return i;
1705         }
1706     }
1707     return ~0;
1708 }
1709
1710 static void vl_api_vnet_ip4_fib_counters_t_handler
1711 (vl_api_vnet_ip4_fib_counters_t *mp)
1712 {
1713     /* not supported */
1714 }
1715
1716 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1717 (vl_api_vnet_ip4_fib_counters_t *mp)
1718 {
1719     vat_main_t * vam = &vat_main;
1720     vl_api_ip4_fib_counter_t *v;
1721     ip4_fib_counter_t *counter;
1722     struct in_addr ip4;
1723     u32 vrf_id;
1724     u32 vrf_index;
1725     u32 count;
1726     int i;
1727
1728     vrf_id = ntohl(mp->vrf_id);
1729     vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1730     if (~0 == vrf_index) {
1731         vrf_index = vec_len(vam->ip4_fib_counters_vrf_id_by_index);
1732         vec_validate(vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1733         vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1734         vec_validate(vam->ip4_fib_counters, vrf_index);
1735         vam->ip4_fib_counters[vrf_index] = NULL;
1736     }
1737
1738     vec_free(vam->ip4_fib_counters[vrf_index]);
1739     v = (vl_api_ip4_fib_counter_t*)&mp->c;
1740     count = ntohl(mp->count);
1741     for (i = 0; i < count; i++) {
1742         vec_validate(vam->ip4_fib_counters[vrf_index], i);
1743         counter = &vam->ip4_fib_counters[vrf_index][i];
1744         clib_memcpy(&ip4, &v->address, sizeof(ip4));
1745         counter->address = ip4;
1746         counter->address_length = v->address_length;
1747         counter->packets = clib_net_to_host_u64(v->packets);
1748         counter->bytes = clib_net_to_host_u64(v->bytes);
1749         v++;
1750     }
1751 }
1752
1753 static void vl_api_vnet_ip6_fib_counters_t_handler
1754 (vl_api_vnet_ip6_fib_counters_t *mp)
1755 {
1756     /* not supported */
1757 }
1758
1759 static void vl_api_vnet_ip6_fib_counters_t_handler_json
1760 (vl_api_vnet_ip6_fib_counters_t *mp)
1761 {
1762     vat_main_t * vam = &vat_main;
1763     vl_api_ip6_fib_counter_t *v;
1764     ip6_fib_counter_t *counter;
1765     struct in6_addr ip6;
1766     u32 vrf_id;
1767     u32 vrf_index;
1768     u32 count;
1769     int i;
1770
1771     vrf_id = ntohl(mp->vrf_id);
1772     vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id(vrf_id);
1773     if (~0 == vrf_index) {
1774         vrf_index = vec_len(vam->ip6_fib_counters_vrf_id_by_index);
1775         vec_validate(vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
1776         vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1777         vec_validate(vam->ip6_fib_counters, vrf_index);
1778         vam->ip6_fib_counters[vrf_index] = NULL;
1779     }
1780
1781     vec_free(vam->ip6_fib_counters[vrf_index]);
1782     v = (vl_api_ip6_fib_counter_t*)&mp->c;
1783     count = ntohl(mp->count);
1784     for (i = 0; i < count; i++) {
1785         vec_validate(vam->ip6_fib_counters[vrf_index], i);
1786         counter = &vam->ip6_fib_counters[vrf_index][i];
1787         clib_memcpy(&ip6, &v->address, sizeof(ip6));
1788         counter->address = ip6;
1789         counter->address_length = v->address_length;
1790         counter->packets = clib_net_to_host_u64(v->packets);
1791         counter->bytes = clib_net_to_host_u64(v->bytes);
1792         v++;
1793     }
1794 }
1795
1796 static void vl_api_get_first_msg_id_reply_t_handler
1797 (vl_api_get_first_msg_id_reply_t * mp)
1798 {
1799     vat_main_t * vam = &vat_main;
1800     i32 retval = ntohl(mp->retval);
1801     
1802     if (vam->async_mode) {
1803         vam->async_errors += (retval < 0);
1804     } else {
1805         vam->retval = retval;
1806         vam->result_ready = 1;
1807     }
1808     if (retval >= 0) {
1809         errmsg ("first message id %d\n", ntohs(mp->first_msg_id));
1810     }
1811 }
1812
1813 static void vl_api_get_first_msg_id_reply_t_handler_json
1814 (vl_api_get_first_msg_id_reply_t * mp)
1815 {
1816     vat_main_t * vam = &vat_main;
1817     vat_json_node_t node;
1818
1819     vat_json_init_object(&node);
1820     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1821     vat_json_object_add_uint(&node, "first_msg_id", 
1822                              (uint) ntohs(mp->first_msg_id));
1823
1824     vat_json_print(vam->ofp, &node);
1825     vat_json_free(&node);
1826
1827     vam->retval = ntohl(mp->retval);
1828     vam->result_ready = 1;
1829 }
1830
1831 static void vl_api_get_node_graph_reply_t_handler
1832 (vl_api_get_node_graph_reply_t * mp)
1833 {
1834     vat_main_t * vam = &vat_main;
1835     api_main_t * am = &api_main;
1836     i32 retval = ntohl(mp->retval);
1837     u8 * pvt_copy, * reply;
1838     void * oldheap;
1839     vlib_node_t * node;
1840     int i;
1841     
1842     if (vam->async_mode) {
1843         vam->async_errors += (retval < 0);
1844     } else {
1845         vam->retval = retval;
1846         vam->result_ready = 1;
1847     }
1848
1849     /* "Should never happen..." */
1850     if (retval != 0)
1851         return;
1852
1853     reply = (u8 *)(mp->reply_in_shmem);
1854     pvt_copy = vec_dup (reply);
1855
1856     /* Toss the shared-memory original... */
1857     pthread_mutex_lock (&am->vlib_rp->mutex);
1858     oldheap = svm_push_data_heap (am->vlib_rp);
1859
1860     vec_free (reply);
1861     
1862     svm_pop_heap (oldheap);
1863     pthread_mutex_unlock (&am->vlib_rp->mutex);
1864
1865     if (vam->graph_nodes) {
1866         hash_free (vam->graph_node_index_by_name);
1867
1868         for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1869             node = vam->graph_nodes[i];
1870             vec_free (node->name);
1871             vec_free (node->next_nodes);
1872             vec_free (node);
1873         }
1874         vec_free(vam->graph_nodes);
1875     }
1876
1877     vam->graph_node_index_by_name = hash_create_string (0, sizeof(uword));
1878     vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1879     vec_free (pvt_copy);
1880
1881     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
1882         node = vam->graph_nodes[i];
1883         hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1884     }
1885 }
1886
1887 static void vl_api_get_node_graph_reply_t_handler_json
1888 (vl_api_get_node_graph_reply_t * mp)
1889 {
1890     vat_main_t * vam = &vat_main;
1891     api_main_t * am = &api_main;
1892     void * oldheap;
1893     vat_json_node_t node;
1894     u8 * reply;
1895
1896     /* $$$$ make this real? */
1897     vat_json_init_object(&node);
1898     vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
1899     vat_json_object_add_uint(&node, "reply_in_shmem", mp->reply_in_shmem);
1900
1901     reply = (u8 *)(mp->reply_in_shmem);
1902
1903     /* Toss the shared-memory original... */
1904     pthread_mutex_lock (&am->vlib_rp->mutex);
1905     oldheap = svm_push_data_heap (am->vlib_rp);
1906
1907     vec_free (reply);
1908     
1909     svm_pop_heap (oldheap);
1910     pthread_mutex_unlock (&am->vlib_rp->mutex);
1911
1912     vat_json_print(vam->ofp, &node);
1913     vat_json_free(&node);
1914
1915     vam->retval = ntohl(mp->retval);
1916     vam->result_ready = 1;
1917 }
1918
1919 static void
1920 vl_api_lisp_locator_set_details_t_handler (
1921     vl_api_lisp_locator_set_details_t *mp)
1922 {
1923     vat_main_t *vam = &vat_main;
1924     u8 * tmp_str = NULL;
1925
1926     if (mp->local) {
1927       fformat(vam->ofp, "%=20s%=16d%=16d%=16d\n",
1928               mp->locator_set_name,
1929               ntohl(mp->sw_if_index),
1930               mp->priority,
1931               mp->weight);
1932     } else {
1933       tmp_str = format(0,"%U/%d",
1934               mp->is_ipv6 ? format_ip6_address : format_ip4_address,
1935               mp->ip_address,
1936               mp->prefix_len);
1937
1938       fformat(vam->ofp, "%=20s%=16s%=16d%=16d\n",
1939               mp->locator_set_name,
1940               tmp_str,
1941               mp->priority,
1942               mp->weight);
1943       vec_free(tmp_str);
1944     }
1945 }
1946
1947 static void
1948 vl_api_lisp_locator_set_details_t_handler_json (
1949     vl_api_lisp_locator_set_details_t *mp)
1950 {
1951     vat_main_t *vam = &vat_main;
1952     vat_json_node_t *node = NULL;
1953     struct in6_addr ip6;
1954     struct in_addr ip4;
1955
1956     if (VAT_JSON_ARRAY != vam->json_tree.type) {
1957         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
1958         vat_json_init_array(&vam->json_tree);
1959     }
1960     node = vat_json_array_add(&vam->json_tree);
1961
1962     vat_json_init_object(node);
1963     vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
1964     if (mp->local) {
1965         vat_json_object_add_uint(node, "locator", ntohl(mp->sw_if_index));
1966     } else {
1967         if (mp->is_ipv6) {
1968             clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
1969             vat_json_object_add_ip6(node, "locator", ip6);
1970         } else {
1971             clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
1972             vat_json_object_add_ip4(node, "locator", ip4);
1973         }
1974         vat_json_object_add_uint(node, "prefix-length", mp->prefix_len);
1975     }
1976     vat_json_object_add_uint(node, "priority", mp->priority);
1977     vat_json_object_add_uint(node, "weight", mp->weight);
1978 }
1979
1980 static void
1981 vl_api_lisp_local_eid_table_details_t_handler (
1982     vl_api_lisp_local_eid_table_details_t *mp)
1983 {
1984     vat_main_t *vam = &vat_main;
1985     u8 *prefix;
1986
1987     prefix = format(0, "%U/%d",
1988                     mp->eid_is_ipv6 ? format_ip6_address : format_ip4_address,
1989                     mp->eid_ip_address,
1990                     mp->eid_prefix_len);
1991
1992     fformat(vam->ofp, "%=20s%=30s\n",
1993             mp->locator_set_name, prefix);
1994
1995     vec_free(prefix);
1996 }
1997
1998 static void
1999 vl_api_lisp_local_eid_table_details_t_handler_json (
2000     vl_api_lisp_local_eid_table_details_t *mp)
2001 {
2002     vat_main_t *vam = &vat_main;
2003     vat_json_node_t *node = NULL;
2004     struct in6_addr ip6;
2005     struct in_addr ip4;
2006
2007     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2008         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2009         vat_json_init_array(&vam->json_tree);
2010     }
2011     node = vat_json_array_add(&vam->json_tree);
2012
2013     vat_json_init_object(node);
2014     vat_json_object_add_string_copy(node, "locator-set", mp->locator_set_name);
2015     if (mp->eid_is_ipv6) {
2016         clib_memcpy(&ip6, mp->eid_ip_address, sizeof(ip6));
2017         vat_json_object_add_ip6(node, "eid address", ip6);
2018     } else {
2019         clib_memcpy(&ip4, mp->eid_ip_address, sizeof(ip4));
2020         vat_json_object_add_ip4(node, "eid address", ip4);
2021     }
2022     vat_json_object_add_uint(node, "eid prefix len", mp->eid_prefix_len);
2023 }
2024
2025 static u8 *
2026 format_decap_next (u8 * s, va_list * args)
2027 {
2028   u32 next_index = va_arg (*args, u32);
2029
2030   switch (next_index)
2031     {
2032     case LISP_GPE_INPUT_NEXT_DROP:
2033       return format (s, "drop");
2034     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2035       return format (s, "ip4");
2036     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2037       return format (s, "ip6");
2038     default:
2039       return format (s, "unknown %d", next_index);
2040     }
2041   return s;
2042 }
2043
2044 static void
2045 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
2046 {
2047     vat_main_t *vam = &vat_main;
2048     u8 *iid_str;
2049     u8 *flag_str = NULL;
2050
2051     iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
2052
2053 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2054   foreach_lisp_gpe_flag_bit;
2055 #undef _
2056
2057     fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2058             "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2059             mp->tunnels,
2060             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2061             mp->source_ip,
2062             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2063             mp->destination_ip,
2064             ntohl(mp->encap_fib_id),
2065             ntohl(mp->decap_fib_id),
2066             format_decap_next, ntohl(mp->dcap_next),
2067             mp->ver_res >> 6,
2068             flag_str,
2069             mp->next_protocol,
2070             mp->ver_res,
2071             mp->res,
2072             iid_str);
2073
2074     vec_free(iid_str);
2075 }
2076
2077 static void
2078 vl_api_lisp_gpe_tunnel_details_t_handler_json (
2079     vl_api_lisp_gpe_tunnel_details_t *mp)
2080 {
2081     vat_main_t *vam = &vat_main;
2082     vat_json_node_t *node = NULL;
2083     struct in6_addr ip6;
2084     struct in_addr ip4;
2085     u8 *next_decap_str;
2086
2087     next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2088
2089     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2090         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2091         vat_json_init_array(&vam->json_tree);
2092     }
2093     node = vat_json_array_add(&vam->json_tree);
2094
2095     vat_json_init_object(node);
2096     vat_json_object_add_uint(node, "tunel", mp->tunnels);
2097     if (mp->is_ipv6) {
2098         clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
2099         vat_json_object_add_ip6(node, "source address", ip6);
2100         clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
2101         vat_json_object_add_ip6(node, "destination address", ip6);
2102     } else {
2103         clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
2104         vat_json_object_add_ip4(node, "source address", ip4);
2105         clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
2106         vat_json_object_add_ip4(node, "destination address", ip4);
2107     }
2108     vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2109     vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2110     vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2111     vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2112     vat_json_object_add_uint(node, "flags", mp->flags);
2113     vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2114     vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2115     vat_json_object_add_uint(node, "res", mp->res);
2116     vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2117
2118     vec_free(next_decap_str);
2119 }
2120
2121 static void
2122 vl_api_lisp_map_resolver_details_t_handler (
2123     vl_api_lisp_map_resolver_details_t *mp)
2124 {
2125     vat_main_t *vam = &vat_main;
2126
2127     fformat(vam->ofp, "%=20U\n",
2128             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2129             mp->ip_address);
2130 }
2131
2132 static void
2133 vl_api_lisp_map_resolver_details_t_handler_json (
2134     vl_api_lisp_map_resolver_details_t *mp)
2135 {
2136     vat_main_t *vam = &vat_main;
2137     vat_json_node_t *node = NULL;
2138     struct in6_addr ip6;
2139     struct in_addr ip4;
2140
2141     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2142         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2143         vat_json_init_array(&vam->json_tree);
2144     }
2145     node = vat_json_array_add(&vam->json_tree);
2146
2147     vat_json_init_object(node);
2148     if (mp->is_ipv6) {
2149         clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2150         vat_json_object_add_ip6(node, "map resolver", ip6);
2151     } else {
2152         clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2153         vat_json_object_add_ip4(node, "map resolver", ip4);
2154     }
2155 }
2156
2157 static void
2158 vl_api_lisp_enable_disable_status_details_t_handler
2159 (vl_api_lisp_enable_disable_status_details_t *mp)
2160 {
2161     vat_main_t *vam = &vat_main;
2162
2163     fformat(vam->ofp, "feature: %s\ngpe: %s\n",
2164             mp->feature_status ? "enabled" : "disabled",
2165             mp->gpe_status ? "enabled" : "disabled");
2166 }
2167
2168 static void
2169 vl_api_lisp_enable_disable_status_details_t_handler_json
2170 (vl_api_lisp_enable_disable_status_details_t *mp)
2171 {
2172     vat_main_t *vam = &vat_main;
2173     vat_json_node_t *node = NULL;
2174     u8 * gpe_status = NULL;
2175     u8 * feature_status = NULL;
2176
2177     gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2178     feature_status = format (0, "%s",
2179                             mp->feature_status ? "enabled" : "disabled");
2180     vec_add1 (gpe_status, 0);
2181     vec_add1 (feature_status, 0);
2182
2183     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2184         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2185         vat_json_init_array(&vam->json_tree);
2186     }
2187     node = vat_json_array_add(&vam->json_tree);
2188
2189     vat_json_init_object(node);
2190     vat_json_object_add_string_copy(node, "gpe_status", gpe_status);
2191     vat_json_object_add_string_copy(node, "feature_status", feature_status);
2192
2193     vec_free (gpe_status);
2194     vec_free (feature_status);
2195 }
2196
2197 static void
2198 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler (
2199     vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2200 {
2201     vat_main_t * vam = &vat_main;
2202     i32 retval = ntohl(mp->retval);
2203
2204     if (retval >= 0) {
2205       fformat(vam->ofp, "%=20s\n",
2206               mp->locator_set_name);
2207     }
2208
2209     vam->retval = retval;
2210     vam->result_ready = 1;
2211 }
2212
2213 static void
2214 vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json (
2215     vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2216 {
2217     vat_main_t * vam = &vat_main;
2218     vat_json_node_t * node = NULL;
2219
2220     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2221         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2222         vat_json_init_array(&vam->json_tree);
2223     }
2224     node = vat_json_array_add(&vam->json_tree);
2225
2226     vat_json_init_object(node);
2227     vat_json_object_add_string_copy(node, "itr-rlocs", mp->locator_set_name);
2228
2229     vat_json_print(vam->ofp, node);
2230     vat_json_free(node);
2231
2232     vam->retval = ntohl(mp->retval);
2233     vam->result_ready = 1;
2234 }
2235
2236 static u8 * format_policer_type (u8 * s, va_list * va)
2237 {
2238     u32 i = va_arg (*va, u32);
2239
2240     if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2241         s = format (s, "1r2c");
2242     else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2243         s = format (s, "1r3c");
2244     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2245         s = format (s, "2r3c-2698");
2246     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2247         s = format (s, "2r3c-4115");
2248     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2249         s = format (s, "2r3c-mef5cf1");
2250     else
2251         s = format (s, "ILLEGAL");
2252     return s;
2253 }
2254
2255 static u8 * format_policer_rate_type (u8 * s, va_list * va)
2256 {
2257     u32 i = va_arg (*va, u32);
2258
2259     if (i == SSE2_QOS_RATE_KBPS)
2260         s = format (s, "kbps");
2261     else if (i == SSE2_QOS_RATE_PPS)
2262         s = format(s, "pps");
2263     else
2264         s = format (s, "ILLEGAL");
2265     return s;
2266 }
2267
2268 static u8 * format_policer_round_type (u8 * s, va_list * va)
2269 {
2270     u32 i = va_arg (*va, u32);
2271
2272     if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2273         s = format(s, "closest");
2274     else if (i == SSE2_QOS_ROUND_TO_UP)
2275         s = format (s, "up");
2276     else if (i == SSE2_QOS_ROUND_TO_DOWN)
2277         s = format (s, "down");
2278     else
2279         s = format (s, "ILLEGAL");
2280   return s;
2281 }
2282
2283 static void vl_api_policer_details_t_handler
2284 (vl_api_policer_details_t * mp)
2285 {
2286     vat_main_t * vam = &vat_main;
2287
2288     fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2289              "rate type %U, round type %U, %s rate, %s color-aware, "
2290              "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2291              "cur bkt %u, ext lim %u, ext bkt %u, last update %llu\n",
2292              mp->name,
2293              format_policer_type, mp->type,
2294              ntohl(mp->cir),
2295              ntohl(mp->eir),
2296              ntohl(mp->cb),
2297              ntohl(mp->eb),
2298              format_policer_rate_type, mp->rate_type,
2299              format_policer_round_type, mp->round_type,
2300              mp->single_rate ? "single" : "dual",
2301              mp->color_aware ? "is" : "not",
2302              ntohl(mp->cir_tokens_per_period),
2303              ntohl(mp->pir_tokens_per_period),
2304              ntohl(mp->scale),
2305              ntohl(mp->current_limit),
2306              ntohl(mp->current_bucket),
2307              ntohl(mp->extended_limit),
2308              ntohl(mp->extended_bucket),
2309              clib_net_to_host_u64(mp->last_update_time));
2310 }
2311
2312 static void vl_api_policer_details_t_handler_json
2313 (vl_api_policer_details_t * mp)
2314 {
2315     vat_main_t * vam = &vat_main;
2316     vat_json_node_t *node;
2317     u8 *rate_type_str, *round_type_str, *type_str;
2318
2319     rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2320     round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2321     type_str = format(0, "%U", format_policer_type, mp->type);
2322
2323     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2324         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2325         vat_json_init_array(&vam->json_tree);
2326     }
2327     node = vat_json_array_add(&vam->json_tree);
2328
2329     vat_json_init_object(node);
2330     vat_json_object_add_string_copy(node, "name", mp->name);
2331     vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2332     vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2333     vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2334     vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2335     vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2336     vat_json_object_add_string_copy(node, "round_type", round_type_str);
2337     vat_json_object_add_string_copy(node, "type", type_str);
2338     vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2339     vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2340     vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2341     vat_json_object_add_uint(node, "cir_tokens_per_period",
2342                              ntohl(mp->cir_tokens_per_period));
2343     vat_json_object_add_uint(node, "eir_tokens_per_period",
2344                              ntohl(mp->pir_tokens_per_period));
2345     vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2346     vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2347     vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2348     vat_json_object_add_uint(node, "extended_bucket",
2349                              ntohl(mp->extended_bucket));
2350     vat_json_object_add_uint(node, "last_update_time",
2351                              ntohl(mp->last_update_time));
2352
2353     vec_free(rate_type_str);
2354     vec_free(round_type_str);
2355     vec_free(type_str);
2356 }
2357
2358
2359 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2360 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2361 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2362 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2363
2364 /* 
2365  * Generate boilerplate reply handlers, which 
2366  * dig the return value out of the xxx_reply_t API message,
2367  * stick it into vam->retval, and set vam->result_ready
2368  *
2369  * Could also do this by pointing N message decode slots at
2370  * a single function, but that could break in subtle ways.
2371  */
2372
2373 #define foreach_standard_reply_retval_handler           \
2374 _(sw_interface_set_flags_reply)                         \
2375 _(sw_interface_add_del_address_reply)                   \
2376 _(sw_interface_set_table_reply)                         \
2377 _(sw_interface_set_vpath_reply)                         \
2378 _(sw_interface_set_l2_bridge_reply)                     \
2379 _(bridge_domain_add_del_reply)                          \
2380 _(sw_interface_set_l2_xconnect_reply)                   \
2381 _(l2fib_add_del_reply)                                  \
2382 _(ip_add_del_route_reply)                               \
2383 _(proxy_arp_add_del_reply)                              \
2384 _(proxy_arp_intfc_enable_disable_reply)                 \
2385 _(mpls_add_del_encap_reply)                             \
2386 _(mpls_add_del_decap_reply)                             \
2387 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
2388 _(sw_interface_set_unnumbered_reply)                    \
2389 _(ip_neighbor_add_del_reply)                            \
2390 _(reset_vrf_reply)                                      \
2391 _(oam_add_del_reply)                                    \
2392 _(reset_fib_reply)                                      \
2393 _(dhcp_proxy_config_reply)                              \
2394 _(dhcp_proxy_config_2_reply)                            \
2395 _(dhcp_proxy_set_vss_reply)                             \
2396 _(dhcp_client_config_reply)                             \
2397 _(set_ip_flow_hash_reply)                               \
2398 _(sw_interface_ip6_enable_disable_reply)                \
2399 _(sw_interface_ip6_set_link_local_address_reply)        \
2400 _(sw_interface_ip6nd_ra_prefix_reply)                   \
2401 _(sw_interface_ip6nd_ra_config_reply)                   \
2402 _(set_arp_neighbor_limit_reply)                         \
2403 _(l2_patch_add_del_reply)                               \
2404 _(sr_tunnel_add_del_reply)                              \
2405 _(sr_policy_add_del_reply)                              \
2406 _(sr_multicast_map_add_del_reply)                       \
2407 _(classify_add_del_session_reply)                       \
2408 _(classify_set_interface_ip_table_reply)                \
2409 _(classify_set_interface_l2_tables_reply)               \
2410 _(l2tpv3_set_tunnel_cookies_reply)                      \
2411 _(l2tpv3_interface_enable_disable_reply)                \
2412 _(l2tpv3_set_lookup_key_reply)                          \
2413 _(l2_fib_clear_table_reply)                             \
2414 _(l2_interface_efp_filter_reply)                        \
2415 _(l2_interface_vlan_tag_rewrite_reply)                  \
2416 _(modify_vhost_user_if_reply)                           \
2417 _(delete_vhost_user_if_reply)                           \
2418 _(want_ip4_arp_events_reply)                            \
2419 _(input_acl_set_interface_reply)                        \
2420 _(ipsec_spd_add_del_reply)                              \
2421 _(ipsec_interface_add_del_spd_reply)                    \
2422 _(ipsec_spd_add_del_entry_reply)                        \
2423 _(ipsec_sad_add_del_entry_reply)                        \
2424 _(ipsec_sa_set_key_reply)                               \
2425 _(ikev2_profile_add_del_reply)                          \
2426 _(ikev2_profile_set_auth_reply)                         \
2427 _(ikev2_profile_set_id_reply)                           \
2428 _(ikev2_profile_set_ts_reply)                           \
2429 _(ikev2_set_local_key_reply)                            \
2430 _(delete_loopback_reply)                                \
2431 _(bd_ip_mac_add_del_reply)                              \
2432 _(map_del_domain_reply)                                 \
2433 _(map_add_del_rule_reply)                               \
2434 _(want_interface_events_reply)                          \
2435 _(want_stats_reply)                                     \
2436 _(cop_interface_enable_disable_reply)                   \
2437 _(cop_whitelist_enable_disable_reply)                   \
2438 _(sw_interface_clear_stats_reply)                       \
2439 _(trace_profile_add_reply)                              \
2440 _(trace_profile_apply_reply)                            \
2441 _(trace_profile_del_reply)                              \
2442 _(lisp_add_del_locator_set_reply)                       \
2443 _(lisp_add_del_locator_reply)                           \
2444 _(lisp_add_del_local_eid_reply)                         \
2445 _(lisp_gpe_add_del_fwd_entry_reply)                     \
2446 _(lisp_add_del_map_resolver_reply)                      \
2447 _(lisp_gpe_enable_disable_reply)                        \
2448 _(lisp_gpe_add_del_iface_reply)                         \
2449 _(lisp_enable_disable_reply)                            \
2450 _(lisp_pitr_set_locator_set_reply)                      \
2451 _(lisp_add_del_map_request_itr_rlocs_reply)             \
2452 _(vxlan_gpe_add_del_tunnel_reply)                       \
2453 _(af_packet_delete_reply)                               \
2454 _(policer_add_del_reply)                                \
2455 _(netmap_create_reply)                                  \
2456 _(netmap_delete_reply)
2457
2458 #define _(n)                                    \
2459     static void vl_api_##n##_t_handler          \
2460     (vl_api_##n##_t * mp)                       \
2461     {                                           \
2462         vat_main_t * vam = &vat_main;           \
2463         i32 retval = ntohl(mp->retval);         \
2464         if (vam->async_mode) {                  \
2465             vam->async_errors += (retval < 0);  \
2466         } else {                                \
2467             vam->retval = retval;               \
2468             vam->result_ready = 1;              \
2469         }                                       \
2470     }
2471 foreach_standard_reply_retval_handler;
2472 #undef _
2473
2474 #define _(n)                                    \
2475     static void vl_api_##n##_t_handler_json     \
2476     (vl_api_##n##_t * mp)                       \
2477     {                                           \
2478         vat_main_t * vam = &vat_main;           \
2479         vat_json_node_t node;                   \
2480         vat_json_init_object(&node);            \
2481         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
2482         vat_json_print(vam->ofp, &node);        \
2483         vam->retval = ntohl(mp->retval);        \
2484         vam->result_ready = 1;                  \
2485     }
2486 foreach_standard_reply_retval_handler;
2487 #undef _
2488
2489 /* 
2490  * Table of message reply handlers, must include boilerplate handlers
2491  * we just generated
2492  */
2493
2494 #define foreach_vpe_api_reply_msg                                       \
2495 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
2496 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
2497 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
2498 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
2499 _(CONTROL_PING_REPLY, control_ping_reply)                               \
2500 _(CLI_REPLY, cli_reply)                                                 \
2501 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
2502   sw_interface_add_del_address_reply)                                   \
2503 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
2504 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
2505 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
2506   sw_interface_set_l2_xconnect_reply)                                   \
2507 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
2508   sw_interface_set_l2_bridge_reply)                                     \
2509 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
2510 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
2511 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
2512 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
2513 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
2514 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
2515 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
2516 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
2517 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
2518 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
2519 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
2520 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
2521 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
2522   proxy_arp_intfc_enable_disable_reply)                                 \
2523 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
2524 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
2525 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
2526 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
2527   mpls_ethernet_add_del_tunnel_reply)                                   \
2528 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
2529   mpls_ethernet_add_del_tunnel_2_reply)                                 \
2530 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
2531   sw_interface_set_unnumbered_reply)                                    \
2532 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
2533 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
2534 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
2535 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
2536 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
2537 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
2538 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
2539 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
2540 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
2541 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
2542 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
2543 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
2544   sw_interface_ip6_enable_disable_reply)                                \
2545 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
2546   sw_interface_ip6_set_link_local_address_reply)                        \
2547 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
2548   sw_interface_ip6nd_ra_prefix_reply)                                   \
2549 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
2550   sw_interface_ip6nd_ra_config_reply)                                   \
2551 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
2552 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
2553 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
2554 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
2555 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
2556 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
2557 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
2558 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
2559 classify_set_interface_ip_table_reply)                                  \
2560 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
2561   classify_set_interface_l2_tables_reply)                               \
2562 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
2563 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
2564 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
2565 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
2566 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
2567   l2tpv3_interface_enable_disable_reply)                                \
2568 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
2569 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
2570 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
2571 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
2572 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
2573 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
2574 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
2575 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
2576 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2577 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
2578 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
2579 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
2580 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
2581 _(SHOW_VERSION_REPLY, show_version_reply)                               \
2582 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
2583 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
2584 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
2585 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
2586 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
2587 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
2588 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
2589 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
2590 _(IP_DETAILS, ip_details)                                               \
2591 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
2592 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2593 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
2594 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
2595 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
2596 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
2597 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
2598 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
2599 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
2600 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
2601 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
2602 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
2603 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
2604 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
2605 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
2606 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
2607 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
2608 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
2609 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
2610 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
2611 _(MAP_RULE_DETAILS, map_rule_details)                                   \
2612 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
2613 _(WANT_STATS_REPLY, want_stats_reply)                                   \
2614 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
2615 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
2616 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
2617 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
2618 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
2619 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
2620 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
2621 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
2622 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
2623 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
2624 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
2625 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
2626 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
2627 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
2628 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
2629 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
2630 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
2631 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
2632 _(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details)           \
2633 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
2634 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
2635 _(LISP_ENABLE_DISABLE_STATUS_DETAILS,                                   \
2636   lisp_enable_disable_status_details)                                   \
2637 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
2638   lisp_add_del_map_request_itr_rlocs_reply)                             \
2639 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
2640   lisp_get_map_request_itr_rlocs_reply)                                 \
2641 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
2642 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
2643 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
2644 _(POLICER_DETAILS, policer_details)                                     \
2645 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
2646 _(NETMAP_DELETE_REPLY, netmap_delete_reply)
2647
2648 /* M: construct, but don't yet send a message */
2649
2650 #define M(T,t)                                  \
2651 do {                                            \
2652     vam->result_ready = 0;                      \
2653     mp = vl_msg_api_alloc(sizeof(*mp));         \
2654     memset (mp, 0, sizeof (*mp));               \
2655     mp->_vl_msg_id = ntohs (VL_API_##T);        \
2656     mp->client_index = vam->my_client_index;    \
2657 } while(0);
2658
2659 #define M2(T,t,n)                               \
2660 do {                                            \
2661     vam->result_ready = 0;                      \
2662     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
2663     memset (mp, 0, sizeof (*mp));               \
2664     mp->_vl_msg_id = ntohs (VL_API_##T);        \
2665     mp->client_index = vam->my_client_index;    \
2666 } while(0);
2667
2668
2669 /* S: send a message */
2670 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2671
2672 /* W: wait for results, with timeout */
2673 #define W                                       \
2674 do {                                            \
2675     timeout = vat_time_now (vam) + 1.0;         \
2676                                                 \
2677     while (vat_time_now (vam) < timeout) {      \
2678         if (vam->result_ready == 1) {           \
2679             return (vam->retval);               \
2680         }                                       \
2681     }                                           \
2682     return -99;                                 \
2683 } while(0);
2684
2685 /* W2: wait for results, with timeout */
2686 #define W2(body)                                \
2687 do {                                            \
2688     timeout = vat_time_now (vam) + 1.0;         \
2689                                                 \
2690     while (vat_time_now (vam) < timeout) {      \
2691         if (vam->result_ready == 1) {           \
2692           (body);                               \
2693           return (vam->retval);                 \
2694         }                                       \
2695     }                                           \
2696     return -99;                                 \
2697 } while(0);
2698
2699 typedef struct {
2700     u8 * name;
2701     u32 value;
2702 } name_sort_t;
2703
2704
2705 #define STR_VTR_OP_CASE(op)     \
2706     case L2_VTR_ ## op:         \
2707         return "" # op;
2708
2709 static const char *str_vtr_op(u32 vtr_op)
2710 {
2711     switch(vtr_op) {
2712         STR_VTR_OP_CASE(DISABLED);
2713         STR_VTR_OP_CASE(PUSH_1);
2714         STR_VTR_OP_CASE(PUSH_2);
2715         STR_VTR_OP_CASE(POP_1);
2716         STR_VTR_OP_CASE(POP_2);
2717         STR_VTR_OP_CASE(TRANSLATE_1_1);
2718         STR_VTR_OP_CASE(TRANSLATE_1_2);
2719         STR_VTR_OP_CASE(TRANSLATE_2_1);
2720         STR_VTR_OP_CASE(TRANSLATE_2_2);
2721     }
2722
2723     return "UNKNOWN";
2724 }
2725
2726 static int dump_sub_interface_table (vat_main_t * vam)
2727 {
2728     const sw_interface_subif_t * sub = NULL;
2729
2730     if (vam->json_output) {
2731         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2732         return -99;
2733     }
2734
2735     fformat (vam->ofp,
2736              "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2737              "Interface", "sw_if_index",
2738              "sub id", "dot1ad", "tags", "outer id",
2739              "inner id", "exact", "default",
2740              "outer any", "inner any");
2741
2742     vec_foreach (sub, vam->sw_if_subif_table) {
2743         fformat (vam->ofp,
2744                  "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2745                  sub->interface_name,
2746                  sub->sw_if_index,
2747                  sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2748                  sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2749                  sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2750                  sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2751         if (sub->vtr_op != L2_VTR_DISABLED) {
2752             fformat (vam->ofp,
2753                      "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2754                      "tag1: %d tag2: %d ]\n",
2755                      str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q, 
2756                      sub->vtr_tag1, sub->vtr_tag2);
2757         }
2758     }
2759
2760     return 0;
2761 }
2762
2763 static int name_sort_cmp (void * a1, void * a2)
2764 {
2765   name_sort_t * n1 = a1;
2766   name_sort_t * n2 = a2;
2767
2768   return strcmp ((char *)n1->name, (char *)n2->name);
2769 }
2770
2771 static int dump_interface_table (vat_main_t * vam)
2772 {
2773     hash_pair_t * p;
2774     name_sort_t * nses = 0, * ns;
2775
2776     if (vam->json_output) {
2777         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2778         return -99;
2779     }
2780
2781     hash_foreach_pair (p, vam->sw_if_index_by_interface_name, 
2782     ({
2783         vec_add2 (nses, ns, 1);
2784         ns->name = (u8 *)(p->key);
2785         ns->value = (u32) p->value[0];
2786     }));
2787
2788     vec_sort_with_function (nses, name_sort_cmp);
2789
2790     fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2791     vec_foreach (ns, nses) {
2792         fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2793     }
2794     vec_free (nses);
2795     return 0;
2796 }
2797
2798 static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2799 {
2800     const ip_details_t * det = NULL;
2801     const ip_address_details_t * address = NULL;
2802     u32 i = ~0;
2803
2804     fformat (vam->ofp,
2805              "%-12s\n",
2806              "sw_if_index");
2807
2808     if (0 == vam) {
2809         return 0;
2810     }
2811
2812     vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2813         i++;
2814         if (!det->present) {
2815             continue;
2816         }
2817         fformat (vam->ofp,
2818                  "%-12d\n",
2819                  i);
2820         fformat (vam->ofp,
2821                  "            %-30s%-13s\n",
2822                  "Address", "Prefix length");
2823         if (!det->addr) {
2824             continue;
2825         }
2826         vec_foreach (address, det->addr) {
2827             fformat (vam->ofp,
2828                      "            %-30U%-13d\n",
2829                      is_ipv6 ? format_ip6_address : format_ip4_address,
2830                      address->ip,
2831                      address->prefix_length);
2832         }
2833     }
2834
2835     return 0;
2836 }
2837
2838 static int dump_ipv4_table (vat_main_t * vam)
2839 {
2840     if (vam->json_output) {
2841         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2842         return -99;
2843     }
2844
2845     return dump_ip_table (vam, 0);
2846 }
2847
2848 static int dump_ipv6_table (vat_main_t * vam)
2849 {
2850     if (vam->json_output) {
2851         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2852         return -99;
2853     }
2854
2855     return dump_ip_table (vam, 1);
2856 }
2857
2858 static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2859 {
2860     if (!is_combined) {
2861         switch(counter_type) {
2862         case VNET_INTERFACE_COUNTER_DROP:
2863             return "drop";
2864         case VNET_INTERFACE_COUNTER_PUNT:
2865             return "punt";
2866         case VNET_INTERFACE_COUNTER_IP4:
2867             return "ip4";
2868         case VNET_INTERFACE_COUNTER_IP6:
2869             return "ip6";
2870         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2871             return "rx-no-buf";
2872         case VNET_INTERFACE_COUNTER_RX_MISS:
2873             return "rx-miss";
2874         case VNET_INTERFACE_COUNTER_RX_ERROR:
2875             return "rx-error";
2876         case VNET_INTERFACE_COUNTER_TX_ERROR:
2877             return "tx-error";
2878         default:
2879             return "INVALID-COUNTER-TYPE";
2880         }
2881     } else {
2882         switch(counter_type) {
2883         case VNET_INTERFACE_COUNTER_RX:
2884             return "rx";
2885         case VNET_INTERFACE_COUNTER_TX:
2886             return "tx";
2887         default:
2888             return "INVALID-COUNTER-TYPE";
2889         }
2890     }
2891 }
2892
2893 static int dump_stats_table (vat_main_t * vam)
2894 {
2895     vat_json_node_t node;
2896     vat_json_node_t *msg_array;
2897     vat_json_node_t *msg;
2898     vat_json_node_t *counter_array;
2899     vat_json_node_t *counter;
2900     interface_counter_t c;
2901     u64 packets;
2902     ip4_fib_counter_t *c4;
2903     ip6_fib_counter_t *c6;
2904     int i, j;
2905
2906     if (!vam->json_output) {
2907         clib_warning ("dump_stats_table supported only in JSON format");
2908         return -99;
2909     }
2910
2911     vat_json_init_object(&node);
2912
2913     /* interface counters */
2914     msg_array = vat_json_object_add(&node, "interface_counters");
2915     vat_json_init_array(msg_array);
2916     for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2917         msg = vat_json_array_add(msg_array);
2918         vat_json_init_object(msg);
2919         vat_json_object_add_string_copy(msg, "vnet_counter_type",
2920                 (u8*)counter_type_to_str(i, 0));
2921         vat_json_object_add_int(msg, "is_combined", 0);
2922         counter_array = vat_json_object_add(msg, "data");
2923         vat_json_init_array(counter_array);
2924         for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2925             packets = vam->simple_interface_counters[i][j];
2926             vat_json_array_add_uint(counter_array, packets);
2927         }
2928     }
2929     for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2930         msg = vat_json_array_add(msg_array);
2931         vat_json_init_object(msg);
2932         vat_json_object_add_string_copy(msg, "vnet_counter_type",
2933                 (u8*)counter_type_to_str(i, 1));
2934         vat_json_object_add_int(msg, "is_combined", 1);
2935         counter_array = vat_json_object_add(msg, "data");
2936         vat_json_init_array(counter_array);
2937         for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2938             c = vam->combined_interface_counters[i][j];
2939             counter = vat_json_array_add(counter_array);
2940             vat_json_init_object(counter);
2941             vat_json_object_add_uint(counter, "packets", c.packets);
2942             vat_json_object_add_uint(counter, "bytes", c.bytes);
2943         }
2944     }
2945
2946     /* ip4 fib counters */
2947     msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2948     vat_json_init_array(msg_array);
2949     for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2950         msg = vat_json_array_add(msg_array);
2951         vat_json_init_object(msg);
2952         vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2953         counter_array = vat_json_object_add(msg, "c");
2954         vat_json_init_array(counter_array);
2955         for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2956             counter = vat_json_array_add(counter_array);
2957             vat_json_init_object(counter);
2958             c4 = &vam->ip4_fib_counters[i][j];
2959             vat_json_object_add_ip4(counter, "address", c4->address);
2960             vat_json_object_add_uint(counter, "address_length", c4->address_length);
2961             vat_json_object_add_uint(counter, "packets", c4->packets);
2962             vat_json_object_add_uint(counter, "bytes", c4->bytes);
2963         }
2964     }
2965
2966     /* ip6 fib counters */
2967     msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2968     vat_json_init_array(msg_array);
2969     for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2970         msg = vat_json_array_add(msg_array);
2971         vat_json_init_object(msg);
2972         vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2973         counter_array = vat_json_object_add(msg, "c");
2974         vat_json_init_array(counter_array);
2975         for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2976             counter = vat_json_array_add(counter_array);
2977             vat_json_init_object(counter);
2978             c6 = &vam->ip6_fib_counters[i][j];
2979             vat_json_object_add_ip6(counter, "address", c6->address);
2980             vat_json_object_add_uint(counter, "address_length", c6->address_length);
2981             vat_json_object_add_uint(counter, "packets", c6->packets);
2982             vat_json_object_add_uint(counter, "bytes", c6->bytes);
2983         }
2984     }
2985
2986     vat_json_print(vam->ofp, &node);
2987     vat_json_free(&node);
2988
2989     return 0;
2990 }
2991
2992 int exec (vat_main_t * vam)
2993 {
2994     api_main_t * am = &api_main;
2995     vl_api_cli_request_t *mp;
2996     f64 timeout;
2997     void * oldheap;
2998     u8 * cmd = 0;
2999     unformat_input_t * i = vam->input;
3000
3001     if (vec_len(i->buffer) == 0)
3002         return -1;
3003
3004     if (vam->exec_mode == 0 && unformat (i, "mode")) {        
3005         vam->exec_mode = 1;
3006         return 0;
3007     }
3008     if (vam->exec_mode == 1 && 
3009         (unformat (i, "exit") || unformat (i, "quit"))) {
3010         vam->exec_mode = 0;
3011         return 0;
3012     }
3013     
3014
3015     M(CLI_REQUEST, cli_request);
3016
3017     /* 
3018      * Copy cmd into shared memory.
3019      * In order for the CLI command to work, it
3020      * must be a vector ending in \n, not a C-string ending
3021      * in \n\0.
3022      */
3023     pthread_mutex_lock (&am->vlib_rp->mutex);
3024     oldheap = svm_push_data_heap (am->vlib_rp);
3025
3026     vec_validate (cmd, vec_len(vam->input->buffer)-1);
3027     clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
3028
3029     svm_pop_heap (oldheap);
3030     pthread_mutex_unlock (&am->vlib_rp->mutex);
3031
3032     mp->cmd_in_shmem = (u64) cmd;
3033     S;
3034     timeout = vat_time_now (vam) + 10.0;
3035
3036     while (vat_time_now (vam) < timeout) {
3037         if (vam->result_ready == 1) {
3038             u8 * free_me;
3039             if (vam->shmem_result != NULL)
3040                 fformat (vam->ofp, "%s", vam->shmem_result);
3041             pthread_mutex_lock (&am->vlib_rp->mutex);
3042             oldheap = svm_push_data_heap (am->vlib_rp);
3043             
3044             free_me = (u8 *)vam->shmem_result;
3045             vec_free (free_me);
3046
3047             svm_pop_heap (oldheap);
3048             pthread_mutex_unlock (&am->vlib_rp->mutex);
3049             return 0;
3050         }
3051     }
3052     return -99;
3053 }
3054
3055 static int api_create_loopback (vat_main_t * vam)
3056 {
3057     unformat_input_t * i = vam->input;
3058     vl_api_create_loopback_t *mp;
3059     f64 timeout;
3060     u8 mac_address[6];
3061     u8 mac_set = 0;
3062
3063     memset (mac_address, 0, sizeof (mac_address));
3064
3065     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3066       {
3067         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3068             mac_set = 1;
3069         else
3070           break;
3071       }
3072
3073     /* Construct the API message */
3074     M(CREATE_LOOPBACK, create_loopback);
3075     if (mac_set)
3076         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3077
3078     S; W;
3079 }
3080
3081 static int api_delete_loopback (vat_main_t * vam)
3082 {
3083     unformat_input_t * i = vam->input;
3084     vl_api_delete_loopback_t *mp;
3085     f64 timeout;
3086     u32 sw_if_index = ~0;
3087
3088     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3089       {
3090         if (unformat (i, "sw_if_index %d", &sw_if_index))
3091           ;
3092         else
3093           break;
3094       }
3095
3096     if (sw_if_index == ~0)
3097       {
3098         errmsg ("missing sw_if_index\n");
3099         return -99;
3100       }
3101
3102     /* Construct the API message */
3103     M(DELETE_LOOPBACK, delete_loopback);
3104     mp->sw_if_index = ntohl (sw_if_index);
3105
3106     S; W;
3107 }
3108
3109 static int api_want_stats (vat_main_t * vam)
3110 {
3111     unformat_input_t * i = vam->input;
3112     vl_api_want_stats_t * mp;
3113     f64 timeout;
3114     int enable = -1;
3115
3116     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3117       {
3118         if (unformat (i, "enable"))
3119           enable = 1;
3120         else if (unformat (i, "disable"))
3121           enable = 0;
3122         else
3123           break;
3124       }
3125
3126     if (enable == -1)
3127       {
3128         errmsg ("missing enable|disable\n");
3129         return -99;
3130       }
3131
3132     M(WANT_STATS, want_stats);
3133     mp->enable_disable = enable;
3134
3135     S; W;
3136 }
3137
3138 static int api_want_interface_events (vat_main_t * vam)
3139 {
3140     unformat_input_t * i = vam->input;
3141     vl_api_want_interface_events_t * mp;
3142     f64 timeout;
3143     int enable = -1;
3144
3145     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3146       {
3147         if (unformat (i, "enable"))
3148           enable = 1;
3149         else if (unformat (i, "disable"))
3150           enable = 0;
3151         else
3152           break;
3153       }
3154
3155     if (enable == -1)
3156       {
3157         errmsg ("missing enable|disable\n");
3158         return -99;
3159       }
3160
3161     M(WANT_INTERFACE_EVENTS, want_interface_events);
3162     mp->enable_disable = enable;
3163
3164     vam->interface_event_display = enable;
3165
3166     S; W;
3167 }
3168
3169
3170 /* Note: non-static, called once to set up the initial intfc table */
3171 int api_sw_interface_dump (vat_main_t * vam)
3172 {
3173     vl_api_sw_interface_dump_t *mp;
3174     f64 timeout;
3175     hash_pair_t * p;
3176     name_sort_t * nses = 0, * ns;
3177     sw_interface_subif_t * sub = NULL;
3178
3179     /* Toss the old name table */
3180     hash_foreach_pair (p, vam->sw_if_index_by_interface_name, 
3181     ({
3182         vec_add2 (nses, ns, 1);
3183         ns->name = (u8 *)(p->key);
3184         ns->value = (u32) p->value[0];
3185     }));
3186
3187     hash_free (vam->sw_if_index_by_interface_name);
3188
3189     vec_foreach (ns, nses)
3190         vec_free (ns->name);
3191
3192     vec_free (nses);
3193
3194     vec_foreach (sub, vam->sw_if_subif_table) {
3195         vec_free (sub->interface_name);
3196     }
3197     vec_free (vam->sw_if_subif_table);
3198
3199     /* recreate the interface name hash table */
3200     vam->sw_if_index_by_interface_name 
3201         = hash_create_string (0, sizeof(uword));
3202
3203     /* Get list of ethernets */
3204     M(SW_INTERFACE_DUMP, sw_interface_dump);
3205     mp->name_filter_valid = 1;
3206     strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
3207     S;
3208
3209     /* and local / loopback interfaces */
3210     M(SW_INTERFACE_DUMP, sw_interface_dump);
3211     mp->name_filter_valid = 1;
3212     strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
3213     S;
3214
3215
3216     /* and vxlan-gpe tunnel interfaces */
3217     M(SW_INTERFACE_DUMP, sw_interface_dump);
3218     mp->name_filter_valid = 1;
3219     strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
3220     S;
3221
3222     /* and vxlan tunnel interfaces */
3223     M(SW_INTERFACE_DUMP, sw_interface_dump);
3224     mp->name_filter_valid = 1;
3225     strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
3226     S;
3227
3228     /* and host (af_packet) interfaces */
3229     M(SW_INTERFACE_DUMP, sw_interface_dump);
3230     mp->name_filter_valid = 1;
3231     strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
3232     S;
3233
3234     /* and l2tpv3 tunnel interfaces */
3235     M(SW_INTERFACE_DUMP, sw_interface_dump);
3236     mp->name_filter_valid = 1;
3237     strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
3238     S;
3239
3240     /* and GRE tunnel interfaces */
3241     M(SW_INTERFACE_DUMP, sw_interface_dump);
3242     mp->name_filter_valid = 1;
3243     strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3244     S;
3245
3246     /* Use a control ping for synchronization */
3247     {
3248         vl_api_control_ping_t * mp;
3249         M(CONTROL_PING, control_ping);
3250         S;
3251     }
3252     W;
3253 }
3254
3255 static int api_sw_interface_set_flags (vat_main_t * vam)
3256 {
3257     unformat_input_t * i = vam->input;
3258     vl_api_sw_interface_set_flags_t *mp;
3259     f64 timeout;
3260     u32 sw_if_index;
3261     u8 sw_if_index_set = 0;
3262     u8 admin_up = 0, link_up = 0;
3263     
3264     /* Parse args required to build the message */
3265     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3266         if (unformat (i, "admin-up"))
3267             admin_up = 1;
3268         else if (unformat (i, "admin-down"))
3269             admin_up = 0;
3270         else if (unformat (i, "link-up"))
3271             link_up = 1;
3272         else if (unformat (i, "link-down"))
3273             link_up = 0;
3274         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3275             sw_if_index_set = 1;
3276         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3277             sw_if_index_set = 1;
3278         else
3279             break;
3280     }
3281
3282     if (sw_if_index_set == 0) {
3283         errmsg ("missing interface name or sw_if_index\n");
3284         return -99;
3285     }
3286
3287     /* Construct the API message */
3288     M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3289     mp->sw_if_index = ntohl (sw_if_index);
3290     mp->admin_up_down = admin_up;
3291     mp->link_up_down = link_up;
3292
3293     /* send it... */
3294     S;
3295
3296     /* Wait for a reply, return the good/bad news... */
3297     W;
3298 }
3299
3300 static int api_sw_interface_clear_stats (vat_main_t * vam)
3301 {
3302     unformat_input_t * i = vam->input;
3303     vl_api_sw_interface_clear_stats_t *mp;
3304     f64 timeout;
3305     u32 sw_if_index;
3306     u8 sw_if_index_set = 0;
3307
3308     /* Parse args required to build the message */
3309     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3310         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3311             sw_if_index_set = 1;
3312         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3313             sw_if_index_set = 1;
3314         else
3315             break;
3316     }
3317
3318     /* Construct the API message */
3319     M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3320
3321     if (sw_if_index_set == 1)
3322         mp->sw_if_index = ntohl (sw_if_index);
3323     else
3324         mp->sw_if_index = ~0;
3325
3326     /* send it... */
3327     S;
3328
3329     /* Wait for a reply, return the good/bad news... */
3330     W;
3331 }
3332
3333 static int api_sw_interface_add_del_address (vat_main_t * vam)
3334 {
3335     unformat_input_t * i = vam->input;
3336     vl_api_sw_interface_add_del_address_t *mp;
3337     f64 timeout;
3338     u32 sw_if_index;
3339     u8 sw_if_index_set = 0;
3340     u8 is_add = 1, del_all = 0;
3341     u32 address_length = 0;
3342     u8 v4_address_set = 0;
3343     u8 v6_address_set = 0;
3344     ip4_address_t v4address;
3345     ip6_address_t v6address;
3346     
3347     /* Parse args required to build the message */
3348     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3349         if (unformat (i, "del-all"))
3350             del_all = 1;
3351         else if (unformat (i, "del"))
3352             is_add = 0;
3353         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3354             sw_if_index_set = 1;
3355         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3356             sw_if_index_set = 1;
3357         else if (unformat (i, "%U/%d", 
3358                            unformat_ip4_address, &v4address, 
3359                            &address_length))
3360             v4_address_set = 1;
3361         else if (unformat (i, "%U/%d", 
3362                            unformat_ip6_address, &v6address, 
3363                            &address_length))
3364             v6_address_set = 1;
3365         else
3366             break;
3367     }
3368
3369     if (sw_if_index_set == 0) {
3370         errmsg ("missing interface name or sw_if_index\n");
3371         return -99;
3372     }
3373     if (v4_address_set && v6_address_set) {
3374         errmsg ("both v4 and v6 addresses set\n");
3375         return -99;
3376     }
3377     if (!v4_address_set && !v6_address_set && !del_all) {
3378         errmsg ("no addresses set\n");
3379         return -99;
3380     }
3381
3382     /* Construct the API message */
3383     M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3384
3385     mp->sw_if_index = ntohl (sw_if_index);
3386     mp->is_add = is_add;
3387     mp->del_all = del_all;
3388     if (v6_address_set) {
3389         mp->is_ipv6 = 1;
3390         clib_memcpy (mp->address, &v6address, sizeof (v6address));
3391     } else {
3392         clib_memcpy (mp->address, &v4address, sizeof (v4address));
3393     }
3394     mp->address_length = address_length;
3395
3396     /* send it... */
3397     S;
3398
3399     /* Wait for a reply, return good/bad news  */
3400     W;
3401 }
3402
3403 static int api_sw_interface_set_table (vat_main_t * vam)
3404 {
3405     unformat_input_t * i = vam->input;
3406     vl_api_sw_interface_set_table_t *mp;
3407     f64 timeout;
3408     u32 sw_if_index, vrf_id = 0;
3409     u8 sw_if_index_set = 0;
3410     u8 is_ipv6 = 0;
3411     
3412     /* Parse args required to build the message */
3413     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3414         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3415             sw_if_index_set = 1;
3416         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3417             sw_if_index_set = 1;
3418         else if (unformat (i, "vrf %d", &vrf_id))
3419             ;
3420         else if (unformat (i, "ipv6"))
3421             is_ipv6 = 1;
3422         else
3423             break;
3424     }
3425
3426     if (sw_if_index_set == 0) {
3427         errmsg ("missing interface name or sw_if_index\n");
3428         return -99;
3429     }
3430
3431     /* Construct the API message */
3432     M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3433
3434     mp->sw_if_index = ntohl (sw_if_index);
3435     mp->is_ipv6 = is_ipv6;
3436     mp->vrf_id = ntohl (vrf_id);
3437
3438     /* send it... */
3439     S;
3440
3441     /* Wait for a reply... */
3442     W;
3443 }
3444
3445 static int api_sw_interface_set_vpath (vat_main_t * vam)
3446 {
3447     unformat_input_t * i = vam->input;
3448     vl_api_sw_interface_set_vpath_t *mp;
3449     f64 timeout;
3450     u32 sw_if_index = 0;
3451     u8 sw_if_index_set = 0;
3452     u8 is_enable = 0;
3453     
3454     /* Parse args required to build the message */
3455     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3456         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3457             sw_if_index_set = 1;
3458         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3459             sw_if_index_set = 1;
3460         else if (unformat (i, "enable"))
3461             is_enable = 1;
3462         else if (unformat (i, "disable"))
3463             is_enable = 0;
3464         else
3465             break;
3466     }
3467
3468     if (sw_if_index_set == 0) {
3469         errmsg ("missing interface name or sw_if_index\n");
3470         return -99;
3471     }
3472
3473     /* Construct the API message */
3474     M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3475
3476     mp->sw_if_index = ntohl (sw_if_index);
3477     mp->enable = is_enable;
3478
3479     /* send it... */
3480     S;
3481
3482     /* Wait for a reply... */
3483     W;
3484 }
3485
3486 static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3487 {
3488     unformat_input_t * i = vam->input;
3489     vl_api_sw_interface_set_l2_xconnect_t *mp;
3490     f64 timeout;
3491     u32 rx_sw_if_index;
3492     u8 rx_sw_if_index_set = 0;
3493     u32 tx_sw_if_index;
3494     u8 tx_sw_if_index_set = 0;
3495     u8 enable = 1;
3496     
3497     /* Parse args required to build the message */
3498     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3499         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3500             rx_sw_if_index_set = 1;     
3501         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3502             tx_sw_if_index_set = 1;
3503         else if (unformat (i, "rx")) {
3504             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3505                 if (unformat (i, "%U", unformat_sw_if_index, vam,
3506                               &rx_sw_if_index))
3507                     rx_sw_if_index_set = 1;
3508             } else
3509                 break;
3510         } else if (unformat (i, "tx")) {
3511             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3512                 if (unformat (i, "%U", unformat_sw_if_index, vam,
3513                               &tx_sw_if_index))
3514                     tx_sw_if_index_set = 1;
3515             } else
3516                 break;
3517         } else if (unformat (i, "enable"))
3518             enable = 1;
3519         else if (unformat (i, "disable")) 
3520             enable = 0;
3521         else
3522             break;
3523     }
3524
3525     if (rx_sw_if_index_set == 0) {
3526         errmsg ("missing rx interface name or rx_sw_if_index\n");
3527         return -99;
3528     }
3529
3530     if (enable && (tx_sw_if_index_set == 0)) {
3531         errmsg ("missing tx interface name or tx_sw_if_index\n");
3532         return -99;
3533     }
3534     
3535     M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3536
3537     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3538     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3539     mp->enable = enable;
3540
3541     S; W;
3542     /* NOTREACHED */
3543     return 0;
3544 }
3545
3546 static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3547 {
3548     unformat_input_t * i = vam->input;
3549     vl_api_sw_interface_set_l2_bridge_t *mp;
3550     f64 timeout;
3551     u32 rx_sw_if_index;
3552     u8 rx_sw_if_index_set = 0;
3553     u32 bd_id;
3554     u8 bd_id_set = 0;
3555     u8 bvi = 0;
3556     u32 shg = 0;
3557     u8 enable = 1;
3558     
3559     /* Parse args required to build the message */
3560     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3561         if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3562             rx_sw_if_index_set = 1;     
3563         else if (unformat (i, "bd_id %d", &bd_id))
3564             bd_id_set = 1;
3565         else if (unformat (i, "%U", unformat_sw_if_index, vam,
3566                            &rx_sw_if_index))
3567             rx_sw_if_index_set = 1;
3568         else if (unformat (i, "shg %d", &shg)) 
3569             ;
3570         else if (unformat (i, "bvi"))
3571             bvi = 1;
3572         else if (unformat (i, "enable"))
3573             enable = 1;
3574         else if (unformat (i, "disable")) 
3575             enable = 0;
3576         else
3577             break;
3578     }
3579
3580     if (rx_sw_if_index_set == 0) {
3581         errmsg ("missing rx interface name or sw_if_index\n");
3582         return -99;
3583     }
3584
3585     if (enable && (bd_id_set == 0)) {
3586         errmsg ("missing bridge domain\n");
3587         return -99;
3588     }
3589     
3590     M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3591
3592     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3593     mp->bd_id = ntohl(bd_id);
3594     mp->shg = (u8)shg;
3595     mp->bvi = bvi;
3596     mp->enable = enable;
3597
3598     S; W;
3599     /* NOTREACHED */
3600     return 0;
3601 }
3602
3603 static int api_bridge_domain_dump (vat_main_t * vam)
3604 {
3605     unformat_input_t * i = vam->input;
3606     vl_api_bridge_domain_dump_t *mp;
3607     f64 timeout;
3608     u32 bd_id = ~0;
3609
3610     /* Parse args required to build the message */
3611     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3612         if (unformat (i, "bd_id %d", &bd_id))
3613             ;
3614         else
3615             break;
3616     }
3617
3618     M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3619     mp->bd_id = ntohl(bd_id);
3620     S;
3621
3622     /* Use a control ping for synchronization */
3623     {
3624         vl_api_control_ping_t * mp;
3625         M(CONTROL_PING, control_ping);
3626         S;
3627     }
3628
3629     W;
3630     /* NOTREACHED */
3631     return 0;
3632 }
3633
3634 static int api_bridge_domain_add_del (vat_main_t * vam)
3635 {
3636     unformat_input_t * i = vam->input;
3637     vl_api_bridge_domain_add_del_t *mp;
3638     f64 timeout;
3639     u32 bd_id = ~0;
3640     u8 is_add = 1;
3641     u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3642
3643     /* Parse args required to build the message */
3644     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3645         if (unformat (i, "bd_id %d", &bd_id))
3646             ;
3647         else if (unformat (i, "flood %d", &flood))
3648              ;
3649         else if (unformat (i, "uu-flood %d", &uu_flood))
3650              ;
3651         else if (unformat (i, "forward %d", &forward))
3652              ;
3653         else if (unformat (i, "learn %d", &learn))
3654              ;
3655         else if (unformat (i, "arp-term %d", &arp_term))
3656              ;
3657         else if (unformat (i, "del")) {
3658              is_add = 0;
3659              flood = uu_flood = forward = learn = 0;
3660         }
3661         else
3662             break;
3663     }
3664
3665     if (bd_id == ~0) {
3666         errmsg ("missing bridge domain\n");
3667         return -99;
3668     }
3669
3670     M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3671
3672     mp->bd_id = ntohl(bd_id);
3673     mp->flood = flood;
3674     mp->uu_flood = uu_flood;
3675     mp->forward = forward;
3676     mp->learn = learn;
3677     mp->arp_term = arp_term;
3678     mp->is_add = is_add;
3679
3680     S; W;
3681     /* NOTREACHED */
3682     return 0;
3683 }
3684
3685 static int api_l2fib_add_del (vat_main_t * vam)
3686 {
3687     unformat_input_t * i = vam->input;
3688     vl_api_l2fib_add_del_t *mp;
3689     f64 timeout;
3690     u64 mac = 0;
3691     u8 mac_set = 0;
3692     u32 bd_id;
3693     u8 bd_id_set = 0;
3694     u32 sw_if_index;
3695     u8 sw_if_index_set = 0;
3696     u8 is_add = 1;
3697     u8 static_mac = 0;
3698     u8 filter_mac = 0;
3699
3700     /* Parse args required to build the message */
3701     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3702         if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3703             mac_set = 1;
3704         else if (unformat (i, "bd_id %d", &bd_id))
3705             bd_id_set = 1;
3706         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3707             sw_if_index_set = 1;        
3708         else if (unformat (i, "sw_if")) {
3709             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3710                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3711                     sw_if_index_set = 1;
3712             } else
3713                 break;
3714         } else if (unformat (i, "static"))
3715                 static_mac = 1;
3716         else if (unformat (i, "filter")) {
3717                 filter_mac = 1;
3718                 static_mac = 1;
3719         } else if (unformat (i, "del"))
3720                 is_add = 0;
3721         else
3722             break;
3723     }
3724
3725     if (mac_set == 0) {
3726         errmsg ("missing mac address\n");
3727         return -99;
3728     }
3729
3730     if (bd_id_set == 0) {
3731         errmsg ("missing bridge domain\n");
3732         return -99;
3733     }
3734
3735     if (is_add && (sw_if_index_set == 0)) {
3736         errmsg ("missing interface name or sw_if_index\n");
3737         return -99;
3738     }
3739
3740     M(L2FIB_ADD_DEL, l2fib_add_del);
3741
3742     mp->mac = mac;
3743     mp->bd_id = ntohl(bd_id);
3744     mp->is_add = is_add;
3745
3746     if (is_add) {
3747         mp->sw_if_index = ntohl(sw_if_index);
3748         mp->static_mac = static_mac;
3749         mp->filter_mac = filter_mac;
3750     }
3751     
3752     S; W;
3753     /* NOTREACHED */
3754     return 0;
3755 }
3756
3757 static int api_l2_flags (vat_main_t * vam)
3758 {
3759     unformat_input_t * i = vam->input;
3760     vl_api_l2_flags_t *mp;
3761     f64 timeout;
3762     u32 sw_if_index;
3763     u32 feature_bitmap = 0;
3764     u8 sw_if_index_set = 0;
3765
3766     /* Parse args required to build the message */
3767     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3768         if (unformat (i, "sw_if_index %d", &sw_if_index))
3769             sw_if_index_set = 1;        
3770         else if (unformat (i, "sw_if")) {
3771             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3772                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3773                     sw_if_index_set = 1;
3774             } else
3775                 break;
3776         } else if (unformat (i, "learn"))
3777             feature_bitmap |= L2INPUT_FEAT_LEARN;
3778         else if (unformat (i, "forward"))
3779             feature_bitmap |= L2INPUT_FEAT_FWD;
3780         else if (unformat (i, "flood"))
3781             feature_bitmap |= L2INPUT_FEAT_FLOOD;
3782         else if (unformat (i, "uu-flood"))
3783             feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3784         else
3785             break;
3786     }
3787
3788     if (sw_if_index_set == 0) {
3789         errmsg ("missing interface name or sw_if_index\n");
3790         return -99;
3791     }
3792
3793     M(L2_FLAGS, l2_flags);
3794
3795     mp->sw_if_index = ntohl(sw_if_index);
3796     mp->feature_bitmap = ntohl(feature_bitmap);
3797
3798     S; W;
3799     /* NOTREACHED */
3800     return 0;
3801 }
3802
3803 static int api_bridge_flags (vat_main_t * vam)
3804 {
3805     unformat_input_t * i = vam->input;
3806     vl_api_bridge_flags_t *mp;
3807     f64 timeout;
3808     u32 bd_id;
3809     u8 bd_id_set = 0;
3810     u8 is_set = 1;
3811     u32 flags = 0;
3812
3813     /* Parse args required to build the message */
3814     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3815         if (unformat (i, "bd_id %d", &bd_id))
3816             bd_id_set = 1;
3817         else if (unformat (i, "learn"))
3818             flags |= L2_LEARN;
3819         else if (unformat (i, "forward"))
3820             flags |= L2_FWD;
3821         else if (unformat (i, "flood"))
3822             flags |= L2_FLOOD;
3823         else if (unformat (i, "uu-flood"))
3824             flags |= L2_UU_FLOOD;
3825         else if (unformat (i, "arp-term"))
3826             flags |= L2_ARP_TERM;
3827         else if (unformat (i, "off"))
3828             is_set = 0;
3829         else if (unformat (i, "disable"))
3830             is_set = 0;
3831         else
3832             break;
3833     }
3834
3835     if (bd_id_set == 0) {
3836         errmsg ("missing bridge domain\n");
3837         return -99;
3838     }
3839
3840     M(BRIDGE_FLAGS, bridge_flags);
3841
3842     mp->bd_id = ntohl(bd_id);
3843     mp->feature_bitmap = ntohl(flags);
3844     mp->is_set = is_set;
3845
3846     S; W;
3847     /* NOTREACHED */
3848     return 0;
3849 }
3850
3851 static int api_bd_ip_mac_add_del (vat_main_t * vam)
3852 {
3853     unformat_input_t * i = vam->input;
3854     vl_api_bd_ip_mac_add_del_t *mp;
3855     f64 timeout;
3856     u32 bd_id;
3857     u8 is_ipv6 = 0;
3858     u8 is_add = 1;
3859     u8 bd_id_set = 0;
3860     u8 ip_set = 0;
3861     u8 mac_set = 0;
3862     ip4_address_t v4addr;
3863     ip6_address_t v6addr;
3864     u8 macaddr[6];
3865     
3866
3867     /* Parse args required to build the message */
3868     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3869         if (unformat (i, "bd_id %d", &bd_id)) {
3870             bd_id_set++;
3871         } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3872             ip_set++;
3873         } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3874             ip_set++;
3875             is_ipv6++;
3876         } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3877             mac_set++;
3878         } else if (unformat (i, "del"))
3879             is_add = 0;
3880         else
3881             break;
3882     }
3883
3884     if (bd_id_set == 0) {
3885         errmsg ("missing bridge domain\n");
3886         return -99;
3887     } else if (ip_set == 0) {
3888         errmsg ("missing IP address\n");
3889         return -99;
3890     } else if (mac_set == 0) {
3891         errmsg ("missing MAC address\n");
3892         return -99;
3893     }
3894
3895     M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3896
3897     mp->bd_id = ntohl(bd_id);
3898     mp->is_ipv6 = is_ipv6;
3899     mp->is_add = is_add;
3900     if (is_ipv6)
3901          clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3902     else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3903     clib_memcpy (mp->mac_address, macaddr, 6);
3904     S; W;
3905     /* NOTREACHED */
3906     return 0;
3907 }
3908
3909 static int api_tap_connect (vat_main_t * vam)
3910 {
3911     unformat_input_t * i = vam->input;
3912     vl_api_tap_connect_t *mp;
3913     f64 timeout;
3914     u8 mac_address[6];
3915     u8 random_mac = 1;
3916     u8 name_set = 0;
3917     u8 * tap_name;
3918
3919     memset (mac_address, 0, sizeof (mac_address));
3920     
3921     /* Parse args required to build the message */
3922     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3923         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3924             random_mac = 0;
3925         }
3926         else if (unformat (i, "random-mac"))
3927             random_mac = 1;
3928         else if (unformat (i, "tapname %s", &tap_name))
3929             name_set = 1;
3930         else
3931             break;
3932     }
3933
3934     if (name_set == 0) {
3935         errmsg ("missing tap name\n");
3936         return -99;
3937     }
3938     if (vec_len (tap_name) > 63) {
3939         errmsg ("tap name too long\n");
3940     }
3941     vec_add1 (tap_name, 0);
3942         
3943     /* Construct the API message */
3944     M(TAP_CONNECT, tap_connect);
3945
3946     mp->use_random_mac = random_mac;
3947     clib_memcpy (mp->mac_address, mac_address, 6);
3948     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3949     vec_free (tap_name);
3950
3951     /* send it... */
3952     S;
3953
3954     /* Wait for a reply... */
3955     W;
3956 }
3957
3958 static int api_tap_modify (vat_main_t * vam)
3959 {
3960     unformat_input_t * i = vam->input;
3961     vl_api_tap_modify_t *mp;
3962     f64 timeout;
3963     u8 mac_address[6];
3964     u8 random_mac = 1;
3965     u8 name_set = 0;
3966     u8 * tap_name;
3967     u32 sw_if_index = ~0;
3968     u8 sw_if_index_set = 0;
3969
3970     memset (mac_address, 0, sizeof (mac_address));
3971     
3972     /* Parse args required to build the message */
3973     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3974         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3975             sw_if_index_set = 1;
3976         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3977             sw_if_index_set = 1;
3978         else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3979             random_mac = 0;
3980         }
3981         else if (unformat (i, "random-mac"))
3982             random_mac = 1;
3983         else if (unformat (i, "tapname %s", &tap_name))
3984             name_set = 1;
3985         else
3986             break;
3987     }
3988
3989     if (sw_if_index_set == 0) {
3990         errmsg ("missing vpp interface name");
3991         return -99;
3992     }
3993     if (name_set == 0) {
3994         errmsg ("missing tap name\n");
3995         return -99;
3996     }
3997     if (vec_len (tap_name) > 63) {
3998         errmsg ("tap name too long\n");
3999     }
4000     vec_add1 (tap_name, 0);
4001         
4002     /* Construct the API message */
4003     M(TAP_MODIFY, tap_modify);
4004
4005     mp->use_random_mac = random_mac;
4006     mp->sw_if_index = ntohl(sw_if_index);
4007     clib_memcpy (mp->mac_address, mac_address, 6);
4008     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
4009     vec_free (tap_name);
4010
4011     /* send it... */
4012     S;
4013
4014     /* Wait for a reply... */
4015     W;
4016 }
4017
4018 static int api_tap_delete (vat_main_t * vam)
4019 {
4020     unformat_input_t * i = vam->input;
4021     vl_api_tap_delete_t *mp;
4022     f64 timeout;
4023     u32 sw_if_index = ~0;
4024     u8 sw_if_index_set = 0;
4025
4026     /* Parse args required to build the message */
4027     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4028         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4029             sw_if_index_set = 1;
4030         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4031             sw_if_index_set = 1;
4032         else
4033             break;
4034     }
4035
4036     if (sw_if_index_set == 0) {
4037         errmsg ("missing vpp interface name");
4038         return -99;
4039     }
4040         
4041     /* Construct the API message */
4042     M(TAP_DELETE, tap_delete);
4043
4044     mp->sw_if_index = ntohl(sw_if_index);
4045
4046     /* send it... */
4047     S;
4048
4049     /* Wait for a reply... */
4050     W;
4051 }
4052
4053 static int api_ip_add_del_route (vat_main_t * vam)
4054 {
4055     unformat_input_t * i = vam->input;
4056     vl_api_ip_add_del_route_t *mp;
4057     f64 timeout;
4058     u32 sw_if_index = 0, vrf_id = 0;
4059     u8 sw_if_index_set = 0;
4060     u8 is_ipv6 = 0;
4061     u8 is_local = 0, is_drop = 0;
4062     u8 create_vrf_if_needed = 0;
4063     u8 is_add = 1;
4064     u8 next_hop_weight = 1;
4065     u8 not_last = 0;
4066     u8 is_multipath = 0;
4067     u8 address_set = 0;
4068     u8 address_length_set = 0;
4069     u32 lookup_in_vrf = 0;
4070     u32 resolve_attempts = 0;
4071     u32 dst_address_length = 0;
4072     u8 next_hop_set = 0;
4073     ip4_address_t v4_dst_address, v4_next_hop_address;
4074     ip6_address_t v6_dst_address, v6_next_hop_address;
4075     int count = 1;
4076     int j;
4077     f64 before = 0;
4078     u32 random_add_del = 0;
4079     u32 * random_vector = 0;
4080     uword * random_hash;
4081     u32 random_seed = 0xdeaddabe;
4082     u32 classify_table_index = ~0;
4083     u8 is_classify = 0;
4084     
4085     /* Parse args required to build the message */
4086     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4087         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4088             sw_if_index_set = 1;
4089         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4090             sw_if_index_set = 1;
4091         else if (unformat (i, "%U", unformat_ip4_address,
4092                            &v4_dst_address)) {
4093             address_set = 1;
4094             is_ipv6 = 0;
4095         }
4096         else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
4097             address_set = 1;
4098             is_ipv6 = 1;
4099         }
4100         else if (unformat (i, "/%d", &dst_address_length)) {
4101             address_length_set = 1;
4102         }
4103         
4104         else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address, 
4105                                            &v4_next_hop_address)) {
4106             next_hop_set = 1;
4107         }
4108         else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address, 
4109                                            &v6_next_hop_address)) {
4110             next_hop_set = 1;
4111         }
4112         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4113             ;
4114         else if (unformat (i, "weight %d", &next_hop_weight))
4115             ;
4116         else if (unformat (i, "drop")) {
4117             is_drop = 1;
4118         } else if (unformat (i, "local")) {
4119             is_local = 1;
4120         } else if (unformat (i, "classify %d", &classify_table_index)) {
4121             is_classify = 1;
4122         } else if (unformat (i, "del"))
4123             is_add = 0;
4124         else if (unformat (i, "add"))
4125             is_add = 1;
4126         else if (unformat (i, "not-last"))
4127             not_last = 1;
4128         else if (unformat (i, "multipath"))
4129             is_multipath = 1;
4130         else if (unformat (i, "vrf %d", &vrf_id))
4131             ;
4132         else if (unformat (i, "create-vrf"))
4133             create_vrf_if_needed = 1;
4134         else if (unformat (i, "count %d", &count))
4135             ;
4136         else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4137             ;
4138         else if (unformat (i, "random"))
4139             random_add_del = 1;
4140         else if (unformat (i, "seed %d", &random_seed))
4141             ;
4142         else {
4143             clib_warning ("parse error '%U'", format_unformat_error, i);
4144             return -99;
4145         }
4146     }
4147
4148     if (resolve_attempts > 0 && sw_if_index_set == 0) {
4149         errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4150         return -99;
4151     }
4152     
4153     if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4154         errmsg ("next hop / local / drop / classify not set\n");
4155         return -99;
4156     }
4157
4158     if (address_set == 0) {
4159         errmsg ("missing addresses\n");
4160         return -99;
4161     }
4162
4163     if (address_length_set == 0) {
4164         errmsg ("missing address length\n");
4165         return -99;
4166     }
4167     
4168     /* Generate a pile of unique, random routes */
4169     if (random_add_del) {
4170         u32 this_random_address;
4171         random_hash = hash_create (count, sizeof(uword));
4172
4173         hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4174         for (j = 0; j <= count; j++) {
4175             do {
4176                 this_random_address = random_u32 (&random_seed);
4177                 this_random_address = 
4178                     clib_host_to_net_u32 (this_random_address);
4179             } while (hash_get (random_hash, this_random_address));
4180             vec_add1 (random_vector, this_random_address);
4181             hash_set (random_hash, this_random_address, 1);
4182         }
4183         hash_free (random_hash);
4184         v4_dst_address.as_u32 = random_vector[0];
4185     }
4186
4187     if (count > 1) {
4188         /* Turn on async mode */
4189         vam->async_mode = 1;
4190         vam->async_errors = 0;
4191         before = vat_time_now(vam);
4192     }
4193
4194     for (j = 0; j < count; j++) {
4195         /* Construct the API message */
4196         M(IP_ADD_DEL_ROUTE, ip_add_del_route);
4197     
4198         mp->next_hop_sw_if_index = ntohl (sw_if_index);
4199         mp->vrf_id = ntohl (vrf_id);
4200         if (resolve_attempts > 0) {
4201             mp->resolve_attempts = ntohl (resolve_attempts);
4202             mp->resolve_if_needed = 1;
4203         }
4204         mp->create_vrf_if_needed = create_vrf_if_needed;
4205     
4206         mp->is_add = is_add;
4207         mp->is_drop = is_drop;
4208         mp->is_ipv6 = is_ipv6;
4209         mp->is_local = is_local;
4210         mp->is_classify = is_classify;
4211         mp->is_multipath = is_multipath;
4212         mp->not_last = not_last;
4213         mp->next_hop_weight = next_hop_weight;
4214         mp->dst_address_length = dst_address_length;
4215         mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4216         mp->classify_table_index = ntohl(classify_table_index);
4217
4218         if (is_ipv6){
4219             clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
4220             if (next_hop_set)
4221                 clib_memcpy (mp->next_hop_address, &v6_next_hop_address, 
4222                         sizeof (v6_next_hop_address));
4223             increment_v6_address (&v6_dst_address);
4224         } else {
4225             clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
4226             if (next_hop_set)
4227                 clib_memcpy (mp->next_hop_address, &v4_next_hop_address, 
4228                         sizeof (v4_next_hop_address));
4229             if (random_add_del)
4230                 v4_dst_address.as_u32 = random_vector[j+1];
4231             else
4232                 increment_v4_address (&v4_dst_address);
4233         }
4234         /* send it... */
4235         S;
4236     }
4237
4238     /* When testing multiple add/del ops, use a control-ping to sync */
4239     if (count > 1) {
4240         vl_api_control_ping_t * mp;
4241         f64 after;
4242
4243         /* Shut off async mode */
4244         vam->async_mode = 0;
4245
4246         M(CONTROL_PING, control_ping);
4247         S;
4248
4249         timeout = vat_time_now(vam) + 1.0;
4250         while (vat_time_now (vam) < timeout)
4251             if (vam->result_ready == 1)
4252                 goto out;
4253         vam->retval = -99;
4254
4255     out:
4256         if (vam->retval == -99)
4257             errmsg ("timeout\n");
4258
4259         if (vam->async_errors > 0) {
4260             errmsg ("%d asynchronous errors\n", vam->async_errors);
4261             vam->retval = -98;
4262         }
4263         vam->async_errors = 0;
4264         after = vat_time_now(vam);
4265
4266         fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4267                 count, after - before, count / (after - before));
4268     } else {
4269         /* Wait for a reply... */
4270         W;
4271     }
4272
4273     /* Return the good/bad news */
4274     return (vam->retval);
4275 }
4276
4277 static int api_proxy_arp_add_del (vat_main_t * vam)
4278 {
4279     unformat_input_t * i = vam->input;
4280     vl_api_proxy_arp_add_del_t *mp;
4281     f64 timeout;
4282     u32 vrf_id = 0;
4283     u8 is_add = 1;
4284     ip4_address_t lo, hi;
4285     u8 range_set = 0;
4286
4287     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4288         if (unformat (i, "vrf %d", &vrf_id))
4289             ;
4290         else if (unformat (i, "%U - %U", unformat_ip4_address, &lo, 
4291                            unformat_ip4_address, &hi))
4292             range_set = 1;
4293         else if (unformat (i, "del"))
4294             is_add = 0;
4295         else {
4296             clib_warning ("parse error '%U'", format_unformat_error, i);
4297             return -99;
4298         }
4299     }
4300     
4301     if (range_set == 0) {
4302         errmsg ("address range not set\n");
4303         return -99;
4304     }
4305
4306     M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4307
4308     mp->vrf_id = ntohl(vrf_id);
4309     mp->is_add = is_add;
4310     clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4311     clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
4312
4313     S; W;
4314     /* NOTREACHED */
4315     return 0;
4316 }
4317
4318 static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4319 {
4320     unformat_input_t * i = vam->input;
4321     vl_api_proxy_arp_intfc_enable_disable_t *mp;
4322     f64 timeout;
4323     u32 sw_if_index;
4324     u8 enable = 1;
4325     u8 sw_if_index_set = 0;
4326
4327     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4328         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4329             sw_if_index_set = 1;
4330         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4331             sw_if_index_set = 1;
4332         else if (unformat (i, "enable"))
4333             enable = 1;
4334         else if (unformat (i, "disable"))
4335             enable = 0;
4336         else {
4337             clib_warning ("parse error '%U'", format_unformat_error, i);
4338             return -99;
4339         }
4340     }
4341     
4342     if (sw_if_index_set == 0) {
4343         errmsg ("missing interface name or sw_if_index\n");
4344         return -99;
4345     }
4346
4347     M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4348
4349     mp->sw_if_index = ntohl(sw_if_index);
4350     mp->enable_disable = enable;
4351
4352     S; W;
4353     /* NOTREACHED */
4354     return 0;
4355 }
4356
4357 static int api_mpls_add_del_decap (vat_main_t * vam)
4358 {
4359     unformat_input_t * i = vam->input;
4360     vl_api_mpls_add_del_decap_t *mp;
4361     f64 timeout;
4362     u32 rx_vrf_id = 0;
4363     u32 tx_vrf_id = 0;
4364     u32 label = 0;
4365     u8 is_add = 1;
4366     u8 s_bit = 1;
4367     u32 next_index = 1;
4368
4369     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4370         if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4371             ;
4372         else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4373             ;
4374         else if (unformat (i, "label %d", &label))
4375             ;
4376         else if (unformat (i, "next-index %d", &next_index))
4377             ;
4378         else if (unformat (i, "del"))
4379             is_add = 0;
4380         else if (unformat (i, "s-bit-clear"))
4381             s_bit = 0;
4382         else {
4383             clib_warning ("parse error '%U'", format_unformat_error, i);
4384             return -99;
4385         }
4386     }
4387     
4388     M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4389
4390     mp->rx_vrf_id = ntohl(rx_vrf_id);
4391     mp->tx_vrf_id = ntohl(tx_vrf_id);
4392     mp->label = ntohl(label);
4393     mp->next_index = ntohl(next_index);
4394     mp->s_bit = s_bit;
4395     mp->is_add = is_add;
4396
4397     S; W;
4398     /* NOTREACHED */
4399     return 0;
4400 }
4401
4402 static int api_mpls_add_del_encap (vat_main_t * vam)
4403 {
4404     unformat_input_t * i = vam->input;
4405     vl_api_mpls_add_del_encap_t *mp;
4406     f64 timeout;
4407     u32 vrf_id = 0;
4408     u32 *labels = 0;
4409     u32 label;
4410     ip4_address_t dst_address;
4411     u8 is_add = 1;
4412
4413     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4414         if (unformat (i, "vrf %d", &vrf_id))
4415             ;
4416         else if (unformat (i, "label %d", &label))
4417             vec_add1 (labels, ntohl(label));
4418         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4419             ;
4420         else if (unformat (i, "del"))
4421             is_add = 0;
4422         else {
4423             clib_warning ("parse error '%U'", format_unformat_error, i);
4424             return -99;
4425         }
4426     }
4427
4428     if (vec_len (labels) == 0) {
4429         errmsg ("missing encap label stack\n");
4430         return -99;
4431     }
4432     
4433     M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap, 
4434        sizeof (u32) * vec_len (labels));
4435
4436     mp->vrf_id = ntohl(vrf_id);
4437     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4438     mp->is_add = is_add;
4439     mp->nlabels = vec_len (labels);
4440     clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
4441
4442     vec_free(labels);
4443
4444     S; W;
4445     /* NOTREACHED */
4446     return 0;
4447 }
4448
4449 static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4450 {
4451     unformat_input_t * i = vam->input;
4452     vl_api_mpls_gre_add_del_tunnel_t *mp;
4453     f64 timeout;
4454     u32 inner_vrf_id = 0;
4455     u32 outer_vrf_id = 0;
4456     ip4_address_t src_address;
4457     ip4_address_t dst_address;
4458     ip4_address_t intfc_address;
4459     u32 tmp;
4460     u8 intfc_address_length = 0;
4461     u8 is_add = 1;
4462     u8 l2_only = 0;
4463     
4464     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4465         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4466             ;
4467         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4468             ;
4469         else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4470             ;
4471         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4472             ;
4473         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4474                            &intfc_address, &tmp))
4475             intfc_address_length = tmp;
4476         else if (unformat (i, "l2-only"))
4477             l2_only = 1;
4478         else if (unformat (i, "del"))
4479             is_add = 0;
4480         else {
4481             clib_warning ("parse error '%U'", format_unformat_error, i);
4482             return -99;
4483         }
4484     }
4485     
4486     M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4487
4488     mp->inner_vrf_id = ntohl(inner_vrf_id);
4489     mp->outer_vrf_id = ntohl(outer_vrf_id);
4490     clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4491     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4492     clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
4493     mp->intfc_address_length = intfc_address_length;
4494     mp->l2_only = l2_only;
4495     mp->is_add = is_add;
4496
4497     S; W;
4498     /* NOTREACHED */
4499     return 0;
4500 }
4501
4502 static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4503 {
4504     unformat_input_t * i = vam->input;
4505     vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4506     f64 timeout;
4507     u32 inner_vrf_id = 0;
4508     ip4_address_t intfc_address;
4509     u8 dst_mac_address[6];
4510     int dst_set = 1;
4511     u32 tmp;
4512     u8 intfc_address_length = 0;
4513     u8 is_add = 1;
4514     u8 l2_only = 0;
4515     u32 tx_sw_if_index;
4516     int tx_sw_if_index_set = 0;
4517     
4518     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4519         if (unformat (i, "vrf %d", &inner_vrf_id))
4520             ;
4521         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4522                            &intfc_address, &tmp))
4523             intfc_address_length = tmp;
4524         else if (unformat (i, "%U", 
4525                            unformat_sw_if_index, vam, &tx_sw_if_index))
4526             tx_sw_if_index_set = 1;
4527         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4528             tx_sw_if_index_set = 1;
4529         else if (unformat (i, "dst %U", unformat_ethernet_address, 
4530                            dst_mac_address))
4531             dst_set = 1;
4532         else if (unformat (i, "l2-only"))
4533             l2_only = 1;
4534         else if (unformat (i, "del"))
4535             is_add = 0;
4536         else {
4537             clib_warning ("parse error '%U'", format_unformat_error, i);
4538             return -99;
4539         }
4540     }
4541
4542     if (!dst_set) {
4543         errmsg ("dst (mac address) not set\n");
4544         return -99;
4545     }
4546     if (!tx_sw_if_index_set) {
4547         errmsg ("tx-intfc not set\n");
4548         return -99;
4549     }
4550     
4551     M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4552
4553     mp->vrf_id = ntohl(inner_vrf_id);
4554     clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
4555     mp->adj_address_length = intfc_address_length;
4556     clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
4557     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4558     mp->l2_only = l2_only;
4559     mp->is_add = is_add;
4560
4561     S; W;
4562     /* NOTREACHED */
4563     return 0;
4564 }
4565
4566 static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4567 {
4568     unformat_input_t * i = vam->input;
4569     vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4570     f64 timeout;
4571     u32 inner_vrf_id = 0;
4572     u32 outer_vrf_id = 0;
4573     ip4_address_t adj_address;
4574     int adj_address_set = 0;
4575     ip4_address_t next_hop_address;
4576     int next_hop_address_set = 0;
4577     u32 tmp;
4578     u8 adj_address_length = 0;
4579     u8 l2_only = 0;
4580     u8 is_add = 1;
4581     u32 resolve_attempts = 5;
4582     u8 resolve_if_needed = 1;
4583     
4584     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4585         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4586             ;
4587         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4588             ;
4589         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4590                            &adj_address, &tmp)) {
4591             adj_address_length = tmp;
4592             adj_address_set = 1;
4593         }
4594         else if (unformat (i, "next-hop %U", unformat_ip4_address,
4595                            &next_hop_address))
4596             next_hop_address_set = 1;
4597         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4598             ;
4599         else if (unformat (i, "resolve-if-needed %d", &tmp))
4600             resolve_if_needed = tmp;
4601         else if (unformat (i, "l2-only"))
4602             l2_only = 1;
4603         else if (unformat (i, "del"))
4604             is_add = 0;
4605         else {
4606             clib_warning ("parse error '%U'", format_unformat_error, i);
4607             return -99;
4608         }
4609     }
4610     
4611     if (!adj_address_set) {
4612         errmsg ("adjacency address/mask not set\n");
4613         return -99;
4614     }
4615     if (!next_hop_address_set) {
4616         errmsg ("ip4 next hop address (in outer fib) not set\n");
4617         return -99;
4618     }
4619     
4620     M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4621     
4622     mp->inner_vrf_id = ntohl(inner_vrf_id);
4623     mp->outer_vrf_id = ntohl(outer_vrf_id);
4624     mp->resolve_attempts = ntohl(resolve_attempts);
4625     mp->resolve_if_needed = resolve_if_needed;
4626     mp->is_add = is_add;
4627     mp->l2_only = l2_only;
4628     clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
4629     mp->adj_address_length = adj_address_length;
4630     clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address, 
4631             sizeof (next_hop_address));
4632
4633     S; W;
4634     /* NOTREACHED */
4635     return 0;
4636 }
4637
4638 static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4639 {
4640     unformat_input_t * i = vam->input;
4641     vl_api_sw_interface_set_unnumbered_t *mp;
4642     f64 timeout;
4643     u32 sw_if_index;
4644     u32 unnum_sw_index;
4645     u8  is_add = 1;
4646     u8 sw_if_index_set = 0;
4647
4648     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4649         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4650             sw_if_index_set = 1;
4651         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4652             sw_if_index_set = 1;
4653         else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4654             ;
4655         else if (unformat (i, "del"))
4656             is_add = 0;
4657         else {
4658             clib_warning ("parse error '%U'", format_unformat_error, i);
4659             return -99;
4660         }
4661     }
4662     
4663     if (sw_if_index_set == 0) {
4664         errmsg ("missing interface name or sw_if_index\n");
4665         return -99;
4666     }
4667
4668     M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4669
4670     mp->sw_if_index = ntohl(sw_if_index);
4671     mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4672     mp->is_add = is_add;
4673
4674     S; W;
4675     /* NOTREACHED */
4676     return 0;
4677 }
4678
4679 static int api_ip_neighbor_add_del (vat_main_t * vam)
4680 {
4681     unformat_input_t * i = vam->input;
4682     vl_api_ip_neighbor_add_del_t *mp;
4683     f64 timeout;
4684     u32 sw_if_index;
4685     u8 sw_if_index_set = 0;
4686     u32 vrf_id = 0;
4687     u8 is_add = 1;
4688     u8 is_static = 0;
4689     u8 mac_address[6];
4690     u8 mac_set = 0;
4691     u8 v4_address_set = 0;
4692     u8 v6_address_set = 0;
4693     ip4_address_t v4address;
4694     ip6_address_t v6address;
4695     
4696     memset (mac_address, 0, sizeof (mac_address));
4697     
4698     /* Parse args required to build the message */
4699     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4700         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4701             mac_set = 1;
4702         }
4703         else if (unformat (i, "del"))
4704             is_add = 0;
4705         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4706             sw_if_index_set = 1;
4707         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4708             sw_if_index_set = 1;
4709         else if (unformat (i, "is_static"))
4710             is_static = 1;
4711         else if (unformat (i, "vrf %d", &vrf_id))
4712             ;
4713         else if (unformat (i, "dst %U", 
4714                            unformat_ip4_address, &v4address))
4715                 v4_address_set = 1;
4716         else if (unformat (i, "dst %U", 
4717                            unformat_ip6_address, &v6address))
4718                 v6_address_set = 1;
4719         else {
4720             clib_warning ("parse error '%U'", format_unformat_error, i);
4721             return -99;
4722         }
4723     }
4724
4725     if (sw_if_index_set == 0) {
4726         errmsg ("missing interface name or sw_if_index\n");
4727         return -99;
4728     }
4729     if (v4_address_set && v6_address_set) {
4730         errmsg ("both v4 and v6 addresses set\n");
4731         return -99;
4732     }
4733     if (!v4_address_set && !v6_address_set) {
4734         errmsg ("no addresses set\n");
4735         return -99;
4736     }
4737
4738     /* Construct the API message */
4739     M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4740
4741     mp->sw_if_index = ntohl (sw_if_index);
4742     mp->is_add = is_add;
4743     mp->vrf_id = ntohl (vrf_id);
4744     mp->is_static = is_static;
4745     if (mac_set)
4746         clib_memcpy (mp->mac_address, mac_address, 6);
4747     if (v6_address_set) {
4748         mp->is_ipv6 = 1;
4749         clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
4750     } else {
4751         /* mp->is_ipv6 = 0; via memset in M macro above */
4752         clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
4753     }
4754
4755     /* send it... */
4756     S;
4757
4758     /* Wait for a reply, return good/bad news  */
4759     W;
4760
4761     /* NOTREACHED */
4762     return 0;
4763 }
4764
4765 static int api_reset_vrf (vat_main_t * vam)
4766 {
4767     unformat_input_t * i = vam->input;
4768     vl_api_reset_vrf_t *mp;
4769     f64 timeout;
4770     u32 vrf_id = 0;
4771     u8 is_ipv6 = 0;
4772     u8 vrf_id_set = 0;
4773
4774     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4775         if (unformat (i, "vrf %d", &vrf_id))
4776             vrf_id_set = 1;
4777         else if (unformat (i, "ipv6"))
4778             is_ipv6 = 1;
4779         else {
4780             clib_warning ("parse error '%U'", format_unformat_error, i);
4781             return -99;
4782         }
4783     }
4784
4785     if (vrf_id_set == 0) {
4786         errmsg ("missing vrf id\n");
4787         return -99;
4788     }
4789     
4790     M(RESET_VRF, reset_vrf);
4791
4792     mp->vrf_id = ntohl(vrf_id);
4793     mp->is_ipv6 = is_ipv6;
4794
4795     S; W;
4796     /* NOTREACHED */
4797     return 0;
4798 }
4799
4800 static int api_create_vlan_subif (vat_main_t * vam)
4801 {
4802     unformat_input_t * i = vam->input;
4803     vl_api_create_vlan_subif_t *mp;
4804     f64 timeout;
4805     u32 sw_if_index;
4806     u8  sw_if_index_set = 0;
4807     u32 vlan_id;
4808     u8  vlan_id_set = 0;
4809
4810     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4811         if (unformat (i, "sw_if_index %d", &sw_if_index))
4812             sw_if_index_set = 1;
4813         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4814             sw_if_index_set = 1;
4815         else if (unformat (i, "vlan %d", &vlan_id))
4816             vlan_id_set = 1;
4817         else {
4818             clib_warning ("parse error '%U'", format_unformat_error, i);
4819             return -99;
4820         }
4821     }
4822     
4823     if (sw_if_index_set == 0) {
4824         errmsg ("missing interface name or sw_if_index\n");
4825         return -99;
4826     }
4827
4828     if (vlan_id_set == 0) {
4829         errmsg ("missing vlan_id\n");
4830         return -99;
4831     }
4832     M(CREATE_VLAN_SUBIF, create_vlan_subif);
4833
4834     mp->sw_if_index = ntohl(sw_if_index);
4835     mp->vlan_id = ntohl(vlan_id);
4836
4837     S; W;
4838     /* NOTREACHED */
4839     return 0;
4840 }
4841
4842 #define foreach_create_subif_bit                \
4843 _(no_tags)                                      \
4844 _(one_tag)                                      \
4845 _(two_tags)                                     \
4846 _(dot1ad)                                       \
4847 _(exact_match)                                  \
4848 _(default_sub)                                  \
4849 _(outer_vlan_id_any)                            \
4850 _(inner_vlan_id_any)
4851
4852 static int api_create_subif (vat_main_t * vam)
4853 {
4854     unformat_input_t * i = vam->input;
4855     vl_api_create_subif_t *mp;
4856     f64 timeout;
4857     u32 sw_if_index;
4858     u8  sw_if_index_set = 0;
4859     u32 sub_id;
4860     u8  sub_id_set = 0;
4861     u32 no_tags = 0;
4862     u32 one_tag = 0;
4863     u32 two_tags = 0;
4864     u32 dot1ad = 0;
4865     u32 exact_match = 0;
4866     u32 default_sub = 0;
4867     u32 outer_vlan_id_any = 0;
4868     u32 inner_vlan_id_any = 0;
4869     u32 tmp;
4870     u16 outer_vlan_id = 0;
4871     u16 inner_vlan_id = 0;
4872
4873     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4874         if (unformat (i, "sw_if_index %d", &sw_if_index))
4875             sw_if_index_set = 1;
4876         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4877             sw_if_index_set = 1;
4878         else if (unformat (i, "sub_id %d", &sub_id))
4879             sub_id_set = 1;
4880         else if (unformat (i, "outer_vlan_id %d", &tmp))
4881             outer_vlan_id = tmp;
4882         else if (unformat (i, "inner_vlan_id %d", &tmp))
4883             inner_vlan_id = tmp;
4884
4885 #define _(a) else if (unformat (i, #a)) a = 1 ;
4886         foreach_create_subif_bit
4887 #undef _
4888
4889         else {
4890             clib_warning ("parse error '%U'", format_unformat_error, i);
4891             return -99;
4892         }
4893     }
4894     
4895     if (sw_if_index_set == 0) {
4896         errmsg ("missing interface name or sw_if_index\n");
4897         return -99;
4898     }
4899
4900     if (sub_id_set == 0) {
4901         errmsg ("missing sub_id\n");
4902         return -99;
4903     }
4904     M(CREATE_SUBIF, create_subif);
4905
4906     mp->sw_if_index = ntohl(sw_if_index);
4907     mp->sub_id = ntohl(sub_id);
4908     
4909 #define _(a) mp->a = a;
4910     foreach_create_subif_bit;
4911 #undef _
4912         
4913     mp->outer_vlan_id = ntohs (outer_vlan_id);
4914     mp->inner_vlan_id = ntohs (inner_vlan_id);
4915
4916     S; W;
4917     /* NOTREACHED */
4918     return 0;
4919 }
4920
4921 static int api_oam_add_del (vat_main_t * vam)
4922 {
4923     unformat_input_t * i = vam->input;
4924     vl_api_oam_add_del_t *mp;
4925     f64 timeout;
4926     u32 vrf_id = 0;
4927     u8 is_add = 1;
4928     ip4_address_t src, dst;
4929     u8 src_set = 0;
4930     u8 dst_set = 0;
4931     
4932     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4933         if (unformat (i, "vrf %d", &vrf_id))
4934             ;
4935         else if (unformat (i, "src %U", unformat_ip4_address, &src))
4936             src_set = 1;
4937         else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4938             dst_set = 1;
4939         else if (unformat (i, "del"))
4940             is_add = 0;
4941         else {
4942             clib_warning ("parse error '%U'", format_unformat_error, i);
4943             return -99;
4944         }
4945     }
4946     
4947     if (src_set == 0) {
4948         errmsg ("missing src addr\n");
4949         return -99;
4950     }
4951
4952     if (dst_set == 0) {
4953         errmsg ("missing dst addr\n");
4954         return -99;
4955     }
4956
4957     M(OAM_ADD_DEL, oam_add_del);
4958
4959     mp->vrf_id = ntohl(vrf_id);
4960     mp->is_add = is_add;
4961     clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
4962     clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
4963
4964     S; W;
4965     /* NOTREACHED */
4966     return 0;
4967 }
4968
4969 static int api_reset_fib (vat_main_t * vam)
4970 {
4971     unformat_input_t * i = vam->input;
4972     vl_api_reset_fib_t *mp;
4973     f64 timeout;
4974     u32 vrf_id = 0;
4975     u8 is_ipv6 = 0;
4976     u8 vrf_id_set = 0;
4977
4978     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4979         if (unformat (i, "vrf %d", &vrf_id))
4980             vrf_id_set = 1;
4981         else if (unformat (i, "ipv6"))
4982             is_ipv6 = 1;
4983         else {
4984             clib_warning ("parse error '%U'", format_unformat_error, i);
4985             return -99;
4986         }
4987     }
4988
4989     if (vrf_id_set == 0) {
4990         errmsg ("missing vrf id\n");
4991         return -99;
4992     }
4993     
4994     M(RESET_FIB, reset_fib);
4995
4996     mp->vrf_id = ntohl(vrf_id);
4997     mp->is_ipv6 = is_ipv6;
4998
4999     S; W;
5000     /* NOTREACHED */
5001     return 0;
5002 }
5003
5004 static int api_dhcp_proxy_config (vat_main_t * vam)
5005 {
5006     unformat_input_t * i = vam->input;
5007     vl_api_dhcp_proxy_config_t *mp;
5008     f64 timeout;
5009     u32 vrf_id = 0;
5010     u8 is_add = 1;
5011     u8 insert_cid = 1;
5012     u8 v4_address_set = 0;
5013     u8 v6_address_set = 0;
5014     ip4_address_t v4address;
5015     ip6_address_t v6address;
5016     u8 v4_src_address_set = 0;
5017     u8 v6_src_address_set = 0;
5018     ip4_address_t v4srcaddress;
5019     ip6_address_t v6srcaddress;
5020     
5021     /* Parse args required to build the message */
5022     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5023         if (unformat (i, "del"))
5024             is_add = 0;
5025         else if (unformat (i, "vrf %d", &vrf_id))
5026             ;
5027         else if (unformat (i, "insert-cid %d", &insert_cid))
5028             ;
5029         else if (unformat (i, "svr %U", 
5030                            unformat_ip4_address, &v4address))
5031                 v4_address_set = 1;
5032         else if (unformat (i, "svr %U", 
5033                            unformat_ip6_address, &v6address))
5034                 v6_address_set = 1;
5035         else if (unformat (i, "src %U", 
5036                            unformat_ip4_address, &v4srcaddress))
5037                 v4_src_address_set = 1;
5038         else if (unformat (i, "src %U", 
5039                            unformat_ip6_address, &v6srcaddress))
5040                 v6_src_address_set = 1;
5041         else
5042             break;
5043     }
5044
5045     if (v4_address_set && v6_address_set) {
5046         errmsg ("both v4 and v6 server addresses set\n");
5047         return -99;
5048     }
5049     if (!v4_address_set && !v6_address_set) {
5050         errmsg ("no server addresses set\n");
5051         return -99;
5052     }
5053
5054     if (v4_src_address_set && v6_src_address_set) {
5055         errmsg ("both v4 and v6  src addresses set\n");
5056         return -99;
5057     }
5058     if (!v4_src_address_set && !v6_src_address_set) {
5059         errmsg ("no src addresses set\n");
5060         return -99;
5061     }
5062
5063     if (!(v4_src_address_set && v4_address_set) &&
5064         !(v6_src_address_set && v6_address_set)) {
5065         errmsg ("no matching server and src addresses set\n");
5066         return -99;
5067     }
5068
5069     /* Construct the API message */
5070     M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
5071
5072     mp->insert_circuit_id = insert_cid;
5073     mp->is_add = is_add;
5074     mp->vrf_id = ntohl (vrf_id);
5075     if (v6_address_set) {
5076         mp->is_ipv6 = 1;
5077         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5078         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
5079     } else {
5080         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5081         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
5082     }
5083
5084     /* send it... */
5085     S;
5086
5087     /* Wait for a reply, return good/bad news  */
5088     W;
5089     /* NOTREACHED */
5090     return 0;
5091 }
5092
5093 static int api_dhcp_proxy_config_2 (vat_main_t * vam)
5094 {
5095     unformat_input_t * i = vam->input;
5096     vl_api_dhcp_proxy_config_2_t *mp;
5097     f64 timeout;
5098     u32 rx_vrf_id = 0;
5099     u32 server_vrf_id = 0;
5100     u8 is_add = 1;
5101     u8 insert_cid = 1;
5102     u8 v4_address_set = 0;
5103     u8 v6_address_set = 0;
5104     ip4_address_t v4address;
5105     ip6_address_t v6address;
5106     u8 v4_src_address_set = 0;
5107     u8 v6_src_address_set = 0;
5108     ip4_address_t v4srcaddress;
5109     ip6_address_t v6srcaddress;
5110     
5111     /* Parse args required to build the message */
5112     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5113         if (unformat (i, "del"))
5114             is_add = 0;
5115         else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5116             ;
5117         else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
5118             ;
5119         else if (unformat (i, "insert-cid %d", &insert_cid))
5120             ;
5121         else if (unformat (i, "svr %U", 
5122                            unformat_ip4_address, &v4address))
5123                 v4_address_set = 1;
5124         else if (unformat (i, "svr %U", 
5125                            unformat_ip6_address, &v6address))
5126                 v6_address_set = 1;
5127         else if (unformat (i, "src %U", 
5128                            unformat_ip4_address, &v4srcaddress))
5129                 v4_src_address_set = 1;
5130         else if (unformat (i, "src %U", 
5131                            unformat_ip6_address, &v6srcaddress))
5132                 v6_src_address_set = 1;
5133         else
5134             break;
5135     }
5136
5137     if (v4_address_set && v6_address_set) {
5138         errmsg ("both v4 and v6 server addresses set\n");
5139         return -99;
5140     }
5141     if (!v4_address_set && !v6_address_set) {
5142         errmsg ("no server addresses set\n");
5143         return -99;
5144     }
5145
5146     if (v4_src_address_set && v6_src_address_set) {
5147         errmsg ("both v4 and v6  src addresses set\n");
5148         return -99;
5149     }
5150     if (!v4_src_address_set && !v6_src_address_set) {
5151         errmsg ("no src addresses set\n");
5152         return -99;
5153     }
5154
5155     if (!(v4_src_address_set && v4_address_set) &&
5156         !(v6_src_address_set && v6_address_set)) {
5157         errmsg ("no matching server and src addresses set\n");
5158         return -99;
5159     }
5160
5161     /* Construct the API message */
5162     M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5163
5164     mp->insert_circuit_id = insert_cid;
5165     mp->is_add = is_add;
5166     mp->rx_vrf_id = ntohl (rx_vrf_id);
5167     mp->server_vrf_id = ntohl (server_vrf_id);
5168     if (v6_address_set) {
5169         mp->is_ipv6 = 1;
5170         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5171         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
5172     } else {
5173         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5174         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
5175     }
5176
5177     /* send it... */
5178     S;
5179
5180     /* Wait for a reply, return good/bad news  */
5181     W;
5182     /* NOTREACHED */
5183     return 0;
5184 }
5185
5186 static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5187 {
5188     unformat_input_t * i = vam->input;
5189     vl_api_dhcp_proxy_set_vss_t *mp;
5190     f64 timeout;
5191     u8  is_ipv6 = 0;
5192     u8  is_add = 1;
5193     u32 tbl_id;
5194     u8  tbl_id_set = 0;
5195     u32 oui;
5196     u8  oui_set = 0;
5197     u32 fib_id;
5198     u8  fib_id_set = 0;
5199
5200     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5201         if (unformat (i, "tbl_id %d", &tbl_id))
5202             tbl_id_set = 1;
5203         if (unformat (i, "fib_id %d", &fib_id))
5204             fib_id_set = 1;
5205         if (unformat (i, "oui %d", &oui))
5206             oui_set = 1;
5207         else if (unformat (i, "ipv6"))
5208             is_ipv6 = 1;
5209         else if (unformat (i, "del"))
5210             is_add = 0;
5211         else {
5212             clib_warning ("parse error '%U'", format_unformat_error, i);
5213             return -99;
5214         }
5215     }
5216
5217     if (tbl_id_set == 0) {
5218         errmsg ("missing tbl id\n");
5219         return -99;
5220     }
5221
5222     if (fib_id_set == 0) {
5223         errmsg ("missing fib id\n");
5224         return -99;
5225     }
5226     if (oui_set == 0) {
5227         errmsg ("missing oui\n");
5228         return -99;
5229     }
5230     
5231     M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5232     mp->tbl_id = ntohl(tbl_id);
5233     mp->fib_id = ntohl(fib_id);
5234     mp->oui = ntohl(oui);
5235     mp->is_ipv6 = is_ipv6;
5236     mp->is_add = is_add;
5237
5238     S; W;
5239     /* NOTREACHED */
5240     return 0;
5241 }
5242
5243 static int api_dhcp_client_config (vat_main_t * vam)
5244 {
5245     unformat_input_t * i = vam->input;
5246     vl_api_dhcp_client_config_t *mp;
5247     f64 timeout;
5248     u32 sw_if_index;
5249     u8 sw_if_index_set = 0;
5250     u8 is_add = 1;
5251     u8 * hostname = 0;
5252     u8 disable_event = 0;
5253
5254     /* Parse args required to build the message */
5255     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5256         if (unformat (i, "del"))
5257             is_add = 0;
5258         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5259             sw_if_index_set = 1;
5260         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5261             sw_if_index_set = 1;
5262         else if (unformat (i, "hostname %s", &hostname))
5263             ;
5264         else if (unformat (i, "disable_event"))
5265             disable_event = 1;
5266         else
5267             break;
5268     }
5269
5270     if (sw_if_index_set == 0) {
5271         errmsg ("missing interface name or sw_if_index\n");
5272         return -99;
5273     }
5274
5275     if (vec_len (hostname) > 63) {
5276         errmsg ("hostname too long\n");
5277     }
5278     vec_add1 (hostname, 0);
5279
5280     /* Construct the API message */
5281     M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5282
5283     mp->sw_if_index = ntohl (sw_if_index);
5284     clib_memcpy (mp->hostname, hostname, vec_len (hostname));
5285     vec_free (hostname);
5286     mp->is_add = is_add;
5287     mp->want_dhcp_event = disable_event ? 0 : 1;
5288     mp->pid = getpid();
5289    
5290     /* send it... */
5291     S;
5292
5293     /* Wait for a reply, return good/bad news  */
5294     W;
5295     /* NOTREACHED */
5296     return 0;
5297 }
5298
5299 static int api_set_ip_flow_hash (vat_main_t * vam)
5300 {
5301     unformat_input_t * i = vam->input;
5302     vl_api_set_ip_flow_hash_t *mp;
5303     f64 timeout;
5304     u32 vrf_id = 0;
5305     u8 is_ipv6 = 0;
5306     u8 vrf_id_set = 0;
5307     u8 src = 0;
5308     u8 dst = 0;
5309     u8 sport = 0;
5310     u8 dport = 0;
5311     u8 proto = 0;
5312     u8 reverse = 0;
5313
5314     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5315         if (unformat (i, "vrf %d", &vrf_id))
5316             vrf_id_set = 1;
5317         else if (unformat (i, "ipv6"))
5318             is_ipv6 = 1;
5319         else if (unformat (i, "src"))
5320             src = 1;
5321         else if (unformat (i, "dst"))
5322             dst = 1;
5323         else if (unformat (i, "sport"))
5324             sport = 1;
5325         else if (unformat (i, "dport"))
5326             dport = 1;
5327         else if (unformat (i, "proto"))
5328             proto = 1;
5329         else if (unformat (i, "reverse"))
5330             reverse = 1;
5331
5332         else {
5333             clib_warning ("parse error '%U'", format_unformat_error, i);
5334             return -99;
5335         }
5336     }
5337
5338     if (vrf_id_set == 0) {
5339         errmsg ("missing vrf id\n");
5340         return -99;
5341     }
5342     
5343     M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5344     mp->src = src;
5345     mp->dst = dst;
5346     mp->sport = sport;
5347     mp->dport = dport;
5348     mp->proto = proto;
5349     mp->reverse = reverse;
5350     mp->vrf_id = ntohl(vrf_id);
5351     mp->is_ipv6 = is_ipv6;
5352
5353     S; W;
5354     /* NOTREACHED */
5355     return 0;
5356 }
5357
5358 static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5359 {
5360     unformat_input_t * i = vam->input;
5361     vl_api_sw_interface_ip6_enable_disable_t *mp;
5362     f64 timeout;
5363     u32 sw_if_index;
5364     u8  sw_if_index_set = 0;
5365     u8  enable = 0;
5366
5367     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5368         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5369             sw_if_index_set = 1;
5370         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5371             sw_if_index_set = 1;
5372         else if (unformat (i, "enable"))
5373             enable = 1;
5374         else if (unformat (i, "disable"))
5375             enable = 0;
5376         else {
5377             clib_warning ("parse error '%U'", format_unformat_error, i);
5378             return -99;
5379         }
5380     }
5381
5382     if (sw_if_index_set == 0) {
5383         errmsg ("missing interface name or sw_if_index\n");
5384         return -99;
5385     }
5386     
5387     M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5388
5389     mp->sw_if_index = ntohl(sw_if_index);
5390     mp->enable = enable;
5391
5392     S; W;
5393     /* NOTREACHED */
5394     return 0;
5395 }
5396
5397 static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5398 {
5399     unformat_input_t * i = vam->input;
5400     vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5401     f64 timeout;
5402     u32 sw_if_index;
5403     u8 sw_if_index_set = 0;
5404     u32 address_length = 0;
5405     u8 v6_address_set = 0;
5406     ip6_address_t v6address;
5407     
5408     /* Parse args required to build the message */
5409     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5410         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5411             sw_if_index_set = 1;
5412         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5413             sw_if_index_set = 1;
5414         else if (unformat (i, "%U/%d", 
5415                            unformat_ip6_address, &v6address, 
5416                            &address_length))
5417             v6_address_set = 1;
5418         else
5419             break;
5420     }
5421
5422     if (sw_if_index_set == 0) {
5423         errmsg ("missing interface name or sw_if_index\n");
5424         return -99;
5425     }
5426     if (!v6_address_set) {
5427         errmsg ("no address set\n");
5428         return -99;
5429     }
5430
5431     /* Construct the API message */
5432     M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5433       sw_interface_ip6_set_link_local_address);
5434
5435     mp->sw_if_index = ntohl (sw_if_index);
5436     clib_memcpy (mp->address, &v6address, sizeof (v6address));
5437     mp->address_length = address_length;
5438
5439     /* send it... */
5440     S;
5441
5442     /* Wait for a reply, return good/bad news  */
5443     W;
5444
5445     /* NOTREACHED */
5446     return 0;
5447 }
5448
5449
5450 static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5451 {
5452     unformat_input_t * i = vam->input;
5453     vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5454     f64 timeout;
5455     u32 sw_if_index;
5456     u8 sw_if_index_set = 0;
5457     u32 address_length = 0;
5458     u8 v6_address_set = 0;
5459     ip6_address_t v6address;
5460     u8 use_default = 0;
5461     u8 no_advertise = 0;
5462     u8 off_link = 0;
5463     u8 no_autoconfig = 0;
5464     u8 no_onlink = 0;
5465     u8 is_no = 0;
5466     u32 val_lifetime = 0;
5467     u32 pref_lifetime = 0;
5468     
5469     /* Parse args required to build the message */
5470     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5471         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5472             sw_if_index_set = 1;
5473         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5474             sw_if_index_set = 1;
5475         else if (unformat (i, "%U/%d", 
5476                            unformat_ip6_address, &v6address, 
5477                            &address_length))
5478             v6_address_set = 1;
5479         else if (unformat (i, "val_life %d", &val_lifetime))
5480             ;
5481         else if (unformat (i, "pref_life %d", &pref_lifetime))
5482             ;
5483         else if (unformat (i, "def"))
5484             use_default = 1;
5485         else if (unformat (i, "noadv"))
5486             no_advertise = 1;
5487         else if (unformat (i, "offl"))
5488             off_link = 1;
5489         else if (unformat (i, "noauto"))
5490             no_autoconfig = 1;
5491         else if (unformat (i, "nolink"))
5492             no_onlink = 1;
5493         else if (unformat (i, "isno"))
5494             is_no = 1;
5495         else {
5496             clib_warning ("parse error '%U'", format_unformat_error, i);
5497             return -99;
5498         }        
5499     }
5500
5501     if (sw_if_index_set == 0) {
5502         errmsg ("missing interface name or sw_if_index\n");
5503         return -99;
5504     }
5505     if (!v6_address_set) {
5506         errmsg ("no address set\n");
5507         return -99;
5508     }
5509
5510     /* Construct the API message */
5511     M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5512
5513     mp->sw_if_index = ntohl (sw_if_index);
5514     clib_memcpy (mp->address, &v6address, sizeof (v6address));
5515     mp->address_length = address_length;
5516     mp->use_default = use_default;
5517     mp->no_advertise = no_advertise;
5518     mp->off_link = off_link;
5519     mp->no_autoconfig = no_autoconfig;
5520     mp->no_onlink = no_onlink;
5521     mp->is_no = is_no;
5522     mp->val_lifetime = ntohl(val_lifetime);
5523     mp->pref_lifetime = ntohl(pref_lifetime);
5524
5525     /* send it... */
5526     S;
5527
5528     /* Wait for a reply, return good/bad news  */
5529     W;
5530
5531     /* NOTREACHED */
5532     return 0;
5533 }
5534
5535 static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5536 {
5537     unformat_input_t * i = vam->input;
5538     vl_api_sw_interface_ip6nd_ra_config_t *mp;
5539     f64 timeout;
5540     u32 sw_if_index;
5541     u8 sw_if_index_set = 0;
5542     u8 surpress = 0;
5543     u8 managed = 0;
5544     u8 other = 0;
5545     u8 ll_option = 0;
5546     u8 send_unicast = 0;
5547     u8 cease = 0;
5548     u8 is_no = 0;
5549     u8 default_router = 0;
5550     u32 max_interval = 0;
5551     u32 min_interval = 0;
5552     u32 lifetime = 0;
5553     u32 initial_count = 0;
5554     u32 initial_interval = 0;
5555
5556     
5557     /* Parse args required to build the message */
5558     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5559         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5560             sw_if_index_set = 1;
5561         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5562             sw_if_index_set = 1;
5563         else if (unformat (i, "maxint %d", &max_interval))
5564             ;
5565         else if (unformat (i, "minint %d", &min_interval))
5566             ;
5567         else if (unformat (i, "life %d", &lifetime))
5568             ;
5569         else if (unformat (i, "count %d", &initial_count))
5570             ;
5571         else if (unformat (i, "interval %d", &initial_interval))
5572             ;
5573         else if (unformat (i, "surpress"))
5574             surpress = 1;
5575         else if (unformat (i, "managed"))
5576             managed = 1;
5577         else if (unformat (i, "other"))
5578             other = 1;
5579         else if (unformat (i, "ll"))
5580             ll_option = 1;
5581         else if (unformat (i, "send"))
5582             send_unicast = 1;
5583         else if (unformat (i, "cease"))
5584             cease = 1;
5585         else if (unformat (i, "isno"))
5586             is_no = 1;
5587         else if (unformat (i, "def"))
5588             default_router = 1;
5589         else {
5590             clib_warning ("parse error '%U'", format_unformat_error, i);
5591             return -99;
5592         }        
5593     }
5594
5595     if (sw_if_index_set == 0) {
5596         errmsg ("missing interface name or sw_if_index\n");
5597         return -99;
5598     }
5599
5600     /* Construct the API message */
5601     M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5602
5603     mp->sw_if_index = ntohl (sw_if_index);
5604     mp->max_interval = ntohl(max_interval);
5605     mp->min_interval = ntohl(min_interval);
5606     mp->lifetime = ntohl(lifetime);
5607     mp->initial_count = ntohl(initial_count);
5608     mp->initial_interval = ntohl(initial_interval);
5609     mp->surpress = surpress;
5610     mp->managed = managed;
5611     mp->other = other;
5612     mp->ll_option = ll_option;
5613     mp->send_unicast = send_unicast;
5614     mp->cease = cease;
5615     mp->is_no = is_no;
5616     mp->default_router = default_router;
5617
5618     /* send it... */
5619     S;
5620
5621     /* Wait for a reply, return good/bad news  */
5622     W;
5623
5624     /* NOTREACHED */
5625     return 0;
5626 }
5627
5628 static int api_set_arp_neighbor_limit (vat_main_t * vam)
5629 {
5630     unformat_input_t * i = vam->input;
5631     vl_api_set_arp_neighbor_limit_t *mp;
5632     f64 timeout;
5633     u32 arp_nbr_limit;
5634     u8 limit_set = 0;
5635     u8 is_ipv6 = 0;
5636
5637     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5638         if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5639             limit_set = 1;
5640         else if (unformat (i, "ipv6"))
5641             is_ipv6 = 1;
5642         else {
5643             clib_warning ("parse error '%U'", format_unformat_error, i);
5644             return -99;
5645         }
5646     }
5647
5648     if (limit_set == 0) {
5649         errmsg ("missing limit value\n");
5650         return -99;
5651     }
5652     
5653     M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5654
5655     mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5656     mp->is_ipv6 = is_ipv6;
5657
5658     S; W;
5659     /* NOTREACHED */
5660     return 0;
5661 }
5662
5663 static int api_l2_patch_add_del (vat_main_t * vam)
5664 {
5665     unformat_input_t * i = vam->input;
5666     vl_api_l2_patch_add_del_t *mp;
5667     f64 timeout;
5668     u32 rx_sw_if_index;
5669     u8 rx_sw_if_index_set = 0;
5670     u32 tx_sw_if_index;
5671     u8 tx_sw_if_index_set = 0;
5672     u8 is_add = 1;
5673     
5674     /* Parse args required to build the message */
5675     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5676         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5677             rx_sw_if_index_set = 1;     
5678         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5679             tx_sw_if_index_set = 1;
5680         else if (unformat (i, "rx")) {
5681             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5682                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5683                               &rx_sw_if_index))
5684                     rx_sw_if_index_set = 1;
5685             } else
5686                 break;
5687         } else if (unformat (i, "tx")) {
5688             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5689                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5690                               &tx_sw_if_index))
5691                     tx_sw_if_index_set = 1;
5692             } else
5693                 break;
5694         } else if (unformat (i, "del"))
5695             is_add = 0;
5696         else
5697             break;
5698     }
5699
5700     if (rx_sw_if_index_set == 0) {
5701         errmsg ("missing rx interface name or rx_sw_if_index\n");
5702         return -99;
5703     }
5704
5705     if (tx_sw_if_index_set == 0) {
5706         errmsg ("missing tx interface name or tx_sw_if_index\n");
5707         return -99;
5708     }
5709     
5710     M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5711
5712     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5713     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5714     mp->is_add = is_add;
5715
5716     S; W;
5717     /* NOTREACHED */
5718     return 0;
5719 }
5720 static int api_trace_profile_add (vat_main_t *vam)
5721 {
5722    unformat_input_t * input = vam->input;
5723    vl_api_trace_profile_add_t *mp;
5724    f64 timeout;
5725    u32 id = 0;
5726    u32 trace_option_elts = 0;
5727    u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5728    int has_pow_option = 0;
5729    int has_ppc_option = 0;
5730   
5731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5732     {
5733       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5734                            "trace-tsp %d node-id 0x%x app-data 0x%x", 
5735                     &id, &trace_type, &trace_option_elts, &trace_tsp,
5736                       &node_id, &app_data))
5737             ;
5738       else if (unformat (input, "pow"))
5739         has_pow_option = 1;
5740       else if (unformat (input, "ppc encap"))
5741         has_ppc_option = PPC_ENCAP;
5742       else if (unformat (input, "ppc decap"))
5743         has_ppc_option = PPC_DECAP;
5744       else if (unformat (input, "ppc none"))
5745         has_ppc_option = PPC_NONE;
5746       else
5747         break;
5748     }
5749   M(TRACE_PROFILE_ADD, trace_profile_add);
5750   mp->id = htons(id);
5751   mp->trace_type = trace_type;
5752   mp->trace_num_elt = trace_option_elts;
5753   mp->trace_ppc = has_ppc_option;
5754   mp->trace_app_data = htonl(app_data);
5755   mp->pow_enable = has_pow_option;
5756   mp->trace_tsp = trace_tsp;
5757   mp->node_id = htonl(node_id);
5758   
5759   S; W;
5760   
5761   return(0);
5762    
5763 }
5764 static int api_trace_profile_apply (vat_main_t *vam)
5765 {
5766   unformat_input_t * input = vam->input;
5767   vl_api_trace_profile_apply_t *mp;
5768   f64 timeout;
5769   ip6_address_t addr;
5770   u32 mask_width = ~0;
5771   int is_add = 0;
5772   int is_pop = 0;
5773   int is_none = 0;
5774   u32 vrf_id = 0;
5775   u32 id = 0;
5776   
5777   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5778     {
5779       if (unformat (input, "%U/%d",
5780                     unformat_ip6_address, &addr, &mask_width))
5781         ;
5782       else if (unformat (input, "id %d", &id))
5783         ;
5784       else if (unformat (input, "vrf-id %d", &vrf_id))
5785         ;
5786       else if (unformat (input, "add"))
5787         is_add = 1;
5788       else if (unformat (input, "pop"))
5789         is_pop = 1;
5790       else if (unformat (input, "none"))
5791         is_none = 1;
5792       else
5793         break;
5794     }
5795
5796   if ((is_add + is_pop + is_none) != 1) {
5797     errmsg("One of (add, pop, none) required");
5798     return -99;
5799   }
5800   if (mask_width == ~0) {
5801     errmsg("<address>/<mask-width> required");
5802     return -99;
5803   }
5804   M(TRACE_PROFILE_APPLY, trace_profile_apply);
5805   clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
5806   mp->id = htons(id);
5807   mp->prefix_length = htonl(mask_width);
5808   mp->vrf_id = htonl(vrf_id);
5809   if (is_add)
5810     mp->trace_op = IOAM_HBYH_ADD;
5811   else if (is_pop)
5812     mp->trace_op = IOAM_HBYH_POP;
5813   else
5814     mp->trace_op = IOAM_HBYH_MOD;
5815
5816   if(is_none)
5817     mp->enable = 0;
5818   else
5819     mp->enable = 1;
5820   
5821   S; W;
5822
5823   return 0;
5824 }
5825
5826 static int api_trace_profile_del (vat_main_t *vam)
5827 {
5828    vl_api_trace_profile_del_t *mp;
5829    f64 timeout;
5830    
5831    M(TRACE_PROFILE_DEL, trace_profile_del);
5832    S; W;
5833    return 0;
5834 }
5835
5836 static int api_sr_tunnel_add_del (vat_main_t * vam)
5837 {
5838   unformat_input_t * i = vam->input;
5839   vl_api_sr_tunnel_add_del_t *mp;
5840   f64 timeout;
5841   int is_del = 0;
5842   int pl_index;
5843   ip6_address_t src_address;
5844   int src_address_set = 0;
5845   ip6_address_t dst_address;
5846   u32 dst_mask_width;
5847   int dst_address_set = 0;
5848   u16 flags = 0;
5849   u32 rx_table_id = 0;
5850   u32 tx_table_id = 0;
5851   ip6_address_t * segments = 0;
5852   ip6_address_t * this_seg;
5853   ip6_address_t * tags = 0;
5854   ip6_address_t * this_tag;
5855   ip6_address_t next_address, tag;
5856   u8 * name = 0;
5857   u8 * policy_name = 0;
5858
5859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5860     {
5861       if (unformat (i, "del"))
5862         is_del = 1;
5863       else if (unformat (i, "name %s", &name))
5864             ;
5865       else if (unformat (i, "policy %s", &policy_name))
5866             ;
5867       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5868         ;
5869       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5870         ;
5871       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5872         src_address_set = 1;
5873       else if (unformat (i, "dst %U/%d", 
5874                          unformat_ip6_address, &dst_address,
5875                          &dst_mask_width))
5876         dst_address_set = 1;
5877       else if (unformat (i, "next %U", unformat_ip6_address,
5878                          &next_address))
5879         {
5880           vec_add2 (segments, this_seg, 1);
5881           clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
5882         }
5883       else if (unformat (i, "tag %U", unformat_ip6_address,
5884                          &tag))
5885         {
5886           vec_add2 (tags, this_tag, 1);
5887           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
5888         }
5889       else if (unformat (i, "clean"))
5890         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5891       else if (unformat (i, "protected"))
5892         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5893       else if (unformat (i, "InPE %d", &pl_index))
5894         {
5895           if (pl_index <= 0 || pl_index > 4)
5896             {
5897             pl_index_range_error:
5898               errmsg ("pl index %d out of range\n", pl_index);
5899               return -99;
5900             }
5901           flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5902         }
5903       else if (unformat (i, "EgPE %d", &pl_index))
5904         {
5905           if (pl_index <= 0 || pl_index > 4)
5906             goto pl_index_range_error;
5907           flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5908         }
5909       else if (unformat (i, "OrgSrc %d", &pl_index))
5910         {
5911           if (pl_index <= 0 || pl_index > 4)
5912             goto pl_index_range_error;
5913           flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5914         }
5915       else 
5916         break;
5917     }
5918
5919   if (!src_address_set)
5920     {
5921       errmsg ("src address required\n");
5922       return -99;
5923     }
5924
5925   if (!dst_address_set)
5926     {
5927       errmsg ("dst address required\n");
5928       return -99;
5929     }
5930
5931   if (!segments)
5932     {
5933       errmsg ("at least one sr segment required\n");
5934       return -99;
5935     }
5936
5937   M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del, 
5938      vec_len(segments) * sizeof (ip6_address_t) 
5939      + vec_len(tags) * sizeof (ip6_address_t));
5940
5941   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5942   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
5943   mp->dst_mask_width = dst_mask_width;
5944   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5945   mp->n_segments = vec_len (segments);
5946   mp->n_tags = vec_len (tags);
5947   mp->is_add = is_del == 0;
5948   clib_memcpy (mp->segs_and_tags, segments, 
5949           vec_len(segments)* sizeof (ip6_address_t));
5950   clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
5951           tags, vec_len(tags)* sizeof (ip6_address_t));
5952
5953   mp->outer_vrf_id = ntohl (rx_table_id);
5954   mp->inner_vrf_id = ntohl (tx_table_id);
5955   memcpy (mp->name, name, vec_len(name));
5956   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5957
5958   vec_free (segments);
5959   vec_free (tags);
5960   
5961   S; W;
5962   /* NOTREACHED */
5963 }
5964
5965 static int api_sr_policy_add_del (vat_main_t * vam)
5966 {
5967   unformat_input_t * input = vam->input;
5968   vl_api_sr_policy_add_del_t *mp;
5969   f64 timeout;
5970   int is_del = 0;
5971   u8 * name = 0;
5972   u8 * tunnel_name = 0;
5973   u8 ** tunnel_names = 0;
5974   
5975   int name_set = 0 ;
5976   int tunnel_set = 0;
5977   int j = 0;
5978   int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
5979   int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
5980
5981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5982     {
5983       if (unformat (input, "del"))
5984         is_del = 1;
5985       else if (unformat (input, "name %s", &name))
5986         name_set = 1;
5987       else if (unformat (input, "tunnel %s", &tunnel_name))
5988         {
5989           if (tunnel_name)
5990             {
5991               vec_add1 (tunnel_names, tunnel_name);
5992               /* For serializer: 
5993                  - length = #bytes to store in serial vector
5994                  - +1 = byte to store that length
5995               */
5996               tunnel_names_length += (vec_len (tunnel_name) + 1); 
5997               tunnel_set = 1;
5998               tunnel_name = 0;
5999             }
6000         }
6001       else 
6002         break;
6003     }
6004
6005   if (!name_set)
6006     {
6007       errmsg ("policy name required\n");
6008       return -99;
6009     }
6010
6011   if ((!tunnel_set) && (!is_del))
6012     {
6013       errmsg ("tunnel name required\n");
6014       return -99;
6015     }
6016
6017   M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
6018
6019   
6020
6021   mp->is_add = !is_del;
6022
6023   memcpy (mp->name, name, vec_len(name));
6024   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
6025   u8 * serial_orig = 0;
6026   vec_validate (serial_orig, tunnel_names_length);
6027   *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
6028   serial_orig += 1; // Move along one byte to store the length of first tunnel_name
6029
6030   for (j=0; j < vec_len(tunnel_names); j++)
6031     {
6032       tun_name_len = vec_len (tunnel_names[j]);
6033       *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
6034       serial_orig += 1; // Move along one byte to store the actual tunnel name
6035       memcpy (serial_orig, tunnel_names[j], tun_name_len);
6036       serial_orig += tun_name_len; // Advance past the copy
6037     }
6038   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
6039
6040   vec_free (tunnel_names);
6041   vec_free (tunnel_name);
6042   
6043   S; W;
6044   /* NOTREACHED */
6045 }
6046
6047 static int api_sr_multicast_map_add_del (vat_main_t * vam)
6048 {
6049   unformat_input_t * input = vam->input;
6050   vl_api_sr_multicast_map_add_del_t *mp;
6051   f64 timeout;
6052   int is_del = 0;
6053   ip6_address_t multicast_address;
6054   u8 * policy_name = 0;
6055   int multicast_address_set = 0;
6056
6057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6058     {
6059       if (unformat (input, "del"))
6060         is_del = 1;
6061       else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
6062         multicast_address_set = 1;
6063       else if (unformat (input, "sr-policy %s", &policy_name))
6064         ;
6065       else 
6066         break;
6067     }
6068
6069   if (!is_del && !policy_name)
6070     {
6071       errmsg ("sr-policy name required\n");
6072       return -99;
6073     }
6074
6075
6076   if (!multicast_address_set)
6077     {
6078       errmsg ("address required\n");
6079       return -99;
6080     }
6081
6082   M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
6083
6084   mp->is_add = !is_del;
6085   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
6086   clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
6087
6088
6089   vec_free (policy_name);
6090   
6091   S; W;
6092   /* NOTREACHED */
6093 }
6094
6095
6096 #define foreach_ip4_proto_field                 \
6097 _(src_address)                                  \
6098 _(dst_address)                                  \
6099 _(tos)                                          \
6100 _(length)                                       \
6101 _(fragment_id)                                  \
6102 _(ttl)                                          \
6103 _(protocol)                                     \
6104 _(checksum)
6105
6106 uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
6107 {
6108   u8 ** maskp = va_arg (*args, u8 **);
6109   u8 * mask = 0;
6110   u8 found_something = 0;
6111   ip4_header_t * ip;
6112   
6113 #define _(a) u8 a=0;
6114   foreach_ip4_proto_field;
6115 #undef _
6116   u8 version = 0;
6117   u8 hdr_length = 0;
6118   
6119   
6120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6121     {
6122       if (unformat (input, "version")) 
6123         version = 1;
6124       else if (unformat (input, "hdr_length"))
6125         hdr_length = 1;
6126       else if (unformat (input, "src"))
6127         src_address = 1;
6128       else if (unformat (input, "dst"))
6129         dst_address = 1;
6130       else if (unformat (input, "proto"))
6131         protocol = 1;
6132       
6133 #define _(a) else if (unformat (input, #a)) a=1;
6134       foreach_ip4_proto_field
6135 #undef _
6136       else
6137         break;
6138     }
6139   
6140 #define _(a) found_something += a;
6141   foreach_ip4_proto_field;
6142 #undef _
6143   
6144   if (found_something == 0)
6145     return 0;
6146   
6147   vec_validate (mask, sizeof (*ip) - 1);
6148   
6149   ip = (ip4_header_t *) mask;
6150   
6151 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6152   foreach_ip4_proto_field;
6153 #undef _
6154   
6155   ip->ip_version_and_header_length = 0;
6156   
6157   if (version)
6158     ip->ip_version_and_header_length |= 0xF0;
6159   
6160   if (hdr_length)
6161     ip->ip_version_and_header_length |= 0x0F;
6162   
6163   *maskp = mask;
6164   return 1;
6165 }
6166
6167 #define foreach_ip6_proto_field                 \
6168 _(src_address)                                  \
6169 _(dst_address)                                  \
6170 _(payload_length)                               \
6171 _(hop_limit)                                    \
6172 _(protocol)
6173
6174 uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6175 {
6176   u8 ** maskp = va_arg (*args, u8 **);
6177   u8 * mask = 0;
6178   u8 found_something = 0;
6179   ip6_header_t * ip;
6180   u32 ip_version_traffic_class_and_flow_label;
6181   
6182 #define _(a) u8 a=0;
6183   foreach_ip6_proto_field;
6184 #undef _
6185   u8 version = 0;
6186   u8 traffic_class = 0;
6187   u8 flow_label = 0;
6188   
6189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6190     {
6191       if (unformat (input, "version")) 
6192         version = 1;
6193       else if (unformat (input, "traffic-class"))
6194         traffic_class = 1;
6195       else if (unformat (input, "flow-label"))
6196         flow_label = 1;
6197       else if (unformat (input, "src"))
6198         src_address = 1;
6199       else if (unformat (input, "dst"))
6200         dst_address = 1;
6201       else if (unformat (input, "proto"))
6202         protocol = 1;
6203       
6204 #define _(a) else if (unformat (input, #a)) a=1;
6205       foreach_ip6_proto_field
6206 #undef _
6207       else
6208         break;
6209     }
6210   
6211 #define _(a) found_something += a;
6212   foreach_ip6_proto_field;
6213 #undef _
6214   
6215   if (found_something == 0)
6216     return 0;
6217   
6218   vec_validate (mask, sizeof (*ip) - 1);
6219   
6220   ip = (ip6_header_t *) mask;
6221   
6222 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6223   foreach_ip6_proto_field;
6224 #undef _
6225   
6226   ip_version_traffic_class_and_flow_label = 0;
6227   
6228   if (version)
6229     ip_version_traffic_class_and_flow_label |= 0xF0000000;
6230
6231   if (traffic_class)
6232     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6233
6234   if (flow_label)
6235     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6236
6237   ip->ip_version_traffic_class_and_flow_label = 
6238     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6239   
6240   *maskp = mask;
6241   return 1;
6242 }
6243
6244 uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6245 {
6246   u8 ** maskp = va_arg (*args, u8 **);
6247
6248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6249     if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6250       return 1;
6251     else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6252       return 1;
6253     else
6254       break;
6255   }
6256   return 0;
6257 }
6258
6259 uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6260 {
6261   u8 ** maskp = va_arg (*args, u8 **);
6262   u8 * mask = 0;
6263   u8 src = 0;
6264   u8 dst = 0;
6265   u8 proto = 0;
6266   u8 tag1 = 0;
6267   u8 tag2 = 0;
6268   u8 ignore_tag1 = 0;
6269   u8 ignore_tag2 = 0;
6270   u8 cos1 = 0;
6271   u8 cos2 = 0;
6272   u8 dot1q = 0;
6273   u8 dot1ad = 0;
6274   int len = 14;
6275
6276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6277     if (unformat (input, "src"))
6278       src = 1;
6279     else if (unformat (input, "dst"))
6280       dst = 1;
6281     else if (unformat (input, "proto"))
6282       proto = 1;
6283     else if (unformat (input, "tag1"))
6284       tag1 = 1;
6285     else if (unformat (input, "tag2"))
6286       tag2 = 1;
6287     else if (unformat (input, "ignore-tag1"))
6288       ignore_tag1 = 1;
6289     else if (unformat (input, "ignore-tag2"))
6290       ignore_tag2 = 1;
6291     else if (unformat (input, "cos1"))
6292       cos1 = 1;
6293     else if (unformat (input, "cos2"))
6294       cos2 = 1;
6295     else if (unformat (input, "dot1q"))
6296       dot1q = 1;
6297     else if (unformat (input, "dot1ad"))
6298       dot1ad = 1;
6299     else
6300       break;
6301   }
6302   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6303       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6304     return 0;
6305
6306   if (tag1 || ignore_tag1 || cos1 || dot1q)
6307     len = 18;
6308   if (tag2 || ignore_tag2 || cos2 || dot1ad)
6309     len = 22;
6310
6311   vec_validate (mask, len-1);
6312
6313   if (dst)
6314     memset (mask, 0xff, 6);
6315
6316   if (src)
6317     memset (mask + 6, 0xff, 6);
6318   
6319   if (tag2 || dot1ad)
6320     {
6321       /* inner vlan tag */
6322       if (tag2)
6323         {
6324           mask[19] = 0xff;
6325           mask[18] = 0x0f;
6326         }
6327       if (cos2)
6328         mask[18] |= 0xe0;
6329       if (proto)
6330           mask[21] = mask [20] = 0xff;
6331       if (tag1)
6332         {
6333           mask [15] = 0xff;
6334           mask [14] = 0x0f;
6335         }
6336       if (cos1)
6337         mask[14] |= 0xe0;
6338       *maskp = mask;
6339       return 1;
6340     }
6341   if (tag1 | dot1q)
6342     {
6343       if (tag1)
6344         {
6345           mask [15] = 0xff;
6346           mask [14] = 0x0f;
6347         }
6348       if (cos1)
6349         mask[14] |= 0xe0;
6350       if (proto)
6351           mask[16] = mask [17] = 0xff;
6352
6353       *maskp = mask;
6354       return 1;
6355     }
6356   if (cos2)
6357     mask[18] |= 0xe0;
6358   if (cos1)
6359     mask[14] |= 0xe0;
6360   if (proto)
6361     mask[12] = mask [13] = 0xff;
6362     
6363   *maskp = mask;
6364   return 1;
6365 }
6366
6367 uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6368 {
6369   u8 ** maskp = va_arg (*args, u8 **);
6370   u32 * skipp = va_arg (*args, u32 *);
6371   u32 * matchp = va_arg (*args, u32 *);
6372   u32 match;
6373   u8 * mask = 0;
6374   u8 * l2 = 0;
6375   u8 * l3 = 0;
6376   int i;
6377   
6378   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6379     if (unformat (input, "hex %U", unformat_hex_string, &mask))
6380       ;
6381     else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6382       ;
6383     else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6384       ;
6385     else
6386       break;
6387   }
6388
6389   if (mask || l2 || l3)
6390     {
6391       if (l2 || l3)
6392         {
6393           /* "With a free Ethernet header in every package" */
6394           if (l2 == 0)
6395             vec_validate (l2, 13);
6396           mask = l2;
6397           vec_append (mask, l3);
6398           vec_free (l3);
6399         }
6400
6401       /* Scan forward looking for the first significant mask octet */
6402       for (i = 0; i < vec_len (mask); i++)
6403         if (mask[i])
6404           break;
6405
6406       /* compute (skip, match) params */
6407       *skipp = i / sizeof(u32x4);
6408       vec_delete (mask, *skipp * sizeof(u32x4), 0);
6409
6410       /* Pad mask to an even multiple of the vector size */
6411       while (vec_len (mask) % sizeof (u32x4))
6412         vec_add1 (mask, 0);
6413
6414       match = vec_len (mask) / sizeof (u32x4);
6415
6416       for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6417         {
6418           u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6419           if (*tmp || *(tmp+1))
6420             break;
6421           match--;
6422         }
6423       if (match == 0)
6424         clib_warning ("BUG: match 0");
6425
6426       _vec_len (mask) = match * sizeof(u32x4);
6427
6428       *matchp = match;
6429       *maskp = mask;
6430
6431       return 1;
6432     }
6433
6434   return 0;
6435 }
6436
6437 #define foreach_l2_next                         \
6438 _(drop, DROP)                                   \
6439 _(ethernet, ETHERNET_INPUT)                     \
6440 _(ip4, IP4_INPUT)                               \
6441 _(ip6, IP6_INPUT)
6442
6443 uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6444 {
6445   u32 * miss_next_indexp = va_arg (*args, u32 *);
6446   u32 next_index = 0;
6447   u32 tmp;
6448   
6449 #define _(n,N) \
6450   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6451   foreach_l2_next;
6452 #undef _
6453   
6454   if (unformat (input, "%d", &tmp))
6455     { 
6456       next_index = tmp; 
6457       goto out; 
6458     }
6459   
6460   return 0;
6461
6462  out:
6463   *miss_next_indexp = next_index;
6464   return 1;
6465 }
6466
6467 #define foreach_ip_next                         \
6468 _(miss, MISS)                                   \
6469 _(drop, DROP)                                   \
6470 _(local, LOCAL)                                 \
6471 _(rewrite, REWRITE)
6472
6473 uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6474 {
6475   u32 * miss_next_indexp = va_arg (*args, u32 *);
6476   u32 next_index = 0;
6477   u32 tmp;
6478   
6479 #define _(n,N) \
6480   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6481   foreach_ip_next;
6482 #undef _
6483   
6484   if (unformat (input, "%d", &tmp))
6485     { 
6486       next_index = tmp; 
6487       goto out; 
6488     }
6489   
6490   return 0;
6491
6492  out:
6493   *miss_next_indexp = next_index;
6494   return 1;
6495 }
6496
6497 #define foreach_acl_next                        \
6498 _(deny, DENY)
6499
6500 uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6501 {
6502   u32 * miss_next_indexp = va_arg (*args, u32 *);
6503   u32 next_index = 0;
6504   u32 tmp;
6505
6506 #define _(n,N) \
6507   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6508   foreach_acl_next;
6509 #undef _
6510
6511   if (unformat (input, "permit"))
6512     {
6513       next_index = ~0;
6514       goto out;
6515     }
6516   else if (unformat (input, "%d", &tmp))
6517     {
6518       next_index = tmp;
6519       goto out;
6520     }
6521
6522   return 0;
6523
6524  out:
6525   *miss_next_indexp = next_index;
6526   return 1;
6527 }
6528
6529 static int api_classify_add_del_table (vat_main_t * vam)
6530 {
6531   unformat_input_t * i = vam->input;
6532   vl_api_classify_add_del_table_t *mp;
6533
6534   u32 nbuckets = 2;
6535   u32 skip = ~0;
6536   u32 match = ~0;
6537   int is_add = 1;
6538   u32 table_index = ~0;
6539   u32 next_table_index = ~0;
6540   u32 miss_next_index = ~0;
6541   u32 memory_size = 32<<20;
6542   u8 * mask = 0;
6543   f64 timeout;
6544
6545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6546     if (unformat (i, "del"))
6547       is_add = 0;
6548     else if (unformat (i, "buckets %d", &nbuckets))
6549       ;
6550     else if (unformat (i, "memory_size %d", &memory_size))
6551       ;
6552     else if (unformat (i, "skip %d", &skip))
6553       ;
6554     else if (unformat (i, "match %d", &match))
6555       ;
6556     else if (unformat (i, "table %d", &table_index))
6557       ;
6558     else if (unformat (i, "mask %U", unformat_classify_mask, 
6559                        &mask, &skip, &match))
6560       ;
6561     else if (unformat (i, "next-table %d", &next_table_index))
6562       ;
6563     else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6564                        &miss_next_index))
6565       ;
6566     else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6567                        &miss_next_index))
6568       ;
6569     else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6570                        &miss_next_index))
6571       ;
6572     else
6573       break;
6574   }
6575   
6576   if (is_add && mask == 0) {
6577       errmsg ("Mask required\n");
6578       return -99;
6579   }
6580
6581   if (is_add && skip == ~0) {
6582       errmsg ("skip count required\n");
6583       return -99;
6584   }
6585
6586   if (is_add && match == ~0) {
6587       errmsg ("match count required\n");
6588       return -99;
6589   }
6590       
6591   if (!is_add && table_index == ~0) {
6592       errmsg ("table index required for delete\n");
6593       return -99;
6594   }
6595
6596   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6597       vec_len(mask));
6598
6599   mp->is_add = is_add;
6600   mp->table_index = ntohl(table_index);
6601   mp->nbuckets = ntohl(nbuckets);
6602   mp->memory_size = ntohl(memory_size);
6603   mp->skip_n_vectors = ntohl(skip);
6604   mp->match_n_vectors = ntohl(match);
6605   mp->next_table_index = ntohl(next_table_index);
6606   mp->miss_next_index = ntohl(miss_next_index);
6607   clib_memcpy (mp->mask, mask, vec_len(mask));
6608
6609   vec_free(mask);
6610
6611   S; W;
6612   /* NOTREACHED */
6613 }
6614
6615 uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6616 {
6617   u8 ** matchp = va_arg (*args, u8 **);
6618   u8 * match = 0;
6619   ip4_header_t * ip;
6620   int version = 0;
6621   u32 version_val;
6622   int hdr_length = 0;
6623   u32 hdr_length_val;
6624   int src = 0, dst = 0;
6625   ip4_address_t src_val, dst_val;
6626   int proto = 0;
6627   u32 proto_val;
6628   int tos = 0;
6629   u32 tos_val;
6630   int length = 0;
6631   u32 length_val;
6632   int fragment_id = 0;
6633   u32 fragment_id_val;
6634   int ttl = 0;
6635   int ttl_val;
6636   int checksum = 0;
6637   u32 checksum_val;
6638
6639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6640     {
6641       if (unformat (input, "version %d", &version_val)) 
6642         version = 1;
6643       else if (unformat (input, "hdr_length %d", &hdr_length_val))
6644         hdr_length = 1;
6645       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6646         src = 1;
6647       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6648         dst = 1;
6649       else if (unformat (input, "proto %d", &proto_val))
6650         proto = 1;
6651       else if (unformat (input, "tos %d", &tos_val))
6652         tos = 1;
6653       else if (unformat (input, "length %d", &length_val))
6654         length = 1;
6655       else if (unformat (input, "fragment_id %d", &fragment_id_val))
6656         fragment_id = 1;
6657       else if (unformat (input, "ttl %d", &ttl_val))
6658         ttl = 1;
6659       else if (unformat (input, "checksum %d", &checksum_val))
6660         checksum = 1;
6661       else
6662         break;
6663     }
6664   
6665   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6666       + ttl + checksum == 0)
6667     return 0;
6668
6669   /* 
6670    * Aligned because we use the real comparison functions
6671    */
6672   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6673   
6674   ip = (ip4_header_t *) match;
6675   
6676   /* These are realistically matched in practice */
6677   if (src)
6678     ip->src_address.as_u32 = src_val.as_u32;
6679
6680   if (dst)
6681     ip->dst_address.as_u32 = dst_val.as_u32;
6682   
6683   if (proto)
6684     ip->protocol = proto_val;
6685     
6686
6687   /* These are not, but they're included for completeness */
6688   if (version)
6689     ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6690
6691   if (hdr_length)
6692     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6693     
6694   if (tos)
6695     ip->tos = tos_val;
6696   
6697   if (length)
6698     ip->length = length_val;
6699   
6700   if (ttl)
6701     ip->ttl = ttl_val;
6702
6703   if (checksum)
6704     ip->checksum = checksum_val;
6705
6706   *matchp = match;
6707   return 1;
6708 }
6709
6710 uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6711 {
6712   u8 ** matchp = va_arg (*args, u8 **);
6713   u8 * match = 0;
6714   ip6_header_t * ip;
6715   int version = 0;
6716   u32 version_val;
6717   u8  traffic_class;
6718   u32 traffic_class_val;
6719   u8  flow_label;
6720   u8  flow_label_val;
6721   int src = 0, dst = 0;
6722   ip6_address_t src_val, dst_val;
6723   int proto = 0;
6724   u32 proto_val;
6725   int payload_length = 0;
6726   u32 payload_length_val;
6727   int hop_limit = 0;
6728   int hop_limit_val;
6729   u32 ip_version_traffic_class_and_flow_label;
6730
6731   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6732     {
6733       if (unformat (input, "version %d", &version_val)) 
6734         version = 1;
6735       else if (unformat (input, "traffic_class %d", &traffic_class_val))
6736         traffic_class = 1;
6737       else if (unformat (input, "flow_label %d", &flow_label_val))
6738         flow_label = 1;
6739       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6740         src = 1;
6741       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6742         dst = 1;
6743       else if (unformat (input, "proto %d", &proto_val))
6744         proto = 1;
6745       else if (unformat (input, "payload_length %d", &payload_length_val))
6746         payload_length = 1;
6747       else if (unformat (input, "hop_limit %d", &hop_limit_val))
6748         hop_limit = 1;
6749       else
6750         break;
6751     }
6752   
6753   if (version + traffic_class + flow_label + src + dst + proto +
6754       payload_length + hop_limit == 0)
6755     return 0;
6756
6757   /* 
6758    * Aligned because we use the real comparison functions
6759    */
6760   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6761   
6762   ip = (ip6_header_t *) match;
6763   
6764   if (src)
6765     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
6766
6767   if (dst)
6768     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
6769   
6770   if (proto)
6771     ip->protocol = proto_val;
6772     
6773   ip_version_traffic_class_and_flow_label = 0;
6774
6775   if (version)
6776     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6777
6778   if (traffic_class)
6779     ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6780
6781   if (flow_label)
6782     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6783     
6784   ip->ip_version_traffic_class_and_flow_label = 
6785     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6786
6787   if (payload_length)
6788     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6789   
6790   if (hop_limit)
6791     ip->hop_limit = hop_limit_val;
6792
6793   *matchp = match;
6794   return 1;
6795 }
6796
6797 uword unformat_l3_match (unformat_input_t * input, va_list * args)
6798 {
6799   u8 ** matchp = va_arg (*args, u8 **);
6800
6801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6802     if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6803       return 1;
6804     else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6805       return 1;
6806     else
6807       break;
6808   }
6809   return 0;
6810 }
6811
6812 uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6813 {
6814   u8 * tagp = va_arg (*args, u8 *);
6815   u32 tag;
6816
6817   if (unformat(input, "%d", &tag))
6818     {
6819       tagp[0] = (tag>>8) & 0x0F;
6820       tagp[1] = tag & 0xFF;
6821       return 1;
6822     }
6823
6824   return 0;
6825 }
6826
6827 uword unformat_l2_match (unformat_input_t * input, va_list * args)
6828 {
6829   u8 ** matchp = va_arg (*args, u8 **);
6830   u8 * match = 0;
6831   u8 src = 0;
6832   u8 src_val[6];
6833   u8 dst = 0;
6834   u8 dst_val[6];
6835   u8 proto = 0;
6836   u16 proto_val;
6837   u8 tag1 = 0;
6838   u8 tag1_val [2];
6839   u8 tag2 = 0;
6840   u8 tag2_val [2];
6841   int len = 14;
6842   u8 ignore_tag1 = 0;
6843   u8 ignore_tag2 = 0;
6844   u8 cos1 = 0;
6845   u8 cos2 = 0;
6846   u32 cos1_val = 0;
6847   u32 cos2_val = 0;
6848
6849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6850     if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6851       src = 1;
6852     else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6853       dst = 1;
6854     else if (unformat (input, "proto %U", 
6855                        unformat_ethernet_type_host_byte_order, &proto_val))
6856       proto = 1;
6857     else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6858       tag1 = 1;
6859     else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6860       tag2 = 1;
6861     else if (unformat (input, "ignore-tag1"))
6862       ignore_tag1 = 1;
6863     else if (unformat (input, "ignore-tag2"))
6864       ignore_tag2 = 1;
6865     else if (unformat (input, "cos1 %d", &cos1_val))
6866       cos1 = 1;
6867     else if (unformat (input, "cos2 %d", &cos2_val))
6868       cos2 = 1;
6869     else
6870       break;
6871   }
6872   if ((src + dst + proto + tag1 + tag2 +
6873       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6874     return 0;
6875
6876   if (tag1 || ignore_tag1 || cos1)
6877     len = 18;
6878   if (tag2 || ignore_tag2 || cos2)
6879     len = 22;
6880
6881   vec_validate_aligned (match, len-1, sizeof(u32x4));
6882
6883   if (dst)
6884     clib_memcpy (match, dst_val, 6);
6885
6886   if (src)
6887     clib_memcpy (match + 6, src_val, 6);
6888   
6889   if (tag2)
6890     {
6891       /* inner vlan tag */
6892       match[19] = tag2_val[1];
6893       match[18] = tag2_val[0];
6894       if (cos2)
6895         match [18] |= (cos2_val & 0x7) << 5;
6896       if (proto)
6897         {
6898           match[21] = proto_val & 0xff;
6899           match[20] = proto_val >> 8;
6900         }
6901       if (tag1)
6902         {
6903           match [15] = tag1_val[1];
6904           match [14] = tag1_val[0];
6905         }
6906       if (cos1)
6907         match [14] |= (cos1_val & 0x7) << 5;
6908       *matchp = match;
6909       return 1;
6910     }
6911   if (tag1)
6912     {
6913       match [15] = tag1_val[1];
6914       match [14] = tag1_val[0];
6915       if (proto)
6916         {
6917           match[17] = proto_val & 0xff;
6918           match[16] = proto_val >> 8;
6919         }
6920       if (cos1)
6921         match [14] |= (cos1_val & 0x7) << 5;
6922
6923       *matchp = match;
6924       return 1;
6925     }
6926   if (cos2)
6927     match [18] |= (cos2_val & 0x7) << 5;
6928   if (cos1)
6929     match [14] |= (cos1_val & 0x7) << 5;
6930   if (proto)
6931     {
6932       match[13] = proto_val & 0xff;
6933       match[12] = proto_val >> 8;
6934     }
6935   
6936   *matchp = match;
6937   return 1;
6938 }
6939
6940
6941 uword unformat_classify_match (unformat_input_t * input, va_list * args)
6942 {
6943   u8 ** matchp = va_arg (*args, u8 **);
6944   u32 skip_n_vectors = va_arg (*args, u32);
6945   u32 match_n_vectors = va_arg (*args, u32);
6946   
6947   u8 * match = 0;
6948   u8 * l2 = 0;
6949   u8 * l3 = 0;
6950
6951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6952     if (unformat (input, "hex %U", unformat_hex_string, &match))
6953       ;
6954     else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6955       ;
6956     else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6957       ;
6958     else
6959       break;
6960   }
6961
6962   if (match || l2 || l3)
6963     {
6964       if (l2 || l3)
6965         {
6966           /* "Win a free Ethernet header in every packet" */
6967           if (l2 == 0)
6968             vec_validate_aligned (l2, 13, sizeof(u32x4));
6969           match = l2;
6970           vec_append_aligned (match, l3, sizeof(u32x4));
6971           vec_free (l3);
6972         }
6973
6974       /* Make sure the vector is big enough even if key is all 0's */
6975       vec_validate_aligned 
6976           (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6977            sizeof(u32x4));
6978       
6979       /* Set size, include skipped vectors*/
6980       _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6981
6982       *matchp = match;
6983
6984       return 1;
6985     }
6986
6987   return 0;
6988 }
6989
6990 static int api_classify_add_del_session (vat_main_t * vam)
6991 {
6992     unformat_input_t * i = vam->input;
6993     vl_api_classify_add_del_session_t *mp;
6994     int is_add = 1;
6995     u32 table_index = ~0;
6996     u32 hit_next_index = ~0;
6997     u32 opaque_index = ~0;
6998     u8 * match = 0;
6999     i32 advance = 0;
7000     f64 timeout;
7001     u32 skip_n_vectors = 0;
7002     u32 match_n_vectors = 0;
7003
7004     /* 
7005      * Warning: you have to supply skip_n and match_n
7006      * because the API client cant simply look at the classify
7007      * table object.
7008      */
7009
7010     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7011         if (unformat (i, "del"))
7012             is_add = 0;
7013         else if (unformat (i, "hit-next %U", unformat_ip_next_index,
7014                            &hit_next_index))
7015             ;
7016         else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
7017                            &hit_next_index))
7018             ;
7019         else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
7020                            &hit_next_index))
7021             ;
7022         else if (unformat (i, "opaque-index %d", &opaque_index))
7023             ;
7024         else if (unformat (i, "skip_n %d", &skip_n_vectors))
7025             ;
7026         else if (unformat (i, "match_n %d", &match_n_vectors))
7027             ;
7028         else if (unformat (i, "match %U", unformat_classify_match,
7029                            &match, skip_n_vectors, match_n_vectors))
7030             ;
7031         else if (unformat (i, "advance %d", &advance))
7032             ;
7033         else if (unformat (i, "table-index %d", &table_index))
7034             ;
7035         else
7036             break;
7037     }
7038
7039     if (table_index == ~0) {
7040         errmsg ("Table index required\n");
7041         return -99;
7042     }
7043
7044     if (is_add && match == 0) {
7045         errmsg ("Match value required\n");
7046         return -99;
7047     }
7048
7049     M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
7050         vec_len(match));
7051
7052     mp->is_add = is_add;
7053     mp->table_index = ntohl(table_index);
7054     mp->hit_next_index = ntohl(hit_next_index);
7055     mp->opaque_index = ntohl(opaque_index);
7056     mp->advance = ntohl(advance);
7057     clib_memcpy (mp->match, match, vec_len(match));
7058     vec_free(match);
7059
7060     S; W;
7061     /* NOTREACHED */
7062 }
7063
7064 static int api_classify_set_interface_ip_table (vat_main_t * vam)
7065 {
7066     unformat_input_t * i = vam->input;
7067     vl_api_classify_set_interface_ip_table_t *mp;
7068     f64 timeout;
7069     u32 sw_if_index;
7070     int sw_if_index_set;
7071     u32 table_index = ~0;
7072     u8  is_ipv6 = 0;
7073
7074     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7075         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7076             sw_if_index_set = 1;
7077         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7078             sw_if_index_set = 1;
7079         else if (unformat (i, "table %d", &table_index))
7080             ;
7081         else {
7082             clib_warning ("parse error '%U'", format_unformat_error, i);
7083             return -99;
7084         }
7085     }
7086     
7087     if (sw_if_index_set == 0) {
7088         errmsg ("missing interface name or sw_if_index\n");
7089         return -99;
7090     }
7091
7092
7093     M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
7094
7095     mp->sw_if_index = ntohl(sw_if_index);
7096     mp->table_index = ntohl(table_index);
7097     mp->is_ipv6 = is_ipv6;
7098
7099     S; W;
7100     /* NOTREACHED */
7101     return 0;
7102 }
7103
7104 static int api_classify_set_interface_l2_tables (vat_main_t * vam)
7105 {
7106     unformat_input_t * i = vam->input;
7107     vl_api_classify_set_interface_l2_tables_t *mp;
7108     f64 timeout;
7109     u32 sw_if_index;
7110     int sw_if_index_set;
7111     u32 ip4_table_index = ~0;
7112     u32 ip6_table_index = ~0;
7113     u32 other_table_index = ~0;
7114
7115     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7116         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7117             sw_if_index_set = 1;
7118         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7119             sw_if_index_set = 1;
7120         else if (unformat (i, "ip4-table %d", &ip4_table_index))
7121             ;
7122         else if (unformat (i, "ip6-table %d", &ip6_table_index))
7123             ;
7124         else if (unformat (i, "other-table %d", &other_table_index))
7125             ;
7126         else {
7127             clib_warning ("parse error '%U'", format_unformat_error, i);
7128             return -99;
7129         }
7130     }
7131     
7132     if (sw_if_index_set == 0) {
7133         errmsg ("missing interface name or sw_if_index\n");
7134         return -99;
7135     }
7136
7137
7138     M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7139
7140     mp->sw_if_index = ntohl(sw_if_index);
7141     mp->ip4_table_index = ntohl(ip4_table_index);
7142     mp->ip6_table_index = ntohl(ip6_table_index);
7143     mp->other_table_index = ntohl(other_table_index);
7144
7145
7146     S; W;
7147     /* NOTREACHED */
7148     return 0;
7149 }
7150
7151 static int api_get_node_index (vat_main_t * vam)
7152 {
7153     unformat_input_t * i = vam->input;
7154     vl_api_get_node_index_t * mp;
7155     f64 timeout;
7156     u8 * name = 0;
7157     
7158     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7159         if (unformat (i, "node %s", &name))
7160             ;
7161         else
7162             break;
7163     }
7164     if (name == 0) {
7165         errmsg ("node name required\n");
7166         return -99;
7167     }
7168     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7169         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7170         return -99;
7171     }
7172
7173     M(GET_NODE_INDEX, get_node_index);
7174     clib_memcpy (mp->node_name, name, vec_len(name));
7175     vec_free(name);
7176     
7177     S; W;
7178     /* NOTREACHED */
7179     return 0;
7180 }
7181
7182 static int api_add_node_next (vat_main_t * vam)
7183 {
7184     unformat_input_t * i = vam->input;
7185     vl_api_add_node_next_t * mp;
7186     f64 timeout;
7187     u8 * name = 0;
7188     u8 * next = 0;
7189
7190     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7191         if (unformat (i, "node %s", &name))
7192             ;
7193         else if (unformat (i, "next %s", &next))
7194             ;
7195         else
7196             break;
7197     }
7198     if (name == 0) {
7199         errmsg ("node name required\n");
7200         return -99;
7201     }
7202     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7203         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7204         return -99;
7205     }
7206     if (next == 0) {
7207         errmsg ("next node required\n");
7208         return -99;
7209     }
7210     if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
7211         errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
7212         return -99;
7213     }
7214     
7215     M(ADD_NODE_NEXT, add_node_next);
7216     clib_memcpy (mp->node_name, name, vec_len(name));
7217     clib_memcpy (mp->next_name, next, vec_len(next));
7218     vec_free(name);
7219     vec_free(next);
7220     
7221     S; W;
7222     /* NOTREACHED */
7223     return 0;
7224 }
7225
7226 static int api_l2tpv3_create_tunnel (vat_main_t * vam)
7227 {
7228     unformat_input_t * i = vam->input;
7229     ip6_address_t client_address, our_address;
7230     int client_address_set = 0;
7231     int our_address_set = 0;
7232     u32 local_session_id = 0;
7233     u32 remote_session_id = 0;
7234     u64 local_cookie = 0;
7235     u64 remote_cookie = 0;
7236     u8 l2_sublayer_present = 0;
7237     vl_api_l2tpv3_create_tunnel_t * mp;
7238     f64 timeout;
7239
7240     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7241         if (unformat (i, "client_address %U", unformat_ip6_address, 
7242                       &client_address))
7243             client_address_set = 1;
7244         else if (unformat (i, "our_address %U", unformat_ip6_address, 
7245                            &our_address))
7246             our_address_set = 1;
7247         else if (unformat (i, "local_session_id %d", &local_session_id))
7248             ;
7249         else if (unformat (i, "remote_session_id %d", &remote_session_id))
7250             ;
7251         else if (unformat (i, "local_cookie %lld", &local_cookie))
7252             ;
7253         else if (unformat (i, "remote_cookie %lld", &remote_cookie))
7254             ;
7255         else if (unformat (i, "l2-sublayer-present"))
7256             l2_sublayer_present = 1;
7257         else
7258             break;
7259     }
7260
7261     if (client_address_set == 0) {
7262         errmsg ("client_address required\n");
7263         return -99;
7264     }
7265
7266     if (our_address_set == 0) {
7267         errmsg ("our_address required\n");
7268         return -99;
7269     }
7270
7271     M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
7272
7273     clib_memcpy (mp->client_address, client_address.as_u8, 
7274             sizeof (mp->client_address));
7275
7276     clib_memcpy (mp->our_address, our_address.as_u8, 
7277             sizeof (mp->our_address));
7278     
7279     mp->local_session_id = ntohl (local_session_id);
7280     mp->remote_session_id = ntohl (remote_session_id);
7281     mp->local_cookie = clib_host_to_net_u64 (local_cookie);
7282     mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
7283     mp->l2_sublayer_present = l2_sublayer_present;
7284     mp->is_ipv6 = 1;
7285
7286     S; W;
7287     /* NOTREACHED */
7288     return 0;
7289 }
7290
7291 static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7292 {
7293     unformat_input_t * i = vam->input;
7294     u32 sw_if_index;
7295     u8  sw_if_index_set = 0;
7296     u64 new_local_cookie = 0;
7297     u64 new_remote_cookie = 0;
7298     vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7299     f64 timeout;
7300
7301     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7302         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7303             sw_if_index_set = 1;
7304         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7305             sw_if_index_set = 1;
7306         else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
7307             ;
7308         else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7309             ;
7310         else
7311             break;
7312     }
7313
7314     if (sw_if_index_set == 0) {
7315         errmsg ("missing interface name or sw_if_index\n");
7316         return -99;
7317     }
7318
7319     M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7320
7321     mp->sw_if_index = ntohl(sw_if_index);
7322     mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7323     mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7324
7325     S; W;
7326     /* NOTREACHED */
7327     return 0;
7328 }
7329
7330 static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7331 {
7332     unformat_input_t * i = vam->input;
7333     vl_api_l2tpv3_interface_enable_disable_t *mp;
7334     f64 timeout;
7335     u32 sw_if_index;
7336     u8  sw_if_index_set = 0;
7337     u8  enable_disable = 1;
7338
7339     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7340         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7341             sw_if_index_set = 1;
7342         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7343             sw_if_index_set = 1;
7344         else if (unformat (i, "enable"))
7345             enable_disable = 1;
7346         else if (unformat (i, "disable"))
7347             enable_disable = 0;
7348         else
7349             break;
7350     }
7351
7352     if (sw_if_index_set == 0) {
7353         errmsg ("missing interface name or sw_if_index\n");
7354         return -99;
7355     }
7356     
7357     M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7358
7359     mp->sw_if_index = ntohl(sw_if_index);
7360     mp->enable_disable = enable_disable;
7361
7362     S; W;
7363     /* NOTREACHED */
7364     return 0;
7365 }
7366
7367 static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7368 {
7369     unformat_input_t * i = vam->input;
7370     vl_api_l2tpv3_set_lookup_key_t * mp;
7371     f64 timeout;
7372     u8 key = ~0;
7373
7374     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7375         if (unformat (i, "lookup_v6_src"))
7376             key = L2T_LOOKUP_SRC_ADDRESS;
7377         else if (unformat (i, "lookup_v6_dst"))
7378             key = L2T_LOOKUP_DST_ADDRESS;
7379         else if (unformat (i, "lookup_session_id"))
7380             key = L2T_LOOKUP_SESSION_ID;
7381         else
7382             break;
7383     }
7384
7385     if (key == (u8) ~0) {
7386         errmsg ("l2tp session lookup key unset\n");
7387         return -99;
7388     }
7389     
7390     M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7391
7392     mp->key = key;
7393
7394     S; W;
7395     /* NOTREACHED */
7396     return 0;
7397 }
7398
7399 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7400 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7401 {
7402     vat_main_t * vam = &vat_main;
7403
7404     fformat(vam->ofp,  "* %U (our) %U (client) (sw_if_index %d)\n",
7405               format_ip6_address, mp->our_address,
7406               format_ip6_address, mp->client_address,
7407               clib_net_to_host_u32(mp->sw_if_index));
7408
7409     fformat (vam->ofp, "   local cookies %016llx %016llx remote cookie %016llx\n",
7410               clib_net_to_host_u64 (mp->local_cookie[0]),
7411               clib_net_to_host_u64 (mp->local_cookie[1]),
7412               clib_net_to_host_u64 (mp->remote_cookie));
7413
7414     fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
7415               clib_net_to_host_u32 (mp->local_session_id),
7416               clib_net_to_host_u32 (mp->remote_session_id));
7417
7418     fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
7419               mp->l2_sublayer_present ? "preset" : "absent");
7420
7421 }
7422
7423 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7424 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7425 {
7426     vat_main_t * vam = &vat_main;
7427     vat_json_node_t *node = NULL;
7428     struct in6_addr addr;
7429
7430     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7431         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7432         vat_json_init_array(&vam->json_tree);
7433     }
7434     node = vat_json_array_add(&vam->json_tree);
7435
7436     vat_json_init_object(node);
7437
7438     clib_memcpy(&addr, mp->our_address, sizeof(addr));
7439     vat_json_object_add_ip6(node, "our_address", addr);
7440     clib_memcpy(&addr, mp->client_address, sizeof(addr));
7441     vat_json_object_add_ip6(node, "client_address", addr);
7442
7443     vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7444     vat_json_init_array(lc);
7445     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7446     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7447     vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7448
7449     printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7450     vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7451     vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7452     vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7453             (u8*)"present" : (u8*)"absent");
7454 }
7455
7456 static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7457 {
7458     vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7459     f64 timeout;
7460
7461     /* Get list of l2tpv3-tunnel interfaces */
7462     M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7463     S;
7464
7465     /* Use a control ping for synchronization */
7466     {
7467         vl_api_control_ping_t * mp;
7468         M(CONTROL_PING, control_ping);
7469         S;
7470     }
7471     W;
7472 }
7473
7474
7475 static void vl_api_sw_interface_tap_details_t_handler
7476 (vl_api_sw_interface_tap_details_t * mp)
7477 {
7478     vat_main_t * vam = &vat_main;
7479
7480     fformat(vam->ofp,  "%-16s %d\n",
7481               mp->dev_name,
7482               clib_net_to_host_u32(mp->sw_if_index));
7483 }
7484
7485 static void vl_api_sw_interface_tap_details_t_handler_json
7486 (vl_api_sw_interface_tap_details_t * mp)
7487 {
7488     vat_main_t * vam = &vat_main;
7489     vat_json_node_t *node = NULL;
7490
7491     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7492         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7493         vat_json_init_array(&vam->json_tree);
7494     }
7495     node = vat_json_array_add(&vam->json_tree);
7496
7497     vat_json_init_object(node);
7498     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7499     vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7500 }
7501
7502 static int api_sw_interface_tap_dump (vat_main_t * vam)
7503 {
7504     vl_api_sw_interface_tap_dump_t *mp;
7505     f64 timeout;
7506
7507     fformat(vam->ofp,  "\n%-16s %s\n", "dev_name", "sw_if_index");
7508     /* Get list of tap interfaces */
7509     M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7510     S;
7511
7512     /* Use a control ping for synchronization */
7513     {
7514         vl_api_control_ping_t * mp;
7515         M(CONTROL_PING, control_ping);
7516         S;
7517     }
7518     W;
7519 }
7520
7521 static uword unformat_vxlan_decap_next 
7522 (unformat_input_t * input, va_list * args)
7523 {
7524   u32 * result = va_arg (*args, u32 *);
7525   u32 tmp;
7526   
7527   if (unformat (input, "drop"))
7528     *result = VXLAN_INPUT_NEXT_DROP;
7529   else if (unformat (input, "ip4"))
7530     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7531   else if (unformat (input, "ip6"))
7532     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7533   else if (unformat (input, "l2"))
7534     *result = VXLAN_INPUT_NEXT_L2_INPUT;
7535   else if (unformat (input, "%d", &tmp))
7536     *result = tmp;
7537   else
7538     return 0;
7539   return 1;
7540 }
7541
7542 static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7543 {
7544     unformat_input_t * line_input = vam->input;
7545     vl_api_vxlan_add_del_tunnel_t *mp;
7546     f64 timeout;
7547     ip4_address_t src4, dst4;
7548     ip6_address_t src6, dst6;
7549     u8 is_add = 1;
7550     u8 ipv4_set = 0, ipv6_set = 0;
7551     u8 src_set = 0;
7552     u8 dst_set = 0;
7553     u32 encap_vrf_id = 0;
7554     u32 decap_next_index = ~0;
7555     u32 vni = 0;
7556
7557     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7558         if (unformat (line_input, "del"))
7559             is_add = 0;
7560         else if (unformat (line_input, "src %U", 
7561                            unformat_ip4_address, &src4))
7562           {
7563             ipv4_set = 1;
7564             src_set = 1;
7565           }
7566         else if (unformat (line_input, "dst %U",
7567                            unformat_ip4_address, &dst4))
7568           {
7569             ipv4_set = 1;
7570             dst_set = 1;
7571           }
7572         else if (unformat (line_input, "src %U", 
7573                            unformat_ip6_address, &src6))
7574           {
7575             ipv6_set = 1;
7576             src_set = 1;
7577           }
7578         else if (unformat (line_input, "dst %U",
7579                            unformat_ip6_address, &dst6))
7580           {
7581             ipv6_set = 1;
7582             dst_set = 1;
7583           }
7584         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7585             ;
7586         else if (unformat (line_input, "decap-next %U", 
7587                            unformat_vxlan_decap_next, &decap_next_index))
7588             ;
7589         else if (unformat (line_input, "vni %d", &vni))
7590             ;
7591         else {
7592             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7593             return -99;
7594         }
7595     }
7596
7597     if (src_set == 0) {
7598         errmsg ("tunnel src address not specified\n");
7599         return -99;
7600     }
7601     if (dst_set == 0) {
7602         errmsg ("tunnel dst address not specified\n");
7603         return -99;
7604     }
7605
7606     if (ipv4_set && ipv6_set) {
7607         errmsg ("both IPv4 and IPv6 addresses specified");
7608         return -99;
7609     }
7610
7611     if ((vni == 0) || (vni>>24)) {
7612         errmsg ("vni not specified or out of range\n");
7613         return -99;
7614     }
7615
7616     M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
7617
7618     if (ipv6_set) {
7619         clib_memcpy(&mp->src_address, &src6, sizeof(src6));
7620         clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
7621     } else { 
7622         clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7623         clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7624     }
7625     mp->encap_vrf_id = ntohl(encap_vrf_id);
7626     mp->decap_next_index = ntohl(decap_next_index);
7627     mp->vni = ntohl(vni);
7628     mp->is_add = is_add;
7629     mp->is_ipv6 = ipv6_set;
7630
7631     S; W;
7632     /* NOTREACHED */
7633     return 0;
7634 }
7635
7636 static void vl_api_vxlan_tunnel_details_t_handler
7637 (vl_api_vxlan_tunnel_details_t * mp)
7638 {
7639     vat_main_t * vam = &vat_main;
7640
7641     fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
7642             ntohl(mp->sw_if_index),
7643             format_ip46_address, &(mp->src_address[0]),
7644             IP46_TYPE_ANY,
7645             format_ip46_address, &(mp->dst_address[0]),
7646             IP46_TYPE_ANY,
7647             ntohl(mp->encap_vrf_id),
7648             ntohl(mp->decap_next_index),
7649             ntohl(mp->vni));
7650 }
7651
7652 static void vl_api_vxlan_tunnel_details_t_handler_json
7653 (vl_api_vxlan_tunnel_details_t * mp)
7654 {
7655     vat_main_t * vam = &vat_main;
7656     vat_json_node_t *node = NULL;
7657     struct in_addr ip4;
7658     struct in6_addr ip6;
7659
7660     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7661         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7662         vat_json_init_array(&vam->json_tree);
7663     }
7664     node = vat_json_array_add(&vam->json_tree);
7665
7666     vat_json_init_object(node);
7667     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7668     if (mp->is_ipv6) {
7669         clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7670         vat_json_object_add_ip6(node, "src_address", ip6);
7671         clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7672         vat_json_object_add_ip6(node, "dst_address", ip6);
7673     } else {
7674         clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7675         vat_json_object_add_ip4(node, "src_address", ip4);
7676         clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7677         vat_json_object_add_ip4(node, "dst_address", ip4);
7678     }
7679     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7680     vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7681     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
7682     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
7683 }
7684
7685 static int api_vxlan_tunnel_dump (vat_main_t * vam)
7686 {
7687     unformat_input_t * i = vam->input;
7688     vl_api_vxlan_tunnel_dump_t *mp;
7689     f64 timeout;
7690     u32 sw_if_index;
7691     u8 sw_if_index_set = 0;
7692
7693     /* Parse args required to build the message */
7694     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7695         if (unformat (i, "sw_if_index %d", &sw_if_index))
7696             sw_if_index_set = 1;
7697         else
7698             break;
7699     }
7700
7701     if (sw_if_index_set == 0) {
7702         sw_if_index = ~0;
7703     }
7704
7705     if (!vam->json_output) {
7706         fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
7707                 "sw_if_index", "src_address", "dst_address",
7708                 "encap_vrf_id", "decap_next_index", "vni");
7709     }
7710
7711     /* Get list of vxlan-tunnel interfaces */
7712     M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7713
7714     mp->sw_if_index = htonl(sw_if_index);
7715
7716     S;
7717
7718     /* Use a control ping for synchronization */
7719     {
7720         vl_api_control_ping_t * mp;
7721         M(CONTROL_PING, control_ping);
7722         S;
7723     }
7724     W;
7725 }
7726
7727 static int api_gre_add_del_tunnel (vat_main_t * vam)
7728 {
7729     unformat_input_t * line_input = vam->input;
7730     vl_api_gre_add_del_tunnel_t *mp;
7731     f64 timeout;
7732     ip4_address_t src4, dst4;
7733     u8 is_add = 1;
7734     u8 src_set = 0;
7735     u8 dst_set = 0;
7736     u32 outer_fib_id = 0;
7737
7738     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7739         if (unformat (line_input, "del"))
7740             is_add = 0;
7741         else if (unformat (line_input, "src %U",
7742                            unformat_ip4_address, &src4))
7743             src_set = 1;
7744         else if (unformat (line_input, "dst %U",
7745                            unformat_ip4_address, &dst4))
7746             dst_set = 1;
7747         else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7748             ;
7749         else {
7750             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7751             return -99;
7752         }
7753     }
7754
7755     if (src_set == 0) {
7756         errmsg ("tunnel src address not specified\n");
7757         return -99;
7758     }
7759     if (dst_set == 0) {
7760         errmsg ("tunnel dst address not specified\n");
7761         return -99;
7762     }
7763
7764
7765     M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7766
7767     clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7768     clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7769     mp->outer_table_id = ntohl(outer_fib_id);
7770     mp->is_add = is_add;
7771
7772     S; W;
7773     /* NOTREACHED */
7774     return 0;
7775 }
7776
7777 static void vl_api_gre_tunnel_details_t_handler
7778 (vl_api_gre_tunnel_details_t * mp)
7779 {
7780     vat_main_t * vam = &vat_main;
7781
7782     fformat(vam->ofp, "%11d%15U%15U%14d\n",
7783             ntohl(mp->sw_if_index),
7784             format_ip4_address, &mp->src_address,
7785             format_ip4_address, &mp->dst_address,
7786             ntohl(mp->outer_table_id));
7787 }
7788
7789 static void vl_api_gre_tunnel_details_t_handler_json
7790 (vl_api_gre_tunnel_details_t * mp)
7791 {
7792     vat_main_t * vam = &vat_main;
7793     vat_json_node_t *node = NULL;
7794     struct in_addr ip4;
7795
7796     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7797         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7798         vat_json_init_array(&vam->json_tree);
7799     }
7800     node = vat_json_array_add(&vam->json_tree);
7801
7802     vat_json_init_object(node);
7803     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7804     clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
7805     vat_json_object_add_ip4(node, "src_address", ip4);
7806     clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
7807     vat_json_object_add_ip4(node, "dst_address", ip4);
7808     vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
7809 }
7810
7811 static int api_gre_tunnel_dump (vat_main_t * vam)
7812 {
7813     unformat_input_t * i = vam->input;
7814     vl_api_gre_tunnel_dump_t *mp;
7815     f64 timeout;
7816     u32 sw_if_index;
7817     u8 sw_if_index_set = 0;
7818
7819     /* Parse args required to build the message */
7820     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7821         if (unformat (i, "sw_if_index %d", &sw_if_index))
7822             sw_if_index_set = 1;
7823         else
7824             break;
7825     }
7826
7827     if (sw_if_index_set == 0) {
7828         sw_if_index = ~0;
7829     }
7830
7831     if (!vam->json_output) {
7832         fformat(vam->ofp, "%11s%15s%15s%14s\n",
7833                 "sw_if_index", "src_address", "dst_address",
7834                 "outer_fib_id");
7835     }
7836
7837     /* Get list of gre-tunnel interfaces */
7838     M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
7839
7840     mp->sw_if_index = htonl(sw_if_index);
7841
7842     S;
7843
7844     /* Use a control ping for synchronization */
7845     {
7846         vl_api_control_ping_t * mp;
7847         M(CONTROL_PING, control_ping);
7848         S;
7849     }
7850     W;
7851 }
7852
7853 static int api_l2_fib_clear_table (vat_main_t * vam)
7854 {
7855 //  unformat_input_t * i = vam->input;
7856     vl_api_l2_fib_clear_table_t *mp;
7857     f64 timeout;
7858
7859     M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
7860
7861     S; W;
7862     /* NOTREACHED */
7863     return 0;
7864 }
7865
7866 static int api_l2_interface_efp_filter (vat_main_t * vam)
7867 {
7868     unformat_input_t * i = vam->input;
7869     vl_api_l2_interface_efp_filter_t *mp;
7870     f64 timeout;
7871     u32 sw_if_index;
7872     u8 enable = 1;
7873     u8 sw_if_index_set = 0;
7874
7875     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7876         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7877             sw_if_index_set = 1;
7878         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7879             sw_if_index_set = 1;
7880         else if (unformat (i, "enable"))
7881             enable = 1;
7882         else if (unformat (i, "disable"))
7883             enable = 0;
7884         else {
7885             clib_warning ("parse error '%U'", format_unformat_error, i);
7886             return -99;
7887         }
7888     }
7889     
7890     if (sw_if_index_set == 0) {
7891         errmsg ("missing sw_if_index\n");
7892         return -99;
7893     }
7894
7895     M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
7896
7897     mp->sw_if_index = ntohl(sw_if_index);
7898     mp->enable_disable = enable;
7899
7900     S; W;
7901     /* NOTREACHED */
7902     return 0;
7903 }
7904
7905 #define foreach_vtr_op                          \
7906 _("disable",  L2_VTR_DISABLED)                  \
7907 _("push-1",  L2_VTR_PUSH_1)                     \
7908 _("push-2",  L2_VTR_PUSH_2)                     \
7909 _("pop-1",  L2_VTR_POP_1)                       \
7910 _("pop-2",  L2_VTR_POP_2)                       \
7911 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
7912 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
7913 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
7914 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
7915
7916 static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
7917 {
7918     unformat_input_t * i = vam->input;
7919     vl_api_l2_interface_vlan_tag_rewrite_t *mp;
7920     f64 timeout;
7921     u32 sw_if_index;
7922     u8 sw_if_index_set = 0;
7923     u8 vtr_op_set = 0;
7924     u32 vtr_op = 0;
7925     u32 push_dot1q = 1;
7926     u32 tag1 = ~0;
7927     u32 tag2 = ~0;
7928
7929     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7930         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7931             sw_if_index_set = 1;
7932         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7933             sw_if_index_set = 1;
7934         else if (unformat (i, "vtr_op %d", &vtr_op))
7935             vtr_op_set = 1;
7936 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7937         foreach_vtr_op
7938 #undef _
7939         
7940         else if (unformat (i, "push_dot1q %d", &push_dot1q))
7941             ;
7942         else if (unformat (i, "tag1 %d", &tag1))
7943             ;
7944         else if (unformat (i, "tag2 %d", &tag2))
7945             ;
7946         else {
7947             clib_warning ("parse error '%U'", format_unformat_error, i);
7948             return -99;
7949         }
7950     }
7951     
7952     if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7953         errmsg ("missing vtr operation or sw_if_index\n");
7954         return -99;
7955     }
7956
7957     M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7958
7959     mp->sw_if_index = ntohl(sw_if_index);
7960     mp->vtr_op = ntohl(vtr_op);
7961     mp->push_dot1q = ntohl(push_dot1q);
7962     mp->tag1 = ntohl(tag1);
7963     mp->tag2 = ntohl(tag2);
7964
7965     S; W;
7966     /* NOTREACHED */
7967     return 0;
7968 }
7969
7970 static int api_create_vhost_user_if (vat_main_t * vam)
7971 {
7972     unformat_input_t * i = vam->input;
7973     vl_api_create_vhost_user_if_t *mp;
7974     f64 timeout;
7975     u8 * file_name;
7976     u8 is_server = 0;
7977     u8 file_name_set = 0;
7978     u32 custom_dev_instance = ~0;
7979     u8 hwaddr[6];
7980     u8 use_custom_mac = 0;
7981
7982     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7983       if (unformat (i, "socket %s", &file_name)) {
7984         file_name_set = 1;
7985       }
7986       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7987         ;
7988       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7989         use_custom_mac = 1;
7990       else if (unformat (i, "server"))
7991         is_server = 1;
7992       else
7993         break;
7994     }
7995
7996     if (file_name_set == 0) {
7997       errmsg ("missing socket file name\n");
7998       return -99;
7999     }
8000
8001     if (vec_len (file_name) > 255) {
8002       errmsg ("socket file name too long\n");
8003       return -99;
8004     }
8005     vec_add1 (file_name, 0);
8006
8007     M(CREATE_VHOST_USER_IF, create_vhost_user_if);
8008
8009     mp->is_server = is_server;
8010     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
8011     vec_free(file_name);
8012     if (custom_dev_instance != ~0) {
8013         mp->renumber = 1;
8014         mp->custom_dev_instance = ntohl(custom_dev_instance);
8015     }
8016     mp->use_custom_mac = use_custom_mac;
8017     clib_memcpy(mp->mac_address, hwaddr, 6);
8018
8019     S; W;
8020     /* NOTREACHED */
8021     return 0;
8022 }
8023
8024 static int api_modify_vhost_user_if (vat_main_t * vam)
8025 {
8026     unformat_input_t * i = vam->input;
8027     vl_api_modify_vhost_user_if_t *mp;
8028     f64 timeout;
8029     u8 * file_name;
8030     u8 is_server = 0;
8031     u8 file_name_set = 0;
8032     u32 custom_dev_instance = ~0;
8033     u8 sw_if_index_set = 0;
8034     u32 sw_if_index = (u32)~0;
8035
8036     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8037       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8038           sw_if_index_set = 1;
8039       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8040           sw_if_index_set = 1;
8041       else if (unformat (i, "socket %s", &file_name)) {
8042         file_name_set = 1;
8043       }
8044       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
8045         ;
8046       else if (unformat (i, "server"))
8047         is_server = 1;
8048       else
8049         break;
8050     }
8051
8052     if (sw_if_index_set == 0) {
8053        errmsg ("missing sw_if_index or interface name\n");
8054        return -99;
8055     }
8056
8057     if (file_name_set == 0) {
8058       errmsg ("missing socket file name\n");
8059       return -99;
8060     }
8061
8062     if (vec_len (file_name) > 255) {
8063       errmsg ("socket file name too long\n");
8064       return -99;
8065     }
8066     vec_add1 (file_name, 0);
8067
8068     M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
8069
8070     mp->sw_if_index = ntohl(sw_if_index);
8071     mp->is_server = is_server;
8072     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
8073     vec_free(file_name);
8074     if (custom_dev_instance != ~0) {
8075         mp->renumber = 1;
8076         mp->custom_dev_instance = ntohl(custom_dev_instance);
8077     }
8078
8079     S; W;
8080     /* NOTREACHED */
8081     return 0;
8082 }
8083
8084 static int api_delete_vhost_user_if (vat_main_t * vam)
8085 {
8086     unformat_input_t * i = vam->input;
8087     vl_api_delete_vhost_user_if_t *mp;
8088     f64 timeout;
8089     u32 sw_if_index = ~0;
8090     u8 sw_if_index_set = 0;
8091
8092     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8093       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8094           sw_if_index_set = 1;
8095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8096           sw_if_index_set = 1;
8097       else
8098         break;
8099     }
8100
8101     if (sw_if_index_set == 0) {
8102        errmsg ("missing sw_if_index or interface name\n");
8103        return -99;
8104     }
8105
8106
8107     M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
8108
8109     mp->sw_if_index = ntohl(sw_if_index);
8110
8111     S; W;
8112     /* NOTREACHED */
8113     return 0;
8114 }
8115
8116 static void vl_api_sw_interface_vhost_user_details_t_handler
8117 (vl_api_sw_interface_vhost_user_details_t * mp)
8118 {
8119     vat_main_t * vam = &vat_main;
8120
8121     fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
8122             (char *)mp->interface_name,
8123             ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8124             clib_net_to_host_u64(mp->features), mp->is_server,
8125             ntohl(mp->num_regions), (char *)mp->sock_filename);
8126     fformat(vam->ofp, "    Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8127 }
8128
8129 static void vl_api_sw_interface_vhost_user_details_t_handler_json
8130 (vl_api_sw_interface_vhost_user_details_t * mp)
8131 {
8132     vat_main_t * vam = &vat_main;
8133     vat_json_node_t *node = NULL;
8134
8135     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8136         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8137         vat_json_init_array(&vam->json_tree);
8138     }
8139     node = vat_json_array_add(&vam->json_tree);
8140
8141     vat_json_init_object(node);
8142     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8143     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8144     vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8145     vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8146     vat_json_object_add_uint(node, "is_server", mp->is_server);
8147     vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8148     vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8149     vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8150 }
8151
8152 static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8153 {
8154     vl_api_sw_interface_vhost_user_dump_t *mp;
8155     f64 timeout;
8156     fformat(vam->ofp, "Interface name           idx hdr_sz features server regions filename\n");
8157
8158     /* Get list of vhost-user interfaces */
8159     M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8160     S;
8161
8162     /* Use a control ping for synchronization */
8163     {
8164         vl_api_control_ping_t * mp;
8165         M(CONTROL_PING, control_ping);
8166         S;
8167     }
8168     W;
8169 }
8170
8171 static int api_show_version (vat_main_t * vam)
8172 {
8173     vl_api_show_version_t *mp;
8174     f64 timeout;
8175
8176     M(SHOW_VERSION, show_version);
8177
8178     S; W;
8179     /* NOTREACHED */
8180     return 0;
8181 }
8182
8183
8184 static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
8185 {
8186     unformat_input_t * line_input = vam->input;
8187     vl_api_vxlan_gpe_add_del_tunnel_t *mp;
8188     f64 timeout;
8189     ip4_address_t local4, remote4;
8190     ip6_address_t local6, remote6;
8191     u8 is_add = 1;
8192     u8 ipv4_set = 0, ipv6_set = 0;
8193     u8 local_set = 0;
8194     u8 remote_set = 0;
8195     u32 encap_vrf_id = 0;
8196     u32 decap_vrf_id = 0;
8197     u8 protocol = ~0;
8198     u32 vni;
8199     u8 vni_set = 0;
8200
8201     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8202         if (unformat (line_input, "del"))
8203             is_add = 0;
8204         else if (unformat (line_input, "local %U", 
8205                            unformat_ip4_address, &local4))
8206         {
8207             local_set = 1;
8208             ipv4_set = 1;
8209         }
8210         else if (unformat (line_input, "remote %U",
8211                            unformat_ip4_address, &remote4))
8212         {
8213             remote_set = 1;
8214             ipv4_set = 1;
8215         }
8216         else if (unformat (line_input, "local %U",
8217                            unformat_ip6_address, &local6))
8218         {
8219             local_set = 1;
8220             ipv6_set = 1;
8221         }
8222         else if (unformat (line_input, "remote %U",
8223                            unformat_ip6_address, &remote6))
8224         {
8225             remote_set = 1;
8226             ipv6_set = 1;
8227         }
8228         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8229             ;
8230         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8231             ;
8232         else if (unformat (line_input, "vni %d", &vni))
8233             vni_set = 1;
8234         else if (unformat(line_input, "next-ip4"))
8235             protocol = 1;
8236         else if (unformat(line_input, "next-ip6"))
8237             protocol = 2;
8238         else if (unformat(line_input, "next-ethernet"))
8239             protocol = 3;
8240         else if (unformat(line_input, "next-nsh"))
8241             protocol = 4;
8242         else {
8243             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8244             return -99;
8245         }
8246     }
8247
8248     if (local_set == 0) {
8249         errmsg ("tunnel local address not specified\n");
8250         return -99;
8251     }
8252     if (remote_set == 0) {
8253         errmsg ("tunnel remote address not specified\n");
8254         return -99;
8255     }
8256     if (ipv4_set && ipv6_set) {
8257         errmsg ("both IPv4 and IPv6 addresses specified");
8258         return -99;
8259     }
8260
8261     if (vni_set == 0) {
8262         errmsg ("vni not specified\n");
8263         return -99;
8264     }
8265
8266     M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
8267     
8268
8269     if (ipv6_set) {
8270         clib_memcpy(&mp->local, &local6, sizeof(local6));
8271         clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
8272     } else {
8273         clib_memcpy(&mp->local, &local4, sizeof(local4));
8274         clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
8275     }
8276
8277     mp->encap_vrf_id = ntohl(encap_vrf_id);
8278     mp->decap_vrf_id = ntohl(decap_vrf_id);
8279     mp->protocol = ntohl(protocol);
8280     mp->vni = ntohl(vni);
8281     mp->is_add = is_add;
8282     mp->is_ipv6 = ipv6_set;
8283
8284     S; W;
8285     /* NOTREACHED */
8286     return 0;
8287 }
8288
8289 static void vl_api_vxlan_gpe_tunnel_details_t_handler
8290 (vl_api_vxlan_gpe_tunnel_details_t * mp)
8291 {
8292     vat_main_t * vam = &vat_main;
8293
8294     fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
8295             ntohl(mp->sw_if_index),
8296             format_ip46_address, &(mp->local[0]),
8297             format_ip46_address, &(mp->remote[0]),
8298                         ntohl(mp->vni),
8299             ntohl(mp->protocol),
8300             ntohl(mp->encap_vrf_id),
8301             ntohl(mp->decap_vrf_id));
8302 }
8303
8304 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
8305 (vl_api_vxlan_gpe_tunnel_details_t * mp)
8306 {
8307     vat_main_t * vam = &vat_main;
8308     vat_json_node_t *node = NULL;
8309     struct in_addr ip4;
8310     struct in6_addr ip6;
8311
8312     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8313         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8314         vat_json_init_array(&vam->json_tree);
8315     }
8316     node = vat_json_array_add(&vam->json_tree);
8317
8318     vat_json_init_object(node);
8319     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8320     if (mp->is_ipv6) {
8321         clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
8322         vat_json_object_add_ip6(node, "local", ip6);
8323         clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
8324         vat_json_object_add_ip6(node, "remote", ip6);
8325     } else {
8326         clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
8327         vat_json_object_add_ip4(node, "local", ip4);
8328         clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
8329         vat_json_object_add_ip4(node, "remote", ip4);
8330     }
8331     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
8332     vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
8333     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8334     vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
8335     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
8336 }
8337
8338 static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
8339 {
8340     unformat_input_t * i = vam->input;
8341     vl_api_vxlan_gpe_tunnel_dump_t *mp;
8342     f64 timeout;
8343     u32 sw_if_index;
8344     u8 sw_if_index_set = 0;
8345
8346     /* Parse args required to build the message */
8347     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8348         if (unformat (i, "sw_if_index %d", &sw_if_index))
8349             sw_if_index_set = 1;
8350         else
8351             break;
8352     }
8353
8354     if (sw_if_index_set == 0) {
8355         sw_if_index = ~0;
8356     }
8357
8358     if (!vam->json_output) {
8359         fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
8360                 "sw_if_index", "local", "remote", "vni",
8361                                 "protocol","encap_vrf_id", "decap_vrf_id");
8362     }
8363
8364     /* Get list of vxlan-tunnel interfaces */
8365     M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
8366
8367     mp->sw_if_index = htonl(sw_if_index);
8368
8369     S;
8370
8371     /* Use a control ping for synchronization */
8372     {
8373         vl_api_control_ping_t * mp;
8374         M(CONTROL_PING, control_ping);
8375         S;
8376     }
8377     W;
8378 }
8379
8380 u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8381 {
8382   u8 * a = va_arg (*args, u8 *);
8383
8384   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8385                  a[2], a[3], a[4], a[5], a[6], a[7]);
8386 }
8387
8388 static void vl_api_l2_fib_table_entry_t_handler
8389 (vl_api_l2_fib_table_entry_t * mp)
8390 {
8391     vat_main_t * vam = &vat_main;
8392
8393     fformat(vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
8394             "       %d       %d     %d\n",
8395             ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8396             ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8397             mp->bvi_mac);
8398 }
8399
8400 static void vl_api_l2_fib_table_entry_t_handler_json
8401 (vl_api_l2_fib_table_entry_t * mp)
8402 {
8403     vat_main_t * vam = &vat_main;
8404     vat_json_node_t *node = NULL;
8405
8406     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8407         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8408         vat_json_init_array(&vam->json_tree);
8409     }
8410     node = vat_json_array_add(&vam->json_tree);
8411
8412     vat_json_init_object(node);
8413     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8414     vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8415     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8416     vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8417     vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8418     vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8419 }
8420
8421 static int api_l2_fib_table_dump (vat_main_t * vam)
8422 {
8423     unformat_input_t * i = vam->input;
8424     vl_api_l2_fib_table_dump_t *mp;
8425     f64 timeout;
8426     u32 bd_id;
8427     u8 bd_id_set = 0;
8428
8429     /* Parse args required to build the message */
8430     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8431         if (unformat (i, "bd_id %d", &bd_id))
8432             bd_id_set = 1;
8433         else
8434             break;
8435     }
8436
8437     if (bd_id_set == 0) {
8438         errmsg ("missing bridge domain\n");
8439         return -99;
8440     }
8441
8442     fformat(vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
8443
8444     /* Get list of l2 fib entries */
8445     M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8446
8447     mp->bd_id = ntohl(bd_id);
8448     S;
8449
8450     /* Use a control ping for synchronization */
8451     {
8452         vl_api_control_ping_t * mp;
8453         M(CONTROL_PING, control_ping);
8454         S;
8455     }
8456     W;
8457 }
8458
8459
8460 static int
8461 api_interface_name_renumber (vat_main_t * vam)
8462 {
8463     unformat_input_t * line_input = vam->input;
8464     vl_api_interface_name_renumber_t *mp;
8465     u32 sw_if_index = ~0;
8466     f64 timeout;
8467     u32 new_show_dev_instance = ~0;
8468
8469     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8470         if (unformat (line_input, "%U", unformat_sw_if_index, vam, 
8471                       &sw_if_index))
8472             ;
8473         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8474             ;
8475         else if (unformat (line_input, "new_show_dev_instance %d", 
8476                            &new_show_dev_instance))
8477             ;
8478         else
8479             break;
8480     }
8481
8482     if (sw_if_index == ~0) {
8483         errmsg ("missing interface name or sw_if_index\n");
8484         return -99;
8485     }
8486
8487     if (new_show_dev_instance == ~0) {
8488         errmsg ("missing new_show_dev_instance\n");
8489         return -99;
8490     }
8491
8492     M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8493
8494     mp->sw_if_index = ntohl (sw_if_index);
8495     mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8496
8497     S; W;
8498 }
8499
8500 static int
8501 api_want_ip4_arp_events (vat_main_t * vam)
8502 {
8503     unformat_input_t * line_input = vam->input;
8504     vl_api_want_ip4_arp_events_t * mp;
8505     f64 timeout;
8506     ip4_address_t address;
8507     int address_set = 0;
8508     u32 enable_disable = 1;
8509
8510     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8511         if (unformat (line_input, "address %U", 
8512                       unformat_ip4_address, &address))
8513             address_set = 1;
8514         else if (unformat (line_input, "del"))
8515             enable_disable = 0;
8516         else
8517             break;
8518     }
8519     
8520     if (address_set == 0) {
8521         errmsg ("missing addresses\n");
8522         return -99;
8523     }
8524         
8525     M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8526     mp->enable_disable = enable_disable;
8527     mp->pid = getpid();
8528     mp->address = address.as_u32;
8529
8530     S; W; 
8531 }
8532
8533 static int api_input_acl_set_interface (vat_main_t * vam)
8534 {
8535     unformat_input_t * i = vam->input;
8536     vl_api_input_acl_set_interface_t *mp;
8537     f64 timeout;
8538     u32 sw_if_index;
8539     int sw_if_index_set;
8540     u32 ip4_table_index = ~0;
8541     u32 ip6_table_index = ~0;
8542     u32 l2_table_index = ~0;
8543     u8 is_add = 1;
8544
8545     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8546         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8547             sw_if_index_set = 1;
8548         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8549             sw_if_index_set = 1;
8550         else if (unformat (i, "del"))
8551             is_add = 0;
8552         else if (unformat (i, "ip4-table %d", &ip4_table_index))
8553             ;
8554         else if (unformat (i, "ip6-table %d", &ip6_table_index))
8555             ;
8556         else if (unformat (i, "l2-table %d", &l2_table_index))
8557             ;
8558         else {
8559             clib_warning ("parse error '%U'", format_unformat_error, i);
8560             return -99;
8561         }
8562     }
8563
8564     if (sw_if_index_set == 0) {
8565         errmsg ("missing interface name or sw_if_index\n");
8566         return -99;
8567     }
8568
8569     M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8570
8571     mp->sw_if_index = ntohl(sw_if_index);
8572     mp->ip4_table_index = ntohl(ip4_table_index);
8573     mp->ip6_table_index = ntohl(ip6_table_index);
8574     mp->l2_table_index = ntohl(l2_table_index);
8575     mp->is_add = is_add;
8576
8577     S; W;
8578     /* NOTREACHED */
8579     return 0;
8580 }
8581
8582 static int
8583 api_ip_address_dump (vat_main_t * vam)
8584 {
8585     unformat_input_t * i = vam->input;
8586     vl_api_ip_address_dump_t * mp;
8587     u32 sw_if_index = ~0;
8588     u8 sw_if_index_set = 0;
8589     u8 ipv4_set = 0;
8590     u8 ipv6_set = 0;
8591     f64 timeout;
8592
8593     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8594         if (unformat (i, "sw_if_index %d", &sw_if_index))
8595             sw_if_index_set = 1;
8596         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8597             sw_if_index_set = 1;
8598         else if (unformat (i, "ipv4"))
8599             ipv4_set = 1;
8600         else if (unformat (i, "ipv6"))
8601             ipv6_set = 1;
8602         else
8603             break;
8604     }
8605
8606     if (ipv4_set && ipv6_set) {
8607         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8608         return -99;
8609     }
8610
8611     if ((!ipv4_set) && (!ipv6_set)) {
8612         errmsg ("no ipv4 nor ipv6 flag set\n");
8613         return -99;
8614     }
8615
8616     if (sw_if_index_set == 0) {
8617         errmsg ("missing interface name or sw_if_index\n");
8618         return -99;
8619     }
8620
8621     vam->current_sw_if_index = sw_if_index;
8622     vam->is_ipv6 = ipv6_set;
8623
8624     M(IP_ADDRESS_DUMP, ip_address_dump);
8625     mp->sw_if_index = ntohl(sw_if_index);
8626     mp->is_ipv6 = ipv6_set;
8627     S;
8628
8629     /* Use a control ping for synchronization */
8630     {
8631         vl_api_control_ping_t * mp;
8632         M(CONTROL_PING, control_ping);
8633         S;
8634     }
8635     W;
8636 }
8637
8638 static int
8639 api_ip_dump (vat_main_t * vam)
8640 {
8641     vl_api_ip_dump_t * mp;
8642     unformat_input_t * in = vam->input;
8643     int ipv4_set = 0;
8644     int ipv6_set = 0;
8645     int is_ipv6;
8646     f64 timeout;
8647     int i;
8648
8649     while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8650         if (unformat (in, "ipv4"))
8651             ipv4_set = 1;
8652         else if (unformat (in, "ipv6"))
8653             ipv6_set = 1;
8654         else
8655             break;
8656     }
8657
8658     if (ipv4_set && ipv6_set) {
8659         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8660         return -99;
8661     }
8662
8663     if ((!ipv4_set) && (!ipv6_set)) {
8664         errmsg ("no ipv4 nor ipv6 flag set\n");
8665         return -99;
8666     }
8667
8668     is_ipv6 = ipv6_set;
8669     vam->is_ipv6 = is_ipv6;
8670
8671     /* free old data */
8672     for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8673         vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8674     }
8675     vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8676
8677     M(IP_DUMP, ip_dump);
8678     mp->is_ipv6 = ipv6_set;
8679     S;
8680
8681     /* Use a control ping for synchronization */
8682     {
8683         vl_api_control_ping_t * mp;
8684         M(CONTROL_PING, control_ping);
8685         S;
8686     }
8687     W;
8688 }
8689
8690 static int
8691 api_ipsec_spd_add_del (vat_main_t * vam)
8692 {
8693 #if DPDK > 0
8694     unformat_input_t * i = vam->input;
8695     vl_api_ipsec_spd_add_del_t *mp;
8696     f64 timeout;
8697     u32 spd_id = ~0;
8698     u8 is_add = 1;
8699
8700     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8701         if (unformat (i, "spd_id %d", &spd_id))
8702             ;
8703         else if (unformat (i, "del"))
8704             is_add = 0;
8705         else {
8706             clib_warning ("parse error '%U'", format_unformat_error, i);
8707             return -99;
8708         }
8709     }
8710     if (spd_id == ~0) {
8711         errmsg ("spd_id must be set\n");
8712         return -99;
8713     }
8714
8715     M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8716
8717     mp->spd_id = ntohl(spd_id);
8718     mp->is_add = is_add;
8719
8720     S; W;
8721     /* NOTREACHED */
8722     return 0;
8723 #else
8724     clib_warning ("unsupported (no dpdk)");
8725     return -99;
8726 #endif
8727 }
8728
8729 static int
8730 api_ipsec_interface_add_del_spd (vat_main_t * vam)
8731 {
8732 #if DPDK > 0
8733     unformat_input_t * i = vam->input;
8734     vl_api_ipsec_interface_add_del_spd_t *mp;
8735     f64 timeout;
8736     u32 sw_if_index;
8737     u8 sw_if_index_set = 0;
8738     u32 spd_id = (u32) ~0;
8739     u8 is_add = 1;
8740
8741     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8742         if (unformat (i, "del"))
8743             is_add = 0;
8744         else if (unformat (i, "spd_id %d", &spd_id))
8745             ;
8746         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8747             sw_if_index_set = 1;
8748         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8749             sw_if_index_set = 1;
8750         else {
8751             clib_warning ("parse error '%U'", format_unformat_error, i);
8752             return -99;
8753         }
8754
8755     }
8756
8757     if (spd_id == (u32) ~0) {
8758         errmsg ("spd_id must be set\n");
8759         return -99;
8760     }
8761
8762     if (sw_if_index_set == 0) {
8763         errmsg ("missing interface name or sw_if_index\n");
8764         return -99;
8765     }
8766
8767     M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8768
8769     mp->spd_id = ntohl(spd_id);
8770     mp->sw_if_index = ntohl (sw_if_index);
8771     mp->is_add = is_add;
8772
8773     S; W;
8774     /* NOTREACHED */
8775     return 0;
8776 #else
8777     clib_warning ("unsupported (no dpdk)");
8778     return -99;
8779 #endif
8780 }
8781
8782 static int
8783 api_ipsec_spd_add_del_entry (vat_main_t * vam)
8784 {
8785 #if DPDK > 0
8786     unformat_input_t * i = vam->input;
8787     vl_api_ipsec_spd_add_del_entry_t *mp;
8788     f64 timeout;
8789     u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8790     u32 spd_id, sa_id, protocol = 0, policy = 0;
8791     i32 priority;
8792     u32 rport_start = 0, rport_stop = (u32) ~0;
8793     u32 lport_start = 0, lport_stop = (u32) ~0;
8794     ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8795     ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8796
8797     laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8798     laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8799     laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8800     laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8801     laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8802     laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8803
8804     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8805         if (unformat (i, "del"))
8806             is_add = 0;
8807         if (unformat (i, "outbound"))
8808             is_outbound = 1;
8809         if (unformat (i, "inbound"))
8810             is_outbound = 0;
8811         else if (unformat (i, "spd_id %d", &spd_id))
8812             ;
8813         else if (unformat (i, "sa_id %d", &sa_id))
8814             ;
8815         else if (unformat (i, "priority %d", &priority))
8816             ;
8817         else if (unformat (i, "protocol %d", &protocol))
8818             ;
8819         else if (unformat (i, "lport_start %d", &lport_start))
8820             ;
8821         else if (unformat (i, "lport_stop %d", &lport_stop))
8822             ;
8823         else if (unformat (i, "rport_start %d", &rport_start))
8824             ;
8825         else if (unformat (i, "rport_stop %d", &rport_stop))
8826             ;
8827         else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8828           {
8829             is_ipv6 = 0;
8830             is_ip_any =0;
8831           }
8832         else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8833           {
8834             is_ipv6 = 0;
8835             is_ip_any = 0;
8836           }
8837         else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8838           {
8839             is_ipv6 = 0;
8840             is_ip_any = 0;
8841           }
8842         else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8843           {
8844             is_ipv6 = 0;
8845             is_ip_any = 0;
8846           }
8847         else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8848           {
8849             is_ipv6 = 1;
8850             is_ip_any = 0;
8851           }
8852         else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8853           {
8854             is_ipv6 = 1;
8855             is_ip_any = 0;
8856           }
8857         else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8858           {
8859             is_ipv6 = 1;
8860             is_ip_any = 0;
8861           }
8862         else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8863           {
8864             is_ipv6 = 1;
8865             is_ip_any = 0;
8866           }
8867         else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8868           {
8869             if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8870                 clib_warning ("unsupported action: 'resolve'");
8871                 return -99;
8872             }
8873           }
8874         else {
8875             clib_warning ("parse error '%U'", format_unformat_error, i);
8876             return -99;
8877         }
8878
8879     }
8880
8881     M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8882
8883     mp->spd_id = ntohl(spd_id);
8884     mp->priority = ntohl(priority);
8885     mp->is_outbound = is_outbound;
8886
8887     mp->is_ipv6 = is_ipv6;
8888     if (is_ipv6 || is_ip_any) {
8889         clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8890         clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8891         clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8892         clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
8893     } else {
8894         clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8895         clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8896         clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8897         clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
8898     }
8899     mp->protocol = (u8) protocol;
8900     mp->local_port_start = ntohs((u16) lport_start);
8901     mp->local_port_stop = ntohs((u16) lport_stop);
8902     mp->remote_port_start = ntohs((u16) rport_start);
8903     mp->remote_port_stop = ntohs((u16) rport_stop);
8904     mp->policy = (u8) policy;
8905     mp->sa_id = ntohl(sa_id);
8906     mp->is_add = is_add;
8907     mp->is_ip_any = is_ip_any;
8908     S; W;
8909     /* NOTREACHED */
8910     return 0;
8911 #else
8912     clib_warning ("unsupported (no dpdk)");
8913     return -99;
8914 #endif
8915 }
8916
8917 static int
8918 api_ipsec_sad_add_del_entry (vat_main_t * vam)
8919 {
8920 #if DPDK > 0
8921     unformat_input_t * i = vam->input;
8922     vl_api_ipsec_sad_add_del_entry_t *mp;
8923     f64 timeout;
8924     u32 sad_id, spi;
8925     u8 * ck, * ik;
8926     u8 is_add = 1;
8927
8928     u8 protocol = IPSEC_PROTOCOL_AH;
8929     u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8930     u32 crypto_alg = 0, integ_alg = 0;
8931     ip4_address_t tun_src4;
8932     ip4_address_t tun_dst4;
8933     ip6_address_t tun_src6;
8934     ip6_address_t tun_dst6;
8935
8936     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8937         if (unformat (i, "del"))
8938             is_add = 0;
8939         else if (unformat (i, "sad_id %d", &sad_id))
8940             ;
8941         else if (unformat (i, "spi %d", &spi))
8942             ;
8943         else if (unformat (i, "esp"))
8944             protocol = IPSEC_PROTOCOL_ESP;
8945         else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8946             is_tunnel = 1;
8947             is_tunnel_ipv6 = 0;
8948         }
8949         else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8950             is_tunnel = 1;
8951             is_tunnel_ipv6 = 0;
8952         }
8953         else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8954             is_tunnel = 1;
8955             is_tunnel_ipv6 = 1;
8956         }
8957         else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8958             is_tunnel = 1;
8959             is_tunnel_ipv6 = 1;
8960         }
8961         else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8962             if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8963                 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8964                 clib_warning ("unsupported crypto-alg: '%U'",
8965                               format_ipsec_crypto_alg, crypto_alg);
8966                 return -99;
8967             }
8968         }
8969         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8970             ;
8971         else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8972             if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8973                 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8974                 clib_warning ("unsupported integ-alg: '%U'",
8975                               format_ipsec_integ_alg, integ_alg);
8976                 return -99;
8977             }
8978         }
8979         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8980             ;
8981         else {
8982             clib_warning ("parse error '%U'", format_unformat_error, i);
8983             return -99;
8984         }
8985
8986     }
8987
8988     M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8989
8990     mp->sad_id = ntohl(sad_id);
8991     mp->is_add = is_add;
8992     mp->protocol = protocol;
8993     mp->spi = ntohl(spi);
8994     mp->is_tunnel = is_tunnel;
8995     mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8996     mp->crypto_algorithm = crypto_alg;
8997     mp->integrity_algorithm = integ_alg;
8998     mp->crypto_key_length = vec_len(ck);
8999     mp->integrity_key_length = vec_len(ik);
9000
9001     if (mp->crypto_key_length > sizeof(mp->crypto_key))
9002       mp->crypto_key_length = sizeof(mp->crypto_key);
9003
9004     if (mp->integrity_key_length > sizeof(mp->integrity_key))
9005       mp->integrity_key_length = sizeof(mp->integrity_key);
9006
9007     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9008     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
9009
9010     if (is_tunnel) {
9011       if (is_tunnel_ipv6) {
9012         clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
9013         clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
9014       } else {
9015         clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
9016         clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
9017       }
9018     }
9019
9020     S; W;
9021     /* NOTREACHED */
9022     return 0;
9023 #else
9024     clib_warning ("unsupported (no dpdk)");
9025     return -99;
9026 #endif
9027 }
9028
9029 static int
9030 api_ipsec_sa_set_key (vat_main_t * vam)
9031 {
9032 #if DPDK > 0
9033     unformat_input_t * i = vam->input;
9034     vl_api_ipsec_sa_set_key_t *mp;
9035     f64 timeout;
9036     u32 sa_id;
9037     u8 * ck, * ik;
9038
9039     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9040         if (unformat (i, "sa_id %d", &sa_id))
9041             ;
9042         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
9043             ;
9044         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
9045             ;
9046         else {
9047             clib_warning ("parse error '%U'", format_unformat_error, i);
9048             return -99;
9049         }
9050     }
9051
9052     M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
9053
9054     mp->sa_id = ntohl(sa_id);
9055     mp->crypto_key_length = vec_len(ck);
9056     mp->integrity_key_length = vec_len(ik);
9057
9058     if (mp->crypto_key_length > sizeof(mp->crypto_key))
9059       mp->crypto_key_length = sizeof(mp->crypto_key);
9060
9061     if (mp->integrity_key_length > sizeof(mp->integrity_key))
9062       mp->integrity_key_length = sizeof(mp->integrity_key);
9063
9064     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
9065     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
9066
9067     S; W;
9068     /* NOTREACHED */
9069     return 0;
9070 #else
9071     clib_warning ("unsupported (no dpdk)");
9072     return -99;
9073 #endif
9074 }
9075
9076 static int
9077 api_ikev2_profile_add_del (vat_main_t * vam)
9078 {
9079 #if DPDK > 0
9080     unformat_input_t * i = vam->input;
9081     vl_api_ikev2_profile_add_del_t * mp;
9082     f64 timeout;
9083     u8 is_add = 1;
9084     u8 * name = 0;
9085
9086     const char * valid_chars = "a-zA-Z0-9_";
9087
9088     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9089         if (unformat (i, "del"))
9090             is_add = 0;
9091         else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9092             vec_add1 (name, 0);
9093         else {
9094             errmsg ("parse error '%U'", format_unformat_error, i);
9095             return -99;
9096         }
9097     }
9098
9099     if (!vec_len (name)) {
9100         errmsg ("profile name must be specified");
9101         return -99;
9102     }
9103
9104     if (vec_len (name) > 64) {
9105         errmsg ("profile name too long");
9106         return -99;
9107     }
9108
9109     M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
9110
9111     clib_memcpy(mp->name, name, vec_len (name));
9112     mp->is_add = is_add;
9113     vec_free (name);
9114
9115     S; W;
9116     /* NOTREACHED */
9117     return 0;
9118 #else
9119     clib_warning ("unsupported (no dpdk)");
9120     return -99;
9121 #endif
9122 }
9123
9124 static int
9125 api_ikev2_profile_set_auth (vat_main_t * vam)
9126 {
9127 #if DPDK > 0
9128     unformat_input_t * i = vam->input;
9129     vl_api_ikev2_profile_set_auth_t * mp;
9130     f64 timeout;
9131     u8 * name = 0;
9132     u8 * data = 0;
9133     u32 auth_method = 0;
9134     u8 is_hex = 0;
9135
9136     const char * valid_chars = "a-zA-Z0-9_";
9137
9138     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9139         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9140             vec_add1 (name, 0);
9141         else if (unformat (i, "auth_method %U",
9142                            unformat_ikev2_auth_method, &auth_method))
9143             ;
9144         else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9145             is_hex = 1;
9146         else if (unformat (i, "auth_data %v", &data))
9147             ;
9148         else {
9149             errmsg ("parse error '%U'", format_unformat_error, i);
9150             return -99;
9151         }
9152     }
9153
9154     if (!vec_len (name)) {
9155         errmsg ("profile name must be specified");
9156         return -99;
9157     }
9158
9159     if (vec_len (name) > 64) {
9160         errmsg ("profile name too long");
9161         return -99;
9162     }
9163
9164     if (!vec_len(data)) {
9165         errmsg ("auth_data must be specified");
9166         return -99;
9167     }
9168
9169     if (!auth_method) {
9170         errmsg ("auth_method must be specified");
9171         return -99;
9172     }
9173
9174     M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9175
9176     mp->is_hex = is_hex;
9177     mp->auth_method = (u8) auth_method;
9178     mp->data_len = vec_len (data);
9179     clib_memcpy (mp->name, name, vec_len (name));
9180     clib_memcpy (mp->data, data, vec_len (data));
9181     vec_free (name);
9182     vec_free (data);
9183
9184     S; W;
9185     /* NOTREACHED */
9186     return 0;
9187 #else
9188     clib_warning ("unsupported (no dpdk)");
9189     return -99;
9190 #endif
9191 }
9192
9193 static int
9194 api_ikev2_profile_set_id (vat_main_t * vam)
9195 {
9196 #if DPDK > 0
9197     unformat_input_t * i = vam->input;
9198     vl_api_ikev2_profile_set_id_t * mp;
9199     f64 timeout;
9200     u8 * name = 0;
9201     u8 * data = 0;
9202     u8 is_local = 0;
9203     u32 id_type = 0;
9204     ip4_address_t ip4;
9205
9206     const char * valid_chars = "a-zA-Z0-9_";
9207
9208     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9209         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9210             vec_add1 (name, 0);
9211         else if (unformat (i, "id_type %U",
9212                            unformat_ikev2_id_type, &id_type))
9213             ;
9214         else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9215           {
9216             data = vec_new(u8, 4);
9217             clib_memcpy(data, ip4.as_u8, 4);
9218           }
9219         else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9220             ;
9221         else if (unformat (i, "id_data %v", &data))
9222             ;
9223         else if (unformat (i, "local"))
9224             is_local = 1;
9225         else if (unformat (i, "remote"))
9226             is_local = 0;
9227         else {
9228             errmsg ("parse error '%U'", format_unformat_error, i);
9229             return -99;
9230         }
9231     }
9232
9233     if (!vec_len (name)) {
9234         errmsg ("profile name must be specified");
9235         return -99;
9236     }
9237
9238     if (vec_len (name) > 64) {
9239         errmsg ("profile name too long");
9240         return -99;
9241     }
9242
9243     if (!vec_len(data)) {
9244         errmsg ("id_data must be specified");
9245         return -99;
9246     }
9247
9248     if (!id_type) {
9249         errmsg ("id_type must be specified");
9250         return -99;
9251     }
9252
9253     M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9254
9255     mp->is_local = is_local;
9256     mp->id_type = (u8) id_type;
9257     mp->data_len = vec_len (data);
9258     clib_memcpy (mp->name, name, vec_len (name));
9259     clib_memcpy (mp->data, data, vec_len (data));
9260     vec_free (name);
9261     vec_free (data);
9262
9263     S; W;
9264     /* NOTREACHED */
9265     return 0;
9266 #else
9267     clib_warning ("unsupported (no dpdk)");
9268     return -99;
9269 #endif
9270 }
9271
9272 static int
9273 api_ikev2_profile_set_ts (vat_main_t * vam)
9274 {
9275 #if DPDK > 0
9276     unformat_input_t * i = vam->input;
9277     vl_api_ikev2_profile_set_ts_t * mp;
9278     f64 timeout;
9279     u8 * name = 0;
9280     u8 is_local = 0;
9281     u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9282     ip4_address_t start_addr, end_addr;
9283
9284     const char * valid_chars = "a-zA-Z0-9_";
9285
9286     start_addr.as_u32 = 0;
9287     end_addr.as_u32 = (u32) ~0;
9288
9289     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9290         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9291             vec_add1 (name, 0);
9292         else if (unformat (i, "protocol %d", &proto))
9293             ;
9294         else if (unformat (i, "start_port %d", &start_port))
9295             ;
9296         else if (unformat (i, "end_port %d", &end_port))
9297             ;
9298         else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9299             ;
9300         else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9301             ;
9302         else if (unformat (i, "local"))
9303             is_local = 1;
9304         else if (unformat (i, "remote"))
9305             is_local = 0;
9306         else {
9307             errmsg ("parse error '%U'", format_unformat_error, i);
9308             return -99;
9309         }
9310     }
9311
9312     if (!vec_len (name)) {
9313         errmsg ("profile name must be specified");
9314         return -99;
9315     }
9316
9317     if (vec_len (name) > 64) {
9318         errmsg ("profile name too long");
9319         return -99;
9320     }
9321
9322     M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9323
9324     mp->is_local = is_local;
9325     mp->proto = (u8) proto;
9326     mp->start_port = (u16) start_port;
9327     mp->end_port = (u16) end_port;
9328     mp->start_addr = start_addr.as_u32;
9329     mp->end_addr = end_addr.as_u32;
9330     clib_memcpy (mp->name, name, vec_len (name));
9331     vec_free (name);
9332
9333     S; W;
9334     /* NOTREACHED */
9335     return 0;
9336 #else
9337     clib_warning ("unsupported (no dpdk)");
9338     return -99;
9339 #endif
9340 }
9341
9342 static int
9343 api_ikev2_set_local_key (vat_main_t * vam)
9344 {
9345 #if DPDK > 0
9346     unformat_input_t * i = vam->input;
9347     vl_api_ikev2_set_local_key_t * mp;
9348     f64 timeout;
9349     u8 * file = 0;
9350
9351     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9352         if (unformat (i, "file %v", &file))
9353             vec_add1 (file, 0);
9354         else {
9355             errmsg ("parse error '%U'", format_unformat_error, i);
9356             return -99;
9357         }
9358     }
9359
9360     if (!vec_len (file)) {
9361         errmsg ("RSA key file must be specified");
9362         return -99;
9363     }
9364
9365     if (vec_len (file) > 256) {
9366         errmsg ("file name too long");
9367         return -99;
9368     }
9369
9370     M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9371
9372     clib_memcpy (mp->key_file, file, vec_len (file));
9373     vec_free (file);
9374
9375     S; W;
9376     /* NOTREACHED */
9377     return 0;
9378 #else
9379     clib_warning ("unsupported (no dpdk)");
9380     return -99;
9381 #endif
9382 }
9383
9384 /*
9385  * MAP
9386  */
9387 static int api_map_add_domain (vat_main_t * vam)
9388 {
9389   unformat_input_t *i = vam->input;
9390   vl_api_map_add_domain_t *mp;
9391   f64 timeout;
9392
9393   ip4_address_t ip4_prefix;
9394   ip6_address_t ip6_prefix;
9395   ip6_address_t ip6_src;
9396   u32 num_m_args = 0;
9397   u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9398     psid_length;
9399   u8 is_translation = 0;
9400   u32 mtu = 0;
9401   u8 ip6_src_len = 128;
9402
9403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9404     if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9405                   &ip4_prefix, &ip4_prefix_len))
9406       num_m_args++;
9407     else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9408                        &ip6_prefix, &ip6_prefix_len))
9409       num_m_args++;
9410     else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9411       num_m_args++;
9412     else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9413       num_m_args++;
9414     else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9415       num_m_args++;
9416     else if (unformat (i, "psid-offset %d", &psid_offset))
9417       num_m_args++;
9418     else if (unformat (i, "psid-len %d", &psid_length))
9419       num_m_args++;
9420     else if (unformat (i, "mtu %d", &mtu))
9421       num_m_args++;
9422     else if (unformat (i, "map-t"))
9423       is_translation = 1;
9424     else {
9425       clib_warning ("parse error '%U'", format_unformat_error, i);
9426       return -99;
9427     }
9428   }
9429
9430   if (num_m_args != 6) {
9431     errmsg("mandatory argument(s) missing\n");
9432     return -99;
9433   }
9434
9435   /* Construct the API message */
9436   M(MAP_ADD_DOMAIN, map_add_domain);
9437
9438   clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
9439   mp->ip4_prefix_len = ip4_prefix_len;
9440
9441   clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
9442   mp->ip6_prefix_len = ip6_prefix_len;
9443
9444   clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
9445   mp->ip6_src_prefix_len = ip6_src_len;
9446
9447   mp->ea_bits_len = ea_bits_len;
9448   mp->psid_offset = psid_offset;
9449   mp->psid_length = psid_length;
9450   mp->is_translation = is_translation;
9451   mp->mtu = htons(mtu);
9452
9453   /* send it... */
9454   S;
9455
9456   /* Wait for a reply, return good/bad news  */
9457   W;
9458 }
9459
9460 static int api_map_del_domain (vat_main_t * vam)
9461 {
9462   unformat_input_t *i = vam->input;
9463   vl_api_map_del_domain_t *mp;
9464   f64 timeout;
9465
9466   u32 num_m_args = 0;
9467   u32 index;
9468
9469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9470     if (unformat (i, "index %d", &index))
9471       num_m_args++;
9472     else {
9473       clib_warning ("parse error '%U'", format_unformat_error, i);
9474       return -99;
9475     }
9476   }
9477
9478   if (num_m_args != 1) {
9479     errmsg("mandatory argument(s) missing\n");
9480     return -99;
9481   }
9482
9483   /* Construct the API message */
9484   M(MAP_DEL_DOMAIN, map_del_domain);
9485
9486   mp->index = ntohl(index);
9487
9488   /* send it... */
9489   S;
9490
9491   /* Wait for a reply, return good/bad news  */
9492   W;
9493 }
9494
9495 static int api_map_add_del_rule (vat_main_t * vam)
9496 {
9497   unformat_input_t *i = vam->input;
9498   vl_api_map_add_del_rule_t *mp;
9499   f64 timeout;
9500   u8 is_add = 1;
9501   ip6_address_t ip6_dst;
9502   u32 num_m_args = 0, index, psid;
9503
9504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9505     if (unformat (i, "index %d", &index))
9506       num_m_args++;
9507     else if (unformat (i, "psid %d", &psid))
9508       num_m_args++;
9509     else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9510       num_m_args++;
9511     else if (unformat (i, "del")) {
9512       is_add = 0;
9513     } else {
9514       clib_warning ("parse error '%U'", format_unformat_error, i);
9515       return -99;
9516     }
9517   }
9518
9519   /* Construct the API message */
9520   M(MAP_ADD_DEL_RULE, map_add_del_rule);
9521
9522   mp->index = ntohl(index);
9523   mp->is_add = is_add;
9524   clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
9525   mp->psid = ntohs(psid);
9526
9527   /* send it... */
9528   S;
9529
9530   /* Wait for a reply, return good/bad news  */
9531   W;
9532 }
9533
9534 static int api_map_domain_dump (vat_main_t * vam)
9535 {
9536     vl_api_map_domain_dump_t *mp;
9537     f64 timeout;
9538
9539     /* Construct the API message */
9540     M(MAP_DOMAIN_DUMP, map_domain_dump);
9541
9542     /* send it... */
9543     S;
9544
9545     /* Use a control ping for synchronization */
9546     {
9547         vl_api_control_ping_t * mp;
9548         M(CONTROL_PING, control_ping);
9549         S;
9550     }
9551     W;
9552 }
9553
9554 static int api_map_rule_dump (vat_main_t * vam)
9555 {
9556     unformat_input_t *i = vam->input;
9557     vl_api_map_rule_dump_t *mp;
9558     f64 timeout;
9559     u32 domain_index = ~0;
9560
9561     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9562         if (unformat (i, "index %u", &domain_index))
9563             ;
9564         else
9565             break;
9566     }
9567
9568     if (domain_index == ~0) {
9569         clib_warning("parse error: domain index expected");
9570         return -99;
9571     }
9572
9573     /* Construct the API message */
9574     M(MAP_RULE_DUMP, map_rule_dump);
9575
9576     mp->domain_index = htonl(domain_index);
9577
9578     /* send it... */
9579     S;
9580
9581     /* Use a control ping for synchronization */
9582     {
9583         vl_api_control_ping_t * mp;
9584         M(CONTROL_PING, control_ping);
9585         S;
9586     }
9587     W;
9588 }
9589
9590 static void vl_api_map_add_domain_reply_t_handler
9591 (vl_api_map_add_domain_reply_t * mp)
9592 {
9593   vat_main_t * vam = &vat_main;
9594   i32 retval = ntohl(mp->retval);
9595
9596   if (vam->async_mode) {
9597       vam->async_errors += (retval < 0);
9598   } else {
9599       vam->retval = retval;
9600       vam->result_ready = 1;
9601   }
9602 }
9603
9604 static void vl_api_map_add_domain_reply_t_handler_json
9605 (vl_api_map_add_domain_reply_t * mp)
9606 {
9607   vat_main_t * vam = &vat_main;
9608   vat_json_node_t node;
9609
9610   vat_json_init_object(&node);
9611   vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9612   vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9613
9614   vat_json_print(vam->ofp, &node);
9615   vat_json_free(&node);
9616
9617   vam->retval = ntohl(mp->retval);
9618   vam->result_ready = 1;
9619 }
9620
9621 static int
9622 api_get_first_msg_id (vat_main_t * vam)
9623 {
9624     vl_api_get_first_msg_id_t * mp;
9625     f64 timeout;
9626     unformat_input_t * i = vam->input;
9627     u8 * name;
9628     u8 name_set = 0;
9629     
9630     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9631         if (unformat (i, "client %s", &name))
9632             name_set = 1;
9633         else 
9634             break;
9635     }
9636
9637     if (name_set == 0) {
9638         errmsg ("missing client name\n");
9639         return -99;
9640     }
9641     vec_add1 (name, 0);
9642
9643     if (vec_len (name) > 63) {
9644         errmsg ("client name too long\n");
9645         return -99;
9646     }
9647
9648     M(GET_FIRST_MSG_ID, get_first_msg_id);
9649     clib_memcpy (mp->name, name, vec_len(name));
9650     S; W;
9651     /* NOTREACHED */
9652     return 0;
9653 }
9654
9655 static int api_cop_interface_enable_disable (vat_main_t * vam)
9656 {
9657     unformat_input_t * line_input = vam->input;
9658     vl_api_cop_interface_enable_disable_t * mp;
9659     f64 timeout;
9660     u32 sw_if_index = ~0;
9661     u8 enable_disable = 1;
9662
9663     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9664         if (unformat (line_input, "disable"))
9665             enable_disable = 0;
9666         if (unformat (line_input, "enable"))
9667             enable_disable = 1;
9668         else if (unformat (line_input, "%U", unformat_sw_if_index,
9669                            vam, &sw_if_index))
9670             ;
9671         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9672             ;
9673         else
9674             break;
9675     }
9676         
9677     if (sw_if_index == ~0) {
9678         errmsg ("missing interface name or sw_if_index\n");
9679         return -99;
9680     }
9681
9682     /* Construct the API message */
9683     M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9684     mp->sw_if_index = ntohl(sw_if_index);
9685     mp->enable_disable = enable_disable;
9686
9687     /* send it... */
9688     S;
9689     /* Wait for the reply */
9690     W;
9691 }
9692
9693 static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9694 {
9695     unformat_input_t * line_input = vam->input;
9696     vl_api_cop_whitelist_enable_disable_t * mp;
9697     f64 timeout;
9698     u32 sw_if_index = ~0;
9699     u8 ip4=0, ip6=0, default_cop=0;
9700     u32 fib_id;
9701
9702     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9703         if (unformat (line_input, "ip4"))
9704             ip4 = 1;
9705         else if (unformat (line_input, "ip6"))
9706             ip6 = 1;
9707         else if (unformat (line_input, "default"))
9708             default_cop = 1;
9709         else if (unformat (line_input, "%U", unformat_sw_if_index,
9710                            vam, &sw_if_index))
9711             ;
9712         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9713             ;
9714         else if (unformat (line_input, "fib-id %d", &fib_id))
9715             ;
9716         else
9717             break;
9718     }
9719         
9720     if (sw_if_index == ~0) {
9721         errmsg ("missing interface name or sw_if_index\n");
9722         return -99;
9723     }
9724
9725     /* Construct the API message */
9726     M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9727     mp->sw_if_index = ntohl(sw_if_index);
9728     mp->fib_id = ntohl(fib_id);
9729     mp->ip4 = ip4;
9730     mp->ip6 = ip6;
9731     mp->default_cop = default_cop;
9732
9733     /* send it... */
9734     S;
9735     /* Wait for the reply */
9736     W;
9737 }
9738
9739 static int api_get_node_graph (vat_main_t * vam)
9740 {
9741     vl_api_get_node_graph_t * mp;
9742     f64 timeout;
9743
9744     M(GET_NODE_GRAPH, get_node_graph);
9745
9746     /* send it... */
9747     S;
9748     /* Wait for the reply */
9749     W;
9750 }
9751
9752 static int
9753 api_lisp_add_del_locator_set(vat_main_t * vam)
9754 {
9755     unformat_input_t * input = vam->input;
9756     vl_api_lisp_add_del_locator_set_t *mp;
9757     f64 timeout = ~0;
9758     u8  is_add = 1;
9759     u8 *locator_set_name = NULL;
9760     u8  locator_set_name_set = 0;
9761
9762     /* Parse args required to build the message */
9763     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9764         if (unformat(input, "del")) {
9765             is_add = 0;
9766         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9767             locator_set_name_set = 1;
9768         } else
9769             break;
9770     }
9771
9772     if (locator_set_name_set == 0) {
9773         errmsg ("missing locator-set name");
9774         return -99;
9775     }
9776
9777     if (vec_len(locator_set_name) > 64) {
9778         errmsg ("locator-set name too long\n");
9779         vec_free(locator_set_name);
9780         return -99;
9781     }
9782     vec_add1(locator_set_name, 0);
9783
9784     /* Construct the API message */
9785     M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9786
9787     mp->is_add = is_add;
9788     clib_memcpy(mp->locator_set_name, locator_set_name,
9789            vec_len(locator_set_name));
9790     vec_free(locator_set_name);
9791
9792     /* send it... */
9793     S;
9794
9795     /* Wait for a reply... */
9796     W;
9797
9798     /* NOTREACHED */
9799     return 0;
9800 }
9801
9802 static int
9803 api_lisp_add_del_locator(vat_main_t * vam)
9804 {
9805     unformat_input_t * input = vam->input;
9806     vl_api_lisp_add_del_locator_t *mp;
9807     f64 timeout = ~0;
9808     u32 tmp_if_index = ~0;
9809     u32 sw_if_index = ~0;
9810     u8  sw_if_index_set = 0;
9811     u8  sw_if_index_if_name_set = 0;
9812     u8  priority = ~0;
9813     u8  priority_set = 0;
9814     u8  weight = ~0;
9815     u8  weight_set = 0;
9816     u8  is_add = 1;
9817     u8  *locator_set_name = NULL;
9818     u8  locator_set_name_set = 0;
9819
9820     /* Parse args required to build the message */
9821     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9822         if (unformat(input, "del")) {
9823             is_add = 0;
9824         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9825             locator_set_name_set = 1;
9826         } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9827             &tmp_if_index)) {
9828             sw_if_index_if_name_set = 1;
9829             sw_if_index = tmp_if_index;
9830         } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9831             sw_if_index_set = 1;
9832             sw_if_index = tmp_if_index;
9833         } else if (unformat(input, "p %d", &priority)) {
9834             priority_set = 1;
9835         } else if (unformat(input, "w %d", &weight)) {
9836             weight_set = 1;
9837         } else
9838             break;
9839     }
9840
9841     if (locator_set_name_set == 0) {
9842         errmsg ("missing locator-set name");
9843         return -99;
9844     }
9845
9846     if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9847         errmsg ("missing sw_if_index");
9848         vec_free(locator_set_name);
9849         return -99;
9850     }
9851
9852     if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9853         errmsg ("cannot use both params interface name and sw_if_index");
9854         vec_free(locator_set_name);
9855         return -99;
9856     }
9857
9858     if (priority_set == 0) {
9859         errmsg ("missing locator-set priority\n");
9860         vec_free(locator_set_name);
9861         return -99;
9862     }
9863
9864     if (weight_set == 0) {
9865         errmsg ("missing locator-set weight\n");
9866         vec_free(locator_set_name);
9867         return -99;
9868     }
9869
9870     if (vec_len(locator_set_name) > 64) {
9871         errmsg ("locator-set name too long\n");
9872         vec_free(locator_set_name);
9873         return -99;
9874     }
9875     vec_add1(locator_set_name, 0);
9876
9877     /* Construct the API message */
9878     M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9879
9880     mp->is_add = is_add;
9881     mp->sw_if_index = ntohl(sw_if_index);
9882     mp->priority = priority;
9883     mp->weight = weight;
9884     clib_memcpy(mp->locator_set_name, locator_set_name,
9885            vec_len(locator_set_name));
9886     vec_free(locator_set_name);
9887
9888     /* send it... */
9889     S;
9890
9891     /* Wait for a reply... */
9892     W;
9893
9894     /* NOTREACHED */
9895     return 0;
9896 }
9897
9898 static int
9899 api_lisp_add_del_local_eid(vat_main_t * vam)
9900 {
9901     unformat_input_t * input = vam->input;
9902     vl_api_lisp_add_del_local_eid_t *mp;
9903     f64 timeout = ~0;
9904     u8 is_add = 1;
9905     u8 eidv4_set = 0;
9906     u8 eidv6_set = 0;
9907     ip4_address_t eidv4;
9908     ip6_address_t eidv6;
9909     u8 tmp_eid_lenght = ~0;
9910     u8 eid_lenght = ~0;
9911     u8 *locator_set_name = NULL;
9912     u8 locator_set_name_set = 0;
9913
9914     /* Parse args required to build the message */
9915     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9916         if (unformat(input, "del")) {
9917             is_add = 0;
9918         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9919             &eidv4, &tmp_eid_lenght)) {
9920             eid_lenght = tmp_eid_lenght;
9921             eidv4_set = 1;
9922         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9923             &eidv6, &tmp_eid_lenght)) {
9924             eid_lenght = tmp_eid_lenght;
9925             eidv6_set = 1;
9926         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9927             locator_set_name_set = 1;
9928         } else
9929             break;
9930     }
9931
9932     if (locator_set_name_set == 0) {
9933         errmsg ("missing locator-set name\n");
9934         return -99;
9935     }
9936
9937     if (vec_len(locator_set_name) > 64) {
9938         errmsg ("locator-set name too long\n");
9939         vec_free(locator_set_name);
9940         return -99;
9941     }
9942     vec_add1(locator_set_name, 0);
9943
9944     if (eidv4_set && eidv6_set) {
9945         errmsg ("both eid v4 and v6 addresses set\n");
9946         vec_free(locator_set_name);
9947         return -99;
9948     }
9949
9950     if (!eidv4_set && !eidv6_set) {
9951         errmsg ("eid addresses not set\n");
9952         vec_free(locator_set_name);
9953         return -99;
9954     }
9955
9956     if (eidv4_set && eid_lenght > 32) {
9957         errmsg ("eid prefix to big\n");
9958         vec_free(locator_set_name);
9959         return -99;
9960     }
9961
9962     if (eidv6_set && eid_lenght > 128) {
9963         errmsg ("eid prefix to big\n");
9964         vec_free(locator_set_name);
9965         return -99;
9966     }
9967
9968     /* Construct the API message */
9969     M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9970
9971     mp->is_add = is_add;
9972     if (eidv6_set) {
9973         mp->is_ipv6 = 1;
9974         clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
9975     } else {
9976         mp->is_ipv6 = 0;
9977         clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
9978     }
9979     mp->prefix_len = eid_lenght;
9980     clib_memcpy(mp->locator_set_name, locator_set_name,
9981            vec_len(locator_set_name));
9982     vec_free(locator_set_name);
9983
9984     /* send it... */
9985     S;
9986
9987     /* Wait for a reply... */
9988     W;
9989
9990     /* NOTREACHED */
9991     return 0;
9992 }
9993
9994 static int
9995 api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9996 {
9997     unformat_input_t * input = vam->input;
9998     vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9999     f64 timeout = ~0;
10000     u8 is_add = 1;
10001     u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
10002     u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
10003     ip4_address_t eidv4, slocv4, dlocv4;
10004     ip6_address_t eidv6, slocv6, dlocv6;
10005     u8 tmp_eid_lenght = ~0;
10006     u8 eid_lenght = ~0;
10007
10008     /* Parse args required to build the message */
10009     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10010         if (unformat(input, "del")) {
10011             is_add = 0;
10012         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
10013                             &eidv4, &tmp_eid_lenght)) {
10014             eid_lenght = tmp_eid_lenght;
10015             eidv4_set = 1;
10016         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
10017                             &eidv6, &tmp_eid_lenght)) {
10018             eid_lenght = tmp_eid_lenght;
10019             eidv6_set = 1;
10020         } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
10021             slocv4_set = 1;
10022         } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
10023             slocv6_set = 1;
10024         } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
10025             dlocv4_set = 1;
10026         } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
10027             dlocv6_set = 1;
10028         } else
10029             break;
10030     }
10031
10032     if (eidv4_set && eidv6_set) {
10033         errmsg ("both eid v4 and v6 addresses set\n");
10034         return -99;
10035     }
10036
10037     if (!eidv4_set && !eidv6_set) {
10038         errmsg ("eid addresses not set\n");
10039         return -99;
10040     }
10041
10042     if (slocv4_set && slocv6_set) {
10043         errmsg ("both source v4 and v6 addresses set\n");
10044         return -99;
10045     }
10046
10047     if (!slocv4_set && !slocv6_set) {
10048         errmsg ("source addresses not set\n");
10049         return -99;
10050     }
10051
10052     if (dlocv4_set && dlocv6_set) {
10053         errmsg ("both destination v4 and v6 addresses set\n");
10054         return -99;
10055     }
10056
10057     if (dlocv4_set && dlocv6_set) {
10058         errmsg ("destination addresses not set\n");
10059         return -99;
10060     }
10061
10062     if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
10063         errmsg ("mixing type of source and destination address\n");
10064         return -99;
10065     }
10066
10067     /* Construct the API message */
10068     M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
10069
10070     mp->is_add = is_add;
10071     if (eidv6_set) {
10072         mp->eid_is_ipv6 = 1;
10073         clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
10074     } else {
10075         mp->eid_is_ipv6 = 0;
10076         clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
10077     }
10078     mp->eid_prefix_len = eid_lenght;
10079     if (slocv6_set) {
10080         mp->address_is_ipv6 = 1;
10081         clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
10082         clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
10083     } else {
10084         mp->address_is_ipv6 = 0;
10085         clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
10086         clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
10087     }
10088
10089     /* send it... */
10090     S;
10091
10092     /* Wait for a reply... */
10093     W;
10094
10095     /* NOTREACHED */
10096     return 0;
10097 }
10098
10099 static int
10100 api_lisp_add_del_map_resolver(vat_main_t * vam)
10101 {
10102     unformat_input_t * input = vam->input;
10103     vl_api_lisp_add_del_map_resolver_t *mp;
10104     f64 timeout = ~0;
10105     u8 is_add = 1;
10106     u8 ipv4_set = 0;
10107     u8 ipv6_set = 0;
10108     ip4_address_t ipv4;
10109     ip6_address_t ipv6;
10110
10111     /* Parse args required to build the message */
10112     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10113         if (unformat(input, "del")) {
10114             is_add = 0;
10115         } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
10116             ipv4_set = 1;
10117         } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
10118             ipv6_set = 1;
10119         } else
10120             break;
10121     }
10122
10123     if (ipv4_set && ipv6_set) {
10124         errmsg ("both eid v4 and v6 addresses set\n");
10125         return -99;
10126     }
10127
10128     if (!ipv4_set && !ipv6_set) {
10129         errmsg ("eid addresses not set\n");
10130         return -99;
10131     }
10132
10133     /* Construct the API message */
10134     M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10135
10136     mp->is_add = is_add;
10137     if (ipv6_set) {
10138         mp->is_ipv6 = 1;
10139         clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
10140     } else {
10141         mp->is_ipv6 = 0;
10142         clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
10143     }
10144
10145     /* send it... */
10146     S;
10147
10148     /* Wait for a reply... */
10149     W;
10150
10151     /* NOTREACHED */
10152     return 0;
10153 }
10154
10155 static int
10156 api_lisp_gpe_enable_disable (vat_main_t * vam)
10157 {
10158   unformat_input_t * input = vam->input;
10159   vl_api_lisp_gpe_enable_disable_t *mp;
10160   f64 timeout = ~0;
10161   u8 is_set = 0;
10162   u8 is_en = 1;
10163
10164   /* Parse args required to build the message */
10165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10166       if (unformat(input, "enable")) {
10167           is_set = 1;
10168           is_en = 1;
10169       } else if (unformat(input, "disable")) {
10170           is_set = 1;
10171           is_en = 0;
10172       } else
10173           break;
10174   }
10175
10176   if (is_set == 0) {
10177       errmsg("Value not set\n");
10178       return -99;
10179   }
10180
10181   /* Construct the API message */
10182   M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10183
10184   mp->is_en = is_en;
10185
10186   /* send it... */
10187   S;
10188
10189   /* Wait for a reply... */
10190   W;
10191
10192   /* NOTREACHED */
10193   return 0;
10194 }
10195
10196 static int
10197 api_lisp_enable_disable (vat_main_t * vam)
10198 {
10199   unformat_input_t * input = vam->input;
10200   vl_api_lisp_enable_disable_t *mp;
10201   f64 timeout = ~0;
10202   u8 is_set = 0;
10203   u8 is_en = 0;
10204
10205   /* Parse args required to build the message */
10206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (input, "enable"))
10209         {
10210           is_set = 1;
10211           is_en = 1;
10212         }
10213       else if (unformat (input, "disable"))
10214         {
10215           is_set = 1;
10216         }
10217       else
10218           break;
10219     }
10220
10221   if (!is_set)
10222     {
10223       errmsg ("Value not set\n");
10224       return -99;
10225     }
10226
10227   /* Construct the API message */
10228   M(LISP_ENABLE_DISABLE, lisp_enable_disable);
10229
10230   mp->is_en = is_en;
10231
10232   /* send it... */
10233   S;
10234
10235   /* Wait for a reply... */
10236   W;
10237
10238   /* NOTREACHED */
10239   return 0;
10240 }
10241
10242 /** Used for transferring locators via VPP API */
10243 typedef CLIB_PACKED(struct
10244 {
10245     u8 is_ip4; /**< is locator an IPv4 address? */
10246     u8 addr[16]; /**< IPv4/IPv6 address */
10247 }) rloc_t;
10248
10249 /**
10250  * Enable/disable LISP proxy ITR.
10251  *
10252  * @param vam vpp API test context
10253  * @return return code
10254  */
10255 static int
10256 api_lisp_pitr_set_locator_set (vat_main_t * vam)
10257 {
10258   f64 timeout = ~0;
10259   u8 ls_name_set = 0;
10260   unformat_input_t * input = vam->input;
10261   vl_api_lisp_pitr_set_locator_set_t * mp;
10262   u8 is_add = 1;
10263   u8 * ls_name = 0;
10264
10265   /* Parse args required to build the message */
10266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10267     {
10268       if (unformat (input, "del"))
10269         is_add = 0;
10270       else if (unformat (input, "locator-set %s", &ls_name))
10271         ls_name_set = 1;
10272       else
10273         {
10274           errmsg ("parse error '%U'", format_unformat_error, input);
10275           return -99;
10276         }
10277     }
10278
10279   if (!ls_name_set)
10280     {
10281       errmsg ("locator-set name not set!");
10282       return -99;
10283     }
10284
10285   M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
10286
10287   mp->is_add = is_add;
10288   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
10289   vec_free (ls_name);
10290
10291   /* send */
10292   S;
10293
10294   /* wait for reply */
10295   W;
10296
10297   /* notreached*/
10298   return 0;
10299 }
10300
10301 /**
10302  * Add/del remote mapping from LISP control plane and updates
10303  * forwarding entries in data-plane accordingly.
10304  *
10305  * @param vam vpp API test context
10306  * @return return code
10307  */
10308 static int
10309 api_lisp_add_del_remote_mapping (vat_main_t * vam)
10310 {
10311     unformat_input_t * input = vam->input;
10312     vl_api_lisp_add_del_remote_mapping_t *mp;
10313     f64 timeout = ~0;
10314     u32 vni = 0;
10315     u8 seid_set = 0, deid_set = 0;
10316     ip4_address_t seid4, deid4, rloc4;
10317     ip6_address_t seid6, deid6, rloc6;
10318     u32 seid_len = 0, deid_len = 0, len;
10319     u8 deid_is_ip4 = 0, seid_is_ip4 = 0;
10320     u8 is_add = 1, del_all = 0;
10321     u32 action = ~0;
10322     rloc_t * rlocs = 0, rloc;
10323
10324     /* Parse args required to build the message */
10325     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10326         if (unformat(input, "del-all")) {
10327             del_all = 1;
10328         } else if (unformat(input, "del")) {
10329             is_add = 0;
10330         } else if (unformat(input, "add")) {
10331             is_add = 1;
10332         } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
10333                             &deid4, &len)) {
10334             deid_set = 1;
10335             deid_is_ip4 = 1;
10336             deid_len = len;
10337         } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
10338                             &deid6, &len)) {
10339             deid_set = 1;
10340             deid_is_ip4 = 0;
10341             deid_len = len;
10342         } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
10343                             &seid4, &len)) {
10344             seid_set = 1;
10345             seid_is_ip4 = 1;
10346             seid_len = len;
10347         } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
10348                             &seid6, &len)) {
10349             seid_set = 1;
10350             seid_is_ip4 = 0;
10351             seid_len = len;
10352         } else if (unformat(input, "vni %d", &vni)) {
10353             ;
10354         } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
10355             rloc.is_ip4 = 1;
10356             clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
10357             vec_add1 (rlocs, rloc);
10358         } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
10359             rloc.is_ip4 = 0;
10360             clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
10361             vec_add1 (rlocs, rloc);
10362         } else if (unformat(input, "action %d", &action)) {
10363             ;
10364         } else {
10365             clib_warning ("parse error '%U'", format_unformat_error, input);
10366             return -99;
10367         }
10368     }
10369
10370     if (!seid_set || !deid_set) {
10371         errmsg ("missing params!");
10372         return -99;
10373     }
10374
10375     if (seid_is_ip4 != deid_is_ip4) {
10376         errmsg ("source and destination EIDs are not in " "same IP family!");
10377         return -99;
10378     }
10379
10380     if (is_add && (~0 == action)
10381         && 0 == vec_len (rlocs)) {
10382           errmsg ("no action set for negative map-reply!");
10383           return -99;
10384     }
10385
10386     M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
10387     mp->is_add = is_add;
10388     mp->vni = htonl (vni);
10389     mp->seid_len = seid_len;
10390     mp->action = (u8) action;
10391     mp->deid_len = deid_len;
10392     mp->del_all = del_all;
10393     if (seid_is_ip4) {
10394         mp->eid_is_ip4 = 1;
10395         clib_memcpy (mp->seid, &seid4, sizeof (seid4));
10396     } else {
10397         mp->eid_is_ip4 = 0;
10398         clib_memcpy (mp->seid, &seid6, sizeof (seid6));
10399     }
10400
10401     if (deid_is_ip4) {
10402         mp->eid_is_ip4 = 1;
10403         clib_memcpy (mp->deid, &deid4, sizeof (deid4));
10404     } else {
10405         mp->eid_is_ip4 = 0;
10406         clib_memcpy (mp->deid, &deid6, sizeof (deid6));
10407     }
10408
10409     mp->rloc_num = vec_len (rlocs);
10410     clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
10411     vec_free (rlocs);
10412
10413     /* send it... */
10414     S;
10415
10416     /* Wait for a reply... */
10417     W;
10418
10419     /* NOTREACHED */
10420     return 0;
10421 }
10422
10423 static int
10424 api_lisp_gpe_add_del_iface(vat_main_t * vam)
10425 {
10426     unformat_input_t * input = vam->input;
10427     vl_api_lisp_gpe_add_del_iface_t *mp;
10428     f64 timeout = ~0;
10429     u8 is_set = 0;
10430     u8 is_add = 1;
10431     u32 table_id, vni;
10432
10433     /* Parse args required to build the message */
10434     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10435         if (unformat(input, "up")) {
10436             is_set = 1;
10437             is_add = 1;
10438         } else if (unformat(input, "down")) {
10439             is_set = 1;
10440             is_add = 0;
10441         } else if (unformat(input, "table_id %d", &table_id)) {
10442             ;
10443         } else if (unformat(input, "vni %d", &vni)) {
10444             ;
10445         } else
10446             break;
10447     }
10448
10449     if (is_set == 0) {
10450         errmsg("Value not set\n");
10451         return -99;
10452     }
10453
10454     /* Construct the API message */
10455     M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10456
10457     mp->is_add = is_add;
10458     mp->table_id = table_id;
10459     mp->vni = vni;
10460
10461     /* send it... */
10462     S;
10463
10464     /* Wait for a reply... */
10465     W;
10466
10467     /* NOTREACHED */
10468     return 0;
10469 }
10470
10471 /**
10472  * Add/del map request itr rlocs from LISP control plane and updates
10473  *
10474  * @param vam vpp API test context
10475  * @return return code
10476  */
10477 static int
10478 api_lisp_add_del_map_request_itr_rlocs(vat_main_t * vam)
10479 {
10480     unformat_input_t * input = vam->input;
10481     vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
10482     f64 timeout = ~0;
10483     u8 *locator_set_name = 0;
10484     u8  locator_set_name_set = 0;
10485     u8 is_add = 1;
10486
10487     /* Parse args required to build the message */
10488     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10489         if (unformat(input, "del")) {
10490             is_add = 0;
10491         } else if (unformat(input, "%_%v%_", &locator_set_name)) {
10492             locator_set_name_set = 1;
10493         } else {
10494             clib_warning ("parse error '%U'", format_unformat_error, input);
10495             return -99;
10496         }
10497     }
10498
10499     if (is_add && !locator_set_name_set) {
10500         errmsg ("itr-rloc is not set!");
10501         return -99;
10502     }
10503
10504     if (is_add && vec_len(locator_set_name) > 64) {
10505         errmsg ("itr-rloc locator-set name too long\n");
10506         vec_free(locator_set_name);
10507         return -99;
10508     }
10509
10510     M(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
10511     mp->is_add = is_add;
10512     if (is_add) {
10513       clib_memcpy (mp->locator_set_name , locator_set_name,
10514                    vec_len(locator_set_name));
10515     } else {
10516       memset(mp->locator_set_name, 0, sizeof(mp->locator_set_name));
10517     }
10518     vec_free (locator_set_name);
10519
10520     /* send it... */
10521     S;
10522
10523     /* Wait for a reply... */
10524     W;
10525
10526     /* NOTREACHED */
10527     return 0;
10528 }
10529
10530 static int
10531 api_lisp_locator_set_dump(vat_main_t *vam)
10532 {
10533     vl_api_lisp_locator_set_dump_t *mp;
10534     f64 timeout = ~0;
10535
10536     if (!vam->json_output) {
10537         fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10538                 "Locator-set", "Locator", "Priority", "Weight");
10539     }
10540
10541     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10542     /* send it... */
10543     S;
10544
10545     /* Use a control ping for synchronization */
10546     {
10547         vl_api_control_ping_t * mp;
10548         M(CONTROL_PING, control_ping);
10549         S;
10550     }
10551     /* Wait for a reply... */
10552     W;
10553
10554     /* NOTREACHED */
10555     return 0;
10556 }
10557
10558 static int
10559 api_lisp_local_eid_table_dump(vat_main_t *vam)
10560 {
10561     vl_api_lisp_local_eid_table_dump_t *mp;
10562     f64 timeout = ~0;
10563
10564     if (!vam->json_output) {
10565         fformat(vam->ofp, "%=20s%=30s\n",
10566                 "Locator-set", "Eid");
10567     }
10568
10569     M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
10570     /* send it... */
10571     S;
10572
10573     /* Use a control ping for synchronization */
10574     {
10575         vl_api_control_ping_t * mp;
10576         M(CONTROL_PING, control_ping);
10577         S;
10578     }
10579     /* Wait for a reply... */
10580     W;
10581
10582     /* NOTREACHED */
10583     return 0;
10584 }
10585
10586 static int
10587 api_lisp_gpe_tunnel_dump(vat_main_t *vam)
10588 {
10589     vl_api_lisp_gpe_tunnel_dump_t *mp;
10590     f64 timeout = ~0;
10591
10592     if (!vam->json_output) {
10593         fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
10594                 "%=16s%=16s%=16s%=16s%=16s\n",
10595                 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
10596                 "Decap next", "Lisp version", "Flags", "Next protocol",
10597                 "ver_res", "res", "iid");
10598     }
10599
10600     M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
10601     /* send it... */
10602     S;
10603
10604     /* Use a control ping for synchronization */
10605     {
10606         vl_api_control_ping_t * mp;
10607         M(CONTROL_PING, control_ping);
10608         S;
10609     }
10610     /* Wait for a reply... */
10611     W;
10612
10613     /* NOTREACHED */
10614     return 0;
10615 }
10616
10617 static int
10618 api_lisp_map_resolver_dump(vat_main_t *vam)
10619 {
10620     vl_api_lisp_map_resolver_dump_t *mp;
10621     f64 timeout = ~0;
10622
10623     if (!vam->json_output) {
10624         fformat(vam->ofp, "%=20s\n",
10625                 "Map resolver");
10626     }
10627
10628     M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
10629     /* send it... */
10630     S;
10631
10632     /* Use a control ping for synchronization */
10633     {
10634         vl_api_control_ping_t * mp;
10635         M(CONTROL_PING, control_ping);
10636         S;
10637     }
10638     /* Wait for a reply... */
10639     W;
10640
10641     /* NOTREACHED */
10642     return 0;
10643 }
10644
10645 static int
10646 api_lisp_enable_disable_status_dump(vat_main_t *vam)
10647 {
10648     vl_api_lisp_enable_disable_status_dump_t *mp;
10649     f64 timeout = ~0;
10650
10651     if (!vam->json_output) {
10652         fformat(vam->ofp, "%=20s\n",
10653                 "lisp status:");
10654     }
10655
10656     M(LISP_ENABLE_DISABLE_STATUS_DUMP,
10657       lisp_enable_disable_status_dump);
10658     /* send it... */
10659     S;
10660
10661     /* Use a control ping for synchronization */
10662     {
10663         vl_api_control_ping_t * mp;
10664         M(CONTROL_PING, control_ping);
10665         S;
10666     }
10667     /* Wait for a reply... */
10668     W;
10669
10670     /* NOTREACHED */
10671     return 0;
10672 }
10673
10674 static int
10675 api_lisp_get_map_request_itr_rlocs(vat_main_t *vam)
10676 {
10677     vl_api_lisp_get_map_request_itr_rlocs_t *mp;
10678     f64 timeout = ~0;
10679
10680     if (!vam->json_output) {
10681         fformat(vam->ofp, "%=20s\n",
10682                 "itr-rlocs:");
10683     }
10684
10685     M(LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
10686     /* send it... */
10687     S;
10688     /* Wait for a reply... */
10689     W;
10690
10691     /* NOTREACHED */
10692     return 0;
10693 }
10694
10695 static int
10696 api_af_packet_create (vat_main_t * vam)
10697 {
10698     unformat_input_t * i = vam->input;
10699     vl_api_af_packet_create_t * mp;
10700     f64 timeout;
10701     u8 * host_if_name = 0;
10702     u8 hw_addr[6];
10703     u8 random_hw_addr = 1;
10704
10705     memset (hw_addr, 0, sizeof (hw_addr));
10706
10707     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10708         if (unformat (i, "name %s", &host_if_name))
10709             vec_add1 (host_if_name, 0);
10710         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10711             random_hw_addr = 0;
10712         else
10713           break;
10714     }
10715
10716     if (!vec_len (host_if_name)) {
10717         errmsg ("host-interface name must be specified");
10718         return -99;
10719     }
10720
10721     if (vec_len (host_if_name) > 64) {
10722         errmsg ("host-interface name too long");
10723         return -99;
10724     }
10725
10726     M(AF_PACKET_CREATE, af_packet_create);
10727
10728     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10729     clib_memcpy (mp->hw_addr, hw_addr, 6);
10730     mp->use_random_hw_addr = random_hw_addr;
10731     vec_free (host_if_name);
10732
10733     S; W2(fprintf(vam->ofp," new sw_if_index = %d ", vam->sw_if_index));
10734     /* NOTREACHED */
10735     return 0;
10736 }
10737
10738 static int
10739 api_af_packet_delete (vat_main_t * vam)
10740 {
10741     unformat_input_t * i = vam->input;
10742     vl_api_af_packet_delete_t * mp;
10743     f64 timeout;
10744     u8 * host_if_name = 0;
10745
10746     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10747         if (unformat (i, "name %s", &host_if_name))
10748             vec_add1 (host_if_name, 0);
10749         else
10750           break;
10751     }
10752
10753     if (!vec_len (host_if_name)) {
10754         errmsg ("host-interface name must be specified");
10755         return -99;
10756     }
10757
10758     if (vec_len (host_if_name) > 64) {
10759         errmsg ("host-interface name too long");
10760         return -99;
10761     }
10762
10763     M(AF_PACKET_DELETE, af_packet_delete);
10764
10765     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10766     vec_free (host_if_name);
10767
10768     S; W;
10769     /* NOTREACHED */
10770     return 0;
10771 }
10772
10773 static int
10774 api_policer_add_del (vat_main_t * vam)
10775 {
10776     unformat_input_t * i = vam->input;
10777     vl_api_policer_add_del_t * mp;
10778     f64 timeout;
10779     u8 is_add = 1;
10780     u8 * name = 0;
10781     u32 cir = 0;
10782     u32 eir = 0;
10783     u64 cb = 0;
10784     u64 eb = 0;
10785     u8 rate_type = 0;
10786     u8 round_type = 0;
10787     u8 type = 0;
10788
10789     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10790         if (unformat (i, "del"))
10791             is_add = 0;
10792         else if (unformat (i, "name %s", &name))
10793             vec_add1 (name, 0);
10794         else if (unformat (i, "cir %u", &cir))
10795             ;
10796         else if (unformat (i, "eir %u", &eir))
10797             ;
10798         else if (unformat (i, "cb %u", &cb))
10799             ;
10800         else if (unformat (i, "eb %u", &eb))
10801             ;
10802         else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
10803                            &rate_type))
10804             ;
10805         else if (unformat (i, "round_type %U", unformat_policer_round_type,
10806                            &round_type))
10807             ;
10808         else if (unformat (i, "type %U", unformat_policer_type, &type))
10809             ;
10810         else
10811           break;
10812     }
10813
10814     if (!vec_len (name)) {
10815         errmsg ("policer name must be specified");
10816         return -99;
10817     }
10818
10819     if (vec_len (name) > 64) {
10820         errmsg ("policer name too long");
10821         return -99;
10822     }
10823
10824     M(POLICER_ADD_DEL, policer_add_del);
10825
10826     clib_memcpy (mp->name, name, vec_len (name));
10827     vec_free (name);
10828     mp->is_add = is_add;
10829     mp->cir = cir;
10830     mp->eir = eir;
10831     mp->cb = cb;
10832     mp->eb = eb;
10833     mp->rate_type = rate_type;
10834     mp->round_type = round_type;
10835     mp->type = type;
10836
10837     S; W;
10838     /* NOTREACHED */
10839     return 0;
10840 }
10841
10842 static int
10843 api_policer_dump(vat_main_t *vam)
10844 {
10845     unformat_input_t * i = vam->input;
10846     vl_api_policer_dump_t *mp;
10847     f64 timeout = ~0;
10848     u8 *match_name = 0;
10849     u8 match_name_valid = 0;
10850
10851     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10852         if (unformat (i, "name %s", &match_name)) {
10853             vec_add1 (match_name, 0);
10854             match_name_valid = 1;
10855         } else
10856             break;
10857     }
10858
10859     M(POLICER_DUMP, policer_dump);
10860     mp->match_name_valid = match_name_valid;
10861     clib_memcpy (mp->match_name, match_name, vec_len (match_name));
10862     vec_free (match_name);
10863     /* send it... */
10864     S;
10865
10866     /* Use a control ping for synchronization */
10867     {
10868         vl_api_control_ping_t * mp;
10869         M(CONTROL_PING, control_ping);
10870         S;
10871     }
10872     /* Wait for a reply... */
10873     W;
10874
10875     /* NOTREACHED */
10876     return 0;
10877 }
10878
10879 static int
10880 api_netmap_create (vat_main_t * vam)
10881 {
10882     unformat_input_t * i = vam->input;
10883     vl_api_netmap_create_t * mp;
10884     f64 timeout;
10885     u8 * if_name = 0;
10886     u8 hw_addr[6];
10887     u8 random_hw_addr = 1;
10888     u8 is_pipe = 0;
10889     u8 is_master = 0;
10890
10891     memset (hw_addr, 0, sizeof (hw_addr));
10892
10893     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10894         if (unformat (i, "name %s", &if_name))
10895             vec_add1 (if_name, 0);
10896         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10897             random_hw_addr = 0;
10898         else if (unformat (i, "pipe"))
10899             is_pipe = 1;
10900         else if (unformat (i, "master"))
10901             is_master = 1;
10902         else if (unformat (i, "slave"))
10903             is_master = 0;
10904         else
10905           break;
10906     }
10907
10908     if (!vec_len (if_name)) {
10909         errmsg ("interface name must be specified");
10910         return -99;
10911     }
10912
10913     if (vec_len (if_name) > 64) {
10914         errmsg ("interface name too long");
10915         return -99;
10916     }
10917
10918     M(NETMAP_CREATE, netmap_create);
10919
10920     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
10921     clib_memcpy (mp->hw_addr, hw_addr, 6);
10922     mp->use_random_hw_addr = random_hw_addr;
10923     mp->is_pipe = is_pipe;
10924     mp->is_master = is_master;
10925     vec_free (if_name);
10926
10927     S; W;
10928     /* NOTREACHED */
10929     return 0;
10930 }
10931
10932 static int
10933 api_netmap_delete (vat_main_t * vam)
10934 {
10935     unformat_input_t * i = vam->input;
10936     vl_api_netmap_delete_t * mp;
10937     f64 timeout;
10938     u8 * if_name = 0;
10939
10940     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10941         if (unformat (i, "name %s", &if_name))
10942             vec_add1 (if_name, 0);
10943         else
10944             break;
10945     }
10946
10947     if (!vec_len (if_name)) {
10948         errmsg ("interface name must be specified");
10949         return -99;
10950     }
10951
10952     if (vec_len (if_name) > 64) {
10953         errmsg ("interface name too long");
10954         return -99;
10955     }
10956
10957     M(NETMAP_DELETE, netmap_delete);
10958
10959     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
10960     vec_free (if_name);
10961
10962     S; W;
10963     /* NOTREACHED */
10964     return 0;
10965 }
10966
10967 static int q_or_quit (vat_main_t * vam)
10968 {
10969     longjmp (vam->jump_buf, 1);
10970     return 0; /* not so much */
10971 }
10972 static int q (vat_main_t * vam) {return q_or_quit (vam);}
10973 static int quit (vat_main_t * vam) {return q_or_quit (vam);}
10974
10975 static int comment (vat_main_t * vam)
10976 {
10977     return 0;
10978 }
10979
10980 static int cmd_cmp (void * a1, void * a2)
10981 {
10982   u8 ** c1 = a1;
10983   u8 ** c2 = a2;
10984
10985   return strcmp ((char *)(c1[0]), (char *)(c2[0]));
10986 }
10987
10988 static int help (vat_main_t * vam)
10989 {
10990     u8 ** cmds = 0;
10991     u8 * name = 0;
10992     hash_pair_t * p;
10993     unformat_input_t * i = vam->input;
10994     int j;
10995
10996     if (unformat (i, "%s", &name)) {
10997         uword *hs;
10998
10999         vec_add1(name, 0);
11000
11001         hs = hash_get_mem (vam->help_by_name, name);
11002         if (hs)
11003             fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
11004         else
11005             fformat (vam->ofp, "No such msg / command '%s'\n", name);
11006         vec_free(name);
11007         return 0;
11008     }
11009
11010     fformat(vam->ofp, "Help is available for the following:\n");
11011
11012     hash_foreach_pair (p, vam->function_by_name, 
11013     ({
11014         vec_add1 (cmds, (u8 *)(p->key));
11015     }));
11016
11017     vec_sort_with_function (cmds, cmd_cmp);
11018
11019     for (j = 0; j < vec_len(cmds); j++)
11020         fformat (vam->ofp, "%s\n", cmds[j]);
11021
11022     vec_free (cmds);
11023     return 0;
11024 }
11025
11026 static int set (vat_main_t * vam)
11027 {
11028     u8 * name = 0, * value = 0;
11029     unformat_input_t * i = vam->input;
11030
11031     if (unformat (i, "%s", &name)) {
11032         /* The input buffer is a vector, not a string. */
11033         value = vec_dup (i->buffer);
11034         vec_delete (value, i->index, 0);
11035         /* Almost certainly has a trailing newline */
11036         if (value[vec_len(value)-1] == '\n')
11037             value[vec_len(value)-1] = 0;
11038         /* Make sure it's a proper string, one way or the other */
11039         vec_add1 (value, 0);
11040         (void) clib_macro_set_value (&vam->macro_main, 
11041                                      (char *)name, (char *)value);
11042     }
11043     else
11044         errmsg ("usage: set <name> <value>\n");
11045
11046     vec_free (name);
11047     vec_free (value);
11048     return 0;
11049 }
11050
11051 static int unset (vat_main_t * vam)
11052 {
11053     u8 * name = 0;
11054
11055     if (unformat (vam->input, "%s", &name))
11056         if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
11057             errmsg ("unset: %s wasn't set\n", name);
11058     vec_free (name);
11059     return 0;
11060 }
11061
11062 typedef struct {
11063     u8 * name;
11064     u8 * value;
11065 } macro_sort_t;
11066
11067
11068 static int macro_sort_cmp (void * a1, void * a2)
11069 {
11070   macro_sort_t * s1 = a1;
11071   macro_sort_t * s2 = a2;
11072
11073   return strcmp ((char *)(s1->name), (char *)(s2->name));
11074 }
11075
11076 static int dump_macro_table (vat_main_t * vam)
11077 {
11078     macro_sort_t * sort_me = 0, * sm;    
11079     int i;
11080     hash_pair_t * p;
11081
11082     hash_foreach_pair (p, vam->macro_main.the_value_table_hash, 
11083     ({
11084         vec_add2 (sort_me, sm, 1);
11085         sm->name = (u8 *)(p->key);
11086         sm->value = (u8 *) (p->value[0]);
11087     }));
11088     
11089     vec_sort_with_function (sort_me, macro_sort_cmp);
11090
11091     if (vec_len(sort_me))
11092         fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
11093     else
11094         fformat (vam->ofp, "The macro table is empty...\n");
11095
11096     for (i = 0; i < vec_len (sort_me); i++)
11097         fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
11098                  sort_me[i].value);
11099     return 0;
11100 }
11101
11102 static int dump_node_table (vat_main_t * vam)
11103 {
11104     int i, j;
11105     vlib_node_t * node, * next_node;
11106
11107     if (vec_len (vam->graph_nodes) == 0) {
11108         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
11109         return 0;
11110     }
11111
11112     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
11113         node = vam->graph_nodes[i];
11114         fformat (vam->ofp, "[%d] %s\n", i, node->name);
11115         for (j = 0; j < vec_len (node->next_nodes); j++) {
11116             if (node->next_nodes[j] != ~0) {
11117                 next_node = vam->graph_nodes[node->next_nodes[j]];
11118                 fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
11119             }
11120         }
11121     }
11122     return 0;
11123 }
11124
11125 static int search_node_table (vat_main_t * vam)
11126 {
11127     unformat_input_t * line_input = vam->input;
11128     u8 * node_to_find;
11129     int j;
11130     vlib_node_t * node, * next_node;
11131     uword * p;
11132
11133     if (vam->graph_node_index_by_name == 0) {
11134         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
11135         return 0;
11136     }
11137
11138     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
11139         if (unformat (line_input, "%s", &node_to_find)) {
11140             vec_add1 (node_to_find, 0);
11141             p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
11142             if (p == 0) {
11143                 fformat (vam->ofp, "%s not found...\n", node_to_find);
11144                 goto out;
11145             }
11146             node = vam->graph_nodes[p[0]];
11147             fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
11148             for (j = 0; j < vec_len (node->next_nodes); j++) {
11149                 if (node->next_nodes[j] != ~0) {
11150                     next_node = vam->graph_nodes[node->next_nodes[j]];
11151                     fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
11152                 }
11153             }
11154         }
11155             
11156         else {
11157             clib_warning ("parse error '%U'", format_unformat_error, 
11158                           line_input);
11159             return -99;
11160         }
11161
11162     out:
11163         vec_free(node_to_find);
11164         
11165     }
11166
11167     return 0;        
11168 }
11169
11170
11171 static int script (vat_main_t * vam)
11172 {
11173     u8 * s = 0;
11174     char * save_current_file;
11175     unformat_input_t save_input;
11176     jmp_buf save_jump_buf;
11177     u32 save_line_number;
11178
11179     FILE * new_fp, * save_ifp;
11180
11181     if (unformat (vam->input, "%s", &s)) {
11182         new_fp = fopen ((char *)s, "r");
11183         if (new_fp == 0) {
11184             errmsg ("Couldn't open script file %s\n", s);
11185             vec_free (s);
11186             return -99;
11187         }
11188     } else {
11189         errmsg ("Missing script name\n");
11190         return -99;
11191     }
11192
11193     clib_memcpy (&save_input, &vam->input, sizeof (save_input));
11194     clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
11195     save_ifp = vam->ifp;
11196     save_line_number = vam->input_line_number;
11197     save_current_file = (char *) vam->current_file;
11198
11199     vam->input_line_number = 0;
11200     vam->ifp = new_fp;
11201     vam->current_file = s;
11202     do_one_file (vam);
11203
11204     clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
11205     clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
11206     vam->ifp = save_ifp;
11207     vam->input_line_number = save_line_number;
11208     vam->current_file = (u8 *) save_current_file;
11209     vec_free (s);
11210
11211     return 0;
11212 }
11213
11214 static int echo (vat_main_t * vam)
11215 {
11216     fformat (vam->ofp, "%v", vam->input->buffer);
11217     return 0;
11218 }
11219
11220 /* List of API message constructors, CLI names map to api_xxx */
11221 #define foreach_vpe_api_msg                                             \
11222 _(create_loopback,"[mac <mac-addr>]")                                   \
11223 _(sw_interface_dump,"")                                                 \
11224 _(sw_interface_set_flags,                                               \
11225   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
11226 _(sw_interface_add_del_address,                                         \
11227   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
11228 _(sw_interface_set_table,                                               \
11229   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
11230 _(sw_interface_set_vpath,                                               \
11231   "<intfc> | sw_if_index <id> enable | disable")                        \
11232 _(sw_interface_set_l2_xconnect,                                         \
11233   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11234   "enable | disable")                                                   \
11235 _(sw_interface_set_l2_bridge,                                           \
11236   "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n"         \
11237   "[shg <split-horizon-group>] [bvi]\n"                                 \
11238   "enable | disable")                                                   \
11239 _(bridge_domain_add_del,                                                \
11240   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
11241 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
11242 _(l2fib_add_del,                                                        \
11243   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
11244 _(l2_flags,                                                             \
11245   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
11246 _(bridge_flags,                                                         \
11247   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
11248 _(tap_connect,                                                          \
11249   "tapname <name> mac <mac-addr> | random-mac")                         \
11250 _(tap_modify,                                                           \
11251   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
11252 _(tap_delete,                                                           \
11253   "<vpp-if-name> | sw_if_index <id>")                                   \
11254 _(sw_interface_tap_dump, "")                                            \
11255 _(ip_add_del_route,                                                     \
11256   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
11257   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
11258   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
11259   "[multipath] [count <n>]")                                            \
11260 _(proxy_arp_add_del,                                                    \
11261   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
11262 _(proxy_arp_intfc_enable_disable,                                       \
11263   "<intfc> | sw_if_index <id> enable | disable")                        \
11264 _(mpls_add_del_encap,                                                   \
11265   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
11266 _(mpls_add_del_decap,                                                   \
11267   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
11268 _(mpls_gre_add_del_tunnel,                                              \
11269   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
11270   "adj <ip4-address>/<mask-width> [del]")                               \
11271 _(sw_interface_set_unnumbered,                                          \
11272   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
11273 _(ip_neighbor_add_del,                                                  \
11274   "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>")       \
11275 _(reset_vrf, "vrf <id> [ipv6]")                                         \
11276 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
11277 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
11278   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
11279   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
11280   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
11281 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
11282 _(reset_fib, "vrf <n> [ipv6]")                                          \
11283 _(dhcp_proxy_config,                                                    \
11284   "svr <v46-address> src <v46-address>\n"                               \
11285    "insert-cid <n> [del]")                                              \
11286 _(dhcp_proxy_config_2,                                                  \
11287   "svr <v46-address> src <v46-address>\n"                               \
11288    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
11289 _(dhcp_proxy_set_vss,                                                   \
11290   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
11291 _(dhcp_client_config,                                                   \
11292   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
11293 _(set_ip_flow_hash,                                                     \
11294   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
11295 _(sw_interface_ip6_enable_disable,                                      \
11296   "<intfc> | sw_if_index <id> enable | disable")                        \
11297 _(sw_interface_ip6_set_link_local_address,                              \
11298   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
11299 _(sw_interface_ip6nd_ra_prefix,                                         \
11300   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
11301   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
11302   "[nolink] [isno]")                                                    \
11303 _(sw_interface_ip6nd_ra_config,                                         \
11304   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
11305   "[life <n>] [count <n>] [interval <n>] [surpress]\n"                  \
11306   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
11307 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
11308 _(l2_patch_add_del,                                                     \
11309   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11310   "enable | disable")                                                   \
11311 _(mpls_ethernet_add_del_tunnel,                                         \
11312   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
11313   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
11314 _(mpls_ethernet_add_del_tunnel_2,                                       \
11315   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
11316   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
11317 _(sr_tunnel_add_del,                                                    \
11318   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
11319   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
11320   "[policy <policy_name>]")                                             \
11321 _(sr_policy_add_del,                                                    \
11322   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
11323 _(sr_multicast_map_add_del,                                             \
11324   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
11325 _(classify_add_del_table,                                               \
11326   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
11327   "[del] mask <mask-value>\n"                                           \
11328   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
11329 _(classify_add_del_session,                                             \
11330   "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n"    \
11331   "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]")           \
11332 _(classify_set_interface_ip_table,                                      \
11333   "<intfc> | sw_if_index <nn> table <nn>")                              \
11334 _(classify_set_interface_l2_tables,                                     \
11335   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
11336   "  [other-table <nn>]")                                               \
11337 _(get_node_index, "node <node-name")                                    \
11338 _(add_node_next, "node <node-name> next <next-node-name>")              \
11339 _(l2tpv3_create_tunnel,                                                 \
11340   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
11341   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
11342   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
11343 _(l2tpv3_set_tunnel_cookies,                                            \
11344   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
11345   "[new_remote_cookie <nn>]\n")                                         \
11346 _(l2tpv3_interface_enable_disable,                                      \
11347   "<intfc> | sw_if_index <nn> enable | disable")                        \
11348 _(l2tpv3_set_lookup_key,                                                \
11349   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
11350 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
11351 _(vxlan_add_del_tunnel,                                                 \
11352   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
11353   " [decap-next l2|ip4|ip6] [del]")                                     \
11354 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
11355 _(gre_add_del_tunnel,                                                   \
11356   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
11357 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
11358 _(l2_fib_clear_table, "")                                               \
11359 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
11360 _(l2_interface_vlan_tag_rewrite,                                        \
11361   "<intfc> | sw_if_index <nn> \n"                                       \
11362   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
11363   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
11364 _(create_vhost_user_if,                                                 \
11365         "socket <filename> [server] [renumber <dev_instance>] "         \
11366         "[mac <mac_address>]")                                          \
11367 _(modify_vhost_user_if,                                                 \
11368         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
11369         "[server] [renumber <dev_instance>]")                           \
11370 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
11371 _(sw_interface_vhost_user_dump, "")                                     \
11372 _(show_version, "")                                                     \
11373 _(vxlan_gpe_add_del_tunnel,                                             \
11374   "local <addr> remote <addr> vni <nn>\n"                               \
11375     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
11376   "[next-ethernet] [next-nsh]\n")                                       \
11377 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
11378 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
11379 _(interface_name_renumber,                                              \
11380   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
11381 _(input_acl_set_interface,                                              \
11382   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
11383   "  [l2-table <nn>] [del]")                                            \
11384 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
11385 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
11386 _(ip_dump, "ipv4 | ipv6")                                               \
11387 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
11388 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
11389   "  spid_id <n> ")                                                     \
11390 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
11391   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
11392   "  integ_alg <alg> integ_key <hex>")                                  \
11393 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
11394   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
11395   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
11396   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
11397 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
11398 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
11399 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
11400   "(auth_data 0x<data> | auth_data <data>)")                            \
11401 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
11402   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
11403 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
11404   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
11405   "(local|remote)")                                                     \
11406 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
11407 _(delete_loopback,"sw_if_index <nn>")                                   \
11408 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
11409 _(map_add_domain,                                                       \
11410   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
11411   "ip6-src <ip6addr> "                                                  \
11412   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
11413 _(map_del_domain, "index <n>")                                          \
11414 _(map_add_del_rule,                                                     \
11415   "index <n> psid <n> dst <ip6addr> [del]")                             \
11416 _(map_domain_dump, "")                                                  \
11417 _(map_rule_dump, "index <map-domain>")                                  \
11418 _(want_interface_events,  "enable|disable")                             \
11419 _(want_stats,"enable|disable")                                          \
11420 _(get_first_msg_id, "client <name>")                                    \
11421 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
11422 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
11423   "fib-id <nn> [ip4][ip6][default]")                                    \
11424 _(get_node_graph, " ")                                                  \
11425 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
11426 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
11427   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
11428   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
11429 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
11430   " vrf_id <nn>  add | pop | none")                                     \
11431 _(trace_profile_del, "")                                                \
11432 _(lisp_add_del_locator_set, "locator-set <locator_name> [del]")         \
11433 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
11434                         "iface <intf> | sw_if_index <sw_if_index> "     \
11435                         "p <priority> w <weight> [del]")                \
11436 _(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> "                       \
11437                           "locator-set <locator_name> [del]")           \
11438 _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
11439     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
11440 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
11441 _(lisp_gpe_enable_disable, "enable|disable")                            \
11442 _(lisp_enable_disable, "enable|disable")                                \
11443 _(lisp_gpe_add_del_iface, "up|down")                                    \
11444 _(lisp_add_del_remote_mapping, "add|del vni <vni> table-id <id> "       \
11445                                "deid <dest-eid> seid"                   \
11446                                " <src-eid> rloc <locator> "             \
11447                                "[rloc <loc> ... ]")                     \
11448 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
11449 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
11450 _(lisp_locator_set_dump, "")                                            \
11451 _(lisp_local_eid_table_dump, "")                                        \
11452 _(lisp_gpe_tunnel_dump, "")                                             \
11453 _(lisp_map_resolver_dump, "")                                           \
11454 _(lisp_enable_disable_status_dump, "")                                  \
11455 _(lisp_get_map_request_itr_rlocs, "")                                   \
11456 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
11457 _(af_packet_delete, "name <host interface name>")                       \
11458 _(policer_add_del, "name <policer name> <params> [del]")                \
11459 _(policer_dump, "[name <policer name>]")                                \
11460 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
11461     "[master|slave]")                                                   \
11462 _(netmap_delete, "name <interface name>")
11463
11464 /* List of command functions, CLI names map directly to functions */
11465 #define foreach_cli_function                                    \
11466 _(comment, "usage: comment <ignore-rest-of-line>")              \
11467 _(dump_interface_table, "usage: dump_interface_table")          \
11468 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
11469 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
11470 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
11471 _(dump_stats_table, "usage: dump_stats_table")                  \
11472 _(dump_macro_table, "usage: dump_macro_table ")                 \
11473 _(dump_node_table, "usage: dump_node_table")                    \
11474 _(echo, "usage: echo <message>")                                \
11475 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
11476 _(help, "usage: help")                                          \
11477 _(q, "usage: quit")                                             \
11478 _(quit, "usage: quit")                                          \
11479 _(search_node_table, "usage: search_node_table <name>...")      \
11480 _(set, "usage: set <variable-name> <value>")                    \
11481 _(script, "usage: script <file-name>")                          \
11482 _(unset, "usage: unset <variable-name>")
11483
11484 #define _(N,n)                                  \
11485     static void vl_api_##n##_t_handler_uni      \
11486     (vl_api_##n##_t * mp)                       \
11487     {                                           \
11488         vat_main_t * vam = &vat_main;           \
11489         if (vam->json_output) {                 \
11490             vl_api_##n##_t_handler_json(mp);    \
11491         } else {                                \
11492             vl_api_##n##_t_handler(mp);         \
11493         }                                       \
11494     }
11495 foreach_vpe_api_reply_msg;
11496 #undef _
11497
11498 void vat_api_hookup (vat_main_t *vam)
11499 {
11500 #define _(N,n)                                                  \
11501     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
11502                            vl_api_##n##_t_handler_uni,          \
11503                            vl_noop_handler,                     \
11504                            vl_api_##n##_t_endian,               \
11505                            vl_api_##n##_t_print,                \
11506                            sizeof(vl_api_##n##_t), 1); 
11507     foreach_vpe_api_reply_msg;
11508 #undef _
11509
11510     vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
11511
11512     vam->sw_if_index_by_interface_name = 
11513         hash_create_string (0, sizeof (uword));
11514
11515     vam->function_by_name = 
11516         hash_create_string (0, sizeof(uword));
11517
11518     vam->help_by_name = 
11519         hash_create_string (0, sizeof(uword));
11520
11521     /* API messages we can send */
11522 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
11523     foreach_vpe_api_msg;
11524 #undef _
11525
11526     /* Help strings */
11527 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11528     foreach_vpe_api_msg;
11529 #undef _
11530
11531     /* CLI functions */
11532 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
11533     foreach_cli_function;
11534 #undef _
11535
11536     /* Help strings */
11537 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11538     foreach_cli_function;
11539 #undef _
11540 }
11541
11542 #undef vl_api_version
11543 #define vl_api_version(n,v) static u32 vpe_api_version = v;
11544 #include <api/vpe.api.h>
11545 #undef vl_api_version
11546
11547 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
11548 {
11549     /* 
11550      * Send the main API signature in slot 0. This bit of code must
11551      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
11552      */
11553     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
11554 }