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