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