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