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