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