Add Dump API for VxLAN-GPE tunnel
[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 static u8 * format_policer_type (u8 * s, va_list * va)
2141 {
2142     u32 i = va_arg (*va, u32);
2143
2144     if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2145         s = format (s, "1r2c");
2146     else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2147         s = format (s, "1r3c");
2148     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2149         s = format (s, "2r3c-2698");
2150     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2151         s = format (s, "2r3c-4115");
2152     else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2153         s = format (s, "2r3c-mef5cf1");
2154     else
2155         s = format (s, "ILLEGAL");
2156     return s;
2157 }
2158
2159 static u8 * format_policer_rate_type (u8 * s, va_list * va)
2160 {
2161     u32 i = va_arg (*va, u32);
2162
2163     if (i == SSE2_QOS_RATE_KBPS)
2164         s = format (s, "kbps");
2165     else if (i == SSE2_QOS_RATE_PPS)
2166         s = format(s, "pps");
2167     else
2168         s = format (s, "ILLEGAL");
2169     return s;
2170 }
2171
2172 static u8 * format_policer_round_type (u8 * s, va_list * va)
2173 {
2174     u32 i = va_arg (*va, u32);
2175
2176     if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2177         s = format(s, "closest");
2178     else if (i == SSE2_QOS_ROUND_TO_UP)
2179         s = format (s, "up");
2180     else if (i == SSE2_QOS_ROUND_TO_DOWN)
2181         s = format (s, "down");
2182     else
2183         s = format (s, "ILLEGAL");
2184   return s;
2185 }
2186
2187 static void vl_api_policer_details_t_handler
2188 (vl_api_policer_details_t * mp)
2189 {
2190     vat_main_t * vam = &vat_main;
2191
2192     fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2193              "rate type %U, round type %U, %s rate, %s color-aware, "
2194              "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2195              "cur bkt %u, ext lim %u, ext bkt %u, last update %llu\n",
2196              mp->name,
2197              format_policer_type, mp->type,
2198              ntohl(mp->cir),
2199              ntohl(mp->eir),
2200              ntohl(mp->cb),
2201              ntohl(mp->eb),
2202              format_policer_rate_type, mp->rate_type,
2203              format_policer_round_type, mp->round_type,
2204              mp->single_rate ? "single" : "dual",
2205              mp->color_aware ? "is" : "not",
2206              ntohl(mp->cir_tokens_per_period),
2207              ntohl(mp->pir_tokens_per_period),
2208              ntohl(mp->scale),
2209              ntohl(mp->current_limit),
2210              ntohl(mp->current_bucket),
2211              ntohl(mp->extended_limit),
2212              ntohl(mp->extended_bucket),
2213              clib_net_to_host_u64(mp->last_update_time));
2214 }
2215
2216 static void vl_api_policer_details_t_handler_json
2217 (vl_api_policer_details_t * mp)
2218 {
2219     vat_main_t * vam = &vat_main;
2220     vat_json_node_t *node;
2221     u8 *rate_type_str, *round_type_str, *type_str;
2222
2223     rate_type_str = format(0, "%U", format_policer_rate_type, mp->rate_type);
2224     round_type_str = format(0, "%U", format_policer_round_type, mp->round_type);
2225     type_str = format(0, "%U", format_policer_type, mp->type);
2226
2227     if (VAT_JSON_ARRAY != vam->json_tree.type) {
2228         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
2229         vat_json_init_array(&vam->json_tree);
2230     }
2231     node = vat_json_array_add(&vam->json_tree);
2232
2233     vat_json_init_object(node);
2234     vat_json_object_add_string_copy(node, "name", mp->name);
2235     vat_json_object_add_uint(node, "cir", ntohl(mp->cir));
2236     vat_json_object_add_uint(node, "eir", ntohl(mp->eir));
2237     vat_json_object_add_uint(node, "cb", ntohl(mp->cb));
2238     vat_json_object_add_uint(node, "eb", ntohl(mp->eb));
2239     vat_json_object_add_string_copy(node, "rate_type", rate_type_str);
2240     vat_json_object_add_string_copy(node, "round_type", round_type_str);
2241     vat_json_object_add_string_copy(node, "type", type_str);
2242     vat_json_object_add_uint(node, "single_rate", mp->single_rate);
2243     vat_json_object_add_uint(node, "color_aware", mp->color_aware);
2244     vat_json_object_add_uint(node, "scale", ntohl(mp->scale));
2245     vat_json_object_add_uint(node, "cir_tokens_per_period",
2246                              ntohl(mp->cir_tokens_per_period));
2247     vat_json_object_add_uint(node, "eir_tokens_per_period",
2248                              ntohl(mp->pir_tokens_per_period));
2249     vat_json_object_add_uint(node, "current_limit", ntohl(mp->current_limit));
2250     vat_json_object_add_uint(node, "current_bucket", ntohl(mp->current_bucket));
2251     vat_json_object_add_uint(node, "extended_limit", ntohl(mp->extended_limit));
2252     vat_json_object_add_uint(node, "extended_bucket",
2253                              ntohl(mp->extended_bucket));
2254     vat_json_object_add_uint(node, "last_update_time",
2255                              ntohl(mp->last_update_time));
2256
2257     vec_free(rate_type_str);
2258     vec_free(round_type_str);
2259     vec_free(type_str);
2260 }
2261
2262
2263 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
2264 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
2265 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
2266 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
2267
2268 /* 
2269  * Generate boilerplate reply handlers, which 
2270  * dig the return value out of the xxx_reply_t API message,
2271  * stick it into vam->retval, and set vam->result_ready
2272  *
2273  * Could also do this by pointing N message decode slots at
2274  * a single function, but that could break in subtle ways.
2275  */
2276
2277 #define foreach_standard_reply_retval_handler           \
2278 _(sw_interface_set_flags_reply)                         \
2279 _(sw_interface_add_del_address_reply)                   \
2280 _(sw_interface_set_table_reply)                         \
2281 _(sw_interface_set_vpath_reply)                         \
2282 _(sw_interface_set_l2_bridge_reply)                     \
2283 _(bridge_domain_add_del_reply)                          \
2284 _(sw_interface_set_l2_xconnect_reply)                   \
2285 _(l2fib_add_del_reply)                                  \
2286 _(ip_add_del_route_reply)                               \
2287 _(proxy_arp_add_del_reply)                              \
2288 _(proxy_arp_intfc_enable_disable_reply)                 \
2289 _(mpls_add_del_encap_reply)                             \
2290 _(mpls_add_del_decap_reply)                             \
2291 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
2292 _(sw_interface_set_unnumbered_reply)                    \
2293 _(ip_neighbor_add_del_reply)                            \
2294 _(reset_vrf_reply)                                      \
2295 _(oam_add_del_reply)                                    \
2296 _(reset_fib_reply)                                      \
2297 _(dhcp_proxy_config_reply)                              \
2298 _(dhcp_proxy_config_2_reply)                            \
2299 _(dhcp_proxy_set_vss_reply)                             \
2300 _(dhcp_client_config_reply)                             \
2301 _(set_ip_flow_hash_reply)                               \
2302 _(sw_interface_ip6_enable_disable_reply)                \
2303 _(sw_interface_ip6_set_link_local_address_reply)        \
2304 _(sw_interface_ip6nd_ra_prefix_reply)                   \
2305 _(sw_interface_ip6nd_ra_config_reply)                   \
2306 _(set_arp_neighbor_limit_reply)                         \
2307 _(l2_patch_add_del_reply)                               \
2308 _(sr_tunnel_add_del_reply)                              \
2309 _(sr_policy_add_del_reply)                              \
2310 _(sr_multicast_map_add_del_reply)                       \
2311 _(classify_add_del_session_reply)                       \
2312 _(classify_set_interface_ip_table_reply)                \
2313 _(classify_set_interface_l2_tables_reply)               \
2314 _(l2tpv3_set_tunnel_cookies_reply)                      \
2315 _(l2tpv3_interface_enable_disable_reply)                \
2316 _(l2tpv3_set_lookup_key_reply)                          \
2317 _(l2_fib_clear_table_reply)                             \
2318 _(l2_interface_efp_filter_reply)                        \
2319 _(l2_interface_vlan_tag_rewrite_reply)                  \
2320 _(modify_vhost_user_if_reply)                           \
2321 _(delete_vhost_user_if_reply)                           \
2322 _(want_ip4_arp_events_reply)                            \
2323 _(input_acl_set_interface_reply)                        \
2324 _(ipsec_spd_add_del_reply)                              \
2325 _(ipsec_interface_add_del_spd_reply)                    \
2326 _(ipsec_spd_add_del_entry_reply)                        \
2327 _(ipsec_sad_add_del_entry_reply)                        \
2328 _(ipsec_sa_set_key_reply)                               \
2329 _(ikev2_profile_add_del_reply)                          \
2330 _(ikev2_profile_set_auth_reply)                         \
2331 _(ikev2_profile_set_id_reply)                           \
2332 _(ikev2_profile_set_ts_reply)                           \
2333 _(ikev2_set_local_key_reply)                            \
2334 _(delete_loopback_reply)                                \
2335 _(bd_ip_mac_add_del_reply)                              \
2336 _(map_del_domain_reply)                                 \
2337 _(map_add_del_rule_reply)                               \
2338 _(want_interface_events_reply)                          \
2339 _(want_stats_reply)                                     \
2340 _(cop_interface_enable_disable_reply)                   \
2341 _(cop_whitelist_enable_disable_reply)                   \
2342 _(sw_interface_clear_stats_reply)                       \
2343 _(trace_profile_add_reply)                              \
2344 _(trace_profile_apply_reply)                            \
2345 _(trace_profile_del_reply)                              \
2346 _(lisp_add_del_locator_set_reply)                       \
2347 _(lisp_add_del_locator_reply)                           \
2348 _(lisp_add_del_local_eid_reply)                         \
2349 _(lisp_gpe_add_del_fwd_entry_reply)                     \
2350 _(lisp_add_del_map_resolver_reply)                      \
2351 _(lisp_gpe_enable_disable_reply)                        \
2352 _(lisp_gpe_add_del_iface_reply)                         \
2353 _(lisp_enable_disable_reply)                            \
2354 _(lisp_pitr_set_locator_set_reply)                      \
2355 _(vxlan_gpe_add_del_tunnel_reply)                       \
2356 _(af_packet_create_reply)                               \
2357 _(af_packet_delete_reply)                               \
2358 _(policer_add_del_reply)                                \
2359 _(netmap_create_reply)                                  \
2360 _(netmap_delete_reply)
2361
2362 #define _(n)                                    \
2363     static void vl_api_##n##_t_handler          \
2364     (vl_api_##n##_t * mp)                       \
2365     {                                           \
2366         vat_main_t * vam = &vat_main;           \
2367         i32 retval = ntohl(mp->retval);         \
2368         if (vam->async_mode) {                  \
2369             vam->async_errors += (retval < 0);  \
2370         } else {                                \
2371             vam->retval = retval;               \
2372             vam->result_ready = 1;              \
2373         }                                       \
2374     }
2375 foreach_standard_reply_retval_handler;
2376 #undef _
2377
2378 #define _(n)                                    \
2379     static void vl_api_##n##_t_handler_json     \
2380     (vl_api_##n##_t * mp)                       \
2381     {                                           \
2382         vat_main_t * vam = &vat_main;           \
2383         vat_json_node_t node;                   \
2384         vat_json_init_object(&node);            \
2385         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
2386         vat_json_print(vam->ofp, &node);        \
2387         vam->retval = ntohl(mp->retval);        \
2388         vam->result_ready = 1;                  \
2389     }
2390 foreach_standard_reply_retval_handler;
2391 #undef _
2392
2393 /* 
2394  * Table of message reply handlers, must include boilerplate handlers
2395  * we just generated
2396  */
2397
2398 #define foreach_vpe_api_reply_msg                                       \
2399 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
2400 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
2401 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
2402 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
2403 _(CONTROL_PING_REPLY, control_ping_reply)                               \
2404 _(CLI_REPLY, cli_reply)                                                 \
2405 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
2406   sw_interface_add_del_address_reply)                                   \
2407 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
2408 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
2409 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
2410   sw_interface_set_l2_xconnect_reply)                                   \
2411 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
2412   sw_interface_set_l2_bridge_reply)                                     \
2413 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
2414 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
2415 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
2416 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
2417 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
2418 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
2419 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
2420 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
2421 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
2422 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
2423 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
2424 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
2425 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
2426   proxy_arp_intfc_enable_disable_reply)                                 \
2427 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
2428 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
2429 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
2430 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
2431   mpls_ethernet_add_del_tunnel_reply)                                   \
2432 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
2433   mpls_ethernet_add_del_tunnel_2_reply)                                 \
2434 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
2435   sw_interface_set_unnumbered_reply)                                    \
2436 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
2437 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
2438 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
2439 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
2440 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
2441 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
2442 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
2443 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
2444 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
2445 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
2446 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
2447 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
2448   sw_interface_ip6_enable_disable_reply)                                \
2449 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
2450   sw_interface_ip6_set_link_local_address_reply)                        \
2451 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
2452   sw_interface_ip6nd_ra_prefix_reply)                                   \
2453 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
2454   sw_interface_ip6nd_ra_config_reply)                                   \
2455 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
2456 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
2457 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
2458 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
2459 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
2460 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
2461 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
2462 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
2463 classify_set_interface_ip_table_reply)                                  \
2464 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
2465   classify_set_interface_l2_tables_reply)                               \
2466 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
2467 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
2468 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
2469 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
2470 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
2471   l2tpv3_interface_enable_disable_reply)                                \
2472 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
2473 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
2474 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
2475 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
2476 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
2477 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
2478 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
2479 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
2480 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
2481 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
2482 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
2483 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
2484 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
2485 _(SHOW_VERSION_REPLY, show_version_reply)                               \
2486 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
2487 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
2488 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
2489 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
2490 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
2491 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
2492 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
2493 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
2494 _(IP_DETAILS, ip_details)                                               \
2495 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
2496 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
2497 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
2498 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
2499 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
2500 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
2501 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
2502 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
2503 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
2504 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
2505 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
2506 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
2507 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
2508 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
2509 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
2510 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
2511 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
2512 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
2513 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
2514 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
2515 _(MAP_RULE_DETAILS, map_rule_details)                                   \
2516 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
2517 _(WANT_STATS_REPLY, want_stats_reply)                                   \
2518 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
2519 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
2520 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
2521 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
2522 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
2523 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
2524 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
2525 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
2526 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
2527 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
2528 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
2529 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
2530 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
2531 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
2532 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
2533 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
2534 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
2535 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
2536 _(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details)           \
2537 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
2538 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
2539 _(LISP_ENABLE_DISABLE_STATUS_DETAILS,                                   \
2540   lisp_enable_disable_status_details)                                   \
2541 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
2542 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
2543 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
2544 _(POLICER_DETAILS, policer_details)                                     \
2545 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
2546 _(NETMAP_DELETE_REPLY, netmap_delete_reply)
2547
2548 /* M: construct, but don't yet send a message */
2549
2550 #define M(T,t)                                  \
2551 do {                                            \
2552     vam->result_ready = 0;                      \
2553     mp = vl_msg_api_alloc(sizeof(*mp));         \
2554     memset (mp, 0, sizeof (*mp));               \
2555     mp->_vl_msg_id = ntohs (VL_API_##T);        \
2556     mp->client_index = vam->my_client_index;    \
2557 } while(0);
2558
2559 #define M2(T,t,n)                               \
2560 do {                                            \
2561     vam->result_ready = 0;                      \
2562     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
2563     memset (mp, 0, sizeof (*mp));               \
2564     mp->_vl_msg_id = ntohs (VL_API_##T);        \
2565     mp->client_index = vam->my_client_index;    \
2566 } while(0);
2567
2568
2569 /* S: send a message */
2570 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
2571
2572 /* W: wait for results, with timeout */
2573 #define W                                       \
2574 do {                                            \
2575     timeout = vat_time_now (vam) + 1.0;         \
2576                                                 \
2577     while (vat_time_now (vam) < timeout) {      \
2578         if (vam->result_ready == 1) {           \
2579             return (vam->retval);               \
2580         }                                       \
2581     }                                           \
2582     return -99;                                 \
2583 } while(0);
2584
2585 typedef struct {
2586     u8 * name;
2587     u32 value;
2588 } name_sort_t;
2589
2590
2591 #define STR_VTR_OP_CASE(op)     \
2592     case L2_VTR_ ## op:         \
2593         return "" # op;
2594
2595 static const char *str_vtr_op(u32 vtr_op)
2596 {
2597     switch(vtr_op) {
2598         STR_VTR_OP_CASE(DISABLED);
2599         STR_VTR_OP_CASE(PUSH_1);
2600         STR_VTR_OP_CASE(PUSH_2);
2601         STR_VTR_OP_CASE(POP_1);
2602         STR_VTR_OP_CASE(POP_2);
2603         STR_VTR_OP_CASE(TRANSLATE_1_1);
2604         STR_VTR_OP_CASE(TRANSLATE_1_2);
2605         STR_VTR_OP_CASE(TRANSLATE_2_1);
2606         STR_VTR_OP_CASE(TRANSLATE_2_2);
2607     }
2608
2609     return "UNKNOWN";
2610 }
2611
2612 static int dump_sub_interface_table (vat_main_t * vam)
2613 {
2614     const sw_interface_subif_t * sub = NULL;
2615
2616     if (vam->json_output) {
2617         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2618         return -99;
2619     }
2620
2621     fformat (vam->ofp,
2622              "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
2623              "Interface", "sw_if_index",
2624              "sub id", "dot1ad", "tags", "outer id",
2625              "inner id", "exact", "default",
2626              "outer any", "inner any");
2627
2628     vec_foreach (sub, vam->sw_if_subif_table) {
2629         fformat (vam->ofp,
2630                  "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
2631                  sub->interface_name,
2632                  sub->sw_if_index,
2633                  sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
2634                  sub->sub_number_of_tags, sub->sub_outer_vlan_id,
2635                  sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
2636                  sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2637         if (sub->vtr_op != L2_VTR_DISABLED) {
2638             fformat (vam->ofp,
2639                      "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2640                      "tag1: %d tag2: %d ]\n",
2641                      str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q, 
2642                      sub->vtr_tag1, sub->vtr_tag2);
2643         }
2644     }
2645
2646     return 0;
2647 }
2648
2649 static int name_sort_cmp (void * a1, void * a2)
2650 {
2651   name_sort_t * n1 = a1;
2652   name_sort_t * n2 = a2;
2653
2654   return strcmp ((char *)n1->name, (char *)n2->name);
2655 }
2656
2657 static int dump_interface_table (vat_main_t * vam)
2658 {
2659     hash_pair_t * p;
2660     name_sort_t * nses = 0, * ns;
2661
2662     if (vam->json_output) {
2663         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2664         return -99;
2665     }
2666
2667     hash_foreach_pair (p, vam->sw_if_index_by_interface_name, 
2668     ({
2669         vec_add2 (nses, ns, 1);
2670         ns->name = (u8 *)(p->key);
2671         ns->value = (u32) p->value[0];
2672     }));
2673
2674     vec_sort_with_function (nses, name_sort_cmp);
2675
2676     fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
2677     vec_foreach (ns, nses) {
2678         fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
2679     }
2680     vec_free (nses);
2681     return 0;
2682 }
2683
2684 static int dump_ip_table (vat_main_t * vam, int is_ipv6)
2685 {
2686     const ip_details_t * det = NULL;
2687     const ip_address_details_t * address = NULL;
2688     u32 i = ~0;
2689
2690     fformat (vam->ofp,
2691              "%-12s\n",
2692              "sw_if_index");
2693
2694     if (0 == vam) {
2695         return 0;
2696     }
2697
2698     vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
2699         i++;
2700         if (!det->present) {
2701             continue;
2702         }
2703         fformat (vam->ofp,
2704                  "%-12d\n",
2705                  i);
2706         fformat (vam->ofp,
2707                  "            %-30s%-13s\n",
2708                  "Address", "Prefix length");
2709         if (!det->addr) {
2710             continue;
2711         }
2712         vec_foreach (address, det->addr) {
2713             fformat (vam->ofp,
2714                      "            %-30U%-13d\n",
2715                      is_ipv6 ? format_ip6_address : format_ip4_address,
2716                      address->ip,
2717                      address->prefix_length);
2718         }
2719     }
2720
2721     return 0;
2722 }
2723
2724 static int dump_ipv4_table (vat_main_t * vam)
2725 {
2726     if (vam->json_output) {
2727         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2728         return -99;
2729     }
2730
2731     return dump_ip_table (vam, 0);
2732 }
2733
2734 static int dump_ipv6_table (vat_main_t * vam)
2735 {
2736     if (vam->json_output) {
2737         clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
2738         return -99;
2739     }
2740
2741     return dump_ip_table (vam, 1);
2742 }
2743
2744 static char* counter_type_to_str (u8 counter_type, u8 is_combined)
2745 {
2746     if (!is_combined) {
2747         switch(counter_type) {
2748         case VNET_INTERFACE_COUNTER_DROP:
2749             return "drop";
2750         case VNET_INTERFACE_COUNTER_PUNT:
2751             return "punt";
2752         case VNET_INTERFACE_COUNTER_IP4:
2753             return "ip4";
2754         case VNET_INTERFACE_COUNTER_IP6:
2755             return "ip6";
2756         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
2757             return "rx-no-buf";
2758         case VNET_INTERFACE_COUNTER_RX_MISS:
2759             return "rx-miss";
2760         case VNET_INTERFACE_COUNTER_RX_ERROR:
2761             return "rx-error";
2762         case VNET_INTERFACE_COUNTER_TX_ERROR:
2763             return "tx-error";
2764         default:
2765             return "INVALID-COUNTER-TYPE";
2766         }
2767     } else {
2768         switch(counter_type) {
2769         case VNET_INTERFACE_COUNTER_RX:
2770             return "rx";
2771         case VNET_INTERFACE_COUNTER_TX:
2772             return "tx";
2773         default:
2774             return "INVALID-COUNTER-TYPE";
2775         }
2776     }
2777 }
2778
2779 static int dump_stats_table (vat_main_t * vam)
2780 {
2781     vat_json_node_t node;
2782     vat_json_node_t *msg_array;
2783     vat_json_node_t *msg;
2784     vat_json_node_t *counter_array;
2785     vat_json_node_t *counter;
2786     interface_counter_t c;
2787     u64 packets;
2788     ip4_fib_counter_t *c4;
2789     ip6_fib_counter_t *c6;
2790     int i, j;
2791
2792     if (!vam->json_output) {
2793         clib_warning ("dump_stats_table supported only in JSON format");
2794         return -99;
2795     }
2796
2797     vat_json_init_object(&node);
2798
2799     /* interface counters */
2800     msg_array = vat_json_object_add(&node, "interface_counters");
2801     vat_json_init_array(msg_array);
2802     for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
2803         msg = vat_json_array_add(msg_array);
2804         vat_json_init_object(msg);
2805         vat_json_object_add_string_copy(msg, "vnet_counter_type",
2806                 (u8*)counter_type_to_str(i, 0));
2807         vat_json_object_add_int(msg, "is_combined", 0);
2808         counter_array = vat_json_object_add(msg, "data");
2809         vat_json_init_array(counter_array);
2810         for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
2811             packets = vam->simple_interface_counters[i][j];
2812             vat_json_array_add_uint(counter_array, packets);
2813         }
2814     }
2815     for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
2816         msg = vat_json_array_add(msg_array);
2817         vat_json_init_object(msg);
2818         vat_json_object_add_string_copy(msg, "vnet_counter_type",
2819                 (u8*)counter_type_to_str(i, 1));
2820         vat_json_object_add_int(msg, "is_combined", 1);
2821         counter_array = vat_json_object_add(msg, "data");
2822         vat_json_init_array(counter_array);
2823         for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
2824             c = vam->combined_interface_counters[i][j];
2825             counter = vat_json_array_add(counter_array);
2826             vat_json_init_object(counter);
2827             vat_json_object_add_uint(counter, "packets", c.packets);
2828             vat_json_object_add_uint(counter, "bytes", c.bytes);
2829         }
2830     }
2831
2832     /* ip4 fib counters */
2833     msg_array = vat_json_object_add(&node, "ip4_fib_counters");
2834     vat_json_init_array(msg_array);
2835     for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
2836         msg = vat_json_array_add(msg_array);
2837         vat_json_init_object(msg);
2838         vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
2839         counter_array = vat_json_object_add(msg, "c");
2840         vat_json_init_array(counter_array);
2841         for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
2842             counter = vat_json_array_add(counter_array);
2843             vat_json_init_object(counter);
2844             c4 = &vam->ip4_fib_counters[i][j];
2845             vat_json_object_add_ip4(counter, "address", c4->address);
2846             vat_json_object_add_uint(counter, "address_length", c4->address_length);
2847             vat_json_object_add_uint(counter, "packets", c4->packets);
2848             vat_json_object_add_uint(counter, "bytes", c4->bytes);
2849         }
2850     }
2851
2852     /* ip6 fib counters */
2853     msg_array = vat_json_object_add(&node, "ip6_fib_counters");
2854     vat_json_init_array(msg_array);
2855     for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
2856         msg = vat_json_array_add(msg_array);
2857         vat_json_init_object(msg);
2858         vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
2859         counter_array = vat_json_object_add(msg, "c");
2860         vat_json_init_array(counter_array);
2861         for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
2862             counter = vat_json_array_add(counter_array);
2863             vat_json_init_object(counter);
2864             c6 = &vam->ip6_fib_counters[i][j];
2865             vat_json_object_add_ip6(counter, "address", c6->address);
2866             vat_json_object_add_uint(counter, "address_length", c6->address_length);
2867             vat_json_object_add_uint(counter, "packets", c6->packets);
2868             vat_json_object_add_uint(counter, "bytes", c6->bytes);
2869         }
2870     }
2871
2872     vat_json_print(vam->ofp, &node);
2873     vat_json_free(&node);
2874
2875     return 0;
2876 }
2877
2878 int exec (vat_main_t * vam)
2879 {
2880     api_main_t * am = &api_main;
2881     vl_api_cli_request_t *mp;
2882     f64 timeout;
2883     void * oldheap;
2884     u8 * cmd = 0;
2885     unformat_input_t * i = vam->input;
2886
2887     if (vec_len(i->buffer) == 0)
2888         return -1;
2889
2890     if (vam->exec_mode == 0 && unformat (i, "mode")) {        
2891         vam->exec_mode = 1;
2892         return 0;
2893     }
2894     if (vam->exec_mode == 1 && 
2895         (unformat (i, "exit") || unformat (i, "quit"))) {
2896         vam->exec_mode = 0;
2897         return 0;
2898     }
2899     
2900
2901     M(CLI_REQUEST, cli_request);
2902
2903     /* 
2904      * Copy cmd into shared memory.
2905      * In order for the CLI command to work, it
2906      * must be a vector ending in \n, not a C-string ending
2907      * in \n\0.
2908      */
2909     pthread_mutex_lock (&am->vlib_rp->mutex);
2910     oldheap = svm_push_data_heap (am->vlib_rp);
2911
2912     vec_validate (cmd, vec_len(vam->input->buffer)-1);
2913     clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
2914
2915     svm_pop_heap (oldheap);
2916     pthread_mutex_unlock (&am->vlib_rp->mutex);
2917
2918     mp->cmd_in_shmem = (u64) cmd;
2919     S;
2920     timeout = vat_time_now (vam) + 10.0;
2921
2922     while (vat_time_now (vam) < timeout) {
2923         if (vam->result_ready == 1) {
2924             u8 * free_me;
2925             if (vam->shmem_result != NULL)
2926                 fformat (vam->ofp, "%s", vam->shmem_result);
2927             pthread_mutex_lock (&am->vlib_rp->mutex);
2928             oldheap = svm_push_data_heap (am->vlib_rp);
2929             
2930             free_me = (u8 *)vam->shmem_result;
2931             vec_free (free_me);
2932
2933             svm_pop_heap (oldheap);
2934             pthread_mutex_unlock (&am->vlib_rp->mutex);
2935             return 0;
2936         }
2937     }
2938     return -99;
2939 }
2940
2941 static int api_create_loopback (vat_main_t * vam)
2942 {
2943     unformat_input_t * i = vam->input;
2944     vl_api_create_loopback_t *mp;
2945     f64 timeout;
2946     u8 mac_address[6];
2947     u8 mac_set = 0;
2948
2949     memset (mac_address, 0, sizeof (mac_address));
2950
2951     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2952       {
2953         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
2954             mac_set = 1;
2955         else
2956           break;
2957       }
2958
2959     /* Construct the API message */
2960     M(CREATE_LOOPBACK, create_loopback);
2961     if (mac_set)
2962         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
2963
2964     S; W;
2965 }
2966
2967 static int api_delete_loopback (vat_main_t * vam)
2968 {
2969     unformat_input_t * i = vam->input;
2970     vl_api_delete_loopback_t *mp;
2971     f64 timeout;
2972     u32 sw_if_index = ~0;
2973
2974     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2975       {
2976         if (unformat (i, "sw_if_index %d", &sw_if_index))
2977           ;
2978         else
2979           break;
2980       }
2981
2982     if (sw_if_index == ~0)
2983       {
2984         errmsg ("missing sw_if_index\n");
2985         return -99;
2986       }
2987
2988     /* Construct the API message */
2989     M(DELETE_LOOPBACK, delete_loopback);
2990     mp->sw_if_index = ntohl (sw_if_index);
2991
2992     S; W;
2993 }
2994
2995 static int api_want_stats (vat_main_t * vam)
2996 {
2997     unformat_input_t * i = vam->input;
2998     vl_api_want_stats_t * mp;
2999     f64 timeout;
3000     int enable = -1;
3001
3002     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3003       {
3004         if (unformat (i, "enable"))
3005           enable = 1;
3006         else if (unformat (i, "disable"))
3007           enable = 0;
3008         else
3009           break;
3010       }
3011
3012     if (enable == -1)
3013       {
3014         errmsg ("missing enable|disable\n");
3015         return -99;
3016       }
3017
3018     M(WANT_STATS, want_stats);
3019     mp->enable_disable = enable;
3020
3021     S; W;
3022 }
3023
3024 static int api_want_interface_events (vat_main_t * vam)
3025 {
3026     unformat_input_t * i = vam->input;
3027     vl_api_want_interface_events_t * mp;
3028     f64 timeout;
3029     int enable = -1;
3030
3031     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3032       {
3033         if (unformat (i, "enable"))
3034           enable = 1;
3035         else if (unformat (i, "disable"))
3036           enable = 0;
3037         else
3038           break;
3039       }
3040
3041     if (enable == -1)
3042       {
3043         errmsg ("missing enable|disable\n");
3044         return -99;
3045       }
3046
3047     M(WANT_INTERFACE_EVENTS, want_interface_events);
3048     mp->enable_disable = enable;
3049
3050     vam->interface_event_display = enable;
3051
3052     S; W;
3053 }
3054
3055
3056 /* Note: non-static, called once to set up the initial intfc table */
3057 int api_sw_interface_dump (vat_main_t * vam)
3058 {
3059     vl_api_sw_interface_dump_t *mp;
3060     f64 timeout;
3061     hash_pair_t * p;
3062     name_sort_t * nses = 0, * ns;
3063     sw_interface_subif_t * sub = NULL;
3064
3065     /* Toss the old name table */
3066     hash_foreach_pair (p, vam->sw_if_index_by_interface_name, 
3067     ({
3068         vec_add2 (nses, ns, 1);
3069         ns->name = (u8 *)(p->key);
3070         ns->value = (u32) p->value[0];
3071     }));
3072
3073     hash_free (vam->sw_if_index_by_interface_name);
3074
3075     vec_foreach (ns, nses)
3076         vec_free (ns->name);
3077
3078     vec_free (nses);
3079
3080     vec_foreach (sub, vam->sw_if_subif_table) {
3081         vec_free (sub->interface_name);
3082     }
3083     vec_free (vam->sw_if_subif_table);
3084
3085     /* recreate the interface name hash table */
3086     vam->sw_if_index_by_interface_name 
3087         = hash_create_string (0, sizeof(uword));
3088
3089     /* Get list of ethernets */
3090     M(SW_INTERFACE_DUMP, sw_interface_dump);
3091     mp->name_filter_valid = 1;
3092     strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
3093     S;
3094
3095     /* and local / loopback interfaces */
3096     M(SW_INTERFACE_DUMP, sw_interface_dump);
3097     mp->name_filter_valid = 1;
3098     strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
3099     S;
3100
3101     /* and vxlan tunnel interfaces */
3102     M(SW_INTERFACE_DUMP, sw_interface_dump);
3103     mp->name_filter_valid = 1;
3104     strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
3105     S;
3106
3107     /* and host (af_packet) interfaces */
3108     M(SW_INTERFACE_DUMP, sw_interface_dump);
3109     mp->name_filter_valid = 1;
3110     strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
3111     S;
3112
3113     /* and l2tpv3 tunnel interfaces */
3114     M(SW_INTERFACE_DUMP, sw_interface_dump);
3115     mp->name_filter_valid = 1;
3116     strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
3117     S;
3118
3119     /* and GRE tunnel interfaces */
3120     M(SW_INTERFACE_DUMP, sw_interface_dump);
3121     mp->name_filter_valid = 1;
3122     strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
3123     S;
3124
3125     /* Use a control ping for synchronization */
3126     {
3127         vl_api_control_ping_t * mp;
3128         M(CONTROL_PING, control_ping);
3129         S;
3130     }
3131     W;
3132 }
3133
3134 static int api_sw_interface_set_flags (vat_main_t * vam)
3135 {
3136     unformat_input_t * i = vam->input;
3137     vl_api_sw_interface_set_flags_t *mp;
3138     f64 timeout;
3139     u32 sw_if_index;
3140     u8 sw_if_index_set = 0;
3141     u8 admin_up = 0, link_up = 0;
3142     
3143     /* Parse args required to build the message */
3144     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3145         if (unformat (i, "admin-up"))
3146             admin_up = 1;
3147         else if (unformat (i, "admin-down"))
3148             admin_up = 0;
3149         else if (unformat (i, "link-up"))
3150             link_up = 1;
3151         else if (unformat (i, "link-down"))
3152             link_up = 0;
3153         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3154             sw_if_index_set = 1;
3155         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3156             sw_if_index_set = 1;
3157         else
3158             break;
3159     }
3160
3161     if (sw_if_index_set == 0) {
3162         errmsg ("missing interface name or sw_if_index\n");
3163         return -99;
3164     }
3165
3166     /* Construct the API message */
3167     M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
3168     mp->sw_if_index = ntohl (sw_if_index);
3169     mp->admin_up_down = admin_up;
3170     mp->link_up_down = link_up;
3171
3172     /* send it... */
3173     S;
3174
3175     /* Wait for a reply, return the good/bad news... */
3176     W;
3177 }
3178
3179 static int api_sw_interface_clear_stats (vat_main_t * vam)
3180 {
3181     unformat_input_t * i = vam->input;
3182     vl_api_sw_interface_clear_stats_t *mp;
3183     f64 timeout;
3184     u32 sw_if_index;
3185     u8 sw_if_index_set = 0;
3186
3187     /* Parse args required to build the message */
3188     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3189         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3190             sw_if_index_set = 1;
3191         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3192             sw_if_index_set = 1;
3193         else
3194             break;
3195     }
3196
3197     /* Construct the API message */
3198     M(SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
3199
3200     if (sw_if_index_set == 1)
3201         mp->sw_if_index = ntohl (sw_if_index);
3202     else
3203         mp->sw_if_index = ~0;
3204
3205     /* send it... */
3206     S;
3207
3208     /* Wait for a reply, return the good/bad news... */
3209     W;
3210 }
3211
3212 static int api_sw_interface_add_del_address (vat_main_t * vam)
3213 {
3214     unformat_input_t * i = vam->input;
3215     vl_api_sw_interface_add_del_address_t *mp;
3216     f64 timeout;
3217     u32 sw_if_index;
3218     u8 sw_if_index_set = 0;
3219     u8 is_add = 1, del_all = 0;
3220     u32 address_length = 0;
3221     u8 v4_address_set = 0;
3222     u8 v6_address_set = 0;
3223     ip4_address_t v4address;
3224     ip6_address_t v6address;
3225     
3226     /* Parse args required to build the message */
3227     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3228         if (unformat (i, "del-all"))
3229             del_all = 1;
3230         else if (unformat (i, "del"))
3231             is_add = 0;
3232         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3233             sw_if_index_set = 1;
3234         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3235             sw_if_index_set = 1;
3236         else if (unformat (i, "%U/%d", 
3237                            unformat_ip4_address, &v4address, 
3238                            &address_length))
3239             v4_address_set = 1;
3240         else if (unformat (i, "%U/%d", 
3241                            unformat_ip6_address, &v6address, 
3242                            &address_length))
3243             v6_address_set = 1;
3244         else
3245             break;
3246     }
3247
3248     if (sw_if_index_set == 0) {
3249         errmsg ("missing interface name or sw_if_index\n");
3250         return -99;
3251     }
3252     if (v4_address_set && v6_address_set) {
3253         errmsg ("both v4 and v6 addresses set\n");
3254         return -99;
3255     }
3256     if (!v4_address_set && !v6_address_set && !del_all) {
3257         errmsg ("no addresses set\n");
3258         return -99;
3259     }
3260
3261     /* Construct the API message */
3262     M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
3263
3264     mp->sw_if_index = ntohl (sw_if_index);
3265     mp->is_add = is_add;
3266     mp->del_all = del_all;
3267     if (v6_address_set) {
3268         mp->is_ipv6 = 1;
3269         clib_memcpy (mp->address, &v6address, sizeof (v6address));
3270     } else {
3271         clib_memcpy (mp->address, &v4address, sizeof (v4address));
3272     }
3273     mp->address_length = address_length;
3274
3275     /* send it... */
3276     S;
3277
3278     /* Wait for a reply, return good/bad news  */
3279     W;
3280 }
3281
3282 static int api_sw_interface_set_table (vat_main_t * vam)
3283 {
3284     unformat_input_t * i = vam->input;
3285     vl_api_sw_interface_set_table_t *mp;
3286     f64 timeout;
3287     u32 sw_if_index, vrf_id = 0;
3288     u8 sw_if_index_set = 0;
3289     u8 is_ipv6 = 0;
3290     
3291     /* Parse args required to build the message */
3292     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3293         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3294             sw_if_index_set = 1;
3295         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3296             sw_if_index_set = 1;
3297         else if (unformat (i, "vrf %d", &vrf_id))
3298             ;
3299         else if (unformat (i, "ipv6"))
3300             is_ipv6 = 1;
3301         else
3302             break;
3303     }
3304
3305     if (sw_if_index_set == 0) {
3306         errmsg ("missing interface name or sw_if_index\n");
3307         return -99;
3308     }
3309
3310     /* Construct the API message */
3311     M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
3312
3313     mp->sw_if_index = ntohl (sw_if_index);
3314     mp->is_ipv6 = is_ipv6;
3315     mp->vrf_id = ntohl (vrf_id);
3316
3317     /* send it... */
3318     S;
3319
3320     /* Wait for a reply... */
3321     W;
3322 }
3323
3324 static int api_sw_interface_set_vpath (vat_main_t * vam)
3325 {
3326     unformat_input_t * i = vam->input;
3327     vl_api_sw_interface_set_vpath_t *mp;
3328     f64 timeout;
3329     u32 sw_if_index = 0;
3330     u8 sw_if_index_set = 0;
3331     u8 is_enable = 0;
3332     
3333     /* Parse args required to build the message */
3334     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3335         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3336             sw_if_index_set = 1;
3337         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3338             sw_if_index_set = 1;
3339         else if (unformat (i, "enable"))
3340             is_enable = 1;
3341         else if (unformat (i, "disable"))
3342             is_enable = 0;
3343         else
3344             break;
3345     }
3346
3347     if (sw_if_index_set == 0) {
3348         errmsg ("missing interface name or sw_if_index\n");
3349         return -99;
3350     }
3351
3352     /* Construct the API message */
3353     M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
3354
3355     mp->sw_if_index = ntohl (sw_if_index);
3356     mp->enable = is_enable;
3357
3358     /* send it... */
3359     S;
3360
3361     /* Wait for a reply... */
3362     W;
3363 }
3364
3365 static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
3366 {
3367     unformat_input_t * i = vam->input;
3368     vl_api_sw_interface_set_l2_xconnect_t *mp;
3369     f64 timeout;
3370     u32 rx_sw_if_index;
3371     u8 rx_sw_if_index_set = 0;
3372     u32 tx_sw_if_index;
3373     u8 tx_sw_if_index_set = 0;
3374     u8 enable = 1;
3375     
3376     /* Parse args required to build the message */
3377     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3378         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
3379             rx_sw_if_index_set = 1;     
3380         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
3381             tx_sw_if_index_set = 1;
3382         else if (unformat (i, "rx")) {
3383             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3384                 if (unformat (i, "%U", unformat_sw_if_index, vam,
3385                               &rx_sw_if_index))
3386                     rx_sw_if_index_set = 1;
3387             } else
3388                 break;
3389         } else if (unformat (i, "tx")) {
3390             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3391                 if (unformat (i, "%U", unformat_sw_if_index, vam,
3392                               &tx_sw_if_index))
3393                     tx_sw_if_index_set = 1;
3394             } else
3395                 break;
3396         } else if (unformat (i, "enable"))
3397             enable = 1;
3398         else if (unformat (i, "disable")) 
3399             enable = 0;
3400         else
3401             break;
3402     }
3403
3404     if (rx_sw_if_index_set == 0) {
3405         errmsg ("missing rx interface name or rx_sw_if_index\n");
3406         return -99;
3407     }
3408
3409     if (enable && (tx_sw_if_index_set == 0)) {
3410         errmsg ("missing tx interface name or tx_sw_if_index\n");
3411         return -99;
3412     }
3413     
3414     M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
3415
3416     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3417     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
3418     mp->enable = enable;
3419
3420     S; W;
3421     /* NOTREACHED */
3422     return 0;
3423 }
3424
3425 static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
3426 {
3427     unformat_input_t * i = vam->input;
3428     vl_api_sw_interface_set_l2_bridge_t *mp;
3429     f64 timeout;
3430     u32 rx_sw_if_index;
3431     u8 rx_sw_if_index_set = 0;
3432     u32 bd_id;
3433     u8 bd_id_set = 0;
3434     u8 bvi = 0;
3435     u32 shg = 0;
3436     u8 enable = 1;
3437     
3438     /* Parse args required to build the message */
3439     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3440         if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
3441             rx_sw_if_index_set = 1;     
3442         else if (unformat (i, "bd_id %d", &bd_id))
3443             bd_id_set = 1;
3444         else if (unformat (i, "%U", unformat_sw_if_index, vam,
3445                            &rx_sw_if_index))
3446             rx_sw_if_index_set = 1;
3447         else if (unformat (i, "shg %d", &shg)) 
3448             ;
3449         else if (unformat (i, "bvi"))
3450             bvi = 1;
3451         else if (unformat (i, "enable"))
3452             enable = 1;
3453         else if (unformat (i, "disable")) 
3454             enable = 0;
3455         else
3456             break;
3457     }
3458
3459     if (rx_sw_if_index_set == 0) {
3460         errmsg ("missing rx interface name or sw_if_index\n");
3461         return -99;
3462     }
3463
3464     if (enable && (bd_id_set == 0)) {
3465         errmsg ("missing bridge domain\n");
3466         return -99;
3467     }
3468     
3469     M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
3470
3471     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
3472     mp->bd_id = ntohl(bd_id);
3473     mp->shg = (u8)shg;
3474     mp->bvi = bvi;
3475     mp->enable = enable;
3476
3477     S; W;
3478     /* NOTREACHED */
3479     return 0;
3480 }
3481
3482 static int api_bridge_domain_dump (vat_main_t * vam)
3483 {
3484     unformat_input_t * i = vam->input;
3485     vl_api_bridge_domain_dump_t *mp;
3486     f64 timeout;
3487     u32 bd_id = ~0;
3488
3489     /* Parse args required to build the message */
3490     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3491         if (unformat (i, "bd_id %d", &bd_id))
3492             ;
3493         else
3494             break;
3495     }
3496
3497     M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
3498     mp->bd_id = ntohl(bd_id);
3499     S;
3500
3501     /* Use a control ping for synchronization */
3502     {
3503         vl_api_control_ping_t * mp;
3504         M(CONTROL_PING, control_ping);
3505         S;
3506     }
3507
3508     W;
3509     /* NOTREACHED */
3510     return 0;
3511 }
3512
3513 static int api_bridge_domain_add_del (vat_main_t * vam)
3514 {
3515     unformat_input_t * i = vam->input;
3516     vl_api_bridge_domain_add_del_t *mp;
3517     f64 timeout;
3518     u32 bd_id = ~0;
3519     u8 is_add = 1;
3520     u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
3521
3522     /* Parse args required to build the message */
3523     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3524         if (unformat (i, "bd_id %d", &bd_id))
3525             ;
3526         else if (unformat (i, "flood %d", &flood))
3527              ;
3528         else if (unformat (i, "uu-flood %d", &uu_flood))
3529              ;
3530         else if (unformat (i, "forward %d", &forward))
3531              ;
3532         else if (unformat (i, "learn %d", &learn))
3533              ;
3534         else if (unformat (i, "arp-term %d", &arp_term))
3535              ;
3536         else if (unformat (i, "del")) {
3537              is_add = 0;
3538              flood = uu_flood = forward = learn = 0;
3539         }
3540         else
3541             break;
3542     }
3543
3544     if (bd_id == ~0) {
3545         errmsg ("missing bridge domain\n");
3546         return -99;
3547     }
3548
3549     M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
3550
3551     mp->bd_id = ntohl(bd_id);
3552     mp->flood = flood;
3553     mp->uu_flood = uu_flood;
3554     mp->forward = forward;
3555     mp->learn = learn;
3556     mp->arp_term = arp_term;
3557     mp->is_add = is_add;
3558
3559     S; W;
3560     /* NOTREACHED */
3561     return 0;
3562 }
3563
3564 static int api_l2fib_add_del (vat_main_t * vam)
3565 {
3566     unformat_input_t * i = vam->input;
3567     vl_api_l2fib_add_del_t *mp;
3568     f64 timeout;
3569     u64 mac = 0;
3570     u8 mac_set = 0;
3571     u32 bd_id;
3572     u8 bd_id_set = 0;
3573     u32 sw_if_index;
3574     u8 sw_if_index_set = 0;
3575     u8 is_add = 1;
3576     u8 static_mac = 0;
3577     u8 filter_mac = 0;
3578
3579     /* Parse args required to build the message */
3580     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3581         if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
3582             mac_set = 1;
3583         else if (unformat (i, "bd_id %d", &bd_id))
3584             bd_id_set = 1;
3585         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3586             sw_if_index_set = 1;        
3587         else if (unformat (i, "sw_if")) {
3588             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3589                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3590                     sw_if_index_set = 1;
3591             } else
3592                 break;
3593         } else if (unformat (i, "static"))
3594                 static_mac = 1;
3595         else if (unformat (i, "filter")) {
3596                 filter_mac = 1;
3597                 static_mac = 1;
3598         } else if (unformat (i, "del"))
3599                 is_add = 0;
3600         else
3601             break;
3602     }
3603
3604     if (mac_set == 0) {
3605         errmsg ("missing mac address\n");
3606         return -99;
3607     }
3608
3609     if (bd_id_set == 0) {
3610         errmsg ("missing bridge domain\n");
3611         return -99;
3612     }
3613
3614     if (is_add && (sw_if_index_set == 0)) {
3615         errmsg ("missing interface name or sw_if_index\n");
3616         return -99;
3617     }
3618
3619     M(L2FIB_ADD_DEL, l2fib_add_del);
3620
3621     mp->mac = mac;
3622     mp->bd_id = ntohl(bd_id);
3623     mp->is_add = is_add;
3624
3625     if (is_add) {
3626         mp->sw_if_index = ntohl(sw_if_index);
3627         mp->static_mac = static_mac;
3628         mp->filter_mac = filter_mac;
3629     }
3630     
3631     S; W;
3632     /* NOTREACHED */
3633     return 0;
3634 }
3635
3636 static int api_l2_flags (vat_main_t * vam)
3637 {
3638     unformat_input_t * i = vam->input;
3639     vl_api_l2_flags_t *mp;
3640     f64 timeout;
3641     u32 sw_if_index;
3642     u32 feature_bitmap = 0;
3643     u8 sw_if_index_set = 0;
3644
3645     /* Parse args required to build the message */
3646     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3647         if (unformat (i, "sw_if_index %d", &sw_if_index))
3648             sw_if_index_set = 1;        
3649         else if (unformat (i, "sw_if")) {
3650             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3651                 if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3652                     sw_if_index_set = 1;
3653             } else
3654                 break;
3655         } else if (unformat (i, "learn"))
3656             feature_bitmap |= L2INPUT_FEAT_LEARN;
3657         else if (unformat (i, "forward"))
3658             feature_bitmap |= L2INPUT_FEAT_FWD;
3659         else if (unformat (i, "flood"))
3660             feature_bitmap |= L2INPUT_FEAT_FLOOD;
3661         else if (unformat (i, "uu-flood"))
3662             feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
3663         else
3664             break;
3665     }
3666
3667     if (sw_if_index_set == 0) {
3668         errmsg ("missing interface name or sw_if_index\n");
3669         return -99;
3670     }
3671
3672     M(L2_FLAGS, l2_flags);
3673
3674     mp->sw_if_index = ntohl(sw_if_index);
3675     mp->feature_bitmap = ntohl(feature_bitmap);
3676
3677     S; W;
3678     /* NOTREACHED */
3679     return 0;
3680 }
3681
3682 static int api_bridge_flags (vat_main_t * vam)
3683 {
3684     unformat_input_t * i = vam->input;
3685     vl_api_bridge_flags_t *mp;
3686     f64 timeout;
3687     u32 bd_id;
3688     u8 bd_id_set = 0;
3689     u8 is_set = 1;
3690     u32 flags = 0;
3691
3692     /* Parse args required to build the message */
3693     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3694         if (unformat (i, "bd_id %d", &bd_id))
3695             bd_id_set = 1;
3696         else if (unformat (i, "learn"))
3697             flags |= L2_LEARN;
3698         else if (unformat (i, "forward"))
3699             flags |= L2_FWD;
3700         else if (unformat (i, "flood"))
3701             flags |= L2_FLOOD;
3702         else if (unformat (i, "uu-flood"))
3703             flags |= L2_UU_FLOOD;
3704         else if (unformat (i, "arp-term"))
3705             flags |= L2_ARP_TERM;
3706         else if (unformat (i, "off"))
3707             is_set = 0;
3708         else if (unformat (i, "disable"))
3709             is_set = 0;
3710         else
3711             break;
3712     }
3713
3714     if (bd_id_set == 0) {
3715         errmsg ("missing bridge domain\n");
3716         return -99;
3717     }
3718
3719     M(BRIDGE_FLAGS, bridge_flags);
3720
3721     mp->bd_id = ntohl(bd_id);
3722     mp->feature_bitmap = ntohl(flags);
3723     mp->is_set = is_set;
3724
3725     S; W;
3726     /* NOTREACHED */
3727     return 0;
3728 }
3729
3730 static int api_bd_ip_mac_add_del (vat_main_t * vam)
3731 {
3732     unformat_input_t * i = vam->input;
3733     vl_api_bd_ip_mac_add_del_t *mp;
3734     f64 timeout;
3735     u32 bd_id;
3736     u8 is_ipv6 = 0;
3737     u8 is_add = 1;
3738     u8 bd_id_set = 0;
3739     u8 ip_set = 0;
3740     u8 mac_set = 0;
3741     ip4_address_t v4addr;
3742     ip6_address_t v6addr;
3743     u8 macaddr[6];
3744     
3745
3746     /* Parse args required to build the message */
3747     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3748         if (unformat (i, "bd_id %d", &bd_id)) {
3749             bd_id_set++;
3750         } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
3751             ip_set++;
3752         } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
3753             ip_set++;
3754             is_ipv6++;
3755         } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
3756             mac_set++;
3757         } else if (unformat (i, "del"))
3758             is_add = 0;
3759         else
3760             break;
3761     }
3762
3763     if (bd_id_set == 0) {
3764         errmsg ("missing bridge domain\n");
3765         return -99;
3766     } else if (ip_set == 0) {
3767         errmsg ("missing IP address\n");
3768         return -99;
3769     } else if (mac_set == 0) {
3770         errmsg ("missing MAC address\n");
3771         return -99;
3772     }
3773
3774     M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
3775
3776     mp->bd_id = ntohl(bd_id);
3777     mp->is_ipv6 = is_ipv6;
3778     mp->is_add = is_add;
3779     if (is_ipv6)
3780          clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
3781     else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
3782     clib_memcpy (mp->mac_address, macaddr, 6);
3783     S; W;
3784     /* NOTREACHED */
3785     return 0;
3786 }
3787
3788 static int api_tap_connect (vat_main_t * vam)
3789 {
3790     unformat_input_t * i = vam->input;
3791     vl_api_tap_connect_t *mp;
3792     f64 timeout;
3793     u8 mac_address[6];
3794     u8 random_mac = 1;
3795     u8 name_set = 0;
3796     u8 * tap_name;
3797
3798     memset (mac_address, 0, sizeof (mac_address));
3799     
3800     /* Parse args required to build the message */
3801     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3802         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3803             random_mac = 0;
3804         }
3805         else if (unformat (i, "random-mac"))
3806             random_mac = 1;
3807         else if (unformat (i, "tapname %s", &tap_name))
3808             name_set = 1;
3809         else
3810             break;
3811     }
3812
3813     if (name_set == 0) {
3814         errmsg ("missing tap name\n");
3815         return -99;
3816     }
3817     if (vec_len (tap_name) > 63) {
3818         errmsg ("tap name too long\n");
3819     }
3820     vec_add1 (tap_name, 0);
3821         
3822     /* Construct the API message */
3823     M(TAP_CONNECT, tap_connect);
3824
3825     mp->use_random_mac = random_mac;
3826     clib_memcpy (mp->mac_address, mac_address, 6);
3827     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3828     vec_free (tap_name);
3829
3830     /* send it... */
3831     S;
3832
3833     /* Wait for a reply... */
3834     W;
3835 }
3836
3837 static int api_tap_modify (vat_main_t * vam)
3838 {
3839     unformat_input_t * i = vam->input;
3840     vl_api_tap_modify_t *mp;
3841     f64 timeout;
3842     u8 mac_address[6];
3843     u8 random_mac = 1;
3844     u8 name_set = 0;
3845     u8 * tap_name;
3846     u32 sw_if_index = ~0;
3847     u8 sw_if_index_set = 0;
3848
3849     memset (mac_address, 0, sizeof (mac_address));
3850     
3851     /* Parse args required to build the message */
3852     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3853         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3854             sw_if_index_set = 1;
3855         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3856             sw_if_index_set = 1;
3857         else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
3858             random_mac = 0;
3859         }
3860         else if (unformat (i, "random-mac"))
3861             random_mac = 1;
3862         else if (unformat (i, "tapname %s", &tap_name))
3863             name_set = 1;
3864         else
3865             break;
3866     }
3867
3868     if (sw_if_index_set == 0) {
3869         errmsg ("missing vpp interface name");
3870         return -99;
3871     }
3872     if (name_set == 0) {
3873         errmsg ("missing tap name\n");
3874         return -99;
3875     }
3876     if (vec_len (tap_name) > 63) {
3877         errmsg ("tap name too long\n");
3878     }
3879     vec_add1 (tap_name, 0);
3880         
3881     /* Construct the API message */
3882     M(TAP_MODIFY, tap_modify);
3883
3884     mp->use_random_mac = random_mac;
3885     mp->sw_if_index = ntohl(sw_if_index);
3886     clib_memcpy (mp->mac_address, mac_address, 6);
3887     clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
3888     vec_free (tap_name);
3889
3890     /* send it... */
3891     S;
3892
3893     /* Wait for a reply... */
3894     W;
3895 }
3896
3897 static int api_tap_delete (vat_main_t * vam)
3898 {
3899     unformat_input_t * i = vam->input;
3900     vl_api_tap_delete_t *mp;
3901     f64 timeout;
3902     u32 sw_if_index = ~0;
3903     u8 sw_if_index_set = 0;
3904
3905     /* Parse args required to build the message */
3906     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3907         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3908             sw_if_index_set = 1;
3909         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3910             sw_if_index_set = 1;
3911         else
3912             break;
3913     }
3914
3915     if (sw_if_index_set == 0) {
3916         errmsg ("missing vpp interface name");
3917         return -99;
3918     }
3919         
3920     /* Construct the API message */
3921     M(TAP_DELETE, tap_delete);
3922
3923     mp->sw_if_index = ntohl(sw_if_index);
3924
3925     /* send it... */
3926     S;
3927
3928     /* Wait for a reply... */
3929     W;
3930 }
3931
3932 static int api_ip_add_del_route (vat_main_t * vam)
3933 {
3934     unformat_input_t * i = vam->input;
3935     vl_api_ip_add_del_route_t *mp;
3936     f64 timeout;
3937     u32 sw_if_index = 0, vrf_id = 0;
3938     u8 sw_if_index_set = 0;
3939     u8 is_ipv6 = 0;
3940     u8 is_local = 0, is_drop = 0;
3941     u8 create_vrf_if_needed = 0;
3942     u8 is_add = 1;
3943     u8 next_hop_weight = 1;
3944     u8 not_last = 0;
3945     u8 is_multipath = 0;
3946     u8 address_set = 0;
3947     u8 address_length_set = 0;
3948     u32 lookup_in_vrf = 0;
3949     u32 resolve_attempts = 0;
3950     u32 dst_address_length = 0;
3951     u8 next_hop_set = 0;
3952     ip4_address_t v4_dst_address, v4_next_hop_address;
3953     ip6_address_t v6_dst_address, v6_next_hop_address;
3954     int count = 1;
3955     int j;
3956     f64 before = 0;
3957     u32 random_add_del = 0;
3958     u32 * random_vector = 0;
3959     uword * random_hash;
3960     u32 random_seed = 0xdeaddabe;
3961     u32 classify_table_index = ~0;
3962     u8 is_classify = 0;
3963     
3964     /* Parse args required to build the message */
3965     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
3966         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
3967             sw_if_index_set = 1;
3968         else if (unformat (i, "sw_if_index %d", &sw_if_index))
3969             sw_if_index_set = 1;
3970         else if (unformat (i, "%U", unformat_ip4_address,
3971                            &v4_dst_address)) {
3972             address_set = 1;
3973             is_ipv6 = 0;
3974         }
3975         else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
3976             address_set = 1;
3977             is_ipv6 = 1;
3978         }
3979         else if (unformat (i, "/%d", &dst_address_length)) {
3980             address_length_set = 1;
3981         }
3982         
3983         else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address, 
3984                                            &v4_next_hop_address)) {
3985             next_hop_set = 1;
3986         }
3987         else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address, 
3988                                            &v6_next_hop_address)) {
3989             next_hop_set = 1;
3990         }
3991         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
3992             ;
3993         else if (unformat (i, "weight %d", &next_hop_weight))
3994             ;
3995         else if (unformat (i, "drop")) {
3996             is_drop = 1;
3997         } else if (unformat (i, "local")) {
3998             is_local = 1;
3999         } else if (unformat (i, "classify %d", &classify_table_index)) {
4000             is_classify = 1;
4001         } else if (unformat (i, "del"))
4002             is_add = 0;
4003         else if (unformat (i, "add"))
4004             is_add = 1;
4005         else if (unformat (i, "not-last"))
4006             not_last = 1;
4007         else if (unformat (i, "multipath"))
4008             is_multipath = 1;
4009         else if (unformat (i, "vrf %d", &vrf_id))
4010             ;
4011         else if (unformat (i, "create-vrf"))
4012             create_vrf_if_needed = 1;
4013         else if (unformat (i, "count %d", &count))
4014             ;
4015         else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
4016             ;
4017         else if (unformat (i, "random"))
4018             random_add_del = 1;
4019         else if (unformat (i, "seed %d", &random_seed))
4020             ;
4021         else {
4022             clib_warning ("parse error '%U'", format_unformat_error, i);
4023             return -99;
4024         }
4025     }
4026
4027     if (resolve_attempts > 0 && sw_if_index_set == 0) {
4028         errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
4029         return -99;
4030     }
4031     
4032     if (!next_hop_set && !is_drop && !is_local && !is_classify) {
4033         errmsg ("next hop / local / drop / classify not set\n");
4034         return -99;
4035     }
4036
4037     if (address_set == 0) {
4038         errmsg ("missing addresses\n");
4039         return -99;
4040     }
4041
4042     if (address_length_set == 0) {
4043         errmsg ("missing address length\n");
4044         return -99;
4045     }
4046     
4047     /* Generate a pile of unique, random routes */
4048     if (random_add_del) {
4049         u32 this_random_address;
4050         random_hash = hash_create (count, sizeof(uword));
4051
4052         hash_set (random_hash, v4_next_hop_address.as_u32, 1);
4053         for (j = 0; j <= count; j++) {
4054             do {
4055                 this_random_address = random_u32 (&random_seed);
4056                 this_random_address = 
4057                     clib_host_to_net_u32 (this_random_address);
4058             } while (hash_get (random_hash, this_random_address));
4059             vec_add1 (random_vector, this_random_address);
4060             hash_set (random_hash, this_random_address, 1);
4061         }
4062         hash_free (random_hash);
4063         v4_dst_address.as_u32 = random_vector[0];
4064     }
4065
4066     if (count > 1) {
4067         /* Turn on async mode */
4068         vam->async_mode = 1;
4069         vam->async_errors = 0;
4070         before = vat_time_now(vam);
4071     }
4072
4073     for (j = 0; j < count; j++) {
4074         /* Construct the API message */
4075         M(IP_ADD_DEL_ROUTE, ip_add_del_route);
4076     
4077         mp->next_hop_sw_if_index = ntohl (sw_if_index);
4078         mp->vrf_id = ntohl (vrf_id);
4079         if (resolve_attempts > 0) {
4080             mp->resolve_attempts = ntohl (resolve_attempts);
4081             mp->resolve_if_needed = 1;
4082         }
4083         mp->create_vrf_if_needed = create_vrf_if_needed;
4084     
4085         mp->is_add = is_add;
4086         mp->is_drop = is_drop;
4087         mp->is_ipv6 = is_ipv6;
4088         mp->is_local = is_local;
4089         mp->is_classify = is_classify;
4090         mp->is_multipath = is_multipath;
4091         mp->not_last = not_last;
4092         mp->next_hop_weight = next_hop_weight;
4093         mp->dst_address_length = dst_address_length;
4094         mp->lookup_in_vrf = ntohl(lookup_in_vrf);
4095         mp->classify_table_index = ntohl(classify_table_index);
4096
4097         if (is_ipv6){
4098             clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
4099             if (next_hop_set)
4100                 clib_memcpy (mp->next_hop_address, &v6_next_hop_address, 
4101                         sizeof (v6_next_hop_address));
4102             increment_v6_address (&v6_dst_address);
4103         } else {
4104             clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
4105             if (next_hop_set)
4106                 clib_memcpy (mp->next_hop_address, &v4_next_hop_address, 
4107                         sizeof (v4_next_hop_address));
4108             if (random_add_del)
4109                 v4_dst_address.as_u32 = random_vector[j+1];
4110             else
4111                 increment_v4_address (&v4_dst_address);
4112         }
4113         /* send it... */
4114         S;
4115     }
4116
4117     /* When testing multiple add/del ops, use a control-ping to sync */
4118     if (count > 1) {
4119         vl_api_control_ping_t * mp;
4120         f64 after;
4121
4122         /* Shut off async mode */
4123         vam->async_mode = 0;
4124
4125         M(CONTROL_PING, control_ping);
4126         S;
4127
4128         timeout = vat_time_now(vam) + 1.0;
4129         while (vat_time_now (vam) < timeout)
4130             if (vam->result_ready == 1)
4131                 goto out;
4132         vam->retval = -99;
4133
4134     out:
4135         if (vam->retval == -99)
4136             errmsg ("timeout\n");
4137
4138         if (vam->async_errors > 0) {
4139             errmsg ("%d asynchronous errors\n", vam->async_errors);
4140             vam->retval = -98;
4141         }
4142         vam->async_errors = 0;
4143         after = vat_time_now(vam);
4144
4145         fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4146                 count, after - before, count / (after - before));
4147     } else {
4148         /* Wait for a reply... */
4149         W;
4150     }
4151
4152     /* Return the good/bad news */
4153     return (vam->retval);
4154 }
4155
4156 static int api_proxy_arp_add_del (vat_main_t * vam)
4157 {
4158     unformat_input_t * i = vam->input;
4159     vl_api_proxy_arp_add_del_t *mp;
4160     f64 timeout;
4161     u32 vrf_id = 0;
4162     u8 is_add = 1;
4163     ip4_address_t lo, hi;
4164     u8 range_set = 0;
4165
4166     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4167         if (unformat (i, "vrf %d", &vrf_id))
4168             ;
4169         else if (unformat (i, "%U - %U", unformat_ip4_address, &lo, 
4170                            unformat_ip4_address, &hi))
4171             range_set = 1;
4172         else if (unformat (i, "del"))
4173             is_add = 0;
4174         else {
4175             clib_warning ("parse error '%U'", format_unformat_error, i);
4176             return -99;
4177         }
4178     }
4179     
4180     if (range_set == 0) {
4181         errmsg ("address range not set\n");
4182         return -99;
4183     }
4184
4185     M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
4186
4187     mp->vrf_id = ntohl(vrf_id);
4188     mp->is_add = is_add;
4189     clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
4190     clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
4191
4192     S; W;
4193     /* NOTREACHED */
4194     return 0;
4195 }
4196
4197 static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
4198 {
4199     unformat_input_t * i = vam->input;
4200     vl_api_proxy_arp_intfc_enable_disable_t *mp;
4201     f64 timeout;
4202     u32 sw_if_index;
4203     u8 enable = 1;
4204     u8 sw_if_index_set = 0;
4205
4206     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4207         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4208             sw_if_index_set = 1;
4209         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4210             sw_if_index_set = 1;
4211         else if (unformat (i, "enable"))
4212             enable = 1;
4213         else if (unformat (i, "disable"))
4214             enable = 0;
4215         else {
4216             clib_warning ("parse error '%U'", format_unformat_error, i);
4217             return -99;
4218         }
4219     }
4220     
4221     if (sw_if_index_set == 0) {
4222         errmsg ("missing interface name or sw_if_index\n");
4223         return -99;
4224     }
4225
4226     M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
4227
4228     mp->sw_if_index = ntohl(sw_if_index);
4229     mp->enable_disable = enable;
4230
4231     S; W;
4232     /* NOTREACHED */
4233     return 0;
4234 }
4235
4236 static int api_mpls_add_del_decap (vat_main_t * vam)
4237 {
4238     unformat_input_t * i = vam->input;
4239     vl_api_mpls_add_del_decap_t *mp;
4240     f64 timeout;
4241     u32 rx_vrf_id = 0;
4242     u32 tx_vrf_id = 0;
4243     u32 label = 0;
4244     u8 is_add = 1;
4245     u8 s_bit = 1;
4246     u32 next_index = 1;
4247
4248     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4249         if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4250             ;
4251         else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
4252             ;
4253         else if (unformat (i, "label %d", &label))
4254             ;
4255         else if (unformat (i, "next-index %d", &next_index))
4256             ;
4257         else if (unformat (i, "del"))
4258             is_add = 0;
4259         else if (unformat (i, "s-bit-clear"))
4260             s_bit = 0;
4261         else {
4262             clib_warning ("parse error '%U'", format_unformat_error, i);
4263             return -99;
4264         }
4265     }
4266     
4267     M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
4268
4269     mp->rx_vrf_id = ntohl(rx_vrf_id);
4270     mp->tx_vrf_id = ntohl(tx_vrf_id);
4271     mp->label = ntohl(label);
4272     mp->next_index = ntohl(next_index);
4273     mp->s_bit = s_bit;
4274     mp->is_add = is_add;
4275
4276     S; W;
4277     /* NOTREACHED */
4278     return 0;
4279 }
4280
4281 static int api_mpls_add_del_encap (vat_main_t * vam)
4282 {
4283     unformat_input_t * i = vam->input;
4284     vl_api_mpls_add_del_encap_t *mp;
4285     f64 timeout;
4286     u32 vrf_id = 0;
4287     u32 *labels = 0;
4288     u32 label;
4289     ip4_address_t dst_address;
4290     u8 is_add = 1;
4291
4292     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4293         if (unformat (i, "vrf %d", &vrf_id))
4294             ;
4295         else if (unformat (i, "label %d", &label))
4296             vec_add1 (labels, ntohl(label));
4297         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4298             ;
4299         else if (unformat (i, "del"))
4300             is_add = 0;
4301         else {
4302             clib_warning ("parse error '%U'", format_unformat_error, i);
4303             return -99;
4304         }
4305     }
4306
4307     if (vec_len (labels) == 0) {
4308         errmsg ("missing encap label stack\n");
4309         return -99;
4310     }
4311     
4312     M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap, 
4313        sizeof (u32) * vec_len (labels));
4314
4315     mp->vrf_id = ntohl(vrf_id);
4316     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4317     mp->is_add = is_add;
4318     mp->nlabels = vec_len (labels);
4319     clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
4320
4321     vec_free(labels);
4322
4323     S; W;
4324     /* NOTREACHED */
4325     return 0;
4326 }
4327
4328 static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
4329 {
4330     unformat_input_t * i = vam->input;
4331     vl_api_mpls_gre_add_del_tunnel_t *mp;
4332     f64 timeout;
4333     u32 inner_vrf_id = 0;
4334     u32 outer_vrf_id = 0;
4335     ip4_address_t src_address;
4336     ip4_address_t dst_address;
4337     ip4_address_t intfc_address;
4338     u32 tmp;
4339     u8 intfc_address_length = 0;
4340     u8 is_add = 1;
4341     u8 l2_only = 0;
4342     
4343     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4344         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4345             ;
4346         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4347             ;
4348         else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
4349             ;
4350         else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
4351             ;
4352         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4353                            &intfc_address, &tmp))
4354             intfc_address_length = tmp;
4355         else if (unformat (i, "l2-only"))
4356             l2_only = 1;
4357         else if (unformat (i, "del"))
4358             is_add = 0;
4359         else {
4360             clib_warning ("parse error '%U'", format_unformat_error, i);
4361             return -99;
4362         }
4363     }
4364     
4365     M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
4366
4367     mp->inner_vrf_id = ntohl(inner_vrf_id);
4368     mp->outer_vrf_id = ntohl(outer_vrf_id);
4369     clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
4370     clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
4371     clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
4372     mp->intfc_address_length = intfc_address_length;
4373     mp->l2_only = l2_only;
4374     mp->is_add = is_add;
4375
4376     S; W;
4377     /* NOTREACHED */
4378     return 0;
4379 }
4380
4381 static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
4382 {
4383     unformat_input_t * i = vam->input;
4384     vl_api_mpls_ethernet_add_del_tunnel_t *mp;
4385     f64 timeout;
4386     u32 inner_vrf_id = 0;
4387     ip4_address_t intfc_address;
4388     u8 dst_mac_address[6];
4389     int dst_set = 1;
4390     u32 tmp;
4391     u8 intfc_address_length = 0;
4392     u8 is_add = 1;
4393     u8 l2_only = 0;
4394     u32 tx_sw_if_index;
4395     int tx_sw_if_index_set = 0;
4396     
4397     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4398         if (unformat (i, "vrf %d", &inner_vrf_id))
4399             ;
4400         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4401                            &intfc_address, &tmp))
4402             intfc_address_length = tmp;
4403         else if (unformat (i, "%U", 
4404                            unformat_sw_if_index, vam, &tx_sw_if_index))
4405             tx_sw_if_index_set = 1;
4406         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4407             tx_sw_if_index_set = 1;
4408         else if (unformat (i, "dst %U", unformat_ethernet_address, 
4409                            dst_mac_address))
4410             dst_set = 1;
4411         else if (unformat (i, "l2-only"))
4412             l2_only = 1;
4413         else if (unformat (i, "del"))
4414             is_add = 0;
4415         else {
4416             clib_warning ("parse error '%U'", format_unformat_error, i);
4417             return -99;
4418         }
4419     }
4420
4421     if (!dst_set) {
4422         errmsg ("dst (mac address) not set\n");
4423         return -99;
4424     }
4425     if (!tx_sw_if_index_set) {
4426         errmsg ("tx-intfc not set\n");
4427         return -99;
4428     }
4429     
4430     M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
4431
4432     mp->vrf_id = ntohl(inner_vrf_id);
4433     clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
4434     mp->adj_address_length = intfc_address_length;
4435     clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
4436     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
4437     mp->l2_only = l2_only;
4438     mp->is_add = is_add;
4439
4440     S; W;
4441     /* NOTREACHED */
4442     return 0;
4443 }
4444
4445 static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
4446 {
4447     unformat_input_t * i = vam->input;
4448     vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
4449     f64 timeout;
4450     u32 inner_vrf_id = 0;
4451     u32 outer_vrf_id = 0;
4452     ip4_address_t adj_address;
4453     int adj_address_set = 0;
4454     ip4_address_t next_hop_address;
4455     int next_hop_address_set = 0;
4456     u32 tmp;
4457     u8 adj_address_length = 0;
4458     u8 l2_only = 0;
4459     u8 is_add = 1;
4460     u32 resolve_attempts = 5;
4461     u8 resolve_if_needed = 1;
4462     
4463     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4464         if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
4465             ;
4466         else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
4467             ;
4468         else if (unformat (i, "adj %U/%d", unformat_ip4_address,
4469                            &adj_address, &tmp)) {
4470             adj_address_length = tmp;
4471             adj_address_set = 1;
4472         }
4473         else if (unformat (i, "next-hop %U", unformat_ip4_address,
4474                            &next_hop_address))
4475             next_hop_address_set = 1;
4476         else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
4477             ;
4478         else if (unformat (i, "resolve-if-needed %d", &tmp))
4479             resolve_if_needed = tmp;
4480         else if (unformat (i, "l2-only"))
4481             l2_only = 1;
4482         else if (unformat (i, "del"))
4483             is_add = 0;
4484         else {
4485             clib_warning ("parse error '%U'", format_unformat_error, i);
4486             return -99;
4487         }
4488     }
4489     
4490     if (!adj_address_set) {
4491         errmsg ("adjacency address/mask not set\n");
4492         return -99;
4493     }
4494     if (!next_hop_address_set) {
4495         errmsg ("ip4 next hop address (in outer fib) not set\n");
4496         return -99;
4497     }
4498     
4499     M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
4500     
4501     mp->inner_vrf_id = ntohl(inner_vrf_id);
4502     mp->outer_vrf_id = ntohl(outer_vrf_id);
4503     mp->resolve_attempts = ntohl(resolve_attempts);
4504     mp->resolve_if_needed = resolve_if_needed;
4505     mp->is_add = is_add;
4506     mp->l2_only = l2_only;
4507     clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
4508     mp->adj_address_length = adj_address_length;
4509     clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address, 
4510             sizeof (next_hop_address));
4511
4512     S; W;
4513     /* NOTREACHED */
4514     return 0;
4515 }
4516
4517 static int api_sw_interface_set_unnumbered (vat_main_t * vam)
4518 {
4519     unformat_input_t * i = vam->input;
4520     vl_api_sw_interface_set_unnumbered_t *mp;
4521     f64 timeout;
4522     u32 sw_if_index;
4523     u32 unnum_sw_index;
4524     u8  is_add = 1;
4525     u8 sw_if_index_set = 0;
4526
4527     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4528         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4529             sw_if_index_set = 1;
4530         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4531             sw_if_index_set = 1;
4532         else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
4533             ;
4534         else if (unformat (i, "del"))
4535             is_add = 0;
4536         else {
4537             clib_warning ("parse error '%U'", format_unformat_error, i);
4538             return -99;
4539         }
4540     }
4541     
4542     if (sw_if_index_set == 0) {
4543         errmsg ("missing interface name or sw_if_index\n");
4544         return -99;
4545     }
4546
4547     M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
4548
4549     mp->sw_if_index = ntohl(sw_if_index);
4550     mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
4551     mp->is_add = is_add;
4552
4553     S; W;
4554     /* NOTREACHED */
4555     return 0;
4556 }
4557
4558 static int api_ip_neighbor_add_del (vat_main_t * vam)
4559 {
4560     unformat_input_t * i = vam->input;
4561     vl_api_ip_neighbor_add_del_t *mp;
4562     f64 timeout;
4563     u32 sw_if_index;
4564     u8 sw_if_index_set = 0;
4565     u32 vrf_id = 0;
4566     u8 is_add = 1;
4567     u8 is_static = 0;
4568     u8 mac_address[6];
4569     u8 mac_set = 0;
4570     u8 v4_address_set = 0;
4571     u8 v6_address_set = 0;
4572     ip4_address_t v4address;
4573     ip6_address_t v6address;
4574     
4575     memset (mac_address, 0, sizeof (mac_address));
4576     
4577     /* Parse args required to build the message */
4578     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4579         if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
4580             mac_set = 1;
4581         }
4582         else if (unformat (i, "del"))
4583             is_add = 0;
4584         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4585             sw_if_index_set = 1;
4586         else if (unformat (i, "sw_if_index %d", &sw_if_index))
4587             sw_if_index_set = 1;
4588         else if (unformat (i, "is_static"))
4589             is_static = 1;
4590         else if (unformat (i, "vrf %d", &vrf_id))
4591             ;
4592         else if (unformat (i, "dst %U", 
4593                            unformat_ip4_address, &v4address))
4594                 v4_address_set = 1;
4595         else if (unformat (i, "dst %U", 
4596                            unformat_ip6_address, &v6address))
4597                 v6_address_set = 1;
4598         else {
4599             clib_warning ("parse error '%U'", format_unformat_error, i);
4600             return -99;
4601         }
4602     }
4603
4604     if (sw_if_index_set == 0) {
4605         errmsg ("missing interface name or sw_if_index\n");
4606         return -99;
4607     }
4608     if (v4_address_set && v6_address_set) {
4609         errmsg ("both v4 and v6 addresses set\n");
4610         return -99;
4611     }
4612     if (!v4_address_set && !v6_address_set) {
4613         errmsg ("no addresses set\n");
4614         return -99;
4615     }
4616
4617     /* Construct the API message */
4618     M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
4619
4620     mp->sw_if_index = ntohl (sw_if_index);
4621     mp->is_add = is_add;
4622     mp->vrf_id = ntohl (vrf_id);
4623     mp->is_static = is_static;
4624     if (mac_set)
4625         clib_memcpy (mp->mac_address, mac_address, 6);
4626     if (v6_address_set) {
4627         mp->is_ipv6 = 1;
4628         clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
4629     } else {
4630         /* mp->is_ipv6 = 0; via memset in M macro above */
4631         clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
4632     }
4633
4634     /* send it... */
4635     S;
4636
4637     /* Wait for a reply, return good/bad news  */
4638     W;
4639
4640     /* NOTREACHED */
4641     return 0;
4642 }
4643
4644 static int api_reset_vrf (vat_main_t * vam)
4645 {
4646     unformat_input_t * i = vam->input;
4647     vl_api_reset_vrf_t *mp;
4648     f64 timeout;
4649     u32 vrf_id = 0;
4650     u8 is_ipv6 = 0;
4651     u8 vrf_id_set = 0;
4652
4653     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4654         if (unformat (i, "vrf %d", &vrf_id))
4655             vrf_id_set = 1;
4656         else if (unformat (i, "ipv6"))
4657             is_ipv6 = 1;
4658         else {
4659             clib_warning ("parse error '%U'", format_unformat_error, i);
4660             return -99;
4661         }
4662     }
4663
4664     if (vrf_id_set == 0) {
4665         errmsg ("missing vrf id\n");
4666         return -99;
4667     }
4668     
4669     M(RESET_VRF, reset_vrf);
4670
4671     mp->vrf_id = ntohl(vrf_id);
4672     mp->is_ipv6 = is_ipv6;
4673
4674     S; W;
4675     /* NOTREACHED */
4676     return 0;
4677 }
4678
4679 static int api_create_vlan_subif (vat_main_t * vam)
4680 {
4681     unformat_input_t * i = vam->input;
4682     vl_api_create_vlan_subif_t *mp;
4683     f64 timeout;
4684     u32 sw_if_index;
4685     u8  sw_if_index_set = 0;
4686     u32 vlan_id;
4687     u8  vlan_id_set = 0;
4688
4689     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4690         if (unformat (i, "sw_if_index %d", &sw_if_index))
4691             sw_if_index_set = 1;
4692         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4693             sw_if_index_set = 1;
4694         else if (unformat (i, "vlan %d", &vlan_id))
4695             vlan_id_set = 1;
4696         else {
4697             clib_warning ("parse error '%U'", format_unformat_error, i);
4698             return -99;
4699         }
4700     }
4701     
4702     if (sw_if_index_set == 0) {
4703         errmsg ("missing interface name or sw_if_index\n");
4704         return -99;
4705     }
4706
4707     if (vlan_id_set == 0) {
4708         errmsg ("missing vlan_id\n");
4709         return -99;
4710     }
4711     M(CREATE_VLAN_SUBIF, create_vlan_subif);
4712
4713     mp->sw_if_index = ntohl(sw_if_index);
4714     mp->vlan_id = ntohl(vlan_id);
4715
4716     S; W;
4717     /* NOTREACHED */
4718     return 0;
4719 }
4720
4721 #define foreach_create_subif_bit                \
4722 _(no_tags)                                      \
4723 _(one_tag)                                      \
4724 _(two_tags)                                     \
4725 _(dot1ad)                                       \
4726 _(exact_match)                                  \
4727 _(default_sub)                                  \
4728 _(outer_vlan_id_any)                            \
4729 _(inner_vlan_id_any)
4730
4731 static int api_create_subif (vat_main_t * vam)
4732 {
4733     unformat_input_t * i = vam->input;
4734     vl_api_create_subif_t *mp;
4735     f64 timeout;
4736     u32 sw_if_index;
4737     u8  sw_if_index_set = 0;
4738     u32 sub_id;
4739     u8  sub_id_set = 0;
4740     u32 no_tags = 0;
4741     u32 one_tag = 0;
4742     u32 two_tags = 0;
4743     u32 dot1ad = 0;
4744     u32 exact_match = 0;
4745     u32 default_sub = 0;
4746     u32 outer_vlan_id_any = 0;
4747     u32 inner_vlan_id_any = 0;
4748     u32 tmp;
4749     u16 outer_vlan_id = 0;
4750     u16 inner_vlan_id = 0;
4751
4752     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4753         if (unformat (i, "sw_if_index %d", &sw_if_index))
4754             sw_if_index_set = 1;
4755         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4756             sw_if_index_set = 1;
4757         else if (unformat (i, "sub_id %d", &sub_id))
4758             sub_id_set = 1;
4759         else if (unformat (i, "outer_vlan_id %d", &tmp))
4760             outer_vlan_id = tmp;
4761         else if (unformat (i, "inner_vlan_id %d", &tmp))
4762             inner_vlan_id = tmp;
4763
4764 #define _(a) else if (unformat (i, #a)) a = 1 ;
4765         foreach_create_subif_bit
4766 #undef _
4767
4768         else {
4769             clib_warning ("parse error '%U'", format_unformat_error, i);
4770             return -99;
4771         }
4772     }
4773     
4774     if (sw_if_index_set == 0) {
4775         errmsg ("missing interface name or sw_if_index\n");
4776         return -99;
4777     }
4778
4779     if (sub_id_set == 0) {
4780         errmsg ("missing sub_id\n");
4781         return -99;
4782     }
4783     M(CREATE_SUBIF, create_subif);
4784
4785     mp->sw_if_index = ntohl(sw_if_index);
4786     mp->sub_id = ntohl(sub_id);
4787     
4788 #define _(a) mp->a = a;
4789     foreach_create_subif_bit;
4790 #undef _
4791         
4792     mp->outer_vlan_id = ntohs (outer_vlan_id);
4793     mp->inner_vlan_id = ntohs (inner_vlan_id);
4794
4795     S; W;
4796     /* NOTREACHED */
4797     return 0;
4798 }
4799
4800 static int api_oam_add_del (vat_main_t * vam)
4801 {
4802     unformat_input_t * i = vam->input;
4803     vl_api_oam_add_del_t *mp;
4804     f64 timeout;
4805     u32 vrf_id = 0;
4806     u8 is_add = 1;
4807     ip4_address_t src, dst;
4808     u8 src_set = 0;
4809     u8 dst_set = 0;
4810     
4811     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4812         if (unformat (i, "vrf %d", &vrf_id))
4813             ;
4814         else if (unformat (i, "src %U", unformat_ip4_address, &src))
4815             src_set = 1;
4816         else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
4817             dst_set = 1;
4818         else if (unformat (i, "del"))
4819             is_add = 0;
4820         else {
4821             clib_warning ("parse error '%U'", format_unformat_error, i);
4822             return -99;
4823         }
4824     }
4825     
4826     if (src_set == 0) {
4827         errmsg ("missing src addr\n");
4828         return -99;
4829     }
4830
4831     if (dst_set == 0) {
4832         errmsg ("missing dst addr\n");
4833         return -99;
4834     }
4835
4836     M(OAM_ADD_DEL, oam_add_del);
4837
4838     mp->vrf_id = ntohl(vrf_id);
4839     mp->is_add = is_add;
4840     clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
4841     clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
4842
4843     S; W;
4844     /* NOTREACHED */
4845     return 0;
4846 }
4847
4848 static int api_reset_fib (vat_main_t * vam)
4849 {
4850     unformat_input_t * i = vam->input;
4851     vl_api_reset_fib_t *mp;
4852     f64 timeout;
4853     u32 vrf_id = 0;
4854     u8 is_ipv6 = 0;
4855     u8 vrf_id_set = 0;
4856
4857     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4858         if (unformat (i, "vrf %d", &vrf_id))
4859             vrf_id_set = 1;
4860         else if (unformat (i, "ipv6"))
4861             is_ipv6 = 1;
4862         else {
4863             clib_warning ("parse error '%U'", format_unformat_error, i);
4864             return -99;
4865         }
4866     }
4867
4868     if (vrf_id_set == 0) {
4869         errmsg ("missing vrf id\n");
4870         return -99;
4871     }
4872     
4873     M(RESET_FIB, reset_fib);
4874
4875     mp->vrf_id = ntohl(vrf_id);
4876     mp->is_ipv6 = is_ipv6;
4877
4878     S; W;
4879     /* NOTREACHED */
4880     return 0;
4881 }
4882
4883 static int api_dhcp_proxy_config (vat_main_t * vam)
4884 {
4885     unformat_input_t * i = vam->input;
4886     vl_api_dhcp_proxy_config_t *mp;
4887     f64 timeout;
4888     u32 vrf_id = 0;
4889     u8 is_add = 1;
4890     u8 insert_cid = 1;
4891     u8 v4_address_set = 0;
4892     u8 v6_address_set = 0;
4893     ip4_address_t v4address;
4894     ip6_address_t v6address;
4895     u8 v4_src_address_set = 0;
4896     u8 v6_src_address_set = 0;
4897     ip4_address_t v4srcaddress;
4898     ip6_address_t v6srcaddress;
4899     
4900     /* Parse args required to build the message */
4901     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4902         if (unformat (i, "del"))
4903             is_add = 0;
4904         else if (unformat (i, "vrf %d", &vrf_id))
4905             ;
4906         else if (unformat (i, "insert-cid %d", &insert_cid))
4907             ;
4908         else if (unformat (i, "svr %U", 
4909                            unformat_ip4_address, &v4address))
4910                 v4_address_set = 1;
4911         else if (unformat (i, "svr %U", 
4912                            unformat_ip6_address, &v6address))
4913                 v6_address_set = 1;
4914         else if (unformat (i, "src %U", 
4915                            unformat_ip4_address, &v4srcaddress))
4916                 v4_src_address_set = 1;
4917         else if (unformat (i, "src %U", 
4918                            unformat_ip6_address, &v6srcaddress))
4919                 v6_src_address_set = 1;
4920         else
4921             break;
4922     }
4923
4924     if (v4_address_set && v6_address_set) {
4925         errmsg ("both v4 and v6 server addresses set\n");
4926         return -99;
4927     }
4928     if (!v4_address_set && !v6_address_set) {
4929         errmsg ("no server addresses set\n");
4930         return -99;
4931     }
4932
4933     if (v4_src_address_set && v6_src_address_set) {
4934         errmsg ("both v4 and v6  src addresses set\n");
4935         return -99;
4936     }
4937     if (!v4_src_address_set && !v6_src_address_set) {
4938         errmsg ("no src addresses set\n");
4939         return -99;
4940     }
4941
4942     if (!(v4_src_address_set && v4_address_set) &&
4943         !(v6_src_address_set && v6_address_set)) {
4944         errmsg ("no matching server and src addresses set\n");
4945         return -99;
4946     }
4947
4948     /* Construct the API message */
4949     M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
4950
4951     mp->insert_circuit_id = insert_cid;
4952     mp->is_add = is_add;
4953     mp->vrf_id = ntohl (vrf_id);
4954     if (v6_address_set) {
4955         mp->is_ipv6 = 1;
4956         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
4957         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
4958     } else {
4959         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
4960         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
4961     }
4962
4963     /* send it... */
4964     S;
4965
4966     /* Wait for a reply, return good/bad news  */
4967     W;
4968     /* NOTREACHED */
4969     return 0;
4970 }
4971
4972 static int api_dhcp_proxy_config_2 (vat_main_t * vam)
4973 {
4974     unformat_input_t * i = vam->input;
4975     vl_api_dhcp_proxy_config_2_t *mp;
4976     f64 timeout;
4977     u32 rx_vrf_id = 0;
4978     u32 server_vrf_id = 0;
4979     u8 is_add = 1;
4980     u8 insert_cid = 1;
4981     u8 v4_address_set = 0;
4982     u8 v6_address_set = 0;
4983     ip4_address_t v4address;
4984     ip6_address_t v6address;
4985     u8 v4_src_address_set = 0;
4986     u8 v6_src_address_set = 0;
4987     ip4_address_t v4srcaddress;
4988     ip6_address_t v6srcaddress;
4989     
4990     /* Parse args required to build the message */
4991     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
4992         if (unformat (i, "del"))
4993             is_add = 0;
4994         else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
4995             ;
4996         else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
4997             ;
4998         else if (unformat (i, "insert-cid %d", &insert_cid))
4999             ;
5000         else if (unformat (i, "svr %U", 
5001                            unformat_ip4_address, &v4address))
5002                 v4_address_set = 1;
5003         else if (unformat (i, "svr %U", 
5004                            unformat_ip6_address, &v6address))
5005                 v6_address_set = 1;
5006         else if (unformat (i, "src %U", 
5007                            unformat_ip4_address, &v4srcaddress))
5008                 v4_src_address_set = 1;
5009         else if (unformat (i, "src %U", 
5010                            unformat_ip6_address, &v6srcaddress))
5011                 v6_src_address_set = 1;
5012         else
5013             break;
5014     }
5015
5016     if (v4_address_set && v6_address_set) {
5017         errmsg ("both v4 and v6 server addresses set\n");
5018         return -99;
5019     }
5020     if (!v4_address_set && !v6_address_set) {
5021         errmsg ("no server addresses set\n");
5022         return -99;
5023     }
5024
5025     if (v4_src_address_set && v6_src_address_set) {
5026         errmsg ("both v4 and v6  src addresses set\n");
5027         return -99;
5028     }
5029     if (!v4_src_address_set && !v6_src_address_set) {
5030         errmsg ("no src addresses set\n");
5031         return -99;
5032     }
5033
5034     if (!(v4_src_address_set && v4_address_set) &&
5035         !(v6_src_address_set && v6_address_set)) {
5036         errmsg ("no matching server and src addresses set\n");
5037         return -99;
5038     }
5039
5040     /* Construct the API message */
5041     M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
5042
5043     mp->insert_circuit_id = insert_cid;
5044     mp->is_add = is_add;
5045     mp->rx_vrf_id = ntohl (rx_vrf_id);
5046     mp->server_vrf_id = ntohl (server_vrf_id);
5047     if (v6_address_set) {
5048         mp->is_ipv6 = 1;
5049         clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
5050         clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
5051     } else {
5052         clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
5053         clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
5054     }
5055
5056     /* send it... */
5057     S;
5058
5059     /* Wait for a reply, return good/bad news  */
5060     W;
5061     /* NOTREACHED */
5062     return 0;
5063 }
5064
5065 static int api_dhcp_proxy_set_vss (vat_main_t * vam)
5066 {
5067     unformat_input_t * i = vam->input;
5068     vl_api_dhcp_proxy_set_vss_t *mp;
5069     f64 timeout;
5070     u8  is_ipv6 = 0;
5071     u8  is_add = 1;
5072     u32 tbl_id;
5073     u8  tbl_id_set = 0;
5074     u32 oui;
5075     u8  oui_set = 0;
5076     u32 fib_id;
5077     u8  fib_id_set = 0;
5078
5079     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5080         if (unformat (i, "tbl_id %d", &tbl_id))
5081             tbl_id_set = 1;
5082         if (unformat (i, "fib_id %d", &fib_id))
5083             fib_id_set = 1;
5084         if (unformat (i, "oui %d", &oui))
5085             oui_set = 1;
5086         else if (unformat (i, "ipv6"))
5087             is_ipv6 = 1;
5088         else if (unformat (i, "del"))
5089             is_add = 0;
5090         else {
5091             clib_warning ("parse error '%U'", format_unformat_error, i);
5092             return -99;
5093         }
5094     }
5095
5096     if (tbl_id_set == 0) {
5097         errmsg ("missing tbl id\n");
5098         return -99;
5099     }
5100
5101     if (fib_id_set == 0) {
5102         errmsg ("missing fib id\n");
5103         return -99;
5104     }
5105     if (oui_set == 0) {
5106         errmsg ("missing oui\n");
5107         return -99;
5108     }
5109     
5110     M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
5111     mp->tbl_id = ntohl(tbl_id);
5112     mp->fib_id = ntohl(fib_id);
5113     mp->oui = ntohl(oui);
5114     mp->is_ipv6 = is_ipv6;
5115     mp->is_add = is_add;
5116
5117     S; W;
5118     /* NOTREACHED */
5119     return 0;
5120 }
5121
5122 static int api_dhcp_client_config (vat_main_t * vam)
5123 {
5124     unformat_input_t * i = vam->input;
5125     vl_api_dhcp_client_config_t *mp;
5126     f64 timeout;
5127     u32 sw_if_index;
5128     u8 sw_if_index_set = 0;
5129     u8 is_add = 1;
5130     u8 * hostname = 0;
5131     u8 disable_event = 0;
5132
5133     /* Parse args required to build the message */
5134     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5135         if (unformat (i, "del"))
5136             is_add = 0;
5137         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5138             sw_if_index_set = 1;
5139         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5140             sw_if_index_set = 1;
5141         else if (unformat (i, "hostname %s", &hostname))
5142             ;
5143         else if (unformat (i, "disable_event"))
5144             disable_event = 1;
5145         else
5146             break;
5147     }
5148
5149     if (sw_if_index_set == 0) {
5150         errmsg ("missing interface name or sw_if_index\n");
5151         return -99;
5152     }
5153
5154     if (vec_len (hostname) > 63) {
5155         errmsg ("hostname too long\n");
5156     }
5157     vec_add1 (hostname, 0);
5158
5159     /* Construct the API message */
5160     M(DHCP_CLIENT_CONFIG, dhcp_client_config);
5161
5162     mp->sw_if_index = ntohl (sw_if_index);
5163     clib_memcpy (mp->hostname, hostname, vec_len (hostname));
5164     vec_free (hostname);
5165     mp->is_add = is_add;
5166     mp->want_dhcp_event = disable_event ? 0 : 1;
5167     mp->pid = getpid();
5168    
5169     /* send it... */
5170     S;
5171
5172     /* Wait for a reply, return good/bad news  */
5173     W;
5174     /* NOTREACHED */
5175     return 0;
5176 }
5177
5178 static int api_set_ip_flow_hash (vat_main_t * vam)
5179 {
5180     unformat_input_t * i = vam->input;
5181     vl_api_set_ip_flow_hash_t *mp;
5182     f64 timeout;
5183     u32 vrf_id = 0;
5184     u8 is_ipv6 = 0;
5185     u8 vrf_id_set = 0;
5186     u8 src = 0;
5187     u8 dst = 0;
5188     u8 sport = 0;
5189     u8 dport = 0;
5190     u8 proto = 0;
5191     u8 reverse = 0;
5192
5193     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5194         if (unformat (i, "vrf %d", &vrf_id))
5195             vrf_id_set = 1;
5196         else if (unformat (i, "ipv6"))
5197             is_ipv6 = 1;
5198         else if (unformat (i, "src"))
5199             src = 1;
5200         else if (unformat (i, "dst"))
5201             dst = 1;
5202         else if (unformat (i, "sport"))
5203             sport = 1;
5204         else if (unformat (i, "dport"))
5205             dport = 1;
5206         else if (unformat (i, "proto"))
5207             proto = 1;
5208         else if (unformat (i, "reverse"))
5209             reverse = 1;
5210
5211         else {
5212             clib_warning ("parse error '%U'", format_unformat_error, i);
5213             return -99;
5214         }
5215     }
5216
5217     if (vrf_id_set == 0) {
5218         errmsg ("missing vrf id\n");
5219         return -99;
5220     }
5221     
5222     M(SET_IP_FLOW_HASH, set_ip_flow_hash);
5223     mp->src = src;
5224     mp->dst = dst;
5225     mp->sport = sport;
5226     mp->dport = dport;
5227     mp->proto = proto;
5228     mp->reverse = reverse;
5229     mp->vrf_id = ntohl(vrf_id);
5230     mp->is_ipv6 = is_ipv6;
5231
5232     S; W;
5233     /* NOTREACHED */
5234     return 0;
5235 }
5236
5237 static int api_sw_interface_ip6_enable_disable (vat_main_t * vam)
5238 {
5239     unformat_input_t * i = vam->input;
5240     vl_api_sw_interface_ip6_enable_disable_t *mp;
5241     f64 timeout;
5242     u32 sw_if_index;
5243     u8  sw_if_index_set = 0;
5244     u8  enable = 0;
5245
5246     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5247         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5248             sw_if_index_set = 1;
5249         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5250             sw_if_index_set = 1;
5251         else if (unformat (i, "enable"))
5252             enable = 1;
5253         else if (unformat (i, "disable"))
5254             enable = 0;
5255         else {
5256             clib_warning ("parse error '%U'", format_unformat_error, i);
5257             return -99;
5258         }
5259     }
5260
5261     if (sw_if_index_set == 0) {
5262         errmsg ("missing interface name or sw_if_index\n");
5263         return -99;
5264     }
5265     
5266     M(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
5267
5268     mp->sw_if_index = ntohl(sw_if_index);
5269     mp->enable = enable;
5270
5271     S; W;
5272     /* NOTREACHED */
5273     return 0;
5274 }
5275
5276 static int api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
5277 {
5278     unformat_input_t * i = vam->input;
5279     vl_api_sw_interface_ip6_set_link_local_address_t *mp;
5280     f64 timeout;
5281     u32 sw_if_index;
5282     u8 sw_if_index_set = 0;
5283     u32 address_length = 0;
5284     u8 v6_address_set = 0;
5285     ip6_address_t v6address;
5286     
5287     /* Parse args required to build the message */
5288     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5289         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5290             sw_if_index_set = 1;
5291         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5292             sw_if_index_set = 1;
5293         else if (unformat (i, "%U/%d", 
5294                            unformat_ip6_address, &v6address, 
5295                            &address_length))
5296             v6_address_set = 1;
5297         else
5298             break;
5299     }
5300
5301     if (sw_if_index_set == 0) {
5302         errmsg ("missing interface name or sw_if_index\n");
5303         return -99;
5304     }
5305     if (!v6_address_set) {
5306         errmsg ("no address set\n");
5307         return -99;
5308     }
5309
5310     /* Construct the API message */
5311     M(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
5312       sw_interface_ip6_set_link_local_address);
5313
5314     mp->sw_if_index = ntohl (sw_if_index);
5315     clib_memcpy (mp->address, &v6address, sizeof (v6address));
5316     mp->address_length = address_length;
5317
5318     /* send it... */
5319     S;
5320
5321     /* Wait for a reply, return good/bad news  */
5322     W;
5323
5324     /* NOTREACHED */
5325     return 0;
5326 }
5327
5328
5329 static int api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
5330 {
5331     unformat_input_t * i = vam->input;
5332     vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
5333     f64 timeout;
5334     u32 sw_if_index;
5335     u8 sw_if_index_set = 0;
5336     u32 address_length = 0;
5337     u8 v6_address_set = 0;
5338     ip6_address_t v6address;
5339     u8 use_default = 0;
5340     u8 no_advertise = 0;
5341     u8 off_link = 0;
5342     u8 no_autoconfig = 0;
5343     u8 no_onlink = 0;
5344     u8 is_no = 0;
5345     u32 val_lifetime = 0;
5346     u32 pref_lifetime = 0;
5347     
5348     /* Parse args required to build the message */
5349     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5350         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5351             sw_if_index_set = 1;
5352         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5353             sw_if_index_set = 1;
5354         else if (unformat (i, "%U/%d", 
5355                            unformat_ip6_address, &v6address, 
5356                            &address_length))
5357             v6_address_set = 1;
5358         else if (unformat (i, "val_life %d", &val_lifetime))
5359             ;
5360         else if (unformat (i, "pref_life %d", &pref_lifetime))
5361             ;
5362         else if (unformat (i, "def"))
5363             use_default = 1;
5364         else if (unformat (i, "noadv"))
5365             no_advertise = 1;
5366         else if (unformat (i, "offl"))
5367             off_link = 1;
5368         else if (unformat (i, "noauto"))
5369             no_autoconfig = 1;
5370         else if (unformat (i, "nolink"))
5371             no_onlink = 1;
5372         else if (unformat (i, "isno"))
5373             is_no = 1;
5374         else {
5375             clib_warning ("parse error '%U'", format_unformat_error, i);
5376             return -99;
5377         }        
5378     }
5379
5380     if (sw_if_index_set == 0) {
5381         errmsg ("missing interface name or sw_if_index\n");
5382         return -99;
5383     }
5384     if (!v6_address_set) {
5385         errmsg ("no address set\n");
5386         return -99;
5387     }
5388
5389     /* Construct the API message */
5390     M(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
5391
5392     mp->sw_if_index = ntohl (sw_if_index);
5393     clib_memcpy (mp->address, &v6address, sizeof (v6address));
5394     mp->address_length = address_length;
5395     mp->use_default = use_default;
5396     mp->no_advertise = no_advertise;
5397     mp->off_link = off_link;
5398     mp->no_autoconfig = no_autoconfig;
5399     mp->no_onlink = no_onlink;
5400     mp->is_no = is_no;
5401     mp->val_lifetime = ntohl(val_lifetime);
5402     mp->pref_lifetime = ntohl(pref_lifetime);
5403
5404     /* send it... */
5405     S;
5406
5407     /* Wait for a reply, return good/bad news  */
5408     W;
5409
5410     /* NOTREACHED */
5411     return 0;
5412 }
5413
5414 static int api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
5415 {
5416     unformat_input_t * i = vam->input;
5417     vl_api_sw_interface_ip6nd_ra_config_t *mp;
5418     f64 timeout;
5419     u32 sw_if_index;
5420     u8 sw_if_index_set = 0;
5421     u8 surpress = 0;
5422     u8 managed = 0;
5423     u8 other = 0;
5424     u8 ll_option = 0;
5425     u8 send_unicast = 0;
5426     u8 cease = 0;
5427     u8 is_no = 0;
5428     u8 default_router = 0;
5429     u32 max_interval = 0;
5430     u32 min_interval = 0;
5431     u32 lifetime = 0;
5432     u32 initial_count = 0;
5433     u32 initial_interval = 0;
5434
5435     
5436     /* Parse args required to build the message */
5437     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5438         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5439             sw_if_index_set = 1;
5440         else if (unformat (i, "sw_if_index %d", &sw_if_index))
5441             sw_if_index_set = 1;
5442         else if (unformat (i, "maxint %d", &max_interval))
5443             ;
5444         else if (unformat (i, "minint %d", &min_interval))
5445             ;
5446         else if (unformat (i, "life %d", &lifetime))
5447             ;
5448         else if (unformat (i, "count %d", &initial_count))
5449             ;
5450         else if (unformat (i, "interval %d", &initial_interval))
5451             ;
5452         else if (unformat (i, "surpress"))
5453             surpress = 1;
5454         else if (unformat (i, "managed"))
5455             managed = 1;
5456         else if (unformat (i, "other"))
5457             other = 1;
5458         else if (unformat (i, "ll"))
5459             ll_option = 1;
5460         else if (unformat (i, "send"))
5461             send_unicast = 1;
5462         else if (unformat (i, "cease"))
5463             cease = 1;
5464         else if (unformat (i, "isno"))
5465             is_no = 1;
5466         else if (unformat (i, "def"))
5467             default_router = 1;
5468         else {
5469             clib_warning ("parse error '%U'", format_unformat_error, i);
5470             return -99;
5471         }        
5472     }
5473
5474     if (sw_if_index_set == 0) {
5475         errmsg ("missing interface name or sw_if_index\n");
5476         return -99;
5477     }
5478
5479     /* Construct the API message */
5480     M(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
5481
5482     mp->sw_if_index = ntohl (sw_if_index);
5483     mp->max_interval = ntohl(max_interval);
5484     mp->min_interval = ntohl(min_interval);
5485     mp->lifetime = ntohl(lifetime);
5486     mp->initial_count = ntohl(initial_count);
5487     mp->initial_interval = ntohl(initial_interval);
5488     mp->surpress = surpress;
5489     mp->managed = managed;
5490     mp->other = other;
5491     mp->ll_option = ll_option;
5492     mp->send_unicast = send_unicast;
5493     mp->cease = cease;
5494     mp->is_no = is_no;
5495     mp->default_router = default_router;
5496
5497     /* send it... */
5498     S;
5499
5500     /* Wait for a reply, return good/bad news  */
5501     W;
5502
5503     /* NOTREACHED */
5504     return 0;
5505 }
5506
5507 static int api_set_arp_neighbor_limit (vat_main_t * vam)
5508 {
5509     unformat_input_t * i = vam->input;
5510     vl_api_set_arp_neighbor_limit_t *mp;
5511     f64 timeout;
5512     u32 arp_nbr_limit;
5513     u8 limit_set = 0;
5514     u8 is_ipv6 = 0;
5515
5516     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5517         if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
5518             limit_set = 1;
5519         else if (unformat (i, "ipv6"))
5520             is_ipv6 = 1;
5521         else {
5522             clib_warning ("parse error '%U'", format_unformat_error, i);
5523             return -99;
5524         }
5525     }
5526
5527     if (limit_set == 0) {
5528         errmsg ("missing limit value\n");
5529         return -99;
5530     }
5531     
5532     M(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
5533
5534     mp->arp_neighbor_limit = ntohl(arp_nbr_limit);
5535     mp->is_ipv6 = is_ipv6;
5536
5537     S; W;
5538     /* NOTREACHED */
5539     return 0;
5540 }
5541
5542 static int api_l2_patch_add_del (vat_main_t * vam)
5543 {
5544     unformat_input_t * i = vam->input;
5545     vl_api_l2_patch_add_del_t *mp;
5546     f64 timeout;
5547     u32 rx_sw_if_index;
5548     u8 rx_sw_if_index_set = 0;
5549     u32 tx_sw_if_index;
5550     u8 tx_sw_if_index_set = 0;
5551     u8 is_add = 1;
5552     
5553     /* Parse args required to build the message */
5554     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5555         if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5556             rx_sw_if_index_set = 1;     
5557         else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5558             tx_sw_if_index_set = 1;
5559         else if (unformat (i, "rx")) {
5560             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5561                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5562                               &rx_sw_if_index))
5563                     rx_sw_if_index_set = 1;
5564             } else
5565                 break;
5566         } else if (unformat (i, "tx")) {
5567             if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
5568                 if (unformat (i, "%U", unformat_sw_if_index, vam,
5569                               &tx_sw_if_index))
5570                     tx_sw_if_index_set = 1;
5571             } else
5572                 break;
5573         } else if (unformat (i, "del"))
5574             is_add = 0;
5575         else
5576             break;
5577     }
5578
5579     if (rx_sw_if_index_set == 0) {
5580         errmsg ("missing rx interface name or rx_sw_if_index\n");
5581         return -99;
5582     }
5583
5584     if (tx_sw_if_index_set == 0) {
5585         errmsg ("missing tx interface name or tx_sw_if_index\n");
5586         return -99;
5587     }
5588     
5589     M(L2_PATCH_ADD_DEL, l2_patch_add_del);
5590
5591     mp->rx_sw_if_index = ntohl(rx_sw_if_index);
5592     mp->tx_sw_if_index = ntohl(tx_sw_if_index);
5593     mp->is_add = is_add;
5594
5595     S; W;
5596     /* NOTREACHED */
5597     return 0;
5598 }
5599 static int api_trace_profile_add (vat_main_t *vam)
5600 {
5601    unformat_input_t * input = vam->input;
5602    vl_api_trace_profile_add_t *mp;
5603    f64 timeout;
5604    u32 id = 0;
5605    u32 trace_option_elts = 0;
5606    u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
5607    int has_pow_option = 0;
5608    int has_ppc_option = 0;
5609   
5610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5611     {
5612       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
5613                            "trace-tsp %d node-id 0x%x app-data 0x%x", 
5614                     &id, &trace_type, &trace_option_elts, &trace_tsp,
5615                       &node_id, &app_data))
5616             ;
5617       else if (unformat (input, "pow"))
5618         has_pow_option = 1;
5619       else if (unformat (input, "ppc encap"))
5620         has_ppc_option = PPC_ENCAP;
5621       else if (unformat (input, "ppc decap"))
5622         has_ppc_option = PPC_DECAP;
5623       else if (unformat (input, "ppc none"))
5624         has_ppc_option = PPC_NONE;
5625       else
5626         break;
5627     }
5628   M(TRACE_PROFILE_ADD, trace_profile_add);
5629   mp->id = htons(id);
5630   mp->trace_type = trace_type;
5631   mp->trace_num_elt = trace_option_elts;
5632   mp->trace_ppc = has_ppc_option;
5633   mp->trace_app_data = htonl(app_data);
5634   mp->pow_enable = has_pow_option;
5635   mp->trace_tsp = trace_tsp;
5636   mp->node_id = htonl(node_id);
5637   
5638   S; W;
5639   
5640   return(0);
5641    
5642 }
5643 static int api_trace_profile_apply (vat_main_t *vam)
5644 {
5645   unformat_input_t * input = vam->input;
5646   vl_api_trace_profile_apply_t *mp;
5647   f64 timeout;
5648   ip6_address_t addr;
5649   u32 mask_width = ~0;
5650   int is_add = 0;
5651   int is_pop = 0;
5652   int is_none = 0;
5653   u32 vrf_id = 0;
5654   u32 id = 0;
5655   
5656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5657     {
5658       if (unformat (input, "%U/%d",
5659                     unformat_ip6_address, &addr, &mask_width))
5660         ;
5661       else if (unformat (input, "id %d", &id))
5662         ;
5663       else if (unformat (input, "vrf-id %d", &vrf_id))
5664         ;
5665       else if (unformat (input, "add"))
5666         is_add = 1;
5667       else if (unformat (input, "pop"))
5668         is_pop = 1;
5669       else if (unformat (input, "none"))
5670         is_none = 1;
5671       else
5672         break;
5673     }
5674
5675   if ((is_add + is_pop + is_none) != 1) {
5676     errmsg("One of (add, pop, none) required");
5677     return -99;
5678   }
5679   if (mask_width == ~0) {
5680     errmsg("<address>/<mask-width> required");
5681     return -99;
5682   }
5683   M(TRACE_PROFILE_APPLY, trace_profile_apply);
5684   clib_memcpy(mp->dest_ipv6, &addr, sizeof(mp->dest_ipv6));
5685   mp->id = htons(id);
5686   mp->prefix_length = htonl(mask_width);
5687   mp->vrf_id = htonl(vrf_id);
5688   if (is_add)
5689     mp->trace_op = IOAM_HBYH_ADD;
5690   else if (is_pop)
5691     mp->trace_op = IOAM_HBYH_POP;
5692   else
5693     mp->trace_op = IOAM_HBYH_MOD;
5694
5695   if(is_none)
5696     mp->enable = 0;
5697   else
5698     mp->enable = 1;
5699   
5700   S; W;
5701
5702   return 0;
5703 }
5704
5705 static int api_trace_profile_del (vat_main_t *vam)
5706 {
5707    vl_api_trace_profile_del_t *mp;
5708    f64 timeout;
5709    
5710    M(TRACE_PROFILE_DEL, trace_profile_del);
5711    S; W;
5712    return 0;
5713 }
5714
5715 static int api_sr_tunnel_add_del (vat_main_t * vam)
5716 {
5717   unformat_input_t * i = vam->input;
5718   vl_api_sr_tunnel_add_del_t *mp;
5719   f64 timeout;
5720   int is_del = 0;
5721   int pl_index;
5722   ip6_address_t src_address;
5723   int src_address_set = 0;
5724   ip6_address_t dst_address;
5725   u32 dst_mask_width;
5726   int dst_address_set = 0;
5727   u16 flags = 0;
5728   u32 rx_table_id = 0;
5729   u32 tx_table_id = 0;
5730   ip6_address_t * segments = 0;
5731   ip6_address_t * this_seg;
5732   ip6_address_t * tags = 0;
5733   ip6_address_t * this_tag;
5734   ip6_address_t next_address, tag;
5735   u8 * name = 0;
5736   u8 * policy_name = 0;
5737
5738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739     {
5740       if (unformat (i, "del"))
5741         is_del = 1;
5742       else if (unformat (i, "name %s", &name))
5743             ;
5744       else if (unformat (i, "policy %s", &policy_name))
5745             ;
5746       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
5747         ;
5748       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
5749         ;
5750       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
5751         src_address_set = 1;
5752       else if (unformat (i, "dst %U/%d", 
5753                          unformat_ip6_address, &dst_address,
5754                          &dst_mask_width))
5755         dst_address_set = 1;
5756       else if (unformat (i, "next %U", unformat_ip6_address,
5757                          &next_address))
5758         {
5759           vec_add2 (segments, this_seg, 1);
5760           clib_memcpy (this_seg->as_u8, next_address.as_u8, sizeof (*this_seg));
5761         }
5762       else if (unformat (i, "tag %U", unformat_ip6_address,
5763                          &tag))
5764         {
5765           vec_add2 (tags, this_tag, 1);
5766           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
5767         }
5768       else if (unformat (i, "clean"))
5769         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
5770       else if (unformat (i, "protected"))
5771         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
5772       else if (unformat (i, "InPE %d", &pl_index))
5773         {
5774           if (pl_index <= 0 || pl_index > 4)
5775             {
5776             pl_index_range_error:
5777               errmsg ("pl index %d out of range\n", pl_index);
5778               return -99;
5779             }
5780           flags |= IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3*(pl_index - 1));
5781         }
5782       else if (unformat (i, "EgPE %d", &pl_index))
5783         {
5784           if (pl_index <= 0 || pl_index > 4)
5785             goto pl_index_range_error;
5786           flags |= IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3*(pl_index - 1));
5787         }
5788       else if (unformat (i, "OrgSrc %d", &pl_index))
5789         {
5790           if (pl_index <= 0 || pl_index > 4)
5791             goto pl_index_range_error;
5792           flags |= IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3*(pl_index - 1));
5793         }
5794       else 
5795         break;
5796     }
5797
5798   if (!src_address_set)
5799     {
5800       errmsg ("src address required\n");
5801       return -99;
5802     }
5803
5804   if (!dst_address_set)
5805     {
5806       errmsg ("dst address required\n");
5807       return -99;
5808     }
5809
5810   if (!segments)
5811     {
5812       errmsg ("at least one sr segment required\n");
5813       return -99;
5814     }
5815
5816   M2(SR_TUNNEL_ADD_DEL, sr_tunnel_add_del, 
5817      vec_len(segments) * sizeof (ip6_address_t) 
5818      + vec_len(tags) * sizeof (ip6_address_t));
5819
5820   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
5821   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
5822   mp->dst_mask_width = dst_mask_width;
5823   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
5824   mp->n_segments = vec_len (segments);
5825   mp->n_tags = vec_len (tags);
5826   mp->is_add = is_del == 0;
5827   clib_memcpy (mp->segs_and_tags, segments, 
5828           vec_len(segments)* sizeof (ip6_address_t));
5829   clib_memcpy (mp->segs_and_tags + vec_len(segments)*sizeof (ip6_address_t),
5830           tags, vec_len(tags)* sizeof (ip6_address_t));
5831
5832   mp->outer_vrf_id = ntohl (rx_table_id);
5833   mp->inner_vrf_id = ntohl (tx_table_id);
5834   memcpy (mp->name, name, vec_len(name));
5835   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5836
5837   vec_free (segments);
5838   vec_free (tags);
5839   
5840   S; W;
5841   /* NOTREACHED */
5842 }
5843
5844 static int api_sr_policy_add_del (vat_main_t * vam)
5845 {
5846   unformat_input_t * input = vam->input;
5847   vl_api_sr_policy_add_del_t *mp;
5848   f64 timeout;
5849   int is_del = 0;
5850   u8 * name = 0;
5851   u8 * tunnel_name = 0;
5852   u8 ** tunnel_names = 0;
5853   
5854   int name_set = 0 ;
5855   int tunnel_set = 0;
5856   int j = 0;
5857   int tunnel_names_length = 1; // Init to 1 to offset the #tunnel_names counter byte
5858   int tun_name_len = 0; // Different naming convention used as confusing these would be "bad" (TM)
5859
5860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5861     {
5862       if (unformat (input, "del"))
5863         is_del = 1;
5864       else if (unformat (input, "name %s", &name))
5865         name_set = 1;
5866       else if (unformat (input, "tunnel %s", &tunnel_name))
5867         {
5868           if (tunnel_name)
5869             {
5870               vec_add1 (tunnel_names, tunnel_name);
5871               /* For serializer: 
5872                  - length = #bytes to store in serial vector
5873                  - +1 = byte to store that length
5874               */
5875               tunnel_names_length += (vec_len (tunnel_name) + 1); 
5876               tunnel_set = 1;
5877               tunnel_name = 0;
5878             }
5879         }
5880       else 
5881         break;
5882     }
5883
5884   if (!name_set)
5885     {
5886       errmsg ("policy name required\n");
5887       return -99;
5888     }
5889
5890   if ((!tunnel_set) && (!is_del))
5891     {
5892       errmsg ("tunnel name required\n");
5893       return -99;
5894     }
5895
5896   M2(SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
5897
5898   
5899
5900   mp->is_add = !is_del;
5901
5902   memcpy (mp->name, name, vec_len(name));
5903   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
5904   u8 * serial_orig = 0;
5905   vec_validate (serial_orig, tunnel_names_length);
5906   *serial_orig = vec_len(tunnel_names); // Store the number of tunnels as length in first byte of serialized vector
5907   serial_orig += 1; // Move along one byte to store the length of first tunnel_name
5908
5909   for (j=0; j < vec_len(tunnel_names); j++)
5910     {
5911       tun_name_len = vec_len (tunnel_names[j]);
5912       *serial_orig = tun_name_len; // Store length of tunnel name in first byte of Length/Value pair
5913       serial_orig += 1; // Move along one byte to store the actual tunnel name
5914       memcpy (serial_orig, tunnel_names[j], tun_name_len);
5915       serial_orig += tun_name_len; // Advance past the copy
5916     }
5917   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length); // Regress serial_orig to head then copy fwd
5918
5919   vec_free (tunnel_names);
5920   vec_free (tunnel_name);
5921   
5922   S; W;
5923   /* NOTREACHED */
5924 }
5925
5926 static int api_sr_multicast_map_add_del (vat_main_t * vam)
5927 {
5928   unformat_input_t * input = vam->input;
5929   vl_api_sr_multicast_map_add_del_t *mp;
5930   f64 timeout;
5931   int is_del = 0;
5932   ip6_address_t multicast_address;
5933   u8 * policy_name = 0;
5934   int multicast_address_set = 0;
5935
5936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5937     {
5938       if (unformat (input, "del"))
5939         is_del = 1;
5940       else if (unformat (input, "address %U", unformat_ip6_address, &multicast_address))
5941         multicast_address_set = 1;
5942       else if (unformat (input, "sr-policy %s", &policy_name))
5943         ;
5944       else 
5945         break;
5946     }
5947
5948   if (!is_del && !policy_name)
5949     {
5950       errmsg ("sr-policy name required\n");
5951       return -99;
5952     }
5953
5954
5955   if (!multicast_address_set)
5956     {
5957       errmsg ("address required\n");
5958       return -99;
5959     }
5960
5961   M(SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
5962
5963   mp->is_add = !is_del;
5964   memcpy (mp->policy_name, policy_name, vec_len(policy_name));
5965   clib_memcpy (mp->multicast_address, &multicast_address, sizeof (mp->multicast_address));
5966
5967
5968   vec_free (policy_name);
5969   
5970   S; W;
5971   /* NOTREACHED */
5972 }
5973
5974
5975 #define foreach_ip4_proto_field                 \
5976 _(src_address)                                  \
5977 _(dst_address)                                  \
5978 _(tos)                                          \
5979 _(length)                                       \
5980 _(fragment_id)                                  \
5981 _(ttl)                                          \
5982 _(protocol)                                     \
5983 _(checksum)
5984
5985 uword unformat_ip4_mask (unformat_input_t * input, va_list * args)
5986 {
5987   u8 ** maskp = va_arg (*args, u8 **);
5988   u8 * mask = 0;
5989   u8 found_something = 0;
5990   ip4_header_t * ip;
5991   
5992 #define _(a) u8 a=0;
5993   foreach_ip4_proto_field;
5994 #undef _
5995   u8 version = 0;
5996   u8 hdr_length = 0;
5997   
5998   
5999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6000     {
6001       if (unformat (input, "version")) 
6002         version = 1;
6003       else if (unformat (input, "hdr_length"))
6004         hdr_length = 1;
6005       else if (unformat (input, "src"))
6006         src_address = 1;
6007       else if (unformat (input, "dst"))
6008         dst_address = 1;
6009       else if (unformat (input, "proto"))
6010         protocol = 1;
6011       
6012 #define _(a) else if (unformat (input, #a)) a=1;
6013       foreach_ip4_proto_field
6014 #undef _
6015       else
6016         break;
6017     }
6018   
6019 #define _(a) found_something += a;
6020   foreach_ip4_proto_field;
6021 #undef _
6022   
6023   if (found_something == 0)
6024     return 0;
6025   
6026   vec_validate (mask, sizeof (*ip) - 1);
6027   
6028   ip = (ip4_header_t *) mask;
6029   
6030 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6031   foreach_ip4_proto_field;
6032 #undef _
6033   
6034   ip->ip_version_and_header_length = 0;
6035   
6036   if (version)
6037     ip->ip_version_and_header_length |= 0xF0;
6038   
6039   if (hdr_length)
6040     ip->ip_version_and_header_length |= 0x0F;
6041   
6042   *maskp = mask;
6043   return 1;
6044 }
6045
6046 #define foreach_ip6_proto_field                 \
6047 _(src_address)                                  \
6048 _(dst_address)                                  \
6049 _(payload_length)                               \
6050 _(hop_limit)                                    \
6051 _(protocol)
6052
6053 uword unformat_ip6_mask (unformat_input_t * input, va_list * args)
6054 {
6055   u8 ** maskp = va_arg (*args, u8 **);
6056   u8 * mask = 0;
6057   u8 found_something = 0;
6058   ip6_header_t * ip;
6059   u32 ip_version_traffic_class_and_flow_label;
6060   
6061 #define _(a) u8 a=0;
6062   foreach_ip6_proto_field;
6063 #undef _
6064   u8 version = 0;
6065   u8 traffic_class = 0;
6066   u8 flow_label = 0;
6067   
6068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6069     {
6070       if (unformat (input, "version")) 
6071         version = 1;
6072       else if (unformat (input, "traffic-class"))
6073         traffic_class = 1;
6074       else if (unformat (input, "flow-label"))
6075         flow_label = 1;
6076       else if (unformat (input, "src"))
6077         src_address = 1;
6078       else if (unformat (input, "dst"))
6079         dst_address = 1;
6080       else if (unformat (input, "proto"))
6081         protocol = 1;
6082       
6083 #define _(a) else if (unformat (input, #a)) a=1;
6084       foreach_ip6_proto_field
6085 #undef _
6086       else
6087         break;
6088     }
6089   
6090 #define _(a) found_something += a;
6091   foreach_ip6_proto_field;
6092 #undef _
6093   
6094   if (found_something == 0)
6095     return 0;
6096   
6097   vec_validate (mask, sizeof (*ip) - 1);
6098   
6099   ip = (ip6_header_t *) mask;
6100   
6101 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
6102   foreach_ip6_proto_field;
6103 #undef _
6104   
6105   ip_version_traffic_class_and_flow_label = 0;
6106   
6107   if (version)
6108     ip_version_traffic_class_and_flow_label |= 0xF0000000;
6109
6110   if (traffic_class)
6111     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
6112
6113   if (flow_label)
6114     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
6115
6116   ip->ip_version_traffic_class_and_flow_label = 
6117     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6118   
6119   *maskp = mask;
6120   return 1;
6121 }
6122
6123 uword unformat_l3_mask (unformat_input_t * input, va_list * args)
6124 {
6125   u8 ** maskp = va_arg (*args, u8 **);
6126
6127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6128     if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
6129       return 1;
6130     else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
6131       return 1;
6132     else
6133       break;
6134   }
6135   return 0;
6136 }
6137
6138 uword unformat_l2_mask (unformat_input_t * input, va_list * args)
6139 {
6140   u8 ** maskp = va_arg (*args, u8 **);
6141   u8 * mask = 0;
6142   u8 src = 0;
6143   u8 dst = 0;
6144   u8 proto = 0;
6145   u8 tag1 = 0;
6146   u8 tag2 = 0;
6147   u8 ignore_tag1 = 0;
6148   u8 ignore_tag2 = 0;
6149   u8 cos1 = 0;
6150   u8 cos2 = 0;
6151   u8 dot1q = 0;
6152   u8 dot1ad = 0;
6153   int len = 14;
6154
6155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6156     if (unformat (input, "src"))
6157       src = 1;
6158     else if (unformat (input, "dst"))
6159       dst = 1;
6160     else if (unformat (input, "proto"))
6161       proto = 1;
6162     else if (unformat (input, "tag1"))
6163       tag1 = 1;
6164     else if (unformat (input, "tag2"))
6165       tag2 = 1;
6166     else if (unformat (input, "ignore-tag1"))
6167       ignore_tag1 = 1;
6168     else if (unformat (input, "ignore-tag2"))
6169       ignore_tag2 = 1;
6170     else if (unformat (input, "cos1"))
6171       cos1 = 1;
6172     else if (unformat (input, "cos2"))
6173       cos2 = 1;
6174     else if (unformat (input, "dot1q"))
6175       dot1q = 1;
6176     else if (unformat (input, "dot1ad"))
6177       dot1ad = 1;
6178     else
6179       break;
6180   }
6181   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
6182       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6183     return 0;
6184
6185   if (tag1 || ignore_tag1 || cos1 || dot1q)
6186     len = 18;
6187   if (tag2 || ignore_tag2 || cos2 || dot1ad)
6188     len = 22;
6189
6190   vec_validate (mask, len-1);
6191
6192   if (dst)
6193     memset (mask, 0xff, 6);
6194
6195   if (src)
6196     memset (mask + 6, 0xff, 6);
6197   
6198   if (tag2 || dot1ad)
6199     {
6200       /* inner vlan tag */
6201       if (tag2)
6202         {
6203           mask[19] = 0xff;
6204           mask[18] = 0x0f;
6205         }
6206       if (cos2)
6207         mask[18] |= 0xe0;
6208       if (proto)
6209           mask[21] = mask [20] = 0xff;
6210       if (tag1)
6211         {
6212           mask [15] = 0xff;
6213           mask [14] = 0x0f;
6214         }
6215       if (cos1)
6216         mask[14] |= 0xe0;
6217       *maskp = mask;
6218       return 1;
6219     }
6220   if (tag1 | dot1q)
6221     {
6222       if (tag1)
6223         {
6224           mask [15] = 0xff;
6225           mask [14] = 0x0f;
6226         }
6227       if (cos1)
6228         mask[14] |= 0xe0;
6229       if (proto)
6230           mask[16] = mask [17] = 0xff;
6231
6232       *maskp = mask;
6233       return 1;
6234     }
6235   if (cos2)
6236     mask[18] |= 0xe0;
6237   if (cos1)
6238     mask[14] |= 0xe0;
6239   if (proto)
6240     mask[12] = mask [13] = 0xff;
6241     
6242   *maskp = mask;
6243   return 1;
6244 }
6245
6246 uword unformat_classify_mask (unformat_input_t * input, va_list * args)
6247 {
6248   u8 ** maskp = va_arg (*args, u8 **);
6249   u32 * skipp = va_arg (*args, u32 *);
6250   u32 * matchp = va_arg (*args, u32 *);
6251   u32 match;
6252   u8 * mask = 0;
6253   u8 * l2 = 0;
6254   u8 * l3 = 0;
6255   int i;
6256   
6257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6258     if (unformat (input, "hex %U", unformat_hex_string, &mask))
6259       ;
6260     else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
6261       ;
6262     else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
6263       ;
6264     else
6265       break;
6266   }
6267
6268   if (mask || l2 || l3)
6269     {
6270       if (l2 || l3)
6271         {
6272           /* "With a free Ethernet header in every package" */
6273           if (l2 == 0)
6274             vec_validate (l2, 13);
6275           mask = l2;
6276           vec_append (mask, l3);
6277           vec_free (l3);
6278         }
6279
6280       /* Scan forward looking for the first significant mask octet */
6281       for (i = 0; i < vec_len (mask); i++)
6282         if (mask[i])
6283           break;
6284
6285       /* compute (skip, match) params */
6286       *skipp = i / sizeof(u32x4);
6287       vec_delete (mask, *skipp * sizeof(u32x4), 0);
6288
6289       /* Pad mask to an even multiple of the vector size */
6290       while (vec_len (mask) % sizeof (u32x4))
6291         vec_add1 (mask, 0);
6292
6293       match = vec_len (mask) / sizeof (u32x4);
6294
6295       for (i = match*sizeof(u32x4); i > 0; i-= sizeof(u32x4))
6296         {
6297           u64 *tmp = (u64 *)(mask + (i-sizeof(u32x4)));
6298           if (*tmp || *(tmp+1))
6299             break;
6300           match--;
6301         }
6302       if (match == 0)
6303         clib_warning ("BUG: match 0");
6304
6305       _vec_len (mask) = match * sizeof(u32x4);
6306
6307       *matchp = match;
6308       *maskp = mask;
6309
6310       return 1;
6311     }
6312
6313   return 0;
6314 }
6315
6316 #define foreach_l2_next                         \
6317 _(drop, DROP)                                   \
6318 _(ethernet, ETHERNET_INPUT)                     \
6319 _(ip4, IP4_INPUT)                               \
6320 _(ip6, IP6_INPUT)
6321
6322 uword unformat_l2_next_index (unformat_input_t * input, va_list * args)
6323 {
6324   u32 * miss_next_indexp = va_arg (*args, u32 *);
6325   u32 next_index = 0;
6326   u32 tmp;
6327   
6328 #define _(n,N) \
6329   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
6330   foreach_l2_next;
6331 #undef _
6332   
6333   if (unformat (input, "%d", &tmp))
6334     { 
6335       next_index = tmp; 
6336       goto out; 
6337     }
6338   
6339   return 0;
6340
6341  out:
6342   *miss_next_indexp = next_index;
6343   return 1;
6344 }
6345
6346 #define foreach_ip_next                         \
6347 _(miss, MISS)                                   \
6348 _(drop, DROP)                                   \
6349 _(local, LOCAL)                                 \
6350 _(rewrite, REWRITE)
6351
6352 uword unformat_ip_next_index (unformat_input_t * input, va_list * args)
6353 {
6354   u32 * miss_next_indexp = va_arg (*args, u32 *);
6355   u32 next_index = 0;
6356   u32 tmp;
6357   
6358 #define _(n,N) \
6359   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
6360   foreach_ip_next;
6361 #undef _
6362   
6363   if (unformat (input, "%d", &tmp))
6364     { 
6365       next_index = tmp; 
6366       goto out; 
6367     }
6368   
6369   return 0;
6370
6371  out:
6372   *miss_next_indexp = next_index;
6373   return 1;
6374 }
6375
6376 #define foreach_acl_next                        \
6377 _(deny, DENY)
6378
6379 uword unformat_acl_next_index (unformat_input_t * input, va_list * args)
6380 {
6381   u32 * miss_next_indexp = va_arg (*args, u32 *);
6382   u32 next_index = 0;
6383   u32 tmp;
6384
6385 #define _(n,N) \
6386   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
6387   foreach_acl_next;
6388 #undef _
6389
6390   if (unformat (input, "permit"))
6391     {
6392       next_index = ~0;
6393       goto out;
6394     }
6395   else if (unformat (input, "%d", &tmp))
6396     {
6397       next_index = tmp;
6398       goto out;
6399     }
6400
6401   return 0;
6402
6403  out:
6404   *miss_next_indexp = next_index;
6405   return 1;
6406 }
6407
6408 static int api_classify_add_del_table (vat_main_t * vam)
6409 {
6410   unformat_input_t * i = vam->input;
6411   vl_api_classify_add_del_table_t *mp;
6412
6413   u32 nbuckets = 2;
6414   u32 skip = ~0;
6415   u32 match = ~0;
6416   int is_add = 1;
6417   u32 table_index = ~0;
6418   u32 next_table_index = ~0;
6419   u32 miss_next_index = ~0;
6420   u32 memory_size = 32<<20;
6421   u8 * mask = 0;
6422   f64 timeout;
6423
6424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6425     if (unformat (i, "del"))
6426       is_add = 0;
6427     else if (unformat (i, "buckets %d", &nbuckets))
6428       ;
6429     else if (unformat (i, "memory_size %d", &memory_size))
6430       ;
6431     else if (unformat (i, "skip %d", &skip))
6432       ;
6433     else if (unformat (i, "match %d", &match))
6434       ;
6435     else if (unformat (i, "table %d", &table_index))
6436       ;
6437     else if (unformat (i, "mask %U", unformat_classify_mask, 
6438                        &mask, &skip, &match))
6439       ;
6440     else if (unformat (i, "next-table %d", &next_table_index))
6441       ;
6442     else if (unformat (i, "miss-next %U", unformat_ip_next_index,
6443                        &miss_next_index))
6444       ;
6445     else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
6446                        &miss_next_index))
6447       ;
6448     else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
6449                        &miss_next_index))
6450       ;
6451     else
6452       break;
6453   }
6454   
6455   if (is_add && mask == 0) {
6456       errmsg ("Mask required\n");
6457       return -99;
6458   }
6459
6460   if (is_add && skip == ~0) {
6461       errmsg ("skip count required\n");
6462       return -99;
6463   }
6464
6465   if (is_add && match == ~0) {
6466       errmsg ("match count required\n");
6467       return -99;
6468   }
6469       
6470   if (!is_add && table_index == ~0) {
6471       errmsg ("table index required for delete\n");
6472       return -99;
6473   }
6474
6475   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table,
6476       vec_len(mask));
6477
6478   mp->is_add = is_add;
6479   mp->table_index = ntohl(table_index);
6480   mp->nbuckets = ntohl(nbuckets);
6481   mp->memory_size = ntohl(memory_size);
6482   mp->skip_n_vectors = ntohl(skip);
6483   mp->match_n_vectors = ntohl(match);
6484   mp->next_table_index = ntohl(next_table_index);
6485   mp->miss_next_index = ntohl(miss_next_index);
6486   clib_memcpy (mp->mask, mask, vec_len(mask));
6487
6488   vec_free(mask);
6489
6490   S; W;
6491   /* NOTREACHED */
6492 }
6493
6494 uword unformat_ip4_match (unformat_input_t * input, va_list * args)
6495 {
6496   u8 ** matchp = va_arg (*args, u8 **);
6497   u8 * match = 0;
6498   ip4_header_t * ip;
6499   int version = 0;
6500   u32 version_val;
6501   int hdr_length = 0;
6502   u32 hdr_length_val;
6503   int src = 0, dst = 0;
6504   ip4_address_t src_val, dst_val;
6505   int proto = 0;
6506   u32 proto_val;
6507   int tos = 0;
6508   u32 tos_val;
6509   int length = 0;
6510   u32 length_val;
6511   int fragment_id = 0;
6512   u32 fragment_id_val;
6513   int ttl = 0;
6514   int ttl_val;
6515   int checksum = 0;
6516   u32 checksum_val;
6517
6518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6519     {
6520       if (unformat (input, "version %d", &version_val)) 
6521         version = 1;
6522       else if (unformat (input, "hdr_length %d", &hdr_length_val))
6523         hdr_length = 1;
6524       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
6525         src = 1;
6526       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
6527         dst = 1;
6528       else if (unformat (input, "proto %d", &proto_val))
6529         proto = 1;
6530       else if (unformat (input, "tos %d", &tos_val))
6531         tos = 1;
6532       else if (unformat (input, "length %d", &length_val))
6533         length = 1;
6534       else if (unformat (input, "fragment_id %d", &fragment_id_val))
6535         fragment_id = 1;
6536       else if (unformat (input, "ttl %d", &ttl_val))
6537         ttl = 1;
6538       else if (unformat (input, "checksum %d", &checksum_val))
6539         checksum = 1;
6540       else
6541         break;
6542     }
6543   
6544   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
6545       + ttl + checksum == 0)
6546     return 0;
6547
6548   /* 
6549    * Aligned because we use the real comparison functions
6550    */
6551   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6552   
6553   ip = (ip4_header_t *) match;
6554   
6555   /* These are realistically matched in practice */
6556   if (src)
6557     ip->src_address.as_u32 = src_val.as_u32;
6558
6559   if (dst)
6560     ip->dst_address.as_u32 = dst_val.as_u32;
6561   
6562   if (proto)
6563     ip->protocol = proto_val;
6564     
6565
6566   /* These are not, but they're included for completeness */
6567   if (version)
6568     ip->ip_version_and_header_length |= (version_val & 0xF)<<4;
6569
6570   if (hdr_length)
6571     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
6572     
6573   if (tos)
6574     ip->tos = tos_val;
6575   
6576   if (length)
6577     ip->length = length_val;
6578   
6579   if (ttl)
6580     ip->ttl = ttl_val;
6581
6582   if (checksum)
6583     ip->checksum = checksum_val;
6584
6585   *matchp = match;
6586   return 1;
6587 }
6588
6589 uword unformat_ip6_match (unformat_input_t * input, va_list * args)
6590 {
6591   u8 ** matchp = va_arg (*args, u8 **);
6592   u8 * match = 0;
6593   ip6_header_t * ip;
6594   int version = 0;
6595   u32 version_val;
6596   u8  traffic_class;
6597   u32 traffic_class_val;
6598   u8  flow_label;
6599   u8  flow_label_val;
6600   int src = 0, dst = 0;
6601   ip6_address_t src_val, dst_val;
6602   int proto = 0;
6603   u32 proto_val;
6604   int payload_length = 0;
6605   u32 payload_length_val;
6606   int hop_limit = 0;
6607   int hop_limit_val;
6608   u32 ip_version_traffic_class_and_flow_label;
6609
6610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) 
6611     {
6612       if (unformat (input, "version %d", &version_val)) 
6613         version = 1;
6614       else if (unformat (input, "traffic_class %d", &traffic_class_val))
6615         traffic_class = 1;
6616       else if (unformat (input, "flow_label %d", &flow_label_val))
6617         flow_label = 1;
6618       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
6619         src = 1;
6620       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
6621         dst = 1;
6622       else if (unformat (input, "proto %d", &proto_val))
6623         proto = 1;
6624       else if (unformat (input, "payload_length %d", &payload_length_val))
6625         payload_length = 1;
6626       else if (unformat (input, "hop_limit %d", &hop_limit_val))
6627         hop_limit = 1;
6628       else
6629         break;
6630     }
6631   
6632   if (version + traffic_class + flow_label + src + dst + proto +
6633       payload_length + hop_limit == 0)
6634     return 0;
6635
6636   /* 
6637    * Aligned because we use the real comparison functions
6638    */
6639   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof(u32x4));
6640   
6641   ip = (ip6_header_t *) match;
6642   
6643   if (src)
6644     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
6645
6646   if (dst)
6647     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
6648   
6649   if (proto)
6650     ip->protocol = proto_val;
6651     
6652   ip_version_traffic_class_and_flow_label = 0;
6653
6654   if (version)
6655     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
6656
6657   if (traffic_class)
6658     ip_version_traffic_class_and_flow_label |= (traffic_class_val & 0xFF) << 20;
6659
6660   if (flow_label)
6661     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
6662     
6663   ip->ip_version_traffic_class_and_flow_label = 
6664     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
6665
6666   if (payload_length)
6667     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
6668   
6669   if (hop_limit)
6670     ip->hop_limit = hop_limit_val;
6671
6672   *matchp = match;
6673   return 1;
6674 }
6675
6676 uword unformat_l3_match (unformat_input_t * input, va_list * args)
6677 {
6678   u8 ** matchp = va_arg (*args, u8 **);
6679
6680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6681     if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
6682       return 1;
6683     else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
6684       return 1;
6685     else
6686       break;
6687   }
6688   return 0;
6689 }
6690
6691 uword unformat_vlan_tag (unformat_input_t * input, va_list * args)
6692 {
6693   u8 * tagp = va_arg (*args, u8 *);
6694   u32 tag;
6695
6696   if (unformat(input, "%d", &tag))
6697     {
6698       tagp[0] = (tag>>8) & 0x0F;
6699       tagp[1] = tag & 0xFF;
6700       return 1;
6701     }
6702
6703   return 0;
6704 }
6705
6706 uword unformat_l2_match (unformat_input_t * input, va_list * args)
6707 {
6708   u8 ** matchp = va_arg (*args, u8 **);
6709   u8 * match = 0;
6710   u8 src = 0;
6711   u8 src_val[6];
6712   u8 dst = 0;
6713   u8 dst_val[6];
6714   u8 proto = 0;
6715   u16 proto_val;
6716   u8 tag1 = 0;
6717   u8 tag1_val [2];
6718   u8 tag2 = 0;
6719   u8 tag2_val [2];
6720   int len = 14;
6721   u8 ignore_tag1 = 0;
6722   u8 ignore_tag2 = 0;
6723   u8 cos1 = 0;
6724   u8 cos2 = 0;
6725   u32 cos1_val = 0;
6726   u32 cos2_val = 0;
6727
6728   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6729     if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
6730       src = 1;
6731     else if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
6732       dst = 1;
6733     else if (unformat (input, "proto %U", 
6734                        unformat_ethernet_type_host_byte_order, &proto_val))
6735       proto = 1;
6736     else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
6737       tag1 = 1;
6738     else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
6739       tag2 = 1;
6740     else if (unformat (input, "ignore-tag1"))
6741       ignore_tag1 = 1;
6742     else if (unformat (input, "ignore-tag2"))
6743       ignore_tag2 = 1;
6744     else if (unformat (input, "cos1 %d", &cos1_val))
6745       cos1 = 1;
6746     else if (unformat (input, "cos2 %d", &cos2_val))
6747       cos2 = 1;
6748     else
6749       break;
6750   }
6751   if ((src + dst + proto + tag1 + tag2 +
6752       ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
6753     return 0;
6754
6755   if (tag1 || ignore_tag1 || cos1)
6756     len = 18;
6757   if (tag2 || ignore_tag2 || cos2)
6758     len = 22;
6759
6760   vec_validate_aligned (match, len-1, sizeof(u32x4));
6761
6762   if (dst)
6763     clib_memcpy (match, dst_val, 6);
6764
6765   if (src)
6766     clib_memcpy (match + 6, src_val, 6);
6767   
6768   if (tag2)
6769     {
6770       /* inner vlan tag */
6771       match[19] = tag2_val[1];
6772       match[18] = tag2_val[0];
6773       if (cos2)
6774         match [18] |= (cos2_val & 0x7) << 5;
6775       if (proto)
6776         {
6777           match[21] = proto_val & 0xff;
6778           match[20] = proto_val >> 8;
6779         }
6780       if (tag1)
6781         {
6782           match [15] = tag1_val[1];
6783           match [14] = tag1_val[0];
6784         }
6785       if (cos1)
6786         match [14] |= (cos1_val & 0x7) << 5;
6787       *matchp = match;
6788       return 1;
6789     }
6790   if (tag1)
6791     {
6792       match [15] = tag1_val[1];
6793       match [14] = tag1_val[0];
6794       if (proto)
6795         {
6796           match[17] = proto_val & 0xff;
6797           match[16] = proto_val >> 8;
6798         }
6799       if (cos1)
6800         match [14] |= (cos1_val & 0x7) << 5;
6801
6802       *matchp = match;
6803       return 1;
6804     }
6805   if (cos2)
6806     match [18] |= (cos2_val & 0x7) << 5;
6807   if (cos1)
6808     match [14] |= (cos1_val & 0x7) << 5;
6809   if (proto)
6810     {
6811       match[13] = proto_val & 0xff;
6812       match[12] = proto_val >> 8;
6813     }
6814   
6815   *matchp = match;
6816   return 1;
6817 }
6818
6819
6820 uword unformat_classify_match (unformat_input_t * input, va_list * args)
6821 {
6822   u8 ** matchp = va_arg (*args, u8 **);
6823   u32 skip_n_vectors = va_arg (*args, u32);
6824   u32 match_n_vectors = va_arg (*args, u32);
6825   
6826   u8 * match = 0;
6827   u8 * l2 = 0;
6828   u8 * l3 = 0;
6829
6830   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
6831     if (unformat (input, "hex %U", unformat_hex_string, &match))
6832       ;
6833     else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
6834       ;
6835     else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
6836       ;
6837     else
6838       break;
6839   }
6840
6841   if (match || l2 || l3)
6842     {
6843       if (l2 || l3)
6844         {
6845           /* "Win a free Ethernet header in every packet" */
6846           if (l2 == 0)
6847             vec_validate_aligned (l2, 13, sizeof(u32x4));
6848           match = l2;
6849           vec_append_aligned (match, l3, sizeof(u32x4));
6850           vec_free (l3);
6851         }
6852
6853       /* Make sure the vector is big enough even if key is all 0's */
6854       vec_validate_aligned 
6855           (match, ((match_n_vectors + skip_n_vectors) * sizeof(u32x4)) - 1,
6856            sizeof(u32x4));
6857       
6858       /* Set size, include skipped vectors*/
6859       _vec_len (match) = (match_n_vectors+skip_n_vectors) * sizeof(u32x4);
6860
6861       *matchp = match;
6862
6863       return 1;
6864     }
6865
6866   return 0;
6867 }
6868
6869 static int api_classify_add_del_session (vat_main_t * vam)
6870 {
6871     unformat_input_t * i = vam->input;
6872     vl_api_classify_add_del_session_t *mp;
6873     int is_add = 1;
6874     u32 table_index = ~0;
6875     u32 hit_next_index = ~0;
6876     u32 opaque_index = ~0;
6877     u8 * match = 0;
6878     i32 advance = 0;
6879     f64 timeout;
6880     u32 skip_n_vectors = 0;
6881     u32 match_n_vectors = 0;
6882
6883     /* 
6884      * Warning: you have to supply skip_n and match_n
6885      * because the API client cant simply look at the classify
6886      * table object.
6887      */
6888
6889     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6890         if (unformat (i, "del"))
6891             is_add = 0;
6892         else if (unformat (i, "hit-next %U", unformat_ip_next_index,
6893                            &hit_next_index))
6894             ;
6895         else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
6896                            &hit_next_index))
6897             ;
6898         else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
6899                            &hit_next_index))
6900             ;
6901         else if (unformat (i, "opaque-index %d", &opaque_index))
6902             ;
6903         else if (unformat (i, "skip_n %d", &skip_n_vectors))
6904             ;
6905         else if (unformat (i, "match_n %d", &match_n_vectors))
6906             ;
6907         else if (unformat (i, "match %U", unformat_classify_match,
6908                            &match, skip_n_vectors, match_n_vectors))
6909             ;
6910         else if (unformat (i, "advance %d", &advance))
6911             ;
6912         else if (unformat (i, "table-index %d", &table_index))
6913             ;
6914         else
6915             break;
6916     }
6917
6918     if (table_index == ~0) {
6919         errmsg ("Table index required\n");
6920         return -99;
6921     }
6922
6923     if (is_add && match == 0) {
6924         errmsg ("Match value required\n");
6925         return -99;
6926     }
6927
6928     M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session,
6929         vec_len(match));
6930
6931     mp->is_add = is_add;
6932     mp->table_index = ntohl(table_index);
6933     mp->hit_next_index = ntohl(hit_next_index);
6934     mp->opaque_index = ntohl(opaque_index);
6935     mp->advance = ntohl(advance);
6936     clib_memcpy (mp->match, match, vec_len(match));
6937     vec_free(match);
6938
6939     S; W;
6940     /* NOTREACHED */
6941 }
6942
6943 static int api_classify_set_interface_ip_table (vat_main_t * vam)
6944 {
6945     unformat_input_t * i = vam->input;
6946     vl_api_classify_set_interface_ip_table_t *mp;
6947     f64 timeout;
6948     u32 sw_if_index;
6949     int sw_if_index_set;
6950     u32 table_index = ~0;
6951     u8  is_ipv6 = 0;
6952
6953     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6954         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6955             sw_if_index_set = 1;
6956         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6957             sw_if_index_set = 1;
6958         else if (unformat (i, "table %d", &table_index))
6959             ;
6960         else {
6961             clib_warning ("parse error '%U'", format_unformat_error, i);
6962             return -99;
6963         }
6964     }
6965     
6966     if (sw_if_index_set == 0) {
6967         errmsg ("missing interface name or sw_if_index\n");
6968         return -99;
6969     }
6970
6971
6972     M(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
6973
6974     mp->sw_if_index = ntohl(sw_if_index);
6975     mp->table_index = ntohl(table_index);
6976     mp->is_ipv6 = is_ipv6;
6977
6978     S; W;
6979     /* NOTREACHED */
6980     return 0;
6981 }
6982
6983 static int api_classify_set_interface_l2_tables (vat_main_t * vam)
6984 {
6985     unformat_input_t * i = vam->input;
6986     vl_api_classify_set_interface_l2_tables_t *mp;
6987     f64 timeout;
6988     u32 sw_if_index;
6989     int sw_if_index_set;
6990     u32 ip4_table_index = ~0;
6991     u32 ip6_table_index = ~0;
6992     u32 other_table_index = ~0;
6993
6994     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
6995         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6996             sw_if_index_set = 1;
6997         else if (unformat (i, "sw_if_index %d", &sw_if_index))
6998             sw_if_index_set = 1;
6999         else if (unformat (i, "ip4-table %d", &ip4_table_index))
7000             ;
7001         else if (unformat (i, "ip6-table %d", &ip6_table_index))
7002             ;
7003         else if (unformat (i, "other-table %d", &other_table_index))
7004             ;
7005         else {
7006             clib_warning ("parse error '%U'", format_unformat_error, i);
7007             return -99;
7008         }
7009     }
7010     
7011     if (sw_if_index_set == 0) {
7012         errmsg ("missing interface name or sw_if_index\n");
7013         return -99;
7014     }
7015
7016
7017     M(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
7018
7019     mp->sw_if_index = ntohl(sw_if_index);
7020     mp->ip4_table_index = ntohl(ip4_table_index);
7021     mp->ip6_table_index = ntohl(ip6_table_index);
7022     mp->other_table_index = ntohl(other_table_index);
7023
7024
7025     S; W;
7026     /* NOTREACHED */
7027     return 0;
7028 }
7029
7030 static int api_get_node_index (vat_main_t * vam)
7031 {
7032     unformat_input_t * i = vam->input;
7033     vl_api_get_node_index_t * mp;
7034     f64 timeout;
7035     u8 * name = 0;
7036     
7037     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7038         if (unformat (i, "node %s", &name))
7039             ;
7040         else
7041             break;
7042     }
7043     if (name == 0) {
7044         errmsg ("node name required\n");
7045         return -99;
7046     }
7047     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7048         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7049         return -99;
7050     }
7051
7052     M(GET_NODE_INDEX, get_node_index);
7053     clib_memcpy (mp->node_name, name, vec_len(name));
7054     vec_free(name);
7055     
7056     S; W;
7057     /* NOTREACHED */
7058     return 0;
7059 }
7060
7061 static int api_add_node_next (vat_main_t * vam)
7062 {
7063     unformat_input_t * i = vam->input;
7064     vl_api_add_node_next_t * mp;
7065     f64 timeout;
7066     u8 * name = 0;
7067     u8 * next = 0;
7068
7069     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7070         if (unformat (i, "node %s", &name))
7071             ;
7072         else if (unformat (i, "next %s", &next))
7073             ;
7074         else
7075             break;
7076     }
7077     if (name == 0) {
7078         errmsg ("node name required\n");
7079         return -99;
7080     }
7081     if (vec_len (name) >= ARRAY_LEN(mp->node_name)) {
7082         errmsg ("node name too long, max %d\n", ARRAY_LEN(mp->node_name));
7083         return -99;
7084     }
7085     if (next == 0) {
7086         errmsg ("next node required\n");
7087         return -99;
7088     }
7089     if (vec_len (next) >= ARRAY_LEN(mp->next_name)) {
7090         errmsg ("next name too long, max %d\n", ARRAY_LEN(mp->next_name));
7091         return -99;
7092     }
7093     
7094     M(ADD_NODE_NEXT, add_node_next);
7095     clib_memcpy (mp->node_name, name, vec_len(name));
7096     clib_memcpy (mp->next_name, next, vec_len(next));
7097     vec_free(name);
7098     vec_free(next);
7099     
7100     S; W;
7101     /* NOTREACHED */
7102     return 0;
7103 }
7104
7105 static int api_l2tpv3_create_tunnel (vat_main_t * vam)
7106 {
7107     unformat_input_t * i = vam->input;
7108     ip6_address_t client_address, our_address;
7109     int client_address_set = 0;
7110     int our_address_set = 0;
7111     u32 local_session_id = 0;
7112     u32 remote_session_id = 0;
7113     u64 local_cookie = 0;
7114     u64 remote_cookie = 0;
7115     u8 l2_sublayer_present = 0;
7116     vl_api_l2tpv3_create_tunnel_t * mp;
7117     f64 timeout;
7118
7119     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7120         if (unformat (i, "client_address %U", unformat_ip6_address, 
7121                       &client_address))
7122             client_address_set = 1;
7123         else if (unformat (i, "our_address %U", unformat_ip6_address, 
7124                            &our_address))
7125             our_address_set = 1;
7126         else if (unformat (i, "local_session_id %d", &local_session_id))
7127             ;
7128         else if (unformat (i, "remote_session_id %d", &remote_session_id))
7129             ;
7130         else if (unformat (i, "local_cookie %lld", &local_cookie))
7131             ;
7132         else if (unformat (i, "remote_cookie %lld", &remote_cookie))
7133             ;
7134         else if (unformat (i, "l2-sublayer-present"))
7135             l2_sublayer_present = 1;
7136         else
7137             break;
7138     }
7139
7140     if (client_address_set == 0) {
7141         errmsg ("client_address required\n");
7142         return -99;
7143     }
7144
7145     if (our_address_set == 0) {
7146         errmsg ("our_address required\n");
7147         return -99;
7148     }
7149
7150     M(L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
7151
7152     clib_memcpy (mp->client_address, client_address.as_u8, 
7153             sizeof (mp->client_address));
7154
7155     clib_memcpy (mp->our_address, our_address.as_u8, 
7156             sizeof (mp->our_address));
7157     
7158     mp->local_session_id = ntohl (local_session_id);
7159     mp->remote_session_id = ntohl (remote_session_id);
7160     mp->local_cookie = clib_host_to_net_u64 (local_cookie);
7161     mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
7162     mp->l2_sublayer_present = l2_sublayer_present;
7163     mp->is_ipv6 = 1;
7164
7165     S; W;
7166     /* NOTREACHED */
7167     return 0;
7168 }
7169
7170 static int api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
7171 {
7172     unformat_input_t * i = vam->input;
7173     u32 sw_if_index;
7174     u8  sw_if_index_set = 0;
7175     u64 new_local_cookie = 0;
7176     u64 new_remote_cookie = 0;
7177     vl_api_l2tpv3_set_tunnel_cookies_t *mp;
7178     f64 timeout;
7179
7180     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7181         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7182             sw_if_index_set = 1;
7183         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7184             sw_if_index_set = 1;
7185         else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
7186             ;
7187         else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
7188             ;
7189         else
7190             break;
7191     }
7192
7193     if (sw_if_index_set == 0) {
7194         errmsg ("missing interface name or sw_if_index\n");
7195         return -99;
7196     }
7197
7198     M(L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
7199
7200     mp->sw_if_index = ntohl(sw_if_index);
7201     mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
7202     mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
7203
7204     S; W;
7205     /* NOTREACHED */
7206     return 0;
7207 }
7208
7209 static int api_l2tpv3_interface_enable_disable (vat_main_t * vam)
7210 {
7211     unformat_input_t * i = vam->input;
7212     vl_api_l2tpv3_interface_enable_disable_t *mp;
7213     f64 timeout;
7214     u32 sw_if_index;
7215     u8  sw_if_index_set = 0;
7216     u8  enable_disable = 1;
7217
7218     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7219         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7220             sw_if_index_set = 1;
7221         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7222             sw_if_index_set = 1;
7223         else if (unformat (i, "enable"))
7224             enable_disable = 1;
7225         else if (unformat (i, "disable"))
7226             enable_disable = 0;
7227         else
7228             break;
7229     }
7230
7231     if (sw_if_index_set == 0) {
7232         errmsg ("missing interface name or sw_if_index\n");
7233         return -99;
7234     }
7235     
7236     M(L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
7237
7238     mp->sw_if_index = ntohl(sw_if_index);
7239     mp->enable_disable = enable_disable;
7240
7241     S; W;
7242     /* NOTREACHED */
7243     return 0;
7244 }
7245
7246 static int api_l2tpv3_set_lookup_key (vat_main_t * vam)
7247 {
7248     unformat_input_t * i = vam->input;
7249     vl_api_l2tpv3_set_lookup_key_t * mp;
7250     f64 timeout;
7251     u8 key = ~0;
7252
7253     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7254         if (unformat (i, "lookup_v6_src"))
7255             key = L2T_LOOKUP_SRC_ADDRESS;
7256         else if (unformat (i, "lookup_v6_dst"))
7257             key = L2T_LOOKUP_DST_ADDRESS;
7258         else if (unformat (i, "lookup_session_id"))
7259             key = L2T_LOOKUP_SESSION_ID;
7260         else
7261             break;
7262     }
7263
7264     if (key == (u8) ~0) {
7265         errmsg ("l2tp session lookup key unset\n");
7266         return -99;
7267     }
7268     
7269     M(L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
7270
7271     mp->key = key;
7272
7273     S; W;
7274     /* NOTREACHED */
7275     return 0;
7276 }
7277
7278 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
7279 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7280 {
7281     vat_main_t * vam = &vat_main;
7282
7283     fformat(vam->ofp,  "* %U (our) %U (client) (sw_if_index %d)\n",
7284               format_ip6_address, mp->our_address,
7285               format_ip6_address, mp->client_address,
7286               clib_net_to_host_u32(mp->sw_if_index));
7287
7288     fformat (vam->ofp, "   local cookies %016llx %016llx remote cookie %016llx\n",
7289               clib_net_to_host_u64 (mp->local_cookie[0]),
7290               clib_net_to_host_u64 (mp->local_cookie[1]),
7291               clib_net_to_host_u64 (mp->remote_cookie));
7292
7293     fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
7294               clib_net_to_host_u32 (mp->local_session_id),
7295               clib_net_to_host_u32 (mp->remote_session_id));
7296
7297     fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
7298               mp->l2_sublayer_present ? "preset" : "absent");
7299
7300 }
7301
7302 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
7303 (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
7304 {
7305     vat_main_t * vam = &vat_main;
7306     vat_json_node_t *node = NULL;
7307     struct in6_addr addr;
7308
7309     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7310         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7311         vat_json_init_array(&vam->json_tree);
7312     }
7313     node = vat_json_array_add(&vam->json_tree);
7314
7315     vat_json_init_object(node);
7316
7317     clib_memcpy(&addr, mp->our_address, sizeof(addr));
7318     vat_json_object_add_ip6(node, "our_address", addr);
7319     clib_memcpy(&addr, mp->client_address, sizeof(addr));
7320     vat_json_object_add_ip6(node, "client_address", addr);
7321
7322     vat_json_node_t * lc = vat_json_object_add(node, "local_cookie");
7323     vat_json_init_array(lc);
7324     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[0]));
7325     vat_json_array_add_uint(lc, clib_net_to_host_u64(mp->local_cookie[1]));
7326     vat_json_object_add_uint(node, "remote_cookie", clib_net_to_host_u64(mp->remote_cookie));
7327
7328     printf("local id: %u", clib_net_to_host_u32(mp->local_session_id));
7329     vat_json_object_add_uint(node, "local_session_id", clib_net_to_host_u32(mp->local_session_id));
7330     vat_json_object_add_uint(node, "remote_session_id", clib_net_to_host_u32(mp->remote_session_id));
7331     vat_json_object_add_string_copy(node, "l2_sublayer", mp->l2_sublayer_present ?
7332             (u8*)"present" : (u8*)"absent");
7333 }
7334
7335 static int api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
7336 {
7337     vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
7338     f64 timeout;
7339
7340     /* Get list of l2tpv3-tunnel interfaces */
7341     M(SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
7342     S;
7343
7344     /* Use a control ping for synchronization */
7345     {
7346         vl_api_control_ping_t * mp;
7347         M(CONTROL_PING, control_ping);
7348         S;
7349     }
7350     W;
7351 }
7352
7353
7354 static void vl_api_sw_interface_tap_details_t_handler
7355 (vl_api_sw_interface_tap_details_t * mp)
7356 {
7357     vat_main_t * vam = &vat_main;
7358
7359     fformat(vam->ofp,  "%-16s %d\n",
7360               mp->dev_name,
7361               clib_net_to_host_u32(mp->sw_if_index));
7362 }
7363
7364 static void vl_api_sw_interface_tap_details_t_handler_json
7365 (vl_api_sw_interface_tap_details_t * mp)
7366 {
7367     vat_main_t * vam = &vat_main;
7368     vat_json_node_t *node = NULL;
7369
7370     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7371         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7372         vat_json_init_array(&vam->json_tree);
7373     }
7374     node = vat_json_array_add(&vam->json_tree);
7375
7376     vat_json_init_object(node);
7377     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7378     vat_json_object_add_string_copy(node, "dev_name", mp->dev_name);
7379 }
7380
7381 static int api_sw_interface_tap_dump (vat_main_t * vam)
7382 {
7383     vl_api_sw_interface_tap_dump_t *mp;
7384     f64 timeout;
7385
7386     fformat(vam->ofp,  "\n%-16s %s\n", "dev_name", "sw_if_index");
7387     /* Get list of tap interfaces */
7388     M(SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
7389     S;
7390
7391     /* Use a control ping for synchronization */
7392     {
7393         vl_api_control_ping_t * mp;
7394         M(CONTROL_PING, control_ping);
7395         S;
7396     }
7397     W;
7398 }
7399
7400 static uword unformat_vxlan_decap_next 
7401 (unformat_input_t * input, va_list * args)
7402 {
7403   u32 * result = va_arg (*args, u32 *);
7404   u32 tmp;
7405   
7406   if (unformat (input, "drop"))
7407     *result = VXLAN_INPUT_NEXT_DROP;
7408   else if (unformat (input, "ip4"))
7409     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
7410   else if (unformat (input, "ip6"))
7411     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
7412   else if (unformat (input, "l2"))
7413     *result = VXLAN_INPUT_NEXT_L2_INPUT;
7414   else if (unformat (input, "%d", &tmp))
7415     *result = tmp;
7416   else
7417     return 0;
7418   return 1;
7419 }
7420
7421 static int api_vxlan_add_del_tunnel (vat_main_t * vam)
7422 {
7423     unformat_input_t * line_input = vam->input;
7424     vl_api_vxlan_add_del_tunnel_t *mp;
7425     f64 timeout;
7426     ip4_address_t src4, dst4;
7427     ip6_address_t src6, dst6;
7428     u8 is_add = 1;
7429     u8 ipv4_set = 0, ipv6_set = 0;
7430     u8 src_set = 0;
7431     u8 dst_set = 0;
7432     u32 encap_vrf_id = 0;
7433     u32 decap_next_index = ~0;
7434     u32 vni = 0;
7435
7436     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7437         if (unformat (line_input, "del"))
7438             is_add = 0;
7439         else if (unformat (line_input, "src %U", 
7440                            unformat_ip4_address, &src4))
7441           {
7442             ipv4_set = 1;
7443             src_set = 1;
7444           }
7445         else if (unformat (line_input, "dst %U",
7446                            unformat_ip4_address, &dst4))
7447           {
7448             ipv4_set = 1;
7449             dst_set = 1;
7450           }
7451         else if (unformat (line_input, "src %U", 
7452                            unformat_ip6_address, &src6))
7453           {
7454             ipv6_set = 1;
7455             src_set = 1;
7456           }
7457         else if (unformat (line_input, "dst %U",
7458                            unformat_ip6_address, &dst6))
7459           {
7460             ipv6_set = 1;
7461             dst_set = 1;
7462           }
7463         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
7464             ;
7465         else if (unformat (line_input, "decap-next %U", 
7466                            unformat_vxlan_decap_next, &decap_next_index))
7467             ;
7468         else if (unformat (line_input, "vni %d", &vni))
7469             ;
7470         else {
7471             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7472             return -99;
7473         }
7474     }
7475
7476     if (src_set == 0) {
7477         errmsg ("tunnel src address not specified\n");
7478         return -99;
7479     }
7480     if (dst_set == 0) {
7481         errmsg ("tunnel dst address not specified\n");
7482         return -99;
7483     }
7484
7485     if (ipv4_set && ipv6_set) {
7486         errmsg ("both IPv4 and IPv6 addresses specified");
7487         return -99;
7488     }
7489
7490     if ((vni == 0) || (vni>>24)) {
7491         errmsg ("vni not specified or out of range\n");
7492         return -99;
7493     }
7494
7495     M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
7496
7497     if (ipv6_set) {
7498         clib_memcpy(&mp->src_address, &src6, sizeof(src6));
7499         clib_memcpy(&mp->dst_address, &dst6, sizeof(dst6));
7500     } else { 
7501         clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7502         clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7503     }
7504     mp->encap_vrf_id = ntohl(encap_vrf_id);
7505     mp->decap_next_index = ntohl(decap_next_index);
7506     mp->vni = ntohl(vni);
7507     mp->is_add = is_add;
7508     mp->is_ipv6 = ipv6_set;
7509
7510     S; W;
7511     /* NOTREACHED */
7512     return 0;
7513 }
7514
7515 static void vl_api_vxlan_tunnel_details_t_handler
7516 (vl_api_vxlan_tunnel_details_t * mp)
7517 {
7518     vat_main_t * vam = &vat_main;
7519
7520     fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
7521             ntohl(mp->sw_if_index),
7522             format_ip46_address, &(mp->src_address[0]),
7523             format_ip46_address, &(mp->dst_address[0]),
7524             ntohl(mp->encap_vrf_id),
7525             ntohl(mp->decap_next_index),
7526             ntohl(mp->vni));
7527 }
7528
7529 static void vl_api_vxlan_tunnel_details_t_handler_json
7530 (vl_api_vxlan_tunnel_details_t * mp)
7531 {
7532     vat_main_t * vam = &vat_main;
7533     vat_json_node_t *node = NULL;
7534     struct in_addr ip4;
7535     struct in6_addr ip6;
7536
7537     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7538         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7539         vat_json_init_array(&vam->json_tree);
7540     }
7541     node = vat_json_array_add(&vam->json_tree);
7542
7543     vat_json_init_object(node);
7544     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7545     if (mp->is_ipv6) {
7546         clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
7547         vat_json_object_add_ip6(node, "src_address", ip6);
7548         clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
7549         vat_json_object_add_ip6(node, "dst_address", ip6);
7550     } else {
7551         clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
7552         vat_json_object_add_ip4(node, "src_address", ip4);
7553         clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
7554         vat_json_object_add_ip4(node, "dst_address", ip4);
7555     }
7556     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
7557     vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
7558     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
7559     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
7560 }
7561
7562 static int api_vxlan_tunnel_dump (vat_main_t * vam)
7563 {
7564     unformat_input_t * i = vam->input;
7565     vl_api_vxlan_tunnel_dump_t *mp;
7566     f64 timeout;
7567     u32 sw_if_index;
7568     u8 sw_if_index_set = 0;
7569
7570     /* Parse args required to build the message */
7571     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7572         if (unformat (i, "sw_if_index %d", &sw_if_index))
7573             sw_if_index_set = 1;
7574         else
7575             break;
7576     }
7577
7578     if (sw_if_index_set == 0) {
7579         sw_if_index = ~0;
7580     }
7581
7582     if (!vam->json_output) {
7583         fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
7584                 "sw_if_index", "src_address", "dst_address",
7585                 "encap_vrf_id", "decap_next_index", "vni");
7586     }
7587
7588     /* Get list of vxlan-tunnel interfaces */
7589     M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
7590
7591     mp->sw_if_index = htonl(sw_if_index);
7592
7593     S;
7594
7595     /* Use a control ping for synchronization */
7596     {
7597         vl_api_control_ping_t * mp;
7598         M(CONTROL_PING, control_ping);
7599         S;
7600     }
7601     W;
7602 }
7603
7604 static int api_gre_add_del_tunnel (vat_main_t * vam)
7605 {
7606     unformat_input_t * line_input = vam->input;
7607     vl_api_gre_add_del_tunnel_t *mp;
7608     f64 timeout;
7609     ip4_address_t src4, dst4;
7610     u8 is_add = 1;
7611     u8 src_set = 0;
7612     u8 dst_set = 0;
7613     u32 outer_fib_id = 0;
7614
7615     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
7616         if (unformat (line_input, "del"))
7617             is_add = 0;
7618         else if (unformat (line_input, "src %U",
7619                            unformat_ip4_address, &src4))
7620             src_set = 1;
7621         else if (unformat (line_input, "dst %U",
7622                            unformat_ip4_address, &dst4))
7623             dst_set = 1;
7624         else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
7625             ;
7626         else {
7627             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
7628             return -99;
7629         }
7630     }
7631
7632     if (src_set == 0) {
7633         errmsg ("tunnel src address not specified\n");
7634         return -99;
7635     }
7636     if (dst_set == 0) {
7637         errmsg ("tunnel dst address not specified\n");
7638         return -99;
7639     }
7640
7641
7642     M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
7643
7644     clib_memcpy(&mp->src_address, &src4, sizeof(src4));
7645     clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
7646     mp->outer_table_id = ntohl(outer_fib_id);
7647     mp->is_add = is_add;
7648
7649     S; W;
7650     /* NOTREACHED */
7651     return 0;
7652 }
7653
7654 static void vl_api_gre_tunnel_details_t_handler
7655 (vl_api_gre_tunnel_details_t * mp)
7656 {
7657     vat_main_t * vam = &vat_main;
7658
7659     fformat(vam->ofp, "%11d%15U%15U%14d\n",
7660             ntohl(mp->sw_if_index),
7661             format_ip4_address, &mp->src_address,
7662             format_ip4_address, &mp->dst_address,
7663             ntohl(mp->outer_table_id));
7664 }
7665
7666 static void vl_api_gre_tunnel_details_t_handler_json
7667 (vl_api_gre_tunnel_details_t * mp)
7668 {
7669     vat_main_t * vam = &vat_main;
7670     vat_json_node_t *node = NULL;
7671     struct in_addr ip4;
7672
7673     if (VAT_JSON_ARRAY != vam->json_tree.type) {
7674         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
7675         vat_json_init_array(&vam->json_tree);
7676     }
7677     node = vat_json_array_add(&vam->json_tree);
7678
7679     vat_json_init_object(node);
7680     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
7681     clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
7682     vat_json_object_add_ip4(node, "src_address", ip4);
7683     clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
7684     vat_json_object_add_ip4(node, "dst_address", ip4);
7685     vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
7686 }
7687
7688 static int api_gre_tunnel_dump (vat_main_t * vam)
7689 {
7690     unformat_input_t * i = vam->input;
7691     vl_api_gre_tunnel_dump_t *mp;
7692     f64 timeout;
7693     u32 sw_if_index;
7694     u8 sw_if_index_set = 0;
7695
7696     /* Parse args required to build the message */
7697     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7698         if (unformat (i, "sw_if_index %d", &sw_if_index))
7699             sw_if_index_set = 1;
7700         else
7701             break;
7702     }
7703
7704     if (sw_if_index_set == 0) {
7705         sw_if_index = ~0;
7706     }
7707
7708     if (!vam->json_output) {
7709         fformat(vam->ofp, "%11s%15s%15s%14s\n",
7710                 "sw_if_index", "src_address", "dst_address",
7711                 "outer_fib_id");
7712     }
7713
7714     /* Get list of gre-tunnel interfaces */
7715     M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
7716
7717     mp->sw_if_index = htonl(sw_if_index);
7718
7719     S;
7720
7721     /* Use a control ping for synchronization */
7722     {
7723         vl_api_control_ping_t * mp;
7724         M(CONTROL_PING, control_ping);
7725         S;
7726     }
7727     W;
7728 }
7729
7730 static int api_l2_fib_clear_table (vat_main_t * vam)
7731 {
7732 //  unformat_input_t * i = vam->input;
7733     vl_api_l2_fib_clear_table_t *mp;
7734     f64 timeout;
7735
7736     M(L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
7737
7738     S; W;
7739     /* NOTREACHED */
7740     return 0;
7741 }
7742
7743 static int api_l2_interface_efp_filter (vat_main_t * vam)
7744 {
7745     unformat_input_t * i = vam->input;
7746     vl_api_l2_interface_efp_filter_t *mp;
7747     f64 timeout;
7748     u32 sw_if_index;
7749     u8 enable = 1;
7750     u8 sw_if_index_set = 0;
7751
7752     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7753         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7754             sw_if_index_set = 1;
7755         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7756             sw_if_index_set = 1;
7757         else if (unformat (i, "enable"))
7758             enable = 1;
7759         else if (unformat (i, "disable"))
7760             enable = 0;
7761         else {
7762             clib_warning ("parse error '%U'", format_unformat_error, i);
7763             return -99;
7764         }
7765     }
7766     
7767     if (sw_if_index_set == 0) {
7768         errmsg ("missing sw_if_index\n");
7769         return -99;
7770     }
7771
7772     M(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
7773
7774     mp->sw_if_index = ntohl(sw_if_index);
7775     mp->enable_disable = enable;
7776
7777     S; W;
7778     /* NOTREACHED */
7779     return 0;
7780 }
7781
7782 #define foreach_vtr_op                          \
7783 _("disable",  L2_VTR_DISABLED)                  \
7784 _("push-1",  L2_VTR_PUSH_1)                     \
7785 _("push-2",  L2_VTR_PUSH_2)                     \
7786 _("pop-1",  L2_VTR_POP_1)                       \
7787 _("pop-2",  L2_VTR_POP_2)                       \
7788 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
7789 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
7790 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
7791 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
7792
7793 static int api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
7794 {
7795     unformat_input_t * i = vam->input;
7796     vl_api_l2_interface_vlan_tag_rewrite_t *mp;
7797     f64 timeout;
7798     u32 sw_if_index;
7799     u8 sw_if_index_set = 0;
7800     u8 vtr_op_set = 0;
7801     u32 vtr_op = 0;
7802     u32 push_dot1q = 1;
7803     u32 tag1 = ~0;
7804     u32 tag2 = ~0;
7805
7806     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7807         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7808             sw_if_index_set = 1;
7809         else if (unformat (i, "sw_if_index %d", &sw_if_index))
7810             sw_if_index_set = 1;
7811         else if (unformat (i, "vtr_op %d", &vtr_op))
7812             vtr_op_set = 1;
7813 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
7814         foreach_vtr_op
7815 #undef _
7816         
7817         else if (unformat (i, "push_dot1q %d", &push_dot1q))
7818             ;
7819         else if (unformat (i, "tag1 %d", &tag1))
7820             ;
7821         else if (unformat (i, "tag2 %d", &tag2))
7822             ;
7823         else {
7824             clib_warning ("parse error '%U'", format_unformat_error, i);
7825             return -99;
7826         }
7827     }
7828     
7829     if ((sw_if_index_set == 0)||(vtr_op_set == 0)) {
7830         errmsg ("missing vtr operation or sw_if_index\n");
7831         return -99;
7832     }
7833
7834     M(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
7835
7836     mp->sw_if_index = ntohl(sw_if_index);
7837     mp->vtr_op = ntohl(vtr_op);
7838     mp->push_dot1q = ntohl(push_dot1q);
7839     mp->tag1 = ntohl(tag1);
7840     mp->tag2 = ntohl(tag2);
7841
7842     S; W;
7843     /* NOTREACHED */
7844     return 0;
7845 }
7846
7847 static int api_create_vhost_user_if (vat_main_t * vam)
7848 {
7849     unformat_input_t * i = vam->input;
7850     vl_api_create_vhost_user_if_t *mp;
7851     f64 timeout;
7852     u8 * file_name;
7853     u8 is_server = 0;
7854     u8 file_name_set = 0;
7855     u32 custom_dev_instance = ~0;
7856     u8 hwaddr[6];
7857     u8 use_custom_mac = 0;
7858
7859     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7860       if (unformat (i, "socket %s", &file_name)) {
7861         file_name_set = 1;
7862       }
7863       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7864         ;
7865       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
7866         use_custom_mac = 1;
7867       else if (unformat (i, "server"))
7868         is_server = 1;
7869       else
7870         break;
7871     }
7872
7873     if (file_name_set == 0) {
7874       errmsg ("missing socket file name\n");
7875       return -99;
7876     }
7877
7878     if (vec_len (file_name) > 255) {
7879       errmsg ("socket file name too long\n");
7880       return -99;
7881     }
7882     vec_add1 (file_name, 0);
7883
7884     M(CREATE_VHOST_USER_IF, create_vhost_user_if);
7885
7886     mp->is_server = is_server;
7887     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
7888     vec_free(file_name);
7889     if (custom_dev_instance != ~0) {
7890         mp->renumber = 1;
7891         mp->custom_dev_instance = ntohl(custom_dev_instance);
7892     }
7893     mp->use_custom_mac = use_custom_mac;
7894     clib_memcpy(mp->mac_address, hwaddr, 6);
7895
7896     S; W;
7897     /* NOTREACHED */
7898     return 0;
7899 }
7900
7901 static int api_modify_vhost_user_if (vat_main_t * vam)
7902 {
7903     unformat_input_t * i = vam->input;
7904     vl_api_modify_vhost_user_if_t *mp;
7905     f64 timeout;
7906     u8 * file_name;
7907     u8 is_server = 0;
7908     u8 file_name_set = 0;
7909     u32 custom_dev_instance = ~0;
7910     u8 sw_if_index_set = 0;
7911     u32 sw_if_index = (u32)~0;
7912
7913     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7914       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7915           sw_if_index_set = 1;
7916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917           sw_if_index_set = 1;
7918       else if (unformat (i, "socket %s", &file_name)) {
7919         file_name_set = 1;
7920       }
7921       else if (unformat (i, "renumber %"PRIu32, &custom_dev_instance))
7922         ;
7923       else if (unformat (i, "server"))
7924         is_server = 1;
7925       else
7926         break;
7927     }
7928
7929     if (sw_if_index_set == 0) {
7930        errmsg ("missing sw_if_index or interface name\n");
7931        return -99;
7932     }
7933
7934     if (file_name_set == 0) {
7935       errmsg ("missing socket file name\n");
7936       return -99;
7937     }
7938
7939     if (vec_len (file_name) > 255) {
7940       errmsg ("socket file name too long\n");
7941       return -99;
7942     }
7943     vec_add1 (file_name, 0);
7944
7945     M(MODIFY_VHOST_USER_IF, modify_vhost_user_if);
7946
7947     mp->sw_if_index = ntohl(sw_if_index);
7948     mp->is_server = is_server;
7949     clib_memcpy(mp->sock_filename, file_name, vec_len(file_name));
7950     vec_free(file_name);
7951     if (custom_dev_instance != ~0) {
7952         mp->renumber = 1;
7953         mp->custom_dev_instance = ntohl(custom_dev_instance);
7954     }
7955
7956     S; W;
7957     /* NOTREACHED */
7958     return 0;
7959 }
7960
7961 static int api_delete_vhost_user_if (vat_main_t * vam)
7962 {
7963     unformat_input_t * i = vam->input;
7964     vl_api_delete_vhost_user_if_t *mp;
7965     f64 timeout;
7966     u32 sw_if_index = ~0;
7967     u8 sw_if_index_set = 0;
7968
7969     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
7970       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7971           sw_if_index_set = 1;
7972       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7973           sw_if_index_set = 1;
7974       else
7975         break;
7976     }
7977
7978     if (sw_if_index_set == 0) {
7979        errmsg ("missing sw_if_index or interface name\n");
7980        return -99;
7981     }
7982
7983
7984     M(DELETE_VHOST_USER_IF, delete_vhost_user_if);
7985
7986     mp->sw_if_index = ntohl(sw_if_index);
7987
7988     S; W;
7989     /* NOTREACHED */
7990     return 0;
7991 }
7992
7993 static void vl_api_sw_interface_vhost_user_details_t_handler
7994 (vl_api_sw_interface_vhost_user_details_t * mp)
7995 {
7996     vat_main_t * vam = &vat_main;
7997
7998     fformat(vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
7999             (char *)mp->interface_name,
8000             ntohl(mp->sw_if_index), ntohl(mp->virtio_net_hdr_sz),
8001             clib_net_to_host_u64(mp->features), mp->is_server,
8002             ntohl(mp->num_regions), (char *)mp->sock_filename);
8003     fformat(vam->ofp, "    Status: '%s'\n", strerror(ntohl(mp->sock_errno)));
8004 }
8005
8006 static void vl_api_sw_interface_vhost_user_details_t_handler_json
8007 (vl_api_sw_interface_vhost_user_details_t * mp)
8008 {
8009     vat_main_t * vam = &vat_main;
8010     vat_json_node_t *node = NULL;
8011
8012     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8013         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8014         vat_json_init_array(&vam->json_tree);
8015     }
8016     node = vat_json_array_add(&vam->json_tree);
8017
8018     vat_json_init_object(node);
8019     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8020     vat_json_object_add_string_copy(node, "interface_name", mp->interface_name);
8021     vat_json_object_add_uint(node, "virtio_net_hdr_sz", ntohl(mp->virtio_net_hdr_sz));
8022     vat_json_object_add_uint(node, "features", clib_net_to_host_u64(mp->features));
8023     vat_json_object_add_uint(node, "is_server", mp->is_server);
8024     vat_json_object_add_string_copy(node, "sock_filename", mp->sock_filename);
8025     vat_json_object_add_uint(node, "num_regions", ntohl(mp->num_regions));
8026     vat_json_object_add_uint(node, "sock_errno", ntohl(mp->sock_errno));
8027 }
8028
8029 static int api_sw_interface_vhost_user_dump (vat_main_t * vam)
8030 {
8031     vl_api_sw_interface_vhost_user_dump_t *mp;
8032     f64 timeout;
8033     fformat(vam->ofp, "Interface name           idx hdr_sz features server regions filename\n");
8034
8035     /* Get list of vhost-user interfaces */
8036     M(SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
8037     S;
8038
8039     /* Use a control ping for synchronization */
8040     {
8041         vl_api_control_ping_t * mp;
8042         M(CONTROL_PING, control_ping);
8043         S;
8044     }
8045     W;
8046 }
8047
8048 static int api_show_version (vat_main_t * vam)
8049 {
8050     vl_api_show_version_t *mp;
8051     f64 timeout;
8052
8053     M(SHOW_VERSION, show_version);
8054
8055     S; W;
8056     /* NOTREACHED */
8057     return 0;
8058 }
8059
8060
8061 static int api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
8062 {
8063     unformat_input_t * line_input = vam->input;
8064     vl_api_vxlan_gpe_add_del_tunnel_t *mp;
8065     f64 timeout;
8066     ip4_address_t local4, remote4;
8067     ip6_address_t local6, remote6;
8068     u8 is_add = 1;
8069     u8 ipv4_set = 0, ipv6_set = 0;
8070     u8 local_set = 0;
8071     u8 remote_set = 0;
8072     u32 encap_vrf_id = 0;
8073     u32 decap_vrf_id = 0;
8074     u8 protocol = ~0;
8075     u32 vni;
8076     u8 vni_set = 0;
8077
8078     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8079         if (unformat (line_input, "del"))
8080             is_add = 0;
8081         else if (unformat (line_input, "local %U", 
8082                            unformat_ip4_address, &local4))
8083         {
8084             local_set = 1;
8085             ipv4_set = 1;
8086         }
8087         else if (unformat (line_input, "remote %U",
8088                            unformat_ip4_address, &remote4))
8089         {
8090             remote_set = 1;
8091             ipv4_set = 1;
8092         }
8093         else if (unformat (line_input, "local %U",
8094                            unformat_ip6_address, &local6))
8095         {
8096             local_set = 1;
8097             ipv6_set = 1;
8098         }
8099         else if (unformat (line_input, "remote %U",
8100                            unformat_ip6_address, &remote6))
8101         {
8102             remote_set = 1;
8103             ipv6_set = 1;
8104         }
8105         else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
8106             ;
8107         else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
8108             ;
8109         else if (unformat (line_input, "vni %d", &vni))
8110             vni_set = 1;
8111         else if (unformat(line_input, "next-ip4"))
8112             protocol = 1;
8113         else if (unformat(line_input, "next-ip6"))
8114             protocol = 2;
8115         else if (unformat(line_input, "next-ethernet"))
8116             protocol = 3;
8117         else if (unformat(line_input, "next-nsh"))
8118             protocol = 4;
8119         else {
8120             errmsg ("parse error '%U'\n", format_unformat_error, line_input);
8121             return -99;
8122         }
8123     }
8124
8125     if (local_set == 0) {
8126         errmsg ("tunnel local address not specified\n");
8127         return -99;
8128     }
8129     if (remote_set == 0) {
8130         errmsg ("tunnel remote address not specified\n");
8131         return -99;
8132     }
8133     if (ipv4_set && ipv6_set) {
8134         errmsg ("both IPv4 and IPv6 addresses specified");
8135         return -99;
8136     }
8137
8138     if (vni_set == 0) {
8139         errmsg ("vni not specified\n");
8140         return -99;
8141     }
8142
8143     M(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
8144     
8145
8146     if (ipv6_set) {
8147         clib_memcpy(&mp->local, &local6, sizeof(local6));
8148         clib_memcpy(&mp->remote, &remote6, sizeof(remote6));
8149     } else {
8150         clib_memcpy(&mp->local, &local4, sizeof(local4));
8151         clib_memcpy(&mp->remote, &remote4, sizeof(remote4));
8152     }
8153
8154     mp->encap_vrf_id = ntohl(encap_vrf_id);
8155     mp->decap_vrf_id = ntohl(decap_vrf_id);
8156     mp->protocol = ntohl(protocol);
8157     mp->vni = ntohl(vni);
8158     mp->is_add = is_add;
8159     mp->is_ipv6 = ipv6_set;
8160
8161     S; W;
8162     /* NOTREACHED */
8163     return 0;
8164 }
8165
8166 static void vl_api_vxlan_gpe_tunnel_details_t_handler
8167 (vl_api_vxlan_gpe_tunnel_details_t * mp)
8168 {
8169     vat_main_t * vam = &vat_main;
8170
8171     fformat(vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
8172             ntohl(mp->sw_if_index),
8173             format_ip46_address, &(mp->local[0]),
8174             format_ip46_address, &(mp->remote[0]),
8175                         ntohl(mp->vni),
8176             ntohl(mp->protocol),
8177             ntohl(mp->encap_vrf_id),
8178             ntohl(mp->decap_vrf_id));
8179 }
8180
8181 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
8182 (vl_api_vxlan_gpe_tunnel_details_t * mp)
8183 {
8184     vat_main_t * vam = &vat_main;
8185     vat_json_node_t *node = NULL;
8186     struct in_addr ip4;
8187     struct in6_addr ip6;
8188
8189     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8190         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8191         vat_json_init_array(&vam->json_tree);
8192     }
8193     node = vat_json_array_add(&vam->json_tree);
8194
8195     vat_json_init_object(node);
8196     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8197     if (mp->is_ipv6) {
8198         clib_memcpy(&ip6, &(mp->local[0]), sizeof(ip6));
8199         vat_json_object_add_ip6(node, "local", ip6);
8200         clib_memcpy(&ip6, &(mp->remote[0]), sizeof(ip6));
8201         vat_json_object_add_ip6(node, "remote", ip6);
8202     } else {
8203         clib_memcpy(&ip4, &(mp->local[0]), sizeof(ip4));
8204         vat_json_object_add_ip4(node, "local", ip4);
8205         clib_memcpy(&ip4, &(mp->remote[0]), sizeof(ip4));
8206         vat_json_object_add_ip4(node, "remote", ip4);
8207     }
8208     vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
8209     vat_json_object_add_uint(node, "protocol", ntohl(mp->protocol));
8210     vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
8211     vat_json_object_add_uint(node, "decap_vrf_id", ntohl(mp->decap_vrf_id));
8212     vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
8213 }
8214
8215 static int api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
8216 {
8217     unformat_input_t * i = vam->input;
8218     vl_api_vxlan_gpe_tunnel_dump_t *mp;
8219     f64 timeout;
8220     u32 sw_if_index;
8221     u8 sw_if_index_set = 0;
8222
8223     /* Parse args required to build the message */
8224     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8225         if (unformat (i, "sw_if_index %d", &sw_if_index))
8226             sw_if_index_set = 1;
8227         else
8228             break;
8229     }
8230
8231     if (sw_if_index_set == 0) {
8232         sw_if_index = ~0;
8233     }
8234
8235     if (!vam->json_output) {
8236         fformat(vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
8237                 "sw_if_index", "local", "remote", "vni",
8238                                 "protocol","encap_vrf_id", "decap_vrf_id");
8239     }
8240
8241     /* Get list of vxlan-tunnel interfaces */
8242     M(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
8243
8244     mp->sw_if_index = htonl(sw_if_index);
8245
8246     S;
8247
8248     /* Use a control ping for synchronization */
8249     {
8250         vl_api_control_ping_t * mp;
8251         M(CONTROL_PING, control_ping);
8252         S;
8253     }
8254     W;
8255 }
8256
8257 u8 * format_l2_fib_mac_address (u8 * s, va_list * args)
8258 {
8259   u8 * a = va_arg (*args, u8 *);
8260
8261   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
8262                  a[2], a[3], a[4], a[5], a[6], a[7]);
8263 }
8264
8265 static void vl_api_l2_fib_table_entry_t_handler
8266 (vl_api_l2_fib_table_entry_t * mp)
8267 {
8268     vat_main_t * vam = &vat_main;
8269
8270     fformat(vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
8271             "       %d       %d     %d\n",
8272             ntohl(mp->bd_id), format_l2_fib_mac_address, &mp->mac,
8273             ntohl(mp->sw_if_index), mp->static_mac, mp->filter_mac,
8274             mp->bvi_mac);
8275 }
8276
8277 static void vl_api_l2_fib_table_entry_t_handler_json
8278 (vl_api_l2_fib_table_entry_t * mp)
8279 {
8280     vat_main_t * vam = &vat_main;
8281     vat_json_node_t *node = NULL;
8282
8283     if (VAT_JSON_ARRAY != vam->json_tree.type) {
8284         ASSERT(VAT_JSON_NONE == vam->json_tree.type);
8285         vat_json_init_array(&vam->json_tree);
8286     }
8287     node = vat_json_array_add(&vam->json_tree);
8288
8289     vat_json_init_object(node);
8290     vat_json_object_add_uint(node, "bd_id", ntohl(mp->bd_id));
8291     vat_json_object_add_uint(node, "mac", clib_net_to_host_u64(mp->mac));
8292     vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
8293     vat_json_object_add_uint(node, "static_mac", mp->static_mac);
8294     vat_json_object_add_uint(node, "filter_mac", mp->filter_mac);
8295     vat_json_object_add_uint(node, "bvi_mac", mp->bvi_mac);
8296 }
8297
8298 static int api_l2_fib_table_dump (vat_main_t * vam)
8299 {
8300     unformat_input_t * i = vam->input;
8301     vl_api_l2_fib_table_dump_t *mp;
8302     f64 timeout;
8303     u32 bd_id;
8304     u8 bd_id_set = 0;
8305
8306     /* Parse args required to build the message */
8307     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8308         if (unformat (i, "bd_id %d", &bd_id))
8309             bd_id_set = 1;
8310         else
8311             break;
8312     }
8313
8314     if (bd_id_set == 0) {
8315         errmsg ("missing bridge domain\n");
8316         return -99;
8317     }
8318
8319     fformat(vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
8320
8321     /* Get list of l2 fib entries */
8322     M(L2_FIB_TABLE_DUMP, l2_fib_table_dump);
8323
8324     mp->bd_id = ntohl(bd_id);
8325     S;
8326
8327     /* Use a control ping for synchronization */
8328     {
8329         vl_api_control_ping_t * mp;
8330         M(CONTROL_PING, control_ping);
8331         S;
8332     }
8333     W;
8334 }
8335
8336
8337 static int
8338 api_interface_name_renumber (vat_main_t * vam)
8339 {
8340     unformat_input_t * line_input = vam->input;
8341     vl_api_interface_name_renumber_t *mp;
8342     u32 sw_if_index = ~0;
8343     f64 timeout;
8344     u32 new_show_dev_instance = ~0;
8345
8346     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8347         if (unformat (line_input, "%U", unformat_sw_if_index, vam, 
8348                       &sw_if_index))
8349             ;
8350         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
8351             ;
8352         else if (unformat (line_input, "new_show_dev_instance %d", 
8353                            &new_show_dev_instance))
8354             ;
8355         else
8356             break;
8357     }
8358
8359     if (sw_if_index == ~0) {
8360         errmsg ("missing interface name or sw_if_index\n");
8361         return -99;
8362     }
8363
8364     if (new_show_dev_instance == ~0) {
8365         errmsg ("missing new_show_dev_instance\n");
8366         return -99;
8367     }
8368
8369     M(INTERFACE_NAME_RENUMBER, interface_name_renumber);
8370
8371     mp->sw_if_index = ntohl (sw_if_index);
8372     mp->new_show_dev_instance = ntohl (new_show_dev_instance);
8373
8374     S; W;
8375 }
8376
8377 static int
8378 api_want_ip4_arp_events (vat_main_t * vam)
8379 {
8380     unformat_input_t * line_input = vam->input;
8381     vl_api_want_ip4_arp_events_t * mp;
8382     f64 timeout;
8383     ip4_address_t address;
8384     int address_set = 0;
8385     u32 enable_disable = 1;
8386
8387     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
8388         if (unformat (line_input, "address %U", 
8389                       unformat_ip4_address, &address))
8390             address_set = 1;
8391         else if (unformat (line_input, "del"))
8392             enable_disable = 0;
8393         else
8394             break;
8395     }
8396     
8397     if (address_set == 0) {
8398         errmsg ("missing addresses\n");
8399         return -99;
8400     }
8401         
8402     M(WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
8403     mp->enable_disable = enable_disable;
8404     mp->pid = getpid();
8405     mp->address = address.as_u32;
8406
8407     S; W; 
8408 }
8409
8410 static int api_input_acl_set_interface (vat_main_t * vam)
8411 {
8412     unformat_input_t * i = vam->input;
8413     vl_api_input_acl_set_interface_t *mp;
8414     f64 timeout;
8415     u32 sw_if_index;
8416     int sw_if_index_set;
8417     u32 ip4_table_index = ~0;
8418     u32 ip6_table_index = ~0;
8419     u32 l2_table_index = ~0;
8420     u8 is_add = 1;
8421
8422     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8423         if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8424             sw_if_index_set = 1;
8425         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8426             sw_if_index_set = 1;
8427         else if (unformat (i, "del"))
8428             is_add = 0;
8429         else if (unformat (i, "ip4-table %d", &ip4_table_index))
8430             ;
8431         else if (unformat (i, "ip6-table %d", &ip6_table_index))
8432             ;
8433         else if (unformat (i, "l2-table %d", &l2_table_index))
8434             ;
8435         else {
8436             clib_warning ("parse error '%U'", format_unformat_error, i);
8437             return -99;
8438         }
8439     }
8440
8441     if (sw_if_index_set == 0) {
8442         errmsg ("missing interface name or sw_if_index\n");
8443         return -99;
8444     }
8445
8446     M(INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
8447
8448     mp->sw_if_index = ntohl(sw_if_index);
8449     mp->ip4_table_index = ntohl(ip4_table_index);
8450     mp->ip6_table_index = ntohl(ip6_table_index);
8451     mp->l2_table_index = ntohl(l2_table_index);
8452     mp->is_add = is_add;
8453
8454     S; W;
8455     /* NOTREACHED */
8456     return 0;
8457 }
8458
8459 static int
8460 api_ip_address_dump (vat_main_t * vam)
8461 {
8462     unformat_input_t * i = vam->input;
8463     vl_api_ip_address_dump_t * mp;
8464     u32 sw_if_index = ~0;
8465     u8 sw_if_index_set = 0;
8466     u8 ipv4_set = 0;
8467     u8 ipv6_set = 0;
8468     f64 timeout;
8469
8470     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8471         if (unformat (i, "sw_if_index %d", &sw_if_index))
8472             sw_if_index_set = 1;
8473         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8474             sw_if_index_set = 1;
8475         else if (unformat (i, "ipv4"))
8476             ipv4_set = 1;
8477         else if (unformat (i, "ipv6"))
8478             ipv6_set = 1;
8479         else
8480             break;
8481     }
8482
8483     if (ipv4_set && ipv6_set) {
8484         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8485         return -99;
8486     }
8487
8488     if ((!ipv4_set) && (!ipv6_set)) {
8489         errmsg ("no ipv4 nor ipv6 flag set\n");
8490         return -99;
8491     }
8492
8493     if (sw_if_index_set == 0) {
8494         errmsg ("missing interface name or sw_if_index\n");
8495         return -99;
8496     }
8497
8498     vam->current_sw_if_index = sw_if_index;
8499     vam->is_ipv6 = ipv6_set;
8500
8501     M(IP_ADDRESS_DUMP, ip_address_dump);
8502     mp->sw_if_index = ntohl(sw_if_index);
8503     mp->is_ipv6 = ipv6_set;
8504     S;
8505
8506     /* Use a control ping for synchronization */
8507     {
8508         vl_api_control_ping_t * mp;
8509         M(CONTROL_PING, control_ping);
8510         S;
8511     }
8512     W;
8513 }
8514
8515 static int
8516 api_ip_dump (vat_main_t * vam)
8517 {
8518     vl_api_ip_dump_t * mp;
8519     unformat_input_t * in = vam->input;
8520     int ipv4_set = 0;
8521     int ipv6_set = 0;
8522     int is_ipv6;
8523     f64 timeout;
8524     int i;
8525
8526     while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT) {
8527         if (unformat (in, "ipv4"))
8528             ipv4_set = 1;
8529         else if (unformat (in, "ipv6"))
8530             ipv6_set = 1;
8531         else
8532             break;
8533     }
8534
8535     if (ipv4_set && ipv6_set) {
8536         errmsg ("ipv4 and ipv6 flags cannot be both set\n");
8537         return -99;
8538     }
8539
8540     if ((!ipv4_set) && (!ipv6_set)) {
8541         errmsg ("no ipv4 nor ipv6 flag set\n");
8542         return -99;
8543     }
8544
8545     is_ipv6 = ipv6_set;
8546     vam->is_ipv6 = is_ipv6;
8547
8548     /* free old data */
8549     for (i = 0; i < vec_len(vam->ip_details_by_sw_if_index[is_ipv6]); i++) {
8550         vec_free(vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
8551     }
8552     vec_free(vam->ip_details_by_sw_if_index[is_ipv6]);
8553
8554     M(IP_DUMP, ip_dump);
8555     mp->is_ipv6 = ipv6_set;
8556     S;
8557
8558     /* Use a control ping for synchronization */
8559     {
8560         vl_api_control_ping_t * mp;
8561         M(CONTROL_PING, control_ping);
8562         S;
8563     }
8564     W;
8565 }
8566
8567 static int
8568 api_ipsec_spd_add_del (vat_main_t * vam)
8569 {
8570 #if DPDK > 0
8571     unformat_input_t * i = vam->input;
8572     vl_api_ipsec_spd_add_del_t *mp;
8573     f64 timeout;
8574     u32 spd_id = ~0;
8575     u8 is_add = 1;
8576
8577     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8578         if (unformat (i, "spd_id %d", &spd_id))
8579             ;
8580         else if (unformat (i, "del"))
8581             is_add = 0;
8582         else {
8583             clib_warning ("parse error '%U'", format_unformat_error, i);
8584             return -99;
8585         }
8586     }
8587     if (spd_id == ~0) {
8588         errmsg ("spd_id must be set\n");
8589         return -99;
8590     }
8591
8592     M(IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
8593
8594     mp->spd_id = ntohl(spd_id);
8595     mp->is_add = is_add;
8596
8597     S; W;
8598     /* NOTREACHED */
8599     return 0;
8600 #else
8601     clib_warning ("unsupported (no dpdk)");
8602     return -99;
8603 #endif
8604 }
8605
8606 static int
8607 api_ipsec_interface_add_del_spd (vat_main_t * vam)
8608 {
8609 #if DPDK > 0
8610     unformat_input_t * i = vam->input;
8611     vl_api_ipsec_interface_add_del_spd_t *mp;
8612     f64 timeout;
8613     u32 sw_if_index;
8614     u8 sw_if_index_set = 0;
8615     u32 spd_id = (u32) ~0;
8616     u8 is_add = 1;
8617
8618     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8619         if (unformat (i, "del"))
8620             is_add = 0;
8621         else if (unformat (i, "spd_id %d", &spd_id))
8622             ;
8623         else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8624             sw_if_index_set = 1;
8625         else if (unformat (i, "sw_if_index %d", &sw_if_index))
8626             sw_if_index_set = 1;
8627         else {
8628             clib_warning ("parse error '%U'", format_unformat_error, i);
8629             return -99;
8630         }
8631
8632     }
8633
8634     if (spd_id == (u32) ~0) {
8635         errmsg ("spd_id must be set\n");
8636         return -99;
8637     }
8638
8639     if (sw_if_index_set == 0) {
8640         errmsg ("missing interface name or sw_if_index\n");
8641         return -99;
8642     }
8643
8644     M(IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
8645
8646     mp->spd_id = ntohl(spd_id);
8647     mp->sw_if_index = ntohl (sw_if_index);
8648     mp->is_add = is_add;
8649
8650     S; W;
8651     /* NOTREACHED */
8652     return 0;
8653 #else
8654     clib_warning ("unsupported (no dpdk)");
8655     return -99;
8656 #endif
8657 }
8658
8659 static int
8660 api_ipsec_spd_add_del_entry (vat_main_t * vam)
8661 {
8662 #if DPDK > 0
8663     unformat_input_t * i = vam->input;
8664     vl_api_ipsec_spd_add_del_entry_t *mp;
8665     f64 timeout;
8666     u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
8667     u32 spd_id, sa_id, protocol = 0, policy = 0;
8668     i32 priority;
8669     u32 rport_start = 0, rport_stop = (u32) ~0;
8670     u32 lport_start = 0, lport_stop = (u32) ~0;
8671     ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
8672     ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
8673
8674     laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
8675     laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~0;
8676     laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
8677     laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
8678     laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~0;
8679     laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~0;
8680
8681     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8682         if (unformat (i, "del"))
8683             is_add = 0;
8684         if (unformat (i, "outbound"))
8685             is_outbound = 1;
8686         if (unformat (i, "inbound"))
8687             is_outbound = 0;
8688         else if (unformat (i, "spd_id %d", &spd_id))
8689             ;
8690         else if (unformat (i, "sa_id %d", &sa_id))
8691             ;
8692         else if (unformat (i, "priority %d", &priority))
8693             ;
8694         else if (unformat (i, "protocol %d", &protocol))
8695             ;
8696         else if (unformat (i, "lport_start %d", &lport_start))
8697             ;
8698         else if (unformat (i, "lport_stop %d", &lport_stop))
8699             ;
8700         else if (unformat (i, "rport_start %d", &rport_start))
8701             ;
8702         else if (unformat (i, "rport_stop %d", &rport_stop))
8703             ;
8704         else if (unformat (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
8705           {
8706             is_ipv6 = 0;
8707             is_ip_any =0;
8708           }
8709         else if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
8710           {
8711             is_ipv6 = 0;
8712             is_ip_any = 0;
8713           }
8714         else if (unformat (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
8715           {
8716             is_ipv6 = 0;
8717             is_ip_any = 0;
8718           }
8719         else if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
8720           {
8721             is_ipv6 = 0;
8722             is_ip_any = 0;
8723           }
8724         else if (unformat (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
8725           {
8726             is_ipv6 = 1;
8727             is_ip_any = 0;
8728           }
8729         else if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
8730           {
8731             is_ipv6 = 1;
8732             is_ip_any = 0;
8733           }
8734         else if (unformat (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
8735           {
8736             is_ipv6 = 1;
8737             is_ip_any = 0;
8738           }
8739         else if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
8740           {
8741             is_ipv6 = 1;
8742             is_ip_any = 0;
8743           }
8744         else if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
8745           {
8746             if (policy == IPSEC_POLICY_ACTION_RESOLVE) {
8747                 clib_warning ("unsupported action: 'resolve'");
8748                 return -99;
8749             }
8750           }
8751         else {
8752             clib_warning ("parse error '%U'", format_unformat_error, i);
8753             return -99;
8754         }
8755
8756     }
8757
8758     M(IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
8759
8760     mp->spd_id = ntohl(spd_id);
8761     mp->priority = ntohl(priority);
8762     mp->is_outbound = is_outbound;
8763
8764     mp->is_ipv6 = is_ipv6;
8765     if (is_ipv6 || is_ip_any) {
8766         clib_memcpy (mp->remote_address_start, &raddr6_start, sizeof(ip6_address_t));
8767         clib_memcpy (mp->remote_address_stop, &raddr6_stop, sizeof(ip6_address_t));
8768         clib_memcpy (mp->local_address_start, &laddr6_start, sizeof(ip6_address_t));
8769         clib_memcpy (mp->local_address_stop, &laddr6_stop, sizeof(ip6_address_t));
8770     } else {
8771         clib_memcpy (mp->remote_address_start, &raddr4_start, sizeof(ip4_address_t));
8772         clib_memcpy (mp->remote_address_stop, &raddr4_stop, sizeof(ip4_address_t));
8773         clib_memcpy (mp->local_address_start, &laddr4_start, sizeof(ip4_address_t));
8774         clib_memcpy (mp->local_address_stop, &laddr4_stop, sizeof(ip4_address_t));
8775     }
8776     mp->protocol = (u8) protocol;
8777     mp->local_port_start = ntohs((u16) lport_start);
8778     mp->local_port_stop = ntohs((u16) lport_stop);
8779     mp->remote_port_start = ntohs((u16) rport_start);
8780     mp->remote_port_stop = ntohs((u16) rport_stop);
8781     mp->policy = (u8) policy;
8782     mp->sa_id = ntohl(sa_id);
8783     mp->is_add = is_add;
8784     mp->is_ip_any = is_ip_any;
8785     S; W;
8786     /* NOTREACHED */
8787     return 0;
8788 #else
8789     clib_warning ("unsupported (no dpdk)");
8790     return -99;
8791 #endif
8792 }
8793
8794 static int
8795 api_ipsec_sad_add_del_entry (vat_main_t * vam)
8796 {
8797 #if DPDK > 0
8798     unformat_input_t * i = vam->input;
8799     vl_api_ipsec_sad_add_del_entry_t *mp;
8800     f64 timeout;
8801     u32 sad_id, spi;
8802     u8 * ck, * ik;
8803     u8 is_add = 1;
8804
8805     u8 protocol = IPSEC_PROTOCOL_AH;
8806     u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
8807     u32 crypto_alg = 0, integ_alg = 0;
8808     ip4_address_t tun_src4;
8809     ip4_address_t tun_dst4;
8810     ip6_address_t tun_src6;
8811     ip6_address_t tun_dst6;
8812
8813     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8814         if (unformat (i, "del"))
8815             is_add = 0;
8816         else if (unformat (i, "sad_id %d", &sad_id))
8817             ;
8818         else if (unformat (i, "spi %d", &spi))
8819             ;
8820         else if (unformat (i, "esp"))
8821             protocol = IPSEC_PROTOCOL_ESP;
8822         else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4)) {
8823             is_tunnel = 1;
8824             is_tunnel_ipv6 = 0;
8825         }
8826         else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4)) {
8827             is_tunnel = 1;
8828             is_tunnel_ipv6 = 0;
8829         }
8830         else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6)) {
8831             is_tunnel = 1;
8832             is_tunnel_ipv6 = 1;
8833         }
8834         else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6)) {
8835             is_tunnel = 1;
8836             is_tunnel_ipv6 = 1;
8837         }
8838         else if (unformat (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg)) {
8839             if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
8840                 crypto_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8841                 clib_warning ("unsupported crypto-alg: '%U'",
8842                               format_ipsec_crypto_alg, crypto_alg);
8843                 return -99;
8844             }
8845         }
8846         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8847             ;
8848         else if (unformat (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg)) {
8849             if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
8850                 integ_alg > IPSEC_INTEG_ALG_SHA_512_256) {
8851                 clib_warning ("unsupported integ-alg: '%U'",
8852                               format_ipsec_integ_alg, integ_alg);
8853                 return -99;
8854             }
8855         }
8856         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8857             ;
8858         else {
8859             clib_warning ("parse error '%U'", format_unformat_error, i);
8860             return -99;
8861         }
8862
8863     }
8864
8865     M(IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
8866
8867     mp->sad_id = ntohl(sad_id);
8868     mp->is_add = is_add;
8869     mp->protocol = protocol;
8870     mp->spi = ntohl(spi);
8871     mp->is_tunnel = is_tunnel;
8872     mp->is_tunnel_ipv6 = is_tunnel_ipv6;
8873     mp->crypto_algorithm = crypto_alg;
8874     mp->integrity_algorithm = integ_alg;
8875     mp->crypto_key_length = vec_len(ck);
8876     mp->integrity_key_length = vec_len(ik);
8877
8878     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8879       mp->crypto_key_length = sizeof(mp->crypto_key);
8880
8881     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8882       mp->integrity_key_length = sizeof(mp->integrity_key);
8883
8884     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8885     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8886
8887     if (is_tunnel) {
8888       if (is_tunnel_ipv6) {
8889         clib_memcpy (mp->tunnel_src_address, &tun_src6, sizeof(ip6_address_t));
8890         clib_memcpy (mp->tunnel_dst_address, &tun_dst6, sizeof(ip6_address_t));
8891       } else {
8892         clib_memcpy (mp->tunnel_src_address, &tun_src4, sizeof(ip4_address_t));
8893         clib_memcpy (mp->tunnel_dst_address, &tun_dst4, sizeof(ip4_address_t));
8894       }
8895     }
8896
8897     S; W;
8898     /* NOTREACHED */
8899     return 0;
8900 #else
8901     clib_warning ("unsupported (no dpdk)");
8902     return -99;
8903 #endif
8904 }
8905
8906 static int
8907 api_ipsec_sa_set_key (vat_main_t * vam)
8908 {
8909 #if DPDK > 0
8910     unformat_input_t * i = vam->input;
8911     vl_api_ipsec_sa_set_key_t *mp;
8912     f64 timeout;
8913     u32 sa_id;
8914     u8 * ck, * ik;
8915
8916     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8917         if (unformat (i, "sa_id %d", &sa_id))
8918             ;
8919         else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
8920             ;
8921         else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
8922             ;
8923         else {
8924             clib_warning ("parse error '%U'", format_unformat_error, i);
8925             return -99;
8926         }
8927     }
8928
8929     M(IPSEC_SA_SET_KEY, ipsec_set_sa_key);
8930
8931     mp->sa_id = ntohl(sa_id);
8932     mp->crypto_key_length = vec_len(ck);
8933     mp->integrity_key_length = vec_len(ik);
8934
8935     if (mp->crypto_key_length > sizeof(mp->crypto_key))
8936       mp->crypto_key_length = sizeof(mp->crypto_key);
8937
8938     if (mp->integrity_key_length > sizeof(mp->integrity_key))
8939       mp->integrity_key_length = sizeof(mp->integrity_key);
8940
8941     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
8942     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
8943
8944     S; W;
8945     /* NOTREACHED */
8946     return 0;
8947 #else
8948     clib_warning ("unsupported (no dpdk)");
8949     return -99;
8950 #endif
8951 }
8952
8953 static int
8954 api_ikev2_profile_add_del (vat_main_t * vam)
8955 {
8956 #if DPDK > 0
8957     unformat_input_t * i = vam->input;
8958     vl_api_ikev2_profile_add_del_t * mp;
8959     f64 timeout;
8960     u8 is_add = 1;
8961     u8 * name = 0;
8962
8963     const char * valid_chars = "a-zA-Z0-9_";
8964
8965     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
8966         if (unformat (i, "del"))
8967             is_add = 0;
8968         else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
8969             vec_add1 (name, 0);
8970         else {
8971             errmsg ("parse error '%U'", format_unformat_error, i);
8972             return -99;
8973         }
8974     }
8975
8976     if (!vec_len (name)) {
8977         errmsg ("profile name must be specified");
8978         return -99;
8979     }
8980
8981     if (vec_len (name) > 64) {
8982         errmsg ("profile name too long");
8983         return -99;
8984     }
8985
8986     M(IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
8987
8988     clib_memcpy(mp->name, name, vec_len (name));
8989     mp->is_add = is_add;
8990     vec_free (name);
8991
8992     S; W;
8993     /* NOTREACHED */
8994     return 0;
8995 #else
8996     clib_warning ("unsupported (no dpdk)");
8997     return -99;
8998 #endif
8999 }
9000
9001 static int
9002 api_ikev2_profile_set_auth (vat_main_t * vam)
9003 {
9004 #if DPDK > 0
9005     unformat_input_t * i = vam->input;
9006     vl_api_ikev2_profile_set_auth_t * mp;
9007     f64 timeout;
9008     u8 * name = 0;
9009     u8 * data = 0;
9010     u32 auth_method = 0;
9011     u8 is_hex = 0;
9012
9013     const char * valid_chars = "a-zA-Z0-9_";
9014
9015     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9016         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9017             vec_add1 (name, 0);
9018         else if (unformat (i, "auth_method %U",
9019                            unformat_ikev2_auth_method, &auth_method))
9020             ;
9021         else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
9022             is_hex = 1;
9023         else if (unformat (i, "auth_data %v", &data))
9024             ;
9025         else {
9026             errmsg ("parse error '%U'", format_unformat_error, i);
9027             return -99;
9028         }
9029     }
9030
9031     if (!vec_len (name)) {
9032         errmsg ("profile name must be specified");
9033         return -99;
9034     }
9035
9036     if (vec_len (name) > 64) {
9037         errmsg ("profile name too long");
9038         return -99;
9039     }
9040
9041     if (!vec_len(data)) {
9042         errmsg ("auth_data must be specified");
9043         return -99;
9044     }
9045
9046     if (!auth_method) {
9047         errmsg ("auth_method must be specified");
9048         return -99;
9049     }
9050
9051     M(IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
9052
9053     mp->is_hex = is_hex;
9054     mp->auth_method = (u8) auth_method;
9055     mp->data_len = vec_len (data);
9056     clib_memcpy (mp->name, name, vec_len (name));
9057     clib_memcpy (mp->data, data, vec_len (data));
9058     vec_free (name);
9059     vec_free (data);
9060
9061     S; W;
9062     /* NOTREACHED */
9063     return 0;
9064 #else
9065     clib_warning ("unsupported (no dpdk)");
9066     return -99;
9067 #endif
9068 }
9069
9070 static int
9071 api_ikev2_profile_set_id (vat_main_t * vam)
9072 {
9073 #if DPDK > 0
9074     unformat_input_t * i = vam->input;
9075     vl_api_ikev2_profile_set_id_t * mp;
9076     f64 timeout;
9077     u8 * name = 0;
9078     u8 * data = 0;
9079     u8 is_local = 0;
9080     u32 id_type = 0;
9081     ip4_address_t ip4;
9082
9083     const char * valid_chars = "a-zA-Z0-9_";
9084
9085     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9086         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9087             vec_add1 (name, 0);
9088         else if (unformat (i, "id_type %U",
9089                            unformat_ikev2_id_type, &id_type))
9090             ;
9091         else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
9092           {
9093             data = vec_new(u8, 4);
9094             clib_memcpy(data, ip4.as_u8, 4);
9095           }
9096         else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
9097             ;
9098         else if (unformat (i, "id_data %v", &data))
9099             ;
9100         else if (unformat (i, "local"))
9101             is_local = 1;
9102         else if (unformat (i, "remote"))
9103             is_local = 0;
9104         else {
9105             errmsg ("parse error '%U'", format_unformat_error, i);
9106             return -99;
9107         }
9108     }
9109
9110     if (!vec_len (name)) {
9111         errmsg ("profile name must be specified");
9112         return -99;
9113     }
9114
9115     if (vec_len (name) > 64) {
9116         errmsg ("profile name too long");
9117         return -99;
9118     }
9119
9120     if (!vec_len(data)) {
9121         errmsg ("id_data must be specified");
9122         return -99;
9123     }
9124
9125     if (!id_type) {
9126         errmsg ("id_type must be specified");
9127         return -99;
9128     }
9129
9130     M(IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
9131
9132     mp->is_local = is_local;
9133     mp->id_type = (u8) id_type;
9134     mp->data_len = vec_len (data);
9135     clib_memcpy (mp->name, name, vec_len (name));
9136     clib_memcpy (mp->data, data, vec_len (data));
9137     vec_free (name);
9138     vec_free (data);
9139
9140     S; W;
9141     /* NOTREACHED */
9142     return 0;
9143 #else
9144     clib_warning ("unsupported (no dpdk)");
9145     return -99;
9146 #endif
9147 }
9148
9149 static int
9150 api_ikev2_profile_set_ts (vat_main_t * vam)
9151 {
9152 #if DPDK > 0
9153     unformat_input_t * i = vam->input;
9154     vl_api_ikev2_profile_set_ts_t * mp;
9155     f64 timeout;
9156     u8 * name = 0;
9157     u8 is_local = 0;
9158     u32 proto = 0, start_port = 0, end_port = (u32) ~0;
9159     ip4_address_t start_addr, end_addr;
9160
9161     const char * valid_chars = "a-zA-Z0-9_";
9162
9163     start_addr.as_u32 = 0;
9164     end_addr.as_u32 = (u32) ~0;
9165
9166     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9167         if (unformat (i, "name %U", unformat_token, valid_chars, &name))
9168             vec_add1 (name, 0);
9169         else if (unformat (i, "protocol %d", &proto))
9170             ;
9171         else if (unformat (i, "start_port %d", &start_port))
9172             ;
9173         else if (unformat (i, "end_port %d", &end_port))
9174             ;
9175         else if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
9176             ;
9177         else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
9178             ;
9179         else if (unformat (i, "local"))
9180             is_local = 1;
9181         else if (unformat (i, "remote"))
9182             is_local = 0;
9183         else {
9184             errmsg ("parse error '%U'", format_unformat_error, i);
9185             return -99;
9186         }
9187     }
9188
9189     if (!vec_len (name)) {
9190         errmsg ("profile name must be specified");
9191         return -99;
9192     }
9193
9194     if (vec_len (name) > 64) {
9195         errmsg ("profile name too long");
9196         return -99;
9197     }
9198
9199     M(IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
9200
9201     mp->is_local = is_local;
9202     mp->proto = (u8) proto;
9203     mp->start_port = (u16) start_port;
9204     mp->end_port = (u16) end_port;
9205     mp->start_addr = start_addr.as_u32;
9206     mp->end_addr = end_addr.as_u32;
9207     clib_memcpy (mp->name, name, vec_len (name));
9208     vec_free (name);
9209
9210     S; W;
9211     /* NOTREACHED */
9212     return 0;
9213 #else
9214     clib_warning ("unsupported (no dpdk)");
9215     return -99;
9216 #endif
9217 }
9218
9219 static int
9220 api_ikev2_set_local_key (vat_main_t * vam)
9221 {
9222 #if DPDK > 0
9223     unformat_input_t * i = vam->input;
9224     vl_api_ikev2_set_local_key_t * mp;
9225     f64 timeout;
9226     u8 * file = 0;
9227
9228     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9229         if (unformat (i, "file %v", &file))
9230             vec_add1 (file, 0);
9231         else {
9232             errmsg ("parse error '%U'", format_unformat_error, i);
9233             return -99;
9234         }
9235     }
9236
9237     if (!vec_len (file)) {
9238         errmsg ("RSA key file must be specified");
9239         return -99;
9240     }
9241
9242     if (vec_len (file) > 256) {
9243         errmsg ("file name too long");
9244         return -99;
9245     }
9246
9247     M(IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
9248
9249     clib_memcpy (mp->key_file, file, vec_len (file));
9250     vec_free (file);
9251
9252     S; W;
9253     /* NOTREACHED */
9254     return 0;
9255 #else
9256     clib_warning ("unsupported (no dpdk)");
9257     return -99;
9258 #endif
9259 }
9260
9261 /*
9262  * MAP
9263  */
9264 static int api_map_add_domain (vat_main_t * vam)
9265 {
9266   unformat_input_t *i = vam->input;
9267   vl_api_map_add_domain_t *mp;
9268   f64 timeout;
9269
9270   ip4_address_t ip4_prefix;
9271   ip6_address_t ip6_prefix;
9272   ip6_address_t ip6_src;
9273   u32 num_m_args = 0;
9274   u32 ip6_prefix_len, ip4_prefix_len, ea_bits_len, psid_offset,
9275     psid_length;
9276   u8 is_translation = 0;
9277   u32 mtu = 0;
9278   u8 ip6_src_len = 128;
9279
9280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9281     if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
9282                   &ip4_prefix, &ip4_prefix_len))
9283       num_m_args++;
9284     else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
9285                        &ip6_prefix, &ip6_prefix_len))
9286       num_m_args++;
9287     else if (unformat (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src, &ip6_src_len))
9288       num_m_args++;
9289     else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
9290       num_m_args++;
9291     else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
9292       num_m_args++;
9293     else if (unformat (i, "psid-offset %d", &psid_offset))
9294       num_m_args++;
9295     else if (unformat (i, "psid-len %d", &psid_length))
9296       num_m_args++;
9297     else if (unformat (i, "mtu %d", &mtu))
9298       num_m_args++;
9299     else if (unformat (i, "map-t"))
9300       is_translation = 1;
9301     else {
9302       clib_warning ("parse error '%U'", format_unformat_error, i);
9303       return -99;
9304     }
9305   }
9306
9307   if (num_m_args != 6) {
9308     errmsg("mandatory argument(s) missing\n");
9309     return -99;
9310   }
9311
9312   /* Construct the API message */
9313   M(MAP_ADD_DOMAIN, map_add_domain);
9314
9315   clib_memcpy(mp->ip4_prefix, &ip4_prefix, sizeof(ip4_prefix));
9316   mp->ip4_prefix_len = ip4_prefix_len;
9317
9318   clib_memcpy(mp->ip6_prefix, &ip6_prefix, sizeof(ip6_prefix));
9319   mp->ip6_prefix_len = ip6_prefix_len;
9320
9321   clib_memcpy(mp->ip6_src, &ip6_src, sizeof(ip6_src));
9322   mp->ip6_src_prefix_len = ip6_src_len;
9323
9324   mp->ea_bits_len = ea_bits_len;
9325   mp->psid_offset = psid_offset;
9326   mp->psid_length = psid_length;
9327   mp->is_translation = is_translation;
9328   mp->mtu = htons(mtu);
9329
9330   /* send it... */
9331   S;
9332
9333   /* Wait for a reply, return good/bad news  */
9334   W;
9335 }
9336
9337 static int api_map_del_domain (vat_main_t * vam)
9338 {
9339   unformat_input_t *i = vam->input;
9340   vl_api_map_del_domain_t *mp;
9341   f64 timeout;
9342
9343   u32 num_m_args = 0;
9344   u32 index;
9345
9346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9347     if (unformat (i, "index %d", &index))
9348       num_m_args++;
9349     else {
9350       clib_warning ("parse error '%U'", format_unformat_error, i);
9351       return -99;
9352     }
9353   }
9354
9355   if (num_m_args != 1) {
9356     errmsg("mandatory argument(s) missing\n");
9357     return -99;
9358   }
9359
9360   /* Construct the API message */
9361   M(MAP_DEL_DOMAIN, map_del_domain);
9362
9363   mp->index = ntohl(index);
9364
9365   /* send it... */
9366   S;
9367
9368   /* Wait for a reply, return good/bad news  */
9369   W;
9370 }
9371
9372 static int api_map_add_del_rule (vat_main_t * vam)
9373 {
9374   unformat_input_t *i = vam->input;
9375   vl_api_map_add_del_rule_t *mp;
9376   f64 timeout;
9377   u8 is_add = 1;
9378   ip6_address_t ip6_dst;
9379   u32 num_m_args = 0, index, psid;
9380
9381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9382     if (unformat (i, "index %d", &index))
9383       num_m_args++;
9384     else if (unformat (i, "psid %d", &psid))
9385       num_m_args++;
9386     else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
9387       num_m_args++;
9388     else if (unformat (i, "del")) {
9389       is_add = 0;
9390     } else {
9391       clib_warning ("parse error '%U'", format_unformat_error, i);
9392       return -99;
9393     }
9394   }
9395
9396   /* Construct the API message */
9397   M(MAP_ADD_DEL_RULE, map_add_del_rule);
9398
9399   mp->index = ntohl(index);
9400   mp->is_add = is_add;
9401   clib_memcpy(mp->ip6_dst, &ip6_dst, sizeof(ip6_dst));
9402   mp->psid = ntohs(psid);
9403
9404   /* send it... */
9405   S;
9406
9407   /* Wait for a reply, return good/bad news  */
9408   W;
9409 }
9410
9411 static int api_map_domain_dump (vat_main_t * vam)
9412 {
9413     vl_api_map_domain_dump_t *mp;
9414     f64 timeout;
9415
9416     /* Construct the API message */
9417     M(MAP_DOMAIN_DUMP, map_domain_dump);
9418
9419     /* send it... */
9420     S;
9421
9422     /* Use a control ping for synchronization */
9423     {
9424         vl_api_control_ping_t * mp;
9425         M(CONTROL_PING, control_ping);
9426         S;
9427     }
9428     W;
9429 }
9430
9431 static int api_map_rule_dump (vat_main_t * vam)
9432 {
9433     unformat_input_t *i = vam->input;
9434     vl_api_map_rule_dump_t *mp;
9435     f64 timeout;
9436     u32 domain_index = ~0;
9437
9438     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9439         if (unformat (i, "index %u", &domain_index))
9440             ;
9441         else
9442             break;
9443     }
9444
9445     if (domain_index == ~0) {
9446         clib_warning("parse error: domain index expected");
9447         return -99;
9448     }
9449
9450     /* Construct the API message */
9451     M(MAP_RULE_DUMP, map_rule_dump);
9452
9453     mp->domain_index = htonl(domain_index);
9454
9455     /* send it... */
9456     S;
9457
9458     /* Use a control ping for synchronization */
9459     {
9460         vl_api_control_ping_t * mp;
9461         M(CONTROL_PING, control_ping);
9462         S;
9463     }
9464     W;
9465 }
9466
9467 static void vl_api_map_add_domain_reply_t_handler
9468 (vl_api_map_add_domain_reply_t * mp)
9469 {
9470   vat_main_t * vam = &vat_main;
9471   i32 retval = ntohl(mp->retval);
9472
9473   if (vam->async_mode) {
9474       vam->async_errors += (retval < 0);
9475   } else {
9476       vam->retval = retval;
9477       vam->result_ready = 1;
9478   }
9479 }
9480
9481 static void vl_api_map_add_domain_reply_t_handler_json
9482 (vl_api_map_add_domain_reply_t * mp)
9483 {
9484   vat_main_t * vam = &vat_main;
9485   vat_json_node_t node;
9486
9487   vat_json_init_object(&node);
9488   vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
9489   vat_json_object_add_uint(&node, "index", ntohl(mp->index));
9490
9491   vat_json_print(vam->ofp, &node);
9492   vat_json_free(&node);
9493
9494   vam->retval = ntohl(mp->retval);
9495   vam->result_ready = 1;
9496 }
9497
9498 static int
9499 api_get_first_msg_id (vat_main_t * vam)
9500 {
9501     vl_api_get_first_msg_id_t * mp;
9502     f64 timeout;
9503     unformat_input_t * i = vam->input;
9504     u8 * name;
9505     u8 name_set = 0;
9506     
9507     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
9508         if (unformat (i, "client %s", &name))
9509             name_set = 1;
9510         else 
9511             break;
9512     }
9513
9514     if (name_set == 0) {
9515         errmsg ("missing client name\n");
9516         return -99;
9517     }
9518     vec_add1 (name, 0);
9519
9520     if (vec_len (name) > 63) {
9521         errmsg ("client name too long\n");
9522         return -99;
9523     }
9524
9525     M(GET_FIRST_MSG_ID, get_first_msg_id);
9526     clib_memcpy (mp->name, name, vec_len(name));
9527     S; W;
9528     /* NOTREACHED */
9529     return 0;
9530 }
9531
9532 static int api_cop_interface_enable_disable (vat_main_t * vam)
9533 {
9534     unformat_input_t * line_input = vam->input;
9535     vl_api_cop_interface_enable_disable_t * mp;
9536     f64 timeout;
9537     u32 sw_if_index = ~0;
9538     u8 enable_disable = 1;
9539
9540     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9541         if (unformat (line_input, "disable"))
9542             enable_disable = 0;
9543         if (unformat (line_input, "enable"))
9544             enable_disable = 1;
9545         else if (unformat (line_input, "%U", unformat_sw_if_index,
9546                            vam, &sw_if_index))
9547             ;
9548         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9549             ;
9550         else
9551             break;
9552     }
9553         
9554     if (sw_if_index == ~0) {
9555         errmsg ("missing interface name or sw_if_index\n");
9556         return -99;
9557     }
9558
9559     /* Construct the API message */
9560     M(COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
9561     mp->sw_if_index = ntohl(sw_if_index);
9562     mp->enable_disable = enable_disable;
9563
9564     /* send it... */
9565     S;
9566     /* Wait for the reply */
9567     W;
9568 }
9569
9570 static int api_cop_whitelist_enable_disable (vat_main_t * vam)
9571 {
9572     unformat_input_t * line_input = vam->input;
9573     vl_api_cop_whitelist_enable_disable_t * mp;
9574     f64 timeout;
9575     u32 sw_if_index = ~0;
9576     u8 ip4=0, ip6=0, default_cop=0;
9577     u32 fib_id;
9578
9579     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
9580         if (unformat (line_input, "ip4"))
9581             ip4 = 1;
9582         else if (unformat (line_input, "ip6"))
9583             ip6 = 1;
9584         else if (unformat (line_input, "default"))
9585             default_cop = 1;
9586         else if (unformat (line_input, "%U", unformat_sw_if_index,
9587                            vam, &sw_if_index))
9588             ;
9589         else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
9590             ;
9591         else if (unformat (line_input, "fib-id %d", &fib_id))
9592             ;
9593         else
9594             break;
9595     }
9596         
9597     if (sw_if_index == ~0) {
9598         errmsg ("missing interface name or sw_if_index\n");
9599         return -99;
9600     }
9601
9602     /* Construct the API message */
9603     M(COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
9604     mp->sw_if_index = ntohl(sw_if_index);
9605     mp->fib_id = ntohl(fib_id);
9606     mp->ip4 = ip4;
9607     mp->ip6 = ip6;
9608     mp->default_cop = default_cop;
9609
9610     /* send it... */
9611     S;
9612     /* Wait for the reply */
9613     W;
9614 }
9615
9616 static int api_get_node_graph (vat_main_t * vam)
9617 {
9618     vl_api_get_node_graph_t * mp;
9619     f64 timeout;
9620
9621     M(GET_NODE_GRAPH, get_node_graph);
9622
9623     /* send it... */
9624     S;
9625     /* Wait for the reply */
9626     W;
9627 }
9628
9629 static int
9630 api_lisp_add_del_locator_set(vat_main_t * vam)
9631 {
9632     unformat_input_t * input = vam->input;
9633     vl_api_lisp_add_del_locator_set_t *mp;
9634     f64 timeout = ~0;
9635     u8  is_add = 1;
9636     u8 *locator_set_name = NULL;
9637     u8  locator_set_name_set = 0;
9638
9639     /* Parse args required to build the message */
9640     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9641         if (unformat(input, "del")) {
9642             is_add = 0;
9643         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9644             locator_set_name_set = 1;
9645         } else
9646             break;
9647     }
9648
9649     if (locator_set_name_set == 0) {
9650         errmsg ("missing locator-set name");
9651         return -99;
9652     }
9653
9654     if (vec_len(locator_set_name) > 64) {
9655         errmsg ("locator-set name too long\n");
9656         vec_free(locator_set_name);
9657         return -99;
9658     }
9659     vec_add1(locator_set_name, 0);
9660
9661     /* Construct the API message */
9662     M(LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
9663
9664     mp->is_add = is_add;
9665     clib_memcpy(mp->locator_set_name, locator_set_name,
9666            vec_len(locator_set_name));
9667     vec_free(locator_set_name);
9668
9669     /* send it... */
9670     S;
9671
9672     /* Wait for a reply... */
9673     W;
9674
9675     /* NOTREACHED */
9676     return 0;
9677 }
9678
9679 static int
9680 api_lisp_add_del_locator(vat_main_t * vam)
9681 {
9682     unformat_input_t * input = vam->input;
9683     vl_api_lisp_add_del_locator_t *mp;
9684     f64 timeout = ~0;
9685     u32 tmp_if_index = ~0;
9686     u32 sw_if_index = ~0;
9687     u8  sw_if_index_set = 0;
9688     u8  sw_if_index_if_name_set = 0;
9689     u8  priority = ~0;
9690     u8  priority_set = 0;
9691     u8  weight = ~0;
9692     u8  weight_set = 0;
9693     u8  is_add = 1;
9694     u8  *locator_set_name = NULL;
9695     u8  locator_set_name_set = 0;
9696
9697     /* Parse args required to build the message */
9698     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9699         if (unformat(input, "del")) {
9700             is_add = 0;
9701         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9702             locator_set_name_set = 1;
9703         } else if (unformat(input, "iface %U", unformat_sw_if_index, vam,
9704             &tmp_if_index)) {
9705             sw_if_index_if_name_set = 1;
9706             sw_if_index = tmp_if_index;
9707         } else if (unformat(input,"sw_if_index %d", &tmp_if_index)) {
9708             sw_if_index_set = 1;
9709             sw_if_index = tmp_if_index;
9710         } else if (unformat(input, "p %d", &priority)) {
9711             priority_set = 1;
9712         } else if (unformat(input, "w %d", &weight)) {
9713             weight_set = 1;
9714         } else
9715             break;
9716     }
9717
9718     if (locator_set_name_set == 0) {
9719         errmsg ("missing locator-set name");
9720         return -99;
9721     }
9722
9723     if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0) {
9724         errmsg ("missing sw_if_index");
9725         vec_free(locator_set_name);
9726         return -99;
9727     }
9728
9729     if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0) {
9730         errmsg ("cannot use both params interface name and sw_if_index");
9731         vec_free(locator_set_name);
9732         return -99;
9733     }
9734
9735     if (priority_set == 0) {
9736         errmsg ("missing locator-set priority\n");
9737         vec_free(locator_set_name);
9738         return -99;
9739     }
9740
9741     if (weight_set == 0) {
9742         errmsg ("missing locator-set weight\n");
9743         vec_free(locator_set_name);
9744         return -99;
9745     }
9746
9747     if (vec_len(locator_set_name) > 64) {
9748         errmsg ("locator-set name too long\n");
9749         vec_free(locator_set_name);
9750         return -99;
9751     }
9752     vec_add1(locator_set_name, 0);
9753
9754     /* Construct the API message */
9755     M(LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
9756
9757     mp->is_add = is_add;
9758     mp->sw_if_index = ntohl(sw_if_index);
9759     mp->priority = priority;
9760     mp->weight = weight;
9761     clib_memcpy(mp->locator_set_name, locator_set_name,
9762            vec_len(locator_set_name));
9763     vec_free(locator_set_name);
9764
9765     /* send it... */
9766     S;
9767
9768     /* Wait for a reply... */
9769     W;
9770
9771     /* NOTREACHED */
9772     return 0;
9773 }
9774
9775 static int
9776 api_lisp_add_del_local_eid(vat_main_t * vam)
9777 {
9778     unformat_input_t * input = vam->input;
9779     vl_api_lisp_add_del_local_eid_t *mp;
9780     f64 timeout = ~0;
9781     u8 is_add = 1;
9782     u8 eidv4_set = 0;
9783     u8 eidv6_set = 0;
9784     ip4_address_t eidv4;
9785     ip6_address_t eidv6;
9786     u8 tmp_eid_lenght = ~0;
9787     u8 eid_lenght = ~0;
9788     u8 *locator_set_name = NULL;
9789     u8 locator_set_name_set = 0;
9790
9791     /* Parse args required to build the message */
9792     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9793         if (unformat(input, "del")) {
9794             is_add = 0;
9795         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9796             &eidv4, &tmp_eid_lenght)) {
9797             eid_lenght = tmp_eid_lenght;
9798             eidv4_set = 1;
9799         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9800             &eidv6, &tmp_eid_lenght)) {
9801             eid_lenght = tmp_eid_lenght;
9802             eidv6_set = 1;
9803         } else if (unformat(input, "locator-set %s", &locator_set_name)) {
9804             locator_set_name_set = 1;
9805         } else
9806             break;
9807     }
9808
9809     if (locator_set_name_set == 0) {
9810         errmsg ("missing locator-set name\n");
9811         return -99;
9812     }
9813
9814     if (vec_len(locator_set_name) > 64) {
9815         errmsg ("locator-set name too long\n");
9816         vec_free(locator_set_name);
9817         return -99;
9818     }
9819     vec_add1(locator_set_name, 0);
9820
9821     if (eidv4_set && eidv6_set) {
9822         errmsg ("both eid v4 and v6 addresses set\n");
9823         vec_free(locator_set_name);
9824         return -99;
9825     }
9826
9827     if (!eidv4_set && !eidv6_set) {
9828         errmsg ("eid addresses not set\n");
9829         vec_free(locator_set_name);
9830         return -99;
9831     }
9832
9833     if (eidv4_set && eid_lenght > 32) {
9834         errmsg ("eid prefix to big\n");
9835         vec_free(locator_set_name);
9836         return -99;
9837     }
9838
9839     if (eidv6_set && eid_lenght > 128) {
9840         errmsg ("eid prefix to big\n");
9841         vec_free(locator_set_name);
9842         return -99;
9843     }
9844
9845     /* Construct the API message */
9846     M(LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
9847
9848     mp->is_add = is_add;
9849     if (eidv6_set) {
9850         mp->is_ipv6 = 1;
9851         clib_memcpy(mp->ip_address, &eidv6, sizeof(eidv6));
9852     } else {
9853         mp->is_ipv6 = 0;
9854         clib_memcpy(mp->ip_address, &eidv4, sizeof(eidv4));
9855     }
9856     mp->prefix_len = eid_lenght;
9857     clib_memcpy(mp->locator_set_name, locator_set_name,
9858            vec_len(locator_set_name));
9859     vec_free(locator_set_name);
9860
9861     /* send it... */
9862     S;
9863
9864     /* Wait for a reply... */
9865     W;
9866
9867     /* NOTREACHED */
9868     return 0;
9869 }
9870
9871 static int
9872 api_lisp_gpe_add_del_fwd_entry(vat_main_t * vam)
9873 {
9874     unformat_input_t * input = vam->input;
9875     vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
9876     f64 timeout = ~0;
9877     u8 is_add = 1;
9878     u8 eidv4_set = 0, slocv4_set = 0, dlocv4_set = 0;
9879     u8 eidv6_set = 0, slocv6_set = 0, dlocv6_set = 0;
9880     ip4_address_t eidv4, slocv4, dlocv4;
9881     ip6_address_t eidv6, slocv6, dlocv6;
9882     u8 tmp_eid_lenght = ~0;
9883     u8 eid_lenght = ~0;
9884
9885     /* Parse args required to build the message */
9886     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9887         if (unformat(input, "del")) {
9888             is_add = 0;
9889         } else if (unformat(input, "eid %U/%d", unformat_ip4_address,
9890                             &eidv4, &tmp_eid_lenght)) {
9891             eid_lenght = tmp_eid_lenght;
9892             eidv4_set = 1;
9893         } else if (unformat(input, "eid %U/%d", unformat_ip6_address,
9894                             &eidv6, &tmp_eid_lenght)) {
9895             eid_lenght = tmp_eid_lenght;
9896             eidv6_set = 1;
9897         } else if (unformat(input, "sloc %U", unformat_ip4_address, &slocv4)) {
9898             slocv4_set = 1;
9899         } else if (unformat(input, "sloc %U", unformat_ip6_address, &slocv6)) {
9900             slocv6_set = 1;
9901         } else if (unformat(input, "dloc %U", unformat_ip4_address, &dlocv4)) {
9902             dlocv4_set = 1;
9903         } else if (unformat(input, "dloc %U", unformat_ip6_address, &dlocv6)) {
9904             dlocv6_set = 1;
9905         } else
9906             break;
9907     }
9908
9909     if (eidv4_set && eidv6_set) {
9910         errmsg ("both eid v4 and v6 addresses set\n");
9911         return -99;
9912     }
9913
9914     if (!eidv4_set && !eidv6_set) {
9915         errmsg ("eid addresses not set\n");
9916         return -99;
9917     }
9918
9919     if (slocv4_set && slocv6_set) {
9920         errmsg ("both source v4 and v6 addresses set\n");
9921         return -99;
9922     }
9923
9924     if (!slocv4_set && !slocv6_set) {
9925         errmsg ("source addresses not set\n");
9926         return -99;
9927     }
9928
9929     if (dlocv4_set && dlocv6_set) {
9930         errmsg ("both destination v4 and v6 addresses set\n");
9931         return -99;
9932     }
9933
9934     if (dlocv4_set && dlocv6_set) {
9935         errmsg ("destination addresses not set\n");
9936         return -99;
9937     }
9938
9939     if (!(slocv4_set == dlocv4_set && slocv6_set == dlocv6_set)) {
9940         errmsg ("mixing type of source and destination address\n");
9941         return -99;
9942     }
9943
9944     /* Construct the API message */
9945     M(LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
9946
9947     mp->is_add = is_add;
9948     if (eidv6_set) {
9949         mp->eid_is_ipv6 = 1;
9950         clib_memcpy(mp->eid_ip_address, &eidv6, sizeof(eidv6));
9951     } else {
9952         mp->eid_is_ipv6 = 0;
9953         clib_memcpy(mp->eid_ip_address, &eidv4, sizeof(eidv4));
9954     }
9955     mp->eid_prefix_len = eid_lenght;
9956     if (slocv6_set) {
9957         mp->address_is_ipv6 = 1;
9958         clib_memcpy(mp->source_ip_address, &slocv6, sizeof(slocv6));
9959         clib_memcpy(mp->destination_ip_address, &dlocv6, sizeof(dlocv6));
9960     } else {
9961         mp->address_is_ipv6 = 0;
9962         clib_memcpy(mp->source_ip_address, &slocv4, sizeof(slocv4));
9963         clib_memcpy(mp->destination_ip_address, &dlocv4, sizeof(dlocv4));
9964     }
9965
9966     /* send it... */
9967     S;
9968
9969     /* Wait for a reply... */
9970     W;
9971
9972     /* NOTREACHED */
9973     return 0;
9974 }
9975
9976 static int
9977 api_lisp_add_del_map_resolver(vat_main_t * vam)
9978 {
9979     unformat_input_t * input = vam->input;
9980     vl_api_lisp_add_del_map_resolver_t *mp;
9981     f64 timeout = ~0;
9982     u8 is_add = 1;
9983     u8 ipv4_set = 0;
9984     u8 ipv6_set = 0;
9985     ip4_address_t ipv4;
9986     ip6_address_t ipv6;
9987
9988     /* Parse args required to build the message */
9989     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
9990         if (unformat(input, "del")) {
9991             is_add = 0;
9992         } else if (unformat(input, "%U", unformat_ip4_address, &ipv4)) {
9993             ipv4_set = 1;
9994         } else if (unformat(input, "%U", unformat_ip6_address, &ipv6)) {
9995             ipv6_set = 1;
9996         } else
9997             break;
9998     }
9999
10000     if (ipv4_set && ipv6_set) {
10001         errmsg ("both eid v4 and v6 addresses set\n");
10002         return -99;
10003     }
10004
10005     if (!ipv4_set && !ipv6_set) {
10006         errmsg ("eid addresses not set\n");
10007         return -99;
10008     }
10009
10010     /* Construct the API message */
10011     M(LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
10012
10013     mp->is_add = is_add;
10014     if (ipv6_set) {
10015         mp->is_ipv6 = 1;
10016         clib_memcpy(mp->ip_address, &ipv6, sizeof(ipv6));
10017     } else {
10018         mp->is_ipv6 = 0;
10019         clib_memcpy(mp->ip_address, &ipv4, sizeof(ipv4));
10020     }
10021
10022     /* send it... */
10023     S;
10024
10025     /* Wait for a reply... */
10026     W;
10027
10028     /* NOTREACHED */
10029     return 0;
10030 }
10031
10032 static int
10033 api_lisp_gpe_enable_disable (vat_main_t * vam)
10034 {
10035   unformat_input_t * input = vam->input;
10036   vl_api_lisp_gpe_enable_disable_t *mp;
10037   f64 timeout = ~0;
10038   u8 is_set = 0;
10039   u8 is_en = 1;
10040
10041   /* Parse args required to build the message */
10042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10043       if (unformat(input, "enable")) {
10044           is_set = 1;
10045           is_en = 1;
10046       } else if (unformat(input, "disable")) {
10047           is_set = 1;
10048           is_en = 0;
10049       } else
10050           break;
10051   }
10052
10053   if (is_set == 0) {
10054       errmsg("Value not set\n");
10055       return -99;
10056   }
10057
10058   /* Construct the API message */
10059   M(LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
10060
10061   mp->is_en = is_en;
10062
10063   /* send it... */
10064   S;
10065
10066   /* Wait for a reply... */
10067   W;
10068
10069   /* NOTREACHED */
10070   return 0;
10071 }
10072
10073 static int
10074 api_lisp_enable_disable (vat_main_t * vam)
10075 {
10076   unformat_input_t * input = vam->input;
10077   vl_api_lisp_enable_disable_t *mp;
10078   f64 timeout = ~0;
10079   u8 is_set = 0;
10080   u8 is_en = 0;
10081
10082   /* Parse args required to build the message */
10083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10084     {
10085       if (unformat (input, "enable"))
10086         {
10087           is_set = 1;
10088           is_en = 1;
10089         }
10090       else if (unformat (input, "disable"))
10091         {
10092           is_set = 1;
10093         }
10094       else
10095           break;
10096     }
10097
10098   if (!is_set)
10099     {
10100       errmsg ("Value not set\n");
10101       return -99;
10102     }
10103
10104   /* Construct the API message */
10105   M(LISP_ENABLE_DISABLE, lisp_enable_disable);
10106
10107   mp->is_en = is_en;
10108
10109   /* send it... */
10110   S;
10111
10112   /* Wait for a reply... */
10113   W;
10114
10115   /* NOTREACHED */
10116   return 0;
10117 }
10118
10119 /** Used for transferring locators via VPP API */
10120 typedef CLIB_PACKED(struct
10121 {
10122     u8 is_ip4; /**< is locator an IPv4 address? */
10123     u8 addr[16]; /**< IPv4/IPv6 address */
10124 }) rloc_t;
10125
10126 /**
10127  * Enable/disable LISP proxy ITR.
10128  *
10129  * @param vam vpp API test context
10130  * @return return code
10131  */
10132 static int
10133 api_lisp_pitr_set_locator_set (vat_main_t * vam)
10134 {
10135   f64 timeout = ~0;
10136   u8 ls_name_set = 0;
10137   unformat_input_t * input = vam->input;
10138   vl_api_lisp_pitr_set_locator_set_t * mp;
10139   u8 is_add = 1;
10140   u8 * ls_name = 0;
10141
10142   /* Parse args required to build the message */
10143   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (input, "del"))
10146         is_add = 0;
10147       else if (unformat (input, "locator-set %s", &ls_name))
10148         ls_name_set = 1;
10149       else
10150         {
10151           errmsg ("parse error '%U'", format_unformat_error, input);
10152           return -99;
10153         }
10154     }
10155
10156   if (!ls_name_set)
10157     {
10158       errmsg ("locator-set name not set!");
10159       return -99;
10160     }
10161
10162   M(LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
10163
10164   mp->is_add = is_add;
10165   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
10166   vec_free (ls_name);
10167
10168   /* send */
10169   S;
10170
10171   /* wait for reply */
10172   W;
10173
10174   /* notreached*/
10175   return 0;
10176 }
10177
10178 /**
10179  * Add/del remote mapping from LISP control plane and updates
10180  * forwarding entries in data-plane accordingly.
10181  *
10182  * @param vam vpp API test context
10183  * @return return code
10184  */
10185 static int
10186 api_lisp_add_del_remote_mapping (vat_main_t * vam)
10187 {
10188     unformat_input_t * input = vam->input;
10189     vl_api_lisp_add_del_remote_mapping_t *mp;
10190     f64 timeout = ~0;
10191     u32 vni = 0;
10192     u8 seid_set = 0, deid_set = 0;
10193     ip4_address_t seid4, deid4, rloc4;
10194     ip6_address_t seid6, deid6, rloc6;
10195     u32 seid_len = 0, deid_len = 0, len;
10196     u8 deid_is_ip4 = 0, seid_is_ip4 = 0;
10197     u8 is_add = 1;
10198     u32 action = ~0;
10199     rloc_t * rlocs = 0, rloc;
10200
10201     /* Parse args required to build the message */
10202     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10203         if (unformat(input, "del")) {
10204             is_add = 0;
10205         } else if (unformat(input, "add")) {
10206             is_add = 1;
10207         } else if (unformat(input, "deid %U/%d", unformat_ip4_address,
10208                             &deid4, &len)) {
10209             deid_set = 1;
10210             deid_is_ip4 = 1;
10211             deid_len = len;
10212         } else if (unformat(input, "deid %U/%d", unformat_ip6_address,
10213                             &deid6, &len)) {
10214             deid_set = 1;
10215             deid_is_ip4 = 0;
10216             deid_len = len;
10217         } else if (unformat(input, "seid %U/%d", unformat_ip4_address,
10218                             &seid4, &len)) {
10219             seid_set = 1;
10220             seid_is_ip4 = 1;
10221             seid_len = len;
10222         } else if (unformat(input, "seid %U/%d", unformat_ip6_address,
10223                             &seid6, &len)) {
10224             seid_set = 1;
10225             seid_is_ip4 = 0;
10226             seid_len = len;
10227         } else if (unformat(input, "vni %d", &vni)) {
10228             ;
10229         } else if (unformat(input, "rloc %U", unformat_ip4_address, &rloc4)) {
10230             rloc.is_ip4 = 1;
10231             clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
10232             vec_add1 (rlocs, rloc);
10233         } else if (unformat(input, "rloc %U", unformat_ip6_address, &rloc6)) {
10234             rloc.is_ip4 = 0;
10235             clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
10236             vec_add1 (rlocs, rloc);
10237         } else if (unformat(input, "action %d", &action)) {
10238             ;
10239         } else {
10240             clib_warning ("parse error '%U'", format_unformat_error, input);
10241             return -99;
10242         }
10243     }
10244
10245     if (!seid_set || !deid_set) {
10246         errmsg ("missing params!");
10247         return -99;
10248     }
10249
10250     if (seid_is_ip4 != deid_is_ip4) {
10251         errmsg ("source and destination EIDs are not in " "same IP family!");
10252         return -99;
10253     }
10254
10255     if (is_add && (~0 == action)
10256         && 0 == vec_len (rlocs)) {
10257           errmsg ("no action set for negative map-reply!");
10258           return -99;
10259     }
10260
10261     M(LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
10262     mp->is_add = is_add;
10263     mp->vni = htonl (vni);
10264     mp->seid_len = seid_len;
10265     mp->action = (u8) action;
10266     mp->deid_len = deid_len;
10267     if (seid_is_ip4) {
10268         mp->eid_is_ip4 = 1;
10269         clib_memcpy (mp->seid, &seid4, sizeof (seid4));
10270     } else {
10271         mp->eid_is_ip4 = 0;
10272         clib_memcpy (mp->seid, &seid6, sizeof (seid6));
10273     }
10274
10275     if (deid_is_ip4) {
10276         mp->eid_is_ip4 = 1;
10277         clib_memcpy (mp->deid, &deid4, sizeof (deid4));
10278     } else {
10279         mp->eid_is_ip4 = 0;
10280         clib_memcpy (mp->deid, &deid6, sizeof (deid6));
10281     }
10282
10283     mp->rloc_num = vec_len (rlocs);
10284     clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
10285     vec_free (rlocs);
10286
10287     /* send it... */
10288     S;
10289
10290     /* Wait for a reply... */
10291     W;
10292
10293     /* NOTREACHED */
10294     return 0;
10295 }
10296
10297 static int
10298 api_lisp_gpe_add_del_iface(vat_main_t * vam)
10299 {
10300     unformat_input_t * input = vam->input;
10301     vl_api_lisp_gpe_add_del_iface_t *mp;
10302     f64 timeout = ~0;
10303     u8 is_set = 0;
10304     u8 is_add = 1;
10305     u32 table_id, vni;
10306
10307     /* Parse args required to build the message */
10308     while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
10309         if (unformat(input, "up")) {
10310             is_set = 1;
10311             is_add = 1;
10312         } else if (unformat(input, "down")) {
10313             is_set = 1;
10314             is_add = 0;
10315         } else if (unformat(input, "table_id %d", &table_id)) {
10316             ;
10317         } else if (unformat(input, "vni %d", &vni)) {
10318             ;
10319         } else
10320             break;
10321     }
10322
10323     if (is_set == 0) {
10324         errmsg("Value not set\n");
10325         return -99;
10326     }
10327
10328     /* Construct the API message */
10329     M(LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
10330
10331     mp->is_add = is_add;
10332     mp->table_id = table_id;
10333     mp->vni = vni;
10334
10335     /* send it... */
10336     S;
10337
10338     /* Wait for a reply... */
10339     W;
10340
10341     /* NOTREACHED */
10342     return 0;
10343 }
10344
10345 static int
10346 api_lisp_locator_set_dump(vat_main_t *vam)
10347 {
10348     vl_api_lisp_locator_set_dump_t *mp;
10349     f64 timeout = ~0;
10350
10351     if (!vam->json_output) {
10352         fformat(vam->ofp, "%=20s%=16s%=16s%=16s\n",
10353                 "Locator-set", "Locator", "Priority", "Weight");
10354     }
10355
10356     M(LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
10357     /* send it... */
10358     S;
10359
10360     /* Use a control ping for synchronization */
10361     {
10362         vl_api_control_ping_t * mp;
10363         M(CONTROL_PING, control_ping);
10364         S;
10365     }
10366     /* Wait for a reply... */
10367     W;
10368
10369     /* NOTREACHED */
10370     return 0;
10371 }
10372
10373 static int
10374 api_lisp_local_eid_table_dump(vat_main_t *vam)
10375 {
10376     vl_api_lisp_local_eid_table_dump_t *mp;
10377     f64 timeout = ~0;
10378
10379     if (!vam->json_output) {
10380         fformat(vam->ofp, "%=20s%=30s\n",
10381                 "Locator-set", "Eid");
10382     }
10383
10384     M(LISP_LOCAL_EID_TABLE_DUMP, lisp_local_eid_table_dump);
10385     /* send it... */
10386     S;
10387
10388     /* Use a control ping for synchronization */
10389     {
10390         vl_api_control_ping_t * mp;
10391         M(CONTROL_PING, control_ping);
10392         S;
10393     }
10394     /* Wait for a reply... */
10395     W;
10396
10397     /* NOTREACHED */
10398     return 0;
10399 }
10400
10401 static int
10402 api_lisp_gpe_tunnel_dump(vat_main_t *vam)
10403 {
10404     vl_api_lisp_gpe_tunnel_dump_t *mp;
10405     f64 timeout = ~0;
10406
10407     if (!vam->json_output) {
10408         fformat(vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
10409                 "%=16s%=16s%=16s%=16s%=16s\n",
10410                 "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
10411                 "Decap next", "Lisp version", "Flags", "Next protocol",
10412                 "ver_res", "res", "iid");
10413     }
10414
10415     M(LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
10416     /* send it... */
10417     S;
10418
10419     /* Use a control ping for synchronization */
10420     {
10421         vl_api_control_ping_t * mp;
10422         M(CONTROL_PING, control_ping);
10423         S;
10424     }
10425     /* Wait for a reply... */
10426     W;
10427
10428     /* NOTREACHED */
10429     return 0;
10430 }
10431
10432 static int
10433 api_lisp_map_resolver_dump(vat_main_t *vam)
10434 {
10435     vl_api_lisp_map_resolver_dump_t *mp;
10436     f64 timeout = ~0;
10437
10438     if (!vam->json_output) {
10439         fformat(vam->ofp, "%=20s\n",
10440                 "Map resolver");
10441     }
10442
10443     M(LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
10444     /* send it... */
10445     S;
10446
10447     /* Use a control ping for synchronization */
10448     {
10449         vl_api_control_ping_t * mp;
10450         M(CONTROL_PING, control_ping);
10451         S;
10452     }
10453     /* Wait for a reply... */
10454     W;
10455
10456     /* NOTREACHED */
10457     return 0;
10458 }
10459
10460 static int
10461 api_lisp_enable_disable_status_dump(vat_main_t *vam)
10462 {
10463     vl_api_lisp_enable_disable_status_dump_t *mp;
10464     f64 timeout = ~0;
10465
10466     if (!vam->json_output) {
10467         fformat(vam->ofp, "%=20s\n",
10468                 "lisp status:");
10469     }
10470
10471     M(LISP_ENABLE_DISABLE_STATUS_DUMP,
10472       lisp_enable_disable_status_dump);
10473     /* send it... */
10474     S;
10475
10476     /* Use a control ping for synchronization */
10477     {
10478         vl_api_control_ping_t * mp;
10479         M(CONTROL_PING, control_ping);
10480         S;
10481     }
10482     /* Wait for a reply... */
10483     W;
10484
10485     /* NOTREACHED */
10486     return 0;
10487 }
10488
10489 static int
10490 api_af_packet_create (vat_main_t * vam)
10491 {
10492     unformat_input_t * i = vam->input;
10493     vl_api_af_packet_create_t * mp;
10494     f64 timeout;
10495     u8 * host_if_name = 0;
10496     u8 hw_addr[6];
10497     u8 random_hw_addr = 1;
10498
10499     memset (hw_addr, 0, sizeof (hw_addr));
10500
10501     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10502         if (unformat (i, "name %s", &host_if_name))
10503             vec_add1 (host_if_name, 0);
10504         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10505             random_hw_addr = 0;
10506         else
10507           break;
10508     }
10509
10510     if (!vec_len (host_if_name)) {
10511         errmsg ("host-interface name must be specified");
10512         return -99;
10513     }
10514
10515     if (vec_len (host_if_name) > 64) {
10516         errmsg ("host-interface name too long");
10517         return -99;
10518     }
10519
10520     M(AF_PACKET_CREATE, af_packet_create);
10521
10522     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10523     clib_memcpy (mp->hw_addr, hw_addr, 6);
10524     mp->use_random_hw_addr = random_hw_addr;
10525     vec_free (host_if_name);
10526
10527     S; W;
10528     /* NOTREACHED */
10529     return 0;
10530 }
10531
10532 static int
10533 api_af_packet_delete (vat_main_t * vam)
10534 {
10535     unformat_input_t * i = vam->input;
10536     vl_api_af_packet_delete_t * mp;
10537     f64 timeout;
10538     u8 * host_if_name = 0;
10539
10540     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10541         if (unformat (i, "name %s", &host_if_name))
10542             vec_add1 (host_if_name, 0);
10543         else
10544           break;
10545     }
10546
10547     if (!vec_len (host_if_name)) {
10548         errmsg ("host-interface name must be specified");
10549         return -99;
10550     }
10551
10552     if (vec_len (host_if_name) > 64) {
10553         errmsg ("host-interface name too long");
10554         return -99;
10555     }
10556
10557     M(AF_PACKET_DELETE, af_packet_delete);
10558
10559     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
10560     vec_free (host_if_name);
10561
10562     S; W;
10563     /* NOTREACHED */
10564     return 0;
10565 }
10566
10567 static int
10568 api_policer_add_del (vat_main_t * vam)
10569 {
10570     unformat_input_t * i = vam->input;
10571     vl_api_policer_add_del_t * mp;
10572     f64 timeout;
10573     u8 is_add = 1;
10574     u8 * name = 0;
10575     u32 cir = 0;
10576     u32 eir = 0;
10577     u64 cb = 0;
10578     u64 eb = 0;
10579     u8 rate_type = 0;
10580     u8 round_type = 0;
10581     u8 type = 0;
10582
10583     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10584         if (unformat (i, "del"))
10585             is_add = 0;
10586         else if (unformat (i, "name %s", &name))
10587             vec_add1 (name, 0);
10588         else if (unformat (i, "cir %u", &cir))
10589             ;
10590         else if (unformat (i, "eir %u", &eir))
10591             ;
10592         else if (unformat (i, "cb %u", &cb))
10593             ;
10594         else if (unformat (i, "eb %u", &eb))
10595             ;
10596         else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
10597                            &rate_type))
10598             ;
10599         else if (unformat (i, "round_type %U", unformat_policer_round_type,
10600                            &round_type))
10601             ;
10602         else if (unformat (i, "type %U", unformat_policer_type, &type))
10603             ;
10604         else
10605           break;
10606     }
10607
10608     if (!vec_len (name)) {
10609         errmsg ("policer name must be specified");
10610         return -99;
10611     }
10612
10613     if (vec_len (name) > 64) {
10614         errmsg ("policer name too long");
10615         return -99;
10616     }
10617
10618     M(POLICER_ADD_DEL, policer_add_del);
10619
10620     clib_memcpy (mp->name, name, vec_len (name));
10621     vec_free (name);
10622     mp->is_add = is_add;
10623     mp->cir = cir;
10624     mp->eir = eir;
10625     mp->cb = cb;
10626     mp->eb = eb;
10627     mp->rate_type = rate_type;
10628     mp->round_type = round_type;
10629     mp->type = type;
10630
10631     S; W;
10632     /* NOTREACHED */
10633     return 0;
10634 }
10635
10636 static int
10637 api_policer_dump(vat_main_t *vam)
10638 {
10639     unformat_input_t * i = vam->input;
10640     vl_api_policer_dump_t *mp;
10641     f64 timeout = ~0;
10642     u8 *match_name = 0;
10643     u8 match_name_valid = 0;
10644
10645     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10646         if (unformat (i, "name %s", &match_name)) {
10647             vec_add1 (match_name, 0);
10648             match_name_valid = 1;
10649         } else
10650             break;
10651     }
10652
10653     M(POLICER_DUMP, policer_dump);
10654     mp->match_name_valid = match_name_valid;
10655     clib_memcpy (mp->match_name, match_name, vec_len (match_name));
10656     vec_free (match_name);
10657     /* send it... */
10658     S;
10659
10660     /* Use a control ping for synchronization */
10661     {
10662         vl_api_control_ping_t * mp;
10663         M(CONTROL_PING, control_ping);
10664         S;
10665     }
10666     /* Wait for a reply... */
10667     W;
10668
10669     /* NOTREACHED */
10670     return 0;
10671 }
10672
10673 static int
10674 api_netmap_create (vat_main_t * vam)
10675 {
10676     unformat_input_t * i = vam->input;
10677     vl_api_netmap_create_t * mp;
10678     f64 timeout;
10679     u8 * if_name = 0;
10680     u8 hw_addr[6];
10681     u8 random_hw_addr = 1;
10682     u8 is_pipe = 0;
10683     u8 is_master = 0;
10684
10685     memset (hw_addr, 0, sizeof (hw_addr));
10686
10687     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10688         if (unformat (i, "name %s", &if_name))
10689             vec_add1 (if_name, 0);
10690         else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
10691             random_hw_addr = 0;
10692         else if (unformat (i, "pipe"))
10693             is_pipe = 1;
10694         else if (unformat (i, "master"))
10695             is_master = 1;
10696         else if (unformat (i, "slave"))
10697             is_master = 0;
10698         else
10699           break;
10700     }
10701
10702     if (!vec_len (if_name)) {
10703         errmsg ("interface name must be specified");
10704         return -99;
10705     }
10706
10707     if (vec_len (if_name) > 64) {
10708         errmsg ("interface name too long");
10709         return -99;
10710     }
10711
10712     M(NETMAP_CREATE, netmap_create);
10713
10714     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
10715     clib_memcpy (mp->hw_addr, hw_addr, 6);
10716     mp->use_random_hw_addr = random_hw_addr;
10717     mp->is_pipe = is_pipe;
10718     mp->is_master = is_master;
10719     vec_free (if_name);
10720
10721     S; W;
10722     /* NOTREACHED */
10723     return 0;
10724 }
10725
10726 static int
10727 api_netmap_delete (vat_main_t * vam)
10728 {
10729     unformat_input_t * i = vam->input;
10730     vl_api_netmap_delete_t * mp;
10731     f64 timeout;
10732     u8 * if_name = 0;
10733
10734     while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
10735         if (unformat (i, "name %s", &if_name))
10736             vec_add1 (if_name, 0);
10737         else
10738             break;
10739     }
10740
10741     if (!vec_len (if_name)) {
10742         errmsg ("interface name must be specified");
10743         return -99;
10744     }
10745
10746     if (vec_len (if_name) > 64) {
10747         errmsg ("interface name too long");
10748         return -99;
10749     }
10750
10751     M(NETMAP_DELETE, netmap_delete);
10752
10753     clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
10754     vec_free (if_name);
10755
10756     S; W;
10757     /* NOTREACHED */
10758     return 0;
10759 }
10760
10761 static int q_or_quit (vat_main_t * vam)
10762 {
10763     longjmp (vam->jump_buf, 1);
10764     return 0; /* not so much */
10765 }
10766 static int q (vat_main_t * vam) {return q_or_quit (vam);}
10767 static int quit (vat_main_t * vam) {return q_or_quit (vam);}
10768
10769 static int comment (vat_main_t * vam)
10770 {
10771     return 0;
10772 }
10773
10774 static int cmd_cmp (void * a1, void * a2)
10775 {
10776   u8 ** c1 = a1;
10777   u8 ** c2 = a2;
10778
10779   return strcmp ((char *)(c1[0]), (char *)(c2[0]));
10780 }
10781
10782 static int help (vat_main_t * vam)
10783 {
10784     u8 ** cmds = 0;
10785     u8 * name = 0;
10786     hash_pair_t * p;
10787     unformat_input_t * i = vam->input;
10788     int j;
10789
10790     if (unformat (i, "%s", &name)) {
10791         uword *hs;
10792
10793         vec_add1(name, 0);
10794
10795         hs = hash_get_mem (vam->help_by_name, name);
10796         if (hs)
10797             fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
10798         else
10799             fformat (vam->ofp, "No such msg / command '%s'\n", name);
10800         vec_free(name);
10801         return 0;
10802     }
10803
10804     fformat(vam->ofp, "Help is available for the following:\n");
10805
10806     hash_foreach_pair (p, vam->function_by_name, 
10807     ({
10808         vec_add1 (cmds, (u8 *)(p->key));
10809     }));
10810
10811     vec_sort_with_function (cmds, cmd_cmp);
10812
10813     for (j = 0; j < vec_len(cmds); j++)
10814         fformat (vam->ofp, "%s\n", cmds[j]);
10815
10816     vec_free (cmds);
10817     return 0;
10818 }
10819
10820 static int set (vat_main_t * vam)
10821 {
10822     u8 * name = 0, * value = 0;
10823     unformat_input_t * i = vam->input;
10824
10825     if (unformat (i, "%s", &name)) {
10826         /* The input buffer is a vector, not a string. */
10827         value = vec_dup (i->buffer);
10828         vec_delete (value, i->index, 0);
10829         /* Almost certainly has a trailing newline */
10830         if (value[vec_len(value)-1] == '\n')
10831             value[vec_len(value)-1] = 0;
10832         /* Make sure it's a proper string, one way or the other */
10833         vec_add1 (value, 0);
10834         (void) clib_macro_set_value (&vam->macro_main, 
10835                                      (char *)name, (char *)value);
10836     }
10837     else
10838         errmsg ("usage: set <name> <value>\n");
10839
10840     vec_free (name);
10841     vec_free (value);
10842     return 0;
10843 }
10844
10845 static int unset (vat_main_t * vam)
10846 {
10847     u8 * name = 0;
10848
10849     if (unformat (vam->input, "%s", &name))
10850         if (clib_macro_unset (&vam->macro_main, (char *)name) == 1)
10851             errmsg ("unset: %s wasn't set\n", name);
10852     vec_free (name);
10853     return 0;
10854 }
10855
10856 typedef struct {
10857     u8 * name;
10858     u8 * value;
10859 } macro_sort_t;
10860
10861
10862 static int macro_sort_cmp (void * a1, void * a2)
10863 {
10864   macro_sort_t * s1 = a1;
10865   macro_sort_t * s2 = a2;
10866
10867   return strcmp ((char *)(s1->name), (char *)(s2->name));
10868 }
10869
10870 static int dump_macro_table (vat_main_t * vam)
10871 {
10872     macro_sort_t * sort_me = 0, * sm;    
10873     int i;
10874     hash_pair_t * p;
10875
10876     hash_foreach_pair (p, vam->macro_main.the_value_table_hash, 
10877     ({
10878         vec_add2 (sort_me, sm, 1);
10879         sm->name = (u8 *)(p->key);
10880         sm->value = (u8 *) (p->value[0]);
10881     }));
10882     
10883     vec_sort_with_function (sort_me, macro_sort_cmp);
10884
10885     if (vec_len(sort_me))
10886         fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
10887     else
10888         fformat (vam->ofp, "The macro table is empty...\n");
10889
10890     for (i = 0; i < vec_len (sort_me); i++)
10891         fformat (vam->ofp, "%-15s%s\n", sort_me[i].name,
10892                  sort_me[i].value);
10893     return 0;
10894 }
10895
10896 static int dump_node_table (vat_main_t * vam)
10897 {
10898     int i, j;
10899     vlib_node_t * node, * next_node;
10900
10901     if (vec_len (vam->graph_nodes) == 0) {
10902         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10903         return 0;
10904     }
10905
10906     for (i = 0; i < vec_len (vam->graph_nodes); i++) {
10907         node = vam->graph_nodes[i];
10908         fformat (vam->ofp, "[%d] %s\n", i, node->name);
10909         for (j = 0; j < vec_len (node->next_nodes); j++) {
10910             if (node->next_nodes[j] != ~0) {
10911                 next_node = vam->graph_nodes[node->next_nodes[j]];
10912                 fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
10913             }
10914         }
10915     }
10916     return 0;
10917 }
10918
10919 static int search_node_table (vat_main_t * vam)
10920 {
10921     unformat_input_t * line_input = vam->input;
10922     u8 * node_to_find;
10923     int j;
10924     vlib_node_t * node, * next_node;
10925     uword * p;
10926
10927     if (vam->graph_node_index_by_name == 0) {
10928         fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
10929         return 0;
10930     }
10931
10932     while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
10933         if (unformat (line_input, "%s", &node_to_find)) {
10934             vec_add1 (node_to_find, 0);
10935             p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
10936             if (p == 0) {
10937                 fformat (vam->ofp, "%s not found...\n", node_to_find);
10938                 goto out;
10939             }
10940             node = vam->graph_nodes[p[0]];
10941             fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
10942             for (j = 0; j < vec_len (node->next_nodes); j++) {
10943                 if (node->next_nodes[j] != ~0) {
10944                     next_node = vam->graph_nodes[node->next_nodes[j]];
10945                     fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
10946                 }
10947             }
10948         }
10949             
10950         else {
10951             clib_warning ("parse error '%U'", format_unformat_error, 
10952                           line_input);
10953             return -99;
10954         }
10955
10956     out:
10957         vec_free(node_to_find);
10958         
10959     }
10960
10961     return 0;        
10962 }
10963
10964
10965 static int script (vat_main_t * vam)
10966 {
10967     u8 * s = 0;
10968     char * save_current_file;
10969     unformat_input_t save_input;
10970     jmp_buf save_jump_buf;
10971     u32 save_line_number;
10972
10973     FILE * new_fp, * save_ifp;
10974
10975     if (unformat (vam->input, "%s", &s)) {
10976         new_fp = fopen ((char *)s, "r");
10977         if (new_fp == 0) {
10978             errmsg ("Couldn't open script file %s\n", s);
10979             vec_free (s);
10980             return -99;
10981         }
10982     } else {
10983         errmsg ("Missing script name\n");
10984         return -99;
10985     }
10986
10987     clib_memcpy (&save_input, &vam->input, sizeof (save_input));
10988     clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
10989     save_ifp = vam->ifp;
10990     save_line_number = vam->input_line_number;
10991     save_current_file = (char *) vam->current_file;
10992
10993     vam->input_line_number = 0;
10994     vam->ifp = new_fp;
10995     vam->current_file = s;
10996     do_one_file (vam);
10997
10998     clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
10999     clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
11000     vam->ifp = save_ifp;
11001     vam->input_line_number = save_line_number;
11002     vam->current_file = (u8 *) save_current_file;
11003     vec_free (s);
11004
11005     return 0;
11006 }
11007
11008 static int echo (vat_main_t * vam)
11009 {
11010     fformat (vam->ofp, "%v", vam->input->buffer);
11011     return 0;
11012 }
11013
11014 /* List of API message constructors, CLI names map to api_xxx */
11015 #define foreach_vpe_api_msg                                             \
11016 _(create_loopback,"[mac <mac-addr>]")                                   \
11017 _(sw_interface_dump,"")                                                 \
11018 _(sw_interface_set_flags,                                               \
11019   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
11020 _(sw_interface_add_del_address,                                         \
11021   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
11022 _(sw_interface_set_table,                                               \
11023   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
11024 _(sw_interface_set_vpath,                                               \
11025   "<intfc> | sw_if_index <id> enable | disable")                        \
11026 _(sw_interface_set_l2_xconnect,                                         \
11027   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11028   "enable | disable")                                                   \
11029 _(sw_interface_set_l2_bridge,                                           \
11030   "rx <intfc> | rx_sw_if_index <id> bd_id <bridge-domain-id>\n"         \
11031   "[shg <split-horizon-group>] [bvi]\n"                                 \
11032   "enable | disable")                                                   \
11033 _(bridge_domain_add_del,                                                \
11034   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
11035 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
11036 _(l2fib_add_del,                                                        \
11037   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi]\n") \
11038 _(l2_flags,                                                             \
11039   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
11040 _(bridge_flags,                                                         \
11041   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
11042 _(tap_connect,                                                          \
11043   "tapname <name> mac <mac-addr> | random-mac")                         \
11044 _(tap_modify,                                                           \
11045   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
11046 _(tap_delete,                                                           \
11047   "<vpp-if-name> | sw_if_index <id>")                                   \
11048 _(sw_interface_tap_dump, "")                                            \
11049 _(ip_add_del_route,                                                     \
11050   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
11051   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
11052   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
11053   "[multipath] [count <n>]")                                            \
11054 _(proxy_arp_add_del,                                                    \
11055   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
11056 _(proxy_arp_intfc_enable_disable,                                       \
11057   "<intfc> | sw_if_index <id> enable | disable")                        \
11058 _(mpls_add_del_encap,                                                   \
11059   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
11060 _(mpls_add_del_decap,                                                   \
11061   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
11062 _(mpls_gre_add_del_tunnel,                                              \
11063   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
11064   "adj <ip4-address>/<mask-width> [del]")                               \
11065 _(sw_interface_set_unnumbered,                                          \
11066   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
11067 _(ip_neighbor_add_del,                                                  \
11068   "<intfc> | sw_if_index <id> dst <ip46-address> mac <mac-addr>")       \
11069 _(reset_vrf, "vrf <id> [ipv6]")                                         \
11070 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
11071 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
11072   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
11073   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
11074   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
11075 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
11076 _(reset_fib, "vrf <n> [ipv6]")                                          \
11077 _(dhcp_proxy_config,                                                    \
11078   "svr <v46-address> src <v46-address>\n"                               \
11079    "insert-cid <n> [del]")                                              \
11080 _(dhcp_proxy_config_2,                                                  \
11081   "svr <v46-address> src <v46-address>\n"                               \
11082    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
11083 _(dhcp_proxy_set_vss,                                                   \
11084   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
11085 _(dhcp_client_config,                                                   \
11086   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
11087 _(set_ip_flow_hash,                                                     \
11088   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
11089 _(sw_interface_ip6_enable_disable,                                      \
11090   "<intfc> | sw_if_index <id> enable | disable")                        \
11091 _(sw_interface_ip6_set_link_local_address,                              \
11092   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
11093 _(sw_interface_ip6nd_ra_prefix,                                         \
11094   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
11095   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
11096   "[nolink] [isno]")                                                    \
11097 _(sw_interface_ip6nd_ra_config,                                         \
11098   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
11099   "[life <n>] [count <n>] [interval <n>] [surpress]\n"                  \
11100   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
11101 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
11102 _(l2_patch_add_del,                                                     \
11103   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
11104   "enable | disable")                                                   \
11105 _(mpls_ethernet_add_del_tunnel,                                         \
11106   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
11107   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
11108 _(mpls_ethernet_add_del_tunnel_2,                                       \
11109   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
11110   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
11111 _(sr_tunnel_add_del,                                                    \
11112   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
11113   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
11114   "[policy <policy_name>]")                                             \
11115 _(sr_policy_add_del,                                                    \
11116   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
11117 _(sr_multicast_map_add_del,                                             \
11118   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
11119 _(classify_add_del_table,                                               \
11120   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
11121   "[del] mask <mask-value>\n"                                           \
11122   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
11123 _(classify_add_del_session,                                             \
11124   "[hit-next|l2-hit-next|acl-hit-next] <name|nn> table-index <nn>\n"    \
11125   "skip_n <nn> match_n <nn> match [hex] [l2] [l3 [ip4|ip6]]")           \
11126 _(classify_set_interface_ip_table,                                      \
11127   "<intfc> | sw_if_index <nn> table <nn>")                              \
11128 _(classify_set_interface_l2_tables,                                     \
11129   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
11130   "  [other-table <nn>]")                                               \
11131 _(get_node_index, "node <node-name")                                    \
11132 _(add_node_next, "node <node-name> next <next-node-name>")              \
11133 _(l2tpv3_create_tunnel,                                                 \
11134   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
11135   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
11136   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
11137 _(l2tpv3_set_tunnel_cookies,                                            \
11138   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
11139   "[new_remote_cookie <nn>]\n")                                         \
11140 _(l2tpv3_interface_enable_disable,                                      \
11141   "<intfc> | sw_if_index <nn> enable | disable")                        \
11142 _(l2tpv3_set_lookup_key,                                                \
11143   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
11144 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
11145 _(vxlan_add_del_tunnel,                                                 \
11146   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
11147   " [decap-next l2|ip4|ip6] [del]")                                     \
11148 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
11149 _(gre_add_del_tunnel,                                                   \
11150   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
11151 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
11152 _(l2_fib_clear_table, "")                                               \
11153 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
11154 _(l2_interface_vlan_tag_rewrite,                                        \
11155   "<intfc> | sw_if_index <nn> \n"                                       \
11156   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
11157   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
11158 _(create_vhost_user_if,                                                 \
11159         "socket <filename> [server] [renumber <dev_instance>] "         \
11160         "[mac <mac_address>]")                                          \
11161 _(modify_vhost_user_if,                                                 \
11162         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
11163         "[server] [renumber <dev_instance>]")                           \
11164 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
11165 _(sw_interface_vhost_user_dump, "")                                     \
11166 _(show_version, "")                                                     \
11167 _(vxlan_gpe_add_del_tunnel,                                             \
11168   "local <addr> remote <addr> vni <nn>\n"                               \
11169     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
11170   "[next-ethernet] [next-nsh]\n")                                       \
11171 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
11172 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
11173 _(interface_name_renumber,                                              \
11174   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
11175 _(input_acl_set_interface,                                              \
11176   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
11177   "  [l2-table <nn>] [del]")                                            \
11178 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
11179 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
11180 _(ip_dump, "ipv4 | ipv6")                                               \
11181 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
11182 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
11183   "  spid_id <n> ")                                                     \
11184 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
11185   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
11186   "  integ_alg <alg> integ_key <hex>")                                  \
11187 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
11188   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
11189   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
11190   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
11191 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
11192 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
11193 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
11194   "(auth_data 0x<data> | auth_data <data>)")                            \
11195 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
11196   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
11197 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
11198   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
11199   "(local|remote)")                                                     \
11200 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
11201 _(delete_loopback,"sw_if_index <nn>")                                   \
11202 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
11203 _(map_add_domain,                                                       \
11204   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
11205   "ip6-src <ip6addr> "                                                  \
11206   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
11207 _(map_del_domain, "index <n>")                                          \
11208 _(map_add_del_rule,                                                     \
11209   "index <n> psid <n> dst <ip6addr> [del]")                             \
11210 _(map_domain_dump, "")                                                  \
11211 _(map_rule_dump, "index <map-domain>")                                  \
11212 _(want_interface_events,  "enable|disable")                             \
11213 _(want_stats,"enable|disable")                                          \
11214 _(get_first_msg_id, "client <name>")                                    \
11215 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
11216 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
11217   "fib-id <nn> [ip4][ip6][default]")                                    \
11218 _(get_node_graph, " ")                                                  \
11219 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
11220 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
11221   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
11222   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
11223 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
11224   " vrf_id <nn>  add | pop | none")                                     \
11225 _(trace_profile_del, "")                                                \
11226 _(lisp_add_del_locator_set, "locator-set <locator_name> [del]")         \
11227 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
11228                         "iface <intf> | sw_if_index <sw_if_index> "     \
11229                         "p <priority> w <weight> [del]")                \
11230 _(lisp_add_del_local_eid, "<ipv4|ipv6>/<prefix> "                       \
11231                           "locator-set <locator_name> [del]")           \
11232 _(lisp_gpe_add_del_fwd_entry, "eid <ip4|6-addr>/<prefix> "              \
11233     "sloc <ip4/6-addr> dloc <ip4|6-addr> [del]")                        \
11234 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
11235 _(lisp_gpe_enable_disable, "enable|disable")                            \
11236 _(lisp_enable_disable, "enable|disable")                                \
11237 _(lisp_gpe_add_del_iface, "up|down")                                    \
11238 _(lisp_add_del_remote_mapping, "add|del vni <vni> table-id <id> "       \
11239                                "deid <dest-eid> seid"                   \
11240                                " <src-eid> rloc <locator> "             \
11241                                "[rloc <loc> ... ]")                     \
11242 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
11243 _(lisp_locator_set_dump, "")                                            \
11244 _(lisp_local_eid_table_dump, "")                                        \
11245 _(lisp_gpe_tunnel_dump, "")                                             \
11246 _(lisp_map_resolver_dump, "")                                           \
11247 _(lisp_enable_disable_status_dump, "")                                  \
11248 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
11249 _(af_packet_delete, "name <host interface name>")                       \
11250 _(policer_add_del, "name <policer name> <params> [del]")                \
11251 _(policer_dump, "[name <policer name>]")                                \
11252 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
11253     "[master|slave]")                                                   \
11254 _(netmap_delete, "name <interface name>")
11255
11256 /* List of command functions, CLI names map directly to functions */
11257 #define foreach_cli_function                                    \
11258 _(comment, "usage: comment <ignore-rest-of-line>")              \
11259 _(dump_interface_table, "usage: dump_interface_table")          \
11260 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
11261 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
11262 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
11263 _(dump_stats_table, "usage: dump_stats_table")                  \
11264 _(dump_macro_table, "usage: dump_macro_table ")                 \
11265 _(dump_node_table, "usage: dump_node_table")                    \
11266 _(echo, "usage: echo <message>")                                \
11267 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
11268 _(help, "usage: help")                                          \
11269 _(q, "usage: quit")                                             \
11270 _(quit, "usage: quit")                                          \
11271 _(search_node_table, "usage: search_node_table <name>...")      \
11272 _(set, "usage: set <variable-name> <value>")                    \
11273 _(script, "usage: script <file-name>")                          \
11274 _(unset, "usage: unset <variable-name>")
11275
11276 #define _(N,n)                                  \
11277     static void vl_api_##n##_t_handler_uni      \
11278     (vl_api_##n##_t * mp)                       \
11279     {                                           \
11280         vat_main_t * vam = &vat_main;           \
11281         if (vam->json_output) {                 \
11282             vl_api_##n##_t_handler_json(mp);    \
11283         } else {                                \
11284             vl_api_##n##_t_handler(mp);         \
11285         }                                       \
11286     }
11287 foreach_vpe_api_reply_msg;
11288 #undef _
11289
11290 void vat_api_hookup (vat_main_t *vam)
11291 {
11292 #define _(N,n)                                                  \
11293     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
11294                            vl_api_##n##_t_handler_uni,          \
11295                            vl_noop_handler,                     \
11296                            vl_api_##n##_t_endian,               \
11297                            vl_api_##n##_t_print,                \
11298                            sizeof(vl_api_##n##_t), 1); 
11299     foreach_vpe_api_reply_msg;
11300 #undef _
11301
11302     vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
11303
11304     vam->sw_if_index_by_interface_name = 
11305         hash_create_string (0, sizeof (uword));
11306
11307     vam->function_by_name = 
11308         hash_create_string (0, sizeof(uword));
11309
11310     vam->help_by_name = 
11311         hash_create_string (0, sizeof(uword));
11312
11313     /* API messages we can send */
11314 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
11315     foreach_vpe_api_msg;
11316 #undef _
11317
11318     /* Help strings */
11319 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11320     foreach_vpe_api_msg;
11321 #undef _
11322
11323     /* CLI functions */
11324 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
11325     foreach_cli_function;
11326 #undef _
11327
11328     /* Help strings */
11329 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
11330     foreach_cli_function;
11331 #undef _
11332 }
11333
11334 #undef vl_api_version
11335 #define vl_api_version(n,v) static u32 vpe_api_version = v;
11336 #include <api/vpe.api.h>
11337 #undef vl_api_version
11338
11339 void vl_client_add_api_signatures (vl_api_memclnt_create_t *mp) 
11340 {
11341     /* 
11342      * Send the main API signature in slot 0. This bit of code must
11343      * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
11344      */
11345     mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
11346 }