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