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