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