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