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