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