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