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