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