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