iOAM trace configuration APIs
[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 l2tpv3 tunnel interfaces */
2623     M(SW_INTERFACE_DUMP, sw_interface_dump);
2624     mp->name_filter_valid = 1;
2625     strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter-1));
2626     S;
2627
2628     /* Use a control ping for synchronization */
2629     {
2630         vl_api_control_ping_t * mp;
2631         M(CONTROL_PING, control_ping);
2632         S;
2633     }
2634     W;
2635 }
2636
2637 static int api_sw_interface_set_flags (vat_main_t * vam)
2638 {
2639     unformat_input_t * i = vam->input;
2640     vl_api_sw_interface_set_flags_t *mp;
2641     f64 timeout;
2642     u32 sw_if_index;
2643     u8 sw_if_index_set = 0;
2644     u8 admin_up = 0, link_up = 0;
2645     
2646     /* Parse args required to build the message */
2647     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2648         if (unformat (i, "admin-up"))
2649             admin_up = 1;
2650         else if (unformat (i, "admin-down"))
2651             admin_up = 0;
2652         else if (unformat (i, "link-up"))
2653             link_up = 1;
2654         else if (unformat (i, "link-down"))
2655             link_up = 0;
2656         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2657             sw_if_index_set = 1;
2658         else if (unformat (i, "sw_if_index %d", &sw_if_index))
2659             sw_if_index_set = 1;
2660         else
2661             break;
2662     }
2663
2664     if (sw_if_index_set == 0) {
2665         errmsg ("missing interface name or sw_if_index\n");
2666         return -99;
2667     }
2668
2669     /* Construct the API message */
2670     M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
2671     mp->sw_if_index = ntohl (sw_if_index);
2672     mp->admin_up_down = admin_up;
2673     mp->link_up_down = link_up;
2674
2675     /* send it... */
2676     S;
2677
2678     /* Wait for a reply, return the good/bad news... */
2679     W;
2680 }
2681
2682 static int api_sw_interface_clear_stats (vat_main_t * vam)
2683 {
2684     unformat_input_t * i = vam->input;
2685     vl_api_sw_interface_clear_stats_t *mp;
2686     f64 timeout;
2687     u32 sw_if_index;
2688     u8 sw_if_index_set = 0;
2689
2690     /* Parse args required to build the message */
2691     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2692         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2693             sw_if_index_set = 1;
2694         else if (unformat (i, "sw_if_index %d", &sw_if_index))
2695             sw_if_index_set = 1;
2696         else
2697             break;
2698     }
2699
2700     /* Construct the API message */
2701     M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
2702
2703     if (sw_if_index_set == 1)
2704         mp->sw_if_index = ntohl (sw_if_index);
2705     else
2706         mp->sw_if_index = ~0;
2707
2708     /* send it... */
2709     S;
2710
2711     /* Wait for a reply, return the good/bad news... */
2712     W;
2713 }
2714
2715 static int api_sw_interface_add_del_address (vat_main_t * vam)
2716 {
2717     unformat_input_t * i = vam->input;
2718     vl_api_sw_interface_add_del_address_t *mp;
2719     f64 timeout;
2720     u32 sw_if_index;
2721     u8 sw_if_index_set = 0;
2722     u8 is_add = 1, del_all = 0;
2723     u32 address_length = 0;
2724     u8 v4_address_set = 0;
2725     u8 v6_address_set = 0;
2726     ip4_address_t v4address;
2727     ip6_address_t v6address;
2728     
2729     /* Parse args required to build the message */
2730     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2731         if (unformat (i, "del-all"))
2732             del_all = 1;
2733         else if (unformat (i, "del"))
2734             is_add = 0;
2735         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2736             sw_if_index_set = 1;
2737         else if (unformat (i, "sw_if_index %d", &sw_if_index))
2738             sw_if_index_set = 1;
2739         else if (unformat (i, "%U/%d", 
2740                            unformat_ip4_address, &v4address, 
2741                            &address_length))
2742             v4_address_set = 1;
2743         else if (unformat (i, "%U/%d", 
2744                            unformat_ip6_address, &v6address, 
2745                            &address_length))
2746             v6_address_set = 1;
2747         else
2748             break;
2749     }
2750
2751     if (sw_if_index_set == 0) {
2752         errmsg ("missing interface name or sw_if_index\n");
2753         return -99;
2754     }
2755     if (v4_address_set && v6_address_set) {
2756         errmsg ("both v4 and v6 addresses set\n");
2757         return -99;
2758     }
2759     if (!v4_address_set && !v6_address_set && !del_all) {
2760         errmsg ("no addresses set\n");
2761         return -99;
2762     }
2763
2764     /* Construct the API message */
2765     M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
2766
2767     mp->sw_if_index = ntohl (sw_if_index);
2768     mp->is_add = is_add;
2769     mp->del_all = del_all;
2770     if (v6_address_set) {
2771         mp->is_ipv6 = 1;
2772         memcpy (mp->address, &v6address, sizeof (v6address));
2773     } else {
2774         memcpy (mp->address, &v4address, sizeof (v4address));
2775     }
2776     mp->address_length = address_length;
2777
2778     /* send it... */
2779     S;
2780
2781     /* Wait for a reply, return good/bad news  */
2782     W;
2783 }
2784
2785 static int api_sw_interface_set_table (vat_main_t * vam)
2786 {
2787     unformat_input_t * i = vam->input;
2788     vl_api_sw_interface_set_table_t *mp;
2789     f64 timeout;
2790     u32 sw_if_index, vrf_id = 0;
2791     u8 sw_if_index_set = 0;
2792     u8 is_ipv6 = 0;
2793     
2794     /* Parse args required to build the message */
2795     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2796         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2797             sw_if_index_set = 1;
2798         else if (unformat (i, "sw_if_index %d", &sw_if_index))
2799             sw_if_index_set = 1;
2800         else if (unformat (i, "vrf %d", &vrf_id))
2801             ;
2802         else if (unformat (i, "ipv6"))
2803             is_ipv6 = 1;
2804         else
2805             break;
2806     }
2807
2808     if (sw_if_index_set == 0) {
2809         errmsg ("missing interface name or sw_if_index\n");
2810         return -99;
2811     }
2812
2813     /* Construct the API message */
2814     M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
2815
2816     mp->sw_if_index = ntohl (sw_if_index);
2817     mp->is_ipv6 = is_ipv6;
2818     mp->vrf_id = ntohl (vrf_id);
2819
2820     /* send it... */
2821     S;
2822
2823     /* Wait for a reply... */
2824     W;
2825 }
2826
2827 static int api_sw_interface_set_vpath (vat_main_t * vam)
2828 {
2829     unformat_input_t * i = vam->input;
2830     vl_api_sw_interface_set_vpath_t *mp;
2831     f64 timeout;
2832     u32 sw_if_index = 0;
2833     u8 sw_if_index_set = 0;
2834     u8 is_enable = 0;
2835     
2836     /* Parse args required to build the message */
2837     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2838         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
2839             sw_if_index_set = 1;
2840         else if (unformat (i, "sw_if_index %d", &sw_if_index))
2841             sw_if_index_set = 1;
2842         else if (unformat (i, "enable"))
2843             is_enable = 1;
2844         else if (unformat (i, "disable"))
2845             is_enable = 0;
2846         else
2847             break;
2848     }
2849
2850     if (sw_if_index_set == 0) {
2851         errmsg ("missing interface name or sw_if_index\n");
2852         return -99;
2853     }
2854
2855     /* Construct the API message */
2856     M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
2857
2858     mp->sw_if_index = ntohl (sw_if_index);
2859     mp->enable = is_enable;
2860
2861     /* send it... */
2862     S;
2863
2864     /* Wait for a reply... */
2865     W;
2866 }
2867
2868 static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
2869 {
2870     unformat_input_t * i = vam->input;
2871     vl_api_sw_interface_set_l2_xconnect_t *mp;
2872     f64 timeout;
2873     u32 rx_sw_if_index;
2874     u8 rx_sw_if_index_set = 0;
2875     u32 tx_sw_if_index;
2876     u8 tx_sw_if_index_set = 0;
2877     u8 enable = 1;
2878     
2879     /* Parse args required to build the message */
2880     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2881         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
2882             rx_sw_if_index_set = 1;     
2883         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
2884             tx_sw_if_index_set = 1;
2885         else if (unformat (i, "rx")) {
2886             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2887                 if (unformat (i, "%U", unformat_sw_if_index, vam,
2888                               &rx_sw_if_index))
2889                     rx_sw_if_index_set = 1;
2890             } else
2891                 break;
2892         } else if (unformat (i, "tx")) {
2893             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2894                 if (unformat (i, "%U", unformat_sw_if_index, vam,
2895                               &tx_sw_if_index))
2896                     tx_sw_if_index_set = 1;
2897             } else
2898                 break;
2899         } else if (unformat (i, "enable"))
2900             enable = 1;
2901         else if (unformat (i, "disable")) 
2902             enable = 0;
2903         else
2904             break;
2905     }
2906
2907     if (rx_sw_if_index_set == 0) {
2908         errmsg ("missing rx interface name or rx_sw_if_index\n");
2909         return -99;
2910     }
2911
2912     if (enable && (tx_sw_if_index_set == 0)) {
2913         errmsg ("missing tx interface name or tx_sw_if_index\n");
2914         return -99;
2915     }
2916     
2917     M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
2918
2919     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
2920     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
2921     mp->enable = enable;
2922
2923     S; W;
2924     /* NOTREACHED */
2925     return 0;
2926 }
2927
2928 static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
2929 {
2930     unformat_input_t * i = vam->input;
2931     vl_api_sw_interface_set_l2_bridge_t *mp;
2932     f64 timeout;
2933     u32 rx_sw_if_index;
2934     u8 rx_sw_if_index_set = 0;
2935     u32 bd_id;
2936     u8 bd_id_set = 0;
2937     u8 bvi = 0;
2938     u32 shg = 0;
2939     u8 enable = 1;
2940     
2941     /* Parse args required to build the message */
2942     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2943         if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
2944             rx_sw_if_index_set = 1;     
2945         else if (unformat (i, "bd_id %d", &bd_id))
2946             bd_id_set = 1;
2947         else if (unformat (i, "%U", unformat_sw_if_index, vam,
2948                            &rx_sw_if_index))
2949             rx_sw_if_index_set = 1;
2950         else if (unformat (i, "shg %d", &shg)) 
2951             ;
2952         else if (unformat (i, "bvi"))
2953             bvi = 1;
2954         else if (unformat (i, "enable"))
2955             enable = 1;
2956         else if (unformat (i, "disable")) 
2957             enable = 0;
2958         else
2959             break;
2960     }
2961
2962     if (rx_sw_if_index_set == 0) {
2963         errmsg ("missing rx interface name or sw_if_index\n");
2964         return -99;
2965     }
2966
2967     if (enable && (bd_id_set == 0)) {
2968         errmsg ("missing bridge domain\n");
2969         return -99;
2970     }
2971     
2972     M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
2973
2974     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
2975     mp->bd_id = ntohl(bd_id);
2976     mp->shg = (u8)shg;
2977     mp->bvi = bvi;
2978     mp->enable = enable;
2979
2980     S; W;
2981     /* NOTREACHED */
2982     return 0;
2983 }
2984
2985 static int api_bridge_domain_dump (vat_main_t * vam)
2986 {
2987     unformat_input_t * i = vam->input;
2988     vl_api_bridge_domain_dump_t *mp;
2989     f64 timeout;
2990     u32 bd_id = ~0;
2991
2992     /* Parse args required to build the message */
2993     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
2994         if (unformat (i, "bd_id %d", &bd_id))
2995             ;
2996         else
2997             break;
2998     }
2999
3000     M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3001     mp->bd_id = ntohl(bd_id);
3002     S;
3003
3004     /* Use a control ping for synchronization */
3005     {
3006         vl_api_control_ping_t * mp;
3007         M(CONTROL_PING, control_ping);
3008         S;
3009     }
3010
3011     W;
3012     /* NOTREACHED */
3013     return 0;
3014 }
3015
3016 static int api_bridge_domain_add_del (vat_main_t * vam)
3017 {
3018     unformat_input_t * i = vam->input;
3019     vl_api_bridge_domain_add_del_t *mp;
3020     f64 timeout;
3021     u32 bd_id = ~0;
3022     u8 is_add = 1;
3023     u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3024
3025     /* Parse args required to build the message */
3026     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3027         if (unformat (i, "bd_id %d", &bd_id))
3028             ;
3029         else if (unformat (i, "flood %d", &flood))
3030              ;
3031         else if (unformat (i, "uu-flood %d", &uu_flood))
3032              ;
3033         else if (unformat (i, "forward %d", &forward))
3034              ;
3035         else if (unformat (i, "learn %d", &learn))
3036              ;
3037         else if (unformat (i, "arp-term %d", &arp_term))
3038              ;
3039         else if (unformat (i, "del")) {
3040              is_add = 0;
3041              flood = uu_flood = forward = learn = 0;
3042         }
3043         else
3044             break;
3045     }
3046
3047     if (bd_id == ~0) {
3048         errmsg ("missing bridge domain\n");
3049         return -99;
3050     }
3051
3052     M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3053
3054     mp->bd_id = ntohl(bd_id);
3055     mp->flood = flood;
3056     mp->uu_flood = uu_flood;
3057     mp->forward = forward;
3058     mp->learn = learn;
3059     mp->arp_term = arp_term;
3060     mp->is_add = is_add;
3061
3062     S; W;
3063     /* NOTREACHED */
3064     return 0;
3065 }
3066
3067 static int api_l2fib_add_del (vat_main_t * vam)
3068 {
3069     unformat_input_t * i = vam->input;
3070     vl_api_l2fib_add_del_t *mp;
3071     f64 timeout;
3072     u64 mac = 0;
3073     u8 mac_set = 0;
3074     u32 bd_id;
3075     u8 bd_id_set = 0;
3076     u32 sw_if_index;
3077     u8 sw_if_index_set = 0;
3078     u8 is_add = 1;
3079     u8 static_mac = 0;
3080     u8 filter_mac = 0;
3081
3082     /* Parse args required to build the message */
3083     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3084         if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3085             mac_set = 1;
3086         else if (unformat (i, "bd_id %d", &bd_id))
3087             bd_id_set = 1;
3088         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3089             sw_if_index_set = 1;        
3090         else if (unformat (i, "sw_if")) {
3091             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3092                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3093                     sw_if_index_set = 1;
3094             } else
3095                 break;
3096         } else if (unformat (i, "static"))
3097                 static_mac = 1;
3098         else if (unformat (i, "filter")) {
3099                 filter_mac = 1;
3100                 static_mac = 1;
3101         } else if (unformat (i, "del"))
3102                 is_add = 0;
3103         else
3104             break;
3105     }
3106
3107     if (mac_set == 0) {
3108         errmsg ("missing mac address\n");
3109         return -99;
3110     }
3111
3112     if (bd_id_set == 0) {
3113         errmsg ("missing bridge domain\n");
3114         return -99;
3115     }
3116
3117     if (is_add && (sw_if_index_set == 0)) {
3118         errmsg ("missing interface name or sw_if_index\n");
3119         return -99;
3120     }
3121
3122     M(L2FIB_ADD_DEL, l2fib_add_del);
3123
3124     mp->mac = mac;
3125     mp->bd_id = ntohl(bd_id);
3126     mp->is_add = is_add;
3127
3128     if (is_add) {
3129         mp->sw_if_index = ntohl(sw_if_index);
3130         mp->static_mac = static_mac;
3131         mp->filter_mac = filter_mac;
3132     }
3133     
3134     S; W;
3135     /* NOTREACHED */
3136     return 0;
3137 }
3138
3139 static int api_l2_flags (vat_main_t * vam)
3140 {
3141     unformat_input_t * i = vam->input;
3142     vl_api_l2_flags_t *mp;
3143     f64 timeout;
3144     u32 sw_if_index;
3145     u32 feature_bitmap = 0;
3146     u8 sw_if_index_set = 0;
3147
3148     /* Parse args required to build the message */
3149     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3150         if (unformat (i, "sw_if_index %d", &sw_if_index))
3151             sw_if_index_set = 1;        
3152         else if (unformat (i, "sw_if")) {
3153             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3154                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3155                     sw_if_index_set = 1;
3156             } else
3157                 break;
3158         } else if (unformat (i, "learn"))
3159             feature_bitmap |= L2INPUT_FEAT_LEARN;
3160         else if (unformat (i, "forward"))
3161             feature_bitmap |= L2INPUT_FEAT_FWD;
3162         else if (unformat (i, "flood"))
3163             feature_bitmap |= L2INPUT_FEAT_FLOOD;
3164         else if (unformat (i, "uu-flood"))
3165             feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3166         else
3167             break;
3168     }
3169
3170     if (sw_if_index_set == 0) {
3171         errmsg ("missing interface name or sw_if_index\n");
3172         return -99;
3173     }
3174
3175     M(L2_FLAGS, l2_flags);
3176
3177     mp->sw_if_index = ntohl(sw_if_index);
3178     mp->feature_bitmap = ntohl(feature_bitmap);
3179
3180     S; W;
3181     /* NOTREACHED */
3182     return 0;
3183 }
3184
3185 static int api_bridge_flags (vat_main_t * vam)
3186 {
3187     unformat_input_t * i = vam->input;
3188     vl_api_bridge_flags_t *mp;
3189     f64 timeout;
3190     u32 bd_id;
3191     u8 bd_id_set = 0;
3192     u8 is_set = 1;
3193     u32 flags = 0;
3194
3195     /* Parse args required to build the message */
3196     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3197         if (unformat (i, "bd_id %d", &bd_id))
3198             bd_id_set = 1;
3199         else if (unformat (i, "learn"))
3200             flags |= L2_LEARN;
3201         else if (unformat (i, "forward"))
3202             flags |= L2_FWD;
3203         else if (unformat (i, "flood"))
3204             flags |= L2_FLOOD;
3205         else if (unformat (i, "uu-flood"))
3206             flags |= L2_UU_FLOOD;
3207         else if (unformat (i, "arp-term"))
3208             flags |= L2_ARP_TERM;
3209         else if (unformat (i, "off"))
3210             is_set = 0;
3211         else if (unformat (i, "disable"))
3212             is_set = 0;
3213         else
3214             break;
3215     }
3216
3217     if (bd_id_set == 0) {
3218         errmsg ("missing bridge domain\n");
3219         return -99;
3220     }
3221
3222     M(BRIDGE_FLAGS, bridge_flags);
3223
3224     mp->bd_id = ntohl(bd_id);
3225     mp->feature_bitmap = ntohl(flags);
3226     mp->is_set = is_set;
3227
3228     S; W;
3229     /* NOTREACHED */
3230     return 0;
3231 }
3232
3233 static int api_bd_ip_mac_add_del (vat_main_t * vam)
3234 {
3235     unformat_input_t * i = vam->input;
3236     vl_api_bd_ip_mac_add_del_t *mp;
3237     f64 timeout;
3238     u32 bd_id;
3239     u8 is_ipv6 = 0;
3240     u8 is_add = 1;
3241     u8 bd_id_set = 0;
3242     u8 ip_set = 0;
3243     u8 mac_set = 0;
3244     ip4_address_t v4addr;
3245     ip6_address_t v6addr;
3246     u8 macaddr[6];
3247     
3248
3249     /* Parse args required to build the message */
3250     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3251         if (unformat (i, "bd_id %d", &bd_id)) {
3252             bd_id_set++;
3253         } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3254             ip_set++;
3255         } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3256             ip_set++;
3257             is_ipv6++;
3258         } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3259             mac_set++;
3260         } else if (unformat (i, "del"))
3261             is_add = 0;
3262         else
3263             break;
3264     }
3265
3266     if (bd_id_set == 0) {
3267         errmsg ("missing bridge domain\n");
3268         return -99;
3269     } else if (ip_set == 0) {
3270         errmsg ("missing IP address\n");
3271         return -99;
3272     } else if (mac_set == 0) {
3273         errmsg ("missing MAC address\n");
3274         return -99;
3275     }
3276
3277     M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3278
3279     mp->bd_id = ntohl(bd_id);
3280     mp->is_ipv6 = is_ipv6;
3281     mp->is_add = is_add;
3282     if (is_ipv6)
3283          memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3284     else memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3285     memcpy (mp->mac_address, macaddr, 6);
3286     S; W;
3287     /* NOTREACHED */
3288     return 0;
3289 }
3290
3291 static int api_tap_connect (vat_main_t * vam)
3292 {
3293     unformat_input_t * i = vam->input;
3294     vl_api_tap_connect_t *mp;
3295     f64 timeout;
3296     u8 mac_address[6];
3297     u8 random_mac = 1;
3298     u8 name_set = 0;
3299     u8 * tap_name;
3300
3301     memset (mac_address, 0, sizeof (mac_address));
3302     
3303     /* Parse args required to build the message */
3304     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3305         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3306             random_mac = 0;
3307         }
3308         else if (unformat (i, "random-mac"))
3309             random_mac = 1;
3310         else if (unformat (i, "tapname %s", &tap_name))
3311             name_set = 1;
3312         else
3313             break;
3314     }
3315
3316     if (name_set == 0) {
3317         errmsg ("missing tap name\n");
3318         return -99;
3319     }
3320     if (vec_len (tap_name) > 63) {
3321         errmsg ("tap name too long\n");
3322     }
3323     vec_add1 (tap_name, 0);
3324         
3325     /* Construct the API message */
3326     M(TAP_CONNECT, tap_connect);
3327
3328     mp->use_random_mac = random_mac;
3329     memcpy (mp->mac_address, mac_address, 6);
3330     memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3331     vec_free (tap_name);
3332
3333     /* send it... */
3334     S;
3335
3336     /* Wait for a reply... */
3337     W;
3338 }
3339
3340 static int api_tap_modify (vat_main_t * vam)
3341 {
3342     unformat_input_t * i = vam->input;
3343     vl_api_tap_modify_t *mp;
3344     f64 timeout;
3345     u8 mac_address[6];
3346     u8 random_mac = 1;
3347     u8 name_set = 0;
3348     u8 * tap_name;
3349     u32 sw_if_index = ~0;
3350     u8 sw_if_index_set = 0;
3351
3352     memset (mac_address, 0, sizeof (mac_address));
3353     
3354     /* Parse args required to build the message */
3355     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3356         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3357             sw_if_index_set = 1;
3358         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3359             sw_if_index_set = 1;
3360         else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3361             random_mac = 0;
3362         }
3363         else if (unformat (i, "random-mac"))
3364             random_mac = 1;
3365         else if (unformat (i, "tapname %s", &tap_name))
3366             name_set = 1;
3367         else
3368             break;
3369     }
3370
3371     if (sw_if_index_set == 0) {
3372         errmsg ("missing vpp interface name");
3373         return -99;
3374     }
3375     if (name_set == 0) {
3376         errmsg ("missing tap name\n");
3377         return -99;
3378     }
3379     if (vec_len (tap_name) > 63) {
3380         errmsg ("tap name too long\n");
3381     }
3382     vec_add1 (tap_name, 0);
3383         
3384     /* Construct the API message */
3385     M(TAP_MODIFY, tap_modify);
3386
3387     mp->use_random_mac = random_mac;
3388     mp->sw_if_index = ntohl(sw_if_index);
3389     memcpy (mp->mac_address, mac_address, 6);
3390     memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3391     vec_free (tap_name);
3392
3393     /* send it... */
3394     S;
3395
3396     /* Wait for a reply... */
3397     W;
3398 }
3399
3400 static int api_tap_delete (vat_main_t * vam)
3401 {
3402     unformat_input_t * i = vam->input;
3403     vl_api_tap_delete_t *mp;
3404     f64 timeout;
3405     u32 sw_if_index = ~0;
3406     u8 sw_if_index_set = 0;
3407
3408     /* Parse args required to build the message */
3409     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3410         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3411             sw_if_index_set = 1;
3412         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3413             sw_if_index_set = 1;
3414         else
3415             break;
3416     }
3417
3418     if (sw_if_index_set == 0) {
3419         errmsg ("missing vpp interface name");
3420         return -99;
3421     }
3422         
3423     /* Construct the API message */
3424     M(TAP_DELETE, tap_delete);
3425
3426     mp->sw_if_index = ntohl(sw_if_index);
3427
3428     /* send it... */
3429     S;
3430
3431     /* Wait for a reply... */
3432     W;
3433 }
3434
3435 static int api_ip_add_del_route (vat_main_t * vam)
3436 {
3437     unformat_input_t * i = vam->input;
3438     vl_api_ip_add_del_route_t *mp;
3439     f64 timeout;
3440     u32 sw_if_index = 0, vrf_id = 0;
3441     u8 sw_if_index_set = 0;
3442     u8 is_ipv6 = 0;
3443     u8 is_local = 0, is_drop = 0;
3444     u8 create_vrf_if_needed = 0;
3445     u8 is_add = 1;
3446     u8 next_hop_weight = 1;
3447     u8 not_last = 0;
3448     u8 is_multipath = 0;
3449     u8 address_set = 0;
3450     u8 address_length_set = 0;
3451     u32 lookup_in_vrf = 0;
3452     u32 resolve_attempts = 0;
3453     u32 dst_address_length = 0;
3454     u8 next_hop_set = 0;
3455     ip4_address_t v4_dst_address, v4_next_hop_address;
3456     ip6_address_t v6_dst_address, v6_next_hop_address;
3457     int count = 1;
3458     int j;
3459     f64 before = 0;
3460     u32 random_add_del = 0;
3461     u32 * random_vector = 0;
3462     uword * random_hash;
3463     u32 random_seed = 0xdeaddabe;
3464     u32 classify_table_index = ~0;
3465     u8 is_classify = 0;
3466     
3467     /* Parse args required to build the message */
3468     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3469         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3470             sw_if_index_set = 1;
3471         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3472             sw_if_index_set = 1;
3473         else if (unformat (i, "%U", unformat_ip4_address,
3474                            &v4_dst_address)) {
3475             address_set = 1;
3476             is_ipv6 = 0;
3477         }
3478         else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
3479             address_set = 1;
3480             is_ipv6 = 1;
3481         }
3482         else if (unformat (i, "/%d", &dst_address_length)) {
3483             address_length_set = 1;
3484         }
3485         
3486         else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address, 
3487                                            &v4_next_hop_address)) {
3488             next_hop_set = 1;
3489         }
3490         else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address, 
3491                                            &v6_next_hop_address)) {
3492             next_hop_set = 1;
3493         }
3494         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3495             ;
3496         else if (unformat (i, "weight %d", &next_hop_weight))
3497             ;
3498         else if (unformat (i, "drop")) {
3499             is_drop = 1;
3500         } else if (unformat (i, "local")) {
3501             is_local = 1;
3502         } else if (unformat (i, "classify %d", &classify_table_index)) {
3503             is_classify = 1;
3504         } else if (unformat (i, "del"))
3505             is_add = 0;
3506         else if (unformat (i, "add"))
3507             is_add = 1;
3508         else if (unformat (i, "not-last"))
3509             not_last = 1;
3510         else if (unformat (i, "multipath"))
3511             is_multipath = 1;
3512         else if (unformat (i, "vrf %d", &vrf_id))
3513             ;
3514         else if (unformat (i, "create-vrf"))
3515             create_vrf_if_needed = 1;
3516         else if (unformat (i, "count %d", &count))
3517             ;
3518         else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
3519             ;
3520         else if (unformat (i, "random"))
3521             random_add_del = 1;
3522         else if (unformat (i, "seed %d", &random_seed))
3523             ;
3524         else {
3525             clib_warning ("parse error '%U'", format_unformat_error, i);
3526             return -99;
3527         }
3528     }
3529
3530     if (resolve_attempts > 0 && sw_if_index_set == 0) {
3531         errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
3532         return -99;
3533     }
3534     
3535     if (!next_hop_set && !is_drop && !is_local && !is_classify) {
3536         errmsg ("next hop / local / drop / classify not set\n");
3537         return -99;
3538     }
3539
3540     if (address_set == 0) {
3541         errmsg ("missing addresses\n");
3542         return -99;
3543     }
3544
3545     if (address_length_set == 0) {
3546         errmsg ("missing address length\n");
3547         return -99;
3548     }
3549     
3550     /* Generate a pile of unique, random routes */
3551     if (random_add_del) {
3552         u32 this_random_address;
3553         random_hash = hash_create (count, sizeof(uword));
3554
3555         hash_set (random_hash, v4_next_hop_address.as_u32, 1);
3556         for (j = 0; j <= count; j++) {
3557             do {
3558                 this_random_address = random_u32 (&random_seed);
3559                 this_random_address = 
3560                     clib_host_to_net_u32 (this_random_address);
3561             } while (hash_get (random_hash, this_random_address));
3562             vec_add1 (random_vector, this_random_address);
3563             hash_set (random_hash, this_random_address, 1);
3564         }
3565         hash_free (random_hash);
3566         v4_dst_address.as_u32 = random_vector[0];
3567     }
3568
3569     if (count > 1) {
3570         /* Turn on async mode */
3571         vam->async_mode = 1;
3572         vam->async_errors = 0;
3573         before = vat_time_now(vam);
3574     }
3575
3576     for (j = 0; j < count; j++) {
3577         /* Construct the API message */
3578         M(IP_ADD_DEL_ROUTE, ip_add_del_route);
3579     
3580         mp->next_hop_sw_if_index = ntohl (sw_if_index);
3581         mp->vrf_id = ntohl (vrf_id);
3582         if (resolve_attempts > 0) {
3583             mp->resolve_attempts = ntohl (resolve_attempts);
3584             mp->resolve_if_needed = 1;
3585         }
3586         mp->create_vrf_if_needed = create_vrf_if_needed;
3587     
3588         mp->is_add = is_add;
3589         mp->is_drop = is_drop;
3590         mp->is_ipv6 = is_ipv6;
3591         mp->is_local = is_local;
3592         mp->is_classify = is_classify;
3593         mp->is_multipath = is_multipath;
3594         mp->not_last = not_last;
3595         mp->next_hop_weight = next_hop_weight;
3596         mp->dst_address_length = dst_address_length;
3597         mp->lookup_in_vrf = ntohl(lookup_in_vrf);
3598         mp->classify_table_index = ntohl(classify_table_index);
3599
3600         if (is_ipv6){
3601             memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
3602             if (next_hop_set)
3603                 memcpy (mp->next_hop_address, &v6_next_hop_address, 
3604                         sizeof (v6_next_hop_address));
3605             increment_v6_address (&v6_dst_address);
3606         } else {
3607             memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
3608             if (next_hop_set)
3609                 memcpy (mp->next_hop_address, &v4_next_hop_address, 
3610                         sizeof (v4_next_hop_address));
3611             if (random_add_del)
3612                 v4_dst_address.as_u32 = random_vector[j+1];
3613             else
3614                 increment_v4_address (&v4_dst_address);
3615         }
3616         /* send it... */
3617         S;
3618     }
3619
3620     /* When testing multiple add/del ops, use a control-ping to sync */
3621     if (count > 1) {
3622         vl_api_control_ping_t * mp;
3623         f64 after;
3624
3625         /* Shut off async mode */
3626         vam->async_mode = 0;
3627
3628         M(CONTROL_PING, control_ping);
3629         S;
3630
3631         timeout = vat_time_now(vam) + 1.0;
3632         while (vat_time_now (vam) < timeout)
3633             if (vam->result_ready == 1)
3634                 goto out;
3635         vam->retval = -99;
3636
3637     out:
3638         if (vam->retval == -99)
3639             errmsg ("timeout\n");
3640
3641         if (vam->async_errors > 0) {
3642             errmsg ("%d asynchronous errors\n", vam->async_errors);
3643             vam->retval = -98;
3644         }
3645         vam->async_errors = 0;
3646         after = vat_time_now(vam);
3647
3648         fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
3649                 count, after - before, count / (after - before));
3650     } else {
3651         /* Wait for a reply... */
3652         W;
3653     }
3654
3655     /* Return the good/bad news */
3656     return (vam->retval);
3657 }
3658
3659 static int api_proxy_arp_add_del (vat_main_t * vam)
3660 {
3661     unformat_input_t * i = vam->input;
3662     vl_api_proxy_arp_add_del_t *mp;
3663     f64 timeout;
3664     u32 vrf_id = 0;
3665     u8 is_add = 1;
3666     ip4_address_t lo, hi;
3667     u8 range_set = 0;
3668
3669     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3670         if (unformat (i, "vrf %d", &vrf_id))
3671             ;
3672         else if (unformat (i, "%U - %U", unformat_ip4_address, &lo, 
3673                            unformat_ip4_address, &hi))
3674             range_set = 1;
3675         else if (unformat (i, "del"))
3676             is_add = 0;
3677         else {
3678             clib_warning ("parse error '%U'", format_unformat_error, i);
3679             return -99;
3680         }
3681     }
3682     
3683     if (range_set == 0) {
3684         errmsg ("address range not set\n");
3685         return -99;
3686     }
3687
3688     M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
3689
3690     mp->vrf_id = ntohl(vrf_id);
3691     mp->is_add = is_add;
3692     memcpy(mp->low_address, &lo, sizeof (mp->low_address));
3693     memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
3694
3695     S; W;
3696     /* NOTREACHED */
3697     return 0;
3698 }
3699
3700 static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
3701 {
3702     unformat_input_t * i = vam->input;
3703     vl_api_proxy_arp_intfc_enable_disable_t *mp;
3704     f64 timeout;
3705     u32 sw_if_index;
3706     u8 enable = 1;
3707     u8 sw_if_index_set = 0;
3708
3709     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3710         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3711             sw_if_index_set = 1;
3712         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3713             sw_if_index_set = 1;
3714         else if (unformat (i, "enable"))
3715             enable = 1;
3716         else if (unformat (i, "disable"))
3717             enable = 0;
3718         else {
3719             clib_warning ("parse error '%U'", format_unformat_error, i);
3720             return -99;
3721         }
3722     }
3723     
3724     if (sw_if_index_set == 0) {
3725         errmsg ("missing interface name or sw_if_index\n");
3726         return -99;
3727     }
3728
3729     M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
3730
3731     mp->sw_if_index = ntohl(sw_if_index);
3732     mp->enable_disable = enable;
3733
3734     S; W;
3735     /* NOTREACHED */
3736     return 0;
3737 }
3738
3739 static int api_mpls_add_del_decap (vat_main_t * vam)
3740 {
3741     unformat_input_t * i = vam->input;
3742     vl_api_mpls_add_del_decap_t *mp;
3743     f64 timeout;
3744     u32 rx_vrf_id = 0;
3745     u32 tx_vrf_id = 0;
3746     u32 label = 0;
3747     u8 is_add = 1;
3748     u8 s_bit = 1;
3749     u32 next_index = 1;
3750
3751     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3752         if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
3753             ;
3754         else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
3755             ;
3756         else if (unformat (i, "label %d", &label))
3757             ;
3758         else if (unformat (i, "next-index %d", &next_index))
3759             ;
3760         else if (unformat (i, "del"))
3761             is_add = 0;
3762         else if (unformat (i, "s-bit-clear"))
3763             s_bit = 0;
3764         else {
3765             clib_warning ("parse error '%U'", format_unformat_error, i);
3766             return -99;
3767         }
3768     }
3769     
3770     M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
3771
3772     mp->rx_vrf_id = ntohl(rx_vrf_id);
3773     mp->tx_vrf_id = ntohl(tx_vrf_id);
3774     mp->label = ntohl(label);
3775     mp->next_index = ntohl(next_index);
3776     mp->s_bit = s_bit;
3777     mp->is_add = is_add;
3778
3779     S; W;
3780     /* NOTREACHED */
3781     return 0;
3782 }
3783
3784 static int api_mpls_add_del_encap (vat_main_t * vam)
3785 {
3786     unformat_input_t * i = vam->input;
3787     vl_api_mpls_add_del_encap_t *mp;
3788     f64 timeout;
3789     u32 vrf_id = 0;
3790     u32 *labels = 0;
3791     u32 label;
3792     ip4_address_t dst_address;
3793     u8 is_add = 1;
3794
3795     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3796         if (unformat (i, "vrf %d", &vrf_id))
3797             ;
3798         else if (unformat (i, "label %d", &label))
3799             vec_add1 (labels, ntohl(label));
3800         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
3801             ;
3802         else if (unformat (i, "del"))
3803             is_add = 0;
3804         else {
3805             clib_warning ("parse error '%U'", format_unformat_error, i);
3806             return -99;
3807         }
3808     }
3809
3810     if (vec_len (labels) == 0) {
3811         errmsg ("missing encap label stack\n");
3812         return -99;
3813     }
3814     
3815     M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap, 
3816        sizeof (u32) * vec_len (labels));
3817
3818     mp->vrf_id = ntohl(vrf_id);
3819     memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
3820     mp->is_add = is_add;
3821     mp->nlabels = vec_len (labels);
3822     memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
3823
3824     vec_free(labels);
3825
3826     S; W;
3827     /* NOTREACHED */
3828     return 0;
3829 }
3830
3831 static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
3832 {
3833     unformat_input_t * i = vam->input;
3834     vl_api_mpls_gre_add_del_tunnel_t *mp;
3835     f64 timeout;
3836     u32 inner_vrf_id = 0;
3837     u32 outer_vrf_id = 0;
3838     ip4_address_t src_address;
3839     ip4_address_t dst_address;
3840     ip4_address_t intfc_address;
3841     u32 tmp;
3842     u8 intfc_address_length = 0;
3843     u8 is_add = 1;
3844     u8 l2_only = 0;
3845     
3846     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3847         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
3848             ;
3849         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
3850             ;
3851         else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
3852             ;
3853         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
3854             ;
3855         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3856                            &intfc_address, &tmp))
3857             intfc_address_length = tmp;
3858         else if (unformat (i, "l2-only"))
3859             l2_only = 1;
3860         else if (unformat (i, "del"))
3861             is_add = 0;
3862         else {
3863             clib_warning ("parse error '%U'", format_unformat_error, i);
3864             return -99;
3865         }
3866     }
3867     
3868     M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
3869
3870     mp->inner_vrf_id = ntohl(inner_vrf_id);
3871     mp->outer_vrf_id = ntohl(outer_vrf_id);
3872     memcpy(mp->src_address, &src_address, sizeof (src_address));
3873     memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
3874     memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
3875     mp->intfc_address_length = intfc_address_length;
3876     mp->l2_only = l2_only;
3877     mp->is_add = is_add;
3878
3879     S; W;
3880     /* NOTREACHED */
3881     return 0;
3882 }
3883
3884 static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
3885 {
3886     unformat_input_t * i = vam->input;
3887     vl_api_mpls_ethernet_add_del_tunnel_t *mp;
3888     f64 timeout;
3889     u32 inner_vrf_id = 0;
3890     ip4_address_t intfc_address;
3891     u8 dst_mac_address[6];
3892     int dst_set = 1;
3893     u32 tmp;
3894     u8 intfc_address_length = 0;
3895     u8 is_add = 1;
3896     u8 l2_only = 0;
3897     u32 tx_sw_if_index;
3898     int tx_sw_if_index_set = 0;
3899     
3900     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3901         if (unformat (i, "vrf %d", &inner_vrf_id))
3902             ;
3903         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3904                            &intfc_address, &tmp))
3905             intfc_address_length = tmp;
3906         else if (unformat (i, "%U", 
3907                            unformat_sw_if_index, vam, &tx_sw_if_index))
3908             tx_sw_if_index_set = 1;
3909         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3910             tx_sw_if_index_set = 1;
3911         else if (unformat (i, "dst %U", unformat_ethernet_address, 
3912                            dst_mac_address))
3913             dst_set = 1;
3914         else if (unformat (i, "l2-only"))
3915             l2_only = 1;
3916         else if (unformat (i, "del"))
3917             is_add = 0;
3918         else {
3919             clib_warning ("parse error '%U'", format_unformat_error, i);
3920             return -99;
3921         }
3922     }
3923
3924     if (!dst_set) {
3925         errmsg ("dst (mac address) not set\n");
3926         return -99;
3927     }
3928     if (!tx_sw_if_index_set) {
3929         errmsg ("tx-intfc not set\n");
3930         return -99;
3931     }
3932     
3933     M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
3934
3935     mp->vrf_id = ntohl(inner_vrf_id);
3936     memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
3937     mp->adj_address_length = intfc_address_length;
3938     memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
3939     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3940     mp->l2_only = l2_only;
3941     mp->is_add = is_add;
3942
3943     S; W;
3944     /* NOTREACHED */
3945     return 0;
3946 }
3947
3948 static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
3949 {
3950     unformat_input_t * i = vam->input;
3951     vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
3952     f64 timeout;
3953     u32 inner_vrf_id = 0;
3954     u32 outer_vrf_id = 0;
3955     ip4_address_t adj_address;
3956     int adj_address_set = 0;
3957     ip4_address_t next_hop_address;
3958     int next_hop_address_set = 0;
3959     u32 tmp;
3960     u8 adj_address_length = 0;
3961     u8 l2_only = 0;
3962     u8 is_add = 1;
3963     u32 resolve_attempts = 5;
3964     u8 resolve_if_needed = 1;
3965     
3966     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3967         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
3968             ;
3969         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
3970             ;
3971         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
3972                            &adj_address, &tmp)) {
3973             adj_address_length = tmp;
3974             adj_address_set = 1;
3975         }
3976         else if (unformat (i, "next-hop %U", unformat_ip4_address,
3977                            &next_hop_address))
3978             next_hop_address_set = 1;
3979         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3980             ;
3981         else if (unformat (i, "resolve-if-needed %d", &tmp))
3982             resolve_if_needed = tmp;
3983         else if (unformat (i, "l2-only"))
3984             l2_only = 1;
3985         else if (unformat (i, "del"))
3986             is_add = 0;
3987         else {
3988             clib_warning ("parse error '%U'", format_unformat_error, i);
3989             return -99;
3990         }
3991     }
3992     
3993     if (!adj_address_set) {
3994         errmsg ("adjacency address/mask not set\n");
3995         return -99;
3996     }
3997     if (!next_hop_address_set) {
3998         errmsg ("ip4 next hop address (in outer fib) not set\n");
3999         return -99;
4000     }
4001     
4002     M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4003     
4004     mp->inner_vrf_id = ntohl(inner_vrf_id);
4005     mp->outer_vrf_id = ntohl(outer_vrf_id);
4006     mp->resolve_attempts = ntohl(resolve_attempts);
4007     mp->resolve_if_needed = resolve_if_needed;
4008     mp->is_add = is_add;
4009     mp->l2_only = l2_only;
4010     memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
4011     mp->adj_address_length = adj_address_length;
4012     memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address, 
4013             sizeof (next_hop_address));
4014
4015     S; W;
4016     /* NOTREACHED */
4017     return 0;
4018 }
4019
4020 static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4021 {
4022     unformat_input_t * i = vam->input;
4023     vl_api_sw_interface_set_unnumbered_t *mp;
4024     f64 timeout;
4025     u32 sw_if_index;
4026     u32 unnum_sw_index;
4027     u8  is_add = 1;
4028     u8 sw_if_index_set = 0;
4029
4030     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4031         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4032             sw_if_index_set = 1;
4033         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4034             sw_if_index_set = 1;
4035         else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4036             ;
4037         else if (unformat (i, "del"))
4038             is_add = 0;
4039         else {
4040             clib_warning ("parse error '%U'", format_unformat_error, i);
4041             return -99;
4042         }
4043     }
4044     
4045     if (sw_if_index_set == 0) {
4046         errmsg ("missing interface name or sw_if_index\n");
4047         return -99;
4048     }
4049
4050     M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4051
4052     mp->sw_if_index = ntohl(sw_if_index);
4053     mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4054     mp->is_add = is_add;
4055
4056     S; W;
4057     /* NOTREACHED */
4058     return 0;
4059 }
4060
4061 static int api_ip_neighbor_add_del (vat_main_t * vam)
4062 {
4063     unformat_input_t * i = vam->input;
4064     vl_api_ip_neighbor_add_del_t *mp;
4065     f64 timeout;
4066     u32 sw_if_index;
4067     u8 sw_if_index_set = 0;
4068     u32 vrf_id = 0;
4069     u8 is_add = 1;
4070     u8 is_static = 0;
4071     u8 mac_address[6];
4072     u8 mac_set = 0;
4073     u8 v4_address_set = 0;
4074     u8 v6_address_set = 0;
4075     ip4_address_t v4address;
4076     ip6_address_t v6address;
4077     
4078     memset (mac_address, 0, sizeof (mac_address));
4079     
4080     /* Parse args required to build the message */
4081     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4082         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4083             mac_set = 1;
4084         }
4085         else if (unformat (i, "del"))
4086             is_add = 0;
4087         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4088             sw_if_index_set = 1;
4089         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4090             sw_if_index_set = 1;
4091         else if (unformat (i, "is_static"))
4092             is_static = 1;
4093         else if (unformat (i, "vrf %d", &vrf_id))
4094             ;
4095         else if (unformat (i, "dst %U", 
4096                            unformat_ip4_address, &v4address))
4097                 v4_address_set = 1;
4098         else if (unformat (i, "dst %U", 
4099                            unformat_ip6_address, &v6address))
4100                 v6_address_set = 1;
4101         else {
4102             clib_warning ("parse error '%U'", format_unformat_error, i);
4103             return -99;
4104         }
4105     }
4106
4107     if (sw_if_index_set == 0) {
4108         errmsg ("missing interface name or sw_if_index\n");
4109         return -99;
4110     }
4111     if (v4_address_set && v6_address_set) {
4112         errmsg ("both v4 and v6 addresses set\n");
4113         return -99;
4114     }
4115     if (!v4_address_set && !v6_address_set) {
4116         errmsg ("no addresses set\n");
4117         return -99;
4118     }
4119
4120     /* Construct the API message */
4121     M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4122
4123     mp->sw_if_index = ntohl (sw_if_index);
4124     mp->is_add = is_add;
4125     mp->vrf_id = ntohl (vrf_id);
4126     mp->is_static = is_static;
4127     if (mac_set)
4128         memcpy (mp->mac_address, mac_address, 6);
4129     if (v6_address_set) {
4130         mp->is_ipv6 = 1;
4131         memcpy (mp->dst_address, &v6address, sizeof (v6address));
4132     } else {
4133         /* mp->is_ipv6 = 0; via memset in M macro above */
4134         memcpy (mp->dst_address, &v4address, sizeof (v4address));
4135     }
4136
4137     /* send it... */
4138     S;
4139
4140     /* Wait for a reply, return good/bad news  */
4141     W;
4142
4143     /* NOTREACHED */
4144     return 0;
4145 }
4146
4147 static int api_reset_vrf (vat_main_t * vam)
4148 {
4149     unformat_input_t * i = vam->input;
4150     vl_api_reset_vrf_t *mp;
4151     f64 timeout;
4152     u32 vrf_id = 0;
4153     u8 is_ipv6 = 0;
4154     u8 vrf_id_set = 0;
4155
4156     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4157         if (unformat (i, "vrf %d", &vrf_id))
4158             vrf_id_set = 1;
4159         else if (unformat (i, "ipv6"))
4160             is_ipv6 = 1;
4161         else {
4162             clib_warning ("parse error '%U'", format_unformat_error, i);
4163             return -99;
4164         }
4165     }
4166
4167     if (vrf_id_set == 0) {
4168         errmsg ("missing vrf id\n");
4169         return -99;
4170     }
4171     
4172     M(RESET_VRF, reset_vrf);
4173
4174     mp->vrf_id = ntohl(vrf_id);
4175     mp->is_ipv6 = is_ipv6;
4176
4177     S; W;
4178     /* NOTREACHED */
4179     return 0;
4180 }
4181
4182 static int api_create_vlan_subif (vat_main_t * vam)
4183 {
4184     unformat_input_t * i = vam->input;
4185     vl_api_create_vlan_subif_t *mp;
4186     f64 timeout;
4187     u32 sw_if_index;
4188     u8  sw_if_index_set = 0;
4189     u32 vlan_id;
4190     u8  vlan_id_set = 0;
4191
4192     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4193         if (unformat (i, "sw_if_index %d", &sw_if_index))
4194             sw_if_index_set = 1;
4195         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4196             sw_if_index_set = 1;
4197         else if (unformat (i, "vlan %d", &vlan_id))
4198             vlan_id_set = 1;
4199         else {
4200             clib_warning ("parse error '%U'", format_unformat_error, i);
4201             return -99;
4202         }
4203     }
4204     
4205     if (sw_if_index_set == 0) {
4206         errmsg ("missing interface name or sw_if_index\n");
4207         return -99;
4208     }
4209
4210     if (vlan_id_set == 0) {
4211         errmsg ("missing vlan_id\n");
4212         return -99;
4213     }
4214     M(CREATE_VLAN_SUBIF, create_vlan_subif);
4215
4216     mp->sw_if_index = ntohl(sw_if_index);
4217     mp->vlan_id = ntohl(vlan_id);
4218
4219     S; W;
4220     /* NOTREACHED */
4221     return 0;
4222 }
4223
4224 #define foreach_create_subif_bit                \
4225 _(no_tags)                                      \
4226 _(one_tag)                                      \
4227 _(two_tags)                                     \
4228 _(dot1ad)                                       \
4229 _(exact_match)                                  \
4230 _(default_sub)                                  \
4231 _(outer_vlan_id_any)                            \
4232 _(inner_vlan_id_any)
4233
4234 static int api_create_subif (vat_main_t * vam)
4235 {
4236     unformat_input_t * i = vam->input;
4237     vl_api_create_subif_t *mp;
4238     f64 timeout;
4239     u32 sw_if_index;
4240     u8  sw_if_index_set = 0;
4241     u32 sub_id;
4242     u8  sub_id_set = 0;
4243     u32 no_tags = 0;
4244     u32 one_tag = 0;
4245     u32 two_tags = 0;
4246     u32 dot1ad = 0;
4247     u32 exact_match = 0;
4248     u32 default_sub = 0;
4249     u32 outer_vlan_id_any = 0;
4250     u32 inner_vlan_id_any = 0;
4251     u32 tmp;
4252     u16 outer_vlan_id = 0;
4253     u16 inner_vlan_id = 0;
4254
4255     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4256         if (unformat (i, "sw_if_index %d", &sw_if_index))
4257             sw_if_index_set = 1;
4258         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4259             sw_if_index_set = 1;
4260         else if (unformat (i, "sub_id %d", &sub_id))
4261             sub_id_set = 1;
4262         else if (unformat (i, "outer_vlan_id %d", &tmp))
4263             outer_vlan_id = tmp;
4264         else if (unformat (i, "inner_vlan_id %d", &tmp))
4265             inner_vlan_id = tmp;
4266
4267 #define _(a) else if (unformat (i, #a)) a = 1 ;
4268         foreach_create_subif_bit
4269 #undef _
4270
4271         else {
4272             clib_warning ("parse error '%U'", format_unformat_error, i);
4273             return -99;
4274         }
4275     }
4276     
4277     if (sw_if_index_set == 0) {
4278         errmsg ("missing interface name or sw_if_index\n");
4279         return -99;
4280     }
4281
4282     if (sub_id_set == 0) {
4283         errmsg ("missing sub_id\n");
4284         return -99;
4285     }
4286     M(CREATE_SUBIF, create_subif);
4287
4288     mp->sw_if_index = ntohl(sw_if_index);
4289     mp->sub_id = ntohl(sub_id);
4290     
4291 #define _(a) mp->a = a;
4292     foreach_create_subif_bit;
4293 #undef _
4294         
4295     mp->outer_vlan_id = ntohs (outer_vlan_id);
4296     mp->inner_vlan_id = ntohs (inner_vlan_id);
4297
4298     S; W;
4299     /* NOTREACHED */
4300     return 0;
4301 }
4302
4303 static int api_oam_add_del (vat_main_t * vam)
4304 {
4305     unformat_input_t * i = vam->input;
4306     vl_api_oam_add_del_t *mp;
4307     f64 timeout;
4308     u32 vrf_id = 0;
4309     u8 is_add = 1;
4310     ip4_address_t src, dst;
4311     u8 src_set = 0;
4312     u8 dst_set = 0;
4313     
4314     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4315         if (unformat (i, "vrf %d", &vrf_id))
4316             ;
4317         else if (unformat (i, "src %U", unformat_ip4_address, &src))
4318             src_set = 1;
4319         else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4320             dst_set = 1;
4321         else if (unformat (i, "del"))
4322             is_add = 0;
4323         else {
4324             clib_warning ("parse error '%U'", format_unformat_error, i);
4325             return -99;
4326         }
4327     }
4328     
4329     if (src_set == 0) {
4330         errmsg ("missing src addr\n");
4331         return -99;
4332     }
4333
4334     if (dst_set == 0) {
4335         errmsg ("missing dst addr\n");
4336         return -99;
4337     }
4338
4339     M(OAM_ADD_DEL, oam_add_del);
4340
4341     mp->vrf_id = ntohl(vrf_id);
4342     mp->is_add = is_add;
4343     memcpy(mp->src_address, &src, sizeof (mp->src_address));
4344     memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
4345
4346     S; W;
4347     /* NOTREACHED */
4348     return 0;
4349 }
4350
4351 static int api_reset_fib (vat_main_t * vam)
4352 {
4353     unformat_input_t * i = vam->input;
4354     vl_api_reset_fib_t *mp;
4355     f64 timeout;
4356     u32 vrf_id = 0;
4357     u8 is_ipv6 = 0;
4358     u8 vrf_id_set = 0;
4359
4360     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4361         if (unformat (i, "vrf %d", &vrf_id))
4362             vrf_id_set = 1;
4363         else if (unformat (i, "ipv6"))
4364             is_ipv6 = 1;
4365         else {
4366             clib_warning ("parse error '%U'", format_unformat_error, i);
4367             return -99;
4368         }
4369     }
4370
4371     if (vrf_id_set == 0) {
4372         errmsg ("missing vrf id\n");
4373         return -99;
4374     }
4375     
4376     M(RESET_FIB, reset_fib);
4377
4378     mp->vrf_id = ntohl(vrf_id);
4379     mp->is_ipv6 = is_ipv6;
4380
4381     S; W;
4382     /* NOTREACHED */
4383     return 0;
4384 }
4385
4386 static int api_dhcp_proxy_config (vat_main_t * vam)
4387 {
4388     unformat_input_t * i = vam->input;
4389     vl_api_dhcp_proxy_config_t *mp;
4390     f64 timeout;
4391     u32 vrf_id = 0;
4392     u8 is_add = 1;
4393     u8 insert_cid = 1;
4394     u8 v4_address_set = 0;
4395     u8 v6_address_set = 0;
4396     ip4_address_t v4address;
4397     ip6_address_t v6address;
4398     u8 v4_src_address_set = 0;
4399     u8 v6_src_address_set = 0;
4400     ip4_address_t v4srcaddress;
4401     ip6_address_t v6srcaddress;
4402     
4403     /* Parse args required to build the message */
4404     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4405         if (unformat (i, "del"))
4406             is_add = 0;
4407         else if (unformat (i, "vrf %d", &vrf_id))
4408             ;
4409         else if (unformat (i, "insert-cid %d", &insert_cid))
4410             ;
4411         else if (unformat (i, "svr %U", 
4412                            unformat_ip4_address, &v4address))
4413                 v4_address_set = 1;
4414         else if (unformat (i, "svr %U", 
4415                            unformat_ip6_address, &v6address))
4416                 v6_address_set = 1;
4417         else if (unformat (i, "src %U", 
4418                            unformat_ip4_address, &v4srcaddress))
4419                 v4_src_address_set = 1;
4420         else if (unformat (i, "src %U", 
4421                            unformat_ip6_address, &v6srcaddress))
4422                 v6_src_address_set = 1;
4423         else
4424             break;
4425     }
4426
4427     if (v4_address_set && v6_address_set) {
4428         errmsg ("both v4 and v6 server addresses set\n");
4429         return -99;
4430     }
4431     if (!v4_address_set && !v6_address_set) {
4432         errmsg ("no server addresses set\n");
4433         return -99;
4434     }
4435
4436     if (v4_src_address_set && v6_src_address_set) {
4437         errmsg ("both v4 and v6  src addresses set\n");
4438         return -99;
4439     }
4440     if (!v4_src_address_set && !v6_src_address_set) {
4441         errmsg ("no src addresses set\n");
4442         return -99;
4443     }
4444
4445     if (!(v4_src_address_set && v4_address_set) &&
4446         !(v6_src_address_set && v6_address_set)) {
4447         errmsg ("no matching server and src addresses set\n");
4448         return -99;
4449     }
4450
4451     /* Construct the API message */
4452     M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4453
4454     mp->insert_circuit_id = insert_cid;
4455     mp->is_add = is_add;
4456     mp->vrf_id = ntohl (vrf_id);
4457     if (v6_address_set) {
4458         mp->is_ipv6 = 1;
4459         memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4460         memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
4461     } else {
4462         memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4463         memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
4464     }
4465
4466     /* send it... */
4467     S;
4468
4469     /* Wait for a reply, return good/bad news  */
4470     W;
4471     /* NOTREACHED */
4472     return 0;
4473 }
4474
4475 static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4476 {
4477     unformat_input_t * i = vam->input;
4478     vl_api_dhcp_proxy_config_2_t *mp;
4479     f64 timeout;
4480     u32 rx_vrf_id = 0;
4481     u32 server_vrf_id = 0;
4482     u8 is_add = 1;
4483     u8 insert_cid = 1;
4484     u8 v4_address_set = 0;
4485     u8 v6_address_set = 0;
4486     ip4_address_t v4address;
4487     ip6_address_t v6address;
4488     u8 v4_src_address_set = 0;
4489     u8 v6_src_address_set = 0;
4490     ip4_address_t v4srcaddress;
4491     ip6_address_t v6srcaddress;
4492     
4493     /* Parse args required to build the message */
4494     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4495         if (unformat (i, "del"))
4496             is_add = 0;
4497         else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4498             ;
4499         else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
4500             ;
4501         else if (unformat (i, "insert-cid %d", &insert_cid))
4502             ;
4503         else if (unformat (i, "svr %U", 
4504                            unformat_ip4_address, &v4address))
4505                 v4_address_set = 1;
4506         else if (unformat (i, "svr %U", 
4507                            unformat_ip6_address, &v6address))
4508                 v6_address_set = 1;
4509         else if (unformat (i, "src %U", 
4510                            unformat_ip4_address, &v4srcaddress))
4511                 v4_src_address_set = 1;
4512         else if (unformat (i, "src %U", 
4513                            unformat_ip6_address, &v6srcaddress))
4514                 v6_src_address_set = 1;
4515         else
4516             break;
4517     }
4518
4519     if (v4_address_set && v6_address_set) {
4520         errmsg ("both v4 and v6 server addresses set\n");
4521         return -99;
4522     }
4523     if (!v4_address_set && !v6_address_set) {
4524         errmsg ("no server addresses set\n");
4525         return -99;
4526     }
4527
4528     if (v4_src_address_set && v6_src_address_set) {
4529         errmsg ("both v4 and v6  src addresses set\n");
4530         return -99;
4531     }
4532     if (!v4_src_address_set && !v6_src_address_set) {
4533         errmsg ("no src addresses set\n");
4534         return -99;
4535     }
4536
4537     if (!(v4_src_address_set && v4_address_set) &&
4538         !(v6_src_address_set && v6_address_set)) {
4539         errmsg ("no matching server and src addresses set\n");
4540         return -99;
4541     }
4542
4543     /* Construct the API message */
4544     M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
4545
4546     mp->insert_circuit_id = insert_cid;
4547     mp->is_add = is_add;
4548     mp->rx_vrf_id = ntohl (rx_vrf_id);
4549     mp->server_vrf_id = ntohl (server_vrf_id);
4550     if (v6_address_set) {
4551         mp->is_ipv6 = 1;
4552         memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4553         memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
4554     } else {
4555         memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4556         memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
4557     }
4558
4559     /* send it... */
4560     S;
4561
4562     /* Wait for a reply, return good/bad news  */
4563     W;
4564     /* NOTREACHED */
4565     return 0;
4566 }
4567
4568 static int api_dhcp_proxy_set_vss (vat_main_t * vam)
4569 {
4570     unformat_input_t * i = vam->input;
4571     vl_api_dhcp_proxy_set_vss_t *mp;
4572     f64 timeout;
4573     u8  is_ipv6 = 0;
4574     u8  is_add = 1;
4575     u32 tbl_id;
4576     u8  tbl_id_set = 0;
4577     u32 oui;
4578     u8  oui_set = 0;
4579     u32 fib_id;
4580     u8  fib_id_set = 0;
4581
4582     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4583         if (unformat (i, "tbl_id %d", &tbl_id))
4584             tbl_id_set = 1;
4585         if (unformat (i, "fib_id %d", &fib_id))
4586             fib_id_set = 1;
4587         if (unformat (i, "oui %d", &oui))
4588             oui_set = 1;
4589         else if (unformat (i, "ipv6"))
4590             is_ipv6 = 1;
4591         else if (unformat (i, "del"))
4592             is_add = 0;
4593         else {
4594             clib_warning ("parse error '%U'", format_unformat_error, i);
4595             return -99;
4596         }
4597     }
4598
4599     if (tbl_id_set == 0) {
4600         errmsg ("missing tbl id\n");
4601         return -99;
4602     }
4603
4604     if (fib_id_set == 0) {
4605         errmsg ("missing fib id\n");
4606         return -99;
4607     }
4608     if (oui_set == 0) {
4609         errmsg ("missing oui\n");
4610         return -99;
4611     }
4612     
4613     M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
4614     mp->tbl_id = ntohl(tbl_id);
4615     mp->fib_id = ntohl(fib_id);
4616     mp->oui = ntohl(oui);
4617     mp->is_ipv6 = is_ipv6;
4618     mp->is_add = is_add;
4619
4620     S; W;
4621     /* NOTREACHED */
4622     return 0;
4623 }
4624
4625 static int api_dhcp_client_config (vat_main_t * vam)
4626 {
4627     unformat_input_t * i = vam->input;
4628     vl_api_dhcp_client_config_t *mp;
4629     f64 timeout;
4630     u32 sw_if_index;
4631     u8 sw_if_index_set = 0;
4632     u8 is_add = 1;
4633     u8 * hostname = 0;
4634     u8 disable_event = 0;
4635
4636     /* Parse args required to build the message */
4637     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4638         if (unformat (i, "del"))
4639             is_add = 0;
4640         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4641             sw_if_index_set = 1;
4642         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4643             sw_if_index_set = 1;
4644         else if (unformat (i, "hostname %s", &hostname))
4645             ;
4646         else if (unformat (i, "disable_event"))
4647             disable_event = 1;
4648         else
4649             break;
4650     }
4651
4652     if (sw_if_index_set == 0) {
4653         errmsg ("missing interface name or sw_if_index\n");
4654         return -99;
4655     }
4656
4657     if (vec_len (hostname) > 63) {
4658         errmsg ("hostname too long\n");
4659     }
4660     vec_add1 (hostname, 0);
4661
4662     /* Construct the API message */
4663     M(DHCP_CLIENT_CONFIG, dhcp_client_config);
4664
4665     mp->sw_if_index = ntohl (sw_if_index);
4666     memcpy (mp->hostname, hostname, vec_len (hostname));
4667     vec_free (hostname);
4668     mp->is_add = is_add;
4669     mp->want_dhcp_event = disable_event ? 0 : 1;
4670     mp->pid = getpid();
4671    
4672     /* send it... */
4673     S;
4674
4675     /* Wait for a reply, return good/bad news  */
4676     W;
4677     /* NOTREACHED */
4678     return 0;
4679 }
4680
4681 static int api_set_ip_flow_hash (vat_main_t * vam)
4682 {
4683     unformat_input_t * i = vam->input;
4684     vl_api_set_ip_flow_hash_t *mp;
4685     f64 timeout;
4686     u32 vrf_id = 0;
4687     u8 is_ipv6 = 0;
4688     u8 vrf_id_set = 0;
4689     u8 src = 0;
4690     u8 dst = 0;
4691     u8 sport = 0;
4692     u8 dport = 0;
4693     u8 proto = 0;
4694     u8 reverse = 0;
4695
4696     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4697         if (unformat (i, "vrf %d", &vrf_id))
4698             vrf_id_set = 1;
4699         else if (unformat (i, "ipv6"))
4700             is_ipv6 = 1;
4701         else if (unformat (i, "src"))
4702             src = 1;
4703         else if (unformat (i, "dst"))
4704             dst = 1;
4705         else if (unformat (i, "sport"))
4706             sport = 1;
4707         else if (unformat (i, "dport"))
4708             dport = 1;
4709         else if (unformat (i, "proto"))
4710             proto = 1;
4711         else if (unformat (i, "reverse"))
4712             reverse = 1;
4713
4714         else {
4715             clib_warning ("parse error '%U'", format_unformat_error, i);
4716             return -99;
4717         }
4718     }
4719
4720     if (vrf_id_set == 0) {
4721         errmsg ("missing vrf id\n");
4722         return -99;
4723     }
4724     
4725     M(SET_IP_FLOW_HASH, set_ip_flow_hash);
4726     mp->src = src;
4727     mp->dst = dst;
4728     mp->sport = sport;
4729     mp->dport = dport;
4730     mp->proto = proto;
4731     mp->reverse = reverse;
4732     mp->vrf_id = ntohl(vrf_id);
4733     mp->is_ipv6 = is_ipv6;
4734
4735     S; W;
4736     /* NOTREACHED */
4737     return 0;
4738 }
4739
4740 static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
4741 {
4742     unformat_input_t * i = vam->input;
4743     vl_api_sw_interface_ip6_enable_disable_t *mp;
4744     f64 timeout;
4745     u32 sw_if_index;
4746     u8  sw_if_index_set = 0;
4747     u8  enable = 0;
4748
4749     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4750         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4751             sw_if_index_set = 1;
4752         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4753             sw_if_index_set = 1;
4754         else if (unformat (i, "enable"))
4755             enable = 1;
4756         else if (unformat (i, "disable"))
4757             enable = 0;
4758         else {
4759             clib_warning ("parse error '%U'", format_unformat_error, i);
4760             return -99;
4761         }
4762     }
4763
4764     if (sw_if_index_set == 0) {
4765         errmsg ("missing interface name or sw_if_index\n");
4766         return -99;
4767     }
4768     
4769     M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
4770
4771     mp->sw_if_index = ntohl(sw_if_index);
4772     mp->enable = enable;
4773
4774     S; W;
4775     /* NOTREACHED */
4776     return 0;
4777 }
4778
4779 static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
4780 {
4781     unformat_input_t * i = vam->input;
4782     vl_api_sw_interface_ip6_set_link_local_address_t *mp;
4783     f64 timeout;
4784     u32 sw_if_index;
4785     u8 sw_if_index_set = 0;
4786     u32 address_length = 0;
4787     u8 v6_address_set = 0;
4788     ip6_address_t v6address;
4789     
4790     /* Parse args required to build the message */
4791     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4792         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4793             sw_if_index_set = 1;
4794         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4795             sw_if_index_set = 1;
4796         else if (unformat (i, "%U/%d", 
4797                            unformat_ip6_address, &v6address, 
4798                            &address_length))
4799             v6_address_set = 1;
4800         else
4801             break;
4802     }
4803
4804     if (sw_if_index_set == 0) {
4805         errmsg ("missing interface name or sw_if_index\n");
4806         return -99;
4807     }
4808     if (!v6_address_set) {
4809         errmsg ("no address set\n");
4810         return -99;
4811     }
4812
4813     /* Construct the API message */
4814     M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
4815       sw_interface_ip6_set_link_local_address);
4816
4817     mp->sw_if_index = ntohl (sw_if_index);
4818     memcpy (mp->address, &v6address, sizeof (v6address));
4819     mp->address_length = address_length;
4820
4821     /* send it... */
4822     S;
4823
4824     /* Wait for a reply, return good/bad news  */
4825     W;
4826
4827     /* NOTREACHED */
4828     return 0;
4829 }
4830
4831
4832 static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
4833 {
4834     unformat_input_t * i = vam->input;
4835     vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
4836     f64 timeout;
4837     u32 sw_if_index;
4838     u8 sw_if_index_set = 0;
4839     u32 address_length = 0;
4840     u8 v6_address_set = 0;
4841     ip6_address_t v6address;
4842     u8 use_default = 0;
4843     u8 no_advertise = 0;
4844     u8 off_link = 0;
4845     u8 no_autoconfig = 0;
4846     u8 no_onlink = 0;
4847     u8 is_no = 0;
4848     u32 val_lifetime = 0;
4849     u32 pref_lifetime = 0;
4850     
4851     /* Parse args required to build the message */
4852     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4853         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4854             sw_if_index_set = 1;
4855         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4856             sw_if_index_set = 1;
4857         else if (unformat (i, "%U/%d", 
4858                            unformat_ip6_address, &v6address, 
4859                            &address_length))
4860             v6_address_set = 1;
4861         else if (unformat (i, "val_life %d", &val_lifetime))
4862             ;
4863         else if (unformat (i, "pref_life %d", &pref_lifetime))
4864             ;
4865         else if (unformat (i, "def"))
4866             use_default = 1;
4867         else if (unformat (i, "noadv"))
4868             no_advertise = 1;
4869         else if (unformat (i, "offl"))
4870             off_link = 1;
4871         else if (unformat (i, "noauto"))
4872             no_autoconfig = 1;
4873         else if (unformat (i, "nolink"))
4874             no_onlink = 1;
4875         else if (unformat (i, "isno"))
4876             is_no = 1;
4877         else {
4878             clib_warning ("parse error '%U'", format_unformat_error, i);
4879             return -99;
4880         }        
4881     }
4882
4883     if (sw_if_index_set == 0) {
4884         errmsg ("missing interface name or sw_if_index\n");
4885         return -99;
4886     }
4887     if (!v6_address_set) {
4888         errmsg ("no address set\n");
4889         return -99;
4890     }
4891
4892     /* Construct the API message */
4893     M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
4894
4895     mp->sw_if_index = ntohl (sw_if_index);
4896     memcpy (mp->address, &v6address, sizeof (v6address));
4897     mp->address_length = address_length;
4898     mp->use_default = use_default;
4899     mp->no_advertise = no_advertise;
4900     mp->off_link = off_link;
4901     mp->no_autoconfig = no_autoconfig;
4902     mp->no_onlink = no_onlink;
4903     mp->is_no = is_no;
4904     mp->val_lifetime = ntohl(val_lifetime);
4905     mp->pref_lifetime = ntohl(pref_lifetime);
4906
4907     /* send it... */
4908     S;
4909
4910     /* Wait for a reply, return good/bad news  */
4911     W;
4912
4913     /* NOTREACHED */
4914     return 0;
4915 }
4916
4917 static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
4918 {
4919     unformat_input_t * i = vam->input;
4920     vl_api_sw_interface_ip6nd_ra_config_t *mp;
4921     f64 timeout;
4922     u32 sw_if_index;
4923     u8 sw_if_index_set = 0;
4924     u8 surpress = 0;
4925     u8 managed = 0;
4926     u8 other = 0;
4927     u8 ll_option = 0;
4928     u8 send_unicast = 0;
4929     u8 cease = 0;
4930     u8 is_no = 0;
4931     u8 default_router = 0;
4932     u32 max_interval = 0;
4933     u32 min_interval = 0;
4934     u32 lifetime = 0;
4935     u32 initial_count = 0;
4936     u32 initial_interval = 0;
4937
4938     
4939     /* Parse args required to build the message */
4940     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4941         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4942             sw_if_index_set = 1;
4943         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4944             sw_if_index_set = 1;
4945         else if (unformat (i, "maxint %d", &max_interval))
4946             ;
4947         else if (unformat (i, "minint %d", &min_interval))
4948             ;
4949         else if (unformat (i, "life %d", &lifetime))
4950             ;
4951         else if (unformat (i, "count %d", &initial_count))
4952             ;
4953         else if (unformat (i, "interval %d", &initial_interval))
4954             ;
4955         else if (unformat (i, "surpress"))
4956             surpress = 1;
4957         else if (unformat (i, "managed"))
4958             managed = 1;
4959         else if (unformat (i, "other"))
4960             other = 1;
4961         else if (unformat (i, "ll"))
4962             ll_option = 1;
4963         else if (unformat (i, "send"))
4964             send_unicast = 1;
4965         else if (unformat (i, "cease"))
4966             cease = 1;
4967         else if (unformat (i, "isno"))
4968             is_no = 1;
4969         else if (unformat (i, "def"))
4970             default_router = 1;
4971         else {
4972             clib_warning ("parse error '%U'", format_unformat_error, i);
4973             return -99;
4974         }        
4975     }
4976
4977     if (sw_if_index_set == 0) {
4978         errmsg ("missing interface name or sw_if_index\n");
4979         return -99;
4980     }
4981
4982     /* Construct the API message */
4983     M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
4984
4985     mp->sw_if_index = ntohl (sw_if_index);
4986     mp->max_interval = ntohl(max_interval);
4987     mp->min_interval = ntohl(min_interval);
4988     mp->lifetime = ntohl(lifetime);
4989     mp->initial_count = ntohl(initial_count);
4990     mp->initial_interval = ntohl(initial_interval);
4991     mp->surpress = surpress;
4992     mp->managed = managed;
4993     mp->other = other;
4994     mp->ll_option = ll_option;
4995     mp->send_unicast = send_unicast;
4996     mp->cease = cease;
4997     mp->is_no = is_no;
4998     mp->default_router = default_router;
4999
5000     /* send it... */
5001     S;
5002
5003     /* Wait for a reply, return good/bad news  */
5004     W;
5005
5006     /* NOTREACHED */
5007     return 0;
5008 }
5009
5010 static int api_set_arp_neighbor_limit (vat_main_t * vam)
5011 {
5012     unformat_input_t * i = vam->input;
5013     vl_api_set_arp_neighbor_limit_t *mp;
5014     f64 timeout;
5015     u32 arp_nbr_limit;
5016     u8 limit_set = 0;
5017     u8 is_ipv6 = 0;
5018
5019     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5020         if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5021             limit_set = 1;
5022         else if (unformat (i, "ipv6"))
5023             is_ipv6 = 1;
5024         else {
5025             clib_warning ("parse error '%U'", format_unformat_error, i);
5026             return -99;
5027         }
5028     }
5029
5030     if (limit_set == 0) {
5031         errmsg ("missing limit value\n");
5032         return -99;
5033     }
5034     
5035     M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5036
5037     mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5038     mp->is_ipv6 = is_ipv6;
5039
5040     S; W;
5041     /* NOTREACHED */
5042     return 0;
5043 }
5044
5045 static int api_l2_patch_add_del (vat_main_t * vam)
5046 {
5047     unformat_input_t * i = vam->input;
5048     vl_api_l2_patch_add_del_t *mp;
5049     f64 timeout;
5050     u32 rx_sw_if_index;
5051     u8 rx_sw_if_index_set = 0;
5052     u32 tx_sw_if_index;
5053     u8 tx_sw_if_index_set = 0;
5054     u8 is_add = 1;
5055     
5056     /* Parse args required to build the message */
5057     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5058         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5059             rx_sw_if_index_set = 1;     
5060         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5061             tx_sw_if_index_set = 1;
5062         else if (unformat (i, "rx")) {
5063             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5064                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5065                               &rx_sw_if_index))
5066                     rx_sw_if_index_set = 1;
5067             } else
5068                 break;
5069         } else if (unformat (i, "tx")) {
5070             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5071                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5072                               &tx_sw_if_index))
5073                     tx_sw_if_index_set = 1;
5074             } else
5075                 break;
5076         } else if (unformat (i, "del"))
5077             is_add = 0;
5078         else
5079             break;
5080     }
5081
5082     if (rx_sw_if_index_set == 0) {
5083         errmsg ("missing rx interface name or rx_sw_if_index\n");
5084         return -99;
5085     }
5086
5087     if (tx_sw_if_index_set == 0) {
5088         errmsg ("missing tx interface name or tx_sw_if_index\n");
5089         return -99;
5090     }
5091     
5092     M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5093
5094     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5095     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5096     mp->is_add = is_add;
5097
5098     S; W;
5099     /* NOTREACHED */
5100     return 0;
5101 }
5102 static int api_trace_profile_add (vat_main_t *vam)
5103 {
5104    unformat_input_t * input = vam->input;
5105    vl_api_trace_profile_add_t *mp;
5106    f64 timeout;
5107    u32 id = 0;
5108    u32 trace_option_elts = 0;
5109    u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5110    int has_pow_option = 0;
5111    int has_ppc_option = 0;
5112   
5113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5114     {
5115       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5116                            "trace-tsp %d node-id 0x%x app-data 0x%x", 
5117                     &id, &trace_type, &trace_option_elts, &trace_tsp,
5118                       &node_id, &app_data))
5119             ;
5120       else if (unformat (input, "pow"))
5121         has_pow_option = 1;
5122       else if (unformat (input, "ppc encap"))
5123         has_ppc_option = PPC_ENCAP;
5124       else if (unformat (input, "ppc decap"))
5125         has_ppc_option = PPC_DECAP;
5126       else if (unformat (input, "ppc none"))
5127         has_ppc_option = PPC_NONE;
5128       else
5129         break;
5130     }
5131   M(TRACE_PROFILE_ADD, trace_profile_add);
5132   mp->id = htons(id);
5133   mp->trace_type = trace_type;
5134   mp->trace_num_elt = trace_option_elts;
5135   mp->trace_ppc = has_ppc_option;
5136   mp->trace_app_data = htonl(app_data);
5137   mp->pow_enable = has_pow_option;
5138   mp->trace_tsp = trace_tsp;
5139   mp->node_id = htonl(node_id);
5140   
5141   S; W;
5142   
5143   return(0);
5144    
5145 }
5146 static int api_trace_profile_apply (vat_main_t *vam)
5147 {
5148   unformat_input_t * input = vam->input;
5149   vl_api_trace_profile_apply_t *mp;
5150   f64 timeout;
5151   ip6_address_t addr;
5152   u32 mask_width = ~0;
5153   int is_add = 0;
5154   int is_pop = 0;
5155   int is_none = 0;
5156   u32 vrf_id = 0;
5157   u32 id = 0;
5158   
5159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5160     {
5161       if (unformat (input, "%U/%d",
5162                     unformat_ip6_address, &addr, &mask_width))
5163         ;
5164       else if (unformat (input, "id %d", &id))
5165         ;
5166       else if (unformat (input, "vrf-id %d", &vrf_id))
5167         ;
5168       else if (unformat (input, "add"))
5169         is_add = 1;
5170       else if (unformat (input, "pop"))
5171         is_pop = 1;
5172       else if (unformat (input, "none"))
5173         is_none = 1;
5174       else
5175         break;
5176     }
5177
5178   if ((is_add + is_pop + is_none) != 1) {
5179     errmsg("One of (add, pop, none) required");
5180     return -99;
5181   }
5182   if (mask_width == ~0) {
5183     errmsg("<address>/<mask-width> required");
5184     return -99;
5185   }
5186   M(TRACE_PROFILE_APPLY, trace_profile_apply);
5187   memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
5188   mp->id = htons(id);
5189   mp->prefix_length = htonl(mask_width);
5190   mp->vrf_id = htonl(vrf_id);
5191   if (is_add)
5192     mp->trace_op = IOAM_HBYH_ADD;
5193   else if (is_pop)
5194     mp->trace_op = IOAM_HBYH_POP;
5195   else
5196     mp->trace_op = IOAM_HBYH_MOD;
5197
5198   if(is_none)
5199     mp->enable = 0;
5200   else
5201     mp->enable = 1;
5202   
5203   S; W;
5204
5205   return 0;
5206 }
5207
5208 static int api_trace_profile_del (vat_main_t *vam)
5209 {
5210    vl_api_trace_profile_del_t *mp;
5211    f64 timeout;
5212    
5213    M(TRACE_PROFILE_DEL, trace_profile_del);
5214    S; W;
5215    return 0;
5216 }
5217 static int api_sr_tunnel_add_del (vat_main_t * vam)
5218 {
5219   unformat_input_t * i = vam->input;
5220   vl_api_sr_tunnel_add_del_t *mp;
5221   f64 timeout;
5222   int is_del = 0;
5223   int pl_index;
5224   ip6_address_t src_address;
5225   int src_address_set = 0;
5226   ip6_address_t dst_address;
5227   u32 dst_mask_width;
5228   int dst_address_set = 0;
5229   u16 flags = 0;
5230   u32 rx_table_id = 0;
5231   u32 tx_table_id = 0;
5232   ip6_address_t * segments = 0;
5233   ip6_address_t * this_seg;
5234   ip6_address_t * tags = 0;
5235   ip6_address_t * this_tag;
5236   ip6_address_t next_address, tag;
5237
5238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5239     {
5240       if (unformat (i, "del"))
5241         is_del = 1;
5242       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5243         ;
5244       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5245         ;
5246       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5247         src_address_set = 1;
5248       else if (unformat (i, "dst %U/%d", 
5249                          unformat_ip6_address, &dst_address,
5250                          &dst_mask_width))
5251         dst_address_set = 1;
5252       else if (unformat (i, "next %U", unformat_ip6_address,
5253                          &next_address))
5254         {
5255           vec_add2 (segments, this_seg, 1);
5256           memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
5257         }
5258       else if (unformat (i, "tag %U", unformat_ip6_address,
5259                          &tag))
5260         {
5261           vec_add2 (tags, this_tag, 1);
5262           memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
5263         }
5264       else if (unformat (i, "clean"))
5265         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5266       else if (unformat (i, "protected"))
5267         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5268       else if (unformat (i, "InPE %d", &pl_index))
5269         {
5270           if (pl_index <= 0 || pl_index > 4)
5271             {
5272             pl_index_range_error:
5273               errmsg ("pl index %d out of range\n", pl_index);
5274               return -99;
5275             }
5276           flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5277         }
5278       else if (unformat (i, "EgPE %d", &pl_index))
5279         {
5280           if (pl_index <= 0 || pl_index > 4)
5281             goto pl_index_range_error;
5282           flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5283         }
5284       else if (unformat (i, "OrgSrc %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_ORIG_SRC_ADDR << (3*(pl_index - 1));
5289         }
5290       else 
5291         break;
5292     }
5293
5294   if (!src_address_set)
5295     {
5296       errmsg ("src address required\n");
5297       return -99;
5298     }
5299
5300   if (!dst_address_set)
5301     {
5302       errmsg ("dst address required\n");
5303       return -99;
5304     }
5305
5306   if (!segments)
5307     {
5308       errmsg ("at least one sr segment required\n");
5309       return -99;
5310     }
5311
5312   M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del, 
5313      vec_len(segments) * sizeof (ip6_address_t) 
5314      + vec_len(tags) * sizeof (ip6_address_t));
5315
5316   memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5317   memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
5318   mp->dst_mask_width = dst_mask_width;
5319   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5320   mp->n_segments = vec_len (segments);
5321   mp->n_tags = vec_len (tags);
5322   mp->is_add = is_del == 0;
5323   memcpy (mp->segs_and_tags, segments, 
5324           vec_len(segments)* sizeof (ip6_address_t));
5325   memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
5326           tags, vec_len(tags)* sizeof (ip6_address_t));
5327
5328   mp->outer_vrf_id = ntohl (rx_table_id);
5329   mp->inner_vrf_id = ntohl (tx_table_id);
5330
5331   vec_free (segments);
5332   vec_free (tags);
5333   
5334   S; W;
5335   /* NOTREACHED */
5336 }
5337
5338
5339 #define foreach_ip4_proto_field                 \
5340 _(src_address)                                  \
5341 _(dst_address)                                  \
5342 _(tos)                                          \
5343 _(length)                                       \
5344 _(fragment_id)                                  \
5345 _(ttl)                                          \
5346 _(protocol)                                     \
5347 _(checksum)
5348
5349 uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
5350 {
5351   u8 ** maskp = va_arg (*args, u8 **);
5352   u8 * mask = 0;
5353   u8 found_something = 0;
5354   ip4_header_t * ip;
5355   
5356 #define _(a) u8 a=0;
5357   foreach_ip4_proto_field;
5358 #undef _
5359   u8 version = 0;
5360   u8 hdr_length = 0;
5361   
5362   
5363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
5364     {
5365       if (unformat (input, "version")) 
5366         version = 1;
5367       else if (unformat (input, "hdr_length"))
5368         hdr_length = 1;
5369       else if (unformat (input, "src"))
5370         src_address = 1;
5371       else if (unformat (input, "dst"))
5372         dst_address = 1;
5373       else if (unformat (input, "proto"))
5374         protocol = 1;
5375       
5376 #define _(a) else if (unformat (input, #a)) a=1;
5377       foreach_ip4_proto_field
5378 #undef _
5379       else
5380         break;
5381     }
5382   
5383 #define _(a) found_something += a;
5384   foreach_ip4_proto_field;
5385 #undef _
5386   
5387   if (found_something == 0)
5388     return 0;
5389   
5390   vec_validate (mask, sizeof (*ip) - 1);
5391   
5392   ip = (ip4_header_t *) mask;
5393   
5394 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5395   foreach_ip4_proto_field;
5396 #undef _
5397   
5398   ip->ip_version_and_header_length = 0;
5399   
5400   if (version)
5401     ip->ip_version_and_header_length |= 0xF0;
5402   
5403   if (hdr_length)
5404     ip->ip_version_and_header_length |= 0x0F;
5405   
5406   *maskp = mask;
5407   return 1;
5408 }
5409
5410 #define foreach_ip6_proto_field                 \
5411 _(src_address)                                  \
5412 _(dst_address)                                  \
5413 _(payload_length)                               \
5414 _(hop_limit)                                    \
5415 _(protocol)
5416
5417 uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
5418 {
5419   u8 ** maskp = va_arg (*args, u8 **);
5420   u8 * mask = 0;
5421   u8 found_something = 0;
5422   ip6_header_t * ip;
5423   u32 ip_version_traffic_class_and_flow_label;
5424   
5425 #define _(a) u8 a=0;
5426   foreach_ip6_proto_field;
5427 #undef _
5428   u8 version = 0;
5429   u8 traffic_class = 0;
5430   u8 flow_label = 0;
5431   
5432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
5433     {
5434       if (unformat (input, "version")) 
5435         version = 1;
5436       else if (unformat (input, "traffic-class"))
5437         traffic_class = 1;
5438       else if (unformat (input, "flow-label"))
5439         flow_label = 1;
5440       else if (unformat (input, "src"))
5441         src_address = 1;
5442       else if (unformat (input, "dst"))
5443         dst_address = 1;
5444       else if (unformat (input, "proto"))
5445         protocol = 1;
5446       
5447 #define _(a) else if (unformat (input, #a)) a=1;
5448       foreach_ip6_proto_field
5449 #undef _
5450       else
5451         break;
5452     }
5453   
5454 #define _(a) found_something += a;
5455   foreach_ip6_proto_field;
5456 #undef _
5457   
5458   if (found_something == 0)
5459     return 0;
5460   
5461   vec_validate (mask, sizeof (*ip) - 1);
5462   
5463   ip = (ip6_header_t *) mask;
5464   
5465 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
5466   foreach_ip6_proto_field;
5467 #undef _
5468   
5469   ip_version_traffic_class_and_flow_label = 0;
5470   
5471   if (version)
5472     ip_version_traffic_class_and_flow_label |= 0xF0000000;
5473
5474   if (traffic_class)
5475     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
5476
5477   if (flow_label)
5478     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
5479
5480   ip->ip_version_traffic_class_and_flow_label = 
5481     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
5482   
5483   *maskp = mask;
5484   return 1;
5485 }
5486
5487 uword unformat_l3_mask (unformat_input_t * input, va_list * args)
5488 {
5489   u8 ** maskp = va_arg (*args, u8 **);
5490
5491   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5492     if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
5493       return 1;
5494     else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
5495       return 1;
5496     else
5497       break;
5498   }
5499   return 0;
5500 }
5501
5502 uword unformat_l2_mask (unformat_input_t * input, va_list * args)
5503 {
5504   u8 ** maskp = va_arg (*args, u8 **);
5505   u8 * mask = 0;
5506   u8 src = 0;
5507   u8 dst = 0;
5508   u8 proto = 0;
5509   u8 tag1 = 0;
5510   u8 tag2 = 0;
5511   u8 ignore_tag1 = 0;
5512   u8 ignore_tag2 = 0;
5513   u8 cos1 = 0;
5514   u8 cos2 = 0;
5515   u8 dot1q = 0;
5516   u8 dot1ad = 0;
5517   int len = 14;
5518
5519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5520     if (unformat (input, "src"))
5521       src = 1;
5522     else if (unformat (input, "dst"))
5523       dst = 1;
5524     else if (unformat (input, "proto"))
5525       proto = 1;
5526     else if (unformat (input, "tag1"))
5527       tag1 = 1;
5528     else if (unformat (input, "tag2"))
5529       tag2 = 1;
5530     else if (unformat (input, "ignore-tag1"))
5531       ignore_tag1 = 1;
5532     else if (unformat (input, "ignore-tag2"))
5533       ignore_tag2 = 1;
5534     else if (unformat (input, "cos1"))
5535       cos1 = 1;
5536     else if (unformat (input, "cos2"))
5537       cos2 = 1;
5538     else if (unformat (input, "dot1q"))
5539       dot1q = 1;
5540     else if (unformat (input, "dot1ad"))
5541       dot1ad = 1;
5542     else
5543       break;
5544   }
5545   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
5546       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
5547     return 0;
5548
5549   if (tag1 || ignore_tag1 || cos1 || dot1q)
5550     len = 18;
5551   if (tag2 || ignore_tag2 || cos2 || dot1ad)
5552     len = 22;
5553
5554   vec_validate (mask, len-1);
5555
5556   if (dst)
5557     memset (mask, 0xff, 6);
5558
5559   if (src)
5560     memset (mask + 6, 0xff, 6);
5561   
5562   if (tag2 || dot1ad)
5563     {
5564       /* inner vlan tag */
5565       if (tag2)
5566         {
5567           mask[19] = 0xff;
5568           mask[18] = 0x0f;
5569         }
5570       if (cos2)
5571         mask[18] |= 0xe0;
5572       if (proto)
5573           mask[21] = mask [20] = 0xff;
5574       if (tag1)
5575         {
5576           mask [15] = 0xff;
5577           mask [14] = 0x0f;
5578         }
5579       if (cos1)
5580         mask[14] |= 0xe0;
5581       *maskp = mask;
5582       return 1;
5583     }
5584   if (tag1 | dot1q)
5585     {
5586       if (tag1)
5587         {
5588           mask [15] = 0xff;
5589           mask [14] = 0x0f;
5590         }
5591       if (cos1)
5592         mask[14] |= 0xe0;
5593       if (proto)
5594           mask[16] = mask [17] = 0xff;
5595
5596       *maskp = mask;
5597       return 1;
5598     }
5599   if (cos2)
5600     mask[18] |= 0xe0;
5601   if (cos1)
5602     mask[14] |= 0xe0;
5603   if (proto)
5604     mask[12] = mask [13] = 0xff;
5605     
5606   *maskp = mask;
5607   return 1;
5608 }
5609
5610 uword unformat_classify_mask (unformat_input_t * input, va_list * args)
5611 {
5612   u8 ** maskp = va_arg (*args, u8 **);
5613   u32 * skipp = va_arg (*args, u32 *);
5614   u32 * matchp = va_arg (*args, u32 *);
5615   u32 match;
5616   u8 * mask = 0;
5617   u8 * l2 = 0;
5618   u8 * l3 = 0;
5619   int i;
5620   
5621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
5622     if (unformat (input, "hex %U", unformat_hex_string, &mask))
5623       ;
5624     else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
5625       ;
5626     else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
5627       ;
5628     else
5629       break;
5630   }
5631
5632   if (mask || l2 || l3)
5633     {
5634       if (l2 || l3)
5635         {
5636           /* "With a free Ethernet header in every package" */
5637           if (l2 == 0)
5638             vec_validate (l2, 13);
5639           mask = l2;
5640           vec_append (mask, l3);
5641           vec_free (l3);
5642         }
5643
5644       /* Scan forward looking for the first significant mask octet */
5645       for (i = 0; i < vec_len (mask); i++)
5646         if (mask[i])
5647           break;
5648
5649       /* compute (skip, match) params */
5650       *skipp = i / sizeof(u32x4);
5651       vec_delete (mask, *skipp * sizeof(u32x4), 0);
5652
5653       /* Pad mask to an even multiple of the vector size */
5654       while (vec_len (mask) % sizeof (u32x4))
5655         vec_add1 (mask, 0);
5656
5657       match = vec_len (mask) / sizeof (u32x4);
5658
5659       for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
5660         {
5661           u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
5662           if (*tmp || *(tmp+1))
5663             break;
5664           match--;
5665         }
5666       if (match == 0)
5667         clib_warning ("BUG: match 0");
5668
5669       _vec_len (mask) = match * sizeof(u32x4);
5670
5671       *matchp = match;
5672       *maskp = mask;
5673
5674       return 1;
5675     }
5676
5677   return 0;
5678 }
5679
5680 #define foreach_l2_next                         \
5681 _(drop, DROP)                                   \
5682 _(ethernet, ETHERNET_INPUT)                     \
5683 _(ip4, IP4_INPUT)                               \
5684 _(ip6, IP6_INPUT)
5685
5686 uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
5687 {
5688   u32 * miss_next_indexp = va_arg (*args, u32 *);
5689   u32 next_index = 0;
5690   u32 tmp;
5691   
5692 #define _(n,N) \
5693   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
5694   foreach_l2_next;
5695 #undef _
5696   
5697   if (unformat (input, "%d", &tmp))
5698     { 
5699       next_index = tmp; 
5700       goto out; 
5701     }
5702   
5703   return 0;
5704
5705  out:
5706   *miss_next_indexp = next_index;
5707   return 1;
5708 }
5709
5710 #define foreach_ip_next                         \
5711 _(miss, MISS)                                   \
5712 _(drop, DROP)                                   \
5713 _(local, LOCAL)                                 \
5714 _(rewrite, REWRITE)
5715
5716 uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
5717 {
5718   u32 * miss_next_indexp = va_arg (*args, u32 *);
5719   u32 next_index = 0;
5720   u32 tmp;
5721   
5722 #define _(n,N) \
5723   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
5724   foreach_ip_next;
5725 #undef _
5726   
5727   if (unformat (input, "%d", &tmp))
5728     { 
5729       next_index = tmp; 
5730       goto out; 
5731     }
5732   
5733   return 0;
5734
5735  out:
5736   *miss_next_indexp = next_index;
5737   return 1;
5738 }
5739
5740 #define foreach_acl_next                        \
5741 _(deny, DENY)
5742
5743 uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
5744 {
5745   u32 * miss_next_indexp = va_arg (*args, u32 *);
5746   u32 next_index = 0;
5747   u32 tmp;
5748
5749 #define _(n,N) \
5750   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
5751   foreach_acl_next;
5752 #undef _
5753
5754   if (unformat (input, "permit"))
5755     {
5756       next_index = ~0;
5757       goto out;
5758     }
5759   else if (unformat (input, "%d", &tmp))
5760     {
5761       next_index = tmp;
5762       goto out;
5763     }
5764
5765   return 0;
5766
5767  out:
5768   *miss_next_indexp = next_index;
5769   return 1;
5770 }
5771
5772 static int api_classify_add_del_table (vat_main_t * vam)
5773 {
5774   unformat_input_t * i = vam->input;
5775   vl_api_classify_add_del_table_t *mp;
5776
5777   u32 nbuckets = 2;
5778   u32 skip = ~0;
5779   u32 match = ~0;
5780   int is_add = 1;
5781   u32 table_index = ~0;
5782   u32 next_table_index = ~0;
5783   u32 miss_next_index = ~0;
5784   u32 memory_size = 32<<20;
5785   u8 * mask = 0;
5786   f64 timeout;
5787
5788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5789     if (unformat (i, "del"))
5790       is_add = 0;
5791     else if (unformat (i, "buckets %d", &nbuckets))
5792       ;
5793     else if (unformat (i, "memory_size %d", &memory_size))
5794       ;
5795     else if (unformat (i, "skip %d", &skip))
5796       ;
5797     else if (unformat (i, "match %d", &match))
5798       ;
5799     else if (unformat (i, "table %d", &table_index))
5800       ;
5801     else if (unformat (i, "mask %U", unformat_classify_mask, 
5802                        &mask, &skip, &match))
5803       ;
5804     else if (unformat (i, "next-table %d", &next_table_index))
5805       ;
5806     else if (unformat (i, "miss-next %U", unformat_ip_next_index,
5807                        &miss_next_index))
5808       ;
5809     else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
5810                        &miss_next_index))
5811       ;
5812     else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
5813                        &miss_next_index))
5814       ;
5815     else
5816       break;
5817   }
5818   
5819   if (is_add && mask == 0) {
5820       errmsg ("Mask required\n");
5821       return -99;
5822   }
5823
5824   if (is_add && skip == ~0) {
5825       errmsg ("skip count required\n");
5826       return -99;
5827   }
5828
5829   if (is_add && match == ~0) {
5830       errmsg ("match count required\n");
5831       return -99;
5832   }
5833       
5834   if (!is_add && table_index == ~0) {
5835       errmsg ("table index required for delete\n");
5836       return -99;
5837   }
5838
5839   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
5840       vec_len(mask));
5841
5842   mp->is_add = is_add;
5843   mp->table_index = ntohl(table_index);
5844   mp->nbuckets = ntohl(nbuckets);
5845   mp->memory_size = ntohl(memory_size);
5846   mp->skip_n_vectors = ntohl(skip);
5847   mp->match_n_vectors = ntohl(match);
5848   mp->next_table_index = ntohl(next_table_index);
5849   mp->miss_next_index = ntohl(miss_next_index);
5850   memcpy (mp->mask, mask, vec_len(mask));
5851
5852   vec_free(mask);
5853
5854   S; W;
5855   /* NOTREACHED */
5856 }
5857
5858 uword unformat_ip4_match (unformat_input_t * input, va_list * args)
5859 {
5860   u8 ** matchp = va_arg (*args, u8 **);
5861   u8 * match = 0;
5862   ip4_header_t * ip;
5863   int version = 0;
5864   u32 version_val;
5865   int hdr_length = 0;
5866   u32 hdr_length_val;
5867   int src = 0, dst = 0;
5868   ip4_address_t src_val, dst_val;
5869   int proto = 0;
5870   u32 proto_val;
5871   int tos = 0;
5872   u32 tos_val;
5873   int length = 0;
5874   u32 length_val;
5875   int fragment_id = 0;
5876   u32 fragment_id_val;
5877   int ttl = 0;
5878   int ttl_val;
5879   int checksum = 0;
5880   u32 checksum_val;
5881
5882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
5883     {
5884       if (unformat (input, "version %d", &version_val)) 
5885         version = 1;
5886       else if (unformat (input, "hdr_length %d", &hdr_length_val))
5887         hdr_length = 1;
5888       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
5889         src = 1;
5890       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
5891         dst = 1;
5892       else if (unformat (input, "proto %d", &proto_val))
5893         proto = 1;
5894       else if (unformat (input, "tos %d", &tos_val))
5895         tos = 1;
5896       else if (unformat (input, "length %d", &length_val))
5897         length = 1;
5898       else if (unformat (input, "fragment_id %d", &fragment_id_val))
5899         fragment_id = 1;
5900       else if (unformat (input, "ttl %d", &ttl_val))
5901         ttl = 1;
5902       else if (unformat (input, "checksum %d", &checksum_val))
5903         checksum = 1;
5904       else
5905         break;
5906     }
5907   
5908   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
5909       + ttl + checksum == 0)
5910     return 0;
5911
5912   /* 
5913    * Aligned because we use the real comparison functions
5914    */
5915   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
5916   
5917   ip = (ip4_header_t *) match;
5918   
5919   /* These are realistically matched in practice */
5920   if (src)
5921     ip->src_address.as_u32 = src_val.as_u32;
5922
5923   if (dst)
5924     ip->dst_address.as_u32 = dst_val.as_u32;
5925   
5926   if (proto)
5927     ip->protocol = proto_val;
5928     
5929
5930   /* These are not, but they're included for completeness */
5931   if (version)
5932     ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
5933
5934   if (hdr_length)
5935     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
5936     
5937   if (tos)
5938     ip->tos = tos_val;
5939   
5940   if (length)
5941     ip->length = length_val;
5942   
5943   if (ttl)
5944     ip->ttl = ttl_val;
5945
5946   if (checksum)
5947     ip->checksum = checksum_val;
5948
5949   *matchp = match;
5950   return 1;
5951 }
5952
5953 uword unformat_ip6_match (unformat_input_t * input, va_list * args)
5954 {
5955   u8 ** matchp = va_arg (*args, u8 **);
5956   u8 * match = 0;
5957   ip6_header_t * ip;
5958   int version = 0;
5959   u32 version_val;
5960   u8  traffic_class;
5961   u32 traffic_class_val;
5962   u8  flow_label;
5963   u8  flow_label_val;
5964   int src = 0, dst = 0;
5965   ip6_address_t src_val, dst_val;
5966   int proto = 0;
5967   u32 proto_val;
5968   int payload_length = 0;
5969   u32 payload_length_val;
5970   int hop_limit = 0;
5971   int hop_limit_val;
5972   u32 ip_version_traffic_class_and_flow_label;
5973
5974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
5975     {
5976       if (unformat (input, "version %d", &version_val)) 
5977         version = 1;
5978       else if (unformat (input, "traffic_class %d", &traffic_class_val))
5979         traffic_class = 1;
5980       else if (unformat (input, "flow_label %d", &flow_label_val))
5981         flow_label = 1;
5982       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
5983         src = 1;
5984       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
5985         dst = 1;
5986       else if (unformat (input, "proto %d", &proto_val))
5987         proto = 1;
5988       else if (unformat (input, "payload_length %d", &payload_length_val))
5989         payload_length = 1;
5990       else if (unformat (input, "hop_limit %d", &hop_limit_val))
5991         hop_limit = 1;
5992       else
5993         break;
5994     }
5995   
5996   if (version + traffic_class + flow_label + src + dst + proto +
5997       payload_length + hop_limit == 0)
5998     return 0;
5999
6000   /* 
6001    * Aligned because we use the real comparison functions
6002    */
6003   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6004   
6005   ip = (ip6_header_t *) match;
6006   
6007   if (src)
6008     memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
6009
6010   if (dst)
6011     memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
6012   
6013   if (proto)
6014     ip->protocol = proto_val;
6015     
6016   ip_version_traffic_class_and_flow_label = 0;
6017
6018   if (version)
6019     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6020
6021   if (traffic_class)
6022     ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6023
6024   if (flow_label)
6025     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6026     
6027   ip->ip_version_traffic_class_and_flow_label = 
6028     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6029
6030   if (payload_length)
6031     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6032   
6033   if (hop_limit)
6034     ip->hop_limit = hop_limit_val;
6035
6036   *matchp = match;
6037   return 1;
6038 }
6039
6040 uword unformat_l3_match (unformat_input_t * input, va_list * args)
6041 {
6042   u8 ** matchp = va_arg (*args, u8 **);
6043
6044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6045     if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6046       return 1;
6047     else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6048       return 1;
6049     else
6050       break;
6051   }
6052   return 0;
6053 }
6054
6055 uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6056 {
6057   u8 * tagp = va_arg (*args, u8 *);
6058   u32 tag;
6059
6060   if (unformat(input, "%d", &tag))
6061     {
6062       tagp[0] = (tag>>8) & 0x0F;
6063       tagp[1] = tag & 0xFF;
6064       return 1;
6065     }
6066
6067   return 0;
6068 }
6069
6070 uword unformat_l2_match (unformat_input_t * input, va_list * args)
6071 {
6072   u8 ** matchp = va_arg (*args, u8 **);
6073   u8 * match = 0;
6074   u8 src = 0;
6075   u8 src_val[6];
6076   u8 dst = 0;
6077   u8 dst_val[6];
6078   u8 proto = 0;
6079   u16 proto_val;
6080   u8 tag1 = 0;
6081   u8 tag1_val [2];
6082   u8 tag2 = 0;
6083   u8 tag2_val [2];
6084   int len = 14;
6085   u8 ignore_tag1 = 0;
6086   u8 ignore_tag2 = 0;
6087   u8 cos1 = 0;
6088   u8 cos2 = 0;
6089   u32 cos1_val = 0;
6090   u32 cos2_val = 0;
6091
6092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6093     if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6094       src = 1;
6095     else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6096       dst = 1;
6097     else if (unformat (input, "proto %U", 
6098                        unformat_ethernet_type_host_byte_order, &proto_val))
6099       proto = 1;
6100     else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6101       tag1 = 1;
6102     else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6103       tag2 = 1;
6104     else if (unformat (input, "ignore-tag1"))
6105       ignore_tag1 = 1;
6106     else if (unformat (input, "ignore-tag2"))
6107       ignore_tag2 = 1;
6108     else if (unformat (input, "cos1 %d", &cos1_val))
6109       cos1 = 1;
6110     else if (unformat (input, "cos2 %d", &cos2_val))
6111       cos2 = 1;
6112     else
6113       break;
6114   }
6115   if ((src + dst + proto + tag1 + tag2 +
6116       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6117     return 0;
6118
6119   if (tag1 || ignore_tag1 || cos1)
6120     len = 18;
6121   if (tag2 || ignore_tag2 || cos2)
6122     len = 22;
6123
6124   vec_validate_aligned (match, len-1, sizeof(u32x4));
6125
6126   if (dst)
6127     memcpy (match, dst_val, 6);
6128
6129   if (src)
6130     memcpy (match + 6, src_val, 6);
6131   
6132   if (tag2)
6133     {
6134       /* inner vlan tag */
6135       match[19] = tag2_val[1];
6136       match[18] = tag2_val[0];
6137       if (cos2)
6138         match [18] |= (cos2_val & 0x7) << 5;
6139       if (proto)
6140         {
6141           match[21] = proto_val & 0xff;
6142           match[20] = proto_val >> 8;
6143         }
6144       if (tag1)
6145         {
6146           match [15] = tag1_val[1];
6147           match [14] = tag1_val[0];
6148         }
6149       if (cos1)
6150         match [14] |= (cos1_val & 0x7) << 5;
6151       *matchp = match;
6152       return 1;
6153     }
6154   if (tag1)
6155     {
6156       match [15] = tag1_val[1];
6157       match [14] = tag1_val[0];
6158       if (proto)
6159         {
6160           match[17] = proto_val & 0xff;
6161           match[16] = proto_val >> 8;
6162         }
6163       if (cos1)
6164         match [14] |= (cos1_val & 0x7) << 5;
6165
6166       *matchp = match;
6167       return 1;
6168     }
6169   if (cos2)
6170     match [18] |= (cos2_val & 0x7) << 5;
6171   if (cos1)
6172     match [14] |= (cos1_val & 0x7) << 5;
6173   if (proto)
6174     {
6175       match[13] = proto_val & 0xff;
6176       match[12] = proto_val >> 8;
6177     }
6178   
6179   *matchp = match;
6180   return 1;
6181 }
6182
6183
6184 uword unformat_classify_match (unformat_input_t * input, va_list * args)
6185 {
6186   u8 ** matchp = va_arg (*args, u8 **);
6187   u32 skip_n_vectors = va_arg (*args, u32);
6188   u32 match_n_vectors = va_arg (*args, u32);
6189   
6190   u8 * match = 0;
6191   u8 * l2 = 0;
6192   u8 * l3 = 0;
6193
6194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6195     if (unformat (input, "hex %U", unformat_hex_string, &match))
6196       ;
6197     else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6198       ;
6199     else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6200       ;
6201     else
6202       break;
6203   }
6204
6205   if (match || l2 || l3)
6206     {
6207       if (l2 || l3)
6208         {
6209           /* "Win a free Ethernet header in every packet" */
6210           if (l2 == 0)
6211             vec_validate_aligned (l2, 13, sizeof(u32x4));
6212           match = l2;
6213           vec_append_aligned (match, l3, sizeof(u32x4));
6214           vec_free (l3);
6215         }
6216
6217       /* Make sure the vector is big enough even if key is all 0's */
6218       vec_validate_aligned 
6219           (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6220            sizeof(u32x4));
6221       
6222       /* Set size, include skipped vectors*/
6223       _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6224
6225       *matchp = match;
6226
6227       return 1;
6228     }
6229
6230   return 0;
6231 }
6232
6233 static int api_classify_add_del_session (vat_main_t * vam)
6234 {
6235     unformat_input_t * i = vam->input;
6236     vl_api_classify_add_del_session_t *mp;
6237     int is_add = 1;
6238     u32 table_index = ~0;
6239     u32 hit_next_index = ~0;
6240     u32 opaque_index = ~0;
6241     u8 * match = 0;
6242     i32 advance = 0;
6243     f64 timeout;
6244     u32 skip_n_vectors = 0;
6245     u32 match_n_vectors = 0;
6246
6247     /* 
6248      * Warning: you have to supply skip_n and match_n
6249      * because the API client cant simply look at the classify
6250      * table object.
6251      */
6252
6253     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6254         if (unformat (i, "del"))
6255             is_add = 0;
6256         else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6257                            &hit_next_index))
6258             ;
6259         else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6260                            &hit_next_index))
6261             ;
6262         else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6263                            &hit_next_index))
6264             ;
6265         else if (unformat (i, "opaque-index %d", &opaque_index))
6266             ;
6267         else if (unformat (i, "skip_n %d", &skip_n_vectors))
6268             ;
6269         else if (unformat (i, "match_n %d", &match_n_vectors))
6270             ;
6271         else if (unformat (i, "match %U", unformat_classify_match,
6272                            &match, skip_n_vectors, match_n_vectors))
6273             ;
6274         else if (unformat (i, "advance %d", &advance))
6275             ;
6276         else if (unformat (i, "table-index %d", &table_index))
6277             ;
6278         else
6279             break;
6280     }
6281
6282     if (table_index == ~0) {
6283         errmsg ("Table index required\n");
6284         return -99;
6285     }
6286
6287     if (is_add && match == 0) {
6288         errmsg ("Match value required\n");
6289         return -99;
6290     }
6291
6292     M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6293         vec_len(match));
6294
6295     mp->is_add = is_add;
6296     mp->table_index = ntohl(table_index);
6297     mp->hit_next_index = ntohl(hit_next_index);
6298     mp->opaque_index = ntohl(opaque_index);
6299     mp->advance = ntohl(advance);
6300     memcpy (mp->match, match, vec_len(match));
6301     vec_free(match);
6302
6303     S; W;
6304     /* NOTREACHED */
6305 }
6306
6307 static int api_classify_set_interface_ip_table (vat_main_t * vam)
6308 {
6309     unformat_input_t * i = vam->input;
6310     vl_api_classify_set_interface_ip_table_t *mp;
6311     f64 timeout;
6312     u32 sw_if_index;
6313     int sw_if_index_set;
6314     u32 table_index = ~0;
6315     u8  is_ipv6 = 0;
6316
6317     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6318         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6319             sw_if_index_set = 1;
6320         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6321             sw_if_index_set = 1;
6322         else if (unformat (i, "table %d", &table_index))
6323             ;
6324         else {
6325             clib_warning ("parse error '%U'", format_unformat_error, i);
6326             return -99;
6327         }
6328     }
6329     
6330     if (sw_if_index_set == 0) {
6331         errmsg ("missing interface name or sw_if_index\n");
6332         return -99;
6333     }
6334
6335
6336     M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6337
6338     mp->sw_if_index = ntohl(sw_if_index);
6339     mp->table_index = ntohl(table_index);
6340     mp->is_ipv6 = is_ipv6;
6341
6342     S; W;
6343     /* NOTREACHED */
6344     return 0;
6345 }
6346
6347 static int api_classify_set_interface_l2_tables (vat_main_t * vam)
6348 {
6349     unformat_input_t * i = vam->input;
6350     vl_api_classify_set_interface_l2_tables_t *mp;
6351     f64 timeout;
6352     u32 sw_if_index;
6353     int sw_if_index_set;
6354     u32 ip4_table_index = ~0;
6355     u32 ip6_table_index = ~0;
6356     u32 other_table_index = ~0;
6357
6358     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6359         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6360             sw_if_index_set = 1;
6361         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6362             sw_if_index_set = 1;
6363         else if (unformat (i, "ip4-table %d", &ip4_table_index))
6364             ;
6365         else if (unformat (i, "ip6-table %d", &ip6_table_index))
6366             ;
6367         else if (unformat (i, "other-table %d", &other_table_index))
6368             ;
6369         else {
6370             clib_warning ("parse error '%U'", format_unformat_error, i);
6371             return -99;
6372         }
6373     }
6374     
6375     if (sw_if_index_set == 0) {
6376         errmsg ("missing interface name or sw_if_index\n");
6377         return -99;
6378     }
6379
6380
6381     M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
6382
6383     mp->sw_if_index = ntohl(sw_if_index);
6384     mp->ip4_table_index = ntohl(ip4_table_index);
6385     mp->ip6_table_index = ntohl(ip6_table_index);
6386     mp->other_table_index = ntohl(other_table_index);
6387
6388
6389     S; W;
6390     /* NOTREACHED */
6391     return 0;
6392 }
6393
6394 static int api_get_node_index (vat_main_t * vam)
6395 {
6396     unformat_input_t * i = vam->input;
6397     vl_api_get_node_index_t * mp;
6398     f64 timeout;
6399     u8 * name = 0;
6400     
6401     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6402         if (unformat (i, "node %s", &name))
6403             ;
6404         else
6405             break;
6406     }
6407     if (name == 0) {
6408         errmsg ("node name required\n");
6409         return -99;
6410     }
6411     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6412         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6413         return -99;
6414     }
6415
6416     M(GET_NODE_INDEX, get_node_index);
6417     memcpy (mp->node_name, name, vec_len(name));
6418     vec_free(name);
6419     
6420     S; W;
6421     /* NOTREACHED */
6422     return 0;
6423 }
6424
6425 static int api_add_node_next (vat_main_t * vam)
6426 {
6427     unformat_input_t * i = vam->input;
6428     vl_api_add_node_next_t * mp;
6429     f64 timeout;
6430     u8 * name = 0;
6431     u8 * next = 0;
6432
6433     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6434         if (unformat (i, "node %s", &name))
6435             ;
6436         else if (unformat (i, "next %s", &next))
6437             ;
6438         else
6439             break;
6440     }
6441     if (name == 0) {
6442         errmsg ("node name required\n");
6443         return -99;
6444     }
6445     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
6446         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
6447         return -99;
6448     }
6449     if (next == 0) {
6450         errmsg ("next node required\n");
6451         return -99;
6452     }
6453     if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
6454         errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
6455         return -99;
6456     }
6457     
6458     M(ADD_NODE_NEXT, add_node_next);
6459     memcpy (mp->node_name, name, vec_len(name));
6460     memcpy (mp->next_name, next, vec_len(next));
6461     vec_free(name);
6462     vec_free(next);
6463     
6464     S; W;
6465     /* NOTREACHED */
6466     return 0;
6467 }
6468
6469 static int api_l2tpv3_create_tunnel (vat_main_t * vam)
6470 {
6471     unformat_input_t * i = vam->input;
6472     ip6_address_t client_address, our_address;
6473     int client_address_set = 0;
6474     int our_address_set = 0;
6475     u32 local_session_id = 0;
6476     u32 remote_session_id = 0;
6477     u64 local_cookie = 0;
6478     u64 remote_cookie = 0;
6479     u8 l2_sublayer_present = 0;
6480     vl_api_l2tpv3_create_tunnel_t * mp;
6481     f64 timeout;
6482
6483     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6484         if (unformat (i, "client_address %U", unformat_ip6_address, 
6485                       &client_address))
6486             client_address_set = 1;
6487         else if (unformat (i, "our_address %U", unformat_ip6_address, 
6488                            &our_address))
6489             our_address_set = 1;
6490         else if (unformat (i, "local_session_id %d", &local_session_id))
6491             ;
6492         else if (unformat (i, "remote_session_id %d", &remote_session_id))
6493             ;
6494         else if (unformat (i, "local_cookie %lld", &local_cookie))
6495             ;
6496         else if (unformat (i, "remote_cookie %lld", &remote_cookie))
6497             ;
6498         else if (unformat (i, "l2-sublayer-present"))
6499             l2_sublayer_present = 1;
6500         else
6501             break;
6502     }
6503
6504     if (client_address_set == 0) {
6505         errmsg ("client_address required\n");
6506         return -99;
6507     }
6508
6509     if (our_address_set == 0) {
6510         errmsg ("our_address required\n");
6511         return -99;
6512     }
6513
6514     M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
6515
6516     memcpy (mp->client_address, client_address.as_u8, 
6517             sizeof (mp->client_address));
6518
6519     memcpy (mp->our_address, our_address.as_u8, 
6520             sizeof (mp->our_address));
6521     
6522     mp->local_session_id = ntohl (local_session_id);
6523     mp->remote_session_id = ntohl (remote_session_id);
6524     mp->local_cookie = clib_host_to_net_u64 (local_cookie);
6525     mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
6526     mp->l2_sublayer_present = l2_sublayer_present;
6527     mp->is_ipv6 = 1;
6528
6529     S; W;
6530     /* NOTREACHED */
6531     return 0;
6532 }
6533
6534 static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
6535 {
6536     unformat_input_t * i = vam->input;
6537     u32 sw_if_index;
6538     u8  sw_if_index_set = 0;
6539     u64 new_local_cookie = 0;
6540     u64 new_remote_cookie = 0;
6541     vl_api_l2tpv3_set_tunnel_cookies_t *mp;
6542     f64 timeout;
6543
6544     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6545         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6546             sw_if_index_set = 1;
6547         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6548             sw_if_index_set = 1;
6549         else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
6550             ;
6551         else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
6552             ;
6553         else
6554             break;
6555     }
6556
6557     if (sw_if_index_set == 0) {
6558         errmsg ("missing interface name or sw_if_index\n");
6559         return -99;
6560     }
6561
6562     M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
6563
6564     mp->sw_if_index = ntohl(sw_if_index);
6565     mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
6566     mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
6567
6568     S; W;
6569     /* NOTREACHED */
6570     return 0;
6571 }
6572
6573 static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
6574 {
6575     unformat_input_t * i = vam->input;
6576     vl_api_l2tpv3_interface_enable_disable_t *mp;
6577     f64 timeout;
6578     u32 sw_if_index;
6579     u8  sw_if_index_set = 0;
6580     u8  enable_disable = 1;
6581
6582     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6583         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6584             sw_if_index_set = 1;
6585         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6586             sw_if_index_set = 1;
6587         else if (unformat (i, "enable"))
6588             enable_disable = 1;
6589         else if (unformat (i, "disable"))
6590             enable_disable = 0;
6591         else
6592             break;
6593     }
6594
6595     if (sw_if_index_set == 0) {
6596         errmsg ("missing interface name or sw_if_index\n");
6597         return -99;
6598     }
6599     
6600     M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
6601
6602     mp->sw_if_index = ntohl(sw_if_index);
6603     mp->enable_disable = enable_disable;
6604
6605     S; W;
6606     /* NOTREACHED */
6607     return 0;
6608 }
6609
6610 static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
6611 {
6612     unformat_input_t * i = vam->input;
6613     vl_api_l2tpv3_set_lookup_key_t * mp;
6614     f64 timeout;
6615     u8 key = ~0;
6616
6617     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6618         if (unformat (i, "lookup_v6_src"))
6619             key = L2T_LOOKUP_SRC_ADDRESS;
6620         else if (unformat (i, "lookup_v6_dst"))
6621             key = L2T_LOOKUP_DST_ADDRESS;
6622         else if (unformat (i, "lookup_session_id"))
6623             key = L2T_LOOKUP_SESSION_ID;
6624         else
6625             break;
6626     }
6627
6628     if (key == ~0) {
6629         errmsg ("l2tp session lookup key unset\n");
6630         return -99;
6631     }
6632     
6633     M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
6634
6635     mp->key = key;
6636
6637     S; W;
6638     /* NOTREACHED */
6639     return 0;
6640 }
6641
6642 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
6643 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
6644 {
6645     vat_main_t * vam = &vat_main;
6646
6647     fformat(vam->ofp,  "* %U (our) %U (client) (sw_if_index %d)\n",
6648               format_ip6_address, mp->our_address,
6649               format_ip6_address, mp->client_address,
6650               clib_net_to_host_u32(mp->sw_if_index));
6651
6652     fformat (vam->ofp, "   local cookies %016llx %016llx remote cookie %016llx\n",
6653               clib_net_to_host_u64 (mp->local_cookie[0]),
6654               clib_net_to_host_u64 (mp->local_cookie[1]),
6655               clib_net_to_host_u64 (mp->remote_cookie));
6656
6657     fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
6658               clib_net_to_host_u32 (mp->local_session_id),
6659               clib_net_to_host_u32 (mp->remote_session_id));
6660
6661     fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
6662               mp->l2_sublayer_present ? "preset" : "absent");
6663
6664 }
6665
6666 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
6667 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
6668 {
6669     vat_main_t * vam = &vat_main;
6670     vat_json_node_t *node = NULL;
6671     struct in6_addr addr;
6672
6673     if (VAT_JSON_ARRAY != vam->json_tree.type) {
6674         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6675         vat_json_init_array(&vam->json_tree);
6676     }
6677     node = vat_json_array_add(&vam->json_tree);
6678
6679     vat_json_init_object(node);
6680
6681     memcpy(&addr, mp->our_address, sizeof(addr));
6682     vat_json_object_add_ip6(node, "our_address", addr);
6683     memcpy(&addr, mp->client_address, sizeof(addr));
6684     vat_json_object_add_ip6(node, "client_address", addr);
6685
6686     vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
6687     vat_json_init_array(lc);
6688     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
6689     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
6690     vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
6691
6692     printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
6693     vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
6694     vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
6695     vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
6696             (u8*)"present" : (u8*)"absent");
6697 }
6698
6699 static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
6700 {
6701     vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
6702     f64 timeout;
6703
6704     /* Get list of l2tpv3-tunnel interfaces */
6705     M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
6706     S;
6707
6708     /* Use a control ping for synchronization */
6709     {
6710         vl_api_control_ping_t * mp;
6711         M(CONTROL_PING, control_ping);
6712         S;
6713     }
6714     W;
6715 }
6716
6717
6718 static void vl_api_sw_interface_tap_details_t_handler
6719 (vl_api_sw_interface_tap_details_t * mp)
6720 {
6721     vat_main_t * vam = &vat_main;
6722
6723     fformat(vam->ofp,  "%-16s %d\n",
6724               mp->dev_name,
6725               clib_net_to_host_u32(mp->sw_if_index));
6726 }
6727
6728 static void vl_api_sw_interface_tap_details_t_handler_json
6729 (vl_api_sw_interface_tap_details_t * mp)
6730 {
6731     vat_main_t * vam = &vat_main;
6732     vat_json_node_t *node = NULL;
6733
6734     if (VAT_JSON_ARRAY != vam->json_tree.type) {
6735         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6736         vat_json_init_array(&vam->json_tree);
6737     }
6738     node = vat_json_array_add(&vam->json_tree);
6739
6740     vat_json_init_object(node);
6741     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
6742     vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
6743 }
6744
6745 static int api_sw_interface_tap_dump (vat_main_t * vam)
6746 {
6747     vl_api_sw_interface_tap_dump_t *mp;
6748     f64 timeout;
6749
6750     fformat(vam->ofp,  "\n%-16s %s\n", "dev_name", "sw_if_index");
6751     /* Get list of tap interfaces */
6752     M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
6753     S;
6754
6755     /* Use a control ping for synchronization */
6756     {
6757         vl_api_control_ping_t * mp;
6758         M(CONTROL_PING, control_ping);
6759         S;
6760     }
6761     W;
6762 }
6763
6764 static uword unformat_vxlan_decap_next 
6765 (unformat_input_t * input, va_list * args)
6766 {
6767   u32 * result = va_arg (*args, u32 *);
6768   u32 tmp;
6769   
6770   if (unformat (input, "drop"))
6771     *result = VXLAN_INPUT_NEXT_DROP;
6772   else if (unformat (input, "ip4"))
6773     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
6774   else if (unformat (input, "ip6"))
6775     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
6776   else if (unformat (input, "l2"))
6777     *result = VXLAN_INPUT_NEXT_L2_INPUT;
6778   else if (unformat (input, "%d", &tmp))
6779     *result = tmp;
6780   else
6781     return 0;
6782   return 1;
6783 }
6784
6785 static int api_vxlan_add_del_tunnel (vat_main_t * vam)
6786 {
6787     unformat_input_t * line_input = vam->input;
6788     vl_api_vxlan_add_del_tunnel_t *mp;
6789     f64 timeout;
6790     ip4_address_t src, dst;
6791     u8 is_add = 1;
6792     u8 src_set = 0;
6793     u8 dst_set = 0;
6794     u32 encap_vrf_id = 0;
6795     u32 decap_next_index = ~0;
6796     u32 vni = 0;
6797
6798     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
6799         if (unformat (line_input, "del"))
6800             is_add = 0;
6801         else if (unformat (line_input, "src %U", 
6802                            unformat_ip4_address, &src))
6803             src_set = 1;
6804         else if (unformat (line_input, "dst %U",
6805                            unformat_ip4_address, &dst))
6806             dst_set = 1;
6807         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
6808             ;
6809         else if (unformat (line_input, "decap-next %U", 
6810                            unformat_vxlan_decap_next, &decap_next_index))
6811             ;
6812         else if (unformat (line_input, "vni %d", &vni))
6813             ;
6814         else {
6815             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
6816             return -99;
6817         }
6818     }
6819
6820     if (src_set == 0) {
6821         errmsg ("tunnel src address not specified\n");
6822         return -99;
6823     }
6824     if (dst_set == 0) {
6825         errmsg ("tunnel dst address not specified\n");
6826         return -99;
6827     }
6828
6829     if ((vni == 0) || (vni>>24)) {
6830         errmsg ("vni not specified or out of range\n");
6831         return -99;
6832     }
6833
6834     M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
6835     
6836     mp->src_address = src.as_u32;
6837     mp->dst_address = dst.as_u32;
6838     mp->encap_vrf_id = ntohl(encap_vrf_id);
6839     mp->decap_next_index = ntohl(decap_next_index);
6840     mp->vni = ntohl(vni);
6841     mp->is_add = is_add;
6842
6843     S; W;
6844     /* NOTREACHED */
6845     return 0;
6846 }
6847
6848 static void vl_api_vxlan_tunnel_details_t_handler
6849 (vl_api_vxlan_tunnel_details_t * mp)
6850 {
6851     vat_main_t * vam = &vat_main;
6852
6853     fformat(vam->ofp, "%11d%13U%13U%14d%18d%13d\n",
6854             ntohl(mp->sw_if_index),
6855             format_ip4_address, &mp->src_address,
6856             format_ip4_address, &mp->dst_address,
6857             ntohl(mp->encap_vrf_id),
6858             ntohl(mp->decap_next_index),
6859             ntohl(mp->vni));
6860 }
6861
6862 static void vl_api_vxlan_tunnel_details_t_handler_json
6863 (vl_api_vxlan_tunnel_details_t * mp)
6864 {
6865     vat_main_t * vam = &vat_main;
6866     vat_json_node_t *node = NULL;
6867     struct in_addr ip4;
6868
6869     if (VAT_JSON_ARRAY != vam->json_tree.type) {
6870         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
6871         vat_json_init_array(&vam->json_tree);
6872     }
6873     node = vat_json_array_add(&vam->json_tree);
6874
6875     vat_json_init_object(node);
6876     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
6877     memcpy(&ip4, &mp->src_address, sizeof(ip4));
6878     vat_json_object_add_ip4(node, "src_address", ip4);
6879     memcpy(&ip4, &mp->dst_address, sizeof(ip4));
6880     vat_json_object_add_ip4(node, "dst_address", ip4);
6881     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
6882     vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
6883     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
6884 }
6885
6886 static int api_vxlan_tunnel_dump (vat_main_t * vam)
6887 {
6888     unformat_input_t * i = vam->input;
6889     vl_api_vxlan_tunnel_dump_t *mp;
6890     f64 timeout;
6891     u32 sw_if_index;
6892     u8 sw_if_index_set = 0;
6893
6894     /* Parse args required to build the message */
6895     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6896         if (unformat (i, "sw_if_index %d", &sw_if_index))
6897             sw_if_index_set = 1;
6898         else
6899             break;
6900     }
6901
6902     if (sw_if_index_set == 0) {
6903         sw_if_index = ~0;
6904     }
6905
6906     if (!vam->json_output) {
6907         fformat(vam->ofp, "%11s%13s%13s%14s%18s%13s\n",
6908                 "sw_if_index", "src_address", "dst_address",
6909                 "encap_vrf_id", "decap_next_index", "vni");
6910     }
6911
6912     /* Get list of l2tpv3-tunnel interfaces */
6913     M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
6914
6915     mp->sw_if_index = htonl(sw_if_index);
6916
6917     S;
6918
6919     /* Use a control ping for synchronization */
6920     {
6921         vl_api_control_ping_t * mp;
6922         M(CONTROL_PING, control_ping);
6923         S;
6924     }
6925     W;
6926 }
6927
6928 static int api_l2_fib_clear_table (vat_main_t * vam)
6929 {
6930 //  unformat_input_t * i = vam->input;
6931     vl_api_l2_fib_clear_table_t *mp;
6932     f64 timeout;
6933
6934     M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
6935
6936     S; W;
6937     /* NOTREACHED */
6938     return 0;
6939 }
6940
6941 static int api_l2_interface_efp_filter (vat_main_t * vam)
6942 {
6943     unformat_input_t * i = vam->input;
6944     vl_api_l2_interface_efp_filter_t *mp;
6945     f64 timeout;
6946     u32 sw_if_index;
6947     u8 enable = 1;
6948     u8 sw_if_index_set = 0;
6949
6950     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6951         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6952             sw_if_index_set = 1;
6953         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6954             sw_if_index_set = 1;
6955         else if (unformat (i, "enable"))
6956             enable = 1;
6957         else if (unformat (i, "disable"))
6958             enable = 0;
6959         else {
6960             clib_warning ("parse error '%U'", format_unformat_error, i);
6961             return -99;
6962         }
6963     }
6964     
6965     if (sw_if_index_set == 0) {
6966         errmsg ("missing sw_if_index\n");
6967         return -99;
6968     }
6969
6970     M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
6971
6972     mp->sw_if_index = ntohl(sw_if_index);
6973     mp->enable_disable = enable;
6974
6975     S; W;
6976     /* NOTREACHED */
6977     return 0;
6978 }
6979
6980 #define foreach_vtr_op                          \
6981 _("disable",  L2_VTR_DISABLED)                  \
6982 _("push-1",  L2_VTR_PUSH_1)                     \
6983 _("push-2",  L2_VTR_PUSH_2)                     \
6984 _("pop-1",  L2_VTR_POP_1)                       \
6985 _("pop-2",  L2_VTR_POP_2)                       \
6986 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
6987 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
6988 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
6989 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
6990
6991 static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
6992 {
6993     unformat_input_t * i = vam->input;
6994     vl_api_l2_interface_vlan_tag_rewrite_t *mp;
6995     f64 timeout;
6996     u32 sw_if_index;
6997     u8 sw_if_index_set = 0;
6998     u8 vtr_op_set = 0;
6999     u32 vtr_op = 0;
7000     u32 push_dot1q = 1;
7001     u32 tag1 = ~0;
7002     u32 tag2 = ~0;
7003
7004     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7005         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7006             sw_if_index_set = 1;
7007         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7008             sw_if_index_set = 1;
7009         else if (unformat (i, "vtr_op %d", &vtr_op))
7010             vtr_op_set = 1;
7011 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7012         foreach_vtr_op
7013 #undef _
7014         
7015         else if (unformat (i, "push_dot1q %d", &push_dot1q))
7016             ;
7017         else if (unformat (i, "tag1 %d", &tag1))
7018             ;
7019         else if (unformat (i, "tag2 %d", &tag2))
7020             ;
7021         else {
7022             clib_warning ("parse error '%U'", format_unformat_error, i);
7023             return -99;
7024         }
7025     }
7026     
7027     if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7028         errmsg ("missing vtr operation or sw_if_index\n");
7029         return -99;
7030     }
7031
7032     M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7033
7034     mp->sw_if_index = ntohl(sw_if_index);
7035     mp->vtr_op = ntohl(vtr_op);
7036     mp->push_dot1q = ntohl(push_dot1q);
7037     mp->tag1 = ntohl(tag1);
7038     mp->tag2 = ntohl(tag2);
7039
7040     S; W;
7041     /* NOTREACHED */
7042     return 0;
7043 }
7044
7045 static int api_create_vhost_user_if (vat_main_t * vam)
7046 {
7047     unformat_input_t * i = vam->input;
7048     vl_api_create_vhost_user_if_t *mp;
7049     f64 timeout;
7050     u8 * file_name;
7051     u8 is_server = 0;
7052     u8 file_name_set = 0;
7053     u32 custom_dev_instance = ~0;
7054     u8 hwaddr[6];
7055     u8 use_custom_mac = 0;
7056
7057     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7058       if (unformat (i, "socket %s", &file_name)) {
7059         file_name_set = 1;
7060       }
7061       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7062         ;
7063       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7064         use_custom_mac = 1;
7065       else if (unformat (i, "server"))
7066         is_server = 1;
7067       else
7068         break;
7069     }
7070
7071     if (file_name_set == 0) {
7072       errmsg ("missing socket file name\n");
7073       return -99;
7074     }
7075
7076     if (vec_len (file_name) > 255) {
7077       errmsg ("socket file name too long\n");
7078       return -99;
7079     }
7080     vec_add1 (file_name, 0);
7081
7082     M(CREATE_VHOST_USER_IF, create_vhost_user_if);
7083
7084     mp->is_server = is_server;
7085     memcpy(mp->sock_filename, file_name, vec_len(file_name));
7086     vec_free(file_name);
7087     if (custom_dev_instance != ~0) {
7088         mp->renumber = 1;
7089         mp->custom_dev_instance = ntohl(custom_dev_instance);
7090     }
7091     mp->use_custom_mac = use_custom_mac;
7092     memcpy(mp->mac_address, hwaddr, 6);
7093
7094     S; W;
7095     /* NOTREACHED */
7096     return 0;
7097 }
7098
7099 static int api_modify_vhost_user_if (vat_main_t * vam)
7100 {
7101     unformat_input_t * i = vam->input;
7102     vl_api_modify_vhost_user_if_t *mp;
7103     f64 timeout;
7104     u8 * file_name;
7105     u8 is_server = 0;
7106     u8 file_name_set = 0;
7107     u32 custom_dev_instance = ~0;
7108     u8 sw_if_index_set = 0;
7109     u32 sw_if_index = (u32)~0;
7110
7111     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7112       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7113           sw_if_index_set = 1;
7114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7115           sw_if_index_set = 1;
7116       else if (unformat (i, "socket %s", &file_name)) {
7117         file_name_set = 1;
7118       }
7119       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7120         ;
7121       else if (unformat (i, "server"))
7122         is_server = 1;
7123       else
7124         break;
7125     }
7126
7127     if (sw_if_index_set == 0) {
7128        errmsg ("missing sw_if_index or interface name\n");
7129        return -99;
7130     }
7131
7132     if (file_name_set == 0) {
7133       errmsg ("missing socket file name\n");
7134       return -99;
7135     }
7136
7137     if (vec_len (file_name) > 255) {
7138       errmsg ("socket file name too long\n");
7139       return -99;
7140     }
7141     vec_add1 (file_name, 0);
7142
7143     M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
7144
7145     mp->sw_if_index = ntohl(sw_if_index);
7146     mp->is_server = is_server;
7147     memcpy(mp->sock_filename, file_name, vec_len(file_name));
7148     vec_free(file_name);
7149     if (custom_dev_instance != ~0) {
7150         mp->renumber = 1;
7151         mp->custom_dev_instance = ntohl(custom_dev_instance);
7152     }
7153
7154     S; W;
7155     /* NOTREACHED */
7156     return 0;
7157 }
7158
7159 static int api_delete_vhost_user_if (vat_main_t * vam)
7160 {
7161     unformat_input_t * i = vam->input;
7162     vl_api_delete_vhost_user_if_t *mp;
7163     f64 timeout;
7164     u32 sw_if_index = ~0;
7165     u8 sw_if_index_set = 0;
7166
7167     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7168       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7169           sw_if_index_set = 1;
7170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7171           sw_if_index_set = 1;
7172       else
7173         break;
7174     }
7175
7176     if (sw_if_index_set == 0) {
7177        errmsg ("missing sw_if_index or interface name\n");
7178        return -99;
7179     }
7180
7181
7182     M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
7183
7184     mp->sw_if_index = ntohl(sw_if_index);
7185
7186     S; W;
7187     /* NOTREACHED */
7188     return 0;
7189 }
7190
7191 static void vl_api_sw_interface_vhost_user_details_t_handler
7192 (vl_api_sw_interface_vhost_user_details_t * mp)
7193 {
7194     vat_main_t * vam = &vat_main;
7195
7196     fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
7197             (char *)mp->interface_name,
7198             ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
7199             clib_net_to_host_u64(mp->features), mp->is_server,
7200             ntohl(mp->num_regions), (char *)mp->sock_filename);
7201     fformat(vam->ofp, "    Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
7202 }
7203
7204 static void vl_api_sw_interface_vhost_user_details_t_handler_json
7205 (vl_api_sw_interface_vhost_user_details_t * mp)
7206 {
7207     vat_main_t * vam = &vat_main;
7208     vat_json_node_t *node = NULL;
7209
7210     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7211         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7212         vat_json_init_array(&vam->json_tree);
7213     }
7214     node = vat_json_array_add(&vam->json_tree);
7215
7216     vat_json_init_object(node);
7217     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7218     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
7219     vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
7220     vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
7221     vat_json_object_add_uint(node, "is_server", mp->is_server);
7222     vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
7223     vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
7224     vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
7225 }
7226
7227 static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
7228 {
7229     vl_api_sw_interface_vhost_user_dump_t *mp;
7230     f64 timeout;
7231     fformat(vam->ofp, "Interface name           idx hdr_sz features server regions filename\n");
7232
7233     /* Get list of vhost-user interfaces */
7234     M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
7235     S;
7236
7237     /* Use a control ping for synchronization */
7238     {
7239         vl_api_control_ping_t * mp;
7240         M(CONTROL_PING, control_ping);
7241         S;
7242     }
7243     W;
7244 }
7245
7246 static int api_show_version (vat_main_t * vam)
7247 {
7248     vl_api_show_version_t *mp;
7249     f64 timeout;
7250
7251     M(SHOW_VERSION, show_version);
7252
7253     S; W;
7254     /* NOTREACHED */
7255     return 0;
7256 }
7257
7258 static uword unformat_nsh_gre_decap_next 
7259 (unformat_input_t * input, va_list * args)
7260 {
7261   u32 * result = va_arg (*args, u32 *);
7262   u32 tmp;
7263   
7264   if (unformat (input, "drop"))
7265     *result = NSH_INPUT_NEXT_DROP;
7266   else if (unformat (input, "ip4"))
7267     *result = NSH_INPUT_NEXT_IP4_INPUT;
7268   else if (unformat (input, "ip6"))
7269     *result = NSH_INPUT_NEXT_IP6_INPUT;
7270   else if (unformat (input, "ethernet"))
7271     *result = NSH_INPUT_NEXT_ETHERNET_INPUT;
7272   else if (unformat (input, "%d", &tmp))
7273     *result = tmp;
7274   else
7275     return 0;
7276   return 1;
7277 }
7278
7279 static int api_nsh_gre_add_del_tunnel (vat_main_t * vam)
7280 {
7281     unformat_input_t * line_input = vam->input;
7282     vl_api_nsh_gre_add_del_tunnel_t *mp;
7283     f64 timeout;
7284     ip4_address_t src, dst;
7285     u8 is_add = 1;
7286     u8 src_set = 0;
7287     u8 dst_set = 0;
7288     u32 encap_vrf_id = 0;
7289     u32 decap_vrf_id = 0;
7290     u8 ver_o_c = 0;
7291     u8 md_type = 0;
7292     u8 next_protocol = 1; /* ip4 */
7293     u32 spi;
7294     u8 spi_set = 0;
7295     u32 si;
7296     u8 si_set = 0;
7297     u32 spi_si;
7298     u32 c1 = 0;
7299     u32 c2 = 0;
7300     u32 c3 = 0;
7301     u32 c4 = 0;
7302     u32 *tlvs = 0;
7303     u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
7304     u32 tmp;
7305     int i;
7306
7307     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7308         if (unformat (line_input, "del"))
7309             is_add = 0;
7310         else if (unformat (line_input, "src %U", 
7311                            unformat_ip4_address, &src))
7312             src_set = 1;
7313         else if (unformat (line_input, "dst %U",
7314                            unformat_ip4_address, &dst))
7315             dst_set = 1;
7316         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7317             ;
7318         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7319             ;
7320         else if (unformat (line_input, "decap-next %U", 
7321                            unformat_nsh_gre_decap_next, &decap_next_index))
7322             ;
7323         else if (unformat (line_input, "version %d", &tmp))
7324             ver_o_c |= (tmp & 3) << 6;
7325         else if (unformat (line_input, "o-bit %d", &tmp))
7326             ver_o_c |= (tmp & 1) << 5;
7327         else if (unformat (line_input, "c-bit %d", &tmp))
7328             ver_o_c |= (tmp & 1) << 4;
7329         else if (unformat (line_input, "md-type %d", &tmp))
7330             md_type = tmp;
7331         else if (unformat(line_input, "next-ip4"))
7332             next_protocol = 1;
7333         else if (unformat(line_input, "next-ip6"))
7334             next_protocol = 2;
7335         else if (unformat(line_input, "next-ethernet"))
7336             next_protocol = 3;
7337         else if (unformat (line_input, "c1 %d", &c1))
7338             ;
7339         else if (unformat (line_input, "c2 %d", &c2))
7340             ;
7341         else if (unformat (line_input, "c3 %d", &c3))
7342             ;
7343         else if (unformat (line_input, "c4 %d", &c4))
7344             ;
7345         else if (unformat (line_input, "spi %d", &spi))
7346             spi_set = 1;
7347         else if (unformat (line_input, "si %d", &si))
7348             si_set = 1;
7349         else if (unformat (line_input, "tlv %x"))
7350             vec_add1 (tlvs, tmp);
7351         else {
7352             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7353             return -99;
7354         }
7355     }
7356
7357     if (src_set == 0) {
7358         errmsg ("tunnel src address not specified\n");
7359         return -99;
7360     }
7361     if (dst_set == 0) {
7362         errmsg ("tunnel dst address not specified\n");
7363         return -99;
7364     }
7365
7366     if (spi_set == 0) {
7367         errmsg ("spi not specified\n");
7368         return -99;
7369     }
7370
7371     if (si_set == 0) {
7372         errmsg ("si not specified\n");
7373         return -99;
7374     }
7375
7376     M2 (NSH_GRE_ADD_DEL_TUNNEL, nsh_gre_add_del_tunnel,
7377         sizeof(u32) * vec_len (tlvs));
7378     
7379     spi_si = (spi<<8) | si;
7380
7381     mp->src = src.as_u32;
7382     mp->dst = dst.as_u32;
7383     mp->encap_vrf_id = ntohl(encap_vrf_id);
7384     mp->decap_vrf_id = ntohl(decap_vrf_id);
7385     mp->decap_next_index = ntohl(decap_next_index);
7386     mp->tlv_len_in_words = vec_len (tlvs);
7387     mp->is_add = is_add;
7388     mp->ver_o_c = ver_o_c;
7389     mp->length = 6 + vec_len(tlvs);
7390     mp->md_type = md_type;
7391     mp->next_protocol = next_protocol;
7392     mp->spi_si = ntohl(spi_si);
7393     mp->c1 = ntohl(c1);
7394     mp->c2 = ntohl(c2);
7395     mp->c3 = ntohl(c3);
7396     mp->c4 = ntohl(c4);
7397     
7398     for (i = 0; i < vec_len(tlvs); i++)
7399         mp->tlvs[i] = ntohl(tlvs[i]);
7400
7401     vec_free (tlvs);
7402
7403     S; W;
7404     /* NOTREACHED */
7405     return 0;
7406 }
7407
7408 static uword unformat_nsh_vxlan_gpe_decap_next 
7409 (unformat_input_t * input, va_list * args)
7410 {
7411   u32 * result = va_arg (*args, u32 *);
7412   u32 tmp;
7413   
7414   if (unformat (input, "drop"))
7415     *result = NSH_VXLAN_GPE_INPUT_NEXT_DROP;
7416   else if (unformat (input, "ip4"))
7417     *result = NSH_VXLAN_GPE_INPUT_NEXT_IP4_INPUT;
7418   else if (unformat (input, "ip6"))
7419     *result = NSH_VXLAN_GPE_INPUT_NEXT_IP6_INPUT;
7420   else if (unformat (input, "ethernet"))
7421     *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
7422   else if (unformat (input, "nsh-vxlan-gpe"))
7423       *result = NSH_VXLAN_GPE_INPUT_NEXT_ETHERNET_INPUT;
7424   else if (unformat (input, "%d", &tmp))
7425     *result = tmp;
7426   else
7427     return 0;
7428   return 1;
7429 }
7430
7431 static int api_nsh_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
7432 {
7433     unformat_input_t * line_input = vam->input;
7434     vl_api_nsh_vxlan_gpe_add_del_tunnel_t *mp;
7435     f64 timeout;
7436     ip4_address_t src, dst;
7437     u8 is_add = 1;
7438     u8 src_set = 0;
7439     u8 dst_set = 0;
7440     u32 encap_vrf_id = 0;
7441     u32 decap_vrf_id = 0;
7442     u8 ver_o_c = 0;
7443     u8 md_type = 0;
7444     u8 next_protocol = 1; /* ip4 */
7445     u32 spi;
7446     u8 spi_set = 0;
7447     u32 si;
7448     u8 si_set = 0;
7449     u32 spi_si;
7450     u32 c1 = 0;
7451     u32 c2 = 0;
7452     u32 c3 = 0;
7453     u32 c4 = 0;
7454     u32 *tlvs = 0;
7455     u32 decap_next_index = NSH_INPUT_NEXT_IP4_INPUT;
7456     u32 vni;
7457     u8 vni_set = 0;
7458     u32 tmp;
7459     int i;
7460
7461     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7462         if (unformat (line_input, "del"))
7463             is_add = 0;
7464         else if (unformat (line_input, "src %U", 
7465                            unformat_ip4_address, &src))
7466             src_set = 1;
7467         else if (unformat (line_input, "dst %U",
7468                            unformat_ip4_address, &dst))
7469             dst_set = 1;
7470         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7471             ;
7472         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7473             ;
7474         else if (unformat (line_input, "decap-next %U", 
7475                            unformat_nsh_vxlan_gpe_decap_next, 
7476                            &decap_next_index))
7477             ;
7478         else if (unformat (line_input, "vni %d", &vni))
7479             vni_set = 1;
7480         else if (unformat (line_input, "version %d", &tmp))
7481             ver_o_c |= (tmp & 3) << 6;
7482         else if (unformat (line_input, "o-bit %d", &tmp))
7483             ver_o_c |= (tmp & 1) << 5;
7484         else if (unformat (line_input, "c-bit %d", &tmp))
7485             ver_o_c |= (tmp & 1) << 4;
7486         else if (unformat (line_input, "md-type %d", &tmp))
7487             md_type = tmp;
7488         else if (unformat(line_input, "next-ip4"))
7489             next_protocol = 1;
7490         else if (unformat(line_input, "next-ip6"))
7491             next_protocol = 2;
7492         else if (unformat(line_input, "next-ethernet"))
7493             next_protocol = 3;
7494         else if (unformat (line_input, "c1 %d", &c1))
7495             ;
7496         else if (unformat (line_input, "c2 %d", &c2))
7497             ;
7498         else if (unformat (line_input, "c3 %d", &c3))
7499             ;
7500         else if (unformat (line_input, "c4 %d", &c4))
7501             ;
7502         else if (unformat (line_input, "spi %d", &spi))
7503             spi_set = 1;
7504         else if (unformat (line_input, "si %d", &si))
7505             si_set = 1;
7506         else if (unformat (line_input, "tlv %x"))
7507             vec_add1 (tlvs, tmp);
7508         else {
7509             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7510             return -99;
7511         }
7512     }
7513
7514     if (src_set == 0) {
7515         errmsg ("tunnel src address not specified\n");
7516         return -99;
7517     }
7518     if (dst_set == 0) {
7519         errmsg ("tunnel dst address not specified\n");
7520         return -99;
7521     }
7522
7523     if (spi_set == 0) {
7524         errmsg ("spi not specified\n");
7525         return -99;
7526     }
7527
7528     if (si_set == 0) {
7529         errmsg ("si not specified\n");
7530         return -99;
7531     }
7532     if (vni_set == 0) {
7533         errmsg ("vni not specified\n");
7534         return -99;
7535     }
7536
7537     M2 (NSH_VXLAN_GPE_ADD_DEL_TUNNEL, nsh_vxlan_gpe_add_del_tunnel,
7538         sizeof(u32) * vec_len (tlvs));
7539     
7540     spi_si = (spi<<8) | si;
7541
7542     mp->src = src.as_u32;
7543     mp->dst = dst.as_u32;
7544     mp->encap_vrf_id = ntohl(encap_vrf_id);
7545     mp->decap_vrf_id = ntohl(decap_vrf_id);
7546     mp->decap_next_index = ntohl(decap_next_index);
7547     mp->tlv_len_in_words = vec_len (tlvs);
7548     mp->vni = ntohl(vni);
7549     mp->is_add = is_add;
7550     mp->ver_o_c = ver_o_c;
7551     mp->length = 6 + vec_len(tlvs);
7552     mp->md_type = md_type;
7553     mp->next_protocol = next_protocol;
7554     mp->spi_si = ntohl(spi_si);
7555     mp->c1 = ntohl(c1);
7556     mp->c2 = ntohl(c2);
7557     mp->c3 = ntohl(c3);
7558     mp->c4 = ntohl(c4);
7559     
7560     for (i = 0; i < vec_len(tlvs); i++)
7561         mp->tlvs[i] = ntohl(tlvs[i]);
7562
7563     vec_free (tlvs);
7564
7565     S; W;
7566     /* NOTREACHED */
7567     return 0;
7568 }
7569
7570 static uword unformat_lisp_gpe_decap_next (unformat_input_t * input, 
7571                                                va_list * args)
7572 {
7573     u32 * result = va_arg (*args, u32 *);
7574     u32 tmp;
7575   
7576     if (unformat (input, "drop"))
7577         *result = LISP_GPE_INPUT_NEXT_DROP;
7578     else if (unformat (input, "ip4"))
7579         *result = LISP_GPE_INPUT_NEXT_IP4_INPUT;
7580     else if (unformat (input, "ip6"))
7581         *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
7582     else if (unformat (input, "ethernet"))
7583         *result = LISP_GPE_INPUT_NEXT_IP6_INPUT;
7584     else if (unformat (input, "lisp-gpe"))
7585         *result = LISP_GPE_INPUT_NEXT_LISP_GPE_ENCAP;
7586     else if (unformat (input, "%d", &tmp))
7587         *result = tmp;
7588     else
7589         return 0;
7590     return 1;
7591 }
7592
7593 static int
7594 api_lisp_gpe_add_del_tunnel (vat_main_t * vam)
7595 {
7596     unformat_input_t * line_input = vam->input;
7597     vl_api_lisp_gpe_add_del_tunnel_t *mp;
7598     f64 timeout;
7599     ip4_address_t src, dst;
7600     u8 is_add = 1;
7601     u8 src_set = 0;
7602     u8 dst_set = 0;
7603     u32 encap_vrf_id = 0;
7604     u32 decap_vrf_id = 0;
7605     u8 next_protocol = LISP_GPE_NEXT_PROTOCOL_IP4;
7606     u32 decap_next_index = LISP_GPE_INPUT_NEXT_IP4_INPUT;
7607     u8 flags = LISP_GPE_FLAGS_P;
7608     u8 ver_res = 0;
7609     u8 res = 0;
7610     u32 iid = 0;
7611     u8 iid_set = 0;
7612     u32 tmp;
7613   
7614     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7615         if (unformat (line_input, "del"))
7616             is_add = 0;
7617         else if (unformat (line_input, "src %U", 
7618                            unformat_ip4_address, &src))
7619             src_set = 1;
7620         else if (unformat (line_input, "dst %U",
7621                            unformat_ip4_address, &dst))
7622             dst_set = 1;
7623         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7624             ;
7625         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
7626             ;
7627         else if (unformat (line_input, "decap-next %U", 
7628                            unformat_lisp_gpe_decap_next, 
7629                            &decap_next_index))
7630             ;
7631         else if (unformat(line_input, "next-ip4"))
7632             next_protocol = 1;
7633         else if (unformat(line_input, "next-ip6"))
7634             next_protocol = 2;
7635         else if (unformat(line_input, "next-ethernet"))
7636             next_protocol = 3;
7637         else if (unformat(line_input, "next-nsh"))
7638             next_protocol = 4;
7639         /* Allow the user to specify anything they want in the LISP hdr */
7640         else if (unformat (line_input, "ver_res %x", &tmp))
7641             ver_res = tmp;
7642         else if (unformat (line_input, "res %x", &tmp))
7643             res = tmp;
7644         else if (unformat (line_input, "flags %x", &tmp))
7645             flags = tmp;
7646         else if (unformat (line_input, "n-bit"))
7647             flags |= LISP_GPE_FLAGS_N;
7648         else if (unformat (line_input, "l-bit"))
7649             flags |= LISP_GPE_FLAGS_L;
7650         else if (unformat (line_input, "e-bit"))
7651             flags |= LISP_GPE_FLAGS_E;
7652         else if (unformat (line_input, "v-bit"))
7653             flags |= LISP_GPE_FLAGS_V;
7654         else if (unformat (line_input, "i-bit"))
7655             flags |= LISP_GPE_FLAGS_V;
7656         else if (unformat (line_input, "not-p-bit"))
7657             flags &= !LISP_GPE_FLAGS_P;
7658         else if (unformat (line_input, "p-bit"))
7659             flags |= LISP_GPE_FLAGS_P;
7660         else if (unformat (line_input, "o-bit"))
7661             flags |= LISP_GPE_FLAGS_O;
7662         else if (unformat (line_input, "iidx %x", &iid))
7663             iid_set = 1;
7664         else if (unformat (line_input, "iid %d", &iid))
7665             iid_set = 1;
7666         else {
7667             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7668             return -99;
7669         }
7670     }
7671
7672     if (src_set == 0) {
7673         errmsg ("tunnel src address not specified\n");
7674         return -99;
7675     }
7676     if (dst_set == 0) {
7677         errmsg ("tunnel dst address not specified\n");
7678         return -99;
7679     }
7680     if (iid_set == 0) {
7681         errmsg ("iid not specified\n");
7682         return -99;
7683     }
7684
7685     M(LISP_GPE_ADD_DEL_TUNNEL, lisp_gpe_add_del_tunnel);
7686
7687     mp->src = src.as_u32;
7688     mp->dst = dst.as_u32;
7689     mp->encap_vrf_id = ntohl(encap_vrf_id);
7690     mp->decap_vrf_id = ntohl(decap_vrf_id);
7691     mp->decap_next_index = ntohl(decap_next_index);
7692     mp->is_add = is_add;
7693     mp->flags = flags;
7694     mp->ver_res = ver_res;
7695     mp->res = res;
7696     mp->next_protocol = next_protocol;
7697     mp->iid = ntohl(iid);
7698
7699     S; W; 
7700
7701     /* NOTREACHED */
7702     return 0;
7703 }
7704
7705
7706 u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
7707 {
7708   u8 * a = va_arg (*args, u8 *);
7709
7710   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
7711                  a[2], a[3], a[4], a[5], a[6], a[7]);
7712 }
7713
7714 static void vl_api_l2_fib_table_entry_t_handler
7715 (vl_api_l2_fib_table_entry_t * mp)
7716 {
7717     vat_main_t * vam = &vat_main;
7718
7719     fformat(vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
7720             "       %d       %d     %d\n",
7721             ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
7722             ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
7723             mp->bvi_mac);
7724 }
7725
7726 static void vl_api_l2_fib_table_entry_t_handler_json
7727 (vl_api_l2_fib_table_entry_t * mp)
7728 {
7729     vat_main_t * vam = &vat_main;
7730     vat_json_node_t *node = NULL;
7731
7732     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7733         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7734         vat_json_init_array(&vam->json_tree);
7735     }
7736     node = vat_json_array_add(&vam->json_tree);
7737
7738     vat_json_init_object(node);
7739     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
7740     vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
7741     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7742     vat_json_object_add_uint(node, "static_mac", mp->static_mac);
7743     vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
7744     vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
7745 }
7746
7747 static int api_l2_fib_table_dump (vat_main_t * vam)
7748 {
7749     unformat_input_t * i = vam->input;
7750     vl_api_l2_fib_table_dump_t *mp;
7751     f64 timeout;
7752     u32 bd_id;
7753     u8 bd_id_set = 0;
7754
7755     /* Parse args required to build the message */
7756     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7757         if (unformat (i, "bd_id %d", &bd_id))
7758             bd_id_set = 1;
7759         else
7760             break;
7761     }
7762
7763     if (bd_id_set == 0) {
7764         errmsg ("missing bridge domain\n");
7765         return -99;
7766     }
7767
7768     fformat(vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
7769
7770     /* Get list of l2 fib entries */
7771     M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
7772
7773     mp->bd_id = ntohl(bd_id);
7774     S;
7775
7776     /* Use a control ping for synchronization */
7777     {
7778         vl_api_control_ping_t * mp;
7779         M(CONTROL_PING, control_ping);
7780         S;
7781     }
7782     W;
7783 }
7784
7785
7786 static int
7787 api_interface_name_renumber (vat_main_t * vam)
7788 {
7789     unformat_input_t * line_input = vam->input;
7790     vl_api_interface_name_renumber_t *mp;
7791     u32 sw_if_index = ~0;
7792     f64 timeout;
7793     u32 new_show_dev_instance = ~0;
7794
7795     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7796         if (unformat (line_input, "%U", unformat_sw_if_index, vam, 
7797                       &sw_if_index))
7798             ;
7799         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
7800             ;
7801         else if (unformat (line_input, "new_show_dev_instance %d", 
7802                            &new_show_dev_instance))
7803             ;
7804         else
7805             break;
7806     }
7807
7808     if (sw_if_index == ~0) {
7809         errmsg ("missing interface name or sw_if_index\n");
7810         return -99;
7811     }
7812
7813     if (new_show_dev_instance == ~0) {
7814         errmsg ("missing new_show_dev_instance\n");
7815         return -99;
7816     }
7817
7818     M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
7819
7820     mp->sw_if_index = ntohl (sw_if_index);
7821     mp->new_show_dev_instance = ntohl (new_show_dev_instance);
7822
7823     S; W;
7824 }
7825
7826 static int
7827 api_want_ip4_arp_events (vat_main_t * vam)
7828 {
7829     unformat_input_t * line_input = vam->input;
7830     vl_api_want_ip4_arp_events_t * mp;
7831     f64 timeout;
7832     ip4_address_t address;
7833     int address_set = 0;
7834     u32 enable_disable = 1;
7835
7836     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7837         if (unformat (line_input, "address %U", 
7838                       unformat_ip4_address, &address))
7839             address_set = 1;
7840         else if (unformat (line_input, "del"))
7841             enable_disable = 0;
7842         else
7843             break;
7844     }
7845     
7846     if (address_set == 0) {
7847         errmsg ("missing addresses\n");
7848         return -99;
7849     }
7850         
7851     M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
7852     mp->enable_disable = enable_disable;
7853     mp->pid = getpid();
7854     mp->address = address.as_u32;
7855
7856     S; W; 
7857 }
7858
7859 static int api_input_acl_set_interface (vat_main_t * vam)
7860 {
7861     unformat_input_t * i = vam->input;
7862     vl_api_input_acl_set_interface_t *mp;
7863     f64 timeout;
7864     u32 sw_if_index;
7865     int sw_if_index_set;
7866     u32 ip4_table_index = ~0;
7867     u32 ip6_table_index = ~0;
7868     u32 l2_table_index = ~0;
7869     u8 is_add = 1;
7870
7871     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7872         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7873             sw_if_index_set = 1;
7874         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7875             sw_if_index_set = 1;
7876         else if (unformat (i, "del"))
7877             is_add = 0;
7878         else if (unformat (i, "ip4-table %d", &ip4_table_index))
7879             ;
7880         else if (unformat (i, "ip6-table %d", &ip6_table_index))
7881             ;
7882         else if (unformat (i, "l2-table %d", &l2_table_index))
7883             ;
7884         else {
7885             clib_warning ("parse error '%U'", format_unformat_error, i);
7886             return -99;
7887         }
7888     }
7889
7890     if (sw_if_index_set == 0) {
7891         errmsg ("missing interface name or sw_if_index\n");
7892         return -99;
7893     }
7894
7895     M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
7896
7897     mp->sw_if_index = ntohl(sw_if_index);
7898     mp->ip4_table_index = ntohl(ip4_table_index);
7899     mp->ip6_table_index = ntohl(ip6_table_index);
7900     mp->l2_table_index = ntohl(l2_table_index);
7901     mp->is_add = is_add;
7902
7903     S; W;
7904     /* NOTREACHED */
7905     return 0;
7906 }
7907
7908 static int
7909 api_ip_address_dump (vat_main_t * vam)
7910 {
7911     unformat_input_t * i = vam->input;
7912     vl_api_ip_address_dump_t * mp;
7913     u32 sw_if_index = ~0;
7914     u8 sw_if_index_set = 0;
7915     u8 ipv4_set = 0;
7916     u8 ipv6_set = 0;
7917     f64 timeout;
7918
7919     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7920         if (unformat (i, "sw_if_index %d", &sw_if_index))
7921             sw_if_index_set = 1;
7922         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7923             sw_if_index_set = 1;
7924         else if (unformat (i, "ipv4"))
7925             ipv4_set = 1;
7926         else if (unformat (i, "ipv6"))
7927             ipv6_set = 1;
7928         else
7929             break;
7930     }
7931
7932     if (ipv4_set && ipv6_set) {
7933         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
7934         return -99;
7935     }
7936
7937     if ((!ipv4_set) && (!ipv6_set)) {
7938         errmsg ("no ipv4 nor ipv6 flag set\n");
7939         return -99;
7940     }
7941
7942     if (sw_if_index_set == 0) {
7943         errmsg ("missing interface name or sw_if_index\n");
7944         return -99;
7945     }
7946
7947     vam->current_sw_if_index = sw_if_index;
7948     vam->is_ipv6 = ipv6_set;
7949
7950     M(IP_ADDRESS_DUMP, ip_address_dump);
7951     mp->sw_if_index = ntohl(sw_if_index);
7952     mp->is_ipv6 = ipv6_set;
7953     S;
7954
7955     /* Use a control ping for synchronization */
7956     {
7957         vl_api_control_ping_t * mp;
7958         M(CONTROL_PING, control_ping);
7959         S;
7960     }
7961     W;
7962 }
7963
7964 static int
7965 api_ip_dump (vat_main_t * vam)
7966 {
7967     vl_api_ip_dump_t * mp;
7968     unformat_input_t * in = vam->input;
7969     int ipv4_set = 0;
7970     int ipv6_set = 0;
7971     int is_ipv6;
7972     f64 timeout;
7973     int i;
7974
7975     while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
7976         if (unformat (in, "ipv4"))
7977             ipv4_set = 1;
7978         else if (unformat (in, "ipv6"))
7979             ipv6_set = 1;
7980         else
7981             break;
7982     }
7983
7984     if (ipv4_set && ipv6_set) {
7985         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
7986         return -99;
7987     }
7988
7989     if ((!ipv4_set) && (!ipv6_set)) {
7990         errmsg ("no ipv4 nor ipv6 flag set\n");
7991         return -99;
7992     }
7993
7994     is_ipv6 = ipv6_set;
7995     vam->is_ipv6 = is_ipv6;
7996
7997     /* free old data */
7998     for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
7999         vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8000     }
8001     vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8002
8003     M(IP_DUMP, ip_dump);
8004     mp->is_ipv6 = ipv6_set;
8005     S;
8006
8007     /* Use a control ping for synchronization */
8008     {
8009         vl_api_control_ping_t * mp;
8010         M(CONTROL_PING, control_ping);
8011         S;
8012     }
8013     W;
8014 }
8015
8016 static int
8017 api_ipsec_spd_add_del (vat_main_t * vam)
8018 {
8019 #if DPDK > 0
8020     unformat_input_t * i = vam->input;
8021     vl_api_ipsec_spd_add_del_t *mp;
8022     f64 timeout;
8023     u32 spd_id = ~0;
8024     u8 is_add = 1;
8025
8026     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8027         if (unformat (i, "spd_id %d", &spd_id))
8028             ;
8029         else if (unformat (i, "del"))
8030             is_add = 0;
8031         else {
8032             clib_warning ("parse error '%U'", format_unformat_error, i);
8033             return -99;
8034         }
8035     }
8036     if (spd_id == ~0) {
8037         errmsg ("spd_id must be set\n");
8038         return -99;
8039     }
8040
8041     M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8042
8043     mp->spd_id = ntohl(spd_id);
8044     mp->is_add = is_add;
8045
8046     S; W;
8047     /* NOTREACHED */
8048     return 0;
8049 #else
8050     clib_warning ("unsupported (no dpdk)");
8051     return -99;
8052 #endif
8053 }
8054
8055 static int
8056 api_ipsec_interface_add_del_spd (vat_main_t * vam)
8057 {
8058 #if DPDK > 0
8059     unformat_input_t * i = vam->input;
8060     vl_api_ipsec_interface_add_del_spd_t *mp;
8061     f64 timeout;
8062     u32 sw_if_index;
8063     u8 sw_if_index_set = 0;
8064     u32 spd_id = (u32) ~0;
8065     u8 is_add = 1;
8066
8067     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8068         if (unformat (i, "del"))
8069             is_add = 0;
8070         else if (unformat (i, "spd_id %d", &spd_id))
8071             ;
8072         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8073             sw_if_index_set = 1;
8074         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8075             sw_if_index_set = 1;
8076         else {
8077             clib_warning ("parse error '%U'", format_unformat_error, i);
8078             return -99;
8079         }
8080
8081     }
8082
8083     if (spd_id == (u32) ~0) {
8084         errmsg ("spd_id must be set\n");
8085         return -99;
8086     }
8087
8088     if (sw_if_index_set == 0) {
8089         errmsg ("missing interface name or sw_if_index\n");
8090         return -99;
8091     }
8092
8093     M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8094
8095     mp->spd_id = ntohl(spd_id);
8096     mp->sw_if_index = ntohl (sw_if_index);
8097     mp->is_add = is_add;
8098
8099     S; W;
8100     /* NOTREACHED */
8101     return 0;
8102 #else
8103     clib_warning ("unsupported (no dpdk)");
8104     return -99;
8105 #endif
8106 }
8107
8108 static int
8109 api_ipsec_spd_add_del_entry (vat_main_t * vam)
8110 {
8111 #if DPDK > 0
8112     unformat_input_t * i = vam->input;
8113     vl_api_ipsec_spd_add_del_entry_t *mp;
8114     f64 timeout;
8115     u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8116     u32 spd_id, sa_id, protocol = 0, policy = 0;
8117     i32 priority;
8118     u32 rport_start = 0, rport_stop = (u32) ~0;
8119     u32 lport_start = 0, lport_stop = (u32) ~0;
8120     ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8121     ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8122
8123     laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8124     laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8125     laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8126     laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8127     laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8128     laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8129
8130     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8131         if (unformat (i, "del"))
8132             is_add = 0;
8133         if (unformat (i, "outbound"))
8134             is_outbound = 1;
8135         if (unformat (i, "inbound"))
8136             is_outbound = 0;
8137         else if (unformat (i, "spd_id %d", &spd_id))
8138             ;
8139         else if (unformat (i, "sa_id %d", &sa_id))
8140             ;
8141         else if (unformat (i, "priority %d", &priority))
8142             ;
8143         else if (unformat (i, "protocol %d", &protocol))
8144             ;
8145         else if (unformat (i, "lport_start %d", &lport_start))
8146             ;
8147         else if (unformat (i, "lport_stop %d", &lport_stop))
8148             ;
8149         else if (unformat (i, "rport_start %d", &rport_start))
8150             ;
8151         else if (unformat (i, "rport_stop %d", &rport_stop))
8152             ;
8153         else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8154           {
8155             is_ipv6 = 0;
8156             is_ip_any =0;
8157           }
8158         else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8159           {
8160             is_ipv6 = 0;
8161             is_ip_any = 0;
8162           }
8163         else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8164           {
8165             is_ipv6 = 0;
8166             is_ip_any = 0;
8167           }
8168         else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8169           {
8170             is_ipv6 = 0;
8171             is_ip_any = 0;
8172           }
8173         else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8174           {
8175             is_ipv6 = 1;
8176             is_ip_any = 0;
8177           }
8178         else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8179           {
8180             is_ipv6 = 1;
8181             is_ip_any = 0;
8182           }
8183         else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8184           {
8185             is_ipv6 = 1;
8186             is_ip_any = 0;
8187           }
8188         else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8189           {
8190             is_ipv6 = 1;
8191             is_ip_any = 0;
8192           }
8193         else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8194           {
8195             if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8196                 clib_warning ("unsupported action: 'resolve'");
8197                 return -99;
8198             }
8199           }
8200         else {
8201             clib_warning ("parse error '%U'", format_unformat_error, i);
8202             return -99;
8203         }
8204
8205     }
8206
8207     M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8208
8209     mp->spd_id = ntohl(spd_id);
8210     mp->priority = ntohl(priority);
8211     mp->is_outbound = is_outbound;
8212
8213     mp->is_ipv6 = is_ipv6;
8214     if (is_ipv6 || is_ip_any) {
8215         memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8216         memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8217         memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8218         memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
8219     } else {
8220         memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8221         memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8222         memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8223         memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
8224     }
8225     mp->protocol = (u8) protocol;
8226     mp->local_port_start = ntohs((u16) lport_start);
8227     mp->local_port_stop = ntohs((u16) lport_stop);
8228     mp->remote_port_start = ntohs((u16) rport_start);
8229     mp->remote_port_stop = ntohs((u16) rport_stop);
8230     mp->policy = (u8) policy;
8231     mp->sa_id = ntohl(sa_id);
8232     mp->is_add = is_add;
8233     mp->is_ip_any = is_ip_any;
8234     S; W;
8235     /* NOTREACHED */
8236     return 0;
8237 #else
8238     clib_warning ("unsupported (no dpdk)");
8239     return -99;
8240 #endif
8241 }
8242
8243 static int
8244 api_ipsec_sad_add_del_entry (vat_main_t * vam)
8245 {
8246 #if DPDK > 0
8247     unformat_input_t * i = vam->input;
8248     vl_api_ipsec_sad_add_del_entry_t *mp;
8249     f64 timeout;
8250     u32 sad_id, spi;
8251     u8 * ck, * ik;
8252     u8 is_add = 1;
8253
8254     u8 protocol = IPSEC_PROTOCOL_AH;
8255     u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8256     u32 crypto_alg = 0, integ_alg = 0;
8257     ip4_address_t tun_src4;
8258     ip4_address_t tun_dst4;
8259     ip6_address_t tun_src6;
8260     ip6_address_t tun_dst6;
8261
8262     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8263         if (unformat (i, "del"))
8264             is_add = 0;
8265         else if (unformat (i, "sad_id %d", &sad_id))
8266             ;
8267         else if (unformat (i, "spi %d", &spi))
8268             ;
8269         else if (unformat (i, "esp"))
8270             protocol = IPSEC_PROTOCOL_ESP;
8271         else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8272             is_tunnel = 1;
8273             is_tunnel_ipv6 = 0;
8274         }
8275         else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8276             is_tunnel = 1;
8277             is_tunnel_ipv6 = 0;
8278         }
8279         else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8280             is_tunnel = 1;
8281             is_tunnel_ipv6 = 1;
8282         }
8283         else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8284             is_tunnel = 1;
8285             is_tunnel_ipv6 = 1;
8286         }
8287         else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8288             if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8289                 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8290                 clib_warning ("unsupported crypto-alg: '%U'",
8291                               format_ipsec_crypto_alg, crypto_alg);
8292                 return -99;
8293             }
8294         }
8295         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8296             ;
8297         else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8298             if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8299                 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8300                 clib_warning ("unsupported integ-alg: '%U'",
8301                               format_ipsec_integ_alg, integ_alg);
8302                 return -99;
8303             }
8304         }
8305         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8306             ;
8307         else {
8308             clib_warning ("parse error '%U'", format_unformat_error, i);
8309             return -99;
8310         }
8311
8312     }
8313
8314     M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8315
8316     mp->sad_id = ntohl(sad_id);
8317     mp->is_add = is_add;
8318     mp->protocol = protocol;
8319     mp->spi = ntohl(spi);
8320     mp->is_tunnel = is_tunnel;
8321     mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8322     mp->crypto_algorithm = crypto_alg;
8323     mp->integrity_algorithm = integ_alg;
8324     mp->crypto_key_length = vec_len(ck);
8325     mp->integrity_key_length = vec_len(ik);
8326
8327     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8328       mp->crypto_key_length = sizeof(mp->crypto_key);
8329
8330     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8331       mp->integrity_key_length = sizeof(mp->integrity_key);
8332
8333     memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8334     memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8335
8336     if (is_tunnel) {
8337       if (is_tunnel_ipv6) {
8338         memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8339         memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
8340       } else {
8341         memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8342         memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
8343       }
8344     }
8345
8346     S; W;
8347     /* NOTREACHED */
8348     return 0;
8349 #else
8350     clib_warning ("unsupported (no dpdk)");
8351     return -99;
8352 #endif
8353 }
8354
8355 static int
8356 api_ipsec_sa_set_key (vat_main_t * vam)
8357 {
8358 #if DPDK > 0
8359     unformat_input_t * i = vam->input;
8360     vl_api_ipsec_sa_set_key_t *mp;
8361     f64 timeout;
8362     u32 sa_id;
8363     u8 * ck, * ik;
8364
8365     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8366         if (unformat (i, "sa_id %d", &sa_id))
8367             ;
8368         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8369             ;
8370         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8371             ;
8372         else {
8373             clib_warning ("parse error '%U'", format_unformat_error, i);
8374             return -99;
8375         }
8376     }
8377
8378     M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
8379
8380     mp->sa_id = ntohl(sa_id);
8381     mp->crypto_key_length = vec_len(ck);
8382     mp->integrity_key_length = vec_len(ik);
8383
8384     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8385       mp->crypto_key_length = sizeof(mp->crypto_key);
8386
8387     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8388       mp->integrity_key_length = sizeof(mp->integrity_key);
8389
8390     memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8391     memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8392
8393     S; W;
8394     /* NOTREACHED */
8395     return 0;
8396 #else
8397     clib_warning ("unsupported (no dpdk)");
8398     return -99;
8399 #endif
8400 }
8401
8402 /*
8403  * MAP
8404  */
8405 static int api_map_add_domain (vat_main_t * vam)
8406 {
8407   unformat_input_t *i = vam->input;
8408   vl_api_map_add_domain_t *mp;
8409   f64 timeout;
8410
8411   ip4_address_t ip4_prefix;
8412   ip6_address_t ip6_prefix;
8413   ip6_address_t ip6_src;
8414   u32 num_m_args = 0;
8415   u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
8416     psid_length;
8417   u8 is_translation = 0;
8418   u32 mtu = 0;
8419   u8 ip6_src_len = 128;
8420
8421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8422     if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
8423                   &ip4_prefix, &ip4_prefix_len))
8424       num_m_args++;
8425     else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
8426                        &ip6_prefix, &ip6_prefix_len))
8427       num_m_args++;
8428     else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
8429       num_m_args++;
8430     else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
8431       num_m_args++;
8432     else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
8433       num_m_args++;
8434     else if (unformat (i, "psid-offset %d", &psid_offset))
8435       num_m_args++;
8436     else if (unformat (i, "psid-len %d", &psid_length))
8437       num_m_args++;
8438     else if (unformat (i, "mtu %d", &mtu))
8439       num_m_args++;
8440     else if (unformat (i, "map-t"))
8441       is_translation = 1;
8442     else {
8443       clib_warning ("parse error '%U'", format_unformat_error, i);
8444       return -99;
8445     }
8446   }
8447
8448   if (num_m_args != 6) {
8449     errmsg("mandatory argument(s) missing\n");
8450     return -99;
8451   }
8452
8453   /* Construct the API message */
8454   M(MAP_ADD_DOMAIN, map_add_domain);
8455
8456   memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
8457   mp->ip4_prefix_len = ip4_prefix_len;
8458
8459   memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
8460   mp->ip6_prefix_len = ip6_prefix_len;
8461
8462   memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
8463   mp->ip6_src_prefix_len = ip6_src_len;
8464
8465   mp->ea_bits_len = ea_bits_len;
8466   mp->psid_offset = psid_offset;
8467   mp->psid_length = psid_length;
8468   mp->is_translation = is_translation;
8469   mp->mtu = htons(mtu);
8470
8471   /* send it... */
8472   S;
8473
8474   /* Wait for a reply, return good/bad news  */
8475   W;
8476 }
8477
8478 static int api_map_del_domain (vat_main_t * vam)
8479 {
8480   unformat_input_t *i = vam->input;
8481   vl_api_map_del_domain_t *mp;
8482   f64 timeout;
8483
8484   u32 num_m_args = 0;
8485   u32 index;
8486
8487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8488     if (unformat (i, "index %d", &index))
8489       num_m_args++;
8490     else {
8491       clib_warning ("parse error '%U'", format_unformat_error, i);
8492       return -99;
8493     }
8494   }
8495
8496   if (num_m_args != 1) {
8497     errmsg("mandatory argument(s) missing\n");
8498     return -99;
8499   }
8500
8501   /* Construct the API message */
8502   M(MAP_DEL_DOMAIN, map_del_domain);
8503
8504   mp->index = ntohl(index);
8505
8506   /* send it... */
8507   S;
8508
8509   /* Wait for a reply, return good/bad news  */
8510   W;
8511 }
8512
8513 static int api_map_add_del_rule (vat_main_t * vam)
8514 {
8515   unformat_input_t *i = vam->input;
8516   vl_api_map_add_del_rule_t *mp;
8517   f64 timeout;
8518   u8 is_add = 1;
8519   ip6_address_t ip6_dst;
8520   u32 num_m_args = 0, index, psid;
8521
8522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8523     if (unformat (i, "index %d", &index))
8524       num_m_args++;
8525     else if (unformat (i, "psid %d", &psid))
8526       num_m_args++;
8527     else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
8528       num_m_args++;
8529     else if (unformat (i, "del")) {
8530       is_add = 0;
8531     } else {
8532       clib_warning ("parse error '%U'", format_unformat_error, i);
8533       return -99;
8534     }
8535   }
8536
8537   /* Construct the API message */
8538   M(MAP_ADD_DEL_RULE, map_add_del_rule);
8539
8540   mp->index = ntohl(index);
8541   mp->is_add = is_add;
8542   memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
8543   mp->psid = ntohs(psid);
8544
8545   /* send it... */
8546   S;
8547
8548   /* Wait for a reply, return good/bad news  */
8549   W;
8550 }
8551
8552 static int api_map_domain_dump (vat_main_t * vam)
8553 {
8554     vl_api_map_domain_dump_t *mp;
8555     f64 timeout;
8556
8557     /* Construct the API message */
8558     M(MAP_DOMAIN_DUMP, map_domain_dump);
8559
8560     /* send it... */
8561     S;
8562
8563     /* Use a control ping for synchronization */
8564     {
8565         vl_api_control_ping_t * mp;
8566         M(CONTROL_PING, control_ping);
8567         S;
8568     }
8569     W;
8570 }
8571
8572 static int api_map_rule_dump (vat_main_t * vam)
8573 {
8574     unformat_input_t *i = vam->input;
8575     vl_api_map_rule_dump_t *mp;
8576     f64 timeout;
8577     u32 domain_index = ~0;
8578
8579     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8580         if (unformat (i, "index %u", &domain_index))
8581             ;
8582         else
8583             break;
8584     }
8585
8586     if (domain_index == ~0) {
8587         clib_warning("parse error: domain index expected");
8588         return -99;
8589     }
8590
8591     /* Construct the API message */
8592     M(MAP_RULE_DUMP, map_rule_dump);
8593
8594     mp->domain_index = htonl(domain_index);
8595
8596     /* send it... */
8597     S;
8598
8599     /* Use a control ping for synchronization */
8600     {
8601         vl_api_control_ping_t * mp;
8602         M(CONTROL_PING, control_ping);
8603         S;
8604     }
8605     W;
8606 }
8607
8608 static void vl_api_map_add_domain_reply_t_handler
8609 (vl_api_map_add_domain_reply_t * mp)
8610 {
8611   vat_main_t * vam = &vat_main;
8612   i32 retval = ntohl(mp->retval);
8613
8614   if (vam->async_mode) {
8615       vam->async_errors += (retval < 0);
8616   } else {
8617       vam->retval = retval;
8618       vam->result_ready = 1;
8619   }
8620 }
8621
8622 static void vl_api_map_add_domain_reply_t_handler_json
8623 (vl_api_map_add_domain_reply_t * mp)
8624 {
8625   vat_main_t * vam = &vat_main;
8626   vat_json_node_t node;
8627
8628   vat_json_init_object(&node);
8629   vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
8630   vat_json_object_add_uint(&node, "index", ntohl(mp->index));
8631
8632   vat_json_print(vam->ofp, &node);
8633   vat_json_free(&node);
8634
8635   vam->retval = ntohl(mp->retval);
8636   vam->result_ready = 1;
8637 }
8638
8639 static int
8640 api_get_first_msg_id (vat_main_t * vam)
8641 {
8642     vl_api_get_first_msg_id_t * mp;
8643     f64 timeout;
8644     unformat_input_t * i = vam->input;
8645     u8 * name;
8646     u8 name_set = 0;
8647     
8648     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8649         if (unformat (i, "client %s", &name))
8650             name_set = 1;
8651         else 
8652             break;
8653     }
8654
8655     if (name_set == 0) {
8656         errmsg ("missing client name\n");
8657         return -99;
8658     }
8659     vec_add1 (name, 0);
8660
8661     if (vec_len (name) > 63) {
8662         errmsg ("client name too long\n");
8663         return -99;
8664     }
8665
8666     M(GET_FIRST_MSG_ID, get_first_msg_id);
8667     memcpy (mp->name, name, vec_len(name));
8668     S; W;
8669     /* NOTREACHED */
8670     return 0;
8671 }
8672
8673 static int api_cop_interface_enable_disable (vat_main_t * vam)
8674 {
8675     unformat_input_t * line_input = vam->input;
8676     vl_api_cop_interface_enable_disable_t * mp;
8677     f64 timeout;
8678     u32 sw_if_index = ~0;
8679     u8 enable_disable = 1;
8680
8681     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8682         if (unformat (line_input, "disable"))
8683             enable_disable = 0;
8684         if (unformat (line_input, "enable"))
8685             enable_disable = 1;
8686         else if (unformat (line_input, "%U", unformat_sw_if_index,
8687                            vam, &sw_if_index))
8688             ;
8689         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8690             ;
8691         else
8692             break;
8693     }
8694         
8695     if (sw_if_index == ~0) {
8696         errmsg ("missing interface name or sw_if_index\n");
8697         return -99;
8698     }
8699
8700     /* Construct the API message */
8701     M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
8702     mp->sw_if_index = ntohl(sw_if_index);
8703     mp->enable_disable = enable_disable;
8704
8705     /* send it... */
8706     S;
8707     /* Wait for the reply */
8708     W;
8709 }
8710
8711 static int api_cop_whitelist_enable_disable (vat_main_t * vam)
8712 {
8713     unformat_input_t * line_input = vam->input;
8714     vl_api_cop_whitelist_enable_disable_t * mp;
8715     f64 timeout;
8716     u32 sw_if_index = ~0;
8717     u8 ip4=0, ip6=0, default_cop=0;
8718     u32 fib_id;
8719
8720     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8721         if (unformat (line_input, "ip4"))
8722             ip4 = 1;
8723         else if (unformat (line_input, "ip6"))
8724             ip6 = 1;
8725         else if (unformat (line_input, "default"))
8726             default_cop = 1;
8727         else if (unformat (line_input, "%U", unformat_sw_if_index,
8728                            vam, &sw_if_index))
8729             ;
8730         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8731             ;
8732         else if (unformat (line_input, "fib-id %d", &fib_id))
8733             ;
8734         else
8735             break;
8736     }
8737         
8738     if (sw_if_index == ~0) {
8739         errmsg ("missing interface name or sw_if_index\n");
8740         return -99;
8741     }
8742
8743     /* Construct the API message */
8744     M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
8745     mp->sw_if_index = ntohl(sw_if_index);
8746     mp->fib_id = ntohl(fib_id);
8747     mp->ip4 = ip4;
8748     mp->ip6 = ip6;
8749     mp->default_cop = default_cop;
8750
8751     /* send it... */
8752     S;
8753     /* Wait for the reply */
8754     W;
8755 }
8756
8757 static int api_get_node_graph (vat_main_t * vam)
8758 {
8759     vl_api_get_node_graph_t * mp;
8760     f64 timeout;
8761
8762     M(GET_NODE_GRAPH, get_node_graph);
8763
8764     /* send it... */
8765     S;
8766     /* Wait for the reply */
8767     W;
8768 }
8769
8770 static int q_or_quit (vat_main_t * vam)
8771 {
8772     longjmp (vam->jump_buf, 1);
8773     return 0; /* not so much */
8774 }
8775 static int q (vat_main_t * vam) {return q_or_quit (vam);}
8776 static int quit (vat_main_t * vam) {return q_or_quit (vam);}
8777
8778 static int comment (vat_main_t * vam)
8779 {
8780     return 0;
8781 }
8782
8783 static int cmd_cmp (void * a1, void * a2)
8784 {
8785   u8 ** c1 = a1;
8786   u8 ** c2 = a2;
8787
8788   return strcmp ((char *)(c1[0]), (char *)(c2[0]));
8789 }
8790
8791 static int help (vat_main_t * vam)
8792 {
8793     u8 ** cmds = 0;
8794     u8 * name = 0;
8795     hash_pair_t * p;
8796     unformat_input_t * i = vam->input;
8797     int j;
8798
8799     if (unformat (i, "%s", &name)) {
8800         uword *hs;
8801
8802         vec_add1(name, 0);
8803
8804         hs = hash_get_mem (vam->help_by_name, name);
8805         if (hs)
8806             fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
8807         else
8808             fformat (vam->ofp, "No such msg / command '%s'\n", name);
8809         vec_free(name);
8810         return 0;
8811     }
8812
8813     fformat(vam->ofp, "Help is available for the following:\n");
8814
8815     hash_foreach_pair (p, vam->function_by_name, 
8816     ({
8817         vec_add1 (cmds, (u8 *)(p->key));
8818     }));
8819
8820     vec_sort_with_function (cmds, cmd_cmp);
8821
8822     for (j = 0; j < vec_len(cmds); j++)
8823         fformat (vam->ofp, "%s\n", cmds[j]);
8824
8825     vec_free (cmds);
8826     return 0;
8827 }
8828
8829 static int set (vat_main_t * vam)
8830 {
8831     u8 * name = 0, * value = 0;
8832     unformat_input_t * i = vam->input;
8833
8834     if (unformat (i, "%s", &name)) {
8835         /* The input buffer is a vector, not a string. */
8836         value = vec_dup (i->buffer);
8837         vec_delete (value, i->index, 0);
8838         /* Almost certainly has a trailing newline */
8839         if (value[vec_len(value)-1] == '\n')
8840             value[vec_len(value)-1] = 0;
8841         /* Make sure it's a proper string, one way or the other */
8842         vec_add1 (value, 0);
8843         (void) clib_macro_set_value (&vam->macro_main, 
8844                                      (char *)name, (char *)value);
8845     }
8846     else
8847         errmsg ("usage: set <name> <value>\n");
8848
8849     vec_free (name);
8850     vec_free (value);
8851     return 0;
8852 }
8853
8854 static int unset (vat_main_t * vam)
8855 {
8856     u8 * name = 0;
8857
8858     if (unformat (vam->input, "%s", &name))
8859         if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
8860             errmsg ("unset: %s wasn't set\n", name);
8861     vec_free (name);
8862     return 0;
8863 }
8864
8865 typedef struct {
8866     u8 * name;
8867     u8 * value;
8868 } macro_sort_t;
8869
8870
8871 static int macro_sort_cmp (void * a1, void * a2)
8872 {
8873   macro_sort_t * s1 = a1;
8874   macro_sort_t * s2 = a2;
8875
8876   return strcmp ((char *)(s1->name), (char *)(s2->name));
8877 }
8878
8879 static int dump_macro_table (vat_main_t * vam)
8880 {
8881     macro_sort_t * sort_me = 0, * sm;    
8882     int i;
8883     hash_pair_t * p;
8884
8885     hash_foreach_pair (p, vam->macro_main.the_value_table_hash, 
8886     ({
8887         vec_add2 (sort_me, sm, 1);
8888         sm->name = (u8 *)(p->key);
8889         sm->value = (u8 *) (p->value[0]);
8890     }));
8891     
8892     vec_sort_with_function (sort_me, macro_sort_cmp);
8893
8894     if (vec_len(sort_me))
8895         fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
8896     else
8897         fformat (vam->ofp, "The macro table is empty...\n");
8898
8899     for (i = 0; i < vec_len (sort_me); i++)
8900         fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
8901                  sort_me[i].value);
8902     return 0;
8903 }
8904
8905 static int dump_node_table (vat_main_t * vam)
8906 {
8907     int i, j;
8908     vlib_node_t * node, * next_node;
8909
8910     if (vec_len (vam->graph_nodes) == 0) {
8911         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
8912         return 0;
8913     }
8914
8915     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
8916         node = vam->graph_nodes[i];
8917         fformat (vam->ofp, "[%d] %s\n", i, node->name);
8918         for (j = 0; j < vec_len (node->next_nodes); j++) {
8919             if (node->next_nodes[j] != ~0) {
8920                 next_node = vam->graph_nodes[node->next_nodes[j]];
8921                 fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
8922             }
8923         }
8924     }
8925     return 0;
8926 }
8927
8928 static int search_node_table (vat_main_t * vam)
8929 {
8930     unformat_input_t * line_input = vam->input;
8931     u8 * node_to_find;
8932     int j;
8933     vlib_node_t * node, * next_node;
8934     uword * p;
8935
8936     if (vam->graph_node_index_by_name == 0) {
8937         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
8938         return 0;
8939     }
8940
8941     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8942         if (unformat (line_input, "%s", &node_to_find)) {
8943             vec_add1 (node_to_find, 0);
8944             p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
8945             if (p == 0) {
8946                 fformat (vam->ofp, "%s not found...\n", node_to_find);
8947                 goto out;
8948             }
8949             node = vam->graph_nodes[p[0]];
8950             fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
8951             for (j = 0; j < vec_len (node->next_nodes); j++) {
8952                 if (node->next_nodes[j] != ~0) {
8953                     next_node = vam->graph_nodes[node->next_nodes[j]];
8954                     fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
8955                 }
8956             }
8957         }
8958             
8959         else {
8960             clib_warning ("parse error '%U'", format_unformat_error, 
8961                           line_input);
8962             return -99;
8963         }
8964
8965     out:
8966         vec_free(node_to_find);
8967         
8968     }
8969
8970     return 0;        
8971 }
8972
8973
8974 static int script (vat_main_t * vam)
8975 {
8976     u8 * s = 0;
8977     char * save_current_file;
8978     unformat_input_t save_input;
8979     jmp_buf save_jump_buf;
8980     u32 save_line_number;
8981
8982     FILE * new_fp, * save_ifp;
8983
8984     if (unformat (vam->input, "%s", &s)) {
8985         new_fp = fopen ((char *)s, "r");
8986         if (new_fp == 0) {
8987             errmsg ("Couldn't open script file %s\n", s);
8988             vec_free (s);
8989             return -99;
8990         }
8991     } else {
8992         errmsg ("Missing script name\n");
8993         return -99;
8994     }
8995
8996     memcpy (&save_input, &vam->input, sizeof (save_input));
8997     memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
8998     save_ifp = vam->ifp;
8999     save_line_number = vam->input_line_number;
9000     save_current_file = (char *) vam->current_file;
9001
9002     vam->input_line_number = 0;
9003     vam->ifp = new_fp;
9004     vam->current_file = s;
9005     do_one_file (vam);
9006
9007     memcpy (&vam->input, &save_input, sizeof (vam->input));
9008     memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
9009     vam->ifp = save_ifp;
9010     vam->input_line_number = save_line_number;
9011     vam->current_file = (u8 *) save_current_file;
9012     vec_free (s);
9013
9014     return 0;
9015 }
9016
9017 static int echo (vat_main_t * vam)
9018 {
9019     fformat (vam->ofp, "%v", vam->input->buffer);
9020     return 0;
9021 }
9022
9023 /* List of API message constructors, CLI names map to api_xxx */
9024 #define foreach_vpe_api_msg                                             \
9025 _(create_loopback,"[mac <mac-addr>]")                                   \
9026 _(sw_interface_dump,"")                                                 \
9027 _(sw_interface_set_flags,                                               \
9028   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
9029 _(sw_interface_add_del_address,                                         \
9030   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
9031 _(sw_interface_set_table,                                               \
9032   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
9033 _(sw_interface_set_vpath,                                               \
9034   "<intfc> | sw_if_index <id> enable | disable")                        \
9035 _(sw_interface_set_l2_xconnect,                                         \
9036   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
9037   "enable | disable")                                                   \
9038 _(sw_interface_set_l2_bridge,                                           \
9039   "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n"         \
9040   "[shg <split-horizon-group>] [bvi]\n"                                 \
9041   "enable | disable")                                                   \
9042 _(bridge_domain_add_del,                                                \
9043   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
9044 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
9045 _(l2fib_add_del,                                                        \
9046   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
9047 _(l2_flags,                                                             \
9048   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
9049 _(bridge_flags,                                                         \
9050   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
9051 _(tap_connect,                                                          \
9052   "tapname <name> mac <mac-addr> | random-mac")                         \
9053 _(tap_modify,                                                           \
9054   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
9055 _(tap_delete,                                                           \
9056   "<vpp-if-name> | sw_if_index <id>")                                   \
9057 _(sw_interface_tap_dump, "")                                            \
9058 _(ip_add_del_route,                                                     \
9059   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
9060   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
9061   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
9062   "[multipath] [count <n>]")                                            \
9063 _(proxy_arp_add_del,                                                    \
9064   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
9065 _(proxy_arp_intfc_enable_disable,                                       \
9066   "<intfc> | sw_if_index <id> enable | disable")                        \
9067 _(mpls_add_del_encap,                                                   \
9068   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
9069 _(mpls_add_del_decap,                                                   \
9070   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
9071 _(mpls_gre_add_del_tunnel,                                              \
9072   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
9073   "adj <ip4-address>/<mask-width> [del]")                               \
9074 _(sw_interface_set_unnumbered,                                          \
9075   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
9076 _(ip_neighbor_add_del,                                                  \
9077   "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>")       \
9078 _(reset_vrf, "vrf <id> [ipv6]")                                         \
9079 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
9080 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
9081   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
9082   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
9083   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
9084 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
9085 _(reset_fib, "vrf <n> [ipv6]")                                          \
9086 _(dhcp_proxy_config,                                                    \
9087   "svr <v46-address> src <v46-address>\n"                               \
9088    "insert-cid <n> [del]")                                              \
9089 _(dhcp_proxy_config_2,                                                  \
9090   "svr <v46-address> src <v46-address>\n"                               \
9091    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
9092 _(dhcp_proxy_set_vss,                                                   \
9093   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
9094 _(dhcp_client_config,                                                   \
9095   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
9096 _(set_ip_flow_hash,                                                     \
9097   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
9098 _(sw_interface_ip6_enable_disable,                                      \
9099   "<intfc> | sw_if_index <id> enable | disable")                        \
9100 _(sw_interface_ip6_set_link_local_address,                              \
9101   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
9102 _(sw_interface_ip6nd_ra_prefix,                                         \
9103   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
9104   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
9105   "[nolink] [isno]")                                                    \
9106 _(sw_interface_ip6nd_ra_config,                                         \
9107   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
9108   "[life <n>] [count <n>] [interval <n>] [surpress]\n"                  \
9109   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
9110 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
9111 _(l2_patch_add_del,                                                     \
9112   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
9113   "enable | disable")                                                   \
9114 _(mpls_ethernet_add_del_tunnel,                                         \
9115   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
9116   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
9117 _(mpls_ethernet_add_del_tunnel_2,                                       \
9118   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
9119   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
9120 _(sr_tunnel_add_del,                                                    \
9121   "src <ip6-addr> dst <ip6-addr>/<mw> (next <ip6-addr>)+\n"             \
9122   " [tag <ip6-addr>]* [clean] [reroute]")                               \
9123 _(classify_add_del_table,                                               \
9124   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
9125   "[del] mask <mask-value>\n"                                           \
9126   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
9127 _(classify_add_del_session,                                             \
9128   "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n"    \
9129   "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]")           \
9130 _(classify_set_interface_ip_table,                                      \
9131   "<intfc> | sw_if_index <nn> table <nn>")                              \
9132 _(classify_set_interface_l2_tables,                                     \
9133   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
9134   "  [other-table <nn>]")                                               \
9135 _(get_node_index, "node <node-name")                                    \
9136 _(add_node_next, "node <node-name> next <next-node-name>")              \
9137 _(l2tpv3_create_tunnel,                                                 \
9138   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
9139   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
9140   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
9141 _(l2tpv3_set_tunnel_cookies,                                            \
9142   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
9143   "[new_remote_cookie <nn>]\n")                                         \
9144 _(l2tpv3_interface_enable_disable,                                      \
9145   "<intfc> | sw_if_index <nn> enable | disable")                        \
9146 _(l2tpv3_set_lookup_key,                                                \
9147   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
9148 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
9149 _(vxlan_add_del_tunnel,                                                 \
9150   "src <ip4-addr> dst <ip4-addr> vni [encap-vrf-id <nn>]\n"             \
9151   " [decap-next l2|ip4|ip6] [del]")                                     \
9152 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
9153 _(l2_fib_clear_table, "")                                               \
9154 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
9155 _(l2_interface_vlan_tag_rewrite,                                        \
9156   "<intfc> | sw_if_index <nn> \n"                                       \
9157   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
9158   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
9159 _(create_vhost_user_if,                                                 \
9160         "socket <filename> [server] [renumber <dev_instance>] "         \
9161         "[mac <mac_address>]")                                          \
9162 _(modify_vhost_user_if,                                                 \
9163         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
9164         "[server] [renumber <dev_instance>]")                           \
9165 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
9166 _(sw_interface_vhost_user_dump, "")                                     \
9167 _(show_version, "")                                                     \
9168 _(nsh_gre_add_del_tunnel,                                               \
9169   "src <ip4-addr> dst <ip4-addr>"                                       \
9170   "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n"                  \
9171   "[encap-fib-id <nn>] [decap-fib-id <nn>] [o-bit <1|0>]\n"             \
9172   "[c-bit <1|0>] [md-type <nn>][next-ip4][next-ip6][next-ethernet]\n"   \
9173   "[tlv <xx>][del]")                                                    \
9174 _(nsh_vxlan_gpe_add_del_tunnel,                                         \
9175   "src <ip4-addr> dst <ip4-addr> vni <nn>\n"                            \
9176   "c1 <nn> c2 <nn> c3 <nn> c4 <nn> spi <nn> si <nn>\n"                  \
9177   "[encap-vrf-id <nn>] [decap-vrf-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 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
9181 _(lisp_gpe_add_del_tunnel,                                              \
9182   "src <ip4-addr> dst <ip4-addr> iid <nn>|iidx <0xnn>\n"                \
9183   "[encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                           \
9184   "[n-bit][l-bit][e-bit][v-bit][i-bit][p-bit][not-p-bit][o-bit]\n"      \
9185   "[next-ip4][next-ip6][next-ethernet][next-nsh]\n"                     \
9186   "[decap-next [ip4|ip6|ethernet|nsh-encap|<nn>]][del]")                \
9187 _(interface_name_renumber,                                              \
9188   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
9189 _(input_acl_set_interface,                                              \
9190   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
9191   "  [l2-table <nn>] [del]")                                            \
9192 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
9193 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
9194 _(ip_dump, "ipv4 | ipv6")                                               \
9195 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
9196 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
9197   "  spid_id <n> ")                                                     \
9198 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
9199   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
9200   "  integ_alg <alg> integ_key <hex>")                                  \
9201 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
9202   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
9203   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
9204   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
9205 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
9206 _(delete_loopback,"sw_if_index <nn>")                                   \
9207 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
9208 _(map_add_domain,                                                       \
9209   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
9210   "ip6-src <ip6addr> "                                                  \
9211   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
9212 _(map_del_domain, "index <n>")                                          \
9213 _(map_add_del_rule,                                                     \
9214   "index <n> psid <n> dst <ip6addr> [del]")                             \
9215 _(map_domain_dump, "")                                                  \
9216 _(map_rule_dump, "index <map-domain>")                                  \
9217 _(want_interface_events,  "enable|disable")                             \
9218 _(want_stats,"enable|disable")                                          \
9219 _(get_first_msg_id, "client <name>")                                    \
9220 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
9221 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
9222   "fib-id <nn> [ip4][ip6][default]")                                    \
9223 _(get_node_graph, " ")                                                  \
9224 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
9225 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
9226   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
9227   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
9228 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
9229   " vrf_id <nn>  add | pop | none")                                     \
9230 _(trace_profile_del, "")
9231
9232 /* List of command functions, CLI names map directly to functions */
9233 #define foreach_cli_function                                    \
9234 _(comment, "usage: comment <ignore-rest-of-line>")              \
9235 _(dump_interface_table, "usage: dump_interface_table")          \
9236 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
9237 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
9238 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
9239 _(dump_stats_table, "usage: dump_stats_table")                  \
9240 _(dump_macro_table, "usage: dump_macro_table ")                 \
9241 _(dump_node_table, "usage: dump_node_table")                    \
9242 _(echo, "usage: echo <message>")                                \
9243 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
9244 _(help, "usage: help")                                          \
9245 _(q, "usage: quit")                                             \
9246 _(quit, "usage: quit")                                          \
9247 _(search_node_table, "usage: search_node_table <name>...")      \
9248 _(set, "usage: set <variable-name> <value>")                    \
9249 _(script, "usage: script <file-name>")                          \
9250 _(unset, "usage: unset <variable-name>")
9251
9252 #define _(N,n)                                  \
9253     static void vl_api_##n##_t_handler_uni      \
9254     (vl_api_##n##_t * mp)                       \
9255     {                                           \
9256         vat_main_t * vam = &vat_main;           \
9257         if (vam->json_output) {                 \
9258             vl_api_##n##_t_handler_json(mp);    \
9259         } else {                                \
9260             vl_api_##n##_t_handler(mp);         \
9261         }                                       \
9262     }
9263 foreach_vpe_api_reply_msg;
9264 #undef _
9265
9266 void vat_api_hookup (vat_main_t *vam)
9267 {
9268 #define _(N,n)                                                  \
9269     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
9270                            vl_api_##n##_t_handler_uni,          \
9271                            vl_noop_handler,                     \
9272                            vl_api_##n##_t_endian,               \
9273                            vl_api_##n##_t_print,                \
9274                            sizeof(vl_api_##n##_t), 1); 
9275     foreach_vpe_api_reply_msg;
9276 #undef _
9277
9278     vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
9279
9280     vam->sw_if_index_by_interface_name = 
9281         hash_create_string (0, sizeof (uword));
9282
9283     vam->function_by_name = 
9284         hash_create_string (0, sizeof(uword));
9285
9286     vam->help_by_name = 
9287         hash_create_string (0, sizeof(uword));
9288
9289     /* API messages we can send */
9290 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
9291     foreach_vpe_api_msg;
9292 #undef _
9293
9294     /* Help strings */
9295 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9296     foreach_vpe_api_msg;
9297 #undef _
9298
9299     /* CLI functions */
9300 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
9301     foreach_cli_function;
9302 #undef _
9303
9304     /* Help strings */
9305 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
9306     foreach_cli_function;
9307 #undef _
9308 }
9309
9310 #undef vl_api_version
9311 #define vl_api_version(n,v) static u32 vpe_api_version = v;
9312 #include <api/vpe.api.h>
9313 #undef vl_api_version
9314
9315 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
9316 {
9317     /* 
9318      * Send the main API signature in slot 0. This bit of code must
9319      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
9320      */
9321     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
9322 }