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