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