Convert lisp-gpe encap to interface tx node
[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     default:
1958       return format (s, "unknown %d", next_index);
1959     }
1960   return s;
1961 }
1962
1963 static void
1964 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *mp)
1965 {
1966     vat_main_t *vam = &vat_main;
1967     u8 *iid_str;
1968     u8 *flag_str = NULL;
1969
1970     iid_str = format(0, "%d (0x%x)", ntohl(mp->iid), ntohl(mp->iid));
1971
1972 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
1973   foreach_lisp_gpe_flag_bit;
1974 #undef _
1975
1976     fformat(vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
1977             "%=16d%=16d%=16sd=16d%=16s%=16s\n",
1978             mp->tunnels,
1979             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
1980             mp->source_ip,
1981             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
1982             mp->destination_ip,
1983             ntohl(mp->encap_fib_id),
1984             ntohl(mp->decap_fib_id),
1985             format_decap_next, ntohl(mp->dcap_next),
1986             mp->ver_res >> 6,
1987             flag_str,
1988             mp->next_protocol,
1989             mp->ver_res,
1990             mp->res,
1991             iid_str);
1992
1993     vec_free(iid_str);
1994 }
1995
1996 static void
1997 vl_api_lisp_gpe_tunnel_details_t_handler_json (
1998     vl_api_lisp_gpe_tunnel_details_t *mp)
1999 {
2000     vat_main_t *vam = &vat_main;
2001     vat_json_node_t *node = NULL;
2002     struct in6_addr ip6;
2003     struct in_addr ip4;
2004     u8 *next_decap_str;
2005
2006     next_decap_str = format(0, "%U", format_decap_next, htonl(mp->dcap_next));
2007
2008     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2009         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2010         vat_json_init_array(&vam->json_tree);
2011     }
2012     node = vat_json_array_add(&vam->json_tree);
2013
2014     vat_json_init_object(node);
2015     vat_json_object_add_uint(node, "tunel", mp->tunnels);
2016     if (mp->is_ipv6) {
2017         clib_memcpy(&ip6, mp->source_ip, sizeof(ip6));
2018         vat_json_object_add_ip6(node, "source address", ip6);
2019         clib_memcpy(&ip6, mp->destination_ip, sizeof(ip6));
2020         vat_json_object_add_ip6(node, "destination address", ip6);
2021     } else {
2022         clib_memcpy(&ip4, mp->source_ip, sizeof(ip4));
2023         vat_json_object_add_ip4(node, "source address", ip4);
2024         clib_memcpy(&ip4, mp->destination_ip, sizeof(ip4));
2025         vat_json_object_add_ip4(node, "destination address", ip4);
2026     }
2027     vat_json_object_add_uint(node, "fib encap", ntohl(mp->encap_fib_id));
2028     vat_json_object_add_uint(node, "fib decap", ntohl(mp->decap_fib_id));
2029     vat_json_object_add_string_copy(node, "decap next", next_decap_str);
2030     vat_json_object_add_uint(node, "lisp version", mp->ver_res >> 6);
2031     vat_json_object_add_uint(node, "flags", mp->flags);
2032     vat_json_object_add_uint(node, "next protocol", mp->next_protocol);
2033     vat_json_object_add_uint(node, "ver_res", mp->ver_res);
2034     vat_json_object_add_uint(node, "res", mp->res);
2035     vat_json_object_add_uint(node, "iid", ntohl(mp->iid));
2036
2037     vec_free(next_decap_str);
2038 }
2039
2040 static void
2041 vl_api_lisp_map_resolver_details_t_handler (
2042     vl_api_lisp_map_resolver_details_t *mp)
2043 {
2044     vat_main_t *vam = &vat_main;
2045
2046     fformat(vam->ofp, "%=20U\n",
2047             mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2048             mp->ip_address);
2049 }
2050
2051 static void
2052 vl_api_lisp_map_resolver_details_t_handler_json (
2053     vl_api_lisp_map_resolver_details_t *mp)
2054 {
2055     vat_main_t *vam = &vat_main;
2056     vat_json_node_t *node = NULL;
2057     struct in6_addr ip6;
2058     struct in_addr ip4;
2059
2060     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2061         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2062         vat_json_init_array(&vam->json_tree);
2063     }
2064     node = vat_json_array_add(&vam->json_tree);
2065
2066     vat_json_init_object(node);
2067     if (mp->is_ipv6) {
2068         clib_memcpy(&ip6, mp->ip_address, sizeof(ip6));
2069         vat_json_object_add_ip6(node, "map resolver", ip6);
2070     } else {
2071         clib_memcpy(&ip4, mp->ip_address, sizeof(ip4));
2072         vat_json_object_add_ip4(node, "map resolver", ip4);
2073     }
2074 }
2075
2076 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2077 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2078 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2079 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2080
2081 /* 
2082  * Generate boilerplate reply handlers, which 
2083  * dig the return value out of the xxx_reply_t API message,
2084  * stick it into vam->retval, and set vam->result_ready
2085  *
2086  * Could also do this by pointing N message decode slots at
2087  * a single function, but that could break in subtle ways.
2088  */
2089
2090 #define foreach_standard_reply_retval_handler           \
2091 _(sw_interface_set_flags_reply)                         \
2092 _(sw_interface_add_del_address_reply)                   \
2093 _(sw_interface_set_table_reply)                         \
2094 _(sw_interface_set_vpath_reply)                         \
2095 _(sw_interface_set_l2_bridge_reply)                     \
2096 _(bridge_domain_add_del_reply)                          \
2097 _(sw_interface_set_l2_xconnect_reply)                   \
2098 _(l2fib_add_del_reply)                                  \
2099 _(ip_add_del_route_reply)                               \
2100 _(proxy_arp_add_del_reply)                              \
2101 _(proxy_arp_intfc_enable_disable_reply)                 \
2102 _(mpls_add_del_encap_reply)                             \
2103 _(mpls_add_del_decap_reply)                             \
2104 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
2105 _(sw_interface_set_unnumbered_reply)                    \
2106 _(ip_neighbor_add_del_reply)                            \
2107 _(reset_vrf_reply)                                      \
2108 _(oam_add_del_reply)                                    \
2109 _(reset_fib_reply)                                      \
2110 _(dhcp_proxy_config_reply)                              \
2111 _(dhcp_proxy_config_2_reply)                            \
2112 _(dhcp_proxy_set_vss_reply)                             \
2113 _(dhcp_client_config_reply)                             \
2114 _(set_ip_flow_hash_reply)                               \
2115 _(sw_interface_ip6_enable_disable_reply)                \
2116 _(sw_interface_ip6_set_link_local_address_reply)        \
2117 _(sw_interface_ip6nd_ra_prefix_reply)                   \
2118 _(sw_interface_ip6nd_ra_config_reply)                   \
2119 _(set_arp_neighbor_limit_reply)                         \
2120 _(l2_patch_add_del_reply)                               \
2121 _(sr_tunnel_add_del_reply)                              \
2122 _(classify_add_del_session_reply)                       \
2123 _(classify_set_interface_ip_table_reply)                \
2124 _(classify_set_interface_l2_tables_reply)               \
2125 _(l2tpv3_set_tunnel_cookies_reply)                      \
2126 _(l2tpv3_interface_enable_disable_reply)                \
2127 _(l2tpv3_set_lookup_key_reply)                          \
2128 _(l2_fib_clear_table_reply)                             \
2129 _(l2_interface_efp_filter_reply)                        \
2130 _(l2_interface_vlan_tag_rewrite_reply)                  \
2131 _(modify_vhost_user_if_reply)                           \
2132 _(delete_vhost_user_if_reply)                           \
2133 _(want_ip4_arp_events_reply)                            \
2134 _(input_acl_set_interface_reply)                        \
2135 _(ipsec_spd_add_del_reply)                              \
2136 _(ipsec_interface_add_del_spd_reply)                    \
2137 _(ipsec_spd_add_del_entry_reply)                        \
2138 _(ipsec_sad_add_del_entry_reply)                        \
2139 _(ipsec_sa_set_key_reply)                               \
2140 _(ikev2_profile_add_del_reply)                          \
2141 _(ikev2_profile_set_auth_reply)                         \
2142 _(ikev2_profile_set_id_reply)                           \
2143 _(ikev2_profile_set_ts_reply)                           \
2144 _(ikev2_set_local_key_reply)                            \
2145 _(delete_loopback_reply)                                \
2146 _(bd_ip_mac_add_del_reply)                              \
2147 _(map_del_domain_reply)                                 \
2148 _(map_add_del_rule_reply)                               \
2149 _(want_interface_events_reply)                          \
2150 _(want_stats_reply)                                     \
2151 _(cop_interface_enable_disable_reply)                   \
2152 _(cop_whitelist_enable_disable_reply)                   \
2153 _(sw_interface_clear_stats_reply)                       \
2154 _(trace_profile_add_reply)                              \
2155 _(trace_profile_apply_reply)                            \
2156 _(trace_profile_del_reply)                              \
2157 _(lisp_add_del_locator_set_reply)                       \
2158 _(lisp_add_del_locator_reply)                           \
2159 _(lisp_add_del_local_eid_reply)                         \
2160 _(lisp_gpe_add_del_fwd_entry_reply)                     \
2161 _(lisp_add_del_map_resolver_reply)                      \
2162 _(lisp_gpe_enable_disable_reply)                        \
2163 _(lisp_gpe_add_del_iface_reply)
2164
2165 #define _(n)                                    \
2166     static void vl_api_##n##_t_handler          \
2167     (vl_api_##n##_t * mp)                       \
2168     {                                           \
2169         vat_main_t * vam = &vat_main;           \
2170         i32 retval = ntohl(mp->retval);         \
2171         if (vam->async_mode) {                  \
2172             vam->async_errors += (retval < 0);  \
2173         } else {                                \
2174             vam->retval = retval;               \
2175             vam->result_ready = 1;              \
2176         }                                       \
2177     }
2178 foreach_standard_reply_retval_handler;
2179 #undef _
2180
2181 #define _(n)                                    \
2182     static void vl_api_##n##_t_handler_json     \
2183     (vl_api_##n##_t * mp)                       \
2184     {                                           \
2185         vat_main_t * vam = &vat_main;           \
2186         vat_json_node_t node;                   \
2187         vat_json_init_object(&node);            \
2188         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
2189         vat_json_print(vam->ofp, &node);        \
2190         vam->retval = ntohl(mp->retval);        \
2191         vam->result_ready = 1;                  \
2192     }
2193 foreach_standard_reply_retval_handler;
2194 #undef _
2195
2196 /* 
2197  * Table of message reply handlers, must include boilerplate handlers
2198  * we just generated
2199  */
2200
2201 #define foreach_vpe_api_reply_msg                                       \
2202 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
2203 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
2204 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
2205 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
2206 _(CONTROL_PING_REPLY, control_ping_reply)                               \
2207 _(CLI_REPLY, cli_reply)                                                 \
2208 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
2209   sw_interface_add_del_address_reply)                                   \
2210 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
2211 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
2212 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
2213   sw_interface_set_l2_xconnect_reply)                                   \
2214 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
2215   sw_interface_set_l2_bridge_reply)                                     \
2216 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
2217 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
2218 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
2219 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
2220 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
2221 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
2222 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
2223 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
2224 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
2225 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
2226 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
2227 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
2228 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
2229   proxy_arp_intfc_enable_disable_reply)                                 \
2230 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
2231 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
2232 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
2233 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
2234   mpls_ethernet_add_del_tunnel_reply)                                   \
2235 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
2236   mpls_ethernet_add_del_tunnel_2_reply)                                 \
2237 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
2238   sw_interface_set_unnumbered_reply)                                    \
2239 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
2240 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
2241 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
2242 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
2243 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
2244 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
2245 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
2246 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
2247 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
2248 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
2249 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
2250 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
2251   sw_interface_ip6_enable_disable_reply)                                \
2252 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
2253   sw_interface_ip6_set_link_local_address_reply)                        \
2254 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
2255   sw_interface_ip6nd_ra_prefix_reply)                                   \
2256 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
2257   sw_interface_ip6nd_ra_config_reply)                                   \
2258 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
2259 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
2260 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
2261 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
2262 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
2263 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
2264 classify_set_interface_ip_table_reply)                                  \
2265 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
2266   classify_set_interface_l2_tables_reply)                               \
2267 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
2268 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
2269 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
2270 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
2271 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
2272   l2tpv3_interface_enable_disable_reply)                                \
2273 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
2274 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
2275 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
2276 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
2277 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
2278 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
2279 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2280 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
2281 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
2282 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
2283 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
2284 _(SHOW_VERSION_REPLY, show_version_reply)                               \
2285 _(NSH_GRE_ADD_DEL_TUNNEL_REPLY, nsh_gre_add_del_tunnel_reply)           \
2286 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
2287 _(NSH_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, nsh_vxlan_gpe_add_del_tunnel_reply) \
2288 _(LISP_GPE_ADD_DEL_TUNNEL_REPLY, lisp_gpe_add_del_tunnel_reply)         \
2289 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
2290 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
2291 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
2292 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
2293 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
2294 _(IP_DETAILS, ip_details)                                               \
2295 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
2296 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2297 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
2298 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
2299 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
2300 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
2301 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
2302 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
2303 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
2304 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
2305 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
2306 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
2307 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
2308 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
2309 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
2310 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
2311 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
2312 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
2313 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
2314 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
2315 _(MAP_RULE_DETAILS, map_rule_details)                                   \
2316 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
2317 _(WANT_STATS_REPLY, want_stats_reply)                                   \
2318 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
2319 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
2320 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
2321 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
2322 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
2323 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
2324 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
2325 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
2326 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
2327 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
2328 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
2329 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
2330 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
2331 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_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, "%d", &tmp))
7866         *result = tmp;
7867     else
7868         return 0;
7869     return 1;
7870 }
7871
7872 static int
7873 api_lisp_gpe_add_del_tunnel (vat_main_t * vam)
7874 {
7875     unformat_input_t * line_input = vam->input;
7876     vl_api_lisp_gpe_add_del_tunnel_t *mp;
7877     f64 timeout;
7878     ip4_address_t src, dst;
7879     u8 is_add = 1;
7880     u8 src_set = 0;
7881     u8 dst_set = 0;
7882     u32 encap_vrf_id = 0;
7883     u32 decap_vrf_id = 0;
7884     u8 next_protocol = LISP_GPE_NEXT_PROTOCOL_IP4;
7885     u32 decap_next_index = LISP_GPE_INPUT_NEXT_IP4_INPUT;
7886     u8 flags = LISP_GPE_FLAGS_P;
7887     u8 ver_res = 0;
7888     u8 res = 0;
7889     u32 iid = 0;
7890     u8 iid_set = 0;
7891     u32 tmp;
7892   
7893     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7894         if (unformat (line_input, "del"))
7895             is_add = 0;
7896         else if (unformat (line_input, "src %U", 
7897                            unformat_ip4_address, &src))
7898             src_set = 1;
7899         else if (unformat (line_input, "dst %U",
7900                            unformat_ip4_address, &dst))
7901             dst_set = 1;
7902         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7903             ;
7904         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7905             ;
7906         else if (unformat (line_input, "decap-next %U", 
7907                            unformat_lisp_gpe_decap_next, 
7908                            &decap_next_index))
7909             ;
7910         else if (unformat(line_input, "next-ip4"))
7911             next_protocol = 1;
7912         else if (unformat(line_input, "next-ip6"))
7913             next_protocol = 2;
7914         else if (unformat(line_input, "next-ethernet"))
7915             next_protocol = 3;
7916         else if (unformat(line_input, "next-nsh"))
7917             next_protocol = 4;
7918         /* Allow the user to specify anything they want in the LISP hdr */
7919         else if (unformat (line_input, "ver_res %x", &tmp))
7920             ver_res = tmp;
7921         else if (unformat (line_input, "res %x", &tmp))
7922             res = tmp;
7923         else if (unformat (line_input, "flags %x", &tmp))
7924             flags = tmp;
7925         else if (unformat (line_input, "n-bit"))
7926             flags |= LISP_GPE_FLAGS_N;
7927         else if (unformat (line_input, "l-bit"))
7928             flags |= LISP_GPE_FLAGS_L;
7929         else if (unformat (line_input, "e-bit"))
7930             flags |= LISP_GPE_FLAGS_E;
7931         else if (unformat (line_input, "v-bit"))
7932             flags |= LISP_GPE_FLAGS_V;
7933         else if (unformat (line_input, "i-bit"))
7934             flags |= LISP_GPE_FLAGS_V;
7935         else if (unformat (line_input, "not-p-bit"))
7936             flags &= !LISP_GPE_FLAGS_P;
7937         else if (unformat (line_input, "p-bit"))
7938             flags |= LISP_GPE_FLAGS_P;
7939         else if (unformat (line_input, "o-bit"))
7940             flags |= LISP_GPE_FLAGS_O;
7941         else if (unformat (line_input, "iidx %x", &iid))
7942             iid_set = 1;
7943         else if (unformat (line_input, "iid %d", &iid))
7944             iid_set = 1;
7945         else {
7946             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7947             return -99;
7948         }
7949     }
7950
7951     if (src_set == 0) {
7952         errmsg ("tunnel src address not specified\n");
7953         return -99;
7954     }
7955     if (dst_set == 0) {
7956         errmsg ("tunnel dst address not specified\n");
7957         return -99;
7958     }
7959     if (iid_set == 0) {
7960         errmsg ("iid not specified\n");
7961         return -99;
7962     }
7963
7964     M(LISP_GPE_ADD_DEL_TUNNEL, lisp_gpe_add_del_tunnel);
7965
7966     mp->src = src.as_u32;
7967     mp->dst = dst.as_u32;
7968     mp->encap_vrf_id = ntohl(encap_vrf_id);
7969     mp->decap_vrf_id = ntohl(decap_vrf_id);
7970     mp->decap_next_index = ntohl(decap_next_index);
7971     mp->is_add = is_add;
7972     mp->flags = flags;
7973     mp->ver_res = ver_res;
7974     mp->res = res;
7975     mp->next_protocol = next_protocol;
7976     mp->iid = ntohl(iid);
7977
7978     S; W; 
7979
7980     /* NOTREACHED */
7981     return 0;
7982 }
7983
7984
7985 u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
7986 {
7987   u8 * a = va_arg (*args, u8 *);
7988
7989   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
7990                  a[2], a[3], a[4], a[5], a[6], a[7]);
7991 }
7992
7993 static void vl_api_l2_fib_table_entry_t_handler
7994 (vl_api_l2_fib_table_entry_t * mp)
7995 {
7996     vat_main_t * vam = &vat_main;
7997
7998     fformat(vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
7999             "       %d       %d     %d\n",
8000             ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8001             ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8002             mp->bvi_mac);
8003 }
8004
8005 static void vl_api_l2_fib_table_entry_t_handler_json
8006 (vl_api_l2_fib_table_entry_t * mp)
8007 {
8008     vat_main_t * vam = &vat_main;
8009     vat_json_node_t *node = NULL;
8010
8011     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8012         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8013         vat_json_init_array(&vam->json_tree);
8014     }
8015     node = vat_json_array_add(&vam->json_tree);
8016
8017     vat_json_init_object(node);
8018     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8019     vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8020     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8021     vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8022     vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8023     vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8024 }
8025
8026 static int api_l2_fib_table_dump (vat_main_t * vam)
8027 {
8028     unformat_input_t * i = vam->input;
8029     vl_api_l2_fib_table_dump_t *mp;
8030     f64 timeout;
8031     u32 bd_id;
8032     u8 bd_id_set = 0;
8033
8034     /* Parse args required to build the message */
8035     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8036         if (unformat (i, "bd_id %d", &bd_id))
8037             bd_id_set = 1;
8038         else
8039             break;
8040     }
8041
8042     if (bd_id_set == 0) {
8043         errmsg ("missing bridge domain\n");
8044         return -99;
8045     }
8046
8047     fformat(vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
8048
8049     /* Get list of l2 fib entries */
8050     M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8051
8052     mp->bd_id = ntohl(bd_id);
8053     S;
8054
8055     /* Use a control ping for synchronization */
8056     {
8057         vl_api_control_ping_t * mp;
8058         M(CONTROL_PING, control_ping);
8059         S;
8060     }
8061     W;
8062 }
8063
8064
8065 static int
8066 api_interface_name_renumber (vat_main_t * vam)
8067 {
8068     unformat_input_t * line_input = vam->input;
8069     vl_api_interface_name_renumber_t *mp;
8070     u32 sw_if_index = ~0;
8071     f64 timeout;
8072     u32 new_show_dev_instance = ~0;
8073
8074     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8075         if (unformat (line_input, "%U", unformat_sw_if_index, vam, 
8076                       &sw_if_index))
8077             ;
8078         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8079             ;
8080         else if (unformat (line_input, "new_show_dev_instance %d", 
8081                            &new_show_dev_instance))
8082             ;
8083         else
8084             break;
8085     }
8086
8087     if (sw_if_index == ~0) {
8088         errmsg ("missing interface name or sw_if_index\n");
8089         return -99;
8090     }
8091
8092     if (new_show_dev_instance == ~0) {
8093         errmsg ("missing new_show_dev_instance\n");
8094         return -99;
8095     }
8096
8097     M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8098
8099     mp->sw_if_index = ntohl (sw_if_index);
8100     mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8101
8102     S; W;
8103 }
8104
8105 static int
8106 api_want_ip4_arp_events (vat_main_t * vam)
8107 {
8108     unformat_input_t * line_input = vam->input;
8109     vl_api_want_ip4_arp_events_t * mp;
8110     f64 timeout;
8111     ip4_address_t address;
8112     int address_set = 0;
8113     u32 enable_disable = 1;
8114
8115     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8116         if (unformat (line_input, "address %U", 
8117                       unformat_ip4_address, &address))
8118             address_set = 1;
8119         else if (unformat (line_input, "del"))
8120             enable_disable = 0;
8121         else
8122             break;
8123     }
8124     
8125     if (address_set == 0) {
8126         errmsg ("missing addresses\n");
8127         return -99;
8128     }
8129         
8130     M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8131     mp->enable_disable = enable_disable;
8132     mp->pid = getpid();
8133     mp->address = address.as_u32;
8134
8135     S; W; 
8136 }
8137
8138 static int api_input_acl_set_interface (vat_main_t * vam)
8139 {
8140     unformat_input_t * i = vam->input;
8141     vl_api_input_acl_set_interface_t *mp;
8142     f64 timeout;
8143     u32 sw_if_index;
8144     int sw_if_index_set;
8145     u32 ip4_table_index = ~0;
8146     u32 ip6_table_index = ~0;
8147     u32 l2_table_index = ~0;
8148     u8 is_add = 1;
8149
8150     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8151         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8152             sw_if_index_set = 1;
8153         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8154             sw_if_index_set = 1;
8155         else if (unformat (i, "del"))
8156             is_add = 0;
8157         else if (unformat (i, "ip4-table %d", &ip4_table_index))
8158             ;
8159         else if (unformat (i, "ip6-table %d", &ip6_table_index))
8160             ;
8161         else if (unformat (i, "l2-table %d", &l2_table_index))
8162             ;
8163         else {
8164             clib_warning ("parse error '%U'", format_unformat_error, i);
8165             return -99;
8166         }
8167     }
8168
8169     if (sw_if_index_set == 0) {
8170         errmsg ("missing interface name or sw_if_index\n");
8171         return -99;
8172     }
8173
8174     M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8175
8176     mp->sw_if_index = ntohl(sw_if_index);
8177     mp->ip4_table_index = ntohl(ip4_table_index);
8178     mp->ip6_table_index = ntohl(ip6_table_index);
8179     mp->l2_table_index = ntohl(l2_table_index);
8180     mp->is_add = is_add;
8181
8182     S; W;
8183     /* NOTREACHED */
8184     return 0;
8185 }
8186
8187 static int
8188 api_ip_address_dump (vat_main_t * vam)
8189 {
8190     unformat_input_t * i = vam->input;
8191     vl_api_ip_address_dump_t * mp;
8192     u32 sw_if_index = ~0;
8193     u8 sw_if_index_set = 0;
8194     u8 ipv4_set = 0;
8195     u8 ipv6_set = 0;
8196     f64 timeout;
8197
8198     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8199         if (unformat (i, "sw_if_index %d", &sw_if_index))
8200             sw_if_index_set = 1;
8201         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8202             sw_if_index_set = 1;
8203         else if (unformat (i, "ipv4"))
8204             ipv4_set = 1;
8205         else if (unformat (i, "ipv6"))
8206             ipv6_set = 1;
8207         else
8208             break;
8209     }
8210
8211     if (ipv4_set && ipv6_set) {
8212         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8213         return -99;
8214     }
8215
8216     if ((!ipv4_set) && (!ipv6_set)) {
8217         errmsg ("no ipv4 nor ipv6 flag set\n");
8218         return -99;
8219     }
8220
8221     if (sw_if_index_set == 0) {
8222         errmsg ("missing interface name or sw_if_index\n");
8223         return -99;
8224     }
8225
8226     vam->current_sw_if_index = sw_if_index;
8227     vam->is_ipv6 = ipv6_set;
8228
8229     M(IP_ADDRESS_DUMP, ip_address_dump);
8230     mp->sw_if_index = ntohl(sw_if_index);
8231     mp->is_ipv6 = ipv6_set;
8232     S;
8233
8234     /* Use a control ping for synchronization */
8235     {
8236         vl_api_control_ping_t * mp;
8237         M(CONTROL_PING, control_ping);
8238         S;
8239     }
8240     W;
8241 }
8242
8243 static int
8244 api_ip_dump (vat_main_t * vam)
8245 {
8246     vl_api_ip_dump_t * mp;
8247     unformat_input_t * in = vam->input;
8248     int ipv4_set = 0;
8249     int ipv6_set = 0;
8250     int is_ipv6;
8251     f64 timeout;
8252     int i;
8253
8254     while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8255         if (unformat (in, "ipv4"))
8256             ipv4_set = 1;
8257         else if (unformat (in, "ipv6"))
8258             ipv6_set = 1;
8259         else
8260             break;
8261     }
8262
8263     if (ipv4_set && ipv6_set) {
8264         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8265         return -99;
8266     }
8267
8268     if ((!ipv4_set) && (!ipv6_set)) {
8269         errmsg ("no ipv4 nor ipv6 flag set\n");
8270         return -99;
8271     }
8272
8273     is_ipv6 = ipv6_set;
8274     vam->is_ipv6 = is_ipv6;
8275
8276     /* free old data */
8277     for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8278         vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8279     }
8280     vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8281
8282     M(IP_DUMP, ip_dump);
8283     mp->is_ipv6 = ipv6_set;
8284     S;
8285
8286     /* Use a control ping for synchronization */
8287     {
8288         vl_api_control_ping_t * mp;
8289         M(CONTROL_PING, control_ping);
8290         S;
8291     }
8292     W;
8293 }
8294
8295 static int
8296 api_ipsec_spd_add_del (vat_main_t * vam)
8297 {
8298 #if DPDK > 0
8299     unformat_input_t * i = vam->input;
8300     vl_api_ipsec_spd_add_del_t *mp;
8301     f64 timeout;
8302     u32 spd_id = ~0;
8303     u8 is_add = 1;
8304
8305     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8306         if (unformat (i, "spd_id %d", &spd_id))
8307             ;
8308         else if (unformat (i, "del"))
8309             is_add = 0;
8310         else {
8311             clib_warning ("parse error '%U'", format_unformat_error, i);
8312             return -99;
8313         }
8314     }
8315     if (spd_id == ~0) {
8316         errmsg ("spd_id must be set\n");
8317         return -99;
8318     }
8319
8320     M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8321
8322     mp->spd_id = ntohl(spd_id);
8323     mp->is_add = is_add;
8324
8325     S; W;
8326     /* NOTREACHED */
8327     return 0;
8328 #else
8329     clib_warning ("unsupported (no dpdk)");
8330     return -99;
8331 #endif
8332 }
8333
8334 static int
8335 api_ipsec_interface_add_del_spd (vat_main_t * vam)
8336 {
8337 #if DPDK > 0
8338     unformat_input_t * i = vam->input;
8339     vl_api_ipsec_interface_add_del_spd_t *mp;
8340     f64 timeout;
8341     u32 sw_if_index;
8342     u8 sw_if_index_set = 0;
8343     u32 spd_id = (u32) ~0;
8344     u8 is_add = 1;
8345
8346     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8347         if (unformat (i, "del"))
8348             is_add = 0;
8349         else if (unformat (i, "spd_id %d", &spd_id))
8350             ;
8351         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8352             sw_if_index_set = 1;
8353         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8354             sw_if_index_set = 1;
8355         else {
8356             clib_warning ("parse error '%U'", format_unformat_error, i);
8357             return -99;
8358         }
8359
8360     }
8361
8362     if (spd_id == (u32) ~0) {
8363         errmsg ("spd_id must be set\n");
8364         return -99;
8365     }
8366
8367     if (sw_if_index_set == 0) {
8368         errmsg ("missing interface name or sw_if_index\n");
8369         return -99;
8370     }
8371
8372     M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8373
8374     mp->spd_id = ntohl(spd_id);
8375     mp->sw_if_index = ntohl (sw_if_index);
8376     mp->is_add = is_add;
8377
8378     S; W;
8379     /* NOTREACHED */
8380     return 0;
8381 #else
8382     clib_warning ("unsupported (no dpdk)");
8383     return -99;
8384 #endif
8385 }
8386
8387 static int
8388 api_ipsec_spd_add_del_entry (vat_main_t * vam)
8389 {
8390 #if DPDK > 0
8391     unformat_input_t * i = vam->input;
8392     vl_api_ipsec_spd_add_del_entry_t *mp;
8393     f64 timeout;
8394     u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8395     u32 spd_id, sa_id, protocol = 0, policy = 0;
8396     i32 priority;
8397     u32 rport_start = 0, rport_stop = (u32) ~0;
8398     u32 lport_start = 0, lport_stop = (u32) ~0;
8399     ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8400     ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8401
8402     laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8403     laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8404     laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8405     laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8406     laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8407     laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8408
8409     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8410         if (unformat (i, "del"))
8411             is_add = 0;
8412         if (unformat (i, "outbound"))
8413             is_outbound = 1;
8414         if (unformat (i, "inbound"))
8415             is_outbound = 0;
8416         else if (unformat (i, "spd_id %d", &spd_id))
8417             ;
8418         else if (unformat (i, "sa_id %d", &sa_id))
8419             ;
8420         else if (unformat (i, "priority %d", &priority))
8421             ;
8422         else if (unformat (i, "protocol %d", &protocol))
8423             ;
8424         else if (unformat (i, "lport_start %d", &lport_start))
8425             ;
8426         else if (unformat (i, "lport_stop %d", &lport_stop))
8427             ;
8428         else if (unformat (i, "rport_start %d", &rport_start))
8429             ;
8430         else if (unformat (i, "rport_stop %d", &rport_stop))
8431             ;
8432         else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8433           {
8434             is_ipv6 = 0;
8435             is_ip_any =0;
8436           }
8437         else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8438           {
8439             is_ipv6 = 0;
8440             is_ip_any = 0;
8441           }
8442         else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8443           {
8444             is_ipv6 = 0;
8445             is_ip_any = 0;
8446           }
8447         else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8448           {
8449             is_ipv6 = 0;
8450             is_ip_any = 0;
8451           }
8452         else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8453           {
8454             is_ipv6 = 1;
8455             is_ip_any = 0;
8456           }
8457         else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8458           {
8459             is_ipv6 = 1;
8460             is_ip_any = 0;
8461           }
8462         else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8463           {
8464             is_ipv6 = 1;
8465             is_ip_any = 0;
8466           }
8467         else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8468           {
8469             is_ipv6 = 1;
8470             is_ip_any = 0;
8471           }
8472         else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8473           {
8474             if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8475                 clib_warning ("unsupported action: 'resolve'");
8476                 return -99;
8477             }
8478           }
8479         else {
8480             clib_warning ("parse error '%U'", format_unformat_error, i);
8481             return -99;
8482         }
8483
8484     }
8485
8486     M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8487
8488     mp->spd_id = ntohl(spd_id);
8489     mp->priority = ntohl(priority);
8490     mp->is_outbound = is_outbound;
8491
8492     mp->is_ipv6 = is_ipv6;
8493     if (is_ipv6 || is_ip_any) {
8494         clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8495         clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8496         clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8497         clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
8498     } else {
8499         clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8500         clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8501         clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8502         clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
8503     }
8504     mp->protocol = (u8) protocol;
8505     mp->local_port_start = ntohs((u16) lport_start);
8506     mp->local_port_stop = ntohs((u16) lport_stop);
8507     mp->remote_port_start = ntohs((u16) rport_start);
8508     mp->remote_port_stop = ntohs((u16) rport_stop);
8509     mp->policy = (u8) policy;
8510     mp->sa_id = ntohl(sa_id);
8511     mp->is_add = is_add;
8512     mp->is_ip_any = is_ip_any;
8513     S; W;
8514     /* NOTREACHED */
8515     return 0;
8516 #else
8517     clib_warning ("unsupported (no dpdk)");
8518     return -99;
8519 #endif
8520 }
8521
8522 static int
8523 api_ipsec_sad_add_del_entry (vat_main_t * vam)
8524 {
8525 #if DPDK > 0
8526     unformat_input_t * i = vam->input;
8527     vl_api_ipsec_sad_add_del_entry_t *mp;
8528     f64 timeout;
8529     u32 sad_id, spi;
8530     u8 * ck, * ik;
8531     u8 is_add = 1;
8532
8533     u8 protocol = IPSEC_PROTOCOL_AH;
8534     u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8535     u32 crypto_alg = 0, integ_alg = 0;
8536     ip4_address_t tun_src4;
8537     ip4_address_t tun_dst4;
8538     ip6_address_t tun_src6;
8539     ip6_address_t tun_dst6;
8540
8541     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8542         if (unformat (i, "del"))
8543             is_add = 0;
8544         else if (unformat (i, "sad_id %d", &sad_id))
8545             ;
8546         else if (unformat (i, "spi %d", &spi))
8547             ;
8548         else if (unformat (i, "esp"))
8549             protocol = IPSEC_PROTOCOL_ESP;
8550         else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8551             is_tunnel = 1;
8552             is_tunnel_ipv6 = 0;
8553         }
8554         else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8555             is_tunnel = 1;
8556             is_tunnel_ipv6 = 0;
8557         }
8558         else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8559             is_tunnel = 1;
8560             is_tunnel_ipv6 = 1;
8561         }
8562         else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8563             is_tunnel = 1;
8564             is_tunnel_ipv6 = 1;
8565         }
8566         else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8567             if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8568                 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8569                 clib_warning ("unsupported crypto-alg: '%U'",
8570                               format_ipsec_crypto_alg, crypto_alg);
8571                 return -99;
8572             }
8573         }
8574         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8575             ;
8576         else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8577             if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8578                 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8579                 clib_warning ("unsupported integ-alg: '%U'",
8580                               format_ipsec_integ_alg, integ_alg);
8581                 return -99;
8582             }
8583         }
8584         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8585             ;
8586         else {
8587             clib_warning ("parse error '%U'", format_unformat_error, i);
8588             return -99;
8589         }
8590
8591     }
8592
8593     M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8594
8595     mp->sad_id = ntohl(sad_id);
8596     mp->is_add = is_add;
8597     mp->protocol = protocol;
8598     mp->spi = ntohl(spi);
8599     mp->is_tunnel = is_tunnel;
8600     mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8601     mp->crypto_algorithm = crypto_alg;
8602     mp->integrity_algorithm = integ_alg;
8603     mp->crypto_key_length = vec_len(ck);
8604     mp->integrity_key_length = vec_len(ik);
8605
8606     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8607       mp->crypto_key_length = sizeof(mp->crypto_key);
8608
8609     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8610       mp->integrity_key_length = sizeof(mp->integrity_key);
8611
8612     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8613     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8614
8615     if (is_tunnel) {
8616       if (is_tunnel_ipv6) {
8617         clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8618         clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
8619       } else {
8620         clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8621         clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
8622       }
8623     }
8624
8625     S; W;
8626     /* NOTREACHED */
8627     return 0;
8628 #else
8629     clib_warning ("unsupported (no dpdk)");
8630     return -99;
8631 #endif
8632 }
8633
8634 static int
8635 api_ipsec_sa_set_key (vat_main_t * vam)
8636 {
8637 #if DPDK > 0
8638     unformat_input_t * i = vam->input;
8639     vl_api_ipsec_sa_set_key_t *mp;
8640     f64 timeout;
8641     u32 sa_id;
8642     u8 * ck, * ik;
8643
8644     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8645         if (unformat (i, "sa_id %d", &sa_id))
8646             ;
8647         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8648             ;
8649         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8650             ;
8651         else {
8652             clib_warning ("parse error '%U'", format_unformat_error, i);
8653             return -99;
8654         }
8655     }
8656
8657     M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
8658
8659     mp->sa_id = ntohl(sa_id);
8660     mp->crypto_key_length = vec_len(ck);
8661     mp->integrity_key_length = vec_len(ik);
8662
8663     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8664       mp->crypto_key_length = sizeof(mp->crypto_key);
8665
8666     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8667       mp->integrity_key_length = sizeof(mp->integrity_key);
8668
8669     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8670     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8671
8672     S; W;
8673     /* NOTREACHED */
8674     return 0;
8675 #else
8676     clib_warning ("unsupported (no dpdk)");
8677     return -99;
8678 #endif
8679 }
8680
8681 static int
8682 api_ikev2_profile_add_del (vat_main_t * vam)
8683 {
8684 #if DPDK > 0
8685     unformat_input_t * i = vam->input;
8686     vl_api_ikev2_profile_add_del_t * mp;
8687     f64 timeout;
8688     u8 is_add = 1;
8689     u8 * name = 0;
8690
8691     const char * valid_chars = "a-zA-Z0-9_";
8692
8693     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8694         if (unformat (i, "del"))
8695             is_add = 0;
8696         else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8697             vec_add1 (name, 0);
8698         else {
8699             errmsg ("parse error '%U'", format_unformat_error, i);
8700             return -99;
8701         }
8702     }
8703
8704     if (!vec_len (name)) {
8705         errmsg ("profile name must be specified");
8706         return -99;
8707     }
8708
8709     if (vec_len (name) > 64) {
8710         errmsg ("profile name too long");
8711         return -99;
8712     }
8713
8714     M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
8715
8716     clib_memcpy(mp->name, name, vec_len (name));
8717     mp->is_add = is_add;
8718     vec_free (name);
8719
8720     S; W;
8721     /* NOTREACHED */
8722     return 0;
8723 #else
8724     clib_warning ("unsupported (no dpdk)");
8725     return -99;
8726 #endif
8727 }
8728
8729 static int
8730 api_ikev2_profile_set_auth (vat_main_t * vam)
8731 {
8732 #if DPDK > 0
8733     unformat_input_t * i = vam->input;
8734     vl_api_ikev2_profile_set_auth_t * mp;
8735     f64 timeout;
8736     u8 * name = 0;
8737     u8 * data = 0;
8738     u32 auth_method = 0;
8739     u8 is_hex = 0;
8740
8741     const char * valid_chars = "a-zA-Z0-9_";
8742
8743     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8744         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8745             vec_add1 (name, 0);
8746         else if (unformat (i, "auth_method %U",
8747                            unformat_ikev2_auth_method, &auth_method))
8748             ;
8749         else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
8750             is_hex = 1;
8751         else if (unformat (i, "auth_data %v", &data))
8752             ;
8753         else {
8754             errmsg ("parse error '%U'", format_unformat_error, i);
8755             return -99;
8756         }
8757     }
8758
8759     if (!vec_len (name)) {
8760         errmsg ("profile name must be specified");
8761         return -99;
8762     }
8763
8764     if (vec_len (name) > 64) {
8765         errmsg ("profile name too long");
8766         return -99;
8767     }
8768
8769     if (!vec_len(data)) {
8770         errmsg ("auth_data must be specified");
8771         return -99;
8772     }
8773
8774     if (!auth_method) {
8775         errmsg ("auth_method must be specified");
8776         return -99;
8777     }
8778
8779     M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
8780
8781     mp->is_hex = is_hex;
8782     mp->auth_method = (u8) auth_method;
8783     mp->data_len = vec_len (data);
8784     clib_memcpy (mp->name, name, vec_len (name));
8785     clib_memcpy (mp->data, data, vec_len (data));
8786     vec_free (name);
8787     vec_free (data);
8788
8789     S; W;
8790     /* NOTREACHED */
8791     return 0;
8792 #else
8793     clib_warning ("unsupported (no dpdk)");
8794     return -99;
8795 #endif
8796 }
8797
8798 static int
8799 api_ikev2_profile_set_id (vat_main_t * vam)
8800 {
8801 #if DPDK > 0
8802     unformat_input_t * i = vam->input;
8803     vl_api_ikev2_profile_set_id_t * mp;
8804     f64 timeout;
8805     u8 * name = 0;
8806     u8 * data = 0;
8807     u8 is_local = 0;
8808     u32 id_type = 0;
8809     ip4_address_t ip4;
8810
8811     const char * valid_chars = "a-zA-Z0-9_";
8812
8813     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8814         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8815             vec_add1 (name, 0);
8816         else if (unformat (i, "id_type %U",
8817                            unformat_ikev2_id_type, &id_type))
8818             ;
8819         else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
8820           {
8821             data = vec_new(u8, 4);
8822             clib_memcpy(data, ip4.as_u8, 4);
8823           }
8824         else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
8825             ;
8826         else if (unformat (i, "id_data %v", &data))
8827             ;
8828         else if (unformat (i, "local"))
8829             is_local = 1;
8830         else if (unformat (i, "remote"))
8831             is_local = 0;
8832         else {
8833             errmsg ("parse error '%U'", format_unformat_error, i);
8834             return -99;
8835         }
8836     }
8837
8838     if (!vec_len (name)) {
8839         errmsg ("profile name must be specified");
8840         return -99;
8841     }
8842
8843     if (vec_len (name) > 64) {
8844         errmsg ("profile name too long");
8845         return -99;
8846     }
8847
8848     if (!vec_len(data)) {
8849         errmsg ("id_data must be specified");
8850         return -99;
8851     }
8852
8853     if (!id_type) {
8854         errmsg ("id_type must be specified");
8855         return -99;
8856     }
8857
8858     M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
8859
8860     mp->is_local = is_local;
8861     mp->id_type = (u8) id_type;
8862     mp->data_len = vec_len (data);
8863     clib_memcpy (mp->name, name, vec_len (name));
8864     clib_memcpy (mp->data, data, vec_len (data));
8865     vec_free (name);
8866     vec_free (data);
8867
8868     S; W;
8869     /* NOTREACHED */
8870     return 0;
8871 #else
8872     clib_warning ("unsupported (no dpdk)");
8873     return -99;
8874 #endif
8875 }
8876
8877 static int
8878 api_ikev2_profile_set_ts (vat_main_t * vam)
8879 {
8880 #if DPDK > 0
8881     unformat_input_t * i = vam->input;
8882     vl_api_ikev2_profile_set_ts_t * mp;
8883     f64 timeout;
8884     u8 * name = 0;
8885     u8 is_local = 0;
8886     u32 proto = 0, start_port = 0, end_port = (u32) ~0;
8887     ip4_address_t start_addr, end_addr;
8888
8889     const char * valid_chars = "a-zA-Z0-9_";
8890
8891     start_addr.as_u32 = 0;
8892     end_addr.as_u32 = (u32) ~0;
8893
8894     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8895         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8896             vec_add1 (name, 0);
8897         else if (unformat (i, "protocol %d", &proto))
8898             ;
8899         else if (unformat (i, "start_port %d", &start_port))
8900             ;
8901         else if (unformat (i, "end_port %d", &end_port))
8902             ;
8903         else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
8904             ;
8905         else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
8906             ;
8907         else if (unformat (i, "local"))
8908             is_local = 1;
8909         else if (unformat (i, "remote"))
8910             is_local = 0;
8911         else {
8912             errmsg ("parse error '%U'", format_unformat_error, i);
8913             return -99;
8914         }
8915     }
8916
8917     if (!vec_len (name)) {
8918         errmsg ("profile name must be specified");
8919         return -99;
8920     }
8921
8922     if (vec_len (name) > 64) {
8923         errmsg ("profile name too long");
8924         return -99;
8925     }
8926
8927     M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
8928
8929     mp->is_local = is_local;
8930     mp->proto = (u8) proto;
8931     mp->start_port = (u16) start_port;
8932     mp->end_port = (u16) end_port;
8933     mp->start_addr = start_addr.as_u32;
8934     mp->end_addr = end_addr.as_u32;
8935     clib_memcpy (mp->name, name, vec_len (name));
8936     vec_free (name);
8937
8938     S; W;
8939     /* NOTREACHED */
8940     return 0;
8941 #else
8942     clib_warning ("unsupported (no dpdk)");
8943     return -99;
8944 #endif
8945 }
8946
8947 static int
8948 api_ikev2_set_local_key (vat_main_t * vam)
8949 {
8950 #if DPDK > 0
8951     unformat_input_t * i = vam->input;
8952     vl_api_ikev2_set_local_key_t * mp;
8953     f64 timeout;
8954     u8 * file = 0;
8955
8956     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8957         if (unformat (i, "file %v", &file))
8958             vec_add1 (file, 0);
8959         else {
8960             errmsg ("parse error '%U'", format_unformat_error, i);
8961             return -99;
8962         }
8963     }
8964
8965     if (!vec_len (file)) {
8966         errmsg ("RSA key file must be specified");
8967         return -99;
8968     }
8969
8970     if (vec_len (file) > 256) {
8971         errmsg ("file name too long");
8972         return -99;
8973     }
8974
8975     M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
8976
8977     clib_memcpy (mp->key_file, file, vec_len (file));
8978     vec_free (file);
8979
8980     S; W;
8981     /* NOTREACHED */
8982     return 0;
8983 #else
8984     clib_warning ("unsupported (no dpdk)");
8985     return -99;
8986 #endif
8987 }
8988
8989 /*
8990  * MAP
8991  */
8992 static int api_map_add_domain (vat_main_t * vam)
8993 {
8994   unformat_input_t *i = vam->input;
8995   vl_api_map_add_domain_t *mp;
8996   f64 timeout;
8997
8998   ip4_address_t ip4_prefix;
8999   ip6_address_t ip6_prefix;
9000   ip6_address_t ip6_src;
9001   u32 num_m_args = 0;
9002   u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9003     psid_length;
9004   u8 is_translation = 0;
9005   u32 mtu = 0;
9006   u8 ip6_src_len = 128;
9007
9008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9009     if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9010                   &ip4_prefix, &ip4_prefix_len))
9011       num_m_args++;
9012     else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9013                        &ip6_prefix, &ip6_prefix_len))
9014       num_m_args++;
9015     else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9016       num_m_args++;
9017     else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9018       num_m_args++;
9019     else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9020       num_m_args++;
9021     else if (unformat (i, "psid-offset %d", &psid_offset))
9022       num_m_args++;
9023     else if (unformat (i, "psid-len %d", &psid_length))
9024       num_m_args++;
9025     else if (unformat (i, "mtu %d", &mtu))
9026       num_m_args++;
9027     else if (unformat (i, "map-t"))
9028       is_translation = 1;
9029     else {
9030       clib_warning ("parse error '%U'", format_unformat_error, i);
9031       return -99;
9032     }
9033   }
9034
9035   if (num_m_args != 6) {
9036     errmsg("mandatory argument(s) missing\n");
9037     return -99;
9038   }
9039
9040   /* Construct the API message */
9041   M(MAP_ADD_DOMAIN, map_add_domain);
9042
9043   clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
9044   mp->ip4_prefix_len = ip4_prefix_len;
9045
9046   clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
9047   mp->ip6_prefix_len = ip6_prefix_len;
9048
9049   clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
9050   mp->ip6_src_prefix_len = ip6_src_len;
9051
9052   mp->ea_bits_len = ea_bits_len;
9053   mp->psid_offset = psid_offset;
9054   mp->psid_length = psid_length;
9055   mp->is_translation = is_translation;
9056   mp->mtu = htons(mtu);
9057
9058   /* send it... */
9059   S;
9060
9061   /* Wait for a reply, return good/bad news  */
9062   W;
9063 }
9064
9065 static int api_map_del_domain (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_map_del_domain_t *mp;
9069   f64 timeout;
9070
9071   u32 num_m_args = 0;
9072   u32 index;
9073
9074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9075     if (unformat (i, "index %d", &index))
9076       num_m_args++;
9077     else {
9078       clib_warning ("parse error '%U'", format_unformat_error, i);
9079       return -99;
9080     }
9081   }
9082
9083   if (num_m_args != 1) {
9084     errmsg("mandatory argument(s) missing\n");
9085     return -99;
9086   }
9087
9088   /* Construct the API message */
9089   M(MAP_DEL_DOMAIN, map_del_domain);
9090
9091   mp->index = ntohl(index);
9092
9093   /* send it... */
9094   S;
9095
9096   /* Wait for a reply, return good/bad news  */
9097   W;
9098 }
9099
9100 static int api_map_add_del_rule (vat_main_t * vam)
9101 {
9102   unformat_input_t *i = vam->input;
9103   vl_api_map_add_del_rule_t *mp;
9104   f64 timeout;
9105   u8 is_add = 1;
9106   ip6_address_t ip6_dst;
9107   u32 num_m_args = 0, index, psid;
9108
9109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9110     if (unformat (i, "index %d", &index))
9111       num_m_args++;
9112     else if (unformat (i, "psid %d", &psid))
9113       num_m_args++;
9114     else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9115       num_m_args++;
9116     else if (unformat (i, "del")) {
9117       is_add = 0;
9118     } else {
9119       clib_warning ("parse error '%U'", format_unformat_error, i);
9120       return -99;
9121     }
9122   }
9123
9124   /* Construct the API message */
9125   M(MAP_ADD_DEL_RULE, map_add_del_rule);
9126
9127   mp->index = ntohl(index);
9128   mp->is_add = is_add;
9129   clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
9130   mp->psid = ntohs(psid);
9131
9132   /* send it... */
9133   S;
9134
9135   /* Wait for a reply, return good/bad news  */
9136   W;
9137 }
9138
9139 static int api_map_domain_dump (vat_main_t * vam)
9140 {
9141     vl_api_map_domain_dump_t *mp;
9142     f64 timeout;
9143
9144     /* Construct the API message */
9145     M(MAP_DOMAIN_DUMP, map_domain_dump);
9146
9147     /* send it... */
9148     S;
9149
9150     /* Use a control ping for synchronization */
9151     {
9152         vl_api_control_ping_t * mp;
9153         M(CONTROL_PING, control_ping);
9154         S;
9155     }
9156     W;
9157 }
9158
9159 static int api_map_rule_dump (vat_main_t * vam)
9160 {
9161     unformat_input_t *i = vam->input;
9162     vl_api_map_rule_dump_t *mp;
9163     f64 timeout;
9164     u32 domain_index = ~0;
9165
9166     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9167         if (unformat (i, "index %u", &domain_index))
9168             ;
9169         else
9170             break;
9171     }
9172
9173     if (domain_index == ~0) {
9174         clib_warning("parse error: domain index expected");
9175         return -99;
9176     }
9177
9178     /* Construct the API message */
9179     M(MAP_RULE_DUMP, map_rule_dump);
9180
9181     mp->domain_index = htonl(domain_index);
9182
9183     /* send it... */
9184     S;
9185
9186     /* Use a control ping for synchronization */
9187     {
9188         vl_api_control_ping_t * mp;
9189         M(CONTROL_PING, control_ping);
9190         S;
9191     }
9192     W;
9193 }
9194
9195 static void vl_api_map_add_domain_reply_t_handler
9196 (vl_api_map_add_domain_reply_t * mp)
9197 {
9198   vat_main_t * vam = &vat_main;
9199   i32 retval = ntohl(mp->retval);
9200
9201   if (vam->async_mode) {
9202       vam->async_errors += (retval < 0);
9203   } else {
9204       vam->retval = retval;
9205       vam->result_ready = 1;
9206   }
9207 }
9208
9209 static void vl_api_map_add_domain_reply_t_handler_json
9210 (vl_api_map_add_domain_reply_t * mp)
9211 {
9212   vat_main_t * vam = &vat_main;
9213   vat_json_node_t node;
9214
9215   vat_json_init_object(&node);
9216   vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9217   vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9218
9219   vat_json_print(vam->ofp, &node);
9220   vat_json_free(&node);
9221
9222   vam->retval = ntohl(mp->retval);
9223   vam->result_ready = 1;
9224 }
9225
9226 static int
9227 api_get_first_msg_id (vat_main_t * vam)
9228 {
9229     vl_api_get_first_msg_id_t * mp;
9230     f64 timeout;
9231     unformat_input_t * i = vam->input;
9232     u8 * name;
9233     u8 name_set = 0;
9234     
9235     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9236         if (unformat (i, "client %s", &name))
9237             name_set = 1;
9238         else 
9239             break;
9240     }
9241
9242     if (name_set == 0) {
9243         errmsg ("missing client name\n");
9244         return -99;
9245     }
9246     vec_add1 (name, 0);
9247
9248     if (vec_len (name) > 63) {
9249         errmsg ("client name too long\n");
9250         return -99;
9251     }
9252
9253     M(GET_FIRST_MSG_ID, get_first_msg_id);
9254     clib_memcpy (mp->name, name, vec_len(name));
9255     S; W;
9256     /* NOTREACHED */
9257     return 0;
9258 }
9259
9260 static int api_cop_interface_enable_disable (vat_main_t * vam)
9261 {
9262     unformat_input_t * line_input = vam->input;
9263     vl_api_cop_interface_enable_disable_t * mp;
9264     f64 timeout;
9265     u32 sw_if_index = ~0;
9266     u8 enable_disable = 1;
9267
9268     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9269         if (unformat (line_input, "disable"))
9270             enable_disable = 0;
9271         if (unformat (line_input, "enable"))
9272             enable_disable = 1;
9273         else if (unformat (line_input, "%U", unformat_sw_if_index,
9274                            vam, &sw_if_index))
9275             ;
9276         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9277             ;
9278         else
9279             break;
9280     }
9281         
9282     if (sw_if_index == ~0) {
9283         errmsg ("missing interface name or sw_if_index\n");
9284         return -99;
9285     }
9286
9287     /* Construct the API message */
9288     M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9289     mp->sw_if_index = ntohl(sw_if_index);
9290     mp->enable_disable = enable_disable;
9291
9292     /* send it... */
9293     S;
9294     /* Wait for the reply */
9295     W;
9296 }
9297
9298 static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9299 {
9300     unformat_input_t * line_input = vam->input;
9301     vl_api_cop_whitelist_enable_disable_t * mp;
9302     f64 timeout;
9303     u32 sw_if_index = ~0;
9304     u8 ip4=0, ip6=0, default_cop=0;
9305     u32 fib_id;
9306
9307     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9308         if (unformat (line_input, "ip4"))
9309             ip4 = 1;
9310         else if (unformat (line_input, "ip6"))
9311             ip6 = 1;
9312         else if (unformat (line_input, "default"))
9313             default_cop = 1;
9314         else if (unformat (line_input, "%U", unformat_sw_if_index,
9315                            vam, &sw_if_index))
9316             ;
9317         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9318             ;
9319         else if (unformat (line_input, "fib-id %d", &fib_id))
9320             ;
9321         else
9322             break;
9323     }
9324         
9325     if (sw_if_index == ~0) {
9326         errmsg ("missing interface name or sw_if_index\n");
9327         return -99;
9328     }
9329
9330     /* Construct the API message */
9331     M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9332     mp->sw_if_index = ntohl(sw_if_index);
9333     mp->fib_id = ntohl(fib_id);
9334     mp->ip4 = ip4;
9335     mp->ip6 = ip6;
9336     mp->default_cop = default_cop;
9337
9338     /* send it... */
9339     S;
9340     /* Wait for the reply */
9341     W;
9342 }
9343
9344 static int api_get_node_graph (vat_main_t * vam)
9345 {
9346     vl_api_get_node_graph_t * mp;
9347     f64 timeout;
9348
9349     M(GET_NODE_GRAPH, get_node_graph);
9350
9351     /* send it... */
9352     S;
9353     /* Wait for the reply */
9354     W;
9355 }
9356
9357 static int
9358 api_lisp_add_del_locator_set(vat_main_t * vam)
9359 {
9360     unformat_input_t * input = vam->input;
9361     vl_api_lisp_add_del_locator_set_t *mp;
9362     f64 timeout = ~0;
9363     u8  is_add = 1;
9364     u8 *locator_set_name = NULL;
9365     u8  locator_set_name_set = 0;
9366
9367     /* Parse args required to build the message */
9368     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9369         if (unformat(input, "del")) {
9370             is_add = 0;
9371         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9372             locator_set_name_set = 1;
9373         } else
9374             break;
9375     }
9376
9377     if (locator_set_name_set == 0) {
9378         errmsg ("missing locator-set name");
9379         return -99;
9380     }
9381
9382     if (vec_len(locator_set_name) > 64) {
9383         errmsg ("locator-set name too long\n");
9384         vec_free(locator_set_name);
9385         return -99;
9386     }
9387     vec_add1(locator_set_name, 0);
9388
9389     /* Construct the API message */
9390     M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9391
9392     mp->is_add = is_add;
9393     clib_memcpy(mp->locator_set_name, locator_set_name,
9394            vec_len(locator_set_name));
9395     vec_free(locator_set_name);
9396
9397     /* send it... */
9398     S;
9399
9400     /* Wait for a reply... */
9401     W;
9402
9403     /* NOTREACHED */
9404     return 0;
9405 }
9406
9407 static int
9408 api_lisp_add_del_locator(vat_main_t * vam)
9409 {
9410     unformat_input_t * input = vam->input;
9411     vl_api_lisp_add_del_locator_t *mp;
9412     f64 timeout = ~0;
9413     u32 tmp_if_index = ~0;
9414     u32 sw_if_index = ~0;
9415     u8  sw_if_index_set = 0;
9416     u8  sw_if_index_if_name_set = 0;
9417     u8  priority = ~0;
9418     u8  priority_set = 0;
9419     u8  weight = ~0;
9420     u8  weight_set = 0;
9421     u8  is_add = 1;
9422     u8  *locator_set_name = NULL;
9423     u8  locator_set_name_set = 0;
9424
9425     /* Parse args required to build the message */
9426     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9427         if (unformat(input, "del")) {
9428             is_add = 0;
9429         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9430             locator_set_name_set = 1;
9431         } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9432             &tmp_if_index)) {
9433             sw_if_index_if_name_set = 1;
9434             sw_if_index = tmp_if_index;
9435         } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9436             sw_if_index_set = 1;
9437             sw_if_index = tmp_if_index;
9438         } else if (unformat(input, "p %d", &priority)) {
9439             priority_set = 1;
9440         } else if (unformat(input, "w %d", &weight)) {
9441             weight_set = 1;
9442         } else
9443             break;
9444     }
9445
9446     if (locator_set_name_set == 0) {
9447         errmsg ("missing locator-set name");
9448         return -99;
9449     }
9450
9451     if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9452         errmsg ("missing sw_if_index");
9453         vec_free(locator_set_name);
9454         return -99;
9455     }
9456
9457     if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9458         errmsg ("cannot use both params interface name and sw_if_index");
9459         vec_free(locator_set_name);
9460         return -99;
9461     }
9462
9463     if (priority_set == 0) {
9464         errmsg ("missing locator-set priority\n");
9465         vec_free(locator_set_name);
9466         return -99;
9467     }
9468
9469     if (weight_set == 0) {
9470         errmsg ("missing locator-set weight\n");
9471         vec_free(locator_set_name);
9472         return -99;
9473     }
9474
9475     if (vec_len(locator_set_name) > 64) {
9476         errmsg ("locator-set name too long\n");
9477         vec_free(locator_set_name);
9478         return -99;
9479     }
9480     vec_add1(locator_set_name, 0);
9481
9482     /* Construct the API message */
9483     M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9484
9485     mp->is_add = is_add;
9486     mp->sw_if_index = ntohl(sw_if_index);
9487     mp->priority = priority;
9488     mp->weight = weight;
9489     clib_memcpy(mp->locator_set_name, locator_set_name,
9490            vec_len(locator_set_name));
9491     vec_free(locator_set_name);
9492
9493     /* send it... */
9494     S;
9495
9496     /* Wait for a reply... */
9497     W;
9498
9499     /* NOTREACHED */
9500     return 0;
9501 }
9502
9503 static int
9504 api_lisp_add_del_local_eid(vat_main_t * vam)
9505 {
9506     unformat_input_t * input = vam->input;
9507     vl_api_lisp_add_del_local_eid_t *mp;
9508     f64 timeout = ~0;
9509     u8 is_add = 1;
9510     u8 eidv4_set = 0;
9511     u8 eidv6_set = 0;
9512     ip4_address_t eidv4;
9513     ip6_address_t eidv6;
9514     u8 tmp_eid_lenght = ~0;
9515     u8 eid_lenght = ~0;
9516     u8 *locator_set_name = NULL;
9517     u8 locator_set_name_set = 0;
9518
9519     /* Parse args required to build the message */
9520     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9521         if (unformat(input, "del")) {
9522             is_add = 0;
9523         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9524             &eidv4, &tmp_eid_lenght)) {
9525             eid_lenght = tmp_eid_lenght;
9526             eidv4_set = 1;
9527         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9528             &eidv6, &tmp_eid_lenght)) {
9529             eid_lenght = tmp_eid_lenght;
9530             eidv6_set = 1;
9531         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9532             locator_set_name_set = 1;
9533         } else
9534             break;
9535     }
9536
9537     if (locator_set_name_set == 0) {
9538         errmsg ("missing locator-set name\n");
9539         return -99;
9540     }
9541
9542     if (vec_len(locator_set_name) > 64) {
9543         errmsg ("locator-set name too long\n");
9544         vec_free(locator_set_name);
9545         return -99;
9546     }
9547     vec_add1(locator_set_name, 0);
9548
9549     if (eidv4_set && eidv6_set) {
9550         errmsg ("both eid v4 and v6 addresses set\n");
9551         vec_free(locator_set_name);
9552         return -99;
9553     }
9554
9555     if (!eidv4_set && !eidv6_set) {
9556         errmsg ("eid addresses not set\n");
9557         vec_free(locator_set_name);
9558         return -99;
9559     }
9560
9561     /* Construct the API message */
9562     M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9563
9564     mp->is_add = is_add;
9565     if (eidv6_set) {
9566         mp->is_ipv6 = 1;
9567         clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
9568     } else {
9569         mp->is_ipv6 = 0;
9570         clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
9571     }
9572     mp->prefix_len = eid_lenght;
9573     clib_memcpy(mp->locator_set_name, locator_set_name,
9574            vec_len(locator_set_name));
9575     vec_free(locator_set_name);
9576
9577     /* send it... */
9578     S;
9579
9580     /* Wait for a reply... */
9581     W;
9582
9583     /* NOTREACHED */
9584     return 0;
9585 }
9586
9587 static int
9588 api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9589 {
9590     unformat_input_t * input = vam->input;
9591     vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9592     f64 timeout = ~0;
9593     u8 is_add = 1;
9594     u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
9595     u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
9596     ip4_address_t eidv4, slocv4, dlocv4;
9597     ip6_address_t eidv6, slocv6, dlocv6;
9598     u8 tmp_eid_lenght = ~0;
9599     u8 eid_lenght = ~0;
9600
9601     /* Parse args required to build the message */
9602     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9603         if (unformat(input, "del")) {
9604             is_add = 0;
9605         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9606                             &eidv4, &tmp_eid_lenght)) {
9607             eid_lenght = tmp_eid_lenght;
9608             eidv4_set = 1;
9609         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9610                             &eidv6, &tmp_eid_lenght)) {
9611             eid_lenght = tmp_eid_lenght;
9612             eidv6_set = 1;
9613         } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
9614             slocv4_set = 1;
9615         } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
9616             slocv6_set = 1;
9617         } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
9618             dlocv4_set = 1;
9619         } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
9620             dlocv6_set = 1;
9621         } else
9622             break;
9623     }
9624
9625     if (eidv4_set && eidv6_set) {
9626         errmsg ("both eid v4 and v6 addresses set\n");
9627         return -99;
9628     }
9629
9630     if (!eidv4_set && !eidv6_set) {
9631         errmsg ("eid addresses not set\n");
9632         return -99;
9633     }
9634
9635     if (slocv4_set && slocv6_set) {
9636         errmsg ("both source v4 and v6 addresses set\n");
9637         return -99;
9638     }
9639
9640     if (!slocv4_set && !slocv6_set) {
9641         errmsg ("source addresses not set\n");
9642         return -99;
9643     }
9644
9645     if (dlocv4_set && dlocv6_set) {
9646         errmsg ("both destination v4 and v6 addresses set\n");
9647         return -99;
9648     }
9649
9650     if (dlocv4_set && dlocv6_set) {
9651         errmsg ("destination addresses not set\n");
9652         return -99;
9653     }
9654
9655     if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
9656         errmsg ("mixing type of source and destination address\n");
9657         return -99;
9658     }
9659
9660     /* Construct the API message */
9661     M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
9662
9663     mp->is_add = is_add;
9664     if (eidv6_set) {
9665         mp->eid_is_ipv6 = 1;
9666         clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
9667     } else {
9668         mp->eid_is_ipv6 = 0;
9669         clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
9670     }
9671     mp->eid_prefix_len = eid_lenght;
9672     if (slocv6_set) {
9673         mp->address_is_ipv6 = 1;
9674         clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
9675         clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
9676     } else {
9677         mp->address_is_ipv6 = 0;
9678         clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
9679         clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
9680     }
9681
9682     /* send it... */
9683     S;
9684
9685     /* Wait for a reply... */
9686     W;
9687
9688     /* NOTREACHED */
9689     return 0;
9690 }
9691
9692 static int
9693 api_lisp_add_del_map_resolver(vat_main_t * vam)
9694 {
9695     unformat_input_t * input = vam->input;
9696     vl_api_lisp_add_del_map_resolver_t *mp;
9697     f64 timeout = ~0;
9698     u8 is_add = 1;
9699     u8 ipv4_set = 0;
9700     u8 ipv6_set = 0;
9701     ip4_address_t ipv4;
9702     ip6_address_t ipv6;
9703
9704     /* Parse args required to build the message */
9705     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9706         if (unformat(input, "del")) {
9707             is_add = 0;
9708         } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
9709             ipv4_set = 1;
9710         } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
9711             ipv6_set = 1;
9712         } else
9713             break;
9714     }
9715
9716     if (ipv4_set && ipv6_set) {
9717         errmsg ("both eid v4 and v6 addresses set\n");
9718         return -99;
9719     }
9720
9721     if (!ipv4_set && !ipv6_set) {
9722         errmsg ("eid addresses not set\n");
9723         return -99;
9724     }
9725
9726     /* Construct the API message */
9727     M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
9728
9729     mp->is_add = is_add;
9730     if (ipv6_set) {
9731         mp->is_ipv6 = 1;
9732         clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
9733     } else {
9734         mp->is_ipv6 = 0;
9735         clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
9736     }
9737
9738     /* send it... */
9739     S;
9740
9741     /* Wait for a reply... */
9742     W;
9743
9744     /* NOTREACHED */
9745     return 0;
9746 }
9747
9748 static int
9749 api_lisp_gpe_enable_disable (vat_main_t * vam)
9750 {
9751   unformat_input_t * input = vam->input;
9752   vl_api_lisp_gpe_enable_disable_t *mp;
9753   f64 timeout = ~0;
9754   u8 is_set = 0;
9755   u8 is_en = 1;
9756
9757   /* Parse args required to build the message */
9758   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9759       if (unformat(input, "enable")) {
9760           is_set = 1;
9761           is_en = 1;
9762       } else if (unformat(input, "disable")) {
9763           is_set = 1;
9764           is_en = 0;
9765       } else
9766           break;
9767   }
9768
9769   if (is_set == 0) {
9770       errmsg("Value not set\n");
9771       return -99;
9772   }
9773
9774   /* Construct the API message */
9775   M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
9776
9777   mp->is_en = is_en;
9778
9779   /* send it... */
9780   S;
9781
9782   /* Wait for a reply... */
9783   W;
9784
9785   /* NOTREACHED */
9786   return 0;
9787 }
9788
9789 static int
9790 api_lisp_gpe_add_del_iface(vat_main_t * vam)
9791 {
9792     unformat_input_t * input = vam->input;
9793     vl_api_lisp_gpe_add_del_iface_t *mp;
9794     f64 timeout = ~0;
9795     u8 is_set = 0;
9796     u8 is_add = 1;
9797     u32 table_id, vni;
9798
9799     /* Parse args required to build the message */
9800     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9801         if (unformat(input, "up")) {
9802             is_set = 1;
9803             is_add = 1;
9804         } else if (unformat(input, "down")) {
9805             is_set = 1;
9806             is_add = 0;
9807         } else if (unformat(input, "table_id %d", &table_id)) {
9808             ;
9809         } else if (unformat(input, "vni %d", &vni)) {
9810             ;
9811         } else
9812             break;
9813     }
9814
9815     if (is_set == 0) {
9816         errmsg("Value not set\n");
9817         return -99;
9818     }
9819
9820     /* Construct the API message */
9821     M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
9822
9823     mp->is_add = is_add;
9824     mp->table_id = table_id;
9825     mp->vni = vni;
9826
9827     /* send it... */
9828     S;
9829
9830     /* Wait for a reply... */
9831     W;
9832
9833     /* NOTREACHED */
9834     return 0;
9835 }
9836
9837 static int
9838 api_lisp_locator_set_dump(vat_main_t *vam)
9839 {
9840     vl_api_lisp_locator_set_dump_t *mp;
9841     f64 timeout = ~0;
9842
9843     if (!vam->json_output) {
9844         fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
9845                 "Locator-set", "Locator", "Priority", "Weight");
9846     }
9847
9848     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
9849     /* send it... */
9850     S;
9851
9852     /* Use a control ping for synchronization */
9853     {
9854         vl_api_control_ping_t * mp;
9855         M(CONTROL_PING, control_ping);
9856         S;
9857     }
9858     /* Wait for a reply... */
9859     W;
9860
9861     /* NOTREACHED */
9862     return 0;
9863 }
9864
9865 static int
9866 api_lisp_local_eid_table_dump(vat_main_t *vam)
9867 {
9868     vl_api_lisp_local_eid_table_dump_t *mp;
9869     f64 timeout = ~0;
9870
9871     if (!vam->json_output) {
9872         fformat(vam->ofp, "%=20s%=30s\n",
9873                 "Locator-set", "Eid");
9874     }
9875
9876     M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
9877     /* send it... */
9878     S;
9879
9880     /* Use a control ping for synchronization */
9881     {
9882         vl_api_control_ping_t * mp;
9883         M(CONTROL_PING, control_ping);
9884         S;
9885     }
9886     /* Wait for a reply... */
9887     W;
9888
9889     /* NOTREACHED */
9890     return 0;
9891 }
9892
9893 static int
9894 api_lisp_gpe_tunnel_dump(vat_main_t *vam)
9895 {
9896     vl_api_lisp_gpe_tunnel_dump_t *mp;
9897     f64 timeout = ~0;
9898
9899     if (!vam->json_output) {
9900         fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
9901                 "%=16s%=16s%=16s%=16s%=16s\n",
9902                 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
9903                 "Decap next", "Lisp version", "Flags", "Next protocol",
9904                 "ver_res", "res", "iid");
9905     }
9906
9907     M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
9908     /* send it... */
9909     S;
9910
9911     /* Use a control ping for synchronization */
9912     {
9913         vl_api_control_ping_t * mp;
9914         M(CONTROL_PING, control_ping);
9915         S;
9916     }
9917     /* Wait for a reply... */
9918     W;
9919
9920     /* NOTREACHED */
9921     return 0;
9922 }
9923
9924 static int
9925 api_lisp_map_resolver_dump(vat_main_t *vam)
9926 {
9927     vl_api_lisp_map_resolver_dump_t *mp;
9928     f64 timeout = ~0;
9929
9930     if (!vam->json_output) {
9931         fformat(vam->ofp, "%=20s\n",
9932                 "Map resolver");
9933     }
9934
9935     M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
9936     /* send it... */
9937     S;
9938
9939     /* Use a control ping for synchronization */
9940     {
9941         vl_api_control_ping_t * mp;
9942         M(CONTROL_PING, control_ping);
9943         S;
9944     }
9945     /* Wait for a reply... */
9946     W;
9947
9948     /* NOTREACHED */
9949     return 0;
9950 }
9951
9952 static int q_or_quit (vat_main_t * vam)
9953 {
9954     longjmp (vam->jump_buf, 1);
9955     return 0; /* not so much */
9956 }
9957 static int q (vat_main_t * vam) {return q_or_quit (vam);}
9958 static int quit (vat_main_t * vam) {return q_or_quit (vam);}
9959
9960 static int comment (vat_main_t * vam)
9961 {
9962     return 0;
9963 }
9964
9965 static int cmd_cmp (void * a1, void * a2)
9966 {
9967   u8 ** c1 = a1;
9968   u8 ** c2 = a2;
9969
9970   return strcmp ((char *)(c1[0]), (char *)(c2[0]));
9971 }
9972
9973 static int help (vat_main_t * vam)
9974 {
9975     u8 ** cmds = 0;
9976     u8 * name = 0;
9977     hash_pair_t * p;
9978     unformat_input_t * i = vam->input;
9979     int j;
9980
9981     if (unformat (i, "%s", &name)) {
9982         uword *hs;
9983
9984         vec_add1(name, 0);
9985
9986         hs = hash_get_mem (vam->help_by_name, name);
9987         if (hs)
9988             fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
9989         else
9990             fformat (vam->ofp, "No such msg / command '%s'\n", name);
9991         vec_free(name);
9992         return 0;
9993     }
9994
9995     fformat(vam->ofp, "Help is available for the following:\n");
9996
9997     hash_foreach_pair (p, vam->function_by_name, 
9998     ({
9999         vec_add1 (cmds, (u8 *)(p->key));
10000     }));
10001
10002     vec_sort_with_function (cmds, cmd_cmp);
10003
10004     for (j = 0; j < vec_len(cmds); j++)
10005         fformat (vam->ofp, "%s\n", cmds[j]);
10006
10007     vec_free (cmds);
10008     return 0;
10009 }
10010
10011 static int set (vat_main_t * vam)
10012 {
10013     u8 * name = 0, * value = 0;
10014     unformat_input_t * i = vam->input;
10015
10016     if (unformat (i, "%s", &name)) {
10017         /* The input buffer is a vector, not a string. */
10018         value = vec_dup (i->buffer);
10019         vec_delete (value, i->index, 0);
10020         /* Almost certainly has a trailing newline */
10021         if (value[vec_len(value)-1] == '\n')
10022             value[vec_len(value)-1] = 0;
10023         /* Make sure it's a proper string, one way or the other */
10024         vec_add1 (value, 0);
10025         (void) clib_macro_set_value (&vam->macro_main, 
10026                                      (char *)name, (char *)value);
10027     }
10028     else
10029         errmsg ("usage: set <name> <value>\n");
10030
10031     vec_free (name);
10032     vec_free (value);
10033     return 0;
10034 }
10035
10036 static int unset (vat_main_t * vam)
10037 {
10038     u8 * name = 0;
10039
10040     if (unformat (vam->input, "%s", &name))
10041         if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
10042             errmsg ("unset: %s wasn't set\n", name);
10043     vec_free (name);
10044     return 0;
10045 }
10046
10047 typedef struct {
10048     u8 * name;
10049     u8 * value;
10050 } macro_sort_t;
10051
10052
10053 static int macro_sort_cmp (void * a1, void * a2)
10054 {
10055   macro_sort_t * s1 = a1;
10056   macro_sort_t * s2 = a2;
10057
10058   return strcmp ((char *)(s1->name), (char *)(s2->name));
10059 }
10060
10061 static int dump_macro_table (vat_main_t * vam)
10062 {
10063     macro_sort_t * sort_me = 0, * sm;    
10064     int i;
10065     hash_pair_t * p;
10066
10067     hash_foreach_pair (p, vam->macro_main.the_value_table_hash, 
10068     ({
10069         vec_add2 (sort_me, sm, 1);
10070         sm->name = (u8 *)(p->key);
10071         sm->value = (u8 *) (p->value[0]);
10072     }));
10073     
10074     vec_sort_with_function (sort_me, macro_sort_cmp);
10075
10076     if (vec_len(sort_me))
10077         fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
10078     else
10079         fformat (vam->ofp, "The macro table is empty...\n");
10080
10081     for (i = 0; i < vec_len (sort_me); i++)
10082         fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
10083                  sort_me[i].value);
10084     return 0;
10085 }
10086
10087 static int dump_node_table (vat_main_t * vam)
10088 {
10089     int i, j;
10090     vlib_node_t * node, * next_node;
10091
10092     if (vec_len (vam->graph_nodes) == 0) {
10093         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10094         return 0;
10095     }
10096
10097     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
10098         node = vam->graph_nodes[i];
10099         fformat (vam->ofp, "[%d] %s\n", i, node->name);
10100         for (j = 0; j < vec_len (node->next_nodes); j++) {
10101             if (node->next_nodes[j] != ~0) {
10102                 next_node = vam->graph_nodes[node->next_nodes[j]];
10103                 fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
10104             }
10105         }
10106     }
10107     return 0;
10108 }
10109
10110 static int search_node_table (vat_main_t * vam)
10111 {
10112     unformat_input_t * line_input = vam->input;
10113     u8 * node_to_find;
10114     int j;
10115     vlib_node_t * node, * next_node;
10116     uword * p;
10117
10118     if (vam->graph_node_index_by_name == 0) {
10119         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10120         return 0;
10121     }
10122
10123     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10124         if (unformat (line_input, "%s", &node_to_find)) {
10125             vec_add1 (node_to_find, 0);
10126             p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
10127             if (p == 0) {
10128                 fformat (vam->ofp, "%s not found...\n", node_to_find);
10129                 goto out;
10130             }
10131             node = vam->graph_nodes[p[0]];
10132             fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
10133             for (j = 0; j < vec_len (node->next_nodes); j++) {
10134                 if (node->next_nodes[j] != ~0) {
10135                     next_node = vam->graph_nodes[node->next_nodes[j]];
10136                     fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
10137                 }
10138             }
10139         }
10140             
10141         else {
10142             clib_warning ("parse error '%U'", format_unformat_error, 
10143                           line_input);
10144             return -99;
10145         }
10146
10147     out:
10148         vec_free(node_to_find);
10149         
10150     }
10151
10152     return 0;        
10153 }
10154
10155
10156 static int script (vat_main_t * vam)
10157 {
10158     u8 * s = 0;
10159     char * save_current_file;
10160     unformat_input_t save_input;
10161     jmp_buf save_jump_buf;
10162     u32 save_line_number;
10163
10164     FILE * new_fp, * save_ifp;
10165
10166     if (unformat (vam->input, "%s", &s)) {
10167         new_fp = fopen ((char *)s, "r");
10168         if (new_fp == 0) {
10169             errmsg ("Couldn't open script file %s\n", s);
10170             vec_free (s);
10171             return -99;
10172         }
10173     } else {
10174         errmsg ("Missing script name\n");
10175         return -99;
10176     }
10177
10178     clib_memcpy (&save_input, &vam->input, sizeof (save_input));
10179     clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
10180     save_ifp = vam->ifp;
10181     save_line_number = vam->input_line_number;
10182     save_current_file = (char *) vam->current_file;
10183
10184     vam->input_line_number = 0;
10185     vam->ifp = new_fp;
10186     vam->current_file = s;
10187     do_one_file (vam);
10188
10189     clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
10190     clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
10191     vam->ifp = save_ifp;
10192     vam->input_line_number = save_line_number;
10193     vam->current_file = (u8 *) save_current_file;
10194     vec_free (s);
10195
10196     return 0;
10197 }
10198
10199 static int echo (vat_main_t * vam)
10200 {
10201     fformat (vam->ofp, "%v", vam->input->buffer);
10202     return 0;
10203 }
10204
10205 /* List of API message constructors, CLI names map to api_xxx */
10206 #define foreach_vpe_api_msg                                             \
10207 _(create_loopback,"[mac <mac-addr>]")                                   \
10208 _(sw_interface_dump,"")                                                 \
10209 _(sw_interface_set_flags,                                               \
10210   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
10211 _(sw_interface_add_del_address,                                         \
10212   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
10213 _(sw_interface_set_table,                                               \
10214   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
10215 _(sw_interface_set_vpath,                                               \
10216   "<intfc> | sw_if_index <id> enable | disable")                        \
10217 _(sw_interface_set_l2_xconnect,                                         \
10218   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10219   "enable | disable")                                                   \
10220 _(sw_interface_set_l2_bridge,                                           \
10221   "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n"         \
10222   "[shg <split-horizon-group>] [bvi]\n"                                 \
10223   "enable | disable")                                                   \
10224 _(bridge_domain_add_del,                                                \
10225   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
10226 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
10227 _(l2fib_add_del,                                                        \
10228   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
10229 _(l2_flags,                                                             \
10230   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
10231 _(bridge_flags,                                                         \
10232   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
10233 _(tap_connect,                                                          \
10234   "tapname <name> mac <mac-addr> | random-mac")                         \
10235 _(tap_modify,                                                           \
10236   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
10237 _(tap_delete,                                                           \
10238   "<vpp-if-name> | sw_if_index <id>")                                   \
10239 _(sw_interface_tap_dump, "")                                            \
10240 _(ip_add_del_route,                                                     \
10241   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
10242   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
10243   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
10244   "[multipath] [count <n>]")                                            \
10245 _(proxy_arp_add_del,                                                    \
10246   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
10247 _(proxy_arp_intfc_enable_disable,                                       \
10248   "<intfc> | sw_if_index <id> enable | disable")                        \
10249 _(mpls_add_del_encap,                                                   \
10250   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
10251 _(mpls_add_del_decap,                                                   \
10252   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
10253 _(mpls_gre_add_del_tunnel,                                              \
10254   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
10255   "adj <ip4-address>/<mask-width> [del]")                               \
10256 _(sw_interface_set_unnumbered,                                          \
10257   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
10258 _(ip_neighbor_add_del,                                                  \
10259   "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>")       \
10260 _(reset_vrf, "vrf <id> [ipv6]")                                         \
10261 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
10262 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
10263   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
10264   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
10265   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
10266 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
10267 _(reset_fib, "vrf <n> [ipv6]")                                          \
10268 _(dhcp_proxy_config,                                                    \
10269   "svr <v46-address> src <v46-address>\n"                               \
10270    "insert-cid <n> [del]")                                              \
10271 _(dhcp_proxy_config_2,                                                  \
10272   "svr <v46-address> src <v46-address>\n"                               \
10273    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
10274 _(dhcp_proxy_set_vss,                                                   \
10275   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
10276 _(dhcp_client_config,                                                   \
10277   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
10278 _(set_ip_flow_hash,                                                     \
10279   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
10280 _(sw_interface_ip6_enable_disable,                                      \
10281   "<intfc> | sw_if_index <id> enable | disable")                        \
10282 _(sw_interface_ip6_set_link_local_address,                              \
10283   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
10284 _(sw_interface_ip6nd_ra_prefix,                                         \
10285   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
10286   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
10287   "[nolink] [isno]")                                                    \
10288 _(sw_interface_ip6nd_ra_config,                                         \
10289   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
10290   "[life <n>] [count <n>] [interval <n>] [surpress]\n"                  \
10291   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
10292 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
10293 _(l2_patch_add_del,                                                     \
10294   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
10295   "enable | disable")                                                   \
10296 _(mpls_ethernet_add_del_tunnel,                                         \
10297   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
10298   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
10299 _(mpls_ethernet_add_del_tunnel_2,                                       \
10300   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
10301   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
10302 _(sr_tunnel_add_del,                                                    \
10303   "src <ip6-addr> dst <ip6-addr>/<mw> (next <ip6-addr>)+\n"             \
10304   " [tag <ip6-addr>]* [clean] [reroute]")                               \
10305 _(classify_add_del_table,                                               \
10306   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
10307   "[del] mask <mask-value>\n"                                           \
10308   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
10309 _(classify_add_del_session,                                             \
10310   "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n"    \
10311   "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]")           \
10312 _(classify_set_interface_ip_table,                                      \
10313   "<intfc> | sw_if_index <nn> table <nn>")                              \
10314 _(classify_set_interface_l2_tables,                                     \
10315   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
10316   "  [other-table <nn>]")                                               \
10317 _(get_node_index, "node <node-name")                                    \
10318 _(add_node_next, "node <node-name> next <next-node-name>")              \
10319 _(l2tpv3_create_tunnel,                                                 \
10320   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
10321   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
10322   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
10323 _(l2tpv3_set_tunnel_cookies,                                            \
10324   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
10325   "[new_remote_cookie <nn>]\n")                                         \
10326 _(l2tpv3_interface_enable_disable,                                      \
10327   "<intfc> | sw_if_index <nn> enable | disable")                        \
10328 _(l2tpv3_set_lookup_key,                                                \
10329   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
10330 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
10331 _(vxlan_add_del_tunnel,                                                 \
10332   "src <ip4-addr> dst <ip4-addr> vni [encap-vrf-id <nn>]\n"             \
10333   " [decap-next l2|ip4|ip6] [del]")                                     \
10334 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
10335 _(l2_fib_clear_table, "")                                               \
10336 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
10337 _(l2_interface_vlan_tag_rewrite,                                        \
10338   "<intfc> | sw_if_index <nn> \n"                                       \
10339   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
10340   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
10341 _(create_vhost_user_if,                                                 \
10342         "socket <filename> [server] [renumber <dev_instance>] "         \
10343         "[mac <mac_address>]")                                          \
10344 _(modify_vhost_user_if,                                                 \
10345         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
10346         "[server] [renumber <dev_instance>]")                           \
10347 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
10348 _(sw_interface_vhost_user_dump, "")                                     \
10349 _(show_version, "")                                                     \
10350 _(nsh_gre_add_del_tunnel,                                               \
10351   "src <ip4-addr> dst <ip4-addr>"                                       \
10352   "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n"                  \
10353   "[encap-fib-id <nn>] [decap-fib-id <nn>] [o-bit <1|0>]\n"             \
10354   "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n"   \
10355   "[tlv <xx>][del]")                                                    \
10356 _(nsh_vxlan_gpe_add_del_tunnel,                                         \
10357   "src <ip4-addr> dst <ip4-addr> vni <nn>\n"                            \
10358   "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n"                  \
10359   "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [o-bit <1|0>]\n"             \
10360   "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n"   \
10361   "[tlv <xx>][del]")                                                    \
10362 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
10363 _(lisp_gpe_add_del_tunnel,                                              \
10364   "src <ip4-addr> dst <ip4-addr> iid <nn>|iidx <0xnn>\n"                \
10365   "[encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                           \
10366   "[n-bit][l-bit][e-bit][v-bit][i-bit][p-bit][not-p-bit][o-bit]\n"      \
10367   "[next-ip4][next-ip6][next-ethernet][next-nsh]\n"                     \
10368   "[decap-next [ip4|ip6|ethernet|nsh-encap|<nn>]][del]")                \
10369 _(interface_name_renumber,                                              \
10370   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
10371 _(input_acl_set_interface,                                              \
10372   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
10373   "  [l2-table <nn>] [del]")                                            \
10374 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
10375 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
10376 _(ip_dump, "ipv4 | ipv6")                                               \
10377 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
10378 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
10379   "  spid_id <n> ")                                                     \
10380 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
10381   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
10382   "  integ_alg <alg> integ_key <hex>")                                  \
10383 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
10384   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
10385   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
10386   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
10387 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
10388 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
10389 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
10390   "(auth_data 0x<data> | auth_data <data>)")                            \
10391 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
10392   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
10393 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
10394   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
10395   "(local|remote)")                                                     \
10396 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
10397 _(delete_loopback,"sw_if_index <nn>")                                   \
10398 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
10399 _(map_add_domain,                                                       \
10400   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
10401   "ip6-src <ip6addr> "                                                  \
10402   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
10403 _(map_del_domain, "index <n>")                                          \
10404 _(map_add_del_rule,                                                     \
10405   "index <n> psid <n> dst <ip6addr> [del]")                             \
10406 _(map_domain_dump, "")                                                  \
10407 _(map_rule_dump, "index <map-domain>")                                  \
10408 _(want_interface_events,  "enable|disable")                             \
10409 _(want_stats,"enable|disable")                                          \
10410 _(get_first_msg_id, "client <name>")                                    \
10411 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
10412 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
10413   "fib-id <nn> [ip4][ip6][default]")                                    \
10414 _(get_node_graph, " ")                                                  \
10415 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
10416 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
10417   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
10418   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
10419 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
10420   " vrf_id <nn>  add | pop | none")                                     \
10421 _(trace_profile_del, "")                                                \
10422 _(lisp_add_del_locator_set, "locator-set <locator_name> [del]")         \
10423 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
10424                         "iface <intf> | sw_if_index <sw_if_index> "     \
10425                         "p <priority> w <weight> [del]")                \
10426 _(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> "                       \
10427                           "locator-set <locator_name> [del]")           \
10428 _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
10429     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
10430 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
10431 _(lisp_gpe_enable_disable, "enable|disable")                            \
10432 _(lisp_gpe_add_del_iface, "up|down")                                    \
10433 _(lisp_locator_set_dump, "")                                            \
10434 _(lisp_local_eid_table_dump, "")                                        \
10435 _(lisp_gpe_tunnel_dump, "")                                             \
10436 _(lisp_map_resolver_dump, "")
10437
10438 /* List of command functions, CLI names map directly to functions */
10439 #define foreach_cli_function                                    \
10440 _(comment, "usage: comment <ignore-rest-of-line>")              \
10441 _(dump_interface_table, "usage: dump_interface_table")          \
10442 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
10443 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
10444 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
10445 _(dump_stats_table, "usage: dump_stats_table")                  \
10446 _(dump_macro_table, "usage: dump_macro_table ")                 \
10447 _(dump_node_table, "usage: dump_node_table")                    \
10448 _(echo, "usage: echo <message>")                                \
10449 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
10450 _(help, "usage: help")                                          \
10451 _(q, "usage: quit")                                             \
10452 _(quit, "usage: quit")                                          \
10453 _(search_node_table, "usage: search_node_table <name>...")      \
10454 _(set, "usage: set <variable-name> <value>")                    \
10455 _(script, "usage: script <file-name>")                          \
10456 _(unset, "usage: unset <variable-name>")
10457
10458 #define _(N,n)                                  \
10459     static void vl_api_##n##_t_handler_uni      \
10460     (vl_api_##n##_t * mp)                       \
10461     {                                           \
10462         vat_main_t * vam = &vat_main;           \
10463         if (vam->json_output) {                 \
10464             vl_api_##n##_t_handler_json(mp);    \
10465         } else {                                \
10466             vl_api_##n##_t_handler(mp);         \
10467         }                                       \
10468     }
10469 foreach_vpe_api_reply_msg;
10470 #undef _
10471
10472 void vat_api_hookup (vat_main_t *vam)
10473 {
10474 #define _(N,n)                                                  \
10475     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
10476                            vl_api_##n##_t_handler_uni,          \
10477                            vl_noop_handler,                     \
10478                            vl_api_##n##_t_endian,               \
10479                            vl_api_##n##_t_print,                \
10480                            sizeof(vl_api_##n##_t), 1); 
10481     foreach_vpe_api_reply_msg;
10482 #undef _
10483
10484     vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
10485
10486     vam->sw_if_index_by_interface_name = 
10487         hash_create_string (0, sizeof (uword));
10488
10489     vam->function_by_name = 
10490         hash_create_string (0, sizeof(uword));
10491
10492     vam->help_by_name = 
10493         hash_create_string (0, sizeof(uword));
10494
10495     /* API messages we can send */
10496 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
10497     foreach_vpe_api_msg;
10498 #undef _
10499
10500     /* Help strings */
10501 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10502     foreach_vpe_api_msg;
10503 #undef _
10504
10505     /* CLI functions */
10506 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
10507     foreach_cli_function;
10508 #undef _
10509
10510     /* Help strings */
10511 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
10512     foreach_cli_function;
10513 #undef _
10514 }
10515
10516 #undef vl_api_version
10517 #define vl_api_version(n,v) static u32 vpe_api_version = v;
10518 #include <api/vpe.api.h>
10519 #undef vl_api_version
10520
10521 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
10522 {
10523     /* 
10524      * Send the main API signature in slot 0. This bit of code must
10525      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
10526      */
10527     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
10528 }