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