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