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