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