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