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