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