c12b24703d9a4450361df7c00f4186ed94114b2f
[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/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_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, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1559   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   i32 retval = ntohl (mp->retval);
1563   if (vam->async_mode)
1564     {
1565       vam->async_errors += (retval < 0);
1566     }
1567   else
1568     {
1569       vam->retval = retval;
1570       vam->sw_if_index = ntohl (mp->sw_if_index);
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1576   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_gre_add_del_tunnel_reply_t_handler
1593   (vl_api_gre_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1610   (vl_api_gre_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_create_vhost_user_if_reply_t_handler
1627   (vl_api_create_vhost_user_if_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_create_vhost_user_if_reply_t_handler_json
1644   (vl_api_create_vhost_user_if_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_ip_address_details_t_handler
1661   (vl_api_ip_address_details_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   static ip_address_details_t empty_ip_address_details = { {0} };
1665   ip_address_details_t *address = NULL;
1666   ip_details_t *current_ip_details = NULL;
1667   ip_details_t *details = NULL;
1668
1669   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1670
1671   if (!details || vam->current_sw_if_index >= vec_len (details)
1672       || !details[vam->current_sw_if_index].present)
1673     {
1674       errmsg ("ip address details arrived but not stored\n");
1675       errmsg ("ip_dump should be called first\n");
1676       return;
1677     }
1678
1679   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1680
1681 #define addresses (current_ip_details->addr)
1682
1683   vec_validate_init_empty (addresses, vec_len (addresses),
1684                            empty_ip_address_details);
1685
1686   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1687
1688   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1689   address->prefix_length = mp->prefix_length;
1690 #undef addresses
1691 }
1692
1693 static void vl_api_ip_address_details_t_handler_json
1694   (vl_api_ip_address_details_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   vat_json_node_t *node = NULL;
1698   struct in6_addr ip6;
1699   struct in_addr ip4;
1700
1701   if (VAT_JSON_ARRAY != vam->json_tree.type)
1702     {
1703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1704       vat_json_init_array (&vam->json_tree);
1705     }
1706   node = vat_json_array_add (&vam->json_tree);
1707
1708   vat_json_init_object (node);
1709   if (vam->is_ipv6)
1710     {
1711       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1712       vat_json_object_add_ip6 (node, "ip", ip6);
1713     }
1714   else
1715     {
1716       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1717       vat_json_object_add_ip4 (node, "ip", ip4);
1718     }
1719   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1720 }
1721
1722 static void
1723 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   static ip_details_t empty_ip_details = { 0 };
1727   ip_details_t *ip = NULL;
1728   u32 sw_if_index = ~0;
1729
1730   sw_if_index = ntohl (mp->sw_if_index);
1731
1732   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1733                            sw_if_index, empty_ip_details);
1734
1735   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1736                          sw_if_index);
1737
1738   ip->present = 1;
1739 }
1740
1741 static void
1742 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1743 {
1744   vat_main_t *vam = &vat_main;
1745
1746   if (VAT_JSON_ARRAY != vam->json_tree.type)
1747     {
1748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1749       vat_json_init_array (&vam->json_tree);
1750     }
1751   vat_json_array_add_uint (&vam->json_tree,
1752                            clib_net_to_host_u32 (mp->sw_if_index));
1753 }
1754
1755 static void vl_api_map_domain_details_t_handler_json
1756   (vl_api_map_domain_details_t * mp)
1757 {
1758   vat_json_node_t *node = NULL;
1759   vat_main_t *vam = &vat_main;
1760   struct in6_addr ip6;
1761   struct in_addr ip4;
1762
1763   if (VAT_JSON_ARRAY != vam->json_tree.type)
1764     {
1765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1766       vat_json_init_array (&vam->json_tree);
1767     }
1768
1769   node = vat_json_array_add (&vam->json_tree);
1770   vat_json_init_object (node);
1771
1772   vat_json_object_add_uint (node, "domain_index",
1773                             clib_net_to_host_u32 (mp->domain_index));
1774   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1775   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1776   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1777   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1778   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1779   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1780   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1781   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1782   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1783   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1784   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1785   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1786   vat_json_object_add_uint (node, "flags", mp->flags);
1787   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1788   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1789 }
1790
1791 static void vl_api_map_domain_details_t_handler
1792   (vl_api_map_domain_details_t * mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795
1796   if (mp->is_translation)
1797     {
1798       fformat (vam->ofp,
1799                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1800                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1801                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1802                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1803                clib_net_to_host_u32 (mp->domain_index));
1804     }
1805   else
1806     {
1807       fformat (vam->ofp,
1808                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1809                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1810                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1811                format_ip6_address, mp->ip6_src,
1812                clib_net_to_host_u32 (mp->domain_index));
1813     }
1814   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1815            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1816            mp->is_translation ? "map-t" : "");
1817 }
1818
1819 static void vl_api_map_rule_details_t_handler_json
1820   (vl_api_map_rule_details_t * mp)
1821 {
1822   struct in6_addr ip6;
1823   vat_json_node_t *node = NULL;
1824   vat_main_t *vam = &vat_main;
1825
1826   if (VAT_JSON_ARRAY != vam->json_tree.type)
1827     {
1828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1829       vat_json_init_array (&vam->json_tree);
1830     }
1831
1832   node = vat_json_array_add (&vam->json_tree);
1833   vat_json_init_object (node);
1834
1835   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1836   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1837   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1838 }
1839
1840 static void
1841 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1845            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1846 }
1847
1848 static void
1849 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1850 {
1851   vat_main_t *vam = &vat_main;
1852   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1853           "router_addr %U host_mac %U\n",
1854           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1855           format_ip4_address, &mp->host_address,
1856           format_ip4_address, &mp->router_address,
1857           format_ethernet_address, mp->host_mac);
1858 }
1859
1860 static void vl_api_dhcp_compl_event_t_handler_json
1861   (vl_api_dhcp_compl_event_t * mp)
1862 {
1863   /* JSON output not supported */
1864 }
1865
1866 static void
1867 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1868                               u32 counter)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   static u64 default_counter = 0;
1872
1873   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1874                            NULL);
1875   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1876                            sw_if_index, default_counter);
1877   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1878 }
1879
1880 static void
1881 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1882                                 interface_counter_t counter)
1883 {
1884   vat_main_t *vam = &vat_main;
1885   static interface_counter_t default_counter = { 0, };
1886
1887   vec_validate_init_empty (vam->combined_interface_counters,
1888                            vnet_counter_type, NULL);
1889   vec_validate_init_empty (vam->combined_interface_counters
1890                            [vnet_counter_type], sw_if_index, default_counter);
1891   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1892 }
1893
1894 static void vl_api_vnet_interface_counters_t_handler
1895   (vl_api_vnet_interface_counters_t * mp)
1896 {
1897   /* not supported */
1898 }
1899
1900 static void vl_api_vnet_interface_counters_t_handler_json
1901   (vl_api_vnet_interface_counters_t * mp)
1902 {
1903   interface_counter_t counter;
1904   vlib_counter_t *v;
1905   u64 *v_packets;
1906   u64 packets;
1907   u32 count;
1908   u32 first_sw_if_index;
1909   int i;
1910
1911   count = ntohl (mp->count);
1912   first_sw_if_index = ntohl (mp->first_sw_if_index);
1913
1914   if (!mp->is_combined)
1915     {
1916       v_packets = (u64 *) & mp->data;
1917       for (i = 0; i < count; i++)
1918         {
1919           packets =
1920             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1921           set_simple_interface_counter (mp->vnet_counter_type,
1922                                         first_sw_if_index + i, packets);
1923           v_packets++;
1924         }
1925     }
1926   else
1927     {
1928       v = (vlib_counter_t *) & mp->data;
1929       for (i = 0; i < count; i++)
1930         {
1931           counter.packets =
1932             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1933           counter.bytes =
1934             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1935           set_combined_interface_counter (mp->vnet_counter_type,
1936                                           first_sw_if_index + i, counter);
1937           v++;
1938         }
1939     }
1940 }
1941
1942 static u32
1943 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1944 {
1945   vat_main_t *vam = &vat_main;
1946   u32 i;
1947
1948   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1949     {
1950       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1951         {
1952           return i;
1953         }
1954     }
1955   return ~0;
1956 }
1957
1958 static u32
1959 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   u32 i;
1963
1964   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1965     {
1966       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1967         {
1968           return i;
1969         }
1970     }
1971   return ~0;
1972 }
1973
1974 static void vl_api_vnet_ip4_fib_counters_t_handler
1975   (vl_api_vnet_ip4_fib_counters_t * mp)
1976 {
1977   /* not supported */
1978 }
1979
1980 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1981   (vl_api_vnet_ip4_fib_counters_t * mp)
1982 {
1983   vat_main_t *vam = &vat_main;
1984   vl_api_ip4_fib_counter_t *v;
1985   ip4_fib_counter_t *counter;
1986   struct in_addr ip4;
1987   u32 vrf_id;
1988   u32 vrf_index;
1989   u32 count;
1990   int i;
1991
1992   vrf_id = ntohl (mp->vrf_id);
1993   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1994   if (~0 == vrf_index)
1995     {
1996       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1997       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1998       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1999       vec_validate (vam->ip4_fib_counters, vrf_index);
2000       vam->ip4_fib_counters[vrf_index] = NULL;
2001     }
2002
2003   vec_free (vam->ip4_fib_counters[vrf_index]);
2004   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2005   count = ntohl (mp->count);
2006   for (i = 0; i < count; i++)
2007     {
2008       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2009       counter = &vam->ip4_fib_counters[vrf_index][i];
2010       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2011       counter->address = ip4;
2012       counter->address_length = v->address_length;
2013       counter->packets = clib_net_to_host_u64 (v->packets);
2014       counter->bytes = clib_net_to_host_u64 (v->bytes);
2015       v++;
2016     }
2017 }
2018
2019 static void vl_api_vnet_ip6_fib_counters_t_handler
2020   (vl_api_vnet_ip6_fib_counters_t * mp)
2021 {
2022   /* not supported */
2023 }
2024
2025 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2026   (vl_api_vnet_ip6_fib_counters_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   vl_api_ip6_fib_counter_t *v;
2030   ip6_fib_counter_t *counter;
2031   struct in6_addr ip6;
2032   u32 vrf_id;
2033   u32 vrf_index;
2034   u32 count;
2035   int i;
2036
2037   vrf_id = ntohl (mp->vrf_id);
2038   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2039   if (~0 == vrf_index)
2040     {
2041       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2042       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2043       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2044       vec_validate (vam->ip6_fib_counters, vrf_index);
2045       vam->ip6_fib_counters[vrf_index] = NULL;
2046     }
2047
2048   vec_free (vam->ip6_fib_counters[vrf_index]);
2049   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2050   count = ntohl (mp->count);
2051   for (i = 0; i < count; i++)
2052     {
2053       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2054       counter = &vam->ip6_fib_counters[vrf_index][i];
2055       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2056       counter->address = ip6;
2057       counter->address_length = v->address_length;
2058       counter->packets = clib_net_to_host_u64 (v->packets);
2059       counter->bytes = clib_net_to_host_u64 (v->bytes);
2060       v++;
2061     }
2062 }
2063
2064 static void vl_api_get_first_msg_id_reply_t_handler
2065   (vl_api_get_first_msg_id_reply_t * mp)
2066 {
2067   vat_main_t *vam = &vat_main;
2068   i32 retval = ntohl (mp->retval);
2069
2070   if (vam->async_mode)
2071     {
2072       vam->async_errors += (retval < 0);
2073     }
2074   else
2075     {
2076       vam->retval = retval;
2077       vam->result_ready = 1;
2078     }
2079   if (retval >= 0)
2080     {
2081       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2082     }
2083 }
2084
2085 static void vl_api_get_first_msg_id_reply_t_handler_json
2086   (vl_api_get_first_msg_id_reply_t * mp)
2087 {
2088   vat_main_t *vam = &vat_main;
2089   vat_json_node_t node;
2090
2091   vat_json_init_object (&node);
2092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2093   vat_json_object_add_uint (&node, "first_msg_id",
2094                             (uint) ntohs (mp->first_msg_id));
2095
2096   vat_json_print (vam->ofp, &node);
2097   vat_json_free (&node);
2098
2099   vam->retval = ntohl (mp->retval);
2100   vam->result_ready = 1;
2101 }
2102
2103 static void vl_api_get_node_graph_reply_t_handler
2104   (vl_api_get_node_graph_reply_t * mp)
2105 {
2106   vat_main_t *vam = &vat_main;
2107   api_main_t *am = &api_main;
2108   i32 retval = ntohl (mp->retval);
2109   u8 *pvt_copy, *reply;
2110   void *oldheap;
2111   vlib_node_t *node;
2112   int i;
2113
2114   if (vam->async_mode)
2115     {
2116       vam->async_errors += (retval < 0);
2117     }
2118   else
2119     {
2120       vam->retval = retval;
2121       vam->result_ready = 1;
2122     }
2123
2124   /* "Should never happen..." */
2125   if (retval != 0)
2126     return;
2127
2128   reply = (u8 *) (mp->reply_in_shmem);
2129   pvt_copy = vec_dup (reply);
2130
2131   /* Toss the shared-memory original... */
2132   pthread_mutex_lock (&am->vlib_rp->mutex);
2133   oldheap = svm_push_data_heap (am->vlib_rp);
2134
2135   vec_free (reply);
2136
2137   svm_pop_heap (oldheap);
2138   pthread_mutex_unlock (&am->vlib_rp->mutex);
2139
2140   if (vam->graph_nodes)
2141     {
2142       hash_free (vam->graph_node_index_by_name);
2143
2144       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2145         {
2146           node = vam->graph_nodes[i];
2147           vec_free (node->name);
2148           vec_free (node->next_nodes);
2149           vec_free (node);
2150         }
2151       vec_free (vam->graph_nodes);
2152     }
2153
2154   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2155   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2156   vec_free (pvt_copy);
2157
2158   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2159     {
2160       node = vam->graph_nodes[i];
2161       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2162     }
2163 }
2164
2165 static void vl_api_get_node_graph_reply_t_handler_json
2166   (vl_api_get_node_graph_reply_t * mp)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   api_main_t *am = &api_main;
2170   void *oldheap;
2171   vat_json_node_t node;
2172   u8 *reply;
2173
2174   /* $$$$ make this real? */
2175   vat_json_init_object (&node);
2176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2177   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2178
2179   reply = (u8 *) (mp->reply_in_shmem);
2180
2181   /* Toss the shared-memory original... */
2182   pthread_mutex_lock (&am->vlib_rp->mutex);
2183   oldheap = svm_push_data_heap (am->vlib_rp);
2184
2185   vec_free (reply);
2186
2187   svm_pop_heap (oldheap);
2188   pthread_mutex_unlock (&am->vlib_rp->mutex);
2189
2190   vat_json_print (vam->ofp, &node);
2191   vat_json_free (&node);
2192
2193   vam->retval = ntohl (mp->retval);
2194   vam->result_ready = 1;
2195 }
2196
2197 static void
2198 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2199 {
2200   vat_main_t *vam = &vat_main;
2201   locator_msg_t loc;
2202   u8 *tmp_str = 0;
2203
2204   memset (&loc, 0, sizeof (loc));
2205   if (vam->noprint_msg)
2206     {
2207       loc.local = mp->local;
2208       loc.priority = mp->priority;
2209       loc.weight = mp->weight;
2210       if (loc.local)
2211         {
2212           loc.sw_if_index = ntohl (mp->sw_if_index);
2213         }
2214       else
2215         {
2216           loc.is_ipv6 = mp->is_ipv6;
2217           clib_memcpy (loc.ip_address, mp->ip_address,
2218                        sizeof (loc.ip_address));
2219         }
2220       vec_add1 (vam->locator_msg, loc);
2221     }
2222   else
2223     {
2224       if (mp->local)
2225         {
2226           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2227                             ntohl (mp->sw_if_index),
2228                             mp->priority, mp->weight);
2229         }
2230       else
2231         {
2232           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2233                             mp->is_ipv6 ? format_ip6_address :
2234                             format_ip4_address,
2235                             mp->ip_address, mp->priority, mp->weight);
2236         }
2237
2238       fformat (vam->ofp, "%s", tmp_str);
2239
2240       vec_free (tmp_str);
2241     }
2242 }
2243
2244 static void
2245 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2246                                             mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   vat_json_node_t *node = NULL;
2250   locator_msg_t loc;
2251   struct in6_addr ip6;
2252   struct in_addr ip4;
2253
2254   memset (&loc, 0, sizeof (loc));
2255   if (vam->noprint_msg)
2256     {
2257       loc.local = mp->local;
2258       loc.priority = mp->priority;
2259       loc.weight = mp->weight;
2260       if (loc.local)
2261         {
2262           loc.sw_if_index = ntohl (mp->sw_if_index);
2263         }
2264       else
2265         {
2266           loc.is_ipv6 = mp->is_ipv6;
2267           clib_memcpy (loc.ip_address, mp->ip_address,
2268                        sizeof (loc.ip_address));
2269         }
2270       vec_add1 (vam->locator_msg, loc);
2271       return;
2272     }
2273
2274   if (VAT_JSON_ARRAY != vam->json_tree.type)
2275     {
2276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2277       vat_json_init_array (&vam->json_tree);
2278     }
2279   node = vat_json_array_add (&vam->json_tree);
2280
2281   vat_json_init_object (node);
2282
2283   if (mp->local)
2284     {
2285       vat_json_object_add_uint (node, "locator_index",
2286                                 ntohl (mp->sw_if_index));
2287     }
2288   else
2289     {
2290       if (mp->is_ipv6)
2291         {
2292           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2293           vat_json_object_add_ip6 (node, "locator", ip6);
2294         }
2295       else
2296         {
2297           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2298           vat_json_object_add_ip4 (node, "locator", ip4);
2299         }
2300     }
2301   vat_json_object_add_uint (node, "priority", mp->priority);
2302   vat_json_object_add_uint (node, "weight", mp->weight);
2303 }
2304
2305 static void
2306 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2307                                            mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   locator_set_msg_t ls;
2311
2312   ls.locator_set_index = ntohl (mp->locator_set_index);
2313   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2314   vec_add1 (vam->locator_set_msg, ls);
2315 }
2316
2317 static void
2318   vl_api_lisp_locator_set_details_t_handler_json
2319   (vl_api_lisp_locator_set_details_t * mp)
2320 {
2321   vat_main_t *vam = &vat_main;
2322   locator_set_msg_t ls;
2323
2324   ls.locator_set_index = ntohl (mp->locator_set_index);
2325   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2326   vec_add1 (vam->locator_set_msg, ls);
2327 }
2328
2329 static void
2330 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2331 {
2332   vat_main_t *vam = &vat_main;
2333   eid_table_t eid_table;
2334
2335   memset (&eid_table, 0, sizeof (eid_table));
2336   eid_table.is_local = mp->is_local;
2337   eid_table.locator_set_index = mp->locator_set_index;
2338   eid_table.eid_type = mp->eid_type;
2339   eid_table.vni = mp->vni;
2340   eid_table.eid_prefix_len = mp->eid_prefix_len;
2341   eid_table.ttl = mp->ttl;
2342   eid_table.authoritative = mp->authoritative;
2343   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2344   vec_add1 (vam->eid_tables, eid_table);
2345 }
2346
2347 static void
2348 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2349                                               * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   eid_table_t eid_table;
2353
2354   memset (&eid_table, 0, sizeof (eid_table));
2355   eid_table.is_local = mp->is_local;
2356   eid_table.locator_set_index = mp->locator_set_index;
2357   eid_table.eid_type = mp->eid_type;
2358   eid_table.vni = mp->vni;
2359   eid_table.eid_prefix_len = mp->eid_prefix_len;
2360   eid_table.ttl = mp->ttl;
2361   eid_table.authoritative = mp->authoritative;
2362   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2363   vec_add1 (vam->eid_tables, eid_table);
2364 }
2365
2366 static void
2367   vl_api_lisp_eid_table_map_details_t_handler
2368   (vl_api_lisp_eid_table_map_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371
2372   u8 *line = format (0, "%=10d%=10d",
2373                      clib_net_to_host_u32 (mp->vni),
2374                      clib_net_to_host_u32 (mp->vrf));
2375   fformat (vam->ofp, "%v\n", line);
2376   vec_free (line);
2377 }
2378
2379 static void
2380   vl_api_lisp_eid_table_map_details_t_handler_json
2381   (vl_api_lisp_eid_table_map_details_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t *node = NULL;
2385
2386   if (VAT_JSON_ARRAY != vam->json_tree.type)
2387     {
2388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2389       vat_json_init_array (&vam->json_tree);
2390     }
2391   node = vat_json_array_add (&vam->json_tree);
2392   vat_json_init_object (node);
2393   vat_json_object_add_uint (node, "vrf", clib_net_to_host_u32 (mp->vrf));
2394   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2395 }
2396
2397
2398
2399 static u8 *
2400 format_decap_next (u8 * s, va_list * args)
2401 {
2402   u32 next_index = va_arg (*args, u32);
2403
2404   switch (next_index)
2405     {
2406     case LISP_GPE_INPUT_NEXT_DROP:
2407       return format (s, "drop");
2408     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2409       return format (s, "ip4");
2410     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2411       return format (s, "ip6");
2412     default:
2413       return format (s, "unknown %d", next_index);
2414     }
2415   return s;
2416 }
2417
2418 static void
2419 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2420                                           mp)
2421 {
2422   vat_main_t *vam = &vat_main;
2423   u8 *iid_str;
2424   u8 *flag_str = NULL;
2425
2426   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2427
2428 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2429   foreach_lisp_gpe_flag_bit;
2430 #undef _
2431
2432   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2433            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2434            mp->tunnels,
2435            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2436            mp->source_ip,
2437            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2438            mp->destination_ip,
2439            ntohl (mp->encap_fib_id),
2440            ntohl (mp->decap_fib_id),
2441            format_decap_next, ntohl (mp->dcap_next),
2442            mp->ver_res >> 6,
2443            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2444
2445   vec_free (iid_str);
2446 }
2447
2448 static void
2449   vl_api_lisp_gpe_tunnel_details_t_handler_json
2450   (vl_api_lisp_gpe_tunnel_details_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   vat_json_node_t *node = NULL;
2454   struct in6_addr ip6;
2455   struct in_addr ip4;
2456   u8 *next_decap_str;
2457
2458   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2459
2460   if (VAT_JSON_ARRAY != vam->json_tree.type)
2461     {
2462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2463       vat_json_init_array (&vam->json_tree);
2464     }
2465   node = vat_json_array_add (&vam->json_tree);
2466
2467   vat_json_init_object (node);
2468   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2469   if (mp->is_ipv6)
2470     {
2471       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2472       vat_json_object_add_ip6 (node, "source address", ip6);
2473       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2474       vat_json_object_add_ip6 (node, "destination address", ip6);
2475     }
2476   else
2477     {
2478       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2479       vat_json_object_add_ip4 (node, "source address", ip4);
2480       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2481       vat_json_object_add_ip4 (node, "destination address", ip4);
2482     }
2483   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2484   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2485   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2486   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2487   vat_json_object_add_uint (node, "flags", mp->flags);
2488   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2489   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2490   vat_json_object_add_uint (node, "res", mp->res);
2491   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2492
2493   vec_free (next_decap_str);
2494 }
2495
2496 static void
2497 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2498                                             * mp)
2499 {
2500   vat_main_t *vam = &vat_main;
2501
2502   fformat (vam->ofp, "%=20U\n",
2503            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2504            mp->ip_address);
2505 }
2506
2507 static void
2508   vl_api_lisp_map_resolver_details_t_handler_json
2509   (vl_api_lisp_map_resolver_details_t * mp)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   vat_json_node_t *node = NULL;
2513   struct in6_addr ip6;
2514   struct in_addr ip4;
2515
2516   if (VAT_JSON_ARRAY != vam->json_tree.type)
2517     {
2518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2519       vat_json_init_array (&vam->json_tree);
2520     }
2521   node = vat_json_array_add (&vam->json_tree);
2522
2523   vat_json_init_object (node);
2524   if (mp->is_ipv6)
2525     {
2526       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2527       vat_json_object_add_ip6 (node, "map resolver", ip6);
2528     }
2529   else
2530     {
2531       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2532       vat_json_object_add_ip4 (node, "map resolver", ip4);
2533     }
2534 }
2535
2536 static void
2537   vl_api_show_lisp_status_reply_t_handler
2538   (vl_api_show_lisp_status_reply_t * mp)
2539 {
2540   vat_main_t *vam = &vat_main;
2541   i32 retval = ntohl (mp->retval);
2542
2543   if (0 <= retval)
2544     {
2545       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2546                mp->feature_status ? "enabled" : "disabled",
2547                mp->gpe_status ? "enabled" : "disabled");
2548     }
2549
2550   vam->retval = retval;
2551   vam->result_ready = 1;
2552 }
2553
2554 static void
2555   vl_api_show_lisp_status_reply_t_handler_json
2556   (vl_api_show_lisp_status_reply_t * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559   vat_json_node_t node;
2560   u8 *gpe_status = NULL;
2561   u8 *feature_status = NULL;
2562
2563   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2564   feature_status = format (0, "%s",
2565                            mp->feature_status ? "enabled" : "disabled");
2566   vec_add1 (gpe_status, 0);
2567   vec_add1 (feature_status, 0);
2568
2569   vat_json_init_object (&node);
2570   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2571   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2572
2573   vec_free (gpe_status);
2574   vec_free (feature_status);
2575
2576   vat_json_print (vam->ofp, &node);
2577   vat_json_free (&node);
2578
2579   vam->retval = ntohl (mp->retval);
2580   vam->result_ready = 1;
2581 }
2582
2583 static void
2584   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2585   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   i32 retval = ntohl (mp->retval);
2589
2590   if (retval >= 0)
2591     {
2592       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2593     }
2594
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597 }
2598
2599 static void
2600   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2601   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2602 {
2603   vat_main_t *vam = &vat_main;
2604   vat_json_node_t *node = NULL;
2605
2606   if (VAT_JSON_ARRAY != vam->json_tree.type)
2607     {
2608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2609       vat_json_init_array (&vam->json_tree);
2610     }
2611   node = vat_json_array_add (&vam->json_tree);
2612
2613   vat_json_init_object (node);
2614   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2615
2616   vat_json_print (vam->ofp, node);
2617   vat_json_free (node);
2618
2619   vam->retval = ntohl (mp->retval);
2620   vam->result_ready = 1;
2621 }
2622
2623 static void
2624 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2625 {
2626   vat_main_t *vam = &vat_main;
2627   i32 retval = ntohl (mp->retval);
2628
2629   if (0 <= retval)
2630     {
2631       fformat (vam->ofp, "%-20s%-16s\n",
2632                mp->status ? "enabled" : "disabled",
2633                mp->status ? (char *) mp->locator_set_name : "");
2634     }
2635
2636   vam->retval = retval;
2637   vam->result_ready = 1;
2638 }
2639
2640 static void
2641 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2642                                             mp)
2643 {
2644   vat_main_t *vam = &vat_main;
2645   vat_json_node_t node;
2646   u8 *status = 0;
2647
2648   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2649   vec_add1 (status, 0);
2650
2651   vat_json_init_object (&node);
2652   vat_json_object_add_string_copy (&node, "status", status);
2653   if (mp->status)
2654     {
2655       vat_json_object_add_string_copy (&node, "locator_set",
2656                                        mp->locator_set_name);
2657     }
2658
2659   vec_free (status);
2660
2661   vat_json_print (vam->ofp, &node);
2662   vat_json_free (&node);
2663
2664   vam->retval = ntohl (mp->retval);
2665   vam->result_ready = 1;
2666 }
2667
2668 static u8 *
2669 format_policer_type (u8 * s, va_list * va)
2670 {
2671   u32 i = va_arg (*va, u32);
2672
2673   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2674     s = format (s, "1r2c");
2675   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2676     s = format (s, "1r3c");
2677   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2678     s = format (s, "2r3c-2698");
2679   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2680     s = format (s, "2r3c-4115");
2681   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2682     s = format (s, "2r3c-mef5cf1");
2683   else
2684     s = format (s, "ILLEGAL");
2685   return s;
2686 }
2687
2688 static u8 *
2689 format_policer_rate_type (u8 * s, va_list * va)
2690 {
2691   u32 i = va_arg (*va, u32);
2692
2693   if (i == SSE2_QOS_RATE_KBPS)
2694     s = format (s, "kbps");
2695   else if (i == SSE2_QOS_RATE_PPS)
2696     s = format (s, "pps");
2697   else
2698     s = format (s, "ILLEGAL");
2699   return s;
2700 }
2701
2702 static u8 *
2703 format_policer_round_type (u8 * s, va_list * va)
2704 {
2705   u32 i = va_arg (*va, u32);
2706
2707   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2708     s = format (s, "closest");
2709   else if (i == SSE2_QOS_ROUND_TO_UP)
2710     s = format (s, "up");
2711   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2712     s = format (s, "down");
2713   else
2714     s = format (s, "ILLEGAL");
2715   return s;
2716 }
2717
2718 static u8 *
2719 format_policer_action_type (u8 * s, va_list * va)
2720 {
2721   u32 i = va_arg (*va, u32);
2722
2723   if (i == SSE2_QOS_ACTION_DROP)
2724     s = format (s, "drop");
2725   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2726     s = format (s, "transmit");
2727   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2728     s = format (s, "mark-and-transmit");
2729   else
2730     s = format (s, "ILLEGAL");
2731   return s;
2732 }
2733
2734 static u8 *
2735 format_dscp (u8 * s, va_list * va)
2736 {
2737   u32 i = va_arg (*va, u32);
2738   char *t = 0;
2739
2740   switch (i)
2741     {
2742 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2743       foreach_vnet_dscp
2744 #undef _
2745     default:
2746       return format (s, "ILLEGAL");
2747     }
2748   s = format (s, "%s", t);
2749   return s;
2750 }
2751
2752 static void
2753 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2754 {
2755   vat_main_t *vam = &vat_main;
2756   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2757
2758   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2759     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2760   else
2761     conform_dscp_str = format (0, "");
2762
2763   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2764     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2765   else
2766     exceed_dscp_str = format (0, "");
2767
2768   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2769     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2770   else
2771     violate_dscp_str = format (0, "");
2772
2773   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2774            "rate type %U, round type %U, %s rate, %s color-aware, "
2775            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2776            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2777            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2778            mp->name,
2779            format_policer_type, mp->type,
2780            ntohl (mp->cir),
2781            ntohl (mp->eir),
2782            clib_net_to_host_u64 (mp->cb),
2783            clib_net_to_host_u64 (mp->eb),
2784            format_policer_rate_type, mp->rate_type,
2785            format_policer_round_type, mp->round_type,
2786            mp->single_rate ? "single" : "dual",
2787            mp->color_aware ? "is" : "not",
2788            ntohl (mp->cir_tokens_per_period),
2789            ntohl (mp->pir_tokens_per_period),
2790            ntohl (mp->scale),
2791            ntohl (mp->current_limit),
2792            ntohl (mp->current_bucket),
2793            ntohl (mp->extended_limit),
2794            ntohl (mp->extended_bucket),
2795            clib_net_to_host_u64 (mp->last_update_time),
2796            format_policer_action_type, mp->conform_action_type,
2797            conform_dscp_str,
2798            format_policer_action_type, mp->exceed_action_type,
2799            exceed_dscp_str,
2800            format_policer_action_type, mp->violate_action_type,
2801            violate_dscp_str);
2802
2803   vec_free (conform_dscp_str);
2804   vec_free (exceed_dscp_str);
2805   vec_free (violate_dscp_str);
2806 }
2807
2808 static void vl_api_policer_details_t_handler_json
2809   (vl_api_policer_details_t * mp)
2810 {
2811   vat_main_t *vam = &vat_main;
2812   vat_json_node_t *node;
2813   u8 *rate_type_str, *round_type_str, *type_str;
2814   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2815
2816   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2817   round_type_str =
2818     format (0, "%U", format_policer_round_type, mp->round_type);
2819   type_str = format (0, "%U", format_policer_type, mp->type);
2820   conform_action_str = format (0, "%U", format_policer_action_type,
2821                                mp->conform_action_type);
2822   exceed_action_str = format (0, "%U", format_policer_action_type,
2823                               mp->exceed_action_type);
2824   violate_action_str = format (0, "%U", format_policer_action_type,
2825                                mp->violate_action_type);
2826
2827   if (VAT_JSON_ARRAY != vam->json_tree.type)
2828     {
2829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2830       vat_json_init_array (&vam->json_tree);
2831     }
2832   node = vat_json_array_add (&vam->json_tree);
2833
2834   vat_json_init_object (node);
2835   vat_json_object_add_string_copy (node, "name", mp->name);
2836   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2837   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2838   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2839   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2840   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2841   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2842   vat_json_object_add_string_copy (node, "type", type_str);
2843   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2844   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2845   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2846   vat_json_object_add_uint (node, "cir_tokens_per_period",
2847                             ntohl (mp->cir_tokens_per_period));
2848   vat_json_object_add_uint (node, "eir_tokens_per_period",
2849                             ntohl (mp->pir_tokens_per_period));
2850   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2851   vat_json_object_add_uint (node, "current_bucket",
2852                             ntohl (mp->current_bucket));
2853   vat_json_object_add_uint (node, "extended_limit",
2854                             ntohl (mp->extended_limit));
2855   vat_json_object_add_uint (node, "extended_bucket",
2856                             ntohl (mp->extended_bucket));
2857   vat_json_object_add_uint (node, "last_update_time",
2858                             ntohl (mp->last_update_time));
2859   vat_json_object_add_string_copy (node, "conform_action",
2860                                    conform_action_str);
2861   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2862     {
2863       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2864       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2865       vec_free (dscp_str);
2866     }
2867   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2868   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2869     {
2870       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2871       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2872       vec_free (dscp_str);
2873     }
2874   vat_json_object_add_string_copy (node, "violate_action",
2875                                    violate_action_str);
2876   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2877     {
2878       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2879       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2880       vec_free (dscp_str);
2881     }
2882
2883   vec_free (rate_type_str);
2884   vec_free (round_type_str);
2885   vec_free (type_str);
2886   vec_free (conform_action_str);
2887   vec_free (exceed_action_str);
2888   vec_free (violate_action_str);
2889 }
2890
2891 static void
2892 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2893                                            mp)
2894 {
2895   vat_main_t *vam = &vat_main;
2896   int i, count = ntohl (mp->count);
2897
2898   if (count > 0)
2899     fformat (vam->ofp, "classify table ids (%d) : ", count);
2900   for (i = 0; i < count; i++)
2901     {
2902       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2903       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2904     }
2905   vam->retval = ntohl (mp->retval);
2906   vam->result_ready = 1;
2907 }
2908
2909 static void
2910   vl_api_classify_table_ids_reply_t_handler_json
2911   (vl_api_classify_table_ids_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int i, count = ntohl (mp->count);
2915
2916   if (count > 0)
2917     {
2918       vat_json_node_t node;
2919
2920       vat_json_init_object (&node);
2921       for (i = 0; i < count; i++)
2922         {
2923           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2924         }
2925       vat_json_print (vam->ofp, &node);
2926       vat_json_free (&node);
2927     }
2928   vam->retval = ntohl (mp->retval);
2929   vam->result_ready = 1;
2930 }
2931
2932 static void
2933   vl_api_classify_table_by_interface_reply_t_handler
2934   (vl_api_classify_table_by_interface_reply_t * mp)
2935 {
2936   vat_main_t *vam = &vat_main;
2937   u32 table_id;
2938
2939   table_id = ntohl (mp->l2_table_id);
2940   if (table_id != ~0)
2941     fformat (vam->ofp, "l2 table id : %d\n", table_id);
2942   else
2943     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
2944   table_id = ntohl (mp->ip4_table_id);
2945   if (table_id != ~0)
2946     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
2947   else
2948     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
2949   table_id = ntohl (mp->ip6_table_id);
2950   if (table_id != ~0)
2951     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
2952   else
2953     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
2954   vam->retval = ntohl (mp->retval);
2955   vam->result_ready = 1;
2956 }
2957
2958 static void
2959   vl_api_classify_table_by_interface_reply_t_handler_json
2960   (vl_api_classify_table_by_interface_reply_t * mp)
2961 {
2962   vat_main_t *vam = &vat_main;
2963   vat_json_node_t node;
2964
2965   vat_json_init_object (&node);
2966
2967   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2968   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2969   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2970
2971   vat_json_print (vam->ofp, &node);
2972   vat_json_free (&node);
2973
2974   vam->retval = ntohl (mp->retval);
2975   vam->result_ready = 1;
2976 }
2977
2978 static void vl_api_policer_add_del_reply_t_handler
2979   (vl_api_policer_add_del_reply_t * mp)
2980 {
2981   vat_main_t *vam = &vat_main;
2982   i32 retval = ntohl (mp->retval);
2983   if (vam->async_mode)
2984     {
2985       vam->async_errors += (retval < 0);
2986     }
2987   else
2988     {
2989       vam->retval = retval;
2990       vam->result_ready = 1;
2991       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2992         /*
2993          * Note: this is just barely thread-safe, depends on
2994          * the main thread spinning waiting for an answer...
2995          */
2996         errmsg ("policer index %d\n", ntohl (mp->policer_index));
2997     }
2998 }
2999
3000 static void vl_api_policer_add_del_reply_t_handler_json
3001   (vl_api_policer_add_del_reply_t * mp)
3002 {
3003   vat_main_t *vam = &vat_main;
3004   vat_json_node_t node;
3005
3006   vat_json_init_object (&node);
3007   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3008   vat_json_object_add_uint (&node, "policer_index",
3009                             ntohl (mp->policer_index));
3010
3011   vat_json_print (vam->ofp, &node);
3012   vat_json_free (&node);
3013
3014   vam->retval = ntohl (mp->retval);
3015   vam->result_ready = 1;
3016 }
3017
3018 /* Format hex dump. */
3019 u8 *
3020 format_hex_bytes (u8 * s, va_list * va)
3021 {
3022   u8 *bytes = va_arg (*va, u8 *);
3023   int n_bytes = va_arg (*va, int);
3024   uword i;
3025
3026   /* Print short or long form depending on byte count. */
3027   uword short_form = n_bytes <= 32;
3028   uword indent = format_get_indent (s);
3029
3030   if (n_bytes == 0)
3031     return s;
3032
3033   for (i = 0; i < n_bytes; i++)
3034     {
3035       if (!short_form && (i % 32) == 0)
3036         s = format (s, "%08x: ", i);
3037       s = format (s, "%02x", bytes[i]);
3038       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3039         s = format (s, "\n%U", format_white_space, indent);
3040     }
3041
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3047                                             * mp)
3048 {
3049   vat_main_t *vam = &vat_main;
3050   i32 retval = ntohl (mp->retval);
3051   if (retval == 0)
3052     {
3053       fformat (vam->ofp, "classify table info :\n");
3054       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3055                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3056                ntohl (mp->miss_next_index));
3057       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3058                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3059                ntohl (mp->match_n_vectors));
3060       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3061                ntohl (mp->mask_length));
3062     }
3063   vam->retval = retval;
3064   vam->result_ready = 1;
3065 }
3066
3067 static void
3068   vl_api_classify_table_info_reply_t_handler_json
3069   (vl_api_classify_table_info_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   vat_json_node_t node;
3073
3074   i32 retval = ntohl (mp->retval);
3075   if (retval == 0)
3076     {
3077       vat_json_init_object (&node);
3078
3079       vat_json_object_add_int (&node, "sessions",
3080                                ntohl (mp->active_sessions));
3081       vat_json_object_add_int (&node, "nexttbl",
3082                                ntohl (mp->next_table_index));
3083       vat_json_object_add_int (&node, "nextnode",
3084                                ntohl (mp->miss_next_index));
3085       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3086       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3087       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3088       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3089                       ntohl (mp->mask_length), 0);
3090       vat_json_object_add_string_copy (&node, "mask", s);
3091
3092       vat_json_print (vam->ofp, &node);
3093       vat_json_free (&node);
3094     }
3095   vam->retval = ntohl (mp->retval);
3096   vam->result_ready = 1;
3097 }
3098
3099 static void
3100 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3101                                            mp)
3102 {
3103   vat_main_t *vam = &vat_main;
3104
3105   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3106            ntohl (mp->hit_next_index), ntohl (mp->advance),
3107            ntohl (mp->opaque_index));
3108   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3109            ntohl (mp->match_length));
3110 }
3111
3112 static void
3113   vl_api_classify_session_details_t_handler_json
3114   (vl_api_classify_session_details_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t *node = NULL;
3118
3119   if (VAT_JSON_ARRAY != vam->json_tree.type)
3120     {
3121       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3122       vat_json_init_array (&vam->json_tree);
3123     }
3124   node = vat_json_array_add (&vam->json_tree);
3125
3126   vat_json_init_object (node);
3127   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3128   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3129   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3130   u8 *s =
3131     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3132             0);
3133   vat_json_object_add_string_copy (node, "match", s);
3134 }
3135
3136 static void vl_api_pg_create_interface_reply_t_handler
3137   (vl_api_pg_create_interface_reply_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140
3141   vam->retval = ntohl (mp->retval);
3142   vam->result_ready = 1;
3143 }
3144
3145 static void vl_api_pg_create_interface_reply_t_handler_json
3146   (vl_api_pg_create_interface_reply_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t node;
3150
3151   i32 retval = ntohl (mp->retval);
3152   if (retval == 0)
3153     {
3154       vat_json_init_object (&node);
3155
3156       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3157
3158       vat_json_print (vam->ofp, &node);
3159       vat_json_free (&node);
3160     }
3161   vam->retval = ntohl (mp->retval);
3162   vam->result_ready = 1;
3163 }
3164
3165 static void vl_api_policer_classify_details_t_handler
3166   (vl_api_policer_classify_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3171            ntohl (mp->table_index));
3172 }
3173
3174 static void vl_api_policer_classify_details_t_handler_json
3175   (vl_api_policer_classify_details_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t *node;
3179
3180   if (VAT_JSON_ARRAY != vam->json_tree.type)
3181     {
3182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3183       vat_json_init_array (&vam->json_tree);
3184     }
3185   node = vat_json_array_add (&vam->json_tree);
3186
3187   vat_json_init_object (node);
3188   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3189   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3190 }
3191
3192 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3193   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   i32 retval = ntohl (mp->retval);
3197   if (vam->async_mode)
3198     {
3199       vam->async_errors += (retval < 0);
3200     }
3201   else
3202     {
3203       vam->retval = retval;
3204       vam->sw_if_index = ntohl (mp->sw_if_index);
3205       vam->result_ready = 1;
3206     }
3207 }
3208
3209 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3210   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t node;
3214
3215   vat_json_init_object (&node);
3216   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3217   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3218
3219   vat_json_print (vam->ofp, &node);
3220   vat_json_free (&node);
3221
3222   vam->retval = ntohl (mp->retval);
3223   vam->result_ready = 1;
3224 }
3225
3226 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3227 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3228 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3229 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3230
3231 /*
3232  * Generate boilerplate reply handlers, which
3233  * dig the return value out of the xxx_reply_t API message,
3234  * stick it into vam->retval, and set vam->result_ready
3235  *
3236  * Could also do this by pointing N message decode slots at
3237  * a single function, but that could break in subtle ways.
3238  */
3239
3240 #define foreach_standard_reply_retval_handler           \
3241 _(sw_interface_set_flags_reply)                         \
3242 _(sw_interface_add_del_address_reply)                   \
3243 _(sw_interface_set_table_reply)                         \
3244 _(sw_interface_set_vpath_reply)                         \
3245 _(sw_interface_set_l2_bridge_reply)                     \
3246 _(bridge_domain_add_del_reply)                          \
3247 _(sw_interface_set_l2_xconnect_reply)                   \
3248 _(l2fib_add_del_reply)                                  \
3249 _(ip_add_del_route_reply)                               \
3250 _(proxy_arp_add_del_reply)                              \
3251 _(proxy_arp_intfc_enable_disable_reply)                 \
3252 _(mpls_add_del_encap_reply)                             \
3253 _(mpls_add_del_decap_reply)                             \
3254 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3255 _(sw_interface_set_unnumbered_reply)                    \
3256 _(ip_neighbor_add_del_reply)                            \
3257 _(reset_vrf_reply)                                      \
3258 _(oam_add_del_reply)                                    \
3259 _(reset_fib_reply)                                      \
3260 _(dhcp_proxy_config_reply)                              \
3261 _(dhcp_proxy_config_2_reply)                            \
3262 _(dhcp_proxy_set_vss_reply)                             \
3263 _(dhcp_client_config_reply)                             \
3264 _(set_ip_flow_hash_reply)                               \
3265 _(sw_interface_ip6_enable_disable_reply)                \
3266 _(sw_interface_ip6_set_link_local_address_reply)        \
3267 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3268 _(sw_interface_ip6nd_ra_config_reply)                   \
3269 _(set_arp_neighbor_limit_reply)                         \
3270 _(l2_patch_add_del_reply)                               \
3271 _(sr_tunnel_add_del_reply)                              \
3272 _(sr_policy_add_del_reply)                              \
3273 _(sr_multicast_map_add_del_reply)                       \
3274 _(classify_add_del_session_reply)                       \
3275 _(classify_set_interface_ip_table_reply)                \
3276 _(classify_set_interface_l2_tables_reply)               \
3277 _(l2tpv3_set_tunnel_cookies_reply)                      \
3278 _(l2tpv3_interface_enable_disable_reply)                \
3279 _(l2tpv3_set_lookup_key_reply)                          \
3280 _(l2_fib_clear_table_reply)                             \
3281 _(l2_interface_efp_filter_reply)                        \
3282 _(l2_interface_vlan_tag_rewrite_reply)                  \
3283 _(modify_vhost_user_if_reply)                           \
3284 _(delete_vhost_user_if_reply)                           \
3285 _(want_ip4_arp_events_reply)                            \
3286 _(input_acl_set_interface_reply)                        \
3287 _(ipsec_spd_add_del_reply)                              \
3288 _(ipsec_interface_add_del_spd_reply)                    \
3289 _(ipsec_spd_add_del_entry_reply)                        \
3290 _(ipsec_sad_add_del_entry_reply)                        \
3291 _(ipsec_sa_set_key_reply)                               \
3292 _(ikev2_profile_add_del_reply)                          \
3293 _(ikev2_profile_set_auth_reply)                         \
3294 _(ikev2_profile_set_id_reply)                           \
3295 _(ikev2_profile_set_ts_reply)                           \
3296 _(ikev2_set_local_key_reply)                            \
3297 _(delete_loopback_reply)                                \
3298 _(bd_ip_mac_add_del_reply)                              \
3299 _(map_del_domain_reply)                                 \
3300 _(map_add_del_rule_reply)                               \
3301 _(want_interface_events_reply)                          \
3302 _(want_stats_reply)                                     \
3303 _(cop_interface_enable_disable_reply)                   \
3304 _(cop_whitelist_enable_disable_reply)                   \
3305 _(sw_interface_clear_stats_reply)                       \
3306 _(trace_profile_add_reply)                              \
3307 _(trace_profile_apply_reply)                            \
3308 _(trace_profile_del_reply)                              \
3309 _(lisp_add_del_locator_set_reply)                       \
3310 _(lisp_add_del_locator_reply)                           \
3311 _(lisp_add_del_local_eid_reply)                         \
3312 _(lisp_add_del_remote_mapping_reply)                    \
3313 _(lisp_add_del_adjacency_reply)                         \
3314 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3315 _(lisp_add_del_map_resolver_reply)                      \
3316 _(lisp_gpe_enable_disable_reply)                        \
3317 _(lisp_gpe_add_del_iface_reply)                         \
3318 _(lisp_enable_disable_reply)                            \
3319 _(lisp_pitr_set_locator_set_reply)                      \
3320 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3321 _(lisp_eid_table_add_del_map_reply)                     \
3322 _(vxlan_gpe_add_del_tunnel_reply)                       \
3323 _(af_packet_delete_reply)                               \
3324 _(policer_classify_set_interface_reply)                 \
3325 _(netmap_create_reply)                                  \
3326 _(netmap_delete_reply)                                  \
3327 _(ipfix_enable_reply)                                   \
3328 _(pg_capture_reply)                                     \
3329 _(pg_enable_disable_reply)                              \
3330 _(ip_source_and_port_range_check_add_del_reply)         \
3331 _(ip_source_and_port_range_check_interface_add_del_reply)
3332
3333 #define _(n)                                    \
3334     static void vl_api_##n##_t_handler          \
3335     (vl_api_##n##_t * mp)                       \
3336     {                                           \
3337         vat_main_t * vam = &vat_main;           \
3338         i32 retval = ntohl(mp->retval);         \
3339         if (vam->async_mode) {                  \
3340             vam->async_errors += (retval < 0);  \
3341         } else {                                \
3342             vam->retval = retval;               \
3343             vam->result_ready = 1;              \
3344         }                                       \
3345     }
3346 foreach_standard_reply_retval_handler;
3347 #undef _
3348
3349 #define _(n)                                    \
3350     static void vl_api_##n##_t_handler_json     \
3351     (vl_api_##n##_t * mp)                       \
3352     {                                           \
3353         vat_main_t * vam = &vat_main;           \
3354         vat_json_node_t node;                   \
3355         vat_json_init_object(&node);            \
3356         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3357         vat_json_print(vam->ofp, &node);        \
3358         vam->retval = ntohl(mp->retval);        \
3359         vam->result_ready = 1;                  \
3360     }
3361 foreach_standard_reply_retval_handler;
3362 #undef _
3363
3364 /*
3365  * Table of message reply handlers, must include boilerplate handlers
3366  * we just generated
3367  */
3368
3369 #define foreach_vpe_api_reply_msg                                       \
3370 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3371 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3372 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3373 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3374 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3375 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3376 _(CLI_REPLY, cli_reply)                                                 \
3377 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3378   sw_interface_add_del_address_reply)                                   \
3379 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3380 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3381 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3382   sw_interface_set_l2_xconnect_reply)                                   \
3383 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3384   sw_interface_set_l2_bridge_reply)                                     \
3385 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3386 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3387 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3388 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3389 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3390 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3391 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3392 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3393 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3394 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3395 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3396 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3397 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3398   proxy_arp_intfc_enable_disable_reply)                                 \
3399 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3400 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3401 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3402 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3403   mpls_ethernet_add_del_tunnel_reply)                                   \
3404 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3405   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3406 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3407   sw_interface_set_unnumbered_reply)                                    \
3408 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3409 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3410 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3411 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3412 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3413 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3414 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3415 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3416 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3417 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3418 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3419 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3420   sw_interface_ip6_enable_disable_reply)                                \
3421 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3422   sw_interface_ip6_set_link_local_address_reply)                        \
3423 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3424   sw_interface_ip6nd_ra_prefix_reply)                                   \
3425 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3426   sw_interface_ip6nd_ra_config_reply)                                   \
3427 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3428 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3429 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3430 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3431 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3432 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3433 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3434 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3435 classify_set_interface_ip_table_reply)                                  \
3436 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3437   classify_set_interface_l2_tables_reply)                               \
3438 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3439 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3440 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3441 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3442 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3443   l2tpv3_interface_enable_disable_reply)                                \
3444 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3445 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3446 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3447 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3448 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3449 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3450 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3451 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3452 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3453 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3454 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3455 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3456 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3457 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3458 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3459 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3460 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3461 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3462 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3463 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3464 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3465 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3466 _(IP_DETAILS, ip_details)                                               \
3467 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3468 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3469 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3470 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3471 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3472 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3473 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3474 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3475 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3476 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3477 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3478 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3479 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3480 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3481 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3482 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3483 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3484 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3485 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3486 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3487 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3488 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3489 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3490 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3491 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3492 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3493 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3494 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3495 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3496 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3497 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3498 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3499 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3500 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3501 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3502 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3503 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3504 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3505 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3506 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3507 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3508 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3509 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3510 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3511 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3512 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3513 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3514 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3515 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3516 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3517 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3518   lisp_add_del_map_request_itr_rlocs_reply)                             \
3519 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3520   lisp_get_map_request_itr_rlocs_reply)                                 \
3521 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3522 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3523 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3524 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3525 _(POLICER_DETAILS, policer_details)                                     \
3526 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3527 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3528 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3529 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3530 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3531 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3532 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3533 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3534 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3535 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3536 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3537 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3538 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3539 _(IPFIX_DETAILS, ipfix_details)                                         \
3540 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3541 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3542 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3543 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3544 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3545  ip_source_and_port_range_check_add_del_reply)                          \
3546 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3547  ip_source_and_port_range_check_interface_add_del_reply)                \
3548 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3549 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)
3550
3551 /* M: construct, but don't yet send a message */
3552
3553 #define M(T,t)                                  \
3554 do {                                            \
3555     vam->result_ready = 0;                      \
3556     mp = vl_msg_api_alloc(sizeof(*mp));         \
3557     memset (mp, 0, sizeof (*mp));               \
3558     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3559     mp->client_index = vam->my_client_index;    \
3560 } while(0);
3561
3562 #define M2(T,t,n)                               \
3563 do {                                            \
3564     vam->result_ready = 0;                      \
3565     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3566     memset (mp, 0, sizeof (*mp));               \
3567     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3568     mp->client_index = vam->my_client_index;    \
3569 } while(0);
3570
3571
3572 /* S: send a message */
3573 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3574
3575 /* W: wait for results, with timeout */
3576 #define W                                       \
3577 do {                                            \
3578     timeout = vat_time_now (vam) + 1.0;         \
3579                                                 \
3580     while (vat_time_now (vam) < timeout) {      \
3581         if (vam->result_ready == 1) {           \
3582             return (vam->retval);               \
3583         }                                       \
3584     }                                           \
3585     return -99;                                 \
3586 } while(0);
3587
3588 /* W2: wait for results, with timeout */
3589 #define W2(body)                                \
3590 do {                                            \
3591     timeout = vat_time_now (vam) + 1.0;         \
3592                                                 \
3593     while (vat_time_now (vam) < timeout) {      \
3594         if (vam->result_ready == 1) {           \
3595           (body);                               \
3596           return (vam->retval);                 \
3597         }                                       \
3598     }                                           \
3599     return -99;                                 \
3600 } while(0);
3601
3602 /* W_L: wait for results, with timeout */
3603 #define W_L(body)                               \
3604 do {                                            \
3605     timeout = vat_time_now (vam) + 1.0;         \
3606                                                 \
3607     while (vat_time_now (vam) < timeout) {      \
3608         if (vam->result_ready == 1) {           \
3609           (body);                               \
3610           return (vam->retval);                 \
3611         }                                       \
3612     }                                           \
3613     vam->noprint_msg = 0;     \
3614     return -99;                                 \
3615 } while(0);
3616
3617 typedef struct
3618 {
3619   u8 *name;
3620   u32 value;
3621 } name_sort_t;
3622
3623
3624 #define STR_VTR_OP_CASE(op)     \
3625     case L2_VTR_ ## op:         \
3626         return "" # op;
3627
3628 static const char *
3629 str_vtr_op (u32 vtr_op)
3630 {
3631   switch (vtr_op)
3632     {
3633       STR_VTR_OP_CASE (DISABLED);
3634       STR_VTR_OP_CASE (PUSH_1);
3635       STR_VTR_OP_CASE (PUSH_2);
3636       STR_VTR_OP_CASE (POP_1);
3637       STR_VTR_OP_CASE (POP_2);
3638       STR_VTR_OP_CASE (TRANSLATE_1_1);
3639       STR_VTR_OP_CASE (TRANSLATE_1_2);
3640       STR_VTR_OP_CASE (TRANSLATE_2_1);
3641       STR_VTR_OP_CASE (TRANSLATE_2_2);
3642     }
3643
3644   return "UNKNOWN";
3645 }
3646
3647 static int
3648 dump_sub_interface_table (vat_main_t * vam)
3649 {
3650   const sw_interface_subif_t *sub = NULL;
3651
3652   if (vam->json_output)
3653     {
3654       clib_warning
3655         ("JSON output supported only for VPE API calls and dump_stats_table");
3656       return -99;
3657     }
3658
3659   fformat (vam->ofp,
3660            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3661            "Interface", "sw_if_index",
3662            "sub id", "dot1ad", "tags", "outer id",
3663            "inner id", "exact", "default", "outer any", "inner any");
3664
3665   vec_foreach (sub, vam->sw_if_subif_table)
3666   {
3667     fformat (vam->ofp,
3668              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3669              sub->interface_name,
3670              sub->sw_if_index,
3671              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3672              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3673              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3674              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3675     if (sub->vtr_op != L2_VTR_DISABLED)
3676       {
3677         fformat (vam->ofp,
3678                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3679                  "tag1: %d tag2: %d ]\n",
3680                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3681                  sub->vtr_tag1, sub->vtr_tag2);
3682       }
3683   }
3684
3685   return 0;
3686 }
3687
3688 static int
3689 name_sort_cmp (void *a1, void *a2)
3690 {
3691   name_sort_t *n1 = a1;
3692   name_sort_t *n2 = a2;
3693
3694   return strcmp ((char *) n1->name, (char *) n2->name);
3695 }
3696
3697 static int
3698 dump_interface_table (vat_main_t * vam)
3699 {
3700   hash_pair_t *p;
3701   name_sort_t *nses = 0, *ns;
3702
3703   if (vam->json_output)
3704     {
3705       clib_warning
3706         ("JSON output supported only for VPE API calls and dump_stats_table");
3707       return -99;
3708     }
3709
3710   /* *INDENT-OFF* */
3711   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3712   ({
3713     vec_add2 (nses, ns, 1);
3714     ns->name = (u8 *)(p->key);
3715     ns->value = (u32) p->value[0];
3716   }));
3717   /* *INDENT-ON* */
3718
3719   vec_sort_with_function (nses, name_sort_cmp);
3720
3721   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3722   vec_foreach (ns, nses)
3723   {
3724     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3725   }
3726   vec_free (nses);
3727   return 0;
3728 }
3729
3730 static int
3731 dump_ip_table (vat_main_t * vam, int is_ipv6)
3732 {
3733   const ip_details_t *det = NULL;
3734   const ip_address_details_t *address = NULL;
3735   u32 i = ~0;
3736
3737   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3738
3739   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3740   {
3741     i++;
3742     if (!det->present)
3743       {
3744         continue;
3745       }
3746     fformat (vam->ofp, "%-12d\n", i);
3747     fformat (vam->ofp,
3748              "            %-30s%-13s\n", "Address", "Prefix length");
3749     if (!det->addr)
3750       {
3751         continue;
3752       }
3753     vec_foreach (address, det->addr)
3754     {
3755       fformat (vam->ofp,
3756                "            %-30U%-13d\n",
3757                is_ipv6 ? format_ip6_address : format_ip4_address,
3758                address->ip, address->prefix_length);
3759     }
3760   }
3761
3762   return 0;
3763 }
3764
3765 static int
3766 dump_ipv4_table (vat_main_t * vam)
3767 {
3768   if (vam->json_output)
3769     {
3770       clib_warning
3771         ("JSON output supported only for VPE API calls and dump_stats_table");
3772       return -99;
3773     }
3774
3775   return dump_ip_table (vam, 0);
3776 }
3777
3778 static int
3779 dump_ipv6_table (vat_main_t * vam)
3780 {
3781   if (vam->json_output)
3782     {
3783       clib_warning
3784         ("JSON output supported only for VPE API calls and dump_stats_table");
3785       return -99;
3786     }
3787
3788   return dump_ip_table (vam, 1);
3789 }
3790
3791 static char *
3792 counter_type_to_str (u8 counter_type, u8 is_combined)
3793 {
3794   if (!is_combined)
3795     {
3796       switch (counter_type)
3797         {
3798         case VNET_INTERFACE_COUNTER_DROP:
3799           return "drop";
3800         case VNET_INTERFACE_COUNTER_PUNT:
3801           return "punt";
3802         case VNET_INTERFACE_COUNTER_IP4:
3803           return "ip4";
3804         case VNET_INTERFACE_COUNTER_IP6:
3805           return "ip6";
3806         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3807           return "rx-no-buf";
3808         case VNET_INTERFACE_COUNTER_RX_MISS:
3809           return "rx-miss";
3810         case VNET_INTERFACE_COUNTER_RX_ERROR:
3811           return "rx-error";
3812         case VNET_INTERFACE_COUNTER_TX_ERROR:
3813           return "tx-error";
3814         default:
3815           return "INVALID-COUNTER-TYPE";
3816         }
3817     }
3818   else
3819     {
3820       switch (counter_type)
3821         {
3822         case VNET_INTERFACE_COUNTER_RX:
3823           return "rx";
3824         case VNET_INTERFACE_COUNTER_TX:
3825           return "tx";
3826         default:
3827           return "INVALID-COUNTER-TYPE";
3828         }
3829     }
3830 }
3831
3832 static int
3833 dump_stats_table (vat_main_t * vam)
3834 {
3835   vat_json_node_t node;
3836   vat_json_node_t *msg_array;
3837   vat_json_node_t *msg;
3838   vat_json_node_t *counter_array;
3839   vat_json_node_t *counter;
3840   interface_counter_t c;
3841   u64 packets;
3842   ip4_fib_counter_t *c4;
3843   ip6_fib_counter_t *c6;
3844   int i, j;
3845
3846   if (!vam->json_output)
3847     {
3848       clib_warning ("dump_stats_table supported only in JSON format");
3849       return -99;
3850     }
3851
3852   vat_json_init_object (&node);
3853
3854   /* interface counters */
3855   msg_array = vat_json_object_add (&node, "interface_counters");
3856   vat_json_init_array (msg_array);
3857   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3858     {
3859       msg = vat_json_array_add (msg_array);
3860       vat_json_init_object (msg);
3861       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3862                                        (u8 *) counter_type_to_str (i, 0));
3863       vat_json_object_add_int (msg, "is_combined", 0);
3864       counter_array = vat_json_object_add (msg, "data");
3865       vat_json_init_array (counter_array);
3866       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3867         {
3868           packets = vam->simple_interface_counters[i][j];
3869           vat_json_array_add_uint (counter_array, packets);
3870         }
3871     }
3872   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3873     {
3874       msg = vat_json_array_add (msg_array);
3875       vat_json_init_object (msg);
3876       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3877                                        (u8 *) counter_type_to_str (i, 1));
3878       vat_json_object_add_int (msg, "is_combined", 1);
3879       counter_array = vat_json_object_add (msg, "data");
3880       vat_json_init_array (counter_array);
3881       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3882         {
3883           c = vam->combined_interface_counters[i][j];
3884           counter = vat_json_array_add (counter_array);
3885           vat_json_init_object (counter);
3886           vat_json_object_add_uint (counter, "packets", c.packets);
3887           vat_json_object_add_uint (counter, "bytes", c.bytes);
3888         }
3889     }
3890
3891   /* ip4 fib counters */
3892   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3893   vat_json_init_array (msg_array);
3894   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3895     {
3896       msg = vat_json_array_add (msg_array);
3897       vat_json_init_object (msg);
3898       vat_json_object_add_uint (msg, "vrf_id",
3899                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3900       counter_array = vat_json_object_add (msg, "c");
3901       vat_json_init_array (counter_array);
3902       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3903         {
3904           counter = vat_json_array_add (counter_array);
3905           vat_json_init_object (counter);
3906           c4 = &vam->ip4_fib_counters[i][j];
3907           vat_json_object_add_ip4 (counter, "address", c4->address);
3908           vat_json_object_add_uint (counter, "address_length",
3909                                     c4->address_length);
3910           vat_json_object_add_uint (counter, "packets", c4->packets);
3911           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3912         }
3913     }
3914
3915   /* ip6 fib counters */
3916   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3917   vat_json_init_array (msg_array);
3918   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3919     {
3920       msg = vat_json_array_add (msg_array);
3921       vat_json_init_object (msg);
3922       vat_json_object_add_uint (msg, "vrf_id",
3923                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3924       counter_array = vat_json_object_add (msg, "c");
3925       vat_json_init_array (counter_array);
3926       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3927         {
3928           counter = vat_json_array_add (counter_array);
3929           vat_json_init_object (counter);
3930           c6 = &vam->ip6_fib_counters[i][j];
3931           vat_json_object_add_ip6 (counter, "address", c6->address);
3932           vat_json_object_add_uint (counter, "address_length",
3933                                     c6->address_length);
3934           vat_json_object_add_uint (counter, "packets", c6->packets);
3935           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3936         }
3937     }
3938
3939   vat_json_print (vam->ofp, &node);
3940   vat_json_free (&node);
3941
3942   return 0;
3943 }
3944
3945 int
3946 exec (vat_main_t * vam)
3947 {
3948   api_main_t *am = &api_main;
3949   vl_api_cli_request_t *mp;
3950   f64 timeout;
3951   void *oldheap;
3952   u8 *cmd = 0;
3953   unformat_input_t *i = vam->input;
3954
3955   if (vec_len (i->buffer) == 0)
3956     return -1;
3957
3958   if (vam->exec_mode == 0 && unformat (i, "mode"))
3959     {
3960       vam->exec_mode = 1;
3961       return 0;
3962     }
3963   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3964     {
3965       vam->exec_mode = 0;
3966       return 0;
3967     }
3968
3969
3970   M (CLI_REQUEST, cli_request);
3971
3972   /*
3973    * Copy cmd into shared memory.
3974    * In order for the CLI command to work, it
3975    * must be a vector ending in \n, not a C-string ending
3976    * in \n\0.
3977    */
3978   pthread_mutex_lock (&am->vlib_rp->mutex);
3979   oldheap = svm_push_data_heap (am->vlib_rp);
3980
3981   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
3982   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
3983
3984   svm_pop_heap (oldheap);
3985   pthread_mutex_unlock (&am->vlib_rp->mutex);
3986
3987   mp->cmd_in_shmem = (u64) cmd;
3988   S;
3989   timeout = vat_time_now (vam) + 10.0;
3990
3991   while (vat_time_now (vam) < timeout)
3992     {
3993       if (vam->result_ready == 1)
3994         {
3995           u8 *free_me;
3996           if (vam->shmem_result != NULL)
3997             fformat (vam->ofp, "%s", vam->shmem_result);
3998           pthread_mutex_lock (&am->vlib_rp->mutex);
3999           oldheap = svm_push_data_heap (am->vlib_rp);
4000
4001           free_me = (u8 *) vam->shmem_result;
4002           vec_free (free_me);
4003
4004           svm_pop_heap (oldheap);
4005           pthread_mutex_unlock (&am->vlib_rp->mutex);
4006           return 0;
4007         }
4008     }
4009   return -99;
4010 }
4011
4012 static int
4013 api_create_loopback (vat_main_t * vam)
4014 {
4015   unformat_input_t *i = vam->input;
4016   vl_api_create_loopback_t *mp;
4017   f64 timeout;
4018   u8 mac_address[6];
4019   u8 mac_set = 0;
4020
4021   memset (mac_address, 0, sizeof (mac_address));
4022
4023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4024     {
4025       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4026         mac_set = 1;
4027       else
4028         break;
4029     }
4030
4031   /* Construct the API message */
4032   M (CREATE_LOOPBACK, create_loopback);
4033   if (mac_set)
4034     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4035
4036   S;
4037   W;
4038 }
4039
4040 static int
4041 api_delete_loopback (vat_main_t * vam)
4042 {
4043   unformat_input_t *i = vam->input;
4044   vl_api_delete_loopback_t *mp;
4045   f64 timeout;
4046   u32 sw_if_index = ~0;
4047
4048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4049     {
4050       if (unformat (i, "sw_if_index %d", &sw_if_index))
4051         ;
4052       else
4053         break;
4054     }
4055
4056   if (sw_if_index == ~0)
4057     {
4058       errmsg ("missing sw_if_index\n");
4059       return -99;
4060     }
4061
4062   /* Construct the API message */
4063   M (DELETE_LOOPBACK, delete_loopback);
4064   mp->sw_if_index = ntohl (sw_if_index);
4065
4066   S;
4067   W;
4068 }
4069
4070 static int
4071 api_want_stats (vat_main_t * vam)
4072 {
4073   unformat_input_t *i = vam->input;
4074   vl_api_want_stats_t *mp;
4075   f64 timeout;
4076   int enable = -1;
4077
4078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4079     {
4080       if (unformat (i, "enable"))
4081         enable = 1;
4082       else if (unformat (i, "disable"))
4083         enable = 0;
4084       else
4085         break;
4086     }
4087
4088   if (enable == -1)
4089     {
4090       errmsg ("missing enable|disable\n");
4091       return -99;
4092     }
4093
4094   M (WANT_STATS, want_stats);
4095   mp->enable_disable = enable;
4096
4097   S;
4098   W;
4099 }
4100
4101 static int
4102 api_want_interface_events (vat_main_t * vam)
4103 {
4104   unformat_input_t *i = vam->input;
4105   vl_api_want_interface_events_t *mp;
4106   f64 timeout;
4107   int enable = -1;
4108
4109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4110     {
4111       if (unformat (i, "enable"))
4112         enable = 1;
4113       else if (unformat (i, "disable"))
4114         enable = 0;
4115       else
4116         break;
4117     }
4118
4119   if (enable == -1)
4120     {
4121       errmsg ("missing enable|disable\n");
4122       return -99;
4123     }
4124
4125   M (WANT_INTERFACE_EVENTS, want_interface_events);
4126   mp->enable_disable = enable;
4127
4128   vam->interface_event_display = enable;
4129
4130   S;
4131   W;
4132 }
4133
4134
4135 /* Note: non-static, called once to set up the initial intfc table */
4136 int
4137 api_sw_interface_dump (vat_main_t * vam)
4138 {
4139   vl_api_sw_interface_dump_t *mp;
4140   f64 timeout;
4141   hash_pair_t *p;
4142   name_sort_t *nses = 0, *ns;
4143   sw_interface_subif_t *sub = NULL;
4144
4145   /* Toss the old name table */
4146   /* *INDENT-OFF* */
4147   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4148   ({
4149     vec_add2 (nses, ns, 1);
4150     ns->name = (u8 *)(p->key);
4151     ns->value = (u32) p->value[0];
4152   }));
4153   /* *INDENT-ON* */
4154
4155   hash_free (vam->sw_if_index_by_interface_name);
4156
4157   vec_foreach (ns, nses) vec_free (ns->name);
4158
4159   vec_free (nses);
4160
4161   vec_foreach (sub, vam->sw_if_subif_table)
4162   {
4163     vec_free (sub->interface_name);
4164   }
4165   vec_free (vam->sw_if_subif_table);
4166
4167   /* recreate the interface name hash table */
4168   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4169
4170   /* Get list of ethernets */
4171   M (SW_INTERFACE_DUMP, sw_interface_dump);
4172   mp->name_filter_valid = 1;
4173   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4174   S;
4175
4176   /* and local / loopback interfaces */
4177   M (SW_INTERFACE_DUMP, sw_interface_dump);
4178   mp->name_filter_valid = 1;
4179   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4180   S;
4181
4182
4183   /* and vxlan-gpe tunnel interfaces */
4184   M (SW_INTERFACE_DUMP, sw_interface_dump);
4185   mp->name_filter_valid = 1;
4186   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4187            sizeof (mp->name_filter) - 1);
4188   S;
4189
4190   /* and vxlan tunnel interfaces */
4191   M (SW_INTERFACE_DUMP, sw_interface_dump);
4192   mp->name_filter_valid = 1;
4193   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4194   S;
4195
4196   /* and host (af_packet) interfaces */
4197   M (SW_INTERFACE_DUMP, sw_interface_dump);
4198   mp->name_filter_valid = 1;
4199   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4200   S;
4201
4202   /* and l2tpv3 tunnel interfaces */
4203   M (SW_INTERFACE_DUMP, sw_interface_dump);
4204   mp->name_filter_valid = 1;
4205   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4206            sizeof (mp->name_filter) - 1);
4207   S;
4208
4209   /* and GRE tunnel interfaces */
4210   M (SW_INTERFACE_DUMP, sw_interface_dump);
4211   mp->name_filter_valid = 1;
4212   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4213   S;
4214
4215   /* Use a control ping for synchronization */
4216   {
4217     vl_api_control_ping_t *mp;
4218     M (CONTROL_PING, control_ping);
4219     S;
4220   }
4221   W;
4222 }
4223
4224 static int
4225 api_sw_interface_set_flags (vat_main_t * vam)
4226 {
4227   unformat_input_t *i = vam->input;
4228   vl_api_sw_interface_set_flags_t *mp;
4229   f64 timeout;
4230   u32 sw_if_index;
4231   u8 sw_if_index_set = 0;
4232   u8 admin_up = 0, link_up = 0;
4233
4234   /* Parse args required to build the message */
4235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4236     {
4237       if (unformat (i, "admin-up"))
4238         admin_up = 1;
4239       else if (unformat (i, "admin-down"))
4240         admin_up = 0;
4241       else if (unformat (i, "link-up"))
4242         link_up = 1;
4243       else if (unformat (i, "link-down"))
4244         link_up = 0;
4245       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4246         sw_if_index_set = 1;
4247       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4248         sw_if_index_set = 1;
4249       else
4250         break;
4251     }
4252
4253   if (sw_if_index_set == 0)
4254     {
4255       errmsg ("missing interface name or sw_if_index\n");
4256       return -99;
4257     }
4258
4259   /* Construct the API message */
4260   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4261   mp->sw_if_index = ntohl (sw_if_index);
4262   mp->admin_up_down = admin_up;
4263   mp->link_up_down = link_up;
4264
4265   /* send it... */
4266   S;
4267
4268   /* Wait for a reply, return the good/bad news... */
4269   W;
4270 }
4271
4272 static int
4273 api_sw_interface_clear_stats (vat_main_t * vam)
4274 {
4275   unformat_input_t *i = vam->input;
4276   vl_api_sw_interface_clear_stats_t *mp;
4277   f64 timeout;
4278   u32 sw_if_index;
4279   u8 sw_if_index_set = 0;
4280
4281   /* Parse args required to build the message */
4282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4283     {
4284       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4285         sw_if_index_set = 1;
4286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4287         sw_if_index_set = 1;
4288       else
4289         break;
4290     }
4291
4292   /* Construct the API message */
4293   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4294
4295   if (sw_if_index_set == 1)
4296     mp->sw_if_index = ntohl (sw_if_index);
4297   else
4298     mp->sw_if_index = ~0;
4299
4300   /* send it... */
4301   S;
4302
4303   /* Wait for a reply, return the good/bad news... */
4304   W;
4305 }
4306
4307 static int
4308 api_sw_interface_add_del_address (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_sw_interface_add_del_address_t *mp;
4312   f64 timeout;
4313   u32 sw_if_index;
4314   u8 sw_if_index_set = 0;
4315   u8 is_add = 1, del_all = 0;
4316   u32 address_length = 0;
4317   u8 v4_address_set = 0;
4318   u8 v6_address_set = 0;
4319   ip4_address_t v4address;
4320   ip6_address_t v6address;
4321
4322   /* Parse args required to build the message */
4323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4324     {
4325       if (unformat (i, "del-all"))
4326         del_all = 1;
4327       else if (unformat (i, "del"))
4328         is_add = 0;
4329       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4330         sw_if_index_set = 1;
4331       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4332         sw_if_index_set = 1;
4333       else if (unformat (i, "%U/%d",
4334                          unformat_ip4_address, &v4address, &address_length))
4335         v4_address_set = 1;
4336       else if (unformat (i, "%U/%d",
4337                          unformat_ip6_address, &v6address, &address_length))
4338         v6_address_set = 1;
4339       else
4340         break;
4341     }
4342
4343   if (sw_if_index_set == 0)
4344     {
4345       errmsg ("missing interface name or sw_if_index\n");
4346       return -99;
4347     }
4348   if (v4_address_set && v6_address_set)
4349     {
4350       errmsg ("both v4 and v6 addresses set\n");
4351       return -99;
4352     }
4353   if (!v4_address_set && !v6_address_set && !del_all)
4354     {
4355       errmsg ("no addresses set\n");
4356       return -99;
4357     }
4358
4359   /* Construct the API message */
4360   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4361
4362   mp->sw_if_index = ntohl (sw_if_index);
4363   mp->is_add = is_add;
4364   mp->del_all = del_all;
4365   if (v6_address_set)
4366     {
4367       mp->is_ipv6 = 1;
4368       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4369     }
4370   else
4371     {
4372       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4373     }
4374   mp->address_length = address_length;
4375
4376   /* send it... */
4377   S;
4378
4379   /* Wait for a reply, return good/bad news  */
4380   W;
4381 }
4382
4383 static int
4384 api_sw_interface_set_table (vat_main_t * vam)
4385 {
4386   unformat_input_t *i = vam->input;
4387   vl_api_sw_interface_set_table_t *mp;
4388   f64 timeout;
4389   u32 sw_if_index, vrf_id = 0;
4390   u8 sw_if_index_set = 0;
4391   u8 is_ipv6 = 0;
4392
4393   /* Parse args required to build the message */
4394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4395     {
4396       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4397         sw_if_index_set = 1;
4398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4399         sw_if_index_set = 1;
4400       else if (unformat (i, "vrf %d", &vrf_id))
4401         ;
4402       else if (unformat (i, "ipv6"))
4403         is_ipv6 = 1;
4404       else
4405         break;
4406     }
4407
4408   if (sw_if_index_set == 0)
4409     {
4410       errmsg ("missing interface name or sw_if_index\n");
4411       return -99;
4412     }
4413
4414   /* Construct the API message */
4415   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4416
4417   mp->sw_if_index = ntohl (sw_if_index);
4418   mp->is_ipv6 = is_ipv6;
4419   mp->vrf_id = ntohl (vrf_id);
4420
4421   /* send it... */
4422   S;
4423
4424   /* Wait for a reply... */
4425   W;
4426 }
4427
4428 static int
4429 api_sw_interface_set_vpath (vat_main_t * vam)
4430 {
4431   unformat_input_t *i = vam->input;
4432   vl_api_sw_interface_set_vpath_t *mp;
4433   f64 timeout;
4434   u32 sw_if_index = 0;
4435   u8 sw_if_index_set = 0;
4436   u8 is_enable = 0;
4437
4438   /* Parse args required to build the message */
4439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4440     {
4441       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4442         sw_if_index_set = 1;
4443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4444         sw_if_index_set = 1;
4445       else if (unformat (i, "enable"))
4446         is_enable = 1;
4447       else if (unformat (i, "disable"))
4448         is_enable = 0;
4449       else
4450         break;
4451     }
4452
4453   if (sw_if_index_set == 0)
4454     {
4455       errmsg ("missing interface name or sw_if_index\n");
4456       return -99;
4457     }
4458
4459   /* Construct the API message */
4460   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4461
4462   mp->sw_if_index = ntohl (sw_if_index);
4463   mp->enable = is_enable;
4464
4465   /* send it... */
4466   S;
4467
4468   /* Wait for a reply... */
4469   W;
4470 }
4471
4472 static int
4473 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4474 {
4475   unformat_input_t *i = vam->input;
4476   vl_api_sw_interface_set_l2_xconnect_t *mp;
4477   f64 timeout;
4478   u32 rx_sw_if_index;
4479   u8 rx_sw_if_index_set = 0;
4480   u32 tx_sw_if_index;
4481   u8 tx_sw_if_index_set = 0;
4482   u8 enable = 1;
4483
4484   /* Parse args required to build the message */
4485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4486     {
4487       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4488         rx_sw_if_index_set = 1;
4489       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4490         tx_sw_if_index_set = 1;
4491       else if (unformat (i, "rx"))
4492         {
4493           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4494             {
4495               if (unformat (i, "%U", unformat_sw_if_index, vam,
4496                             &rx_sw_if_index))
4497                 rx_sw_if_index_set = 1;
4498             }
4499           else
4500             break;
4501         }
4502       else if (unformat (i, "tx"))
4503         {
4504           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4505             {
4506               if (unformat (i, "%U", unformat_sw_if_index, vam,
4507                             &tx_sw_if_index))
4508                 tx_sw_if_index_set = 1;
4509             }
4510           else
4511             break;
4512         }
4513       else if (unformat (i, "enable"))
4514         enable = 1;
4515       else if (unformat (i, "disable"))
4516         enable = 0;
4517       else
4518         break;
4519     }
4520
4521   if (rx_sw_if_index_set == 0)
4522     {
4523       errmsg ("missing rx interface name or rx_sw_if_index\n");
4524       return -99;
4525     }
4526
4527   if (enable && (tx_sw_if_index_set == 0))
4528     {
4529       errmsg ("missing tx interface name or tx_sw_if_index\n");
4530       return -99;
4531     }
4532
4533   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4534
4535   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4536   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4537   mp->enable = enable;
4538
4539   S;
4540   W;
4541   /* NOTREACHED */
4542   return 0;
4543 }
4544
4545 static int
4546 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4547 {
4548   unformat_input_t *i = vam->input;
4549   vl_api_sw_interface_set_l2_bridge_t *mp;
4550   f64 timeout;
4551   u32 rx_sw_if_index;
4552   u8 rx_sw_if_index_set = 0;
4553   u32 bd_id;
4554   u8 bd_id_set = 0;
4555   u8 bvi = 0;
4556   u32 shg = 0;
4557   u8 enable = 1;
4558
4559   /* Parse args required to build the message */
4560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4561     {
4562       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4563         rx_sw_if_index_set = 1;
4564       else if (unformat (i, "bd_id %d", &bd_id))
4565         bd_id_set = 1;
4566       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4567         rx_sw_if_index_set = 1;
4568       else if (unformat (i, "shg %d", &shg))
4569         ;
4570       else if (unformat (i, "bvi"))
4571         bvi = 1;
4572       else if (unformat (i, "enable"))
4573         enable = 1;
4574       else if (unformat (i, "disable"))
4575         enable = 0;
4576       else
4577         break;
4578     }
4579
4580   if (rx_sw_if_index_set == 0)
4581     {
4582       errmsg ("missing rx interface name or sw_if_index\n");
4583       return -99;
4584     }
4585
4586   if (enable && (bd_id_set == 0))
4587     {
4588       errmsg ("missing bridge domain\n");
4589       return -99;
4590     }
4591
4592   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4593
4594   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4595   mp->bd_id = ntohl (bd_id);
4596   mp->shg = (u8) shg;
4597   mp->bvi = bvi;
4598   mp->enable = enable;
4599
4600   S;
4601   W;
4602   /* NOTREACHED */
4603   return 0;
4604 }
4605
4606 static int
4607 api_bridge_domain_dump (vat_main_t * vam)
4608 {
4609   unformat_input_t *i = vam->input;
4610   vl_api_bridge_domain_dump_t *mp;
4611   f64 timeout;
4612   u32 bd_id = ~0;
4613
4614   /* Parse args required to build the message */
4615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4616     {
4617       if (unformat (i, "bd_id %d", &bd_id))
4618         ;
4619       else
4620         break;
4621     }
4622
4623   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4624   mp->bd_id = ntohl (bd_id);
4625   S;
4626
4627   /* Use a control ping for synchronization */
4628   {
4629     vl_api_control_ping_t *mp;
4630     M (CONTROL_PING, control_ping);
4631     S;
4632   }
4633
4634   W;
4635   /* NOTREACHED */
4636   return 0;
4637 }
4638
4639 static int
4640 api_bridge_domain_add_del (vat_main_t * vam)
4641 {
4642   unformat_input_t *i = vam->input;
4643   vl_api_bridge_domain_add_del_t *mp;
4644   f64 timeout;
4645   u32 bd_id = ~0;
4646   u8 is_add = 1;
4647   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4648
4649   /* Parse args required to build the message */
4650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4651     {
4652       if (unformat (i, "bd_id %d", &bd_id))
4653         ;
4654       else if (unformat (i, "flood %d", &flood))
4655         ;
4656       else if (unformat (i, "uu-flood %d", &uu_flood))
4657         ;
4658       else if (unformat (i, "forward %d", &forward))
4659         ;
4660       else if (unformat (i, "learn %d", &learn))
4661         ;
4662       else if (unformat (i, "arp-term %d", &arp_term))
4663         ;
4664       else if (unformat (i, "del"))
4665         {
4666           is_add = 0;
4667           flood = uu_flood = forward = learn = 0;
4668         }
4669       else
4670         break;
4671     }
4672
4673   if (bd_id == ~0)
4674     {
4675       errmsg ("missing bridge domain\n");
4676       return -99;
4677     }
4678
4679   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4680
4681   mp->bd_id = ntohl (bd_id);
4682   mp->flood = flood;
4683   mp->uu_flood = uu_flood;
4684   mp->forward = forward;
4685   mp->learn = learn;
4686   mp->arp_term = arp_term;
4687   mp->is_add = is_add;
4688
4689   S;
4690   W;
4691   /* NOTREACHED */
4692   return 0;
4693 }
4694
4695 static int
4696 api_l2fib_add_del (vat_main_t * vam)
4697 {
4698   unformat_input_t *i = vam->input;
4699   vl_api_l2fib_add_del_t *mp;
4700   f64 timeout;
4701   u64 mac = 0;
4702   u8 mac_set = 0;
4703   u32 bd_id;
4704   u8 bd_id_set = 0;
4705   u32 sw_if_index;
4706   u8 sw_if_index_set = 0;
4707   u8 is_add = 1;
4708   u8 static_mac = 0;
4709   u8 filter_mac = 0;
4710   u8 bvi_mac = 0;
4711   int count = 1;
4712   f64 before = 0;
4713   int j;
4714
4715   /* Parse args required to build the message */
4716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4717     {
4718       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4719         mac_set = 1;
4720       else if (unformat (i, "bd_id %d", &bd_id))
4721         bd_id_set = 1;
4722       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4723         sw_if_index_set = 1;
4724       else if (unformat (i, "sw_if"))
4725         {
4726           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4727             {
4728               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4729                 sw_if_index_set = 1;
4730             }
4731           else
4732             break;
4733         }
4734       else if (unformat (i, "static"))
4735         static_mac = 1;
4736       else if (unformat (i, "filter"))
4737         {
4738           filter_mac = 1;
4739           static_mac = 1;
4740         }
4741       else if (unformat (i, "bvi"))
4742         {
4743           bvi_mac = 1;
4744           static_mac = 1;
4745         }
4746       else if (unformat (i, "del"))
4747         is_add = 0;
4748       else if (unformat (i, "count %d", &count))
4749         ;
4750       else
4751         break;
4752     }
4753
4754   if (mac_set == 0)
4755     {
4756       errmsg ("missing mac address\n");
4757       return -99;
4758     }
4759
4760   if (bd_id_set == 0)
4761     {
4762       errmsg ("missing bridge domain\n");
4763       return -99;
4764     }
4765
4766   if (is_add && (sw_if_index_set == 0))
4767     {
4768       errmsg ("missing interface name or sw_if_index\n");
4769       return -99;
4770     }
4771
4772   if (count > 1)
4773     {
4774       /* Turn on async mode */
4775       vam->async_mode = 1;
4776       vam->async_errors = 0;
4777       before = vat_time_now (vam);
4778     }
4779
4780   for (j = 0; j < count; j++)
4781     {
4782       M (L2FIB_ADD_DEL, l2fib_add_del);
4783
4784       mp->mac = mac;
4785       mp->bd_id = ntohl (bd_id);
4786       mp->is_add = is_add;
4787
4788       if (is_add)
4789         {
4790           mp->sw_if_index = ntohl (sw_if_index);
4791           mp->static_mac = static_mac;
4792           mp->filter_mac = filter_mac;
4793           mp->bvi_mac = bvi_mac;
4794         }
4795       increment_mac_address (&mac);
4796       /* send it... */
4797       S;
4798     }
4799
4800   if (count > 1)
4801     {
4802       vl_api_control_ping_t *mp;
4803       f64 after;
4804
4805       /* Shut off async mode */
4806       vam->async_mode = 0;
4807
4808       M (CONTROL_PING, control_ping);
4809       S;
4810
4811       timeout = vat_time_now (vam) + 1.0;
4812       while (vat_time_now (vam) < timeout)
4813         if (vam->result_ready == 1)
4814           goto out;
4815       vam->retval = -99;
4816
4817     out:
4818       if (vam->retval == -99)
4819         errmsg ("timeout\n");
4820
4821       if (vam->async_errors > 0)
4822         {
4823           errmsg ("%d asynchronous errors\n", vam->async_errors);
4824           vam->retval = -98;
4825         }
4826       vam->async_errors = 0;
4827       after = vat_time_now (vam);
4828
4829       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4830                count, after - before, count / (after - before));
4831     }
4832   else
4833     {
4834       /* Wait for a reply... */
4835       W;
4836     }
4837   /* Return the good/bad news */
4838   return (vam->retval);
4839 }
4840
4841 static int
4842 api_l2_flags (vat_main_t * vam)
4843 {
4844   unformat_input_t *i = vam->input;
4845   vl_api_l2_flags_t *mp;
4846   f64 timeout;
4847   u32 sw_if_index;
4848   u32 feature_bitmap = 0;
4849   u8 sw_if_index_set = 0;
4850
4851   /* Parse args required to build the message */
4852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4853     {
4854       if (unformat (i, "sw_if_index %d", &sw_if_index))
4855         sw_if_index_set = 1;
4856       else if (unformat (i, "sw_if"))
4857         {
4858           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4859             {
4860               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4861                 sw_if_index_set = 1;
4862             }
4863           else
4864             break;
4865         }
4866       else if (unformat (i, "learn"))
4867         feature_bitmap |= L2INPUT_FEAT_LEARN;
4868       else if (unformat (i, "forward"))
4869         feature_bitmap |= L2INPUT_FEAT_FWD;
4870       else if (unformat (i, "flood"))
4871         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4872       else if (unformat (i, "uu-flood"))
4873         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4874       else
4875         break;
4876     }
4877
4878   if (sw_if_index_set == 0)
4879     {
4880       errmsg ("missing interface name or sw_if_index\n");
4881       return -99;
4882     }
4883
4884   M (L2_FLAGS, l2_flags);
4885
4886   mp->sw_if_index = ntohl (sw_if_index);
4887   mp->feature_bitmap = ntohl (feature_bitmap);
4888
4889   S;
4890   W;
4891   /* NOTREACHED */
4892   return 0;
4893 }
4894
4895 static int
4896 api_bridge_flags (vat_main_t * vam)
4897 {
4898   unformat_input_t *i = vam->input;
4899   vl_api_bridge_flags_t *mp;
4900   f64 timeout;
4901   u32 bd_id;
4902   u8 bd_id_set = 0;
4903   u8 is_set = 1;
4904   u32 flags = 0;
4905
4906   /* Parse args required to build the message */
4907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4908     {
4909       if (unformat (i, "bd_id %d", &bd_id))
4910         bd_id_set = 1;
4911       else if (unformat (i, "learn"))
4912         flags |= L2_LEARN;
4913       else if (unformat (i, "forward"))
4914         flags |= L2_FWD;
4915       else if (unformat (i, "flood"))
4916         flags |= L2_FLOOD;
4917       else if (unformat (i, "uu-flood"))
4918         flags |= L2_UU_FLOOD;
4919       else if (unformat (i, "arp-term"))
4920         flags |= L2_ARP_TERM;
4921       else if (unformat (i, "off"))
4922         is_set = 0;
4923       else if (unformat (i, "disable"))
4924         is_set = 0;
4925       else
4926         break;
4927     }
4928
4929   if (bd_id_set == 0)
4930     {
4931       errmsg ("missing bridge domain\n");
4932       return -99;
4933     }
4934
4935   M (BRIDGE_FLAGS, bridge_flags);
4936
4937   mp->bd_id = ntohl (bd_id);
4938   mp->feature_bitmap = ntohl (flags);
4939   mp->is_set = is_set;
4940
4941   S;
4942   W;
4943   /* NOTREACHED */
4944   return 0;
4945 }
4946
4947 static int
4948 api_bd_ip_mac_add_del (vat_main_t * vam)
4949 {
4950   unformat_input_t *i = vam->input;
4951   vl_api_bd_ip_mac_add_del_t *mp;
4952   f64 timeout;
4953   u32 bd_id;
4954   u8 is_ipv6 = 0;
4955   u8 is_add = 1;
4956   u8 bd_id_set = 0;
4957   u8 ip_set = 0;
4958   u8 mac_set = 0;
4959   ip4_address_t v4addr;
4960   ip6_address_t v6addr;
4961   u8 macaddr[6];
4962
4963
4964   /* Parse args required to build the message */
4965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4966     {
4967       if (unformat (i, "bd_id %d", &bd_id))
4968         {
4969           bd_id_set++;
4970         }
4971       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
4972         {
4973           ip_set++;
4974         }
4975       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
4976         {
4977           ip_set++;
4978           is_ipv6++;
4979         }
4980       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
4981         {
4982           mac_set++;
4983         }
4984       else if (unformat (i, "del"))
4985         is_add = 0;
4986       else
4987         break;
4988     }
4989
4990   if (bd_id_set == 0)
4991     {
4992       errmsg ("missing bridge domain\n");
4993       return -99;
4994     }
4995   else if (ip_set == 0)
4996     {
4997       errmsg ("missing IP address\n");
4998       return -99;
4999     }
5000   else if (mac_set == 0)
5001     {
5002       errmsg ("missing MAC address\n");
5003       return -99;
5004     }
5005
5006   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5007
5008   mp->bd_id = ntohl (bd_id);
5009   mp->is_ipv6 = is_ipv6;
5010   mp->is_add = is_add;
5011   if (is_ipv6)
5012     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5013   else
5014     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5015   clib_memcpy (mp->mac_address, macaddr, 6);
5016   S;
5017   W;
5018   /* NOTREACHED */
5019   return 0;
5020 }
5021
5022 static int
5023 api_tap_connect (vat_main_t * vam)
5024 {
5025   unformat_input_t *i = vam->input;
5026   vl_api_tap_connect_t *mp;
5027   f64 timeout;
5028   u8 mac_address[6];
5029   u8 random_mac = 1;
5030   u8 name_set = 0;
5031   u8 *tap_name;
5032
5033   memset (mac_address, 0, sizeof (mac_address));
5034
5035   /* Parse args required to build the message */
5036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5037     {
5038       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5039         {
5040           random_mac = 0;
5041         }
5042       else if (unformat (i, "random-mac"))
5043         random_mac = 1;
5044       else if (unformat (i, "tapname %s", &tap_name))
5045         name_set = 1;
5046       else
5047         break;
5048     }
5049
5050   if (name_set == 0)
5051     {
5052       errmsg ("missing tap name\n");
5053       return -99;
5054     }
5055   if (vec_len (tap_name) > 63)
5056     {
5057       errmsg ("tap name too long\n");
5058     }
5059   vec_add1 (tap_name, 0);
5060
5061   /* Construct the API message */
5062   M (TAP_CONNECT, tap_connect);
5063
5064   mp->use_random_mac = random_mac;
5065   clib_memcpy (mp->mac_address, mac_address, 6);
5066   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5067   vec_free (tap_name);
5068
5069   /* send it... */
5070   S;
5071
5072   /* Wait for a reply... */
5073   W;
5074 }
5075
5076 static int
5077 api_tap_modify (vat_main_t * vam)
5078 {
5079   unformat_input_t *i = vam->input;
5080   vl_api_tap_modify_t *mp;
5081   f64 timeout;
5082   u8 mac_address[6];
5083   u8 random_mac = 1;
5084   u8 name_set = 0;
5085   u8 *tap_name;
5086   u32 sw_if_index = ~0;
5087   u8 sw_if_index_set = 0;
5088
5089   memset (mac_address, 0, sizeof (mac_address));
5090
5091   /* Parse args required to build the message */
5092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5093     {
5094       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5095         sw_if_index_set = 1;
5096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5097         sw_if_index_set = 1;
5098       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5099         {
5100           random_mac = 0;
5101         }
5102       else if (unformat (i, "random-mac"))
5103         random_mac = 1;
5104       else if (unformat (i, "tapname %s", &tap_name))
5105         name_set = 1;
5106       else
5107         break;
5108     }
5109
5110   if (sw_if_index_set == 0)
5111     {
5112       errmsg ("missing vpp interface name");
5113       return -99;
5114     }
5115   if (name_set == 0)
5116     {
5117       errmsg ("missing tap name\n");
5118       return -99;
5119     }
5120   if (vec_len (tap_name) > 63)
5121     {
5122       errmsg ("tap name too long\n");
5123     }
5124   vec_add1 (tap_name, 0);
5125
5126   /* Construct the API message */
5127   M (TAP_MODIFY, tap_modify);
5128
5129   mp->use_random_mac = random_mac;
5130   mp->sw_if_index = ntohl (sw_if_index);
5131   clib_memcpy (mp->mac_address, mac_address, 6);
5132   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5133   vec_free (tap_name);
5134
5135   /* send it... */
5136   S;
5137
5138   /* Wait for a reply... */
5139   W;
5140 }
5141
5142 static int
5143 api_tap_delete (vat_main_t * vam)
5144 {
5145   unformat_input_t *i = vam->input;
5146   vl_api_tap_delete_t *mp;
5147   f64 timeout;
5148   u32 sw_if_index = ~0;
5149   u8 sw_if_index_set = 0;
5150
5151   /* Parse args required to build the message */
5152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5153     {
5154       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5155         sw_if_index_set = 1;
5156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5157         sw_if_index_set = 1;
5158       else
5159         break;
5160     }
5161
5162   if (sw_if_index_set == 0)
5163     {
5164       errmsg ("missing vpp interface name");
5165       return -99;
5166     }
5167
5168   /* Construct the API message */
5169   M (TAP_DELETE, tap_delete);
5170
5171   mp->sw_if_index = ntohl (sw_if_index);
5172
5173   /* send it... */
5174   S;
5175
5176   /* Wait for a reply... */
5177   W;
5178 }
5179
5180 static int
5181 api_ip_add_del_route (vat_main_t * vam)
5182 {
5183   unformat_input_t *i = vam->input;
5184   vl_api_ip_add_del_route_t *mp;
5185   f64 timeout;
5186   u32 sw_if_index = ~0, vrf_id = 0;
5187   u8 sw_if_index_set = 0;
5188   u8 is_ipv6 = 0;
5189   u8 is_local = 0, is_drop = 0;
5190   u8 create_vrf_if_needed = 0;
5191   u8 is_add = 1;
5192   u8 next_hop_weight = 1;
5193   u8 not_last = 0;
5194   u8 is_multipath = 0;
5195   u8 address_set = 0;
5196   u8 address_length_set = 0;
5197   u32 lookup_in_vrf = 0;
5198   u32 resolve_attempts = 0;
5199   u32 dst_address_length = 0;
5200   u8 next_hop_set = 0;
5201   ip4_address_t v4_dst_address, v4_next_hop_address;
5202   ip6_address_t v6_dst_address, v6_next_hop_address;
5203   int count = 1;
5204   int j;
5205   f64 before = 0;
5206   u32 random_add_del = 0;
5207   u32 *random_vector = 0;
5208   uword *random_hash;
5209   u32 random_seed = 0xdeaddabe;
5210   u32 classify_table_index = ~0;
5211   u8 is_classify = 0;
5212
5213   /* Parse args required to build the message */
5214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5215     {
5216       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5217         sw_if_index_set = 1;
5218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5219         sw_if_index_set = 1;
5220       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5221         {
5222           address_set = 1;
5223           is_ipv6 = 0;
5224         }
5225       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5226         {
5227           address_set = 1;
5228           is_ipv6 = 1;
5229         }
5230       else if (unformat (i, "/%d", &dst_address_length))
5231         {
5232           address_length_set = 1;
5233         }
5234
5235       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5236                                          &v4_next_hop_address))
5237         {
5238           next_hop_set = 1;
5239         }
5240       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5241                                          &v6_next_hop_address))
5242         {
5243           next_hop_set = 1;
5244         }
5245       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5246         ;
5247       else if (unformat (i, "weight %d", &next_hop_weight))
5248         ;
5249       else if (unformat (i, "drop"))
5250         {
5251           is_drop = 1;
5252         }
5253       else if (unformat (i, "local"))
5254         {
5255           is_local = 1;
5256         }
5257       else if (unformat (i, "classify %d", &classify_table_index))
5258         {
5259           is_classify = 1;
5260         }
5261       else if (unformat (i, "del"))
5262         is_add = 0;
5263       else if (unformat (i, "add"))
5264         is_add = 1;
5265       else if (unformat (i, "not-last"))
5266         not_last = 1;
5267       else if (unformat (i, "multipath"))
5268         is_multipath = 1;
5269       else if (unformat (i, "vrf %d", &vrf_id))
5270         ;
5271       else if (unformat (i, "create-vrf"))
5272         create_vrf_if_needed = 1;
5273       else if (unformat (i, "count %d", &count))
5274         ;
5275       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5276         ;
5277       else if (unformat (i, "random"))
5278         random_add_del = 1;
5279       else if (unformat (i, "seed %d", &random_seed))
5280         ;
5281       else
5282         {
5283           clib_warning ("parse error '%U'", format_unformat_error, i);
5284           return -99;
5285         }
5286     }
5287
5288   if (resolve_attempts > 0 && sw_if_index_set == 0)
5289     {
5290       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5291       return -99;
5292     }
5293
5294   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5295     {
5296       errmsg ("next hop / local / drop / classify not set\n");
5297       return -99;
5298     }
5299
5300   if (address_set == 0)
5301     {
5302       errmsg ("missing addresses\n");
5303       return -99;
5304     }
5305
5306   if (address_length_set == 0)
5307     {
5308       errmsg ("missing address length\n");
5309       return -99;
5310     }
5311
5312   /* Generate a pile of unique, random routes */
5313   if (random_add_del)
5314     {
5315       u32 this_random_address;
5316       random_hash = hash_create (count, sizeof (uword));
5317
5318       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5319       for (j = 0; j <= count; j++)
5320         {
5321           do
5322             {
5323               this_random_address = random_u32 (&random_seed);
5324               this_random_address =
5325                 clib_host_to_net_u32 (this_random_address);
5326             }
5327           while (hash_get (random_hash, this_random_address));
5328           vec_add1 (random_vector, this_random_address);
5329           hash_set (random_hash, this_random_address, 1);
5330         }
5331       hash_free (random_hash);
5332       v4_dst_address.as_u32 = random_vector[0];
5333     }
5334
5335   if (count > 1)
5336     {
5337       /* Turn on async mode */
5338       vam->async_mode = 1;
5339       vam->async_errors = 0;
5340       before = vat_time_now (vam);
5341     }
5342
5343   for (j = 0; j < count; j++)
5344     {
5345       /* Construct the API message */
5346       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5347
5348       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5349       mp->vrf_id = ntohl (vrf_id);
5350       if (resolve_attempts > 0)
5351         {
5352           mp->resolve_attempts = ntohl (resolve_attempts);
5353           mp->resolve_if_needed = 1;
5354         }
5355       mp->create_vrf_if_needed = create_vrf_if_needed;
5356
5357       mp->is_add = is_add;
5358       mp->is_drop = is_drop;
5359       mp->is_ipv6 = is_ipv6;
5360       mp->is_local = is_local;
5361       mp->is_classify = is_classify;
5362       mp->is_multipath = is_multipath;
5363       mp->not_last = not_last;
5364       mp->next_hop_weight = next_hop_weight;
5365       mp->dst_address_length = dst_address_length;
5366       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5367       mp->classify_table_index = ntohl (classify_table_index);
5368
5369       if (is_ipv6)
5370         {
5371           clib_memcpy (mp->dst_address, &v6_dst_address,
5372                        sizeof (v6_dst_address));
5373           if (next_hop_set)
5374             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5375                          sizeof (v6_next_hop_address));
5376           increment_v6_address (&v6_dst_address);
5377         }
5378       else
5379         {
5380           clib_memcpy (mp->dst_address, &v4_dst_address,
5381                        sizeof (v4_dst_address));
5382           if (next_hop_set)
5383             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5384                          sizeof (v4_next_hop_address));
5385           if (random_add_del)
5386             v4_dst_address.as_u32 = random_vector[j + 1];
5387           else
5388             increment_v4_address (&v4_dst_address);
5389         }
5390       /* send it... */
5391       S;
5392     }
5393
5394   /* When testing multiple add/del ops, use a control-ping to sync */
5395   if (count > 1)
5396     {
5397       vl_api_control_ping_t *mp;
5398       f64 after;
5399
5400       /* Shut off async mode */
5401       vam->async_mode = 0;
5402
5403       M (CONTROL_PING, control_ping);
5404       S;
5405
5406       timeout = vat_time_now (vam) + 1.0;
5407       while (vat_time_now (vam) < timeout)
5408         if (vam->result_ready == 1)
5409           goto out;
5410       vam->retval = -99;
5411
5412     out:
5413       if (vam->retval == -99)
5414         errmsg ("timeout\n");
5415
5416       if (vam->async_errors > 0)
5417         {
5418           errmsg ("%d asynchronous errors\n", vam->async_errors);
5419           vam->retval = -98;
5420         }
5421       vam->async_errors = 0;
5422       after = vat_time_now (vam);
5423
5424       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5425                count, after - before, count / (after - before));
5426     }
5427   else
5428     {
5429       /* Wait for a reply... */
5430       W;
5431     }
5432
5433   /* Return the good/bad news */
5434   return (vam->retval);
5435 }
5436
5437 static int
5438 api_proxy_arp_add_del (vat_main_t * vam)
5439 {
5440   unformat_input_t *i = vam->input;
5441   vl_api_proxy_arp_add_del_t *mp;
5442   f64 timeout;
5443   u32 vrf_id = 0;
5444   u8 is_add = 1;
5445   ip4_address_t lo, hi;
5446   u8 range_set = 0;
5447
5448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449     {
5450       if (unformat (i, "vrf %d", &vrf_id))
5451         ;
5452       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5453                          unformat_ip4_address, &hi))
5454         range_set = 1;
5455       else if (unformat (i, "del"))
5456         is_add = 0;
5457       else
5458         {
5459           clib_warning ("parse error '%U'", format_unformat_error, i);
5460           return -99;
5461         }
5462     }
5463
5464   if (range_set == 0)
5465     {
5466       errmsg ("address range not set\n");
5467       return -99;
5468     }
5469
5470   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5471
5472   mp->vrf_id = ntohl (vrf_id);
5473   mp->is_add = is_add;
5474   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5475   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5476
5477   S;
5478   W;
5479   /* NOTREACHED */
5480   return 0;
5481 }
5482
5483 static int
5484 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5485 {
5486   unformat_input_t *i = vam->input;
5487   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5488   f64 timeout;
5489   u32 sw_if_index;
5490   u8 enable = 1;
5491   u8 sw_if_index_set = 0;
5492
5493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5494     {
5495       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5496         sw_if_index_set = 1;
5497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5498         sw_if_index_set = 1;
5499       else if (unformat (i, "enable"))
5500         enable = 1;
5501       else if (unformat (i, "disable"))
5502         enable = 0;
5503       else
5504         {
5505           clib_warning ("parse error '%U'", format_unformat_error, i);
5506           return -99;
5507         }
5508     }
5509
5510   if (sw_if_index_set == 0)
5511     {
5512       errmsg ("missing interface name or sw_if_index\n");
5513       return -99;
5514     }
5515
5516   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5517
5518   mp->sw_if_index = ntohl (sw_if_index);
5519   mp->enable_disable = enable;
5520
5521   S;
5522   W;
5523   /* NOTREACHED */
5524   return 0;
5525 }
5526
5527 static int
5528 api_mpls_add_del_decap (vat_main_t * vam)
5529 {
5530   unformat_input_t *i = vam->input;
5531   vl_api_mpls_add_del_decap_t *mp;
5532   f64 timeout;
5533   u32 rx_vrf_id = 0;
5534   u32 tx_vrf_id = 0;
5535   u32 label = 0;
5536   u8 is_add = 1;
5537   u8 s_bit = 1;
5538   u32 next_index = 1;
5539
5540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5541     {
5542       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5543         ;
5544       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5545         ;
5546       else if (unformat (i, "label %d", &label))
5547         ;
5548       else if (unformat (i, "next-index %d", &next_index))
5549         ;
5550       else if (unformat (i, "del"))
5551         is_add = 0;
5552       else if (unformat (i, "s-bit-clear"))
5553         s_bit = 0;
5554       else
5555         {
5556           clib_warning ("parse error '%U'", format_unformat_error, i);
5557           return -99;
5558         }
5559     }
5560
5561   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5562
5563   mp->rx_vrf_id = ntohl (rx_vrf_id);
5564   mp->tx_vrf_id = ntohl (tx_vrf_id);
5565   mp->label = ntohl (label);
5566   mp->next_index = ntohl (next_index);
5567   mp->s_bit = s_bit;
5568   mp->is_add = is_add;
5569
5570   S;
5571   W;
5572   /* NOTREACHED */
5573   return 0;
5574 }
5575
5576 static int
5577 api_mpls_add_del_encap (vat_main_t * vam)
5578 {
5579   unformat_input_t *i = vam->input;
5580   vl_api_mpls_add_del_encap_t *mp;
5581   f64 timeout;
5582   u32 vrf_id = 0;
5583   u32 *labels = 0;
5584   u32 label;
5585   ip4_address_t dst_address;
5586   u8 is_add = 1;
5587
5588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5589     {
5590       if (unformat (i, "vrf %d", &vrf_id))
5591         ;
5592       else if (unformat (i, "label %d", &label))
5593         vec_add1 (labels, ntohl (label));
5594       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5595         ;
5596       else if (unformat (i, "del"))
5597         is_add = 0;
5598       else
5599         {
5600           clib_warning ("parse error '%U'", format_unformat_error, i);
5601           return -99;
5602         }
5603     }
5604
5605   if (vec_len (labels) == 0)
5606     {
5607       errmsg ("missing encap label stack\n");
5608       return -99;
5609     }
5610
5611   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5612       sizeof (u32) * vec_len (labels));
5613
5614   mp->vrf_id = ntohl (vrf_id);
5615   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5616   mp->is_add = is_add;
5617   mp->nlabels = vec_len (labels);
5618   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5619
5620   vec_free (labels);
5621
5622   S;
5623   W;
5624   /* NOTREACHED */
5625   return 0;
5626 }
5627
5628 static int
5629 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5630 {
5631   unformat_input_t *i = vam->input;
5632   vl_api_mpls_gre_add_del_tunnel_t *mp;
5633   f64 timeout;
5634   u32 inner_vrf_id = 0;
5635   u32 outer_vrf_id = 0;
5636   ip4_address_t src_address;
5637   ip4_address_t dst_address;
5638   ip4_address_t intfc_address;
5639   u32 tmp;
5640   u8 intfc_address_length = 0;
5641   u8 is_add = 1;
5642   u8 l2_only = 0;
5643
5644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5645     {
5646       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5647         ;
5648       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5649         ;
5650       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5651         ;
5652       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5653         ;
5654       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5655                          &intfc_address, &tmp))
5656         intfc_address_length = tmp;
5657       else if (unformat (i, "l2-only"))
5658         l2_only = 1;
5659       else if (unformat (i, "del"))
5660         is_add = 0;
5661       else
5662         {
5663           clib_warning ("parse error '%U'", format_unformat_error, i);
5664           return -99;
5665         }
5666     }
5667
5668   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5669
5670   mp->inner_vrf_id = ntohl (inner_vrf_id);
5671   mp->outer_vrf_id = ntohl (outer_vrf_id);
5672   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5673   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5674   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5675   mp->intfc_address_length = intfc_address_length;
5676   mp->l2_only = l2_only;
5677   mp->is_add = is_add;
5678
5679   S;
5680   W;
5681   /* NOTREACHED */
5682   return 0;
5683 }
5684
5685 static int
5686 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5687 {
5688   unformat_input_t *i = vam->input;
5689   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5690   f64 timeout;
5691   u32 inner_vrf_id = 0;
5692   ip4_address_t intfc_address;
5693   u8 dst_mac_address[6];
5694   int dst_set = 1;
5695   u32 tmp;
5696   u8 intfc_address_length = 0;
5697   u8 is_add = 1;
5698   u8 l2_only = 0;
5699   u32 tx_sw_if_index;
5700   int tx_sw_if_index_set = 0;
5701
5702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5703     {
5704       if (unformat (i, "vrf %d", &inner_vrf_id))
5705         ;
5706       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5707                          &intfc_address, &tmp))
5708         intfc_address_length = tmp;
5709       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5710         tx_sw_if_index_set = 1;
5711       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5712         tx_sw_if_index_set = 1;
5713       else if (unformat (i, "dst %U", unformat_ethernet_address,
5714                          dst_mac_address))
5715         dst_set = 1;
5716       else if (unformat (i, "l2-only"))
5717         l2_only = 1;
5718       else if (unformat (i, "del"))
5719         is_add = 0;
5720       else
5721         {
5722           clib_warning ("parse error '%U'", format_unformat_error, i);
5723           return -99;
5724         }
5725     }
5726
5727   if (!dst_set)
5728     {
5729       errmsg ("dst (mac address) not set\n");
5730       return -99;
5731     }
5732   if (!tx_sw_if_index_set)
5733     {
5734       errmsg ("tx-intfc not set\n");
5735       return -99;
5736     }
5737
5738   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5739
5740   mp->vrf_id = ntohl (inner_vrf_id);
5741   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5742   mp->adj_address_length = intfc_address_length;
5743   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5744                sizeof (dst_mac_address));
5745   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5746   mp->l2_only = l2_only;
5747   mp->is_add = is_add;
5748
5749   S;
5750   W;
5751   /* NOTREACHED */
5752   return 0;
5753 }
5754
5755 static int
5756 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5757 {
5758   unformat_input_t *i = vam->input;
5759   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5760   f64 timeout;
5761   u32 inner_vrf_id = 0;
5762   u32 outer_vrf_id = 0;
5763   ip4_address_t adj_address;
5764   int adj_address_set = 0;
5765   ip4_address_t next_hop_address;
5766   int next_hop_address_set = 0;
5767   u32 tmp;
5768   u8 adj_address_length = 0;
5769   u8 l2_only = 0;
5770   u8 is_add = 1;
5771   u32 resolve_attempts = 5;
5772   u8 resolve_if_needed = 1;
5773
5774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5775     {
5776       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5777         ;
5778       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5779         ;
5780       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5781                          &adj_address, &tmp))
5782         {
5783           adj_address_length = tmp;
5784           adj_address_set = 1;
5785         }
5786       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5787                          &next_hop_address))
5788         next_hop_address_set = 1;
5789       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5790         ;
5791       else if (unformat (i, "resolve-if-needed %d", &tmp))
5792         resolve_if_needed = tmp;
5793       else if (unformat (i, "l2-only"))
5794         l2_only = 1;
5795       else if (unformat (i, "del"))
5796         is_add = 0;
5797       else
5798         {
5799           clib_warning ("parse error '%U'", format_unformat_error, i);
5800           return -99;
5801         }
5802     }
5803
5804   if (!adj_address_set)
5805     {
5806       errmsg ("adjacency address/mask not set\n");
5807       return -99;
5808     }
5809   if (!next_hop_address_set)
5810     {
5811       errmsg ("ip4 next hop address (in outer fib) not set\n");
5812       return -99;
5813     }
5814
5815   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5816
5817   mp->inner_vrf_id = ntohl (inner_vrf_id);
5818   mp->outer_vrf_id = ntohl (outer_vrf_id);
5819   mp->resolve_attempts = ntohl (resolve_attempts);
5820   mp->resolve_if_needed = resolve_if_needed;
5821   mp->is_add = is_add;
5822   mp->l2_only = l2_only;
5823   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5824   mp->adj_address_length = adj_address_length;
5825   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5826                sizeof (next_hop_address));
5827
5828   S;
5829   W;
5830   /* NOTREACHED */
5831   return 0;
5832 }
5833
5834 static int
5835 api_sw_interface_set_unnumbered (vat_main_t * vam)
5836 {
5837   unformat_input_t *i = vam->input;
5838   vl_api_sw_interface_set_unnumbered_t *mp;
5839   f64 timeout;
5840   u32 sw_if_index;
5841   u32 unnum_sw_index = ~0;
5842   u8 is_add = 1;
5843   u8 sw_if_index_set = 0;
5844
5845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5846     {
5847       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5848         sw_if_index_set = 1;
5849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5850         sw_if_index_set = 1;
5851       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5852         ;
5853       else if (unformat (i, "del"))
5854         is_add = 0;
5855       else
5856         {
5857           clib_warning ("parse error '%U'", format_unformat_error, i);
5858           return -99;
5859         }
5860     }
5861
5862   if (sw_if_index_set == 0)
5863     {
5864       errmsg ("missing interface name or sw_if_index\n");
5865       return -99;
5866     }
5867
5868   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5869
5870   mp->sw_if_index = ntohl (sw_if_index);
5871   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5872   mp->is_add = is_add;
5873
5874   S;
5875   W;
5876   /* NOTREACHED */
5877   return 0;
5878 }
5879
5880 static int
5881 api_ip_neighbor_add_del (vat_main_t * vam)
5882 {
5883   unformat_input_t *i = vam->input;
5884   vl_api_ip_neighbor_add_del_t *mp;
5885   f64 timeout;
5886   u32 sw_if_index;
5887   u8 sw_if_index_set = 0;
5888   u32 vrf_id = 0;
5889   u8 is_add = 1;
5890   u8 is_static = 0;
5891   u8 mac_address[6];
5892   u8 mac_set = 0;
5893   u8 v4_address_set = 0;
5894   u8 v6_address_set = 0;
5895   ip4_address_t v4address;
5896   ip6_address_t v6address;
5897
5898   memset (mac_address, 0, sizeof (mac_address));
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5904         {
5905           mac_set = 1;
5906         }
5907       else if (unformat (i, "del"))
5908         is_add = 0;
5909       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5910         sw_if_index_set = 1;
5911       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5912         sw_if_index_set = 1;
5913       else if (unformat (i, "is_static"))
5914         is_static = 1;
5915       else if (unformat (i, "vrf %d", &vrf_id))
5916         ;
5917       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5918         v4_address_set = 1;
5919       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5920         v6_address_set = 1;
5921       else
5922         {
5923           clib_warning ("parse error '%U'", format_unformat_error, i);
5924           return -99;
5925         }
5926     }
5927
5928   if (sw_if_index_set == 0)
5929     {
5930       errmsg ("missing interface name or sw_if_index\n");
5931       return -99;
5932     }
5933   if (v4_address_set && v6_address_set)
5934     {
5935       errmsg ("both v4 and v6 addresses set\n");
5936       return -99;
5937     }
5938   if (!v4_address_set && !v6_address_set)
5939     {
5940       errmsg ("no address set\n");
5941       return -99;
5942     }
5943
5944   /* Construct the API message */
5945   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
5946
5947   mp->sw_if_index = ntohl (sw_if_index);
5948   mp->is_add = is_add;
5949   mp->vrf_id = ntohl (vrf_id);
5950   mp->is_static = is_static;
5951   if (mac_set)
5952     clib_memcpy (mp->mac_address, mac_address, 6);
5953   if (v6_address_set)
5954     {
5955       mp->is_ipv6 = 1;
5956       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
5957     }
5958   else
5959     {
5960       /* mp->is_ipv6 = 0; via memset in M macro above */
5961       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
5962     }
5963
5964   /* send it... */
5965   S;
5966
5967   /* Wait for a reply, return good/bad news  */
5968   W;
5969
5970   /* NOTREACHED */
5971   return 0;
5972 }
5973
5974 static int
5975 api_reset_vrf (vat_main_t * vam)
5976 {
5977   unformat_input_t *i = vam->input;
5978   vl_api_reset_vrf_t *mp;
5979   f64 timeout;
5980   u32 vrf_id = 0;
5981   u8 is_ipv6 = 0;
5982   u8 vrf_id_set = 0;
5983
5984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5985     {
5986       if (unformat (i, "vrf %d", &vrf_id))
5987         vrf_id_set = 1;
5988       else if (unformat (i, "ipv6"))
5989         is_ipv6 = 1;
5990       else
5991         {
5992           clib_warning ("parse error '%U'", format_unformat_error, i);
5993           return -99;
5994         }
5995     }
5996
5997   if (vrf_id_set == 0)
5998     {
5999       errmsg ("missing vrf id\n");
6000       return -99;
6001     }
6002
6003   M (RESET_VRF, reset_vrf);
6004
6005   mp->vrf_id = ntohl (vrf_id);
6006   mp->is_ipv6 = is_ipv6;
6007
6008   S;
6009   W;
6010   /* NOTREACHED */
6011   return 0;
6012 }
6013
6014 static int
6015 api_create_vlan_subif (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_create_vlan_subif_t *mp;
6019   f64 timeout;
6020   u32 sw_if_index;
6021   u8 sw_if_index_set = 0;
6022   u32 vlan_id;
6023   u8 vlan_id_set = 0;
6024
6025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6026     {
6027       if (unformat (i, "sw_if_index %d", &sw_if_index))
6028         sw_if_index_set = 1;
6029       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6030         sw_if_index_set = 1;
6031       else if (unformat (i, "vlan %d", &vlan_id))
6032         vlan_id_set = 1;
6033       else
6034         {
6035           clib_warning ("parse error '%U'", format_unformat_error, i);
6036           return -99;
6037         }
6038     }
6039
6040   if (sw_if_index_set == 0)
6041     {
6042       errmsg ("missing interface name or sw_if_index\n");
6043       return -99;
6044     }
6045
6046   if (vlan_id_set == 0)
6047     {
6048       errmsg ("missing vlan_id\n");
6049       return -99;
6050     }
6051   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6052
6053   mp->sw_if_index = ntohl (sw_if_index);
6054   mp->vlan_id = ntohl (vlan_id);
6055
6056   S;
6057   W;
6058   /* NOTREACHED */
6059   return 0;
6060 }
6061
6062 #define foreach_create_subif_bit                \
6063 _(no_tags)                                      \
6064 _(one_tag)                                      \
6065 _(two_tags)                                     \
6066 _(dot1ad)                                       \
6067 _(exact_match)                                  \
6068 _(default_sub)                                  \
6069 _(outer_vlan_id_any)                            \
6070 _(inner_vlan_id_any)
6071
6072 static int
6073 api_create_subif (vat_main_t * vam)
6074 {
6075   unformat_input_t *i = vam->input;
6076   vl_api_create_subif_t *mp;
6077   f64 timeout;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   u32 sub_id;
6081   u8 sub_id_set = 0;
6082   u32 no_tags = 0;
6083   u32 one_tag = 0;
6084   u32 two_tags = 0;
6085   u32 dot1ad = 0;
6086   u32 exact_match = 0;
6087   u32 default_sub = 0;
6088   u32 outer_vlan_id_any = 0;
6089   u32 inner_vlan_id_any = 0;
6090   u32 tmp;
6091   u16 outer_vlan_id = 0;
6092   u16 inner_vlan_id = 0;
6093
6094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6095     {
6096       if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set = 1;
6098       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6099         sw_if_index_set = 1;
6100       else if (unformat (i, "sub_id %d", &sub_id))
6101         sub_id_set = 1;
6102       else if (unformat (i, "outer_vlan_id %d", &tmp))
6103         outer_vlan_id = tmp;
6104       else if (unformat (i, "inner_vlan_id %d", &tmp))
6105         inner_vlan_id = tmp;
6106
6107 #define _(a) else if (unformat (i, #a)) a = 1 ;
6108       foreach_create_subif_bit
6109 #undef _
6110         else
6111         {
6112           clib_warning ("parse error '%U'", format_unformat_error, i);
6113           return -99;
6114         }
6115     }
6116
6117   if (sw_if_index_set == 0)
6118     {
6119       errmsg ("missing interface name or sw_if_index\n");
6120       return -99;
6121     }
6122
6123   if (sub_id_set == 0)
6124     {
6125       errmsg ("missing sub_id\n");
6126       return -99;
6127     }
6128   M (CREATE_SUBIF, create_subif);
6129
6130   mp->sw_if_index = ntohl (sw_if_index);
6131   mp->sub_id = ntohl (sub_id);
6132
6133 #define _(a) mp->a = a;
6134   foreach_create_subif_bit;
6135 #undef _
6136
6137   mp->outer_vlan_id = ntohs (outer_vlan_id);
6138   mp->inner_vlan_id = ntohs (inner_vlan_id);
6139
6140   S;
6141   W;
6142   /* NOTREACHED */
6143   return 0;
6144 }
6145
6146 static int
6147 api_oam_add_del (vat_main_t * vam)
6148 {
6149   unformat_input_t *i = vam->input;
6150   vl_api_oam_add_del_t *mp;
6151   f64 timeout;
6152   u32 vrf_id = 0;
6153   u8 is_add = 1;
6154   ip4_address_t src, dst;
6155   u8 src_set = 0;
6156   u8 dst_set = 0;
6157
6158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6159     {
6160       if (unformat (i, "vrf %d", &vrf_id))
6161         ;
6162       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6163         src_set = 1;
6164       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6165         dst_set = 1;
6166       else if (unformat (i, "del"))
6167         is_add = 0;
6168       else
6169         {
6170           clib_warning ("parse error '%U'", format_unformat_error, i);
6171           return -99;
6172         }
6173     }
6174
6175   if (src_set == 0)
6176     {
6177       errmsg ("missing src addr\n");
6178       return -99;
6179     }
6180
6181   if (dst_set == 0)
6182     {
6183       errmsg ("missing dst addr\n");
6184       return -99;
6185     }
6186
6187   M (OAM_ADD_DEL, oam_add_del);
6188
6189   mp->vrf_id = ntohl (vrf_id);
6190   mp->is_add = is_add;
6191   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6192   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6193
6194   S;
6195   W;
6196   /* NOTREACHED */
6197   return 0;
6198 }
6199
6200 static int
6201 api_reset_fib (vat_main_t * vam)
6202 {
6203   unformat_input_t *i = vam->input;
6204   vl_api_reset_fib_t *mp;
6205   f64 timeout;
6206   u32 vrf_id = 0;
6207   u8 is_ipv6 = 0;
6208   u8 vrf_id_set = 0;
6209
6210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6211     {
6212       if (unformat (i, "vrf %d", &vrf_id))
6213         vrf_id_set = 1;
6214       else if (unformat (i, "ipv6"))
6215         is_ipv6 = 1;
6216       else
6217         {
6218           clib_warning ("parse error '%U'", format_unformat_error, i);
6219           return -99;
6220         }
6221     }
6222
6223   if (vrf_id_set == 0)
6224     {
6225       errmsg ("missing vrf id\n");
6226       return -99;
6227     }
6228
6229   M (RESET_FIB, reset_fib);
6230
6231   mp->vrf_id = ntohl (vrf_id);
6232   mp->is_ipv6 = is_ipv6;
6233
6234   S;
6235   W;
6236   /* NOTREACHED */
6237   return 0;
6238 }
6239
6240 static int
6241 api_dhcp_proxy_config (vat_main_t * vam)
6242 {
6243   unformat_input_t *i = vam->input;
6244   vl_api_dhcp_proxy_config_t *mp;
6245   f64 timeout;
6246   u32 vrf_id = 0;
6247   u8 is_add = 1;
6248   u8 insert_cid = 1;
6249   u8 v4_address_set = 0;
6250   u8 v6_address_set = 0;
6251   ip4_address_t v4address;
6252   ip6_address_t v6address;
6253   u8 v4_src_address_set = 0;
6254   u8 v6_src_address_set = 0;
6255   ip4_address_t v4srcaddress;
6256   ip6_address_t v6srcaddress;
6257
6258   /* Parse args required to build the message */
6259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6260     {
6261       if (unformat (i, "del"))
6262         is_add = 0;
6263       else if (unformat (i, "vrf %d", &vrf_id))
6264         ;
6265       else if (unformat (i, "insert-cid %d", &insert_cid))
6266         ;
6267       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6268         v4_address_set = 1;
6269       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6270         v6_address_set = 1;
6271       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6272         v4_src_address_set = 1;
6273       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6274         v6_src_address_set = 1;
6275       else
6276         break;
6277     }
6278
6279   if (v4_address_set && v6_address_set)
6280     {
6281       errmsg ("both v4 and v6 server addresses set\n");
6282       return -99;
6283     }
6284   if (!v4_address_set && !v6_address_set)
6285     {
6286       errmsg ("no server addresses set\n");
6287       return -99;
6288     }
6289
6290   if (v4_src_address_set && v6_src_address_set)
6291     {
6292       errmsg ("both v4 and v6  src addresses set\n");
6293       return -99;
6294     }
6295   if (!v4_src_address_set && !v6_src_address_set)
6296     {
6297       errmsg ("no src addresses set\n");
6298       return -99;
6299     }
6300
6301   if (!(v4_src_address_set && v4_address_set) &&
6302       !(v6_src_address_set && v6_address_set))
6303     {
6304       errmsg ("no matching server and src addresses set\n");
6305       return -99;
6306     }
6307
6308   /* Construct the API message */
6309   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6310
6311   mp->insert_circuit_id = insert_cid;
6312   mp->is_add = is_add;
6313   mp->vrf_id = ntohl (vrf_id);
6314   if (v6_address_set)
6315     {
6316       mp->is_ipv6 = 1;
6317       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6318       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6319     }
6320   else
6321     {
6322       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6323       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6324     }
6325
6326   /* send it... */
6327   S;
6328
6329   /* Wait for a reply, return good/bad news  */
6330   W;
6331   /* NOTREACHED */
6332   return 0;
6333 }
6334
6335 static int
6336 api_dhcp_proxy_config_2 (vat_main_t * vam)
6337 {
6338   unformat_input_t *i = vam->input;
6339   vl_api_dhcp_proxy_config_2_t *mp;
6340   f64 timeout;
6341   u32 rx_vrf_id = 0;
6342   u32 server_vrf_id = 0;
6343   u8 is_add = 1;
6344   u8 insert_cid = 1;
6345   u8 v4_address_set = 0;
6346   u8 v6_address_set = 0;
6347   ip4_address_t v4address;
6348   ip6_address_t v6address;
6349   u8 v4_src_address_set = 0;
6350   u8 v6_src_address_set = 0;
6351   ip4_address_t v4srcaddress;
6352   ip6_address_t v6srcaddress;
6353
6354   /* Parse args required to build the message */
6355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6356     {
6357       if (unformat (i, "del"))
6358         is_add = 0;
6359       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6360         ;
6361       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6362         ;
6363       else if (unformat (i, "insert-cid %d", &insert_cid))
6364         ;
6365       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6366         v4_address_set = 1;
6367       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6368         v6_address_set = 1;
6369       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6370         v4_src_address_set = 1;
6371       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6372         v6_src_address_set = 1;
6373       else
6374         break;
6375     }
6376
6377   if (v4_address_set && v6_address_set)
6378     {
6379       errmsg ("both v4 and v6 server addresses set\n");
6380       return -99;
6381     }
6382   if (!v4_address_set && !v6_address_set)
6383     {
6384       errmsg ("no server addresses set\n");
6385       return -99;
6386     }
6387
6388   if (v4_src_address_set && v6_src_address_set)
6389     {
6390       errmsg ("both v4 and v6  src addresses set\n");
6391       return -99;
6392     }
6393   if (!v4_src_address_set && !v6_src_address_set)
6394     {
6395       errmsg ("no src addresses set\n");
6396       return -99;
6397     }
6398
6399   if (!(v4_src_address_set && v4_address_set) &&
6400       !(v6_src_address_set && v6_address_set))
6401     {
6402       errmsg ("no matching server and src addresses set\n");
6403       return -99;
6404     }
6405
6406   /* Construct the API message */
6407   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6408
6409   mp->insert_circuit_id = insert_cid;
6410   mp->is_add = is_add;
6411   mp->rx_vrf_id = ntohl (rx_vrf_id);
6412   mp->server_vrf_id = ntohl (server_vrf_id);
6413   if (v6_address_set)
6414     {
6415       mp->is_ipv6 = 1;
6416       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6417       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6418     }
6419   else
6420     {
6421       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6422       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6423     }
6424
6425   /* send it... */
6426   S;
6427
6428   /* Wait for a reply, return good/bad news  */
6429   W;
6430   /* NOTREACHED */
6431   return 0;
6432 }
6433
6434 static int
6435 api_dhcp_proxy_set_vss (vat_main_t * vam)
6436 {
6437   unformat_input_t *i = vam->input;
6438   vl_api_dhcp_proxy_set_vss_t *mp;
6439   f64 timeout;
6440   u8 is_ipv6 = 0;
6441   u8 is_add = 1;
6442   u32 tbl_id;
6443   u8 tbl_id_set = 0;
6444   u32 oui;
6445   u8 oui_set = 0;
6446   u32 fib_id;
6447   u8 fib_id_set = 0;
6448
6449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450     {
6451       if (unformat (i, "tbl_id %d", &tbl_id))
6452         tbl_id_set = 1;
6453       if (unformat (i, "fib_id %d", &fib_id))
6454         fib_id_set = 1;
6455       if (unformat (i, "oui %d", &oui))
6456         oui_set = 1;
6457       else if (unformat (i, "ipv6"))
6458         is_ipv6 = 1;
6459       else if (unformat (i, "del"))
6460         is_add = 0;
6461       else
6462         {
6463           clib_warning ("parse error '%U'", format_unformat_error, i);
6464           return -99;
6465         }
6466     }
6467
6468   if (tbl_id_set == 0)
6469     {
6470       errmsg ("missing tbl id\n");
6471       return -99;
6472     }
6473
6474   if (fib_id_set == 0)
6475     {
6476       errmsg ("missing fib id\n");
6477       return -99;
6478     }
6479   if (oui_set == 0)
6480     {
6481       errmsg ("missing oui\n");
6482       return -99;
6483     }
6484
6485   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6486   mp->tbl_id = ntohl (tbl_id);
6487   mp->fib_id = ntohl (fib_id);
6488   mp->oui = ntohl (oui);
6489   mp->is_ipv6 = is_ipv6;
6490   mp->is_add = is_add;
6491
6492   S;
6493   W;
6494   /* NOTREACHED */
6495   return 0;
6496 }
6497
6498 static int
6499 api_dhcp_client_config (vat_main_t * vam)
6500 {
6501   unformat_input_t *i = vam->input;
6502   vl_api_dhcp_client_config_t *mp;
6503   f64 timeout;
6504   u32 sw_if_index;
6505   u8 sw_if_index_set = 0;
6506   u8 is_add = 1;
6507   u8 *hostname = 0;
6508   u8 disable_event = 0;
6509
6510   /* Parse args required to build the message */
6511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6512     {
6513       if (unformat (i, "del"))
6514         is_add = 0;
6515       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6516         sw_if_index_set = 1;
6517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6518         sw_if_index_set = 1;
6519       else if (unformat (i, "hostname %s", &hostname))
6520         ;
6521       else if (unformat (i, "disable_event"))
6522         disable_event = 1;
6523       else
6524         break;
6525     }
6526
6527   if (sw_if_index_set == 0)
6528     {
6529       errmsg ("missing interface name or sw_if_index\n");
6530       return -99;
6531     }
6532
6533   if (vec_len (hostname) > 63)
6534     {
6535       errmsg ("hostname too long\n");
6536     }
6537   vec_add1 (hostname, 0);
6538
6539   /* Construct the API message */
6540   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6541
6542   mp->sw_if_index = ntohl (sw_if_index);
6543   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6544   vec_free (hostname);
6545   mp->is_add = is_add;
6546   mp->want_dhcp_event = disable_event ? 0 : 1;
6547   mp->pid = getpid ();
6548
6549   /* send it... */
6550   S;
6551
6552   /* Wait for a reply, return good/bad news  */
6553   W;
6554   /* NOTREACHED */
6555   return 0;
6556 }
6557
6558 static int
6559 api_set_ip_flow_hash (vat_main_t * vam)
6560 {
6561   unformat_input_t *i = vam->input;
6562   vl_api_set_ip_flow_hash_t *mp;
6563   f64 timeout;
6564   u32 vrf_id = 0;
6565   u8 is_ipv6 = 0;
6566   u8 vrf_id_set = 0;
6567   u8 src = 0;
6568   u8 dst = 0;
6569   u8 sport = 0;
6570   u8 dport = 0;
6571   u8 proto = 0;
6572   u8 reverse = 0;
6573
6574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6575     {
6576       if (unformat (i, "vrf %d", &vrf_id))
6577         vrf_id_set = 1;
6578       else if (unformat (i, "ipv6"))
6579         is_ipv6 = 1;
6580       else if (unformat (i, "src"))
6581         src = 1;
6582       else if (unformat (i, "dst"))
6583         dst = 1;
6584       else if (unformat (i, "sport"))
6585         sport = 1;
6586       else if (unformat (i, "dport"))
6587         dport = 1;
6588       else if (unformat (i, "proto"))
6589         proto = 1;
6590       else if (unformat (i, "reverse"))
6591         reverse = 1;
6592
6593       else
6594         {
6595           clib_warning ("parse error '%U'", format_unformat_error, i);
6596           return -99;
6597         }
6598     }
6599
6600   if (vrf_id_set == 0)
6601     {
6602       errmsg ("missing vrf id\n");
6603       return -99;
6604     }
6605
6606   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6607   mp->src = src;
6608   mp->dst = dst;
6609   mp->sport = sport;
6610   mp->dport = dport;
6611   mp->proto = proto;
6612   mp->reverse = reverse;
6613   mp->vrf_id = ntohl (vrf_id);
6614   mp->is_ipv6 = is_ipv6;
6615
6616   S;
6617   W;
6618   /* NOTREACHED */
6619   return 0;
6620 }
6621
6622 static int
6623 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6624 {
6625   unformat_input_t *i = vam->input;
6626   vl_api_sw_interface_ip6_enable_disable_t *mp;
6627   f64 timeout;
6628   u32 sw_if_index;
6629   u8 sw_if_index_set = 0;
6630   u8 enable = 0;
6631
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6635         sw_if_index_set = 1;
6636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6637         sw_if_index_set = 1;
6638       else if (unformat (i, "enable"))
6639         enable = 1;
6640       else if (unformat (i, "disable"))
6641         enable = 0;
6642       else
6643         {
6644           clib_warning ("parse error '%U'", format_unformat_error, i);
6645           return -99;
6646         }
6647     }
6648
6649   if (sw_if_index_set == 0)
6650     {
6651       errmsg ("missing interface name or sw_if_index\n");
6652       return -99;
6653     }
6654
6655   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6656
6657   mp->sw_if_index = ntohl (sw_if_index);
6658   mp->enable = enable;
6659
6660   S;
6661   W;
6662   /* NOTREACHED */
6663   return 0;
6664 }
6665
6666 static int
6667 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6668 {
6669   unformat_input_t *i = vam->input;
6670   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6671   f64 timeout;
6672   u32 sw_if_index;
6673   u8 sw_if_index_set = 0;
6674   u32 address_length = 0;
6675   u8 v6_address_set = 0;
6676   ip6_address_t v6address;
6677
6678   /* Parse args required to build the message */
6679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6680     {
6681       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6682         sw_if_index_set = 1;
6683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6684         sw_if_index_set = 1;
6685       else if (unformat (i, "%U/%d",
6686                          unformat_ip6_address, &v6address, &address_length))
6687         v6_address_set = 1;
6688       else
6689         break;
6690     }
6691
6692   if (sw_if_index_set == 0)
6693     {
6694       errmsg ("missing interface name or sw_if_index\n");
6695       return -99;
6696     }
6697   if (!v6_address_set)
6698     {
6699       errmsg ("no address set\n");
6700       return -99;
6701     }
6702
6703   /* Construct the API message */
6704   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6705      sw_interface_ip6_set_link_local_address);
6706
6707   mp->sw_if_index = ntohl (sw_if_index);
6708   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6709   mp->address_length = address_length;
6710
6711   /* send it... */
6712   S;
6713
6714   /* Wait for a reply, return good/bad news  */
6715   W;
6716
6717   /* NOTREACHED */
6718   return 0;
6719 }
6720
6721
6722 static int
6723 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6724 {
6725   unformat_input_t *i = vam->input;
6726   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6727   f64 timeout;
6728   u32 sw_if_index;
6729   u8 sw_if_index_set = 0;
6730   u32 address_length = 0;
6731   u8 v6_address_set = 0;
6732   ip6_address_t v6address;
6733   u8 use_default = 0;
6734   u8 no_advertise = 0;
6735   u8 off_link = 0;
6736   u8 no_autoconfig = 0;
6737   u8 no_onlink = 0;
6738   u8 is_no = 0;
6739   u32 val_lifetime = 0;
6740   u32 pref_lifetime = 0;
6741
6742   /* Parse args required to build the message */
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "%U/%d",
6750                          unformat_ip6_address, &v6address, &address_length))
6751         v6_address_set = 1;
6752       else if (unformat (i, "val_life %d", &val_lifetime))
6753         ;
6754       else if (unformat (i, "pref_life %d", &pref_lifetime))
6755         ;
6756       else if (unformat (i, "def"))
6757         use_default = 1;
6758       else if (unformat (i, "noadv"))
6759         no_advertise = 1;
6760       else if (unformat (i, "offl"))
6761         off_link = 1;
6762       else if (unformat (i, "noauto"))
6763         no_autoconfig = 1;
6764       else if (unformat (i, "nolink"))
6765         no_onlink = 1;
6766       else if (unformat (i, "isno"))
6767         is_no = 1;
6768       else
6769         {
6770           clib_warning ("parse error '%U'", format_unformat_error, i);
6771           return -99;
6772         }
6773     }
6774
6775   if (sw_if_index_set == 0)
6776     {
6777       errmsg ("missing interface name or sw_if_index\n");
6778       return -99;
6779     }
6780   if (!v6_address_set)
6781     {
6782       errmsg ("no address set\n");
6783       return -99;
6784     }
6785
6786   /* Construct the API message */
6787   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6788
6789   mp->sw_if_index = ntohl (sw_if_index);
6790   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6791   mp->address_length = address_length;
6792   mp->use_default = use_default;
6793   mp->no_advertise = no_advertise;
6794   mp->off_link = off_link;
6795   mp->no_autoconfig = no_autoconfig;
6796   mp->no_onlink = no_onlink;
6797   mp->is_no = is_no;
6798   mp->val_lifetime = ntohl (val_lifetime);
6799   mp->pref_lifetime = ntohl (pref_lifetime);
6800
6801   /* send it... */
6802   S;
6803
6804   /* Wait for a reply, return good/bad news  */
6805   W;
6806
6807   /* NOTREACHED */
6808   return 0;
6809 }
6810
6811 static int
6812 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6813 {
6814   unformat_input_t *i = vam->input;
6815   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6816   f64 timeout;
6817   u32 sw_if_index;
6818   u8 sw_if_index_set = 0;
6819   u8 suppress = 0;
6820   u8 managed = 0;
6821   u8 other = 0;
6822   u8 ll_option = 0;
6823   u8 send_unicast = 0;
6824   u8 cease = 0;
6825   u8 is_no = 0;
6826   u8 default_router = 0;
6827   u32 max_interval = 0;
6828   u32 min_interval = 0;
6829   u32 lifetime = 0;
6830   u32 initial_count = 0;
6831   u32 initial_interval = 0;
6832
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6838         sw_if_index_set = 1;
6839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6840         sw_if_index_set = 1;
6841       else if (unformat (i, "maxint %d", &max_interval))
6842         ;
6843       else if (unformat (i, "minint %d", &min_interval))
6844         ;
6845       else if (unformat (i, "life %d", &lifetime))
6846         ;
6847       else if (unformat (i, "count %d", &initial_count))
6848         ;
6849       else if (unformat (i, "interval %d", &initial_interval))
6850         ;
6851       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6852         suppress = 1;
6853       else if (unformat (i, "managed"))
6854         managed = 1;
6855       else if (unformat (i, "other"))
6856         other = 1;
6857       else if (unformat (i, "ll"))
6858         ll_option = 1;
6859       else if (unformat (i, "send"))
6860         send_unicast = 1;
6861       else if (unformat (i, "cease"))
6862         cease = 1;
6863       else if (unformat (i, "isno"))
6864         is_no = 1;
6865       else if (unformat (i, "def"))
6866         default_router = 1;
6867       else
6868         {
6869           clib_warning ("parse error '%U'", format_unformat_error, i);
6870           return -99;
6871         }
6872     }
6873
6874   if (sw_if_index_set == 0)
6875     {
6876       errmsg ("missing interface name or sw_if_index\n");
6877       return -99;
6878     }
6879
6880   /* Construct the API message */
6881   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6882
6883   mp->sw_if_index = ntohl (sw_if_index);
6884   mp->max_interval = ntohl (max_interval);
6885   mp->min_interval = ntohl (min_interval);
6886   mp->lifetime = ntohl (lifetime);
6887   mp->initial_count = ntohl (initial_count);
6888   mp->initial_interval = ntohl (initial_interval);
6889   mp->suppress = suppress;
6890   mp->managed = managed;
6891   mp->other = other;
6892   mp->ll_option = ll_option;
6893   mp->send_unicast = send_unicast;
6894   mp->cease = cease;
6895   mp->is_no = is_no;
6896   mp->default_router = default_router;
6897
6898   /* send it... */
6899   S;
6900
6901   /* Wait for a reply, return good/bad news  */
6902   W;
6903
6904   /* NOTREACHED */
6905   return 0;
6906 }
6907
6908 static int
6909 api_set_arp_neighbor_limit (vat_main_t * vam)
6910 {
6911   unformat_input_t *i = vam->input;
6912   vl_api_set_arp_neighbor_limit_t *mp;
6913   f64 timeout;
6914   u32 arp_nbr_limit;
6915   u8 limit_set = 0;
6916   u8 is_ipv6 = 0;
6917
6918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6919     {
6920       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6921         limit_set = 1;
6922       else if (unformat (i, "ipv6"))
6923         is_ipv6 = 1;
6924       else
6925         {
6926           clib_warning ("parse error '%U'", format_unformat_error, i);
6927           return -99;
6928         }
6929     }
6930
6931   if (limit_set == 0)
6932     {
6933       errmsg ("missing limit value\n");
6934       return -99;
6935     }
6936
6937   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6938
6939   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
6940   mp->is_ipv6 = is_ipv6;
6941
6942   S;
6943   W;
6944   /* NOTREACHED */
6945   return 0;
6946 }
6947
6948 static int
6949 api_l2_patch_add_del (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_l2_patch_add_del_t *mp;
6953   f64 timeout;
6954   u32 rx_sw_if_index;
6955   u8 rx_sw_if_index_set = 0;
6956   u32 tx_sw_if_index;
6957   u8 tx_sw_if_index_set = 0;
6958   u8 is_add = 1;
6959
6960   /* Parse args required to build the message */
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6964         rx_sw_if_index_set = 1;
6965       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6966         tx_sw_if_index_set = 1;
6967       else if (unformat (i, "rx"))
6968         {
6969           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6970             {
6971               if (unformat (i, "%U", unformat_sw_if_index, vam,
6972                             &rx_sw_if_index))
6973                 rx_sw_if_index_set = 1;
6974             }
6975           else
6976             break;
6977         }
6978       else if (unformat (i, "tx"))
6979         {
6980           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6981             {
6982               if (unformat (i, "%U", unformat_sw_if_index, vam,
6983                             &tx_sw_if_index))
6984                 tx_sw_if_index_set = 1;
6985             }
6986           else
6987             break;
6988         }
6989       else if (unformat (i, "del"))
6990         is_add = 0;
6991       else
6992         break;
6993     }
6994
6995   if (rx_sw_if_index_set == 0)
6996     {
6997       errmsg ("missing rx interface name or rx_sw_if_index\n");
6998       return -99;
6999     }
7000
7001   if (tx_sw_if_index_set == 0)
7002     {
7003       errmsg ("missing tx interface name or tx_sw_if_index\n");
7004       return -99;
7005     }
7006
7007   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7008
7009   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7010   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7011   mp->is_add = is_add;
7012
7013   S;
7014   W;
7015   /* NOTREACHED */
7016   return 0;
7017 }
7018
7019 static int
7020 api_trace_profile_add (vat_main_t * vam)
7021 {
7022   unformat_input_t *input = vam->input;
7023   vl_api_trace_profile_add_t *mp;
7024   f64 timeout;
7025   u32 id = 0;
7026   u32 trace_option_elts = 0;
7027   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7028   int has_pow_option = 0;
7029   int has_ppc_option = 0;
7030
7031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7032     {
7033       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7034                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7035                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7036                     &node_id, &app_data))
7037         ;
7038       else if (unformat (input, "pow"))
7039         has_pow_option = 1;
7040       else if (unformat (input, "ppc encap"))
7041         has_ppc_option = PPC_ENCAP;
7042       else if (unformat (input, "ppc decap"))
7043         has_ppc_option = PPC_DECAP;
7044       else if (unformat (input, "ppc none"))
7045         has_ppc_option = PPC_NONE;
7046       else
7047         break;
7048     }
7049   M (TRACE_PROFILE_ADD, trace_profile_add);
7050   mp->id = htons (id);
7051   mp->trace_type = trace_type;
7052   mp->trace_num_elt = trace_option_elts;
7053   mp->trace_ppc = has_ppc_option;
7054   mp->trace_app_data = htonl (app_data);
7055   mp->pow_enable = has_pow_option;
7056   mp->trace_tsp = trace_tsp;
7057   mp->node_id = htonl (node_id);
7058
7059   S;
7060   W;
7061
7062   return (0);
7063
7064 }
7065
7066 static int
7067 api_trace_profile_apply (vat_main_t * vam)
7068 {
7069   unformat_input_t *input = vam->input;
7070   vl_api_trace_profile_apply_t *mp;
7071   f64 timeout;
7072   ip6_address_t addr;
7073   u32 mask_width = ~0;
7074   int is_add = 0;
7075   int is_pop = 0;
7076   int is_none = 0;
7077   u32 vrf_id = 0;
7078   u32 id = 0;
7079
7080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7081     {
7082       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7083         ;
7084       else if (unformat (input, "id %d", &id))
7085         ;
7086       else if (unformat (input, "vrf-id %d", &vrf_id))
7087         ;
7088       else if (unformat (input, "add"))
7089         is_add = 1;
7090       else if (unformat (input, "pop"))
7091         is_pop = 1;
7092       else if (unformat (input, "none"))
7093         is_none = 1;
7094       else
7095         break;
7096     }
7097
7098   if ((is_add + is_pop + is_none) != 1)
7099     {
7100       errmsg ("One of (add, pop, none) required");
7101       return -99;
7102     }
7103   if (mask_width == ~0)
7104     {
7105       errmsg ("<address>/<mask-width> required");
7106       return -99;
7107     }
7108   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7109   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7110   mp->id = htons (id);
7111   mp->prefix_length = htonl (mask_width);
7112   mp->vrf_id = htonl (vrf_id);
7113   if (is_add)
7114     mp->trace_op = IOAM_HBYH_ADD;
7115   else if (is_pop)
7116     mp->trace_op = IOAM_HBYH_POP;
7117   else
7118     mp->trace_op = IOAM_HBYH_MOD;
7119
7120   if (is_none)
7121     mp->enable = 0;
7122   else
7123     mp->enable = 1;
7124
7125   S;
7126   W;
7127
7128   return 0;
7129 }
7130
7131 static int
7132 api_trace_profile_del (vat_main_t * vam)
7133 {
7134   vl_api_trace_profile_del_t *mp;
7135   f64 timeout;
7136
7137   M (TRACE_PROFILE_DEL, trace_profile_del);
7138   S;
7139   W;
7140   return 0;
7141 }
7142
7143 static int
7144 api_sr_tunnel_add_del (vat_main_t * vam)
7145 {
7146   unformat_input_t *i = vam->input;
7147   vl_api_sr_tunnel_add_del_t *mp;
7148   f64 timeout;
7149   int is_del = 0;
7150   int pl_index;
7151   ip6_address_t src_address;
7152   int src_address_set = 0;
7153   ip6_address_t dst_address;
7154   u32 dst_mask_width;
7155   int dst_address_set = 0;
7156   u16 flags = 0;
7157   u32 rx_table_id = 0;
7158   u32 tx_table_id = 0;
7159   ip6_address_t *segments = 0;
7160   ip6_address_t *this_seg;
7161   ip6_address_t *tags = 0;
7162   ip6_address_t *this_tag;
7163   ip6_address_t next_address, tag;
7164   u8 *name = 0;
7165   u8 *policy_name = 0;
7166
7167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7168     {
7169       if (unformat (i, "del"))
7170         is_del = 1;
7171       else if (unformat (i, "name %s", &name))
7172         ;
7173       else if (unformat (i, "policy %s", &policy_name))
7174         ;
7175       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7176         ;
7177       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7178         ;
7179       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7180         src_address_set = 1;
7181       else if (unformat (i, "dst %U/%d",
7182                          unformat_ip6_address, &dst_address, &dst_mask_width))
7183         dst_address_set = 1;
7184       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7185         {
7186           vec_add2 (segments, this_seg, 1);
7187           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7188                        sizeof (*this_seg));
7189         }
7190       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7191         {
7192           vec_add2 (tags, this_tag, 1);
7193           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7194         }
7195       else if (unformat (i, "clean"))
7196         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7197       else if (unformat (i, "protected"))
7198         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7199       else if (unformat (i, "InPE %d", &pl_index))
7200         {
7201           if (pl_index <= 0 || pl_index > 4)
7202             {
7203             pl_index_range_error:
7204               errmsg ("pl index %d out of range\n", pl_index);
7205               return -99;
7206             }
7207           flags |=
7208             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7209         }
7210       else if (unformat (i, "EgPE %d", &pl_index))
7211         {
7212           if (pl_index <= 0 || pl_index > 4)
7213             goto pl_index_range_error;
7214           flags |=
7215             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7216         }
7217       else if (unformat (i, "OrgSrc %d", &pl_index))
7218         {
7219           if (pl_index <= 0 || pl_index > 4)
7220             goto pl_index_range_error;
7221           flags |=
7222             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7223         }
7224       else
7225         break;
7226     }
7227
7228   if (!src_address_set)
7229     {
7230       errmsg ("src address required\n");
7231       return -99;
7232     }
7233
7234   if (!dst_address_set)
7235     {
7236       errmsg ("dst address required\n");
7237       return -99;
7238     }
7239
7240   if (!segments)
7241     {
7242       errmsg ("at least one sr segment required\n");
7243       return -99;
7244     }
7245
7246   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7247       vec_len (segments) * sizeof (ip6_address_t)
7248       + vec_len (tags) * sizeof (ip6_address_t));
7249
7250   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7251   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7252   mp->dst_mask_width = dst_mask_width;
7253   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7254   mp->n_segments = vec_len (segments);
7255   mp->n_tags = vec_len (tags);
7256   mp->is_add = is_del == 0;
7257   clib_memcpy (mp->segs_and_tags, segments,
7258                vec_len (segments) * sizeof (ip6_address_t));
7259   clib_memcpy (mp->segs_and_tags +
7260                vec_len (segments) * sizeof (ip6_address_t), tags,
7261                vec_len (tags) * sizeof (ip6_address_t));
7262
7263   mp->outer_vrf_id = ntohl (rx_table_id);
7264   mp->inner_vrf_id = ntohl (tx_table_id);
7265   memcpy (mp->name, name, vec_len (name));
7266   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7267
7268   vec_free (segments);
7269   vec_free (tags);
7270
7271   S;
7272   W;
7273   /* NOTREACHED */
7274 }
7275
7276 static int
7277 api_sr_policy_add_del (vat_main_t * vam)
7278 {
7279   unformat_input_t *input = vam->input;
7280   vl_api_sr_policy_add_del_t *mp;
7281   f64 timeout;
7282   int is_del = 0;
7283   u8 *name = 0;
7284   u8 *tunnel_name = 0;
7285   u8 **tunnel_names = 0;
7286
7287   int name_set = 0;
7288   int tunnel_set = 0;
7289   int j = 0;
7290   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7291   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7292
7293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (input, "del"))
7296         is_del = 1;
7297       else if (unformat (input, "name %s", &name))
7298         name_set = 1;
7299       else if (unformat (input, "tunnel %s", &tunnel_name))
7300         {
7301           if (tunnel_name)
7302             {
7303               vec_add1 (tunnel_names, tunnel_name);
7304               /* For serializer:
7305                  - length = #bytes to store in serial vector
7306                  - +1 = byte to store that length
7307                */
7308               tunnel_names_length += (vec_len (tunnel_name) + 1);
7309               tunnel_set = 1;
7310               tunnel_name = 0;
7311             }
7312         }
7313       else
7314         break;
7315     }
7316
7317   if (!name_set)
7318     {
7319       errmsg ("policy name required\n");
7320       return -99;
7321     }
7322
7323   if ((!tunnel_set) && (!is_del))
7324     {
7325       errmsg ("tunnel name required\n");
7326       return -99;
7327     }
7328
7329   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7330
7331
7332
7333   mp->is_add = !is_del;
7334
7335   memcpy (mp->name, name, vec_len (name));
7336   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7337   u8 *serial_orig = 0;
7338   vec_validate (serial_orig, tunnel_names_length);
7339   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7340   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7341
7342   for (j = 0; j < vec_len (tunnel_names); j++)
7343     {
7344       tun_name_len = vec_len (tunnel_names[j]);
7345       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7346       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7347       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7348       serial_orig += tun_name_len;      // Advance past the copy
7349     }
7350   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7351
7352   vec_free (tunnel_names);
7353   vec_free (tunnel_name);
7354
7355   S;
7356   W;
7357   /* NOTREACHED */
7358 }
7359
7360 static int
7361 api_sr_multicast_map_add_del (vat_main_t * vam)
7362 {
7363   unformat_input_t *input = vam->input;
7364   vl_api_sr_multicast_map_add_del_t *mp;
7365   f64 timeout;
7366   int is_del = 0;
7367   ip6_address_t multicast_address;
7368   u8 *policy_name = 0;
7369   int multicast_address_set = 0;
7370
7371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (input, "del"))
7374         is_del = 1;
7375       else
7376         if (unformat
7377             (input, "address %U", unformat_ip6_address, &multicast_address))
7378         multicast_address_set = 1;
7379       else if (unformat (input, "sr-policy %s", &policy_name))
7380         ;
7381       else
7382         break;
7383     }
7384
7385   if (!is_del && !policy_name)
7386     {
7387       errmsg ("sr-policy name required\n");
7388       return -99;
7389     }
7390
7391
7392   if (!multicast_address_set)
7393     {
7394       errmsg ("address required\n");
7395       return -99;
7396     }
7397
7398   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7399
7400   mp->is_add = !is_del;
7401   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7402   clib_memcpy (mp->multicast_address, &multicast_address,
7403                sizeof (mp->multicast_address));
7404
7405
7406   vec_free (policy_name);
7407
7408   S;
7409   W;
7410   /* NOTREACHED */
7411 }
7412
7413
7414 #define foreach_ip4_proto_field                 \
7415 _(src_address)                                  \
7416 _(dst_address)                                  \
7417 _(tos)                                          \
7418 _(length)                                       \
7419 _(fragment_id)                                  \
7420 _(ttl)                                          \
7421 _(protocol)                                     \
7422 _(checksum)
7423
7424 uword
7425 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7426 {
7427   u8 **maskp = va_arg (*args, u8 **);
7428   u8 *mask = 0;
7429   u8 found_something = 0;
7430   ip4_header_t *ip;
7431
7432 #define _(a) u8 a=0;
7433   foreach_ip4_proto_field;
7434 #undef _
7435   u8 version = 0;
7436   u8 hdr_length = 0;
7437
7438
7439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7440     {
7441       if (unformat (input, "version"))
7442         version = 1;
7443       else if (unformat (input, "hdr_length"))
7444         hdr_length = 1;
7445       else if (unformat (input, "src"))
7446         src_address = 1;
7447       else if (unformat (input, "dst"))
7448         dst_address = 1;
7449       else if (unformat (input, "proto"))
7450         protocol = 1;
7451
7452 #define _(a) else if (unformat (input, #a)) a=1;
7453       foreach_ip4_proto_field
7454 #undef _
7455         else
7456         break;
7457     }
7458
7459 #define _(a) found_something += a;
7460   foreach_ip4_proto_field;
7461 #undef _
7462
7463   if (found_something == 0)
7464     return 0;
7465
7466   vec_validate (mask, sizeof (*ip) - 1);
7467
7468   ip = (ip4_header_t *) mask;
7469
7470 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7471   foreach_ip4_proto_field;
7472 #undef _
7473
7474   ip->ip_version_and_header_length = 0;
7475
7476   if (version)
7477     ip->ip_version_and_header_length |= 0xF0;
7478
7479   if (hdr_length)
7480     ip->ip_version_and_header_length |= 0x0F;
7481
7482   *maskp = mask;
7483   return 1;
7484 }
7485
7486 #define foreach_ip6_proto_field                 \
7487 _(src_address)                                  \
7488 _(dst_address)                                  \
7489 _(payload_length)                               \
7490 _(hop_limit)                                    \
7491 _(protocol)
7492
7493 uword
7494 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7495 {
7496   u8 **maskp = va_arg (*args, u8 **);
7497   u8 *mask = 0;
7498   u8 found_something = 0;
7499   ip6_header_t *ip;
7500   u32 ip_version_traffic_class_and_flow_label;
7501
7502 #define _(a) u8 a=0;
7503   foreach_ip6_proto_field;
7504 #undef _
7505   u8 version = 0;
7506   u8 traffic_class = 0;
7507   u8 flow_label = 0;
7508
7509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7510     {
7511       if (unformat (input, "version"))
7512         version = 1;
7513       else if (unformat (input, "traffic-class"))
7514         traffic_class = 1;
7515       else if (unformat (input, "flow-label"))
7516         flow_label = 1;
7517       else if (unformat (input, "src"))
7518         src_address = 1;
7519       else if (unformat (input, "dst"))
7520         dst_address = 1;
7521       else if (unformat (input, "proto"))
7522         protocol = 1;
7523
7524 #define _(a) else if (unformat (input, #a)) a=1;
7525       foreach_ip6_proto_field
7526 #undef _
7527         else
7528         break;
7529     }
7530
7531 #define _(a) found_something += a;
7532   foreach_ip6_proto_field;
7533 #undef _
7534
7535   if (found_something == 0)
7536     return 0;
7537
7538   vec_validate (mask, sizeof (*ip) - 1);
7539
7540   ip = (ip6_header_t *) mask;
7541
7542 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7543   foreach_ip6_proto_field;
7544 #undef _
7545
7546   ip_version_traffic_class_and_flow_label = 0;
7547
7548   if (version)
7549     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7550
7551   if (traffic_class)
7552     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7553
7554   if (flow_label)
7555     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7556
7557   ip->ip_version_traffic_class_and_flow_label =
7558     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7559
7560   *maskp = mask;
7561   return 1;
7562 }
7563
7564 uword
7565 unformat_l3_mask (unformat_input_t * input, va_list * args)
7566 {
7567   u8 **maskp = va_arg (*args, u8 **);
7568
7569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7572         return 1;
7573       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7574         return 1;
7575       else
7576         break;
7577     }
7578   return 0;
7579 }
7580
7581 uword
7582 unformat_l2_mask (unformat_input_t * input, va_list * args)
7583 {
7584   u8 **maskp = va_arg (*args, u8 **);
7585   u8 *mask = 0;
7586   u8 src = 0;
7587   u8 dst = 0;
7588   u8 proto = 0;
7589   u8 tag1 = 0;
7590   u8 tag2 = 0;
7591   u8 ignore_tag1 = 0;
7592   u8 ignore_tag2 = 0;
7593   u8 cos1 = 0;
7594   u8 cos2 = 0;
7595   u8 dot1q = 0;
7596   u8 dot1ad = 0;
7597   int len = 14;
7598
7599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7600     {
7601       if (unformat (input, "src"))
7602         src = 1;
7603       else if (unformat (input, "dst"))
7604         dst = 1;
7605       else if (unformat (input, "proto"))
7606         proto = 1;
7607       else if (unformat (input, "tag1"))
7608         tag1 = 1;
7609       else if (unformat (input, "tag2"))
7610         tag2 = 1;
7611       else if (unformat (input, "ignore-tag1"))
7612         ignore_tag1 = 1;
7613       else if (unformat (input, "ignore-tag2"))
7614         ignore_tag2 = 1;
7615       else if (unformat (input, "cos1"))
7616         cos1 = 1;
7617       else if (unformat (input, "cos2"))
7618         cos2 = 1;
7619       else if (unformat (input, "dot1q"))
7620         dot1q = 1;
7621       else if (unformat (input, "dot1ad"))
7622         dot1ad = 1;
7623       else
7624         break;
7625     }
7626   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7627        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7628     return 0;
7629
7630   if (tag1 || ignore_tag1 || cos1 || dot1q)
7631     len = 18;
7632   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7633     len = 22;
7634
7635   vec_validate (mask, len - 1);
7636
7637   if (dst)
7638     memset (mask, 0xff, 6);
7639
7640   if (src)
7641     memset (mask + 6, 0xff, 6);
7642
7643   if (tag2 || dot1ad)
7644     {
7645       /* inner vlan tag */
7646       if (tag2)
7647         {
7648           mask[19] = 0xff;
7649           mask[18] = 0x0f;
7650         }
7651       if (cos2)
7652         mask[18] |= 0xe0;
7653       if (proto)
7654         mask[21] = mask[20] = 0xff;
7655       if (tag1)
7656         {
7657           mask[15] = 0xff;
7658           mask[14] = 0x0f;
7659         }
7660       if (cos1)
7661         mask[14] |= 0xe0;
7662       *maskp = mask;
7663       return 1;
7664     }
7665   if (tag1 | dot1q)
7666     {
7667       if (tag1)
7668         {
7669           mask[15] = 0xff;
7670           mask[14] = 0x0f;
7671         }
7672       if (cos1)
7673         mask[14] |= 0xe0;
7674       if (proto)
7675         mask[16] = mask[17] = 0xff;
7676
7677       *maskp = mask;
7678       return 1;
7679     }
7680   if (cos2)
7681     mask[18] |= 0xe0;
7682   if (cos1)
7683     mask[14] |= 0xe0;
7684   if (proto)
7685     mask[12] = mask[13] = 0xff;
7686
7687   *maskp = mask;
7688   return 1;
7689 }
7690
7691 uword
7692 unformat_classify_mask (unformat_input_t * input, va_list * args)
7693 {
7694   u8 **maskp = va_arg (*args, u8 **);
7695   u32 *skipp = va_arg (*args, u32 *);
7696   u32 *matchp = va_arg (*args, u32 *);
7697   u32 match;
7698   u8 *mask = 0;
7699   u8 *l2 = 0;
7700   u8 *l3 = 0;
7701   int i;
7702
7703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7704     {
7705       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7706         ;
7707       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7708         ;
7709       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7710         ;
7711       else
7712         break;
7713     }
7714
7715   if (mask || l2 || l3)
7716     {
7717       if (l2 || l3)
7718         {
7719           /* "With a free Ethernet header in every package" */
7720           if (l2 == 0)
7721             vec_validate (l2, 13);
7722           mask = l2;
7723           if (vec_len (l3))
7724             {
7725               vec_append (mask, l3);
7726               vec_free (l3);
7727             }
7728         }
7729
7730       /* Scan forward looking for the first significant mask octet */
7731       for (i = 0; i < vec_len (mask); i++)
7732         if (mask[i])
7733           break;
7734
7735       /* compute (skip, match) params */
7736       *skipp = i / sizeof (u32x4);
7737       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7738
7739       /* Pad mask to an even multiple of the vector size */
7740       while (vec_len (mask) % sizeof (u32x4))
7741         vec_add1 (mask, 0);
7742
7743       match = vec_len (mask) / sizeof (u32x4);
7744
7745       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7746         {
7747           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7748           if (*tmp || *(tmp + 1))
7749             break;
7750           match--;
7751         }
7752       if (match == 0)
7753         clib_warning ("BUG: match 0");
7754
7755       _vec_len (mask) = match * sizeof (u32x4);
7756
7757       *matchp = match;
7758       *maskp = mask;
7759
7760       return 1;
7761     }
7762
7763   return 0;
7764 }
7765
7766 #define foreach_l2_next                         \
7767 _(drop, DROP)                                   \
7768 _(ethernet, ETHERNET_INPUT)                     \
7769 _(ip4, IP4_INPUT)                               \
7770 _(ip6, IP6_INPUT)
7771
7772 uword
7773 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7774 {
7775   u32 *miss_next_indexp = va_arg (*args, u32 *);
7776   u32 next_index = 0;
7777   u32 tmp;
7778
7779 #define _(n,N) \
7780   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7781   foreach_l2_next;
7782 #undef _
7783
7784   if (unformat (input, "%d", &tmp))
7785     {
7786       next_index = tmp;
7787       goto out;
7788     }
7789
7790   return 0;
7791
7792 out:
7793   *miss_next_indexp = next_index;
7794   return 1;
7795 }
7796
7797 #define foreach_ip_next                         \
7798 _(miss, MISS)                                   \
7799 _(drop, DROP)                                   \
7800 _(local, LOCAL)                                 \
7801 _(rewrite, REWRITE)
7802
7803 uword
7804 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7805 {
7806   u32 *miss_next_indexp = va_arg (*args, u32 *);
7807   u32 next_index = 0;
7808   u32 tmp;
7809
7810 #define _(n,N) \
7811   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7812   foreach_ip_next;
7813 #undef _
7814
7815   if (unformat (input, "%d", &tmp))
7816     {
7817       next_index = tmp;
7818       goto out;
7819     }
7820
7821   return 0;
7822
7823 out:
7824   *miss_next_indexp = next_index;
7825   return 1;
7826 }
7827
7828 #define foreach_acl_next                        \
7829 _(deny, DENY)
7830
7831 uword
7832 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7833 {
7834   u32 *miss_next_indexp = va_arg (*args, u32 *);
7835   u32 next_index = 0;
7836   u32 tmp;
7837
7838 #define _(n,N) \
7839   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7840   foreach_acl_next;
7841 #undef _
7842
7843   if (unformat (input, "permit"))
7844     {
7845       next_index = ~0;
7846       goto out;
7847     }
7848   else if (unformat (input, "%d", &tmp))
7849     {
7850       next_index = tmp;
7851       goto out;
7852     }
7853
7854   return 0;
7855
7856 out:
7857   *miss_next_indexp = next_index;
7858   return 1;
7859 }
7860
7861 uword
7862 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7863 {
7864   u32 *r = va_arg (*args, u32 *);
7865
7866   if (unformat (input, "conform-color"))
7867     *r = POLICE_CONFORM;
7868   else if (unformat (input, "exceed-color"))
7869     *r = POLICE_EXCEED;
7870   else
7871     return 0;
7872
7873   return 1;
7874 }
7875
7876 static int
7877 api_classify_add_del_table (vat_main_t * vam)
7878 {
7879   unformat_input_t *i = vam->input;
7880   vl_api_classify_add_del_table_t *mp;
7881
7882   u32 nbuckets = 2;
7883   u32 skip = ~0;
7884   u32 match = ~0;
7885   int is_add = 1;
7886   u32 table_index = ~0;
7887   u32 next_table_index = ~0;
7888   u32 miss_next_index = ~0;
7889   u32 memory_size = 32 << 20;
7890   u8 *mask = 0;
7891   f64 timeout;
7892
7893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7894     {
7895       if (unformat (i, "del"))
7896         is_add = 0;
7897       else if (unformat (i, "buckets %d", &nbuckets))
7898         ;
7899       else if (unformat (i, "memory_size %d", &memory_size))
7900         ;
7901       else if (unformat (i, "skip %d", &skip))
7902         ;
7903       else if (unformat (i, "match %d", &match))
7904         ;
7905       else if (unformat (i, "table %d", &table_index))
7906         ;
7907       else if (unformat (i, "mask %U", unformat_classify_mask,
7908                          &mask, &skip, &match))
7909         ;
7910       else if (unformat (i, "next-table %d", &next_table_index))
7911         ;
7912       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7913                          &miss_next_index))
7914         ;
7915       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7916                          &miss_next_index))
7917         ;
7918       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7919                          &miss_next_index))
7920         ;
7921       else
7922         break;
7923     }
7924
7925   if (is_add && mask == 0)
7926     {
7927       errmsg ("Mask required\n");
7928       return -99;
7929     }
7930
7931   if (is_add && skip == ~0)
7932     {
7933       errmsg ("skip count required\n");
7934       return -99;
7935     }
7936
7937   if (is_add && match == ~0)
7938     {
7939       errmsg ("match count required\n");
7940       return -99;
7941     }
7942
7943   if (!is_add && table_index == ~0)
7944     {
7945       errmsg ("table index required for delete\n");
7946       return -99;
7947     }
7948
7949   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
7950
7951   mp->is_add = is_add;
7952   mp->table_index = ntohl (table_index);
7953   mp->nbuckets = ntohl (nbuckets);
7954   mp->memory_size = ntohl (memory_size);
7955   mp->skip_n_vectors = ntohl (skip);
7956   mp->match_n_vectors = ntohl (match);
7957   mp->next_table_index = ntohl (next_table_index);
7958   mp->miss_next_index = ntohl (miss_next_index);
7959   clib_memcpy (mp->mask, mask, vec_len (mask));
7960
7961   vec_free (mask);
7962
7963   S;
7964   W;
7965   /* NOTREACHED */
7966 }
7967
7968 uword
7969 unformat_ip4_match (unformat_input_t * input, va_list * args)
7970 {
7971   u8 **matchp = va_arg (*args, u8 **);
7972   u8 *match = 0;
7973   ip4_header_t *ip;
7974   int version = 0;
7975   u32 version_val;
7976   int hdr_length = 0;
7977   u32 hdr_length_val;
7978   int src = 0, dst = 0;
7979   ip4_address_t src_val, dst_val;
7980   int proto = 0;
7981   u32 proto_val;
7982   int tos = 0;
7983   u32 tos_val;
7984   int length = 0;
7985   u32 length_val;
7986   int fragment_id = 0;
7987   u32 fragment_id_val;
7988   int ttl = 0;
7989   int ttl_val;
7990   int checksum = 0;
7991   u32 checksum_val;
7992
7993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7994     {
7995       if (unformat (input, "version %d", &version_val))
7996         version = 1;
7997       else if (unformat (input, "hdr_length %d", &hdr_length_val))
7998         hdr_length = 1;
7999       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8000         src = 1;
8001       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8002         dst = 1;
8003       else if (unformat (input, "proto %d", &proto_val))
8004         proto = 1;
8005       else if (unformat (input, "tos %d", &tos_val))
8006         tos = 1;
8007       else if (unformat (input, "length %d", &length_val))
8008         length = 1;
8009       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8010         fragment_id = 1;
8011       else if (unformat (input, "ttl %d", &ttl_val))
8012         ttl = 1;
8013       else if (unformat (input, "checksum %d", &checksum_val))
8014         checksum = 1;
8015       else
8016         break;
8017     }
8018
8019   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8020       + ttl + checksum == 0)
8021     return 0;
8022
8023   /*
8024    * Aligned because we use the real comparison functions
8025    */
8026   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8027
8028   ip = (ip4_header_t *) match;
8029
8030   /* These are realistically matched in practice */
8031   if (src)
8032     ip->src_address.as_u32 = src_val.as_u32;
8033
8034   if (dst)
8035     ip->dst_address.as_u32 = dst_val.as_u32;
8036
8037   if (proto)
8038     ip->protocol = proto_val;
8039
8040
8041   /* These are not, but they're included for completeness */
8042   if (version)
8043     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8044
8045   if (hdr_length)
8046     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8047
8048   if (tos)
8049     ip->tos = tos_val;
8050
8051   if (length)
8052     ip->length = length_val;
8053
8054   if (ttl)
8055     ip->ttl = ttl_val;
8056
8057   if (checksum)
8058     ip->checksum = checksum_val;
8059
8060   *matchp = match;
8061   return 1;
8062 }
8063
8064 uword
8065 unformat_ip6_match (unformat_input_t * input, va_list * args)
8066 {
8067   u8 **matchp = va_arg (*args, u8 **);
8068   u8 *match = 0;
8069   ip6_header_t *ip;
8070   int version = 0;
8071   u32 version_val;
8072   u8 traffic_class = 0;
8073   u32 traffic_class_val = 0;
8074   u8 flow_label = 0;
8075   u8 flow_label_val;
8076   int src = 0, dst = 0;
8077   ip6_address_t src_val, dst_val;
8078   int proto = 0;
8079   u32 proto_val;
8080   int payload_length = 0;
8081   u32 payload_length_val;
8082   int hop_limit = 0;
8083   int hop_limit_val;
8084   u32 ip_version_traffic_class_and_flow_label;
8085
8086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8087     {
8088       if (unformat (input, "version %d", &version_val))
8089         version = 1;
8090       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8091         traffic_class = 1;
8092       else if (unformat (input, "flow_label %d", &flow_label_val))
8093         flow_label = 1;
8094       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8095         src = 1;
8096       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8097         dst = 1;
8098       else if (unformat (input, "proto %d", &proto_val))
8099         proto = 1;
8100       else if (unformat (input, "payload_length %d", &payload_length_val))
8101         payload_length = 1;
8102       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8103         hop_limit = 1;
8104       else
8105         break;
8106     }
8107
8108   if (version + traffic_class + flow_label + src + dst + proto +
8109       payload_length + hop_limit == 0)
8110     return 0;
8111
8112   /*
8113    * Aligned because we use the real comparison functions
8114    */
8115   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8116
8117   ip = (ip6_header_t *) match;
8118
8119   if (src)
8120     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8121
8122   if (dst)
8123     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8124
8125   if (proto)
8126     ip->protocol = proto_val;
8127
8128   ip_version_traffic_class_and_flow_label = 0;
8129
8130   if (version)
8131     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8132
8133   if (traffic_class)
8134     ip_version_traffic_class_and_flow_label |=
8135       (traffic_class_val & 0xFF) << 20;
8136
8137   if (flow_label)
8138     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8139
8140   ip->ip_version_traffic_class_and_flow_label =
8141     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8142
8143   if (payload_length)
8144     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8145
8146   if (hop_limit)
8147     ip->hop_limit = hop_limit_val;
8148
8149   *matchp = match;
8150   return 1;
8151 }
8152
8153 uword
8154 unformat_l3_match (unformat_input_t * input, va_list * args)
8155 {
8156   u8 **matchp = va_arg (*args, u8 **);
8157
8158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8159     {
8160       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8161         return 1;
8162       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8163         return 1;
8164       else
8165         break;
8166     }
8167   return 0;
8168 }
8169
8170 uword
8171 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8172 {
8173   u8 *tagp = va_arg (*args, u8 *);
8174   u32 tag;
8175
8176   if (unformat (input, "%d", &tag))
8177     {
8178       tagp[0] = (tag >> 8) & 0x0F;
8179       tagp[1] = tag & 0xFF;
8180       return 1;
8181     }
8182
8183   return 0;
8184 }
8185
8186 uword
8187 unformat_l2_match (unformat_input_t * input, va_list * args)
8188 {
8189   u8 **matchp = va_arg (*args, u8 **);
8190   u8 *match = 0;
8191   u8 src = 0;
8192   u8 src_val[6];
8193   u8 dst = 0;
8194   u8 dst_val[6];
8195   u8 proto = 0;
8196   u16 proto_val;
8197   u8 tag1 = 0;
8198   u8 tag1_val[2];
8199   u8 tag2 = 0;
8200   u8 tag2_val[2];
8201   int len = 14;
8202   u8 ignore_tag1 = 0;
8203   u8 ignore_tag2 = 0;
8204   u8 cos1 = 0;
8205   u8 cos2 = 0;
8206   u32 cos1_val = 0;
8207   u32 cos2_val = 0;
8208
8209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8210     {
8211       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8212         src = 1;
8213       else
8214         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8215         dst = 1;
8216       else if (unformat (input, "proto %U",
8217                          unformat_ethernet_type_host_byte_order, &proto_val))
8218         proto = 1;
8219       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8220         tag1 = 1;
8221       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8222         tag2 = 1;
8223       else if (unformat (input, "ignore-tag1"))
8224         ignore_tag1 = 1;
8225       else if (unformat (input, "ignore-tag2"))
8226         ignore_tag2 = 1;
8227       else if (unformat (input, "cos1 %d", &cos1_val))
8228         cos1 = 1;
8229       else if (unformat (input, "cos2 %d", &cos2_val))
8230         cos2 = 1;
8231       else
8232         break;
8233     }
8234   if ((src + dst + proto + tag1 + tag2 +
8235        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8236     return 0;
8237
8238   if (tag1 || ignore_tag1 || cos1)
8239     len = 18;
8240   if (tag2 || ignore_tag2 || cos2)
8241     len = 22;
8242
8243   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8244
8245   if (dst)
8246     clib_memcpy (match, dst_val, 6);
8247
8248   if (src)
8249     clib_memcpy (match + 6, src_val, 6);
8250
8251   if (tag2)
8252     {
8253       /* inner vlan tag */
8254       match[19] = tag2_val[1];
8255       match[18] = tag2_val[0];
8256       if (cos2)
8257         match[18] |= (cos2_val & 0x7) << 5;
8258       if (proto)
8259         {
8260           match[21] = proto_val & 0xff;
8261           match[20] = proto_val >> 8;
8262         }
8263       if (tag1)
8264         {
8265           match[15] = tag1_val[1];
8266           match[14] = tag1_val[0];
8267         }
8268       if (cos1)
8269         match[14] |= (cos1_val & 0x7) << 5;
8270       *matchp = match;
8271       return 1;
8272     }
8273   if (tag1)
8274     {
8275       match[15] = tag1_val[1];
8276       match[14] = tag1_val[0];
8277       if (proto)
8278         {
8279           match[17] = proto_val & 0xff;
8280           match[16] = proto_val >> 8;
8281         }
8282       if (cos1)
8283         match[14] |= (cos1_val & 0x7) << 5;
8284
8285       *matchp = match;
8286       return 1;
8287     }
8288   if (cos2)
8289     match[18] |= (cos2_val & 0x7) << 5;
8290   if (cos1)
8291     match[14] |= (cos1_val & 0x7) << 5;
8292   if (proto)
8293     {
8294       match[13] = proto_val & 0xff;
8295       match[12] = proto_val >> 8;
8296     }
8297
8298   *matchp = match;
8299   return 1;
8300 }
8301
8302
8303 uword
8304 unformat_classify_match (unformat_input_t * input, va_list * args)
8305 {
8306   u8 **matchp = va_arg (*args, u8 **);
8307   u32 skip_n_vectors = va_arg (*args, u32);
8308   u32 match_n_vectors = va_arg (*args, u32);
8309
8310   u8 *match = 0;
8311   u8 *l2 = 0;
8312   u8 *l3 = 0;
8313
8314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8315     {
8316       if (unformat (input, "hex %U", unformat_hex_string, &match))
8317         ;
8318       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8319         ;
8320       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8321         ;
8322       else
8323         break;
8324     }
8325
8326   if (match || l2 || l3)
8327     {
8328       if (l2 || l3)
8329         {
8330           /* "Win a free Ethernet header in every packet" */
8331           if (l2 == 0)
8332             vec_validate_aligned (l2, 13, sizeof (u32x4));
8333           match = l2;
8334           if (vec_len (l3))
8335             {
8336               vec_append_aligned (match, l3, sizeof (u32x4));
8337               vec_free (l3);
8338             }
8339         }
8340
8341       /* Make sure the vector is big enough even if key is all 0's */
8342       vec_validate_aligned
8343         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8344          sizeof (u32x4));
8345
8346       /* Set size, include skipped vectors */
8347       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8348
8349       *matchp = match;
8350
8351       return 1;
8352     }
8353
8354   return 0;
8355 }
8356
8357 static int
8358 api_classify_add_del_session (vat_main_t * vam)
8359 {
8360   unformat_input_t *i = vam->input;
8361   vl_api_classify_add_del_session_t *mp;
8362   int is_add = 1;
8363   u32 table_index = ~0;
8364   u32 hit_next_index = ~0;
8365   u32 opaque_index = ~0;
8366   u8 *match = 0;
8367   i32 advance = 0;
8368   f64 timeout;
8369   u32 skip_n_vectors = 0;
8370   u32 match_n_vectors = 0;
8371
8372   /*
8373    * Warning: you have to supply skip_n and match_n
8374    * because the API client cant simply look at the classify
8375    * table object.
8376    */
8377
8378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8379     {
8380       if (unformat (i, "del"))
8381         is_add = 0;
8382       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8383                          &hit_next_index))
8384         ;
8385       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8386                          &hit_next_index))
8387         ;
8388       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8389                          &hit_next_index))
8390         ;
8391       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8392         ;
8393       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8394         ;
8395       else if (unformat (i, "opaque-index %d", &opaque_index))
8396         ;
8397       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8398         ;
8399       else if (unformat (i, "match_n %d", &match_n_vectors))
8400         ;
8401       else if (unformat (i, "match %U", unformat_classify_match,
8402                          &match, skip_n_vectors, match_n_vectors))
8403         ;
8404       else if (unformat (i, "advance %d", &advance))
8405         ;
8406       else if (unformat (i, "table-index %d", &table_index))
8407         ;
8408       else
8409         break;
8410     }
8411
8412   if (table_index == ~0)
8413     {
8414       errmsg ("Table index required\n");
8415       return -99;
8416     }
8417
8418   if (is_add && match == 0)
8419     {
8420       errmsg ("Match value required\n");
8421       return -99;
8422     }
8423
8424   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8425
8426   mp->is_add = is_add;
8427   mp->table_index = ntohl (table_index);
8428   mp->hit_next_index = ntohl (hit_next_index);
8429   mp->opaque_index = ntohl (opaque_index);
8430   mp->advance = ntohl (advance);
8431   clib_memcpy (mp->match, match, vec_len (match));
8432   vec_free (match);
8433
8434   S;
8435   W;
8436   /* NOTREACHED */
8437 }
8438
8439 static int
8440 api_classify_set_interface_ip_table (vat_main_t * vam)
8441 {
8442   unformat_input_t *i = vam->input;
8443   vl_api_classify_set_interface_ip_table_t *mp;
8444   f64 timeout;
8445   u32 sw_if_index;
8446   int sw_if_index_set;
8447   u32 table_index = ~0;
8448   u8 is_ipv6 = 0;
8449
8450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8451     {
8452       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8453         sw_if_index_set = 1;
8454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8455         sw_if_index_set = 1;
8456       else if (unformat (i, "table %d", &table_index))
8457         ;
8458       else
8459         {
8460           clib_warning ("parse error '%U'", format_unformat_error, i);
8461           return -99;
8462         }
8463     }
8464
8465   if (sw_if_index_set == 0)
8466     {
8467       errmsg ("missing interface name or sw_if_index\n");
8468       return -99;
8469     }
8470
8471
8472   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8473
8474   mp->sw_if_index = ntohl (sw_if_index);
8475   mp->table_index = ntohl (table_index);
8476   mp->is_ipv6 = is_ipv6;
8477
8478   S;
8479   W;
8480   /* NOTREACHED */
8481   return 0;
8482 }
8483
8484 static int
8485 api_classify_set_interface_l2_tables (vat_main_t * vam)
8486 {
8487   unformat_input_t *i = vam->input;
8488   vl_api_classify_set_interface_l2_tables_t *mp;
8489   f64 timeout;
8490   u32 sw_if_index;
8491   int sw_if_index_set;
8492   u32 ip4_table_index = ~0;
8493   u32 ip6_table_index = ~0;
8494   u32 other_table_index = ~0;
8495
8496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8499         sw_if_index_set = 1;
8500       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8501         sw_if_index_set = 1;
8502       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8503         ;
8504       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8505         ;
8506       else if (unformat (i, "other-table %d", &other_table_index))
8507         ;
8508       else
8509         {
8510           clib_warning ("parse error '%U'", format_unformat_error, i);
8511           return -99;
8512         }
8513     }
8514
8515   if (sw_if_index_set == 0)
8516     {
8517       errmsg ("missing interface name or sw_if_index\n");
8518       return -99;
8519     }
8520
8521
8522   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8523
8524   mp->sw_if_index = ntohl (sw_if_index);
8525   mp->ip4_table_index = ntohl (ip4_table_index);
8526   mp->ip6_table_index = ntohl (ip6_table_index);
8527   mp->other_table_index = ntohl (other_table_index);
8528
8529
8530   S;
8531   W;
8532   /* NOTREACHED */
8533   return 0;
8534 }
8535
8536 static int
8537 api_ipfix_enable (vat_main_t * vam)
8538 {
8539   unformat_input_t *i = vam->input;
8540   vl_api_ipfix_enable_t *mp;
8541   ip4_address_t collector_address;
8542   u8 collector_address_set = 0;
8543   u32 collector_port = ~0;
8544   ip4_address_t src_address;
8545   u8 src_address_set = 0;
8546   u32 vrf_id = ~0;
8547   u32 path_mtu = ~0;
8548   u32 template_interval = ~0;
8549   f64 timeout;
8550
8551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8552     {
8553       if (unformat (i, "collector_address %U", unformat_ip4_address,
8554                     &collector_address))
8555         collector_address_set = 1;
8556       else if (unformat (i, "collector_port %d", &collector_port))
8557         ;
8558       else if (unformat (i, "src_address %U", unformat_ip4_address,
8559                          &src_address))
8560         src_address_set = 1;
8561       else if (unformat (i, "vrf_id %d", &vrf_id))
8562         ;
8563       else if (unformat (i, "path_mtu %d", &path_mtu))
8564         ;
8565       else if (unformat (i, "template_interval %d", &template_interval))
8566         ;
8567       else
8568         break;
8569     }
8570
8571   if (collector_address_set == 0)
8572     {
8573       errmsg ("collector_address required\n");
8574       return -99;
8575     }
8576
8577   if (src_address_set == 0)
8578     {
8579       errmsg ("src_address required\n");
8580       return -99;
8581     }
8582
8583   M (IPFIX_ENABLE, ipfix_enable);
8584
8585   memcpy (mp->collector_address, collector_address.data,
8586           sizeof (collector_address.data));
8587   mp->collector_port = htons ((u16) collector_port);
8588   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8589   mp->vrf_id = htonl (vrf_id);
8590   mp->path_mtu = htonl (path_mtu);
8591   mp->template_interval = htonl (template_interval);
8592
8593   S;
8594   W;
8595   /* NOTREACHED */
8596 }
8597
8598 static int
8599 api_get_node_index (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_get_node_index_t *mp;
8603   f64 timeout;
8604   u8 *name = 0;
8605
8606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8607     {
8608       if (unformat (i, "node %s", &name))
8609         ;
8610       else
8611         break;
8612     }
8613   if (name == 0)
8614     {
8615       errmsg ("node name required\n");
8616       return -99;
8617     }
8618   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8619     {
8620       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8621       return -99;
8622     }
8623
8624   M (GET_NODE_INDEX, get_node_index);
8625   clib_memcpy (mp->node_name, name, vec_len (name));
8626   vec_free (name);
8627
8628   S;
8629   W;
8630   /* NOTREACHED */
8631   return 0;
8632 }
8633
8634 static int
8635 api_get_next_index (vat_main_t * vam)
8636 {
8637   unformat_input_t *i = vam->input;
8638   vl_api_get_next_index_t *mp;
8639   f64 timeout;
8640   u8 *node_name = 0, *next_node_name = 0;
8641
8642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8643     {
8644       if (unformat (i, "node-name %s", &node_name))
8645         ;
8646       else if (unformat (i, "next-node-name %s", &next_node_name))
8647         break;
8648     }
8649
8650   if (node_name == 0)
8651     {
8652       errmsg ("node name required\n");
8653       return -99;
8654     }
8655   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8656     {
8657       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8658       return -99;
8659     }
8660
8661   if (next_node_name == 0)
8662     {
8663       errmsg ("next node name required\n");
8664       return -99;
8665     }
8666   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8667     {
8668       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8669       return -99;
8670     }
8671
8672   M (GET_NEXT_INDEX, get_next_index);
8673   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8674   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8675   vec_free (node_name);
8676   vec_free (next_node_name);
8677
8678   S;
8679   W;
8680   /* NOTREACHED */
8681   return 0;
8682 }
8683
8684 static int
8685 api_add_node_next (vat_main_t * vam)
8686 {
8687   unformat_input_t *i = vam->input;
8688   vl_api_add_node_next_t *mp;
8689   f64 timeout;
8690   u8 *name = 0;
8691   u8 *next = 0;
8692
8693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8694     {
8695       if (unformat (i, "node %s", &name))
8696         ;
8697       else if (unformat (i, "next %s", &next))
8698         ;
8699       else
8700         break;
8701     }
8702   if (name == 0)
8703     {
8704       errmsg ("node name required\n");
8705       return -99;
8706     }
8707   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8708     {
8709       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8710       return -99;
8711     }
8712   if (next == 0)
8713     {
8714       errmsg ("next node required\n");
8715       return -99;
8716     }
8717   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8718     {
8719       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8720       return -99;
8721     }
8722
8723   M (ADD_NODE_NEXT, add_node_next);
8724   clib_memcpy (mp->node_name, name, vec_len (name));
8725   clib_memcpy (mp->next_name, next, vec_len (next));
8726   vec_free (name);
8727   vec_free (next);
8728
8729   S;
8730   W;
8731   /* NOTREACHED */
8732   return 0;
8733 }
8734
8735 static int
8736 api_l2tpv3_create_tunnel (vat_main_t * vam)
8737 {
8738   unformat_input_t *i = vam->input;
8739   ip6_address_t client_address, our_address;
8740   int client_address_set = 0;
8741   int our_address_set = 0;
8742   u32 local_session_id = 0;
8743   u32 remote_session_id = 0;
8744   u64 local_cookie = 0;
8745   u64 remote_cookie = 0;
8746   u8 l2_sublayer_present = 0;
8747   vl_api_l2tpv3_create_tunnel_t *mp;
8748   f64 timeout;
8749
8750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8751     {
8752       if (unformat (i, "client_address %U", unformat_ip6_address,
8753                     &client_address))
8754         client_address_set = 1;
8755       else if (unformat (i, "our_address %U", unformat_ip6_address,
8756                          &our_address))
8757         our_address_set = 1;
8758       else if (unformat (i, "local_session_id %d", &local_session_id))
8759         ;
8760       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8761         ;
8762       else if (unformat (i, "local_cookie %lld", &local_cookie))
8763         ;
8764       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8765         ;
8766       else if (unformat (i, "l2-sublayer-present"))
8767         l2_sublayer_present = 1;
8768       else
8769         break;
8770     }
8771
8772   if (client_address_set == 0)
8773     {
8774       errmsg ("client_address required\n");
8775       return -99;
8776     }
8777
8778   if (our_address_set == 0)
8779     {
8780       errmsg ("our_address required\n");
8781       return -99;
8782     }
8783
8784   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8785
8786   clib_memcpy (mp->client_address, client_address.as_u8,
8787                sizeof (mp->client_address));
8788
8789   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8790
8791   mp->local_session_id = ntohl (local_session_id);
8792   mp->remote_session_id = ntohl (remote_session_id);
8793   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8794   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8795   mp->l2_sublayer_present = l2_sublayer_present;
8796   mp->is_ipv6 = 1;
8797
8798   S;
8799   W;
8800   /* NOTREACHED */
8801   return 0;
8802 }
8803
8804 static int
8805 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   u32 sw_if_index;
8809   u8 sw_if_index_set = 0;
8810   u64 new_local_cookie = 0;
8811   u64 new_remote_cookie = 0;
8812   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8813   f64 timeout;
8814
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8820         sw_if_index_set = 1;
8821       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8822         ;
8823       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8824         ;
8825       else
8826         break;
8827     }
8828
8829   if (sw_if_index_set == 0)
8830     {
8831       errmsg ("missing interface name or sw_if_index\n");
8832       return -99;
8833     }
8834
8835   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8836
8837   mp->sw_if_index = ntohl (sw_if_index);
8838   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8839   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8840
8841   S;
8842   W;
8843   /* NOTREACHED */
8844   return 0;
8845 }
8846
8847 static int
8848 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8849 {
8850   unformat_input_t *i = vam->input;
8851   vl_api_l2tpv3_interface_enable_disable_t *mp;
8852   f64 timeout;
8853   u32 sw_if_index;
8854   u8 sw_if_index_set = 0;
8855   u8 enable_disable = 1;
8856
8857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8860         sw_if_index_set = 1;
8861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8862         sw_if_index_set = 1;
8863       else if (unformat (i, "enable"))
8864         enable_disable = 1;
8865       else if (unformat (i, "disable"))
8866         enable_disable = 0;
8867       else
8868         break;
8869     }
8870
8871   if (sw_if_index_set == 0)
8872     {
8873       errmsg ("missing interface name or sw_if_index\n");
8874       return -99;
8875     }
8876
8877   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8878
8879   mp->sw_if_index = ntohl (sw_if_index);
8880   mp->enable_disable = enable_disable;
8881
8882   S;
8883   W;
8884   /* NOTREACHED */
8885   return 0;
8886 }
8887
8888 static int
8889 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8890 {
8891   unformat_input_t *i = vam->input;
8892   vl_api_l2tpv3_set_lookup_key_t *mp;
8893   f64 timeout;
8894   u8 key = ~0;
8895
8896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8897     {
8898       if (unformat (i, "lookup_v6_src"))
8899         key = L2T_LOOKUP_SRC_ADDRESS;
8900       else if (unformat (i, "lookup_v6_dst"))
8901         key = L2T_LOOKUP_DST_ADDRESS;
8902       else if (unformat (i, "lookup_session_id"))
8903         key = L2T_LOOKUP_SESSION_ID;
8904       else
8905         break;
8906     }
8907
8908   if (key == (u8) ~ 0)
8909     {
8910       errmsg ("l2tp session lookup key unset\n");
8911       return -99;
8912     }
8913
8914   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8915
8916   mp->key = key;
8917
8918   S;
8919   W;
8920   /* NOTREACHED */
8921   return 0;
8922 }
8923
8924 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8925   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8926 {
8927   vat_main_t *vam = &vat_main;
8928
8929   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8930            format_ip6_address, mp->our_address,
8931            format_ip6_address, mp->client_address,
8932            clib_net_to_host_u32 (mp->sw_if_index));
8933
8934   fformat (vam->ofp,
8935            "   local cookies %016llx %016llx remote cookie %016llx\n",
8936            clib_net_to_host_u64 (mp->local_cookie[0]),
8937            clib_net_to_host_u64 (mp->local_cookie[1]),
8938            clib_net_to_host_u64 (mp->remote_cookie));
8939
8940   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
8941            clib_net_to_host_u32 (mp->local_session_id),
8942            clib_net_to_host_u32 (mp->remote_session_id));
8943
8944   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
8945            mp->l2_sublayer_present ? "preset" : "absent");
8946
8947 }
8948
8949 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
8950   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8951 {
8952   vat_main_t *vam = &vat_main;
8953   vat_json_node_t *node = NULL;
8954   struct in6_addr addr;
8955
8956   if (VAT_JSON_ARRAY != vam->json_tree.type)
8957     {
8958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8959       vat_json_init_array (&vam->json_tree);
8960     }
8961   node = vat_json_array_add (&vam->json_tree);
8962
8963   vat_json_init_object (node);
8964
8965   clib_memcpy (&addr, mp->our_address, sizeof (addr));
8966   vat_json_object_add_ip6 (node, "our_address", addr);
8967   clib_memcpy (&addr, mp->client_address, sizeof (addr));
8968   vat_json_object_add_ip6 (node, "client_address", addr);
8969
8970   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
8971   vat_json_init_array (lc);
8972   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
8973   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
8974   vat_json_object_add_uint (node, "remote_cookie",
8975                             clib_net_to_host_u64 (mp->remote_cookie));
8976
8977   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
8978   vat_json_object_add_uint (node, "local_session_id",
8979                             clib_net_to_host_u32 (mp->local_session_id));
8980   vat_json_object_add_uint (node, "remote_session_id",
8981                             clib_net_to_host_u32 (mp->remote_session_id));
8982   vat_json_object_add_string_copy (node, "l2_sublayer",
8983                                    mp->l2_sublayer_present ? (u8 *) "present"
8984                                    : (u8 *) "absent");
8985 }
8986
8987 static int
8988 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
8989 {
8990   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
8991   f64 timeout;
8992
8993   /* Get list of l2tpv3-tunnel interfaces */
8994   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
8995   S;
8996
8997   /* Use a control ping for synchronization */
8998   {
8999     vl_api_control_ping_t *mp;
9000     M (CONTROL_PING, control_ping);
9001     S;
9002   }
9003   W;
9004 }
9005
9006
9007 static void vl_api_sw_interface_tap_details_t_handler
9008   (vl_api_sw_interface_tap_details_t * mp)
9009 {
9010   vat_main_t *vam = &vat_main;
9011
9012   fformat (vam->ofp, "%-16s %d\n",
9013            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9014 }
9015
9016 static void vl_api_sw_interface_tap_details_t_handler_json
9017   (vl_api_sw_interface_tap_details_t * mp)
9018 {
9019   vat_main_t *vam = &vat_main;
9020   vat_json_node_t *node = NULL;
9021
9022   if (VAT_JSON_ARRAY != vam->json_tree.type)
9023     {
9024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9025       vat_json_init_array (&vam->json_tree);
9026     }
9027   node = vat_json_array_add (&vam->json_tree);
9028
9029   vat_json_init_object (node);
9030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9031   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9032 }
9033
9034 static int
9035 api_sw_interface_tap_dump (vat_main_t * vam)
9036 {
9037   vl_api_sw_interface_tap_dump_t *mp;
9038   f64 timeout;
9039
9040   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9041   /* Get list of tap interfaces */
9042   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9043   S;
9044
9045   /* Use a control ping for synchronization */
9046   {
9047     vl_api_control_ping_t *mp;
9048     M (CONTROL_PING, control_ping);
9049     S;
9050   }
9051   W;
9052 }
9053
9054 static uword unformat_vxlan_decap_next
9055   (unformat_input_t * input, va_list * args)
9056 {
9057   u32 *result = va_arg (*args, u32 *);
9058   u32 tmp;
9059
9060   if (unformat (input, "drop"))
9061     *result = VXLAN_INPUT_NEXT_DROP;
9062   else if (unformat (input, "ip4"))
9063     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9064   else if (unformat (input, "ip6"))
9065     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9066   else if (unformat (input, "l2"))
9067     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9068   else if (unformat (input, "%d", &tmp))
9069     *result = tmp;
9070   else
9071     return 0;
9072   return 1;
9073 }
9074
9075 static int
9076 api_vxlan_add_del_tunnel (vat_main_t * vam)
9077 {
9078   unformat_input_t *line_input = vam->input;
9079   vl_api_vxlan_add_del_tunnel_t *mp;
9080   f64 timeout;
9081   ip4_address_t src4, dst4;
9082   ip6_address_t src6, dst6;
9083   u8 is_add = 1;
9084   u8 ipv4_set = 0, ipv6_set = 0;
9085   u8 src_set = 0;
9086   u8 dst_set = 0;
9087   u32 encap_vrf_id = 0;
9088   u32 decap_next_index = ~0;
9089   u32 vni = 0;
9090
9091   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (line_input, "del"))
9094         is_add = 0;
9095       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9096         {
9097           ipv4_set = 1;
9098           src_set = 1;
9099         }
9100       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9101         {
9102           ipv4_set = 1;
9103           dst_set = 1;
9104         }
9105       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9106         {
9107           ipv6_set = 1;
9108           src_set = 1;
9109         }
9110       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9111         {
9112           ipv6_set = 1;
9113           dst_set = 1;
9114         }
9115       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9116         ;
9117       else if (unformat (line_input, "decap-next %U",
9118                          unformat_vxlan_decap_next, &decap_next_index))
9119         ;
9120       else if (unformat (line_input, "vni %d", &vni))
9121         ;
9122       else
9123         {
9124           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9125           return -99;
9126         }
9127     }
9128
9129   if (src_set == 0)
9130     {
9131       errmsg ("tunnel src address not specified\n");
9132       return -99;
9133     }
9134   if (dst_set == 0)
9135     {
9136       errmsg ("tunnel dst address not specified\n");
9137       return -99;
9138     }
9139
9140   if (ipv4_set && ipv6_set)
9141     {
9142       errmsg ("both IPv4 and IPv6 addresses specified");
9143       return -99;
9144     }
9145
9146   if ((vni == 0) || (vni >> 24))
9147     {
9148       errmsg ("vni not specified or out of range\n");
9149       return -99;
9150     }
9151
9152   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9153
9154   if (ipv6_set)
9155     {
9156       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9157       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9158     }
9159   else
9160     {
9161       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9162       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9163     }
9164   mp->encap_vrf_id = ntohl (encap_vrf_id);
9165   mp->decap_next_index = ntohl (decap_next_index);
9166   mp->vni = ntohl (vni);
9167   mp->is_add = is_add;
9168   mp->is_ipv6 = ipv6_set;
9169
9170   S;
9171   W;
9172   /* NOTREACHED */
9173   return 0;
9174 }
9175
9176 static void vl_api_vxlan_tunnel_details_t_handler
9177   (vl_api_vxlan_tunnel_details_t * mp)
9178 {
9179   vat_main_t *vam = &vat_main;
9180
9181   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9182            ntohl (mp->sw_if_index),
9183            format_ip46_address, &(mp->src_address[0]),
9184            IP46_TYPE_ANY,
9185            format_ip46_address, &(mp->dst_address[0]),
9186            IP46_TYPE_ANY,
9187            ntohl (mp->encap_vrf_id),
9188            ntohl (mp->decap_next_index), ntohl (mp->vni));
9189 }
9190
9191 static void vl_api_vxlan_tunnel_details_t_handler_json
9192   (vl_api_vxlan_tunnel_details_t * mp)
9193 {
9194   vat_main_t *vam = &vat_main;
9195   vat_json_node_t *node = NULL;
9196   struct in_addr ip4;
9197   struct in6_addr ip6;
9198
9199   if (VAT_JSON_ARRAY != vam->json_tree.type)
9200     {
9201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9202       vat_json_init_array (&vam->json_tree);
9203     }
9204   node = vat_json_array_add (&vam->json_tree);
9205
9206   vat_json_init_object (node);
9207   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9208   if (mp->is_ipv6)
9209     {
9210       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9211       vat_json_object_add_ip6 (node, "src_address", ip6);
9212       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9213       vat_json_object_add_ip6 (node, "dst_address", ip6);
9214     }
9215   else
9216     {
9217       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9218       vat_json_object_add_ip4 (node, "src_address", ip4);
9219       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9220       vat_json_object_add_ip4 (node, "dst_address", ip4);
9221     }
9222   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9223   vat_json_object_add_uint (node, "decap_next_index",
9224                             ntohl (mp->decap_next_index));
9225   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9226   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9227 }
9228
9229 static int
9230 api_vxlan_tunnel_dump (vat_main_t * vam)
9231 {
9232   unformat_input_t *i = vam->input;
9233   vl_api_vxlan_tunnel_dump_t *mp;
9234   f64 timeout;
9235   u32 sw_if_index;
9236   u8 sw_if_index_set = 0;
9237
9238   /* Parse args required to build the message */
9239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9240     {
9241       if (unformat (i, "sw_if_index %d", &sw_if_index))
9242         sw_if_index_set = 1;
9243       else
9244         break;
9245     }
9246
9247   if (sw_if_index_set == 0)
9248     {
9249       sw_if_index = ~0;
9250     }
9251
9252   if (!vam->json_output)
9253     {
9254       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9255                "sw_if_index", "src_address", "dst_address",
9256                "encap_vrf_id", "decap_next_index", "vni");
9257     }
9258
9259   /* Get list of vxlan-tunnel interfaces */
9260   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9261
9262   mp->sw_if_index = htonl (sw_if_index);
9263
9264   S;
9265
9266   /* Use a control ping for synchronization */
9267   {
9268     vl_api_control_ping_t *mp;
9269     M (CONTROL_PING, control_ping);
9270     S;
9271   }
9272   W;
9273 }
9274
9275 static int
9276 api_gre_add_del_tunnel (vat_main_t * vam)
9277 {
9278   unformat_input_t *line_input = vam->input;
9279   vl_api_gre_add_del_tunnel_t *mp;
9280   f64 timeout;
9281   ip4_address_t src4, dst4;
9282   u8 is_add = 1;
9283   u8 src_set = 0;
9284   u8 dst_set = 0;
9285   u32 outer_fib_id = 0;
9286
9287   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9288     {
9289       if (unformat (line_input, "del"))
9290         is_add = 0;
9291       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9292         src_set = 1;
9293       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9294         dst_set = 1;
9295       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9296         ;
9297       else
9298         {
9299           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9300           return -99;
9301         }
9302     }
9303
9304   if (src_set == 0)
9305     {
9306       errmsg ("tunnel src address not specified\n");
9307       return -99;
9308     }
9309   if (dst_set == 0)
9310     {
9311       errmsg ("tunnel dst address not specified\n");
9312       return -99;
9313     }
9314
9315
9316   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9317
9318   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9319   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9320   mp->outer_fib_id = ntohl (outer_fib_id);
9321   mp->is_add = is_add;
9322
9323   S;
9324   W;
9325   /* NOTREACHED */
9326   return 0;
9327 }
9328
9329 static void vl_api_gre_tunnel_details_t_handler
9330   (vl_api_gre_tunnel_details_t * mp)
9331 {
9332   vat_main_t *vam = &vat_main;
9333
9334   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9335            ntohl (mp->sw_if_index),
9336            format_ip4_address, &mp->src_address,
9337            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9338 }
9339
9340 static void vl_api_gre_tunnel_details_t_handler_json
9341   (vl_api_gre_tunnel_details_t * mp)
9342 {
9343   vat_main_t *vam = &vat_main;
9344   vat_json_node_t *node = NULL;
9345   struct in_addr ip4;
9346
9347   if (VAT_JSON_ARRAY != vam->json_tree.type)
9348     {
9349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9350       vat_json_init_array (&vam->json_tree);
9351     }
9352   node = vat_json_array_add (&vam->json_tree);
9353
9354   vat_json_init_object (node);
9355   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9356   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9357   vat_json_object_add_ip4 (node, "src_address", ip4);
9358   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9359   vat_json_object_add_ip4 (node, "dst_address", ip4);
9360   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9361 }
9362
9363 static int
9364 api_gre_tunnel_dump (vat_main_t * vam)
9365 {
9366   unformat_input_t *i = vam->input;
9367   vl_api_gre_tunnel_dump_t *mp;
9368   f64 timeout;
9369   u32 sw_if_index;
9370   u8 sw_if_index_set = 0;
9371
9372   /* Parse args required to build the message */
9373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9374     {
9375       if (unformat (i, "sw_if_index %d", &sw_if_index))
9376         sw_if_index_set = 1;
9377       else
9378         break;
9379     }
9380
9381   if (sw_if_index_set == 0)
9382     {
9383       sw_if_index = ~0;
9384     }
9385
9386   if (!vam->json_output)
9387     {
9388       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9389                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9390     }
9391
9392   /* Get list of gre-tunnel interfaces */
9393   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9394
9395   mp->sw_if_index = htonl (sw_if_index);
9396
9397   S;
9398
9399   /* Use a control ping for synchronization */
9400   {
9401     vl_api_control_ping_t *mp;
9402     M (CONTROL_PING, control_ping);
9403     S;
9404   }
9405   W;
9406 }
9407
9408 static int
9409 api_l2_fib_clear_table (vat_main_t * vam)
9410 {
9411 //  unformat_input_t * i = vam->input;
9412   vl_api_l2_fib_clear_table_t *mp;
9413   f64 timeout;
9414
9415   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9416
9417   S;
9418   W;
9419   /* NOTREACHED */
9420   return 0;
9421 }
9422
9423 static int
9424 api_l2_interface_efp_filter (vat_main_t * vam)
9425 {
9426   unformat_input_t *i = vam->input;
9427   vl_api_l2_interface_efp_filter_t *mp;
9428   f64 timeout;
9429   u32 sw_if_index;
9430   u8 enable = 1;
9431   u8 sw_if_index_set = 0;
9432
9433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9436         sw_if_index_set = 1;
9437       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9438         sw_if_index_set = 1;
9439       else if (unformat (i, "enable"))
9440         enable = 1;
9441       else if (unformat (i, "disable"))
9442         enable = 0;
9443       else
9444         {
9445           clib_warning ("parse error '%U'", format_unformat_error, i);
9446           return -99;
9447         }
9448     }
9449
9450   if (sw_if_index_set == 0)
9451     {
9452       errmsg ("missing sw_if_index\n");
9453       return -99;
9454     }
9455
9456   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9457
9458   mp->sw_if_index = ntohl (sw_if_index);
9459   mp->enable_disable = enable;
9460
9461   S;
9462   W;
9463   /* NOTREACHED */
9464   return 0;
9465 }
9466
9467 #define foreach_vtr_op                          \
9468 _("disable",  L2_VTR_DISABLED)                  \
9469 _("push-1",  L2_VTR_PUSH_1)                     \
9470 _("push-2",  L2_VTR_PUSH_2)                     \
9471 _("pop-1",  L2_VTR_POP_1)                       \
9472 _("pop-2",  L2_VTR_POP_2)                       \
9473 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9474 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9475 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9476 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9477
9478 static int
9479 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9480 {
9481   unformat_input_t *i = vam->input;
9482   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9483   f64 timeout;
9484   u32 sw_if_index;
9485   u8 sw_if_index_set = 0;
9486   u8 vtr_op_set = 0;
9487   u32 vtr_op = 0;
9488   u32 push_dot1q = 1;
9489   u32 tag1 = ~0;
9490   u32 tag2 = ~0;
9491
9492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9493     {
9494       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9495         sw_if_index_set = 1;
9496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9497         sw_if_index_set = 1;
9498       else if (unformat (i, "vtr_op %d", &vtr_op))
9499         vtr_op_set = 1;
9500 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9501       foreach_vtr_op
9502 #undef _
9503         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9504         ;
9505       else if (unformat (i, "tag1 %d", &tag1))
9506         ;
9507       else if (unformat (i, "tag2 %d", &tag2))
9508         ;
9509       else
9510         {
9511           clib_warning ("parse error '%U'", format_unformat_error, i);
9512           return -99;
9513         }
9514     }
9515
9516   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9517     {
9518       errmsg ("missing vtr operation or sw_if_index\n");
9519       return -99;
9520     }
9521
9522   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9523     mp->sw_if_index = ntohl (sw_if_index);
9524   mp->vtr_op = ntohl (vtr_op);
9525   mp->push_dot1q = ntohl (push_dot1q);
9526   mp->tag1 = ntohl (tag1);
9527   mp->tag2 = ntohl (tag2);
9528
9529   S;
9530   W;
9531   /* NOTREACHED */
9532   return 0;
9533 }
9534
9535 static int
9536 api_create_vhost_user_if (vat_main_t * vam)
9537 {
9538   unformat_input_t *i = vam->input;
9539   vl_api_create_vhost_user_if_t *mp;
9540   f64 timeout;
9541   u8 *file_name;
9542   u8 is_server = 0;
9543   u8 file_name_set = 0;
9544   u32 custom_dev_instance = ~0;
9545   u8 hwaddr[6];
9546   u8 use_custom_mac = 0;
9547
9548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9549     {
9550       if (unformat (i, "socket %s", &file_name))
9551         {
9552           file_name_set = 1;
9553         }
9554       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9555         ;
9556       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9557         use_custom_mac = 1;
9558       else if (unformat (i, "server"))
9559         is_server = 1;
9560       else
9561         break;
9562     }
9563
9564   if (file_name_set == 0)
9565     {
9566       errmsg ("missing socket file name\n");
9567       return -99;
9568     }
9569
9570   if (vec_len (file_name) > 255)
9571     {
9572       errmsg ("socket file name too long\n");
9573       return -99;
9574     }
9575   vec_add1 (file_name, 0);
9576
9577   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9578
9579   mp->is_server = is_server;
9580   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9581   vec_free (file_name);
9582   if (custom_dev_instance != ~0)
9583     {
9584       mp->renumber = 1;
9585       mp->custom_dev_instance = ntohl (custom_dev_instance);
9586     }
9587   mp->use_custom_mac = use_custom_mac;
9588   clib_memcpy (mp->mac_address, hwaddr, 6);
9589
9590   S;
9591   W;
9592   /* NOTREACHED */
9593   return 0;
9594 }
9595
9596 static int
9597 api_modify_vhost_user_if (vat_main_t * vam)
9598 {
9599   unformat_input_t *i = vam->input;
9600   vl_api_modify_vhost_user_if_t *mp;
9601   f64 timeout;
9602   u8 *file_name;
9603   u8 is_server = 0;
9604   u8 file_name_set = 0;
9605   u32 custom_dev_instance = ~0;
9606   u8 sw_if_index_set = 0;
9607   u32 sw_if_index = (u32) ~ 0;
9608
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9612         sw_if_index_set = 1;
9613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9614         sw_if_index_set = 1;
9615       else if (unformat (i, "socket %s", &file_name))
9616         {
9617           file_name_set = 1;
9618         }
9619       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9620         ;
9621       else if (unformat (i, "server"))
9622         is_server = 1;
9623       else
9624         break;
9625     }
9626
9627   if (sw_if_index_set == 0)
9628     {
9629       errmsg ("missing sw_if_index or interface name\n");
9630       return -99;
9631     }
9632
9633   if (file_name_set == 0)
9634     {
9635       errmsg ("missing socket file name\n");
9636       return -99;
9637     }
9638
9639   if (vec_len (file_name) > 255)
9640     {
9641       errmsg ("socket file name too long\n");
9642       return -99;
9643     }
9644   vec_add1 (file_name, 0);
9645
9646   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9647
9648   mp->sw_if_index = ntohl (sw_if_index);
9649   mp->is_server = is_server;
9650   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9651   vec_free (file_name);
9652   if (custom_dev_instance != ~0)
9653     {
9654       mp->renumber = 1;
9655       mp->custom_dev_instance = ntohl (custom_dev_instance);
9656     }
9657
9658   S;
9659   W;
9660   /* NOTREACHED */
9661   return 0;
9662 }
9663
9664 static int
9665 api_delete_vhost_user_if (vat_main_t * vam)
9666 {
9667   unformat_input_t *i = vam->input;
9668   vl_api_delete_vhost_user_if_t *mp;
9669   f64 timeout;
9670   u32 sw_if_index = ~0;
9671   u8 sw_if_index_set = 0;
9672
9673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9674     {
9675       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9676         sw_if_index_set = 1;
9677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9678         sw_if_index_set = 1;
9679       else
9680         break;
9681     }
9682
9683   if (sw_if_index_set == 0)
9684     {
9685       errmsg ("missing sw_if_index or interface name\n");
9686       return -99;
9687     }
9688
9689
9690   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9691
9692   mp->sw_if_index = ntohl (sw_if_index);
9693
9694   S;
9695   W;
9696   /* NOTREACHED */
9697   return 0;
9698 }
9699
9700 static void vl_api_sw_interface_vhost_user_details_t_handler
9701   (vl_api_sw_interface_vhost_user_details_t * mp)
9702 {
9703   vat_main_t *vam = &vat_main;
9704
9705   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9706            (char *) mp->interface_name,
9707            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9708            clib_net_to_host_u64 (mp->features), mp->is_server,
9709            ntohl (mp->num_regions), (char *) mp->sock_filename);
9710   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9711 }
9712
9713 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9714   (vl_api_sw_interface_vhost_user_details_t * mp)
9715 {
9716   vat_main_t *vam = &vat_main;
9717   vat_json_node_t *node = NULL;
9718
9719   if (VAT_JSON_ARRAY != vam->json_tree.type)
9720     {
9721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9722       vat_json_init_array (&vam->json_tree);
9723     }
9724   node = vat_json_array_add (&vam->json_tree);
9725
9726   vat_json_init_object (node);
9727   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9728   vat_json_object_add_string_copy (node, "interface_name",
9729                                    mp->interface_name);
9730   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9731                             ntohl (mp->virtio_net_hdr_sz));
9732   vat_json_object_add_uint (node, "features",
9733                             clib_net_to_host_u64 (mp->features));
9734   vat_json_object_add_uint (node, "is_server", mp->is_server);
9735   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9736   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9737   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9738 }
9739
9740 static int
9741 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9742 {
9743   vl_api_sw_interface_vhost_user_dump_t *mp;
9744   f64 timeout;
9745   fformat (vam->ofp,
9746            "Interface name           idx hdr_sz features server regions filename\n");
9747
9748   /* Get list of vhost-user interfaces */
9749   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9750   S;
9751
9752   /* Use a control ping for synchronization */
9753   {
9754     vl_api_control_ping_t *mp;
9755     M (CONTROL_PING, control_ping);
9756     S;
9757   }
9758   W;
9759 }
9760
9761 static int
9762 api_show_version (vat_main_t * vam)
9763 {
9764   vl_api_show_version_t *mp;
9765   f64 timeout;
9766
9767   M (SHOW_VERSION, show_version);
9768
9769   S;
9770   W;
9771   /* NOTREACHED */
9772   return 0;
9773 }
9774
9775
9776 static int
9777 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9778 {
9779   unformat_input_t *line_input = vam->input;
9780   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9781   f64 timeout;
9782   ip4_address_t local4, remote4;
9783   ip6_address_t local6, remote6;
9784   u8 is_add = 1;
9785   u8 ipv4_set = 0, ipv6_set = 0;
9786   u8 local_set = 0;
9787   u8 remote_set = 0;
9788   u32 encap_vrf_id = 0;
9789   u32 decap_vrf_id = 0;
9790   u8 protocol = ~0;
9791   u32 vni;
9792   u8 vni_set = 0;
9793
9794   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9795     {
9796       if (unformat (line_input, "del"))
9797         is_add = 0;
9798       else if (unformat (line_input, "local %U",
9799                          unformat_ip4_address, &local4))
9800         {
9801           local_set = 1;
9802           ipv4_set = 1;
9803         }
9804       else if (unformat (line_input, "remote %U",
9805                          unformat_ip4_address, &remote4))
9806         {
9807           remote_set = 1;
9808           ipv4_set = 1;
9809         }
9810       else if (unformat (line_input, "local %U",
9811                          unformat_ip6_address, &local6))
9812         {
9813           local_set = 1;
9814           ipv6_set = 1;
9815         }
9816       else if (unformat (line_input, "remote %U",
9817                          unformat_ip6_address, &remote6))
9818         {
9819           remote_set = 1;
9820           ipv6_set = 1;
9821         }
9822       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9823         ;
9824       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9825         ;
9826       else if (unformat (line_input, "vni %d", &vni))
9827         vni_set = 1;
9828       else if (unformat (line_input, "next-ip4"))
9829         protocol = 1;
9830       else if (unformat (line_input, "next-ip6"))
9831         protocol = 2;
9832       else if (unformat (line_input, "next-ethernet"))
9833         protocol = 3;
9834       else if (unformat (line_input, "next-nsh"))
9835         protocol = 4;
9836       else
9837         {
9838           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9839           return -99;
9840         }
9841     }
9842
9843   if (local_set == 0)
9844     {
9845       errmsg ("tunnel local address not specified\n");
9846       return -99;
9847     }
9848   if (remote_set == 0)
9849     {
9850       errmsg ("tunnel remote address not specified\n");
9851       return -99;
9852     }
9853   if (ipv4_set && ipv6_set)
9854     {
9855       errmsg ("both IPv4 and IPv6 addresses specified");
9856       return -99;
9857     }
9858
9859   if (vni_set == 0)
9860     {
9861       errmsg ("vni not specified\n");
9862       return -99;
9863     }
9864
9865   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9866
9867
9868   if (ipv6_set)
9869     {
9870       clib_memcpy (&mp->local, &local6, sizeof (local6));
9871       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9872     }
9873   else
9874     {
9875       clib_memcpy (&mp->local, &local4, sizeof (local4));
9876       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9877     }
9878
9879   mp->encap_vrf_id = ntohl (encap_vrf_id);
9880   mp->decap_vrf_id = ntohl (decap_vrf_id);
9881   mp->protocol = ntohl (protocol);
9882   mp->vni = ntohl (vni);
9883   mp->is_add = is_add;
9884   mp->is_ipv6 = ipv6_set;
9885
9886   S;
9887   W;
9888   /* NOTREACHED */
9889   return 0;
9890 }
9891
9892 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9893   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9894 {
9895   vat_main_t *vam = &vat_main;
9896
9897   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9898            ntohl (mp->sw_if_index),
9899            format_ip46_address, &(mp->local[0]),
9900            format_ip46_address, &(mp->remote[0]),
9901            ntohl (mp->vni),
9902            ntohl (mp->protocol),
9903            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9904 }
9905
9906 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9907   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9908 {
9909   vat_main_t *vam = &vat_main;
9910   vat_json_node_t *node = NULL;
9911   struct in_addr ip4;
9912   struct in6_addr ip6;
9913
9914   if (VAT_JSON_ARRAY != vam->json_tree.type)
9915     {
9916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9917       vat_json_init_array (&vam->json_tree);
9918     }
9919   node = vat_json_array_add (&vam->json_tree);
9920
9921   vat_json_init_object (node);
9922   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9923   if (mp->is_ipv6)
9924     {
9925       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9926       vat_json_object_add_ip6 (node, "local", ip6);
9927       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9928       vat_json_object_add_ip6 (node, "remote", ip6);
9929     }
9930   else
9931     {
9932       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9933       vat_json_object_add_ip4 (node, "local", ip4);
9934       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9935       vat_json_object_add_ip4 (node, "remote", ip4);
9936     }
9937   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9938   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9939   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9940   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
9941   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9942 }
9943
9944 static int
9945 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
9946 {
9947   unformat_input_t *i = vam->input;
9948   vl_api_vxlan_gpe_tunnel_dump_t *mp;
9949   f64 timeout;
9950   u32 sw_if_index;
9951   u8 sw_if_index_set = 0;
9952
9953   /* Parse args required to build the message */
9954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (unformat (i, "sw_if_index %d", &sw_if_index))
9957         sw_if_index_set = 1;
9958       else
9959         break;
9960     }
9961
9962   if (sw_if_index_set == 0)
9963     {
9964       sw_if_index = ~0;
9965     }
9966
9967   if (!vam->json_output)
9968     {
9969       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
9970                "sw_if_index", "local", "remote", "vni",
9971                "protocol", "encap_vrf_id", "decap_vrf_id");
9972     }
9973
9974   /* Get list of vxlan-tunnel interfaces */
9975   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
9976
9977   mp->sw_if_index = htonl (sw_if_index);
9978
9979   S;
9980
9981   /* Use a control ping for synchronization */
9982   {
9983     vl_api_control_ping_t *mp;
9984     M (CONTROL_PING, control_ping);
9985     S;
9986   }
9987   W;
9988 }
9989
9990 u8 *
9991 format_l2_fib_mac_address (u8 * s, va_list * args)
9992 {
9993   u8 *a = va_arg (*args, u8 *);
9994
9995   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
9996                  a[2], a[3], a[4], a[5], a[6], a[7]);
9997 }
9998
9999 static void vl_api_l2_fib_table_entry_t_handler
10000   (vl_api_l2_fib_table_entry_t * mp)
10001 {
10002   vat_main_t *vam = &vat_main;
10003
10004   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10005            "       %d       %d     %d\n",
10006            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10007            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10008            mp->bvi_mac);
10009 }
10010
10011 static void vl_api_l2_fib_table_entry_t_handler_json
10012   (vl_api_l2_fib_table_entry_t * mp)
10013 {
10014   vat_main_t *vam = &vat_main;
10015   vat_json_node_t *node = NULL;
10016
10017   if (VAT_JSON_ARRAY != vam->json_tree.type)
10018     {
10019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10020       vat_json_init_array (&vam->json_tree);
10021     }
10022   node = vat_json_array_add (&vam->json_tree);
10023
10024   vat_json_init_object (node);
10025   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10026   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10028   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10029   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10030   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10031 }
10032
10033 static int
10034 api_l2_fib_table_dump (vat_main_t * vam)
10035 {
10036   unformat_input_t *i = vam->input;
10037   vl_api_l2_fib_table_dump_t *mp;
10038   f64 timeout;
10039   u32 bd_id;
10040   u8 bd_id_set = 0;
10041
10042   /* Parse args required to build the message */
10043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10044     {
10045       if (unformat (i, "bd_id %d", &bd_id))
10046         bd_id_set = 1;
10047       else
10048         break;
10049     }
10050
10051   if (bd_id_set == 0)
10052     {
10053       errmsg ("missing bridge domain\n");
10054       return -99;
10055     }
10056
10057   fformat (vam->ofp,
10058            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10059
10060   /* Get list of l2 fib entries */
10061   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10062
10063   mp->bd_id = ntohl (bd_id);
10064   S;
10065
10066   /* Use a control ping for synchronization */
10067   {
10068     vl_api_control_ping_t *mp;
10069     M (CONTROL_PING, control_ping);
10070     S;
10071   }
10072   W;
10073 }
10074
10075
10076 static int
10077 api_interface_name_renumber (vat_main_t * vam)
10078 {
10079   unformat_input_t *line_input = vam->input;
10080   vl_api_interface_name_renumber_t *mp;
10081   u32 sw_if_index = ~0;
10082   f64 timeout;
10083   u32 new_show_dev_instance = ~0;
10084
10085   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10086     {
10087       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10088                     &sw_if_index))
10089         ;
10090       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10091         ;
10092       else if (unformat (line_input, "new_show_dev_instance %d",
10093                          &new_show_dev_instance))
10094         ;
10095       else
10096         break;
10097     }
10098
10099   if (sw_if_index == ~0)
10100     {
10101       errmsg ("missing interface name or sw_if_index\n");
10102       return -99;
10103     }
10104
10105   if (new_show_dev_instance == ~0)
10106     {
10107       errmsg ("missing new_show_dev_instance\n");
10108       return -99;
10109     }
10110
10111   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10112
10113   mp->sw_if_index = ntohl (sw_if_index);
10114   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10115
10116   S;
10117   W;
10118 }
10119
10120 static int
10121 api_want_ip4_arp_events (vat_main_t * vam)
10122 {
10123   unformat_input_t *line_input = vam->input;
10124   vl_api_want_ip4_arp_events_t *mp;
10125   f64 timeout;
10126   ip4_address_t address;
10127   int address_set = 0;
10128   u32 enable_disable = 1;
10129
10130   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10131     {
10132       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10133         address_set = 1;
10134       else if (unformat (line_input, "del"))
10135         enable_disable = 0;
10136       else
10137         break;
10138     }
10139
10140   if (address_set == 0)
10141     {
10142       errmsg ("missing addresses\n");
10143       return -99;
10144     }
10145
10146   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10147   mp->enable_disable = enable_disable;
10148   mp->pid = getpid ();
10149   mp->address = address.as_u32;
10150
10151   S;
10152   W;
10153 }
10154
10155 static int
10156 api_input_acl_set_interface (vat_main_t * vam)
10157 {
10158   unformat_input_t *i = vam->input;
10159   vl_api_input_acl_set_interface_t *mp;
10160   f64 timeout;
10161   u32 sw_if_index;
10162   int sw_if_index_set;
10163   u32 ip4_table_index = ~0;
10164   u32 ip6_table_index = ~0;
10165   u32 l2_table_index = ~0;
10166   u8 is_add = 1;
10167
10168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10169     {
10170       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10171         sw_if_index_set = 1;
10172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10173         sw_if_index_set = 1;
10174       else if (unformat (i, "del"))
10175         is_add = 0;
10176       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10177         ;
10178       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10179         ;
10180       else if (unformat (i, "l2-table %d", &l2_table_index))
10181         ;
10182       else
10183         {
10184           clib_warning ("parse error '%U'", format_unformat_error, i);
10185           return -99;
10186         }
10187     }
10188
10189   if (sw_if_index_set == 0)
10190     {
10191       errmsg ("missing interface name or sw_if_index\n");
10192       return -99;
10193     }
10194
10195   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10196
10197   mp->sw_if_index = ntohl (sw_if_index);
10198   mp->ip4_table_index = ntohl (ip4_table_index);
10199   mp->ip6_table_index = ntohl (ip6_table_index);
10200   mp->l2_table_index = ntohl (l2_table_index);
10201   mp->is_add = is_add;
10202
10203   S;
10204   W;
10205   /* NOTREACHED */
10206   return 0;
10207 }
10208
10209 static int
10210 api_ip_address_dump (vat_main_t * vam)
10211 {
10212   unformat_input_t *i = vam->input;
10213   vl_api_ip_address_dump_t *mp;
10214   u32 sw_if_index = ~0;
10215   u8 sw_if_index_set = 0;
10216   u8 ipv4_set = 0;
10217   u8 ipv6_set = 0;
10218   f64 timeout;
10219
10220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10221     {
10222       if (unformat (i, "sw_if_index %d", &sw_if_index))
10223         sw_if_index_set = 1;
10224       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10225         sw_if_index_set = 1;
10226       else if (unformat (i, "ipv4"))
10227         ipv4_set = 1;
10228       else if (unformat (i, "ipv6"))
10229         ipv6_set = 1;
10230       else
10231         break;
10232     }
10233
10234   if (ipv4_set && ipv6_set)
10235     {
10236       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10237       return -99;
10238     }
10239
10240   if ((!ipv4_set) && (!ipv6_set))
10241     {
10242       errmsg ("no ipv4 nor ipv6 flag set\n");
10243       return -99;
10244     }
10245
10246   if (sw_if_index_set == 0)
10247     {
10248       errmsg ("missing interface name or sw_if_index\n");
10249       return -99;
10250     }
10251
10252   vam->current_sw_if_index = sw_if_index;
10253   vam->is_ipv6 = ipv6_set;
10254
10255   M (IP_ADDRESS_DUMP, ip_address_dump);
10256   mp->sw_if_index = ntohl (sw_if_index);
10257   mp->is_ipv6 = ipv6_set;
10258   S;
10259
10260   /* Use a control ping for synchronization */
10261   {
10262     vl_api_control_ping_t *mp;
10263     M (CONTROL_PING, control_ping);
10264     S;
10265   }
10266   W;
10267 }
10268
10269 static int
10270 api_ip_dump (vat_main_t * vam)
10271 {
10272   vl_api_ip_dump_t *mp;
10273   unformat_input_t *in = vam->input;
10274   int ipv4_set = 0;
10275   int ipv6_set = 0;
10276   int is_ipv6;
10277   f64 timeout;
10278   int i;
10279
10280   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10281     {
10282       if (unformat (in, "ipv4"))
10283         ipv4_set = 1;
10284       else if (unformat (in, "ipv6"))
10285         ipv6_set = 1;
10286       else
10287         break;
10288     }
10289
10290   if (ipv4_set && ipv6_set)
10291     {
10292       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10293       return -99;
10294     }
10295
10296   if ((!ipv4_set) && (!ipv6_set))
10297     {
10298       errmsg ("no ipv4 nor ipv6 flag set\n");
10299       return -99;
10300     }
10301
10302   is_ipv6 = ipv6_set;
10303   vam->is_ipv6 = is_ipv6;
10304
10305   /* free old data */
10306   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10307     {
10308       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10309     }
10310   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10311
10312   M (IP_DUMP, ip_dump);
10313   mp->is_ipv6 = ipv6_set;
10314   S;
10315
10316   /* Use a control ping for synchronization */
10317   {
10318     vl_api_control_ping_t *mp;
10319     M (CONTROL_PING, control_ping);
10320     S;
10321   }
10322   W;
10323 }
10324
10325 static int
10326 api_ipsec_spd_add_del (vat_main_t * vam)
10327 {
10328 #if DPDK > 0
10329   unformat_input_t *i = vam->input;
10330   vl_api_ipsec_spd_add_del_t *mp;
10331   f64 timeout;
10332   u32 spd_id = ~0;
10333   u8 is_add = 1;
10334
10335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (unformat (i, "spd_id %d", &spd_id))
10338         ;
10339       else if (unformat (i, "del"))
10340         is_add = 0;
10341       else
10342         {
10343           clib_warning ("parse error '%U'", format_unformat_error, i);
10344           return -99;
10345         }
10346     }
10347   if (spd_id == ~0)
10348     {
10349       errmsg ("spd_id must be set\n");
10350       return -99;
10351     }
10352
10353   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10354
10355   mp->spd_id = ntohl (spd_id);
10356   mp->is_add = is_add;
10357
10358   S;
10359   W;
10360   /* NOTREACHED */
10361   return 0;
10362 #else
10363   clib_warning ("unsupported (no dpdk)");
10364   return -99;
10365 #endif
10366 }
10367
10368 static int
10369 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10370 {
10371 #if DPDK > 0
10372   unformat_input_t *i = vam->input;
10373   vl_api_ipsec_interface_add_del_spd_t *mp;
10374   f64 timeout;
10375   u32 sw_if_index;
10376   u8 sw_if_index_set = 0;
10377   u32 spd_id = (u32) ~ 0;
10378   u8 is_add = 1;
10379
10380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10381     {
10382       if (unformat (i, "del"))
10383         is_add = 0;
10384       else if (unformat (i, "spd_id %d", &spd_id))
10385         ;
10386       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10387         sw_if_index_set = 1;
10388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10389         sw_if_index_set = 1;
10390       else
10391         {
10392           clib_warning ("parse error '%U'", format_unformat_error, i);
10393           return -99;
10394         }
10395
10396     }
10397
10398   if (spd_id == (u32) ~ 0)
10399     {
10400       errmsg ("spd_id must be set\n");
10401       return -99;
10402     }
10403
10404   if (sw_if_index_set == 0)
10405     {
10406       errmsg ("missing interface name or sw_if_index\n");
10407       return -99;
10408     }
10409
10410   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10411
10412   mp->spd_id = ntohl (spd_id);
10413   mp->sw_if_index = ntohl (sw_if_index);
10414   mp->is_add = is_add;
10415
10416   S;
10417   W;
10418   /* NOTREACHED */
10419   return 0;
10420 #else
10421   clib_warning ("unsupported (no dpdk)");
10422   return -99;
10423 #endif
10424 }
10425
10426 static int
10427 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10428 {
10429 #if DPDK > 0
10430   unformat_input_t *i = vam->input;
10431   vl_api_ipsec_spd_add_del_entry_t *mp;
10432   f64 timeout;
10433   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10434   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10435   i32 priority = 0;
10436   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10437   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10438   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10439   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10440
10441   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10442   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10443   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10444   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10445   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10446   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10447
10448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10449     {
10450       if (unformat (i, "del"))
10451         is_add = 0;
10452       if (unformat (i, "outbound"))
10453         is_outbound = 1;
10454       if (unformat (i, "inbound"))
10455         is_outbound = 0;
10456       else if (unformat (i, "spd_id %d", &spd_id))
10457         ;
10458       else if (unformat (i, "sa_id %d", &sa_id))
10459         ;
10460       else if (unformat (i, "priority %d", &priority))
10461         ;
10462       else if (unformat (i, "protocol %d", &protocol))
10463         ;
10464       else if (unformat (i, "lport_start %d", &lport_start))
10465         ;
10466       else if (unformat (i, "lport_stop %d", &lport_stop))
10467         ;
10468       else if (unformat (i, "rport_start %d", &rport_start))
10469         ;
10470       else if (unformat (i, "rport_stop %d", &rport_stop))
10471         ;
10472       else
10473         if (unformat
10474             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10475         {
10476           is_ipv6 = 0;
10477           is_ip_any = 0;
10478         }
10479       else
10480         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10481         {
10482           is_ipv6 = 0;
10483           is_ip_any = 0;
10484         }
10485       else
10486         if (unformat
10487             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10488         {
10489           is_ipv6 = 0;
10490           is_ip_any = 0;
10491         }
10492       else
10493         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10494         {
10495           is_ipv6 = 0;
10496           is_ip_any = 0;
10497         }
10498       else
10499         if (unformat
10500             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10501         {
10502           is_ipv6 = 1;
10503           is_ip_any = 0;
10504         }
10505       else
10506         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10507         {
10508           is_ipv6 = 1;
10509           is_ip_any = 0;
10510         }
10511       else
10512         if (unformat
10513             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10514         {
10515           is_ipv6 = 1;
10516           is_ip_any = 0;
10517         }
10518       else
10519         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10520         {
10521           is_ipv6 = 1;
10522           is_ip_any = 0;
10523         }
10524       else
10525         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10526         {
10527           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10528             {
10529               clib_warning ("unsupported action: 'resolve'");
10530               return -99;
10531             }
10532         }
10533       else
10534         {
10535           clib_warning ("parse error '%U'", format_unformat_error, i);
10536           return -99;
10537         }
10538
10539     }
10540
10541   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10542
10543   mp->spd_id = ntohl (spd_id);
10544   mp->priority = ntohl (priority);
10545   mp->is_outbound = is_outbound;
10546
10547   mp->is_ipv6 = is_ipv6;
10548   if (is_ipv6 || is_ip_any)
10549     {
10550       clib_memcpy (mp->remote_address_start, &raddr6_start,
10551                    sizeof (ip6_address_t));
10552       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10553                    sizeof (ip6_address_t));
10554       clib_memcpy (mp->local_address_start, &laddr6_start,
10555                    sizeof (ip6_address_t));
10556       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10557                    sizeof (ip6_address_t));
10558     }
10559   else
10560     {
10561       clib_memcpy (mp->remote_address_start, &raddr4_start,
10562                    sizeof (ip4_address_t));
10563       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10564                    sizeof (ip4_address_t));
10565       clib_memcpy (mp->local_address_start, &laddr4_start,
10566                    sizeof (ip4_address_t));
10567       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10568                    sizeof (ip4_address_t));
10569     }
10570   mp->protocol = (u8) protocol;
10571   mp->local_port_start = ntohs ((u16) lport_start);
10572   mp->local_port_stop = ntohs ((u16) lport_stop);
10573   mp->remote_port_start = ntohs ((u16) rport_start);
10574   mp->remote_port_stop = ntohs ((u16) rport_stop);
10575   mp->policy = (u8) policy;
10576   mp->sa_id = ntohl (sa_id);
10577   mp->is_add = is_add;
10578   mp->is_ip_any = is_ip_any;
10579   S;
10580   W;
10581   /* NOTREACHED */
10582   return 0;
10583 #else
10584   clib_warning ("unsupported (no dpdk)");
10585   return -99;
10586 #endif
10587 }
10588
10589 static int
10590 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10591 {
10592 #if DPDK > 0
10593   unformat_input_t *i = vam->input;
10594   vl_api_ipsec_sad_add_del_entry_t *mp;
10595   f64 timeout;
10596   u32 sad_id = 0, spi = 0;
10597   u8 *ck = 0, *ik = 0;
10598   u8 is_add = 1;
10599
10600   u8 protocol = IPSEC_PROTOCOL_AH;
10601   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10602   u32 crypto_alg = 0, integ_alg = 0;
10603   ip4_address_t tun_src4;
10604   ip4_address_t tun_dst4;
10605   ip6_address_t tun_src6;
10606   ip6_address_t tun_dst6;
10607
10608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10609     {
10610       if (unformat (i, "del"))
10611         is_add = 0;
10612       else if (unformat (i, "sad_id %d", &sad_id))
10613         ;
10614       else if (unformat (i, "spi %d", &spi))
10615         ;
10616       else if (unformat (i, "esp"))
10617         protocol = IPSEC_PROTOCOL_ESP;
10618       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10619         {
10620           is_tunnel = 1;
10621           is_tunnel_ipv6 = 0;
10622         }
10623       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10624         {
10625           is_tunnel = 1;
10626           is_tunnel_ipv6 = 0;
10627         }
10628       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10629         {
10630           is_tunnel = 1;
10631           is_tunnel_ipv6 = 1;
10632         }
10633       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10634         {
10635           is_tunnel = 1;
10636           is_tunnel_ipv6 = 1;
10637         }
10638       else
10639         if (unformat
10640             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10641         {
10642           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10643               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10644             {
10645               clib_warning ("unsupported crypto-alg: '%U'",
10646                             format_ipsec_crypto_alg, crypto_alg);
10647               return -99;
10648             }
10649         }
10650       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10651         ;
10652       else
10653         if (unformat
10654             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10655         {
10656           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10657               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10658             {
10659               clib_warning ("unsupported integ-alg: '%U'",
10660                             format_ipsec_integ_alg, integ_alg);
10661               return -99;
10662             }
10663         }
10664       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10665         ;
10666       else
10667         {
10668           clib_warning ("parse error '%U'", format_unformat_error, i);
10669           return -99;
10670         }
10671
10672     }
10673
10674   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10675
10676   mp->sad_id = ntohl (sad_id);
10677   mp->is_add = is_add;
10678   mp->protocol = protocol;
10679   mp->spi = ntohl (spi);
10680   mp->is_tunnel = is_tunnel;
10681   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10682   mp->crypto_algorithm = crypto_alg;
10683   mp->integrity_algorithm = integ_alg;
10684   mp->crypto_key_length = vec_len (ck);
10685   mp->integrity_key_length = vec_len (ik);
10686
10687   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10688     mp->crypto_key_length = sizeof (mp->crypto_key);
10689
10690   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10691     mp->integrity_key_length = sizeof (mp->integrity_key);
10692
10693   if (ck)
10694     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10695   if (ik)
10696     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10697
10698   if (is_tunnel)
10699     {
10700       if (is_tunnel_ipv6)
10701         {
10702           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10703                        sizeof (ip6_address_t));
10704           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10705                        sizeof (ip6_address_t));
10706         }
10707       else
10708         {
10709           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10710                        sizeof (ip4_address_t));
10711           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10712                        sizeof (ip4_address_t));
10713         }
10714     }
10715
10716   S;
10717   W;
10718   /* NOTREACHED */
10719   return 0;
10720 #else
10721   clib_warning ("unsupported (no dpdk)");
10722   return -99;
10723 #endif
10724 }
10725
10726 static int
10727 api_ipsec_sa_set_key (vat_main_t * vam)
10728 {
10729 #if DPDK > 0
10730   unformat_input_t *i = vam->input;
10731   vl_api_ipsec_sa_set_key_t *mp;
10732   f64 timeout;
10733   u32 sa_id;
10734   u8 *ck = 0, *ik = 0;
10735
10736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10737     {
10738       if (unformat (i, "sa_id %d", &sa_id))
10739         ;
10740       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10741         ;
10742       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10743         ;
10744       else
10745         {
10746           clib_warning ("parse error '%U'", format_unformat_error, i);
10747           return -99;
10748         }
10749     }
10750
10751   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10752
10753   mp->sa_id = ntohl (sa_id);
10754   mp->crypto_key_length = vec_len (ck);
10755   mp->integrity_key_length = vec_len (ik);
10756
10757   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10758     mp->crypto_key_length = sizeof (mp->crypto_key);
10759
10760   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10761     mp->integrity_key_length = sizeof (mp->integrity_key);
10762
10763   if (ck)
10764     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10765   if (ik)
10766     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10767
10768   S;
10769   W;
10770   /* NOTREACHED */
10771   return 0;
10772 #else
10773   clib_warning ("unsupported (no dpdk)");
10774   return -99;
10775 #endif
10776 }
10777
10778 static int
10779 api_ikev2_profile_add_del (vat_main_t * vam)
10780 {
10781 #if DPDK > 0
10782   unformat_input_t *i = vam->input;
10783   vl_api_ikev2_profile_add_del_t *mp;
10784   f64 timeout;
10785   u8 is_add = 1;
10786   u8 *name = 0;
10787
10788   const char *valid_chars = "a-zA-Z0-9_";
10789
10790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10791     {
10792       if (unformat (i, "del"))
10793         is_add = 0;
10794       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10795         vec_add1 (name, 0);
10796       else
10797         {
10798           errmsg ("parse error '%U'", format_unformat_error, i);
10799           return -99;
10800         }
10801     }
10802
10803   if (!vec_len (name))
10804     {
10805       errmsg ("profile name must be specified");
10806       return -99;
10807     }
10808
10809   if (vec_len (name) > 64)
10810     {
10811       errmsg ("profile name too long");
10812       return -99;
10813     }
10814
10815   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10816
10817   clib_memcpy (mp->name, name, vec_len (name));
10818   mp->is_add = is_add;
10819   vec_free (name);
10820
10821   S;
10822   W;
10823   /* NOTREACHED */
10824   return 0;
10825 #else
10826   clib_warning ("unsupported (no dpdk)");
10827   return -99;
10828 #endif
10829 }
10830
10831 static int
10832 api_ikev2_profile_set_auth (vat_main_t * vam)
10833 {
10834 #if DPDK > 0
10835   unformat_input_t *i = vam->input;
10836   vl_api_ikev2_profile_set_auth_t *mp;
10837   f64 timeout;
10838   u8 *name = 0;
10839   u8 *data = 0;
10840   u32 auth_method = 0;
10841   u8 is_hex = 0;
10842
10843   const char *valid_chars = "a-zA-Z0-9_";
10844
10845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10846     {
10847       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10848         vec_add1 (name, 0);
10849       else if (unformat (i, "auth_method %U",
10850                          unformat_ikev2_auth_method, &auth_method))
10851         ;
10852       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10853         is_hex = 1;
10854       else if (unformat (i, "auth_data %v", &data))
10855         ;
10856       else
10857         {
10858           errmsg ("parse error '%U'", format_unformat_error, i);
10859           return -99;
10860         }
10861     }
10862
10863   if (!vec_len (name))
10864     {
10865       errmsg ("profile name must be specified");
10866       return -99;
10867     }
10868
10869   if (vec_len (name) > 64)
10870     {
10871       errmsg ("profile name too long");
10872       return -99;
10873     }
10874
10875   if (!vec_len (data))
10876     {
10877       errmsg ("auth_data must be specified");
10878       return -99;
10879     }
10880
10881   if (!auth_method)
10882     {
10883       errmsg ("auth_method must be specified");
10884       return -99;
10885     }
10886
10887   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10888
10889   mp->is_hex = is_hex;
10890   mp->auth_method = (u8) auth_method;
10891   mp->data_len = vec_len (data);
10892   clib_memcpy (mp->name, name, vec_len (name));
10893   clib_memcpy (mp->data, data, vec_len (data));
10894   vec_free (name);
10895   vec_free (data);
10896
10897   S;
10898   W;
10899   /* NOTREACHED */
10900   return 0;
10901 #else
10902   clib_warning ("unsupported (no dpdk)");
10903   return -99;
10904 #endif
10905 }
10906
10907 static int
10908 api_ikev2_profile_set_id (vat_main_t * vam)
10909 {
10910 #if DPDK > 0
10911   unformat_input_t *i = vam->input;
10912   vl_api_ikev2_profile_set_id_t *mp;
10913   f64 timeout;
10914   u8 *name = 0;
10915   u8 *data = 0;
10916   u8 is_local = 0;
10917   u32 id_type = 0;
10918   ip4_address_t ip4;
10919
10920   const char *valid_chars = "a-zA-Z0-9_";
10921
10922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10925         vec_add1 (name, 0);
10926       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10927         ;
10928       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10929         {
10930           data = vec_new (u8, 4);
10931           clib_memcpy (data, ip4.as_u8, 4);
10932         }
10933       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10934         ;
10935       else if (unformat (i, "id_data %v", &data))
10936         ;
10937       else if (unformat (i, "local"))
10938         is_local = 1;
10939       else if (unformat (i, "remote"))
10940         is_local = 0;
10941       else
10942         {
10943           errmsg ("parse error '%U'", format_unformat_error, i);
10944           return -99;
10945         }
10946     }
10947
10948   if (!vec_len (name))
10949     {
10950       errmsg ("profile name must be specified");
10951       return -99;
10952     }
10953
10954   if (vec_len (name) > 64)
10955     {
10956       errmsg ("profile name too long");
10957       return -99;
10958     }
10959
10960   if (!vec_len (data))
10961     {
10962       errmsg ("id_data must be specified");
10963       return -99;
10964     }
10965
10966   if (!id_type)
10967     {
10968       errmsg ("id_type must be specified");
10969       return -99;
10970     }
10971
10972   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
10973
10974   mp->is_local = is_local;
10975   mp->id_type = (u8) id_type;
10976   mp->data_len = vec_len (data);
10977   clib_memcpy (mp->name, name, vec_len (name));
10978   clib_memcpy (mp->data, data, vec_len (data));
10979   vec_free (name);
10980   vec_free (data);
10981
10982   S;
10983   W;
10984   /* NOTREACHED */
10985   return 0;
10986 #else
10987   clib_warning ("unsupported (no dpdk)");
10988   return -99;
10989 #endif
10990 }
10991
10992 static int
10993 api_ikev2_profile_set_ts (vat_main_t * vam)
10994 {
10995 #if DPDK > 0
10996   unformat_input_t *i = vam->input;
10997   vl_api_ikev2_profile_set_ts_t *mp;
10998   f64 timeout;
10999   u8 *name = 0;
11000   u8 is_local = 0;
11001   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11002   ip4_address_t start_addr, end_addr;
11003
11004   const char *valid_chars = "a-zA-Z0-9_";
11005
11006   start_addr.as_u32 = 0;
11007   end_addr.as_u32 = (u32) ~ 0;
11008
11009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11010     {
11011       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11012         vec_add1 (name, 0);
11013       else if (unformat (i, "protocol %d", &proto))
11014         ;
11015       else if (unformat (i, "start_port %d", &start_port))
11016         ;
11017       else if (unformat (i, "end_port %d", &end_port))
11018         ;
11019       else
11020         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11021         ;
11022       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11023         ;
11024       else if (unformat (i, "local"))
11025         is_local = 1;
11026       else if (unformat (i, "remote"))
11027         is_local = 0;
11028       else
11029         {
11030           errmsg ("parse error '%U'", format_unformat_error, i);
11031           return -99;
11032         }
11033     }
11034
11035   if (!vec_len (name))
11036     {
11037       errmsg ("profile name must be specified");
11038       return -99;
11039     }
11040
11041   if (vec_len (name) > 64)
11042     {
11043       errmsg ("profile name too long");
11044       return -99;
11045     }
11046
11047   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11048
11049   mp->is_local = is_local;
11050   mp->proto = (u8) proto;
11051   mp->start_port = (u16) start_port;
11052   mp->end_port = (u16) end_port;
11053   mp->start_addr = start_addr.as_u32;
11054   mp->end_addr = end_addr.as_u32;
11055   clib_memcpy (mp->name, name, vec_len (name));
11056   vec_free (name);
11057
11058   S;
11059   W;
11060   /* NOTREACHED */
11061   return 0;
11062 #else
11063   clib_warning ("unsupported (no dpdk)");
11064   return -99;
11065 #endif
11066 }
11067
11068 static int
11069 api_ikev2_set_local_key (vat_main_t * vam)
11070 {
11071 #if DPDK > 0
11072   unformat_input_t *i = vam->input;
11073   vl_api_ikev2_set_local_key_t *mp;
11074   f64 timeout;
11075   u8 *file = 0;
11076
11077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11078     {
11079       if (unformat (i, "file %v", &file))
11080         vec_add1 (file, 0);
11081       else
11082         {
11083           errmsg ("parse error '%U'", format_unformat_error, i);
11084           return -99;
11085         }
11086     }
11087
11088   if (!vec_len (file))
11089     {
11090       errmsg ("RSA key file must be specified");
11091       return -99;
11092     }
11093
11094   if (vec_len (file) > 256)
11095     {
11096       errmsg ("file name too long");
11097       return -99;
11098     }
11099
11100   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11101
11102   clib_memcpy (mp->key_file, file, vec_len (file));
11103   vec_free (file);
11104
11105   S;
11106   W;
11107   /* NOTREACHED */
11108   return 0;
11109 #else
11110   clib_warning ("unsupported (no dpdk)");
11111   return -99;
11112 #endif
11113 }
11114
11115 /*
11116  * MAP
11117  */
11118 static int
11119 api_map_add_domain (vat_main_t * vam)
11120 {
11121   unformat_input_t *i = vam->input;
11122   vl_api_map_add_domain_t *mp;
11123   f64 timeout;
11124
11125   ip4_address_t ip4_prefix;
11126   ip6_address_t ip6_prefix;
11127   ip6_address_t ip6_src;
11128   u32 num_m_args = 0;
11129   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11130     0, psid_length = 0;
11131   u8 is_translation = 0;
11132   u32 mtu = 0;
11133   u8 ip6_src_len = 128;
11134
11135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11138                     &ip4_prefix, &ip4_prefix_len))
11139         num_m_args++;
11140       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11141                          &ip6_prefix, &ip6_prefix_len))
11142         num_m_args++;
11143       else
11144         if (unformat
11145             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11146              &ip6_src_len))
11147         num_m_args++;
11148       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11149         num_m_args++;
11150       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11151         num_m_args++;
11152       else if (unformat (i, "psid-offset %d", &psid_offset))
11153         num_m_args++;
11154       else if (unformat (i, "psid-len %d", &psid_length))
11155         num_m_args++;
11156       else if (unformat (i, "mtu %d", &mtu))
11157         num_m_args++;
11158       else if (unformat (i, "map-t"))
11159         is_translation = 1;
11160       else
11161         {
11162           clib_warning ("parse error '%U'", format_unformat_error, i);
11163           return -99;
11164         }
11165     }
11166
11167   if (num_m_args != 6)
11168     {
11169       errmsg ("mandatory argument(s) missing\n");
11170       return -99;
11171     }
11172
11173   /* Construct the API message */
11174   M (MAP_ADD_DOMAIN, map_add_domain);
11175
11176   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11177   mp->ip4_prefix_len = ip4_prefix_len;
11178
11179   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11180   mp->ip6_prefix_len = ip6_prefix_len;
11181
11182   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11183   mp->ip6_src_prefix_len = ip6_src_len;
11184
11185   mp->ea_bits_len = ea_bits_len;
11186   mp->psid_offset = psid_offset;
11187   mp->psid_length = psid_length;
11188   mp->is_translation = is_translation;
11189   mp->mtu = htons (mtu);
11190
11191   /* send it... */
11192   S;
11193
11194   /* Wait for a reply, return good/bad news  */
11195   W;
11196 }
11197
11198 static int
11199 api_map_del_domain (vat_main_t * vam)
11200 {
11201   unformat_input_t *i = vam->input;
11202   vl_api_map_del_domain_t *mp;
11203   f64 timeout;
11204
11205   u32 num_m_args = 0;
11206   u32 index;
11207
11208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11209     {
11210       if (unformat (i, "index %d", &index))
11211         num_m_args++;
11212       else
11213         {
11214           clib_warning ("parse error '%U'", format_unformat_error, i);
11215           return -99;
11216         }
11217     }
11218
11219   if (num_m_args != 1)
11220     {
11221       errmsg ("mandatory argument(s) missing\n");
11222       return -99;
11223     }
11224
11225   /* Construct the API message */
11226   M (MAP_DEL_DOMAIN, map_del_domain);
11227
11228   mp->index = ntohl (index);
11229
11230   /* send it... */
11231   S;
11232
11233   /* Wait for a reply, return good/bad news  */
11234   W;
11235 }
11236
11237 static int
11238 api_map_add_del_rule (vat_main_t * vam)
11239 {
11240   unformat_input_t *i = vam->input;
11241   vl_api_map_add_del_rule_t *mp;
11242   f64 timeout;
11243   u8 is_add = 1;
11244   ip6_address_t ip6_dst;
11245   u32 num_m_args = 0, index, psid = 0;
11246
11247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11248     {
11249       if (unformat (i, "index %d", &index))
11250         num_m_args++;
11251       else if (unformat (i, "psid %d", &psid))
11252         num_m_args++;
11253       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11254         num_m_args++;
11255       else if (unformat (i, "del"))
11256         {
11257           is_add = 0;
11258         }
11259       else
11260         {
11261           clib_warning ("parse error '%U'", format_unformat_error, i);
11262           return -99;
11263         }
11264     }
11265
11266   /* Construct the API message */
11267   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11268
11269   mp->index = ntohl (index);
11270   mp->is_add = is_add;
11271   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11272   mp->psid = ntohs (psid);
11273
11274   /* send it... */
11275   S;
11276
11277   /* Wait for a reply, return good/bad news  */
11278   W;
11279 }
11280
11281 static int
11282 api_map_domain_dump (vat_main_t * vam)
11283 {
11284   vl_api_map_domain_dump_t *mp;
11285   f64 timeout;
11286
11287   /* Construct the API message */
11288   M (MAP_DOMAIN_DUMP, map_domain_dump);
11289
11290   /* send it... */
11291   S;
11292
11293   /* Use a control ping for synchronization */
11294   {
11295     vl_api_control_ping_t *mp;
11296     M (CONTROL_PING, control_ping);
11297     S;
11298   }
11299   W;
11300 }
11301
11302 static int
11303 api_map_rule_dump (vat_main_t * vam)
11304 {
11305   unformat_input_t *i = vam->input;
11306   vl_api_map_rule_dump_t *mp;
11307   f64 timeout;
11308   u32 domain_index = ~0;
11309
11310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (i, "index %u", &domain_index))
11313         ;
11314       else
11315         break;
11316     }
11317
11318   if (domain_index == ~0)
11319     {
11320       clib_warning ("parse error: domain index expected");
11321       return -99;
11322     }
11323
11324   /* Construct the API message */
11325   M (MAP_RULE_DUMP, map_rule_dump);
11326
11327   mp->domain_index = htonl (domain_index);
11328
11329   /* send it... */
11330   S;
11331
11332   /* Use a control ping for synchronization */
11333   {
11334     vl_api_control_ping_t *mp;
11335     M (CONTROL_PING, control_ping);
11336     S;
11337   }
11338   W;
11339 }
11340
11341 static void vl_api_map_add_domain_reply_t_handler
11342   (vl_api_map_add_domain_reply_t * mp)
11343 {
11344   vat_main_t *vam = &vat_main;
11345   i32 retval = ntohl (mp->retval);
11346
11347   if (vam->async_mode)
11348     {
11349       vam->async_errors += (retval < 0);
11350     }
11351   else
11352     {
11353       vam->retval = retval;
11354       vam->result_ready = 1;
11355     }
11356 }
11357
11358 static void vl_api_map_add_domain_reply_t_handler_json
11359   (vl_api_map_add_domain_reply_t * mp)
11360 {
11361   vat_main_t *vam = &vat_main;
11362   vat_json_node_t node;
11363
11364   vat_json_init_object (&node);
11365   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11366   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11367
11368   vat_json_print (vam->ofp, &node);
11369   vat_json_free (&node);
11370
11371   vam->retval = ntohl (mp->retval);
11372   vam->result_ready = 1;
11373 }
11374
11375 static int
11376 api_get_first_msg_id (vat_main_t * vam)
11377 {
11378   vl_api_get_first_msg_id_t *mp;
11379   f64 timeout;
11380   unformat_input_t *i = vam->input;
11381   u8 *name;
11382   u8 name_set = 0;
11383
11384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11385     {
11386       if (unformat (i, "client %s", &name))
11387         name_set = 1;
11388       else
11389         break;
11390     }
11391
11392   if (name_set == 0)
11393     {
11394       errmsg ("missing client name\n");
11395       return -99;
11396     }
11397   vec_add1 (name, 0);
11398
11399   if (vec_len (name) > 63)
11400     {
11401       errmsg ("client name too long\n");
11402       return -99;
11403     }
11404
11405   M (GET_FIRST_MSG_ID, get_first_msg_id);
11406   clib_memcpy (mp->name, name, vec_len (name));
11407   S;
11408   W;
11409   /* NOTREACHED */
11410   return 0;
11411 }
11412
11413 static int
11414 api_cop_interface_enable_disable (vat_main_t * vam)
11415 {
11416   unformat_input_t *line_input = vam->input;
11417   vl_api_cop_interface_enable_disable_t *mp;
11418   f64 timeout;
11419   u32 sw_if_index = ~0;
11420   u8 enable_disable = 1;
11421
11422   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11423     {
11424       if (unformat (line_input, "disable"))
11425         enable_disable = 0;
11426       if (unformat (line_input, "enable"))
11427         enable_disable = 1;
11428       else if (unformat (line_input, "%U", unformat_sw_if_index,
11429                          vam, &sw_if_index))
11430         ;
11431       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11432         ;
11433       else
11434         break;
11435     }
11436
11437   if (sw_if_index == ~0)
11438     {
11439       errmsg ("missing interface name or sw_if_index\n");
11440       return -99;
11441     }
11442
11443   /* Construct the API message */
11444   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11445   mp->sw_if_index = ntohl (sw_if_index);
11446   mp->enable_disable = enable_disable;
11447
11448   /* send it... */
11449   S;
11450   /* Wait for the reply */
11451   W;
11452 }
11453
11454 static int
11455 api_cop_whitelist_enable_disable (vat_main_t * vam)
11456 {
11457   unformat_input_t *line_input = vam->input;
11458   vl_api_cop_whitelist_enable_disable_t *mp;
11459   f64 timeout;
11460   u32 sw_if_index = ~0;
11461   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11462   u32 fib_id = 0;
11463
11464   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11465     {
11466       if (unformat (line_input, "ip4"))
11467         ip4 = 1;
11468       else if (unformat (line_input, "ip6"))
11469         ip6 = 1;
11470       else if (unformat (line_input, "default"))
11471         default_cop = 1;
11472       else if (unformat (line_input, "%U", unformat_sw_if_index,
11473                          vam, &sw_if_index))
11474         ;
11475       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11476         ;
11477       else if (unformat (line_input, "fib-id %d", &fib_id))
11478         ;
11479       else
11480         break;
11481     }
11482
11483   if (sw_if_index == ~0)
11484     {
11485       errmsg ("missing interface name or sw_if_index\n");
11486       return -99;
11487     }
11488
11489   /* Construct the API message */
11490   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11491   mp->sw_if_index = ntohl (sw_if_index);
11492   mp->fib_id = ntohl (fib_id);
11493   mp->ip4 = ip4;
11494   mp->ip6 = ip6;
11495   mp->default_cop = default_cop;
11496
11497   /* send it... */
11498   S;
11499   /* Wait for the reply */
11500   W;
11501 }
11502
11503 static int
11504 api_get_node_graph (vat_main_t * vam)
11505 {
11506   vl_api_get_node_graph_t *mp;
11507   f64 timeout;
11508
11509   M (GET_NODE_GRAPH, get_node_graph);
11510
11511   /* send it... */
11512   S;
11513   /* Wait for the reply */
11514   W;
11515 }
11516
11517 /* *INDENT-OFF* */
11518 /** Used for parsing LISP eids */
11519 typedef CLIB_PACKED(struct{
11520   u8 addr[16];   /**< eid address */
11521   u32 len;       /**< prefix length if IP */
11522   u8 type;      /**< type of eid */
11523 }) lisp_eid_vat_t;
11524 /* *INDENT-ON* */
11525
11526 static uword
11527 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11528 {
11529   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11530
11531   memset (a, 0, sizeof (a[0]));
11532
11533   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11534     {
11535       a->type = 0;              /* ipv4 type */
11536     }
11537   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11538     {
11539       a->type = 1;              /* ipv6 type */
11540     }
11541   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11542     {
11543       a->type = 2;              /* mac type */
11544     }
11545   else
11546     {
11547       return 0;
11548     }
11549
11550   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11551     {
11552       return 0;
11553     }
11554
11555   return 1;
11556 }
11557
11558 static int
11559 lisp_eid_size_vat (u8 type)
11560 {
11561   switch (type)
11562     {
11563     case 0:
11564       return 4;
11565     case 1:
11566       return 16;
11567     case 2:
11568       return 6;
11569     }
11570   return 0;
11571 }
11572
11573 static void
11574 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11575 {
11576   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11577 }
11578
11579 /* *INDENT-OFF* */
11580 /** Used for transferring locators via VPP API */
11581 typedef CLIB_PACKED(struct
11582 {
11583   u32 sw_if_index; /**< locator sw_if_index */
11584   u8 priority; /**< locator priority */
11585   u8 weight;   /**< locator weight */
11586 }) ls_locator_t;
11587 /* *INDENT-ON* */
11588
11589 static int
11590 api_lisp_add_del_locator_set (vat_main_t * vam)
11591 {
11592   unformat_input_t *input = vam->input;
11593   vl_api_lisp_add_del_locator_set_t *mp;
11594   f64 timeout = ~0;
11595   u8 is_add = 1;
11596   u8 *locator_set_name = NULL;
11597   u8 locator_set_name_set = 0;
11598   ls_locator_t locator, *locators = 0;
11599   u32 sw_if_index, priority, weight;
11600
11601   /* Parse args required to build the message */
11602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11603     {
11604       if (unformat (input, "del"))
11605         {
11606           is_add = 0;
11607         }
11608       else if (unformat (input, "locator-set %s", &locator_set_name))
11609         {
11610           locator_set_name_set = 1;
11611         }
11612       else if (unformat (input, "sw_if_index %u p %u w %u",
11613                          &sw_if_index, &priority, &weight))
11614         {
11615           locator.sw_if_index = htonl (sw_if_index);
11616           locator.priority = priority;
11617           locator.weight = weight;
11618           vec_add1 (locators, locator);
11619         }
11620       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11621                          vam, &sw_if_index, &priority, &weight))
11622         {
11623           locator.sw_if_index = htonl (sw_if_index);
11624           locator.priority = priority;
11625           locator.weight = weight;
11626           vec_add1 (locators, locator);
11627         }
11628       else
11629         break;
11630     }
11631
11632   if (locator_set_name_set == 0)
11633     {
11634       errmsg ("missing locator-set name");
11635       vec_free (locators);
11636       return -99;
11637     }
11638
11639   if (vec_len (locator_set_name) > 64)
11640     {
11641       errmsg ("locator-set name too long\n");
11642       vec_free (locator_set_name);
11643       vec_free (locators);
11644       return -99;
11645     }
11646   vec_add1 (locator_set_name, 0);
11647
11648   /* Construct the API message */
11649   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11650
11651   mp->is_add = is_add;
11652   clib_memcpy (mp->locator_set_name, locator_set_name,
11653                vec_len (locator_set_name));
11654   vec_free (locator_set_name);
11655
11656   mp->locator_num = vec_len (locators);
11657   if (locators)
11658     clib_memcpy (mp->locators, locators,
11659                  (sizeof (ls_locator_t) * vec_len (locators)));
11660   vec_free (locators);
11661
11662   /* send it... */
11663   S;
11664
11665   /* Wait for a reply... */
11666   W;
11667
11668   /* NOTREACHED */
11669   return 0;
11670 }
11671
11672 static int
11673 api_lisp_add_del_locator (vat_main_t * vam)
11674 {
11675   unformat_input_t *input = vam->input;
11676   vl_api_lisp_add_del_locator_t *mp;
11677   f64 timeout = ~0;
11678   u32 tmp_if_index = ~0;
11679   u32 sw_if_index = ~0;
11680   u8 sw_if_index_set = 0;
11681   u8 sw_if_index_if_name_set = 0;
11682   u32 priority = ~0;
11683   u8 priority_set = 0;
11684   u32 weight = ~0;
11685   u8 weight_set = 0;
11686   u8 is_add = 1;
11687   u8 *locator_set_name = NULL;
11688   u8 locator_set_name_set = 0;
11689
11690   /* Parse args required to build the message */
11691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11692     {
11693       if (unformat (input, "del"))
11694         {
11695           is_add = 0;
11696         }
11697       else if (unformat (input, "locator-set %s", &locator_set_name))
11698         {
11699           locator_set_name_set = 1;
11700         }
11701       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11702                          &tmp_if_index))
11703         {
11704           sw_if_index_if_name_set = 1;
11705           sw_if_index = tmp_if_index;
11706         }
11707       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11708         {
11709           sw_if_index_set = 1;
11710           sw_if_index = tmp_if_index;
11711         }
11712       else if (unformat (input, "p %d", &priority))
11713         {
11714           priority_set = 1;
11715         }
11716       else if (unformat (input, "w %d", &weight))
11717         {
11718           weight_set = 1;
11719         }
11720       else
11721         break;
11722     }
11723
11724   if (locator_set_name_set == 0)
11725     {
11726       errmsg ("missing locator-set name");
11727       return -99;
11728     }
11729
11730   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11731     {
11732       errmsg ("missing sw_if_index");
11733       vec_free (locator_set_name);
11734       return -99;
11735     }
11736
11737   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11738     {
11739       errmsg ("cannot use both params interface name and sw_if_index");
11740       vec_free (locator_set_name);
11741       return -99;
11742     }
11743
11744   if (priority_set == 0)
11745     {
11746       errmsg ("missing locator-set priority\n");
11747       vec_free (locator_set_name);
11748       return -99;
11749     }
11750
11751   if (weight_set == 0)
11752     {
11753       errmsg ("missing locator-set weight\n");
11754       vec_free (locator_set_name);
11755       return -99;
11756     }
11757
11758   if (vec_len (locator_set_name) > 64)
11759     {
11760       errmsg ("locator-set name too long\n");
11761       vec_free (locator_set_name);
11762       return -99;
11763     }
11764   vec_add1 (locator_set_name, 0);
11765
11766   /* Construct the API message */
11767   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11768
11769   mp->is_add = is_add;
11770   mp->sw_if_index = ntohl (sw_if_index);
11771   mp->priority = priority;
11772   mp->weight = weight;
11773   clib_memcpy (mp->locator_set_name, locator_set_name,
11774                vec_len (locator_set_name));
11775   vec_free (locator_set_name);
11776
11777   /* send it... */
11778   S;
11779
11780   /* Wait for a reply... */
11781   W;
11782
11783   /* NOTREACHED */
11784   return 0;
11785 }
11786
11787 static int
11788 api_lisp_add_del_local_eid (vat_main_t * vam)
11789 {
11790   unformat_input_t *input = vam->input;
11791   vl_api_lisp_add_del_local_eid_t *mp;
11792   f64 timeout = ~0;
11793   u8 is_add = 1;
11794   u8 eid_set = 0;
11795   lisp_eid_vat_t _eid, *eid = &_eid;
11796   u8 *locator_set_name = 0;
11797   u8 locator_set_name_set = 0;
11798   u32 vni = 0;
11799
11800   /* Parse args required to build the message */
11801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11802     {
11803       if (unformat (input, "del"))
11804         {
11805           is_add = 0;
11806         }
11807       else if (unformat (input, "vni %d", &vni))
11808         {
11809           ;
11810         }
11811       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11812         {
11813           eid_set = 1;
11814         }
11815       else if (unformat (input, "locator-set %s", &locator_set_name))
11816         {
11817           locator_set_name_set = 1;
11818         }
11819       else
11820         break;
11821     }
11822
11823   if (locator_set_name_set == 0)
11824     {
11825       errmsg ("missing locator-set name\n");
11826       return -99;
11827     }
11828
11829   if (0 == eid_set)
11830     {
11831       errmsg ("EID address not set!");
11832       vec_free (locator_set_name);
11833       return -99;
11834     }
11835
11836   if (vec_len (locator_set_name) > 64)
11837     {
11838       errmsg ("locator-set name too long\n");
11839       vec_free (locator_set_name);
11840       return -99;
11841     }
11842   vec_add1 (locator_set_name, 0);
11843
11844   /* Construct the API message */
11845   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11846
11847   mp->is_add = is_add;
11848   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11849   mp->eid_type = eid->type;
11850   mp->prefix_len = eid->len;
11851   mp->vni = clib_host_to_net_u32 (vni);
11852   clib_memcpy (mp->locator_set_name, locator_set_name,
11853                vec_len (locator_set_name));
11854
11855   vec_free (locator_set_name);
11856
11857   /* send it... */
11858   S;
11859
11860   /* Wait for a reply... */
11861   W;
11862
11863   /* NOTREACHED */
11864   return 0;
11865 }
11866
11867 /* *INDENT-OFF* */
11868 /** Used for transferring locators via VPP API */
11869 typedef CLIB_PACKED(struct
11870 {
11871   u8 is_ip4; /**< is locator an IPv4 address? */
11872   u8 priority; /**< locator priority */
11873   u8 weight;   /**< locator weight */
11874   u8 addr[16]; /**< IPv4/IPv6 address */
11875 }) rloc_t;
11876 /* *INDENT-ON* */
11877
11878 static int
11879 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11880 {
11881   unformat_input_t *input = vam->input;
11882   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11883   f64 timeout = ~0;
11884   u8 is_add = 1;
11885   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11886   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11887   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11888   u32 action = ~0, p, w;
11889   ip4_address_t rmt_rloc4, lcl_rloc4;
11890   ip6_address_t rmt_rloc6, lcl_rloc6;
11891   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11892
11893   memset (&rloc, 0, sizeof (rloc));
11894
11895   /* Parse args required to build the message */
11896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (input, "del"))
11899         {
11900           is_add = 0;
11901         }
11902       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11903         {
11904           rmt_eid_set = 1;
11905         }
11906       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11907         {
11908           lcl_eid_set = 1;
11909         }
11910       else if (unformat (input, "p %d w %d", &p, &w))
11911         {
11912           if (!curr_rloc)
11913             {
11914               errmsg ("No RLOC configured for setting priority/weight!");
11915               return -99;
11916             }
11917           curr_rloc->priority = p;
11918           curr_rloc->weight = w;
11919         }
11920       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11921                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11922         {
11923           rloc.is_ip4 = 1;
11924
11925           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11926           rloc.priority = rloc.weight = 0;
11927           vec_add1 (lcl_locs, rloc);
11928
11929           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11930           vec_add1 (rmt_locs, rloc);
11931           /* priority and weight saved in rmt loc */
11932           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11933         }
11934       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11935                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11936         {
11937           rloc.is_ip4 = 0;
11938           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11939           rloc.priority = rloc.weight = 0;
11940           vec_add1 (lcl_locs, rloc);
11941
11942           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
11943           vec_add1 (rmt_locs, rloc);
11944           /* priority and weight saved in rmt loc */
11945           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11946         }
11947       else if (unformat (input, "action %d", &action))
11948         {
11949           ;
11950         }
11951       else
11952         {
11953           clib_warning ("parse error '%U'", format_unformat_error, input);
11954           return -99;
11955         }
11956     }
11957
11958   if (!rmt_eid_set)
11959     {
11960       errmsg ("remote eid addresses not set\n");
11961       return -99;
11962     }
11963
11964   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
11965     {
11966       errmsg ("eid types don't match\n");
11967       return -99;
11968     }
11969
11970   if (0 == rmt_locs && (u32) ~ 0 == action)
11971     {
11972       errmsg ("action not set for negative mapping\n");
11973       return -99;
11974     }
11975
11976   /* Construct the API message */
11977   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
11978
11979   mp->is_add = is_add;
11980   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
11981   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
11982   mp->eid_type = rmt_eid->type;
11983   mp->rmt_len = rmt_eid->len;
11984   mp->lcl_len = lcl_eid->len;
11985   mp->action = action;
11986
11987   if (0 != rmt_locs && 0 != lcl_locs)
11988     {
11989       mp->loc_num = vec_len (rmt_locs);
11990       clib_memcpy (mp->lcl_locs, lcl_locs,
11991                    (sizeof (rloc_t) * vec_len (lcl_locs)));
11992       clib_memcpy (mp->rmt_locs, rmt_locs,
11993                    (sizeof (rloc_t) * vec_len (rmt_locs)));
11994     }
11995   vec_free (lcl_locs);
11996   vec_free (rmt_locs);
11997
11998   /* send it... */
11999   S;
12000
12001   /* Wait for a reply... */
12002   W;
12003
12004   /* NOTREACHED */
12005   return 0;
12006 }
12007
12008 static int
12009 api_lisp_add_del_map_resolver (vat_main_t * vam)
12010 {
12011   unformat_input_t *input = vam->input;
12012   vl_api_lisp_add_del_map_resolver_t *mp;
12013   f64 timeout = ~0;
12014   u8 is_add = 1;
12015   u8 ipv4_set = 0;
12016   u8 ipv6_set = 0;
12017   ip4_address_t ipv4;
12018   ip6_address_t ipv6;
12019
12020   /* Parse args required to build the message */
12021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12022     {
12023       if (unformat (input, "del"))
12024         {
12025           is_add = 0;
12026         }
12027       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12028         {
12029           ipv4_set = 1;
12030         }
12031       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12032         {
12033           ipv6_set = 1;
12034         }
12035       else
12036         break;
12037     }
12038
12039   if (ipv4_set && ipv6_set)
12040     {
12041       errmsg ("both eid v4 and v6 addresses set\n");
12042       return -99;
12043     }
12044
12045   if (!ipv4_set && !ipv6_set)
12046     {
12047       errmsg ("eid addresses not set\n");
12048       return -99;
12049     }
12050
12051   /* Construct the API message */
12052   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12053
12054   mp->is_add = is_add;
12055   if (ipv6_set)
12056     {
12057       mp->is_ipv6 = 1;
12058       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12059     }
12060   else
12061     {
12062       mp->is_ipv6 = 0;
12063       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12064     }
12065
12066   /* send it... */
12067   S;
12068
12069   /* Wait for a reply... */
12070   W;
12071
12072   /* NOTREACHED */
12073   return 0;
12074 }
12075
12076 static int
12077 api_lisp_gpe_enable_disable (vat_main_t * vam)
12078 {
12079   unformat_input_t *input = vam->input;
12080   vl_api_lisp_gpe_enable_disable_t *mp;
12081   f64 timeout = ~0;
12082   u8 is_set = 0;
12083   u8 is_en = 1;
12084
12085   /* Parse args required to build the message */
12086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12087     {
12088       if (unformat (input, "enable"))
12089         {
12090           is_set = 1;
12091           is_en = 1;
12092         }
12093       else if (unformat (input, "disable"))
12094         {
12095           is_set = 1;
12096           is_en = 0;
12097         }
12098       else
12099         break;
12100     }
12101
12102   if (is_set == 0)
12103     {
12104       errmsg ("Value not set\n");
12105       return -99;
12106     }
12107
12108   /* Construct the API message */
12109   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12110
12111   mp->is_en = is_en;
12112
12113   /* send it... */
12114   S;
12115
12116   /* Wait for a reply... */
12117   W;
12118
12119   /* NOTREACHED */
12120   return 0;
12121 }
12122
12123 static int
12124 api_lisp_enable_disable (vat_main_t * vam)
12125 {
12126   unformat_input_t *input = vam->input;
12127   vl_api_lisp_enable_disable_t *mp;
12128   f64 timeout = ~0;
12129   u8 is_set = 0;
12130   u8 is_en = 0;
12131
12132   /* Parse args required to build the message */
12133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12134     {
12135       if (unformat (input, "enable"))
12136         {
12137           is_set = 1;
12138           is_en = 1;
12139         }
12140       else if (unformat (input, "disable"))
12141         {
12142           is_set = 1;
12143         }
12144       else
12145         break;
12146     }
12147
12148   if (!is_set)
12149     {
12150       errmsg ("Value not set\n");
12151       return -99;
12152     }
12153
12154   /* Construct the API message */
12155   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12156
12157   mp->is_en = is_en;
12158
12159   /* send it... */
12160   S;
12161
12162   /* Wait for a reply... */
12163   W;
12164
12165   /* NOTREACHED */
12166   return 0;
12167 }
12168
12169 /**
12170  * Enable/disable LISP proxy ITR.
12171  *
12172  * @param vam vpp API test context
12173  * @return return code
12174  */
12175 static int
12176 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12177 {
12178   f64 timeout = ~0;
12179   u8 ls_name_set = 0;
12180   unformat_input_t *input = vam->input;
12181   vl_api_lisp_pitr_set_locator_set_t *mp;
12182   u8 is_add = 1;
12183   u8 *ls_name = 0;
12184
12185   /* Parse args required to build the message */
12186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12187     {
12188       if (unformat (input, "del"))
12189         is_add = 0;
12190       else if (unformat (input, "locator-set %s", &ls_name))
12191         ls_name_set = 1;
12192       else
12193         {
12194           errmsg ("parse error '%U'", format_unformat_error, input);
12195           return -99;
12196         }
12197     }
12198
12199   if (!ls_name_set)
12200     {
12201       errmsg ("locator-set name not set!");
12202       return -99;
12203     }
12204
12205   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12206
12207   mp->is_add = is_add;
12208   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12209   vec_free (ls_name);
12210
12211   /* send */
12212   S;
12213
12214   /* wait for reply */
12215   W;
12216
12217   /* notreached */
12218   return 0;
12219 }
12220
12221 static int
12222 api_show_lisp_pitr (vat_main_t * vam)
12223 {
12224   vl_api_show_lisp_pitr_t *mp;
12225   f64 timeout = ~0;
12226
12227   if (!vam->json_output)
12228     {
12229       fformat (vam->ofp, "%=20s\n", "lisp status:");
12230     }
12231
12232   M (SHOW_LISP_PITR, show_lisp_pitr);
12233   /* send it... */
12234   S;
12235
12236   /* Wait for a reply... */
12237   W;
12238
12239   /* NOTREACHED */
12240   return 0;
12241 }
12242
12243 /**
12244  * Add/delete mapping between vni and vrf
12245  */
12246 static int
12247 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12248 {
12249   f64 timeout = ~0;
12250   unformat_input_t *input = vam->input;
12251   vl_api_lisp_eid_table_add_del_map_t *mp;
12252   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12253   u32 vni, vrf, bd_index;
12254
12255   /* Parse args required to build the message */
12256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (input, "del"))
12259         is_add = 0;
12260       else if (unformat (input, "vrf %d", &vrf))
12261         vrf_set = 1;
12262       else if (unformat (input, "bd_index %d", &bd_index))
12263         bd_index_set = 1;
12264       else if (unformat (input, "vni %d", &vni))
12265         vni_set = 1;
12266       else
12267         break;
12268     }
12269
12270   if (!vni_set || (!vrf_set && !bd_index_set))
12271     {
12272       errmsg ("missing arguments!");
12273       return -99;
12274     }
12275
12276   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12277
12278   mp->is_add = is_add;
12279   mp->vni = htonl (vni);
12280   mp->dp_table = htonl (vrf);
12281   mp->is_l2 = bd_index_set;
12282
12283   /* send */
12284   S;
12285
12286   /* wait for reply */
12287   W;
12288
12289   /* notreached */
12290   return 0;
12291 }
12292
12293 /**
12294  * Add/del remote mapping to/from LISP control plane
12295  *
12296  * @param vam vpp API test context
12297  * @return return code
12298  */
12299 static int
12300 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12301 {
12302   unformat_input_t *input = vam->input;
12303   vl_api_lisp_add_del_remote_mapping_t *mp;
12304   f64 timeout = ~0;
12305   u32 vni = 0;
12306   //TODO: seid need remove
12307   lisp_eid_vat_t _eid, *eid = &_eid;
12308   lisp_eid_vat_t _seid, *seid = &_seid;
12309   u8 is_add = 1, del_all = 0, eid_set = 0;
12310   u32 action = ~0, p, w;
12311   ip4_address_t rloc4;
12312   ip6_address_t rloc6;
12313   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12314
12315   memset (&rloc, 0, sizeof (rloc));
12316
12317   /* Parse args required to build the message */
12318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12319     {
12320       if (unformat (input, "del-all"))
12321         {
12322           del_all = 1;
12323         }
12324       else if (unformat (input, "del"))
12325         {
12326           is_add = 0;
12327         }
12328       else if (unformat (input, "add"))
12329         {
12330           is_add = 1;
12331         }
12332       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12333         {
12334           eid_set = 1;
12335         }
12336       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12337         {
12338           //TODO: Need remove, but first must be remove from CSIT test
12339         }
12340       else if (unformat (input, "vni %d", &vni))
12341         {
12342           ;
12343         }
12344       else if (unformat (input, "p %d w %d", &p, &w))
12345         {
12346           if (!curr_rloc)
12347             {
12348               errmsg ("No RLOC configured for setting priority/weight!");
12349               return -99;
12350             }
12351           curr_rloc->priority = p;
12352           curr_rloc->weight = w;
12353         }
12354       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12355         {
12356           rloc.is_ip4 = 1;
12357           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12358           vec_add1 (rlocs, rloc);
12359           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12360         }
12361       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12362         {
12363           rloc.is_ip4 = 0;
12364           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12365           vec_add1 (rlocs, rloc);
12366           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12367         }
12368       else if (unformat (input, "action %d", &action))
12369         {
12370           ;
12371         }
12372       else
12373         {
12374           clib_warning ("parse error '%U'", format_unformat_error, input);
12375           return -99;
12376         }
12377     }
12378
12379   if (0 == eid_set)
12380     {
12381       errmsg ("missing params!");
12382       return -99;
12383     }
12384
12385   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12386     {
12387       errmsg ("no action set for negative map-reply!");
12388       return -99;
12389     }
12390
12391   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12392   mp->is_add = is_add;
12393   mp->vni = htonl (vni);
12394   mp->action = (u8) action;
12395   mp->eid_len = eid->len;
12396   mp->del_all = del_all;
12397   mp->eid_type = eid->type;
12398   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12399
12400   mp->rloc_num = vec_len (rlocs);
12401   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12402   vec_free (rlocs);
12403
12404   /* send it... */
12405   S;
12406
12407   /* Wait for a reply... */
12408   W;
12409
12410   /* NOTREACHED */
12411   return 0;
12412 }
12413
12414 /**
12415  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12416  * forwarding entries in data-plane accordingly.
12417  *
12418  * @param vam vpp API test context
12419  * @return return code
12420  */
12421 static int
12422 api_lisp_add_del_adjacency (vat_main_t * vam)
12423 {
12424   unformat_input_t *input = vam->input;
12425   vl_api_lisp_add_del_adjacency_t *mp;
12426   f64 timeout = ~0;
12427   u32 vni = 0;
12428   ip4_address_t seid4, deid4;
12429   ip6_address_t seid6, deid6;
12430   u8 deid_mac[6] = { 0 };
12431   u8 seid_mac[6] = { 0 };
12432   u8 deid_type, seid_type;
12433   u32 seid_len = 0, deid_len = 0, len;
12434   u8 is_add = 1;
12435
12436   seid_type = deid_type = (u8) ~ 0;
12437
12438   /* Parse args required to build the message */
12439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12440     {
12441       if (unformat (input, "del"))
12442         {
12443           is_add = 0;
12444         }
12445       else if (unformat (input, "add"))
12446         {
12447           is_add = 1;
12448         }
12449       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12450                          &deid4, &len))
12451         {
12452           deid_type = 0;        /* ipv4 */
12453           deid_len = len;
12454         }
12455       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12456                          &deid6, &len))
12457         {
12458           deid_type = 1;        /* ipv6 */
12459           deid_len = len;
12460         }
12461       else if (unformat (input, "deid %U", unformat_ethernet_address,
12462                          deid_mac))
12463         {
12464           deid_type = 2;        /* mac */
12465         }
12466       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12467                          &seid4, &len))
12468         {
12469           seid_type = 0;        /* ipv4 */
12470           seid_len = len;
12471         }
12472       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12473                          &seid6, &len))
12474         {
12475           seid_type = 1;        /* ipv6 */
12476           seid_len = len;
12477         }
12478       else if (unformat (input, "seid %U", unformat_ethernet_address,
12479                          seid_mac))
12480         {
12481           seid_type = 2;        /* mac */
12482         }
12483       else if (unformat (input, "vni %d", &vni))
12484         {
12485           ;
12486         }
12487       else
12488         {
12489           errmsg ("parse error '%U'", format_unformat_error, input);
12490           return -99;
12491         }
12492     }
12493
12494   if ((u8) ~ 0 == deid_type)
12495     {
12496       errmsg ("missing params!");
12497       return -99;
12498     }
12499
12500   if (seid_type != deid_type)
12501     {
12502       errmsg ("source and destination EIDs are of different types!");
12503       return -99;
12504     }
12505
12506   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12507   mp->is_add = is_add;
12508   mp->vni = htonl (vni);
12509   mp->seid_len = seid_len;
12510   mp->deid_len = deid_len;
12511   mp->eid_type = deid_type;
12512
12513   switch (mp->eid_type)
12514     {
12515     case 0:
12516       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12517       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12518       break;
12519     case 1:
12520       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12521       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12522       break;
12523     case 2:
12524       clib_memcpy (mp->seid, seid_mac, 6);
12525       clib_memcpy (mp->deid, deid_mac, 6);
12526       break;
12527     default:
12528       errmsg ("unknown EID type %d!", mp->eid_type);
12529       return 0;
12530     }
12531
12532   /* send it... */
12533   S;
12534
12535   /* Wait for a reply... */
12536   W;
12537
12538   /* NOTREACHED */
12539   return 0;
12540 }
12541
12542 static int
12543 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12544 {
12545   unformat_input_t *input = vam->input;
12546   vl_api_lisp_gpe_add_del_iface_t *mp;
12547   f64 timeout = ~0;
12548   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12549   u32 dp_table = 0, vni = 0;
12550
12551   /* Parse args required to build the message */
12552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12553     {
12554       if (unformat (input, "up"))
12555         {
12556           action_set = 1;
12557           is_add = 1;
12558         }
12559       else if (unformat (input, "down"))
12560         {
12561           action_set = 1;
12562           is_add = 0;
12563         }
12564       else if (unformat (input, "table_id %d", &dp_table))
12565         {
12566           dp_table_set = 1;
12567         }
12568       else if (unformat (input, "bd_id %d", &dp_table))
12569         {
12570           dp_table_set = 1;
12571           is_l2 = 1;
12572         }
12573       else if (unformat (input, "vni %d", &vni))
12574         {
12575           vni_set = 1;
12576         }
12577       else
12578         break;
12579     }
12580
12581   if (action_set == 0)
12582     {
12583       errmsg ("Action not set\n");
12584       return -99;
12585     }
12586   if (dp_table_set == 0 || vni_set == 0)
12587     {
12588       errmsg ("vni and dp_table must be set\n");
12589       return -99;
12590     }
12591
12592   /* Construct the API message */
12593   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12594
12595   mp->is_add = is_add;
12596   mp->dp_table = dp_table;
12597   mp->is_l2 = is_l2;
12598   mp->vni = vni;
12599
12600   /* send it... */
12601   S;
12602
12603   /* Wait for a reply... */
12604   W;
12605
12606   /* NOTREACHED */
12607   return 0;
12608 }
12609
12610 /**
12611  * Add/del map request itr rlocs from LISP control plane and updates
12612  *
12613  * @param vam vpp API test context
12614  * @return return code
12615  */
12616 static int
12617 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12618 {
12619   unformat_input_t *input = vam->input;
12620   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12621   f64 timeout = ~0;
12622   u8 *locator_set_name = 0;
12623   u8 locator_set_name_set = 0;
12624   u8 is_add = 1;
12625
12626   /* Parse args required to build the message */
12627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12628     {
12629       if (unformat (input, "del"))
12630         {
12631           is_add = 0;
12632         }
12633       else if (unformat (input, "%_%v%_", &locator_set_name))
12634         {
12635           locator_set_name_set = 1;
12636         }
12637       else
12638         {
12639           clib_warning ("parse error '%U'", format_unformat_error, input);
12640           return -99;
12641         }
12642     }
12643
12644   if (is_add && !locator_set_name_set)
12645     {
12646       errmsg ("itr-rloc is not set!");
12647       return -99;
12648     }
12649
12650   if (is_add && vec_len (locator_set_name) > 64)
12651     {
12652       errmsg ("itr-rloc locator-set name too long\n");
12653       vec_free (locator_set_name);
12654       return -99;
12655     }
12656
12657   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12658   mp->is_add = is_add;
12659   if (is_add)
12660     {
12661       clib_memcpy (mp->locator_set_name, locator_set_name,
12662                    vec_len (locator_set_name));
12663     }
12664   else
12665     {
12666       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12667     }
12668   vec_free (locator_set_name);
12669
12670   /* send it... */
12671   S;
12672
12673   /* Wait for a reply... */
12674   W;
12675
12676   /* NOTREACHED */
12677   return 0;
12678 }
12679
12680 static int
12681 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12682                             u8 filter)
12683 {
12684   vl_api_lisp_locator_dump_t *mp;
12685   f64 timeout = ~0;
12686
12687   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12688
12689   mp->locator_set_index = htonl (locator_set_index);
12690   mp->filter = filter;
12691
12692   /* send it... */
12693   S;
12694
12695   /* Use a control ping for synchronization */
12696   {
12697     vl_api_noprint_control_ping_t *mp;
12698     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12699     S;
12700   }
12701   /* Wait for a reply... */
12702   W;
12703 }
12704
12705 static inline void
12706 clean_locator_set_message (vat_main_t * vam)
12707 {
12708   locator_set_msg_t *ls = 0;
12709
12710   vec_foreach (ls, vam->locator_set_msg)
12711   {
12712     vec_free (ls->locator_set_name);
12713   }
12714
12715   vec_free (vam->locator_set_msg);
12716 }
12717
12718 static int
12719 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12720 {
12721   locator_set_msg_t *ls;
12722   locator_msg_t *loc;
12723   u8 *tmp_str = 0;
12724   int i = 0, ret = 0;
12725
12726   vec_foreach (ls, vam->locator_set_msg)
12727   {
12728     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12729     if (ret)
12730       {
12731         vec_free (vam->locator_msg);
12732         clean_locator_set_message (vam);
12733         return ret;
12734       }
12735
12736     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12737                       ls->locator_set_index,
12738                       vec_len (vam->locator_msg) ? "" : "\n");
12739     i = 0;
12740     vec_foreach (loc, vam->locator_msg)
12741     {
12742       if (i)
12743         {
12744           tmp_str = format (tmp_str, "%=37s", " ");
12745         }
12746       if (loc->local)
12747         {
12748           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12749                             loc->sw_if_index, loc->priority, loc->weight);
12750         }
12751       else
12752         {
12753           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12754                             loc->is_ipv6 ? format_ip6_address :
12755                             format_ip4_address,
12756                             loc->ip_address, loc->priority, loc->weight);
12757         }
12758       i++;
12759     }
12760
12761     fformat (vam->ofp, "%s", tmp_str);
12762     vec_free (tmp_str);
12763     vec_free (vam->locator_msg);
12764   }
12765
12766   clean_locator_set_message (vam);
12767
12768   return ret;
12769 }
12770
12771 static int
12772 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12773 {
12774   locator_set_msg_t *ls;
12775   locator_msg_t *loc;
12776   vat_json_node_t *node = NULL;
12777   vat_json_node_t *locator_array;
12778   vat_json_node_t *locator;
12779   struct in6_addr ip6;
12780   struct in_addr ip4;
12781   int ret = 0;
12782
12783   if (!vec_len (vam->locator_set_msg))
12784     {
12785       /* just print [] */
12786       vat_json_init_array (&vam->json_tree);
12787       vat_json_print (vam->ofp, &vam->json_tree);
12788       vam->json_tree.type = VAT_JSON_NONE;
12789       return ret;
12790     }
12791
12792   if (VAT_JSON_ARRAY != vam->json_tree.type)
12793     {
12794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12795       vat_json_init_array (&vam->json_tree);
12796     }
12797
12798   vec_foreach (ls, vam->locator_set_msg)
12799   {
12800     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12801     if (ret)
12802       {
12803         vec_free (ls->locator_set_name);
12804         vec_free (vam->locator_msg);
12805         vec_free (vam->locator_set_msg);
12806         vat_json_free (&vam->json_tree);
12807         vam->json_tree.type = VAT_JSON_NONE;
12808         return ret;
12809       }
12810
12811     node = vat_json_array_add (&vam->json_tree);
12812     vat_json_init_object (node);
12813
12814     vat_json_object_add_uint (node, "locator-set-index",
12815                               ls->locator_set_index);
12816     vat_json_object_add_string_copy (node, "locator-set",
12817                                      ls->locator_set_name);
12818     locator_array = vat_json_object_add_list (node, "locator");
12819     vec_foreach (loc, vam->locator_msg)
12820     {
12821       locator = vat_json_array_add (locator_array);
12822       vat_json_init_object (locator);
12823       if (loc->local)
12824         {
12825           vat_json_object_add_uint (locator, "locator-index",
12826                                     loc->sw_if_index);
12827         }
12828       else
12829         {
12830           if (loc->is_ipv6)
12831             {
12832               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12833               vat_json_object_add_ip6 (locator, "locator", ip6);
12834             }
12835           else
12836             {
12837               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12838               vat_json_object_add_ip4 (locator, "locator", ip4);
12839             }
12840         }
12841       vat_json_object_add_uint (locator, "priority", loc->priority);
12842       vat_json_object_add_uint (locator, "weight", loc->weight);
12843     }
12844
12845     vec_free (ls->locator_set_name);
12846     vec_free (vam->locator_msg);
12847   }
12848
12849   vat_json_print (vam->ofp, &vam->json_tree);
12850   vat_json_free (&vam->json_tree);
12851   vam->json_tree.type = VAT_JSON_NONE;
12852
12853   vec_free (vam->locator_set_msg);
12854
12855   return ret;
12856 }
12857
12858 static int
12859 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12860                                 u32 * locator_set_index)
12861 {
12862   locator_set_msg_t *ls;
12863   int ret = 0;
12864
12865   *locator_set_index = ~0;
12866
12867   if (!vec_len (vam->locator_set_msg))
12868     {
12869       return ret;
12870     }
12871
12872   vec_foreach (ls, vam->locator_set_msg)
12873   {
12874     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12875       {
12876         *locator_set_index = ls->locator_set_index;
12877         vec_free (vam->locator_set_msg);
12878         return ret;
12879       }
12880   }
12881
12882   vec_free (vam->locator_set_msg);
12883
12884   return ret;
12885 }
12886
12887 static int
12888 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12889                        u32 * locator_set_index)
12890 {
12891   vl_api_lisp_locator_set_dump_t *mp;
12892   f64 timeout = ~0;
12893
12894   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12895   /* send it... */
12896   S;
12897
12898   /* Use a control ping for synchronization */
12899   {
12900     vl_api_noprint_control_ping_t *mp;
12901     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12902     S;
12903   }
12904
12905   vam->noprint_msg = 1;
12906   /* Wait for a reply... */
12907   /* *INDENT-OFF* */
12908   W_L
12909   ({
12910     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12911     vam->noprint_msg = 0;
12912   });
12913   /* *INDENT-ON* */
12914
12915   /* NOTREACHED */
12916   return 0;
12917 }
12918
12919 static inline int
12920 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12921                    u8 filter)
12922 {
12923   int ret = 0;
12924
12925   ASSERT (vam);
12926
12927   if (!vam->json_output)
12928     {
12929       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12930                "locator", "priority", "weight");
12931     }
12932
12933   if (locator_set)
12934     {
12935       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
12936     }
12937
12938   if (!ret && ~0 == locator_set_index)
12939     {
12940       return -99;
12941     }
12942
12943   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
12944
12945   return ret;
12946 }
12947
12948 static int
12949 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
12950 {
12951   vl_api_lisp_locator_set_dump_t *mp;
12952   f64 timeout = ~0;
12953
12954   if (!vam->json_output)
12955     {
12956       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
12957                "locator-set", "locator-set-index", "locator", "priority",
12958                "weight");
12959     }
12960
12961   vam->noprint_msg = 1;
12962
12963   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12964
12965   mp->filter = filter;
12966
12967   /* send it... */
12968   S;
12969
12970   /* Use a control ping for synchronization */
12971   {
12972     vl_api_noprint_control_ping_t *mp;
12973     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12974     S;
12975   }
12976
12977   /* Wait for a reply... */
12978   /* *INDENT-OFF* */
12979   W_L
12980   ({
12981     if (vam->noprint_msg)
12982       {
12983         if (!vam->json_output)
12984           {
12985             print_locator_in_locator_set(vam, filter);
12986           }
12987         else
12988           {
12989             json_locator_in_locator_set(vam, filter);
12990           }
12991       }
12992     vam->noprint_msg = 0;
12993   });
12994   /* *INDENT-ON* */
12995
12996   /* NOTREACHED */
12997   return 0;
12998 }
12999
13000 static int
13001 api_lisp_locator_set_dump (vat_main_t * vam)
13002 {
13003   unformat_input_t *input = vam->input;
13004   vam->noprint_msg = 0;
13005   u32 locator_set_index = ~0;
13006   u8 locator_set_index_set = 0;
13007   u8 *locator_set = 0;
13008   u8 locator_set_set = 0;
13009   u8 filter = 0;
13010   int ret = 0;
13011
13012   /* Parse args required to build the message */
13013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13014     {
13015       if (unformat (input, "locator-set-index %u", &locator_set_index))
13016         {
13017           locator_set_index_set = 1;
13018         }
13019       else if (unformat (input, "locator-set %s", &locator_set))
13020         {
13021           locator_set_set = 1;
13022         }
13023       else if (unformat (input, "local"))
13024         {
13025           filter = 1;
13026         }
13027       else if (unformat (input, "remote"))
13028         {
13029           filter = 2;
13030         }
13031       else
13032         {
13033           break;
13034         }
13035     }
13036
13037   if (locator_set_index_set && locator_set_set)
13038     {
13039       errmsg ("use only input parameter!\n");
13040       return -99;
13041     }
13042
13043   if (locator_set_index_set || locator_set_set)
13044     {
13045       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13046     }
13047   else
13048     {
13049       ret = lisp_locator_set_dump (vam, filter);
13050     }
13051
13052   vec_free (locator_set);
13053
13054   return ret;
13055 }
13056
13057 static int
13058 api_lisp_eid_table_map_dump (vat_main_t * vam)
13059 {
13060   vl_api_lisp_eid_table_map_dump_t *mp;
13061   f64 timeout = ~0;
13062
13063   if (!vam->json_output)
13064     {
13065       fformat (vam->ofp, "%=10s%=10s\n", "VNI", "VRF");
13066     }
13067
13068   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13069
13070   /* send it... */
13071   S;
13072
13073   /* Use a control ping for synchronization */
13074   {
13075     vl_api_control_ping_t *mp;
13076     M (CONTROL_PING, control_ping);
13077     S;
13078   }
13079   /* Wait for a reply... */
13080   W;
13081
13082   /* NOTREACHED */
13083   return 0;
13084 }
13085
13086 static int
13087 get_locator_set (vat_main_t * vam)
13088 {
13089   vl_api_lisp_locator_set_dump_t *mp;
13090   f64 timeout = ~0;
13091
13092   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13093   /* send it... */
13094   S;
13095
13096   /* Use a control ping for synchronization */
13097   {
13098     vl_api_noprint_control_ping_t *mp;
13099     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13100     S;
13101   }
13102
13103   /* Wait for a reply... */
13104   W;
13105
13106   /* NOTREACHED */
13107   return 0;
13108 }
13109
13110 static inline u8 *
13111 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13112                           int *ret)
13113 {
13114   u8 *(*format_eid) (u8 *, va_list *) = 0;
13115
13116   ASSERT (vam != NULL);
13117   ASSERT (eid_table != NULL);
13118
13119   if (ret)
13120     {
13121       *ret = 0;
13122     }
13123
13124   switch (eid_table->eid_type)
13125     {
13126     case 0:
13127     case 1:
13128       format_eid = (eid_table->eid_type ? format_ip6_address :
13129                     format_ip4_address);
13130       str = format (0, "[%d] %U/%d",
13131                     clib_net_to_host_u32 (eid_table->vni),
13132                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13133       break;
13134     case 2:
13135       str = format (0, "[%d] %U",
13136                     clib_net_to_host_u32 (eid_table->vni),
13137                     format_ethernet_address, eid_table->eid);
13138       break;
13139     default:
13140       errmsg ("unknown EID type %d!", eid_table->eid_type);
13141       if (ret)
13142         {
13143           *ret = -99;
13144         }
13145       return 0;
13146     }
13147
13148   return str;
13149 }
13150
13151 static inline u8 *
13152 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13153                                   eid_table_t * eid_table)
13154 {
13155   locator_set_msg_t *ls = 0;
13156
13157   ASSERT (vam != NULL);
13158   ASSERT (eid_table != NULL);
13159
13160   if (eid_table->is_local)
13161     {
13162       vec_foreach (ls, vam->locator_set_msg)
13163       {
13164         if (ls->locator_set_index == eid_table->locator_set_index)
13165           {
13166             str = format (0, "local(%s)", ls->locator_set_name);
13167             return str;
13168           }
13169       }
13170
13171       str = format (0, "local(N/A)");
13172     }
13173   else
13174     {
13175       str = format (0, "remote");
13176     }
13177
13178   return str;
13179 }
13180
13181 static inline u8 *
13182 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13183                               eid_table_t * eid_table)
13184 {
13185   locator_msg_t *loc = 0;
13186   int first_line = 1;
13187
13188   ASSERT (vam != NULL);
13189   ASSERT (eid_table != NULL);
13190
13191   vec_foreach (loc, vam->locator_msg)
13192   {
13193     if (!first_line)
13194       {
13195         if (loc->local)
13196           {
13197             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13198           }
13199         else
13200           {
13201             str = format (str, "%=55s%-U\n", " ",
13202                           loc->is_ipv6 ? format_ip6_address :
13203                           format_ip4_address, loc->ip_address);
13204           }
13205
13206         continue;
13207       }
13208
13209     if (loc->local)
13210       {
13211         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13212                       eid_table->ttl, eid_table->authoritative);
13213       }
13214     else
13215       {
13216         str = format (str, "%-30U%-20u%-u\n",
13217                       loc->is_ipv6 ? format_ip6_address :
13218                       format_ip4_address,
13219                       loc->ip_address, eid_table->ttl,
13220                       eid_table->authoritative);
13221       }
13222     first_line = 0;
13223   }
13224
13225   return str;
13226 }
13227
13228 static int
13229 print_lisp_eid_table_dump (vat_main_t * vam)
13230 {
13231   eid_table_t *eid_table = 0;
13232   u8 *tmp_str = 0, *tmp_str2 = 0;
13233   int ret = 0;
13234
13235   ASSERT (vam != NULL);
13236
13237   ret = get_locator_set (vam);
13238   if (ret)
13239     {
13240       vec_free (vam->eid_tables);
13241       return ret;
13242     }
13243
13244   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13245            "ttl", "authoritative");
13246
13247   vec_foreach (eid_table, vam->eid_tables)
13248   {
13249     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13250     if (ret)
13251       {
13252         vec_free (vam->locator_msg);
13253         clean_locator_set_message (vam);
13254         vec_free (vam->eid_tables);
13255         return ret;
13256       }
13257
13258     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13259     if (ret)
13260       {
13261         vec_free (vam->locator_msg);
13262         clean_locator_set_message (vam);
13263         vec_free (vam->eid_tables);
13264         return ret;
13265       }
13266
13267     tmp_str = format (0, "%-35s", tmp_str2);
13268     vec_free (tmp_str2);
13269
13270     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13271     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13272     vec_free (tmp_str2);
13273
13274     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13275     tmp_str = format (tmp_str, "%-s", tmp_str2);
13276     vec_free (tmp_str2);
13277
13278     fformat (vam->ofp, "%s", tmp_str);
13279     vec_free (tmp_str);
13280     vec_free (vam->locator_msg);
13281   }
13282
13283   clean_locator_set_message (vam);
13284   vec_free (vam->eid_tables);
13285
13286   return ret;
13287 }
13288
13289 static inline void
13290 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13291                                 eid_table_t * eid_table)
13292 {
13293   locator_set_msg_t *ls = 0;
13294   u8 *s = 0;
13295
13296   ASSERT (vam != NULL);
13297   ASSERT (node != NULL);
13298   ASSERT (eid_table != NULL);
13299
13300   if (eid_table->is_local)
13301     {
13302       vec_foreach (ls, vam->locator_set_msg)
13303       {
13304         if (ls->locator_set_index == eid_table->locator_set_index)
13305           {
13306             vat_json_object_add_string_copy (node, "locator-set",
13307                                              ls->locator_set_name);
13308             return;
13309           }
13310       }
13311
13312       s = format (0, "N/A");
13313       vec_add1 (s, 0);
13314       vat_json_object_add_string_copy (node, "locator-set", s);
13315       vec_free (s);
13316     }
13317   else
13318     {
13319       s = format (0, "remote");
13320       vec_add1 (s, 0);
13321       vat_json_object_add_string_copy (node, "locator-set", s);
13322       vec_free (s);
13323     }
13324 }
13325
13326 static inline int
13327 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13328                         eid_table_t * eid_table)
13329 {
13330   u8 *s = 0;
13331   struct in6_addr ip6;
13332   struct in_addr ip4;
13333
13334   ASSERT (vam != NULL);
13335   ASSERT (node != NULL);
13336   ASSERT (eid_table != NULL);
13337
13338   switch (eid_table->eid_type)
13339     {
13340     case 0:
13341       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13342       vat_json_object_add_ip4 (node, "eid", ip4);
13343       vat_json_object_add_uint (node, "eid-prefix-len",
13344                                 eid_table->eid_prefix_len);
13345       break;
13346     case 1:
13347       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13348       vat_json_object_add_ip6 (node, "eid", ip6);
13349       vat_json_object_add_uint (node, "eid-prefix-len",
13350                                 eid_table->eid_prefix_len);
13351       break;
13352     case 2:
13353       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13354       vec_add1 (s, 0);
13355       vat_json_object_add_string_copy (node, "eid", s);
13356       vec_free (s);
13357       break;
13358     default:
13359       errmsg ("unknown EID type %d!", eid_table->eid_type);
13360       return -99;
13361     }
13362
13363   return 0;
13364 }
13365
13366 static inline void
13367 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13368                             eid_table_t * eid_table)
13369 {
13370   locator_msg_t *loc = 0;
13371   vat_json_node_t *locator_array = 0;
13372   vat_json_node_t *locator = 0;
13373   struct in6_addr ip6;
13374   struct in_addr ip4;
13375
13376   ASSERT (vam != NULL);
13377   ASSERT (node != NULL);
13378   ASSERT (eid_table != NULL);
13379
13380   locator_array = vat_json_object_add_list (node, "locator");
13381   vec_foreach (loc, vam->locator_msg)
13382   {
13383     locator = vat_json_array_add (locator_array);
13384     vat_json_init_object (locator);
13385     if (loc->local)
13386       {
13387         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13388       }
13389     else
13390       {
13391         if (loc->is_ipv6)
13392           {
13393             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13394             vat_json_object_add_ip6 (locator, "locator", ip6);
13395           }
13396         else
13397           {
13398             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13399             vat_json_object_add_ip4 (locator, "locator", ip4);
13400           }
13401       }
13402   }
13403 }
13404
13405 static int
13406 json_lisp_eid_table_dump (vat_main_t * vam)
13407 {
13408   eid_table_t *eid_table;
13409   vat_json_node_t *node = 0;
13410   int ret = 0;
13411
13412   ASSERT (vam != NULL);
13413
13414   ret = get_locator_set (vam);
13415   if (ret)
13416     {
13417       vec_free (vam->eid_tables);
13418       return ret;
13419     }
13420
13421   if (!vec_len (vam->eid_tables))
13422     {
13423       /* just print [] */
13424       vat_json_init_array (&vam->json_tree);
13425       vat_json_print (vam->ofp, &vam->json_tree);
13426       vam->json_tree.type = VAT_JSON_NONE;
13427       return ret;
13428     }
13429
13430   if (VAT_JSON_ARRAY != vam->json_tree.type)
13431     {
13432       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13433       vat_json_init_array (&vam->json_tree);
13434     }
13435
13436   vec_foreach (eid_table, vam->eid_tables)
13437   {
13438     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13439     if (ret)
13440       {
13441         vec_free (vam->locator_msg);
13442         vec_free (vam->eid_tables);
13443         clean_locator_set_message (vam);
13444         vat_json_free (&vam->json_tree);
13445         vam->json_tree.type = VAT_JSON_NONE;
13446         return ret;
13447       }
13448
13449     node = vat_json_array_add (&vam->json_tree);
13450     vat_json_init_object (node);
13451
13452     vat_json_object_add_uint (node, "vni", eid_table->vni);
13453
13454     json_locator_set_for_eid_table (vam, node, eid_table);
13455     ret = json_eid_for_eid_table (vam, node, eid_table);
13456     if (ret)
13457       {
13458         vec_free (vam->locator_msg);
13459         vec_free (vam->eid_tables);
13460         clean_locator_set_message (vam);
13461         vat_json_free (&vam->json_tree);
13462         vam->json_tree.type = VAT_JSON_NONE;
13463         return ret;
13464       }
13465
13466     json_locator_for_eid_table (vam, node, eid_table);
13467
13468     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13469     vat_json_object_add_uint (node, "authoritative",
13470                               eid_table->authoritative);
13471
13472     vec_free (vam->locator_msg);
13473   }
13474
13475   vat_json_print (vam->ofp, &vam->json_tree);
13476   vat_json_free (&vam->json_tree);
13477   vam->json_tree.type = VAT_JSON_NONE;
13478
13479   clean_locator_set_message (vam);
13480   vec_free (vam->eid_tables);
13481
13482   return ret;
13483 }
13484
13485 static int
13486 api_lisp_eid_table_dump (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_lisp_eid_table_dump_t *mp;
13490   f64 timeout = ~0;
13491   struct in_addr ip4;
13492   struct in6_addr ip6;
13493   u8 mac[6];
13494   u8 eid_type = ~0, eid_set = 0;
13495   u32 prefix_length = ~0, t, vni = 0;
13496   u8 filter = 0;
13497
13498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13499     {
13500       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13501         {
13502           eid_set = 1;
13503           eid_type = 0;
13504           prefix_length = t;
13505         }
13506       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13507         {
13508           eid_set = 1;
13509           eid_type = 1;
13510           prefix_length = t;
13511         }
13512       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13513         {
13514           eid_set = 1;
13515           eid_type = 2;
13516         }
13517       else if (unformat (i, "vni %d", &t))
13518         {
13519           vni = t;
13520         }
13521       else if (unformat (i, "local"))
13522         {
13523           filter = 1;
13524         }
13525       else if (unformat (i, "remote"))
13526         {
13527           filter = 2;
13528         }
13529       else
13530         {
13531           errmsg ("parse error '%U'", format_unformat_error, i);
13532           return -99;
13533         }
13534     }
13535
13536   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13537
13538   mp->filter = filter;
13539   if (eid_set)
13540     {
13541       mp->eid_set = 1;
13542       mp->vni = htonl (vni);
13543       mp->eid_type = eid_type;
13544       switch (eid_type)
13545         {
13546         case 0:
13547           mp->prefix_length = prefix_length;
13548           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13549           break;
13550         case 1:
13551           mp->prefix_length = prefix_length;
13552           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13553           break;
13554         case 2:
13555           clib_memcpy (mp->eid, mac, sizeof (mac));
13556           break;
13557         default:
13558           errmsg ("unknown EID type %d!", eid_type);
13559           return -99;
13560         }
13561     }
13562
13563   vam->noprint_msg = 1;
13564
13565   /* send it... */
13566   S;
13567
13568   /* Use a control ping for synchronization */
13569   {
13570     vl_api_noprint_control_ping_t *mp;
13571     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13572     S;
13573   }
13574
13575   /* Wait for a reply... */
13576   /* *INDENT-OFF* */
13577   W_L
13578   ({
13579     if (vam->noprint_msg)
13580       {
13581         if (!vam->json_output)
13582           {
13583             vam->retval = print_lisp_eid_table_dump(vam);
13584           }
13585         else
13586           {
13587             vam->retval = json_lisp_eid_table_dump(vam);
13588           }
13589       }
13590     vam->noprint_msg = 0;
13591   });
13592   /* *INDENT-ON* */
13593
13594   /* NOTREACHED */
13595   return 0;
13596 }
13597
13598 static int
13599 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13600 {
13601   vl_api_lisp_gpe_tunnel_dump_t *mp;
13602   f64 timeout = ~0;
13603
13604   if (!vam->json_output)
13605     {
13606       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13607                "%=16s%=16s%=16s%=16s%=16s\n",
13608                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13609                "Decap next", "Lisp version", "Flags", "Next protocol",
13610                "ver_res", "res", "iid");
13611     }
13612
13613   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13614   /* send it... */
13615   S;
13616
13617   /* Use a control ping for synchronization */
13618   {
13619     vl_api_control_ping_t *mp;
13620     M (CONTROL_PING, control_ping);
13621     S;
13622   }
13623   /* Wait for a reply... */
13624   W;
13625
13626   /* NOTREACHED */
13627   return 0;
13628 }
13629
13630 static int
13631 api_lisp_map_resolver_dump (vat_main_t * vam)
13632 {
13633   vl_api_lisp_map_resolver_dump_t *mp;
13634   f64 timeout = ~0;
13635
13636   if (!vam->json_output)
13637     {
13638       fformat (vam->ofp, "%=20s\n", "Map resolver");
13639     }
13640
13641   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13642   /* send it... */
13643   S;
13644
13645   /* Use a control ping for synchronization */
13646   {
13647     vl_api_control_ping_t *mp;
13648     M (CONTROL_PING, control_ping);
13649     S;
13650   }
13651   /* Wait for a reply... */
13652   W;
13653
13654   /* NOTREACHED */
13655   return 0;
13656 }
13657
13658 static int
13659 api_show_lisp_status (vat_main_t * vam)
13660 {
13661   vl_api_show_lisp_status_t *mp;
13662   f64 timeout = ~0;
13663
13664   if (!vam->json_output)
13665     {
13666       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13667     }
13668
13669   M (SHOW_LISP_STATUS, show_lisp_status);
13670   /* send it... */
13671   S;
13672   /* Wait for a reply... */
13673   W;
13674
13675   /* NOTREACHED */
13676   return 0;
13677 }
13678
13679 static int
13680 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13681 {
13682   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13683   f64 timeout = ~0;
13684
13685   if (!vam->json_output)
13686     {
13687       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13688     }
13689
13690   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13691   /* send it... */
13692   S;
13693   /* Wait for a reply... */
13694   W;
13695
13696   /* NOTREACHED */
13697   return 0;
13698 }
13699
13700 static int
13701 api_af_packet_create (vat_main_t * vam)
13702 {
13703   unformat_input_t *i = vam->input;
13704   vl_api_af_packet_create_t *mp;
13705   f64 timeout;
13706   u8 *host_if_name = 0;
13707   u8 hw_addr[6];
13708   u8 random_hw_addr = 1;
13709
13710   memset (hw_addr, 0, sizeof (hw_addr));
13711
13712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13713     {
13714       if (unformat (i, "name %s", &host_if_name))
13715         vec_add1 (host_if_name, 0);
13716       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13717         random_hw_addr = 0;
13718       else
13719         break;
13720     }
13721
13722   if (!vec_len (host_if_name))
13723     {
13724       errmsg ("host-interface name must be specified");
13725       return -99;
13726     }
13727
13728   if (vec_len (host_if_name) > 64)
13729     {
13730       errmsg ("host-interface name too long");
13731       return -99;
13732     }
13733
13734   M (AF_PACKET_CREATE, af_packet_create);
13735
13736   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13737   clib_memcpy (mp->hw_addr, hw_addr, 6);
13738   mp->use_random_hw_addr = random_hw_addr;
13739   vec_free (host_if_name);
13740
13741   S;
13742   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13743   /* NOTREACHED */
13744   return 0;
13745 }
13746
13747 static int
13748 api_af_packet_delete (vat_main_t * vam)
13749 {
13750   unformat_input_t *i = vam->input;
13751   vl_api_af_packet_delete_t *mp;
13752   f64 timeout;
13753   u8 *host_if_name = 0;
13754
13755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13756     {
13757       if (unformat (i, "name %s", &host_if_name))
13758         vec_add1 (host_if_name, 0);
13759       else
13760         break;
13761     }
13762
13763   if (!vec_len (host_if_name))
13764     {
13765       errmsg ("host-interface name must be specified");
13766       return -99;
13767     }
13768
13769   if (vec_len (host_if_name) > 64)
13770     {
13771       errmsg ("host-interface name too long");
13772       return -99;
13773     }
13774
13775   M (AF_PACKET_DELETE, af_packet_delete);
13776
13777   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13778   vec_free (host_if_name);
13779
13780   S;
13781   W;
13782   /* NOTREACHED */
13783   return 0;
13784 }
13785
13786 static int
13787 api_policer_add_del (vat_main_t * vam)
13788 {
13789   unformat_input_t *i = vam->input;
13790   vl_api_policer_add_del_t *mp;
13791   f64 timeout;
13792   u8 is_add = 1;
13793   u8 *name = 0;
13794   u32 cir = 0;
13795   u32 eir = 0;
13796   u64 cb = 0;
13797   u64 eb = 0;
13798   u8 rate_type = 0;
13799   u8 round_type = 0;
13800   u8 type = 0;
13801   u8 color_aware = 0;
13802   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13803
13804   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13805   conform_action.dscp = 0;
13806   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13807   exceed_action.dscp = 0;
13808   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13809   violate_action.dscp = 0;
13810
13811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (i, "del"))
13814         is_add = 0;
13815       else if (unformat (i, "name %s", &name))
13816         vec_add1 (name, 0);
13817       else if (unformat (i, "cir %u", &cir))
13818         ;
13819       else if (unformat (i, "eir %u", &eir))
13820         ;
13821       else if (unformat (i, "cb %u", &cb))
13822         ;
13823       else if (unformat (i, "eb %u", &eb))
13824         ;
13825       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13826                          &rate_type))
13827         ;
13828       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13829                          &round_type))
13830         ;
13831       else if (unformat (i, "type %U", unformat_policer_type, &type))
13832         ;
13833       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13834                          &conform_action))
13835         ;
13836       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13837                          &exceed_action))
13838         ;
13839       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13840                          &violate_action))
13841         ;
13842       else if (unformat (i, "color-aware"))
13843         color_aware = 1;
13844       else
13845         break;
13846     }
13847
13848   if (!vec_len (name))
13849     {
13850       errmsg ("policer name must be specified");
13851       return -99;
13852     }
13853
13854   if (vec_len (name) > 64)
13855     {
13856       errmsg ("policer name too long");
13857       return -99;
13858     }
13859
13860   M (POLICER_ADD_DEL, policer_add_del);
13861
13862   clib_memcpy (mp->name, name, vec_len (name));
13863   vec_free (name);
13864   mp->is_add = is_add;
13865   mp->cir = cir;
13866   mp->eir = eir;
13867   mp->cb = cb;
13868   mp->eb = eb;
13869   mp->rate_type = rate_type;
13870   mp->round_type = round_type;
13871   mp->type = type;
13872   mp->conform_action_type = conform_action.action_type;
13873   mp->conform_dscp = conform_action.dscp;
13874   mp->exceed_action_type = exceed_action.action_type;
13875   mp->exceed_dscp = exceed_action.dscp;
13876   mp->violate_action_type = violate_action.action_type;
13877   mp->violate_dscp = violate_action.dscp;
13878   mp->color_aware = color_aware;
13879
13880   S;
13881   W;
13882   /* NOTREACHED */
13883   return 0;
13884 }
13885
13886 static int
13887 api_policer_dump (vat_main_t * vam)
13888 {
13889   unformat_input_t *i = vam->input;
13890   vl_api_policer_dump_t *mp;
13891   f64 timeout = ~0;
13892   u8 *match_name = 0;
13893   u8 match_name_valid = 0;
13894
13895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (i, "name %s", &match_name))
13898         {
13899           vec_add1 (match_name, 0);
13900           match_name_valid = 1;
13901         }
13902       else
13903         break;
13904     }
13905
13906   M (POLICER_DUMP, policer_dump);
13907   mp->match_name_valid = match_name_valid;
13908   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
13909   vec_free (match_name);
13910   /* send it... */
13911   S;
13912
13913   /* Use a control ping for synchronization */
13914   {
13915     vl_api_control_ping_t *mp;
13916     M (CONTROL_PING, control_ping);
13917     S;
13918   }
13919   /* Wait for a reply... */
13920   W;
13921
13922   /* NOTREACHED */
13923   return 0;
13924 }
13925
13926 static int
13927 api_policer_classify_set_interface (vat_main_t * vam)
13928 {
13929   unformat_input_t *i = vam->input;
13930   vl_api_policer_classify_set_interface_t *mp;
13931   f64 timeout;
13932   u32 sw_if_index;
13933   int sw_if_index_set;
13934   u32 ip4_table_index = ~0;
13935   u32 ip6_table_index = ~0;
13936   u32 l2_table_index = ~0;
13937   u8 is_add = 1;
13938
13939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13940     {
13941       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
13942         sw_if_index_set = 1;
13943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13944         sw_if_index_set = 1;
13945       else if (unformat (i, "del"))
13946         is_add = 0;
13947       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13948         ;
13949       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13950         ;
13951       else if (unformat (i, "l2-table %d", &l2_table_index))
13952         ;
13953       else
13954         {
13955           clib_warning ("parse error '%U'", format_unformat_error, i);
13956           return -99;
13957         }
13958     }
13959
13960   if (sw_if_index_set == 0)
13961     {
13962       errmsg ("missing interface name or sw_if_index\n");
13963       return -99;
13964     }
13965
13966   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
13967
13968   mp->sw_if_index = ntohl (sw_if_index);
13969   mp->ip4_table_index = ntohl (ip4_table_index);
13970   mp->ip6_table_index = ntohl (ip6_table_index);
13971   mp->l2_table_index = ntohl (l2_table_index);
13972   mp->is_add = is_add;
13973
13974   S;
13975   W;
13976   /* NOTREACHED */
13977   return 0;
13978 }
13979
13980 static int
13981 api_policer_classify_dump (vat_main_t * vam)
13982 {
13983   unformat_input_t *i = vam->input;
13984   vl_api_policer_classify_dump_t *mp;
13985   f64 timeout = ~0;
13986   u8 type = POLICER_CLASSIFY_N_TABLES;
13987
13988   if (unformat (i, "type %U", unformat_classify_table_type, &type))
13989     ;
13990   else
13991     {
13992       errmsg ("classify table type must be specified\n");
13993       return -99;
13994     }
13995
13996   if (!vam->json_output)
13997     {
13998       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
13999     }
14000
14001   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14002   mp->type = type;
14003   /* send it... */
14004   S;
14005
14006   /* Use a control ping for synchronization */
14007   {
14008     vl_api_control_ping_t *mp;
14009     M (CONTROL_PING, control_ping);
14010     S;
14011   }
14012   /* Wait for a reply... */
14013   W;
14014
14015   /* NOTREACHED */
14016   return 0;
14017 }
14018
14019 static int
14020 api_netmap_create (vat_main_t * vam)
14021 {
14022   unformat_input_t *i = vam->input;
14023   vl_api_netmap_create_t *mp;
14024   f64 timeout;
14025   u8 *if_name = 0;
14026   u8 hw_addr[6];
14027   u8 random_hw_addr = 1;
14028   u8 is_pipe = 0;
14029   u8 is_master = 0;
14030
14031   memset (hw_addr, 0, sizeof (hw_addr));
14032
14033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14034     {
14035       if (unformat (i, "name %s", &if_name))
14036         vec_add1 (if_name, 0);
14037       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14038         random_hw_addr = 0;
14039       else if (unformat (i, "pipe"))
14040         is_pipe = 1;
14041       else if (unformat (i, "master"))
14042         is_master = 1;
14043       else if (unformat (i, "slave"))
14044         is_master = 0;
14045       else
14046         break;
14047     }
14048
14049   if (!vec_len (if_name))
14050     {
14051       errmsg ("interface name must be specified");
14052       return -99;
14053     }
14054
14055   if (vec_len (if_name) > 64)
14056     {
14057       errmsg ("interface name too long");
14058       return -99;
14059     }
14060
14061   M (NETMAP_CREATE, netmap_create);
14062
14063   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14064   clib_memcpy (mp->hw_addr, hw_addr, 6);
14065   mp->use_random_hw_addr = random_hw_addr;
14066   mp->is_pipe = is_pipe;
14067   mp->is_master = is_master;
14068   vec_free (if_name);
14069
14070   S;
14071   W;
14072   /* NOTREACHED */
14073   return 0;
14074 }
14075
14076 static int
14077 api_netmap_delete (vat_main_t * vam)
14078 {
14079   unformat_input_t *i = vam->input;
14080   vl_api_netmap_delete_t *mp;
14081   f64 timeout;
14082   u8 *if_name = 0;
14083
14084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14085     {
14086       if (unformat (i, "name %s", &if_name))
14087         vec_add1 (if_name, 0);
14088       else
14089         break;
14090     }
14091
14092   if (!vec_len (if_name))
14093     {
14094       errmsg ("interface name must be specified");
14095       return -99;
14096     }
14097
14098   if (vec_len (if_name) > 64)
14099     {
14100       errmsg ("interface name too long");
14101       return -99;
14102     }
14103
14104   M (NETMAP_DELETE, netmap_delete);
14105
14106   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14107   vec_free (if_name);
14108
14109   S;
14110   W;
14111   /* NOTREACHED */
14112   return 0;
14113 }
14114
14115 static void vl_api_mpls_gre_tunnel_details_t_handler
14116   (vl_api_mpls_gre_tunnel_details_t * mp)
14117 {
14118   vat_main_t *vam = &vat_main;
14119   i32 i;
14120   i32 len = ntohl (mp->nlabels);
14121
14122   if (mp->l2_only == 0)
14123     {
14124       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14125                ntohl (mp->tunnel_index),
14126                format_ip4_address, &mp->tunnel_src,
14127                format_ip4_address, &mp->tunnel_dst,
14128                format_ip4_address, &mp->intfc_address,
14129                ntohl (mp->mask_width));
14130       for (i = 0; i < len; i++)
14131         {
14132           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14133         }
14134       fformat (vam->ofp, "\n");
14135       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14136                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14137     }
14138   else
14139     {
14140       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14141                ntohl (mp->tunnel_index),
14142                format_ip4_address, &mp->tunnel_src,
14143                format_ip4_address, &mp->tunnel_dst,
14144                format_ip4_address, &mp->intfc_address);
14145       for (i = 0; i < len; i++)
14146         {
14147           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14148         }
14149       fformat (vam->ofp, "\n");
14150       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14151                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14152     }
14153 }
14154
14155 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14156   (vl_api_mpls_gre_tunnel_details_t * mp)
14157 {
14158   vat_main_t *vam = &vat_main;
14159   vat_json_node_t *node = NULL;
14160   struct in_addr ip4;
14161   i32 i;
14162   i32 len = ntohl (mp->nlabels);
14163
14164   if (VAT_JSON_ARRAY != vam->json_tree.type)
14165     {
14166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14167       vat_json_init_array (&vam->json_tree);
14168     }
14169   node = vat_json_array_add (&vam->json_tree);
14170
14171   vat_json_init_object (node);
14172   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14173   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14174   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14175   vat_json_object_add_uint (node, "inner_fib_index",
14176                             ntohl (mp->inner_fib_index));
14177   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14178   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14179   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14180   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14181   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14182   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14183   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14184   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14185   vat_json_object_add_uint (node, "outer_fib_index",
14186                             ntohl (mp->outer_fib_index));
14187   vat_json_object_add_uint (node, "label_count", len);
14188   for (i = 0; i < len; i++)
14189     {
14190       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14191     }
14192 }
14193
14194 static int
14195 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14196 {
14197   vl_api_mpls_gre_tunnel_dump_t *mp;
14198   f64 timeout;
14199   i32 index = -1;
14200
14201   /* Parse args required to build the message */
14202   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14203     {
14204       if (!unformat (vam->input, "tunnel_index %d", &index))
14205         {
14206           index = -1;
14207           break;
14208         }
14209     }
14210
14211   fformat (vam->ofp, "  tunnel_index %d\n", index);
14212
14213   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14214   mp->tunnel_index = htonl (index);
14215   S;
14216
14217   /* Use a control ping for synchronization */
14218   {
14219     vl_api_control_ping_t *mp;
14220     M (CONTROL_PING, control_ping);
14221     S;
14222   }
14223   W;
14224 }
14225
14226 static void vl_api_mpls_eth_tunnel_details_t_handler
14227   (vl_api_mpls_eth_tunnel_details_t * mp)
14228 {
14229   vat_main_t *vam = &vat_main;
14230   i32 i;
14231   i32 len = ntohl (mp->nlabels);
14232
14233   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14234            ntohl (mp->tunnel_index),
14235            format_ethernet_address, &mp->tunnel_dst_mac,
14236            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14237   for (i = 0; i < len; i++)
14238     {
14239       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14240     }
14241   fformat (vam->ofp, "\n");
14242   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14243            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14244 }
14245
14246 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14247   (vl_api_mpls_eth_tunnel_details_t * mp)
14248 {
14249   vat_main_t *vam = &vat_main;
14250   vat_json_node_t *node = NULL;
14251   struct in_addr ip4;
14252   i32 i;
14253   i32 len = ntohl (mp->nlabels);
14254
14255   if (VAT_JSON_ARRAY != vam->json_tree.type)
14256     {
14257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14258       vat_json_init_array (&vam->json_tree);
14259     }
14260   node = vat_json_array_add (&vam->json_tree);
14261
14262   vat_json_init_object (node);
14263   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14264   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14265   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14266   vat_json_object_add_uint (node, "inner_fib_index",
14267                             ntohl (mp->inner_fib_index));
14268   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14269   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14270   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14271   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14272   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14273                                    format (0, "%U", format_ethernet_address,
14274                                            &mp->tunnel_dst_mac));
14275   vat_json_object_add_uint (node, "tx_sw_if_index",
14276                             ntohl (mp->tx_sw_if_index));
14277   vat_json_object_add_uint (node, "label_count", len);
14278   for (i = 0; i < len; i++)
14279     {
14280       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14281     }
14282 }
14283
14284 static int
14285 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14286 {
14287   vl_api_mpls_eth_tunnel_dump_t *mp;
14288   f64 timeout;
14289   i32 index = -1;
14290
14291   /* Parse args required to build the message */
14292   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14293     {
14294       if (!unformat (vam->input, "tunnel_index %d", &index))
14295         {
14296           index = -1;
14297           break;
14298         }
14299     }
14300
14301   fformat (vam->ofp, "  tunnel_index %d\n", index);
14302
14303   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14304   mp->tunnel_index = htonl (index);
14305   S;
14306
14307   /* Use a control ping for synchronization */
14308   {
14309     vl_api_control_ping_t *mp;
14310     M (CONTROL_PING, control_ping);
14311     S;
14312   }
14313   W;
14314 }
14315
14316 static void vl_api_mpls_fib_encap_details_t_handler
14317   (vl_api_mpls_fib_encap_details_t * mp)
14318 {
14319   vat_main_t *vam = &vat_main;
14320   i32 i;
14321   i32 len = ntohl (mp->nlabels);
14322
14323   fformat (vam->ofp, "table %d, dest %U, label ",
14324            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14325   for (i = 0; i < len; i++)
14326     {
14327       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14328     }
14329   fformat (vam->ofp, "\n");
14330 }
14331
14332 static void vl_api_mpls_fib_encap_details_t_handler_json
14333   (vl_api_mpls_fib_encap_details_t * mp)
14334 {
14335   vat_main_t *vam = &vat_main;
14336   vat_json_node_t *node = NULL;
14337   i32 i;
14338   i32 len = ntohl (mp->nlabels);
14339   struct in_addr ip4;
14340
14341   if (VAT_JSON_ARRAY != vam->json_tree.type)
14342     {
14343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14344       vat_json_init_array (&vam->json_tree);
14345     }
14346   node = vat_json_array_add (&vam->json_tree);
14347
14348   vat_json_init_object (node);
14349   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14350   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14351   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14352   vat_json_object_add_ip4 (node, "dest", ip4);
14353   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14354   vat_json_object_add_uint (node, "label_count", len);
14355   for (i = 0; i < len; i++)
14356     {
14357       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14358     }
14359 }
14360
14361 static int
14362 api_mpls_fib_encap_dump (vat_main_t * vam)
14363 {
14364   vl_api_mpls_fib_encap_dump_t *mp;
14365   f64 timeout;
14366
14367   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14368   S;
14369
14370   /* Use a control ping for synchronization */
14371   {
14372     vl_api_control_ping_t *mp;
14373     M (CONTROL_PING, control_ping);
14374     S;
14375   }
14376   W;
14377 }
14378
14379 static void vl_api_mpls_fib_decap_details_t_handler
14380   (vl_api_mpls_fib_decap_details_t * mp)
14381 {
14382   vat_main_t *vam = &vat_main;
14383
14384   fformat (vam->ofp,
14385            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14386            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14387            ntohl (mp->label), ntohl (mp->s_bit));
14388 }
14389
14390 static void vl_api_mpls_fib_decap_details_t_handler_json
14391   (vl_api_mpls_fib_decap_details_t * mp)
14392 {
14393   vat_main_t *vam = &vat_main;
14394   vat_json_node_t *node = NULL;
14395   struct in_addr ip4;
14396
14397   if (VAT_JSON_ARRAY != vam->json_tree.type)
14398     {
14399       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14400       vat_json_init_array (&vam->json_tree);
14401     }
14402   node = vat_json_array_add (&vam->json_tree);
14403
14404   vat_json_init_object (node);
14405   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14406   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14407   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14408   vat_json_object_add_ip4 (node, "dest", ip4);
14409   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14410   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14411   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14412   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14413   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14414 }
14415
14416 static int
14417 api_mpls_fib_decap_dump (vat_main_t * vam)
14418 {
14419   vl_api_mpls_fib_decap_dump_t *mp;
14420   f64 timeout;
14421
14422   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14423   S;
14424
14425   /* Use a control ping for synchronization */
14426   {
14427     vl_api_control_ping_t *mp;
14428     M (CONTROL_PING, control_ping);
14429     S;
14430   }
14431   W;
14432 }
14433
14434 int
14435 api_classify_table_ids (vat_main_t * vam)
14436 {
14437   vl_api_classify_table_ids_t *mp;
14438   f64 timeout;
14439
14440   /* Construct the API message */
14441   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14442   mp->context = 0;
14443
14444   S;
14445   W;
14446   /* NOTREACHED */
14447   return 0;
14448 }
14449
14450 int
14451 api_classify_table_by_interface (vat_main_t * vam)
14452 {
14453   unformat_input_t *input = vam->input;
14454   vl_api_classify_table_by_interface_t *mp;
14455   f64 timeout;
14456
14457   u32 sw_if_index = ~0;
14458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14459     {
14460       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14461         ;
14462       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14463         ;
14464       else
14465         break;
14466     }
14467   if (sw_if_index == ~0)
14468     {
14469       errmsg ("missing interface name or sw_if_index\n");
14470       return -99;
14471     }
14472
14473   /* Construct the API message */
14474   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14475   mp->context = 0;
14476   mp->sw_if_index = ntohl (sw_if_index);
14477
14478   S;
14479   W;
14480   /* NOTREACHED */
14481   return 0;
14482 }
14483
14484 int
14485 api_classify_table_info (vat_main_t * vam)
14486 {
14487   unformat_input_t *input = vam->input;
14488   vl_api_classify_table_info_t *mp;
14489   f64 timeout;
14490
14491   u32 table_id = ~0;
14492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14493     {
14494       if (unformat (input, "table_id %d", &table_id))
14495         ;
14496       else
14497         break;
14498     }
14499   if (table_id == ~0)
14500     {
14501       errmsg ("missing table id\n");
14502       return -99;
14503     }
14504
14505   /* Construct the API message */
14506   M (CLASSIFY_TABLE_INFO, classify_table_info);
14507   mp->context = 0;
14508   mp->table_id = ntohl (table_id);
14509
14510   S;
14511   W;
14512   /* NOTREACHED */
14513   return 0;
14514 }
14515
14516 int
14517 api_classify_session_dump (vat_main_t * vam)
14518 {
14519   unformat_input_t *input = vam->input;
14520   vl_api_classify_session_dump_t *mp;
14521   f64 timeout;
14522
14523   u32 table_id = ~0;
14524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14525     {
14526       if (unformat (input, "table_id %d", &table_id))
14527         ;
14528       else
14529         break;
14530     }
14531   if (table_id == ~0)
14532     {
14533       errmsg ("missing table id\n");
14534       return -99;
14535     }
14536
14537   /* Construct the API message */
14538   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14539   mp->context = 0;
14540   mp->table_id = ntohl (table_id);
14541   S;
14542
14543   /* Use a control ping for synchronization */
14544   {
14545     vl_api_control_ping_t *mp;
14546     M (CONTROL_PING, control_ping);
14547     S;
14548   }
14549   W;
14550   /* NOTREACHED */
14551   return 0;
14552 }
14553
14554 static void
14555 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14556 {
14557   vat_main_t *vam = &vat_main;
14558
14559   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14560            "src_address %U, fib_index %u, path_mtu %u, "
14561            "template_interval %u\n",
14562            format_ip4_address, mp->collector_address,
14563            ntohs (mp->collector_port),
14564            format_ip4_address, mp->src_address,
14565            ntohl (mp->fib_index),
14566            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14567
14568   vam->retval = 0;
14569   vam->result_ready = 1;
14570 }
14571
14572 static void
14573 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14574 {
14575   vat_main_t *vam = &vat_main;
14576   vat_json_node_t node;
14577   struct in_addr collector_address;
14578   struct in_addr src_address;
14579
14580   vat_json_init_object (&node);
14581   clib_memcpy (&collector_address, &mp->collector_address,
14582                sizeof (collector_address));
14583   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14584   vat_json_object_add_uint (&node, "collector_port",
14585                             ntohs (mp->collector_port));
14586   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14587   vat_json_object_add_ip4 (&node, "src_address", src_address);
14588   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14589   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14590   vat_json_object_add_uint (&node, "template_interval",
14591                             ntohl (mp->template_interval));
14592
14593   vat_json_print (vam->ofp, &node);
14594   vat_json_free (&node);
14595   vam->retval = 0;
14596   vam->result_ready = 1;
14597 }
14598
14599 int
14600 api_ipfix_dump (vat_main_t * vam)
14601 {
14602   vl_api_ipfix_dump_t *mp;
14603   f64 timeout;
14604
14605   /* Construct the API message */
14606   M (IPFIX_DUMP, ipfix_dump);
14607   mp->context = 0;
14608
14609   S;
14610   W;
14611   /* NOTREACHED */
14612   return 0;
14613 }
14614
14615 int
14616 api_pg_create_interface (vat_main_t * vam)
14617 {
14618   unformat_input_t *input = vam->input;
14619   vl_api_pg_create_interface_t *mp;
14620   f64 timeout;
14621
14622   u32 if_id = ~0;
14623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (input, "if_id %d", &if_id))
14626         ;
14627       else
14628         break;
14629     }
14630   if (if_id == ~0)
14631     {
14632       errmsg ("missing pg interface index\n");
14633       return -99;
14634     }
14635
14636   /* Construct the API message */
14637   M (PG_CREATE_INTERFACE, pg_create_interface);
14638   mp->context = 0;
14639   mp->interface_id = ntohl (if_id);
14640
14641   S;
14642   W;
14643   /* NOTREACHED */
14644   return 0;
14645 }
14646
14647 int
14648 api_pg_capture (vat_main_t * vam)
14649 {
14650   unformat_input_t *input = vam->input;
14651   vl_api_pg_capture_t *mp;
14652   f64 timeout;
14653
14654   u32 if_id = ~0;
14655   u8 enable = 1;
14656   u32 count = 1;
14657   u8 pcap_file_set = 0;
14658   u8 *pcap_file = 0;
14659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14660     {
14661       if (unformat (input, "if_id %d", &if_id))
14662         ;
14663       else if (unformat (input, "pcap %s", &pcap_file))
14664         pcap_file_set = 1;
14665       else if (unformat (input, "count %d", &count))
14666         ;
14667       else if (unformat (input, "disable"))
14668         enable = 0;
14669       else
14670         break;
14671     }
14672   if (if_id == ~0)
14673     {
14674       errmsg ("missing pg interface index\n");
14675       return -99;
14676     }
14677   if (pcap_file_set > 0)
14678     {
14679       if (vec_len (pcap_file) > 255)
14680         {
14681           errmsg ("pcap file name is too long\n");
14682           return -99;
14683         }
14684     }
14685
14686   u32 name_len = vec_len (pcap_file);
14687   /* Construct the API message */
14688   M (PG_CAPTURE, pg_capture);
14689   mp->context = 0;
14690   mp->interface_id = ntohl (if_id);
14691   mp->is_enabled = enable;
14692   mp->count = ntohl (count);
14693   mp->pcap_name_length = ntohl (name_len);
14694   if (pcap_file_set != 0)
14695     {
14696       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14697     }
14698   vec_free (pcap_file);
14699
14700   S;
14701   W;
14702   /* NOTREACHED */
14703   return 0;
14704 }
14705
14706 int
14707 api_pg_enable_disable (vat_main_t * vam)
14708 {
14709   unformat_input_t *input = vam->input;
14710   vl_api_pg_enable_disable_t *mp;
14711   f64 timeout;
14712
14713   u8 enable = 1;
14714   u8 stream_name_set = 0;
14715   u8 *stream_name = 0;
14716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (input, "stream %s", &stream_name))
14719         stream_name_set = 1;
14720       else if (unformat (input, "disable"))
14721         enable = 0;
14722       else
14723         break;
14724     }
14725
14726   if (stream_name_set > 0)
14727     {
14728       if (vec_len (stream_name) > 255)
14729         {
14730           errmsg ("stream name too long\n");
14731           return -99;
14732         }
14733     }
14734
14735   u32 name_len = vec_len (stream_name);
14736   /* Construct the API message */
14737   M (PG_ENABLE_DISABLE, pg_enable_disable);
14738   mp->context = 0;
14739   mp->is_enabled = enable;
14740   if (stream_name_set != 0)
14741     {
14742       mp->stream_name_length = ntohl (name_len);
14743       clib_memcpy (mp->stream_name, stream_name, name_len);
14744     }
14745   vec_free (stream_name);
14746
14747   S;
14748   W;
14749   /* NOTREACHED */
14750   return 0;
14751 }
14752
14753 int
14754 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14755 {
14756   unformat_input_t *input = vam->input;
14757   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14758   f64 timeout;
14759
14760   u16 *low_ports = 0;
14761   u16 *high_ports = 0;
14762   u16 this_low;
14763   u16 this_hi;
14764   ip4_address_t ip4_addr;
14765   ip6_address_t ip6_addr;
14766   u32 length;
14767   u32 tmp, tmp2;
14768   u8 prefix_set = 0;
14769   u32 vrf_id = ~0;
14770   u8 is_add = 1;
14771   u8 is_ipv6 = 0;
14772
14773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14774     {
14775       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14776         {
14777           prefix_set = 1;
14778         }
14779       else
14780         if (unformat
14781             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14782         {
14783           prefix_set = 1;
14784           is_ipv6 = 1;
14785         }
14786       else if (unformat (input, "vrf %d", &vrf_id))
14787         ;
14788       else if (unformat (input, "del"))
14789         is_add = 0;
14790       else if (unformat (input, "port %d", &tmp))
14791         {
14792           if (tmp == 0 || tmp > 65535)
14793             {
14794               errmsg ("port %d out of range", tmp);
14795               return -99;
14796             }
14797           this_low = tmp;
14798           this_hi = this_low + 1;
14799           vec_add1 (low_ports, this_low);
14800           vec_add1 (high_ports, this_hi);
14801         }
14802       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14803         {
14804           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14805             {
14806               errmsg ("incorrect range parameters\n");
14807               return -99;
14808             }
14809           this_low = tmp;
14810           /* Note: in debug CLI +1 is added to high before
14811              passing to real fn that does "the work"
14812              (ip_source_and_port_range_check_add_del).
14813              This fn is a wrapper around the binary API fn a
14814              control plane will call, which expects this increment
14815              to have occurred. Hence letting the binary API control
14816              plane fn do the increment for consistency between VAT
14817              and other control planes.
14818            */
14819           this_hi = tmp2;
14820           vec_add1 (low_ports, this_low);
14821           vec_add1 (high_ports, this_hi);
14822         }
14823       else
14824         break;
14825     }
14826
14827   if (prefix_set == 0)
14828     {
14829       errmsg ("<address>/<mask> not specified\n");
14830       return -99;
14831     }
14832
14833   if (vrf_id == ~0)
14834     {
14835       errmsg ("VRF ID required, not specified\n");
14836       return -99;
14837     }
14838
14839   if (vrf_id == 0)
14840     {
14841       errmsg
14842         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14843       return -99;
14844     }
14845
14846   if (vec_len (low_ports) == 0)
14847     {
14848       errmsg ("At least one port or port range required\n");
14849       return -99;
14850     }
14851
14852   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14853      ip_source_and_port_range_check_add_del);
14854
14855   mp->is_add = is_add;
14856
14857   if (is_ipv6)
14858     {
14859       mp->is_ipv6 = 1;
14860       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14861     }
14862   else
14863     {
14864       mp->is_ipv6 = 0;
14865       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14866     }
14867
14868   mp->mask_length = length;
14869   mp->number_of_ranges = vec_len (low_ports);
14870
14871   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
14872   vec_free (low_ports);
14873
14874   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
14875   vec_free (high_ports);
14876
14877   mp->vrf_id = ntohl (vrf_id);
14878
14879   S;
14880   W;
14881   /* NOTREACHED */
14882   return 0;
14883 }
14884
14885 int
14886 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
14887 {
14888   unformat_input_t *input = vam->input;
14889   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
14890   f64 timeout;
14891   u32 sw_if_index = ~0;
14892   int vrf_set = 0;
14893   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
14894   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
14895   u8 is_add = 1;
14896
14897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14900         ;
14901       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14902         ;
14903       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
14904         vrf_set = 1;
14905       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
14906         vrf_set = 1;
14907       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
14908         vrf_set = 1;
14909       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
14910         vrf_set = 1;
14911       else if (unformat (input, "del"))
14912         is_add = 0;
14913       else
14914         break;
14915     }
14916
14917   if (sw_if_index == ~0)
14918     {
14919       errmsg ("Interface required but not specified\n");
14920       return -99;
14921     }
14922
14923   if (vrf_set == 0)
14924     {
14925       errmsg ("VRF ID required but not specified\n");
14926       return -99;
14927     }
14928
14929   if (tcp_out_vrf_id == 0
14930       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
14931     {
14932       errmsg
14933         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14934       return -99;
14935     }
14936
14937   /* Construct the API message */
14938   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
14939      ip_source_and_port_range_check_interface_add_del);
14940
14941   mp->sw_if_index = ntohl (sw_if_index);
14942   mp->is_add = is_add;
14943   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
14944   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
14945   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
14946   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
14947
14948   /* send it... */
14949   S;
14950
14951   /* Wait for a reply... */
14952   W;
14953 }
14954
14955 static int
14956 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
14957 {
14958   unformat_input_t *i = vam->input;
14959   vl_api_ipsec_gre_add_del_tunnel_t *mp;
14960   f64 timeout;
14961   u32 local_sa_id = 0;
14962   u32 remote_sa_id = 0;
14963   ip4_address_t src_address;
14964   ip4_address_t dst_address;
14965   u8 is_add = 1;
14966
14967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14968     {
14969       if (unformat (i, "local_sa %d", &local_sa_id))
14970         ;
14971       else if (unformat (i, "remote_sa %d", &remote_sa_id))
14972         ;
14973       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
14974         ;
14975       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
14976         ;
14977       else if (unformat (i, "del"))
14978         is_add = 0;
14979       else
14980         {
14981           clib_warning ("parse error '%U'", format_unformat_error, i);
14982           return -99;
14983         }
14984     }
14985
14986   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
14987
14988   mp->local_sa_id = ntohl (local_sa_id);
14989   mp->remote_sa_id = ntohl (remote_sa_id);
14990   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
14991   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
14992   mp->is_add = is_add;
14993
14994   S;
14995   W;
14996   /* NOTREACHED */
14997   return 0;
14998 }
14999
15000 static void vl_api_ipsec_gre_tunnel_details_t_handler
15001   (vl_api_ipsec_gre_tunnel_details_t * mp)
15002 {
15003   vat_main_t *vam = &vat_main;
15004
15005   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15006            ntohl (mp->sw_if_index),
15007            format_ip4_address, &mp->src_address,
15008            format_ip4_address, &mp->dst_address,
15009            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15010 }
15011
15012 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15013   (vl_api_ipsec_gre_tunnel_details_t * mp)
15014 {
15015   vat_main_t *vam = &vat_main;
15016   vat_json_node_t *node = NULL;
15017   struct in_addr ip4;
15018
15019   if (VAT_JSON_ARRAY != vam->json_tree.type)
15020     {
15021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15022       vat_json_init_array (&vam->json_tree);
15023     }
15024   node = vat_json_array_add (&vam->json_tree);
15025
15026   vat_json_init_object (node);
15027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15028   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15029   vat_json_object_add_ip4 (node, "src_address", ip4);
15030   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15031   vat_json_object_add_ip4 (node, "dst_address", ip4);
15032   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15033   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15034 }
15035
15036 static int
15037 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15038 {
15039   unformat_input_t *i = vam->input;
15040   vl_api_ipsec_gre_tunnel_dump_t *mp;
15041   f64 timeout;
15042   u32 sw_if_index;
15043   u8 sw_if_index_set = 0;
15044
15045   /* Parse args required to build the message */
15046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15047     {
15048       if (unformat (i, "sw_if_index %d", &sw_if_index))
15049         sw_if_index_set = 1;
15050       else
15051         break;
15052     }
15053
15054   if (sw_if_index_set == 0)
15055     {
15056       sw_if_index = ~0;
15057     }
15058
15059   if (!vam->json_output)
15060     {
15061       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15062                "sw_if_index", "src_address", "dst_address",
15063                "local_sa_id", "remote_sa_id");
15064     }
15065
15066   /* Get list of gre-tunnel interfaces */
15067   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15068
15069   mp->sw_if_index = htonl (sw_if_index);
15070
15071   S;
15072
15073   /* Use a control ping for synchronization */
15074   {
15075     vl_api_control_ping_t *mp;
15076     M (CONTROL_PING, control_ping);
15077     S;
15078   }
15079   W;
15080 }
15081
15082 static int
15083 q_or_quit (vat_main_t * vam)
15084 {
15085   longjmp (vam->jump_buf, 1);
15086   return 0;                     /* not so much */
15087 }
15088
15089 static int
15090 q (vat_main_t * vam)
15091 {
15092   return q_or_quit (vam);
15093 }
15094
15095 static int
15096 quit (vat_main_t * vam)
15097 {
15098   return q_or_quit (vam);
15099 }
15100
15101 static int
15102 comment (vat_main_t * vam)
15103 {
15104   return 0;
15105 }
15106
15107 static int
15108 cmd_cmp (void *a1, void *a2)
15109 {
15110   u8 **c1 = a1;
15111   u8 **c2 = a2;
15112
15113   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15114 }
15115
15116 static int
15117 help (vat_main_t * vam)
15118 {
15119   u8 **cmds = 0;
15120   u8 *name = 0;
15121   hash_pair_t *p;
15122   unformat_input_t *i = vam->input;
15123   int j;
15124
15125   if (unformat (i, "%s", &name))
15126     {
15127       uword *hs;
15128
15129       vec_add1 (name, 0);
15130
15131       hs = hash_get_mem (vam->help_by_name, name);
15132       if (hs)
15133         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15134       else
15135         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15136       vec_free (name);
15137       return 0;
15138     }
15139
15140   fformat (vam->ofp, "Help is available for the following:\n");
15141
15142     /* *INDENT-OFF* */
15143     hash_foreach_pair (p, vam->function_by_name,
15144     ({
15145       vec_add1 (cmds, (u8 *)(p->key));
15146     }));
15147     /* *INDENT-ON* */
15148
15149   vec_sort_with_function (cmds, cmd_cmp);
15150
15151   for (j = 0; j < vec_len (cmds); j++)
15152     fformat (vam->ofp, "%s\n", cmds[j]);
15153
15154   vec_free (cmds);
15155   return 0;
15156 }
15157
15158 static int
15159 set (vat_main_t * vam)
15160 {
15161   u8 *name = 0, *value = 0;
15162   unformat_input_t *i = vam->input;
15163
15164   if (unformat (i, "%s", &name))
15165     {
15166       /* The input buffer is a vector, not a string. */
15167       value = vec_dup (i->buffer);
15168       vec_delete (value, i->index, 0);
15169       /* Almost certainly has a trailing newline */
15170       if (value[vec_len (value) - 1] == '\n')
15171         value[vec_len (value) - 1] = 0;
15172       /* Make sure it's a proper string, one way or the other */
15173       vec_add1 (value, 0);
15174       (void) clib_macro_set_value (&vam->macro_main,
15175                                    (char *) name, (char *) value);
15176     }
15177   else
15178     errmsg ("usage: set <name> <value>\n");
15179
15180   vec_free (name);
15181   vec_free (value);
15182   return 0;
15183 }
15184
15185 static int
15186 unset (vat_main_t * vam)
15187 {
15188   u8 *name = 0;
15189
15190   if (unformat (vam->input, "%s", &name))
15191     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15192       errmsg ("unset: %s wasn't set\n", name);
15193   vec_free (name);
15194   return 0;
15195 }
15196
15197 typedef struct
15198 {
15199   u8 *name;
15200   u8 *value;
15201 } macro_sort_t;
15202
15203
15204 static int
15205 macro_sort_cmp (void *a1, void *a2)
15206 {
15207   macro_sort_t *s1 = a1;
15208   macro_sort_t *s2 = a2;
15209
15210   return strcmp ((char *) (s1->name), (char *) (s2->name));
15211 }
15212
15213 static int
15214 dump_macro_table (vat_main_t * vam)
15215 {
15216   macro_sort_t *sort_me = 0, *sm;
15217   int i;
15218   hash_pair_t *p;
15219
15220     /* *INDENT-OFF* */
15221     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15222     ({
15223       vec_add2 (sort_me, sm, 1);
15224       sm->name = (u8 *)(p->key);
15225       sm->value = (u8 *) (p->value[0]);
15226     }));
15227     /* *INDENT-ON* */
15228
15229   vec_sort_with_function (sort_me, macro_sort_cmp);
15230
15231   if (vec_len (sort_me))
15232     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15233   else
15234     fformat (vam->ofp, "The macro table is empty...\n");
15235
15236   for (i = 0; i < vec_len (sort_me); i++)
15237     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15238   return 0;
15239 }
15240
15241 static int
15242 dump_node_table (vat_main_t * vam)
15243 {
15244   int i, j;
15245   vlib_node_t *node, *next_node;
15246
15247   if (vec_len (vam->graph_nodes) == 0)
15248     {
15249       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15250       return 0;
15251     }
15252
15253   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15254     {
15255       node = vam->graph_nodes[i];
15256       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15257       for (j = 0; j < vec_len (node->next_nodes); j++)
15258         {
15259           if (node->next_nodes[j] != ~0)
15260             {
15261               next_node = vam->graph_nodes[node->next_nodes[j]];
15262               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15263             }
15264         }
15265     }
15266   return 0;
15267 }
15268
15269 static int
15270 search_node_table (vat_main_t * vam)
15271 {
15272   unformat_input_t *line_input = vam->input;
15273   u8 *node_to_find;
15274   int j;
15275   vlib_node_t *node, *next_node;
15276   uword *p;
15277
15278   if (vam->graph_node_index_by_name == 0)
15279     {
15280       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15281       return 0;
15282     }
15283
15284   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15285     {
15286       if (unformat (line_input, "%s", &node_to_find))
15287         {
15288           vec_add1 (node_to_find, 0);
15289           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15290           if (p == 0)
15291             {
15292               fformat (vam->ofp, "%s not found...\n", node_to_find);
15293               goto out;
15294             }
15295           node = vam->graph_nodes[p[0]];
15296           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15297           for (j = 0; j < vec_len (node->next_nodes); j++)
15298             {
15299               if (node->next_nodes[j] != ~0)
15300                 {
15301                   next_node = vam->graph_nodes[node->next_nodes[j]];
15302                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15303                 }
15304             }
15305         }
15306
15307       else
15308         {
15309           clib_warning ("parse error '%U'", format_unformat_error,
15310                         line_input);
15311           return -99;
15312         }
15313
15314     out:
15315       vec_free (node_to_find);
15316
15317     }
15318
15319   return 0;
15320 }
15321
15322
15323 static int
15324 script (vat_main_t * vam)
15325 {
15326   u8 *s = 0;
15327   char *save_current_file;
15328   unformat_input_t save_input;
15329   jmp_buf save_jump_buf;
15330   u32 save_line_number;
15331
15332   FILE *new_fp, *save_ifp;
15333
15334   if (unformat (vam->input, "%s", &s))
15335     {
15336       new_fp = fopen ((char *) s, "r");
15337       if (new_fp == 0)
15338         {
15339           errmsg ("Couldn't open script file %s\n", s);
15340           vec_free (s);
15341           return -99;
15342         }
15343     }
15344   else
15345     {
15346       errmsg ("Missing script name\n");
15347       return -99;
15348     }
15349
15350   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15351   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15352   save_ifp = vam->ifp;
15353   save_line_number = vam->input_line_number;
15354   save_current_file = (char *) vam->current_file;
15355
15356   vam->input_line_number = 0;
15357   vam->ifp = new_fp;
15358   vam->current_file = s;
15359   do_one_file (vam);
15360
15361   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15362   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15363   vam->ifp = save_ifp;
15364   vam->input_line_number = save_line_number;
15365   vam->current_file = (u8 *) save_current_file;
15366   vec_free (s);
15367
15368   return 0;
15369 }
15370
15371 static int
15372 echo (vat_main_t * vam)
15373 {
15374   fformat (vam->ofp, "%v", vam->input->buffer);
15375   return 0;
15376 }
15377
15378 /* List of API message constructors, CLI names map to api_xxx */
15379 #define foreach_vpe_api_msg                                             \
15380 _(create_loopback,"[mac <mac-addr>]")                                   \
15381 _(sw_interface_dump,"")                                                 \
15382 _(sw_interface_set_flags,                                               \
15383   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15384 _(sw_interface_add_del_address,                                         \
15385   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15386 _(sw_interface_set_table,                                               \
15387   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15388 _(sw_interface_set_vpath,                                               \
15389   "<intfc> | sw_if_index <id> enable | disable")                        \
15390 _(sw_interface_set_l2_xconnect,                                         \
15391   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15392   "enable | disable")                                                   \
15393 _(sw_interface_set_l2_bridge,                                           \
15394   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15395   "[shg <split-horizon-group>] [bvi]\n"                                 \
15396   "enable | disable")                                                   \
15397 _(bridge_domain_add_del,                                                \
15398   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15399 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15400 _(l2fib_add_del,                                                        \
15401   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15402 _(l2_flags,                                                             \
15403   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15404 _(bridge_flags,                                                         \
15405   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15406 _(tap_connect,                                                          \
15407   "tapname <name> mac <mac-addr> | random-mac")                         \
15408 _(tap_modify,                                                           \
15409   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15410 _(tap_delete,                                                           \
15411   "<vpp-if-name> | sw_if_index <id>")                                   \
15412 _(sw_interface_tap_dump, "")                                            \
15413 _(ip_add_del_route,                                                     \
15414   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15415   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15416   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15417   "[multipath] [count <n>]")                                            \
15418 _(proxy_arp_add_del,                                                    \
15419   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15420 _(proxy_arp_intfc_enable_disable,                                       \
15421   "<intfc> | sw_if_index <id> enable | disable")                        \
15422 _(mpls_add_del_encap,                                                   \
15423   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15424 _(mpls_add_del_decap,                                                   \
15425   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15426 _(mpls_gre_add_del_tunnel,                                              \
15427   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15428   "adj <ip4-address>/<mask-width> [del]")                               \
15429 _(sw_interface_set_unnumbered,                                          \
15430   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15431 _(ip_neighbor_add_del,                                                  \
15432   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15433   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15434 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15435 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15436 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15437   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15438   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15439   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15440 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15441 _(reset_fib, "vrf <n> [ipv6]")                                          \
15442 _(dhcp_proxy_config,                                                    \
15443   "svr <v46-address> src <v46-address>\n"                               \
15444    "insert-cid <n> [del]")                                              \
15445 _(dhcp_proxy_config_2,                                                  \
15446   "svr <v46-address> src <v46-address>\n"                               \
15447    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15448 _(dhcp_proxy_set_vss,                                                   \
15449   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15450 _(dhcp_client_config,                                                   \
15451   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15452 _(set_ip_flow_hash,                                                     \
15453   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15454 _(sw_interface_ip6_enable_disable,                                      \
15455   "<intfc> | sw_if_index <id> enable | disable")                        \
15456 _(sw_interface_ip6_set_link_local_address,                              \
15457   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15458 _(sw_interface_ip6nd_ra_prefix,                                         \
15459   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15460   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15461   "[nolink] [isno]")                                                    \
15462 _(sw_interface_ip6nd_ra_config,                                         \
15463   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15464   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15465   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15466 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15467 _(l2_patch_add_del,                                                     \
15468   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15469   "enable | disable")                                                   \
15470 _(mpls_ethernet_add_del_tunnel,                                         \
15471   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15472   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15473 _(mpls_ethernet_add_del_tunnel_2,                                       \
15474   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15475   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15476 _(sr_tunnel_add_del,                                                    \
15477   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15478   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15479   "[policy <policy_name>]")                                             \
15480 _(sr_policy_add_del,                                                    \
15481   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15482 _(sr_multicast_map_add_del,                                             \
15483   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15484 _(classify_add_del_table,                                               \
15485   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15486   "[del] mask <mask-value>\n"                                           \
15487   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15488 _(classify_add_del_session,                                             \
15489   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15490   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15491   "  [l3 [ip4|ip6]]")                                                   \
15492 _(classify_set_interface_ip_table,                                      \
15493   "<intfc> | sw_if_index <nn> table <nn>")                              \
15494 _(classify_set_interface_l2_tables,                                     \
15495   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15496   "  [other-table <nn>]")                                               \
15497 _(get_node_index, "node <node-name")                                    \
15498 _(add_node_next, "node <node-name> next <next-node-name>")              \
15499 _(l2tpv3_create_tunnel,                                                 \
15500   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15501   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15502   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15503 _(l2tpv3_set_tunnel_cookies,                                            \
15504   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15505   "[new_remote_cookie <nn>]\n")                                         \
15506 _(l2tpv3_interface_enable_disable,                                      \
15507   "<intfc> | sw_if_index <nn> enable | disable")                        \
15508 _(l2tpv3_set_lookup_key,                                                \
15509   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15510 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15511 _(vxlan_add_del_tunnel,                                                 \
15512   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15513   " [decap-next l2|ip4|ip6] [del]")                                     \
15514 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15515 _(gre_add_del_tunnel,                                                   \
15516   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15517 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15518 _(l2_fib_clear_table, "")                                               \
15519 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15520 _(l2_interface_vlan_tag_rewrite,                                        \
15521   "<intfc> | sw_if_index <nn> \n"                                       \
15522   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15523   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15524 _(create_vhost_user_if,                                                 \
15525         "socket <filename> [server] [renumber <dev_instance>] "         \
15526         "[mac <mac_address>]")                                          \
15527 _(modify_vhost_user_if,                                                 \
15528         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15529         "[server] [renumber <dev_instance>]")                           \
15530 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15531 _(sw_interface_vhost_user_dump, "")                                     \
15532 _(show_version, "")                                                     \
15533 _(vxlan_gpe_add_del_tunnel,                                             \
15534   "local <addr> remote <addr> vni <nn>\n"                               \
15535     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15536   "[next-ethernet] [next-nsh]\n")                                       \
15537 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15538 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15539 _(interface_name_renumber,                                              \
15540   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15541 _(input_acl_set_interface,                                              \
15542   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15543   "  [l2-table <nn>] [del]")                                            \
15544 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15545 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15546 _(ip_dump, "ipv4 | ipv6")                                               \
15547 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15548 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15549   "  spid_id <n> ")                                                     \
15550 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15551   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15552   "  integ_alg <alg> integ_key <hex>")                                  \
15553 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15554   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15555   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15556   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15557 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15558 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15559 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15560   "(auth_data 0x<data> | auth_data <data>)")                            \
15561 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15562   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15563 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15564   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15565   "(local|remote)")                                                     \
15566 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15567 _(delete_loopback,"sw_if_index <nn>")                                   \
15568 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15569 _(map_add_domain,                                                       \
15570   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15571   "ip6-src <ip6addr> "                                                  \
15572   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15573 _(map_del_domain, "index <n>")                                          \
15574 _(map_add_del_rule,                                                     \
15575   "index <n> psid <n> dst <ip6addr> [del]")                             \
15576 _(map_domain_dump, "")                                                  \
15577 _(map_rule_dump, "index <map-domain>")                                  \
15578 _(want_interface_events,  "enable|disable")                             \
15579 _(want_stats,"enable|disable")                                          \
15580 _(get_first_msg_id, "client <name>")                                    \
15581 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15582 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15583   "fib-id <nn> [ip4][ip6][default]")                                    \
15584 _(get_node_graph, " ")                                                  \
15585 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15586 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15587   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15588   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15589 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15590   " vrf_id <nn>  add | pop | none")                                     \
15591 _(trace_profile_del, "")                                                \
15592 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15593                             " sw_if_index <sw_if_index> p <priority> "  \
15594                             "w <weight>] [del]")                        \
15595 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15596                         "iface <intf> | sw_if_index <sw_if_index> "     \
15597                         "p <priority> w <weight> [del]")                \
15598 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15599                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15600                           "locator-set <locator_name> [del]")           \
15601 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15602   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15603 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15604 _(lisp_gpe_enable_disable, "enable|disable")                            \
15605 _(lisp_enable_disable, "enable|disable")                                \
15606 _(lisp_gpe_add_del_iface, "up|down")                                    \
15607 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15608                                "rloc <locator> p <prio> "               \
15609                                "w <weight> [rloc <loc> ... ] "          \
15610                                "action <action> [del-all]")             \
15611 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15612                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15613                           "[rloc <loc> ... ] action <action>")          \
15614 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15615 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15616 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15617 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15618                          "locator-set <loc-set-name>] [local | remote]")\
15619 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15620                        "[local] | [remote]")                            \
15621 _(lisp_eid_table_map_dump, "")                                          \
15622 _(lisp_gpe_tunnel_dump, "")                                             \
15623 _(lisp_map_resolver_dump, "")                                           \
15624 _(show_lisp_status, "")                                                 \
15625 _(lisp_get_map_request_itr_rlocs, "")                                   \
15626 _(show_lisp_pitr, "")                                                   \
15627 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15628 _(af_packet_delete, "name <host interface name>")                       \
15629 _(policer_add_del, "name <policer name> <params> [del]")                \
15630 _(policer_dump, "[name <policer name>]")                                \
15631 _(policer_classify_set_interface,                                       \
15632   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15633   "  [l2-table <nn>] [del]")                                            \
15634 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15635 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15636     "[master|slave]")                                                   \
15637 _(netmap_delete, "name <interface name>")                               \
15638 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15639 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15640 _(mpls_fib_encap_dump, "")                                              \
15641 _(mpls_fib_decap_dump, "")                                              \
15642 _(classify_table_ids, "")                                               \
15643 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15644 _(classify_table_info, "table_id <nn>")                                 \
15645 _(classify_session_dump, "table_id <nn>")                               \
15646 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15647                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15648                 "[template_interval <nn>]")                             \
15649 _(ipfix_dump, "")                                                       \
15650 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15651 _(pg_create_interface, "if_id <nn>")                                    \
15652 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15653 _(pg_enable_disable, "[stream <id>] disable")                           \
15654 _(ip_source_and_port_range_check_add_del,                               \
15655   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15656 _(ip_source_and_port_range_check_interface_add_del,                     \
15657   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15658   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15659 _(ipsec_gre_add_del_tunnel,                                             \
15660   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15661 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")
15662
15663 /* List of command functions, CLI names map directly to functions */
15664 #define foreach_cli_function                                    \
15665 _(comment, "usage: comment <ignore-rest-of-line>")              \
15666 _(dump_interface_table, "usage: dump_interface_table")          \
15667 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15668 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15669 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15670 _(dump_stats_table, "usage: dump_stats_table")                  \
15671 _(dump_macro_table, "usage: dump_macro_table ")                 \
15672 _(dump_node_table, "usage: dump_node_table")                    \
15673 _(echo, "usage: echo <message>")                                \
15674 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15675 _(help, "usage: help")                                          \
15676 _(q, "usage: quit")                                             \
15677 _(quit, "usage: quit")                                          \
15678 _(search_node_table, "usage: search_node_table <name>...")      \
15679 _(set, "usage: set <variable-name> <value>")                    \
15680 _(script, "usage: script <file-name>")                          \
15681 _(unset, "usage: unset <variable-name>")
15682
15683 #define _(N,n)                                  \
15684     static void vl_api_##n##_t_handler_uni      \
15685     (vl_api_##n##_t * mp)                       \
15686     {                                           \
15687         vat_main_t * vam = &vat_main;           \
15688         if (vam->json_output) {                 \
15689             vl_api_##n##_t_handler_json(mp);    \
15690         } else {                                \
15691             vl_api_##n##_t_handler(mp);         \
15692         }                                       \
15693     }
15694 foreach_vpe_api_reply_msg;
15695 #undef _
15696
15697 void
15698 vat_api_hookup (vat_main_t * vam)
15699 {
15700 #define _(N,n)                                                  \
15701     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15702                            vl_api_##n##_t_handler_uni,          \
15703                            vl_noop_handler,                     \
15704                            vl_api_##n##_t_endian,               \
15705                            vl_api_##n##_t_print,                \
15706                            sizeof(vl_api_##n##_t), 1);
15707   foreach_vpe_api_reply_msg;
15708 #undef _
15709
15710   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15711
15712   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15713
15714   vam->function_by_name = hash_create_string (0, sizeof (uword));
15715
15716   vam->help_by_name = hash_create_string (0, sizeof (uword));
15717
15718   /* API messages we can send */
15719 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15720   foreach_vpe_api_msg;
15721 #undef _
15722
15723   /* Help strings */
15724 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15725   foreach_vpe_api_msg;
15726 #undef _
15727
15728   /* CLI functions */
15729 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15730   foreach_cli_function;
15731 #undef _
15732
15733   /* Help strings */
15734 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15735   foreach_cli_function;
15736 #undef _
15737 }
15738
15739 #undef vl_api_version
15740 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15741 #include <vpp-api/vpe.api.h>
15742 #undef vl_api_version
15743
15744 void
15745 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15746 {
15747   /*
15748    * Send the main API signature in slot 0. This bit of code must
15749    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15750    */
15751   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15752 }
15753
15754 /*
15755  * fd.io coding-style-patch-verification: ON
15756  *
15757  * Local Variables:
15758  * eval: (c-set-style "gnu")
15759  * End:
15760  */