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