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