bier: api cleanup
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/udp/udp_local.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <inttypes.h>
43 #include <vnet/ip/ip6_hop_by_hop.h>
44 #include <vnet/ip/ip_source_and_port_range_check.h>
45 #include <vnet/policer/xlate.h>
46 #include <vnet/span/span.h>
47 #include <vnet/policer/policer.h>
48 #include <vnet/policer/police.h>
49 #include <vnet/mfib/mfib_types.h>
50 #include <vnet/bonding/node.h>
51 #include <vnet/qos/qos_types.h>
52 #include <vnet/ethernet/ethernet_types_api.h>
53 #include <vnet/ip/ip_types_api.h>
54 #include "vat/json_format.h"
55 #include <vnet/ip/ip_types_api.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #if VPP_API_TEST_BUILTIN == 0
73 #define vl_print(handle, ...)
74 #else
75 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76 #endif
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 void vl_api_set_elog_main (elog_main_t * m);
85 int vl_api_set_elog_trace_api_messages (int enable);
86
87 #if VPP_API_TEST_BUILTIN == 0
88 #include <netdb.h>
89
90 u32
91 vl (void *p)
92 {
93   return vec_len (p);
94 }
95
96 int
97 vat_socket_connect (vat_main_t * vam)
98 {
99   int rv;
100   api_main_t *am = vlibapi_get_main ();
101   vam->socket_client_main = &socket_client_main;
102   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
103                                       "vpp_api_test",
104                                       0 /* default socket rx, tx buffer */ )))
105     return rv;
106
107   /* vpp expects the client index in network order */
108   vam->my_client_index = htonl (socket_client_main.client_index);
109   am->my_client_index = vam->my_client_index;
110   return 0;
111 }
112 #else /* vpp built-in case, we don't do sockets... */
113 int
114 vat_socket_connect (vat_main_t * vam)
115 {
116   return 0;
117 }
118
119 int
120 vl_socket_client_read (int wait)
121 {
122   return -1;
123 };
124
125 int
126 vl_socket_client_write ()
127 {
128   return -1;
129 };
130
131 void *
132 vl_socket_client_msg_alloc (int nbytes)
133 {
134   return 0;
135 }
136 #endif
137
138
139 f64
140 vat_time_now (vat_main_t * vam)
141 {
142 #if VPP_API_TEST_BUILTIN
143   return vlib_time_now (vam->vlib_main);
144 #else
145   return clib_time_now (&vam->clib_time);
146 #endif
147 }
148
149 void
150 errmsg (char *fmt, ...)
151 {
152   vat_main_t *vam = &vat_main;
153   va_list va;
154   u8 *s;
155
156   va_start (va, fmt);
157   s = va_format (0, fmt, &va);
158   va_end (va);
159
160   vec_add1 (s, 0);
161
162 #if VPP_API_TEST_BUILTIN
163   vlib_cli_output (vam->vlib_main, (char *) s);
164 #else
165   {
166     if (vam->ifp != stdin)
167       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
168                vam->input_line_number);
169     else
170       fformat (vam->ofp, "%s\n", (char *) s);
171     fflush (vam->ofp);
172   }
173 #endif
174
175   vec_free (s);
176 }
177
178 #if VPP_API_TEST_BUILTIN == 0
179 static uword
180 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
181 {
182   vat_main_t *vam = va_arg (*args, vat_main_t *);
183   u32 *result = va_arg (*args, u32 *);
184   u8 *if_name;
185   uword *p;
186
187   if (!unformat (input, "%s", &if_name))
188     return 0;
189
190   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
191   if (p == 0)
192     return 0;
193   *result = p[0];
194   return 1;
195 }
196
197 static uword
198 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
199 {
200   return 0;
201 }
202
203 /* Parse an IP4 address %d.%d.%d.%d. */
204 uword
205 unformat_ip4_address (unformat_input_t * input, va_list * args)
206 {
207   u8 *result = va_arg (*args, u8 *);
208   unsigned a[4];
209
210   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
211     return 0;
212
213   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
214     return 0;
215
216   result[0] = a[0];
217   result[1] = a[1];
218   result[2] = a[2];
219   result[3] = a[3];
220
221   return 1;
222 }
223
224 uword
225 unformat_ethernet_address (unformat_input_t * input, va_list * args)
226 {
227   u8 *result = va_arg (*args, u8 *);
228   u32 i, a[6];
229
230   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
231                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
232     return 0;
233
234   /* Check range. */
235   for (i = 0; i < 6; i++)
236     if (a[i] >= (1 << 8))
237       return 0;
238
239   for (i = 0; i < 6; i++)
240     result[i] = a[i];
241
242   return 1;
243 }
244
245 /* Returns ethernet type as an int in host byte order. */
246 uword
247 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
248                                         va_list * args)
249 {
250   u16 *result = va_arg (*args, u16 *);
251   int type;
252
253   /* Numeric type. */
254   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
255     {
256       if (type >= (1 << 16))
257         return 0;
258       *result = type;
259       return 1;
260     }
261   return 0;
262 }
263
264 /* Parse an IP46 address. */
265 uword
266 unformat_ip46_address (unformat_input_t * input, va_list * args)
267 {
268   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
269   ip46_type_t type = va_arg (*args, ip46_type_t);
270   if ((type != IP46_TYPE_IP6) &&
271       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
272     {
273       ip46_address_mask_ip4 (ip46);
274       return 1;
275     }
276   else if ((type != IP46_TYPE_IP4) &&
277            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
278     {
279       return 1;
280     }
281   return 0;
282 }
283
284 /* Parse an IP6 address. */
285 uword
286 unformat_ip6_address (unformat_input_t * input, va_list * args)
287 {
288   ip6_address_t *result = va_arg (*args, ip6_address_t *);
289   u16 hex_quads[8];
290   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
291   uword c, n_colon, double_colon_index;
292
293   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
294   double_colon_index = ARRAY_LEN (hex_quads);
295   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
296     {
297       hex_digit = 16;
298       if (c >= '0' && c <= '9')
299         hex_digit = c - '0';
300       else if (c >= 'a' && c <= 'f')
301         hex_digit = c + 10 - 'a';
302       else if (c >= 'A' && c <= 'F')
303         hex_digit = c + 10 - 'A';
304       else if (c == ':' && n_colon < 2)
305         n_colon++;
306       else
307         {
308           unformat_put_input (input);
309           break;
310         }
311
312       /* Too many hex quads. */
313       if (n_hex_quads >= ARRAY_LEN (hex_quads))
314         return 0;
315
316       if (hex_digit < 16)
317         {
318           hex_quad = (hex_quad << 4) | hex_digit;
319
320           /* Hex quad must fit in 16 bits. */
321           if (n_hex_digits >= 4)
322             return 0;
323
324           n_colon = 0;
325           n_hex_digits++;
326         }
327
328       /* Save position of :: */
329       if (n_colon == 2)
330         {
331           /* More than one :: ? */
332           if (double_colon_index < ARRAY_LEN (hex_quads))
333             return 0;
334           double_colon_index = n_hex_quads;
335         }
336
337       if (n_colon > 0 && n_hex_digits > 0)
338         {
339           hex_quads[n_hex_quads++] = hex_quad;
340           hex_quad = 0;
341           n_hex_digits = 0;
342         }
343     }
344
345   if (n_hex_digits > 0)
346     hex_quads[n_hex_quads++] = hex_quad;
347
348   {
349     word i;
350
351     /* Expand :: to appropriate number of zero hex quads. */
352     if (double_colon_index < ARRAY_LEN (hex_quads))
353       {
354         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
355
356         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
357           hex_quads[n_zero + i] = hex_quads[i];
358
359         for (i = 0; i < n_zero; i++)
360           hex_quads[double_colon_index + i] = 0;
361
362         n_hex_quads = ARRAY_LEN (hex_quads);
363       }
364
365     /* Too few hex quads given. */
366     if (n_hex_quads < ARRAY_LEN (hex_quads))
367       return 0;
368
369     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
370       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
371
372     return 1;
373   }
374 }
375
376 uword
377 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
383   foreach_ipsec_policy_action
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389
390 u8 *
391 format_ipsec_crypto_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_crypto_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 u8 *
408 format_ipsec_integ_alg (u8 * s, va_list * args)
409 {
410   u32 i = va_arg (*args, u32);
411   u8 *t = 0;
412
413   switch (i)
414     {
415 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
416       foreach_ipsec_integ_alg
417 #undef _
418     default:
419       return format (s, "unknown");
420     }
421   return format (s, "%s", t);
422 }
423
424 #else /* VPP_API_TEST_BUILTIN == 1 */
425 static uword
426 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
427 {
428   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
429   vnet_main_t *vnm = vnet_get_main ();
430   u32 *result = va_arg (*args, u32 *);
431
432   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
433 }
434
435 static uword
436 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
437 {
438   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
439   vnet_main_t *vnm = vnet_get_main ();
440   u32 *result = va_arg (*args, u32 *);
441
442   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
443 }
444
445 #endif /* VPP_API_TEST_BUILTIN */
446
447 uword
448 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
449 {
450   u32 *r = va_arg (*args, u32 *);
451
452   if (0);
453 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
454   foreach_ipsec_crypto_alg
455 #undef _
456     else
457     return 0;
458   return 1;
459 }
460
461 uword
462 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
463 {
464   u32 *r = va_arg (*args, u32 *);
465
466   if (0);
467 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
468   foreach_ipsec_integ_alg
469 #undef _
470     else
471     return 0;
472   return 1;
473 }
474
475 static uword
476 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
477 {
478   u8 *r = va_arg (*args, u8 *);
479
480   if (unformat (input, "kbps"))
481     *r = QOS_RATE_KBPS;
482   else if (unformat (input, "pps"))
483     *r = QOS_RATE_PPS;
484   else
485     return 0;
486   return 1;
487 }
488
489 static uword
490 unformat_policer_round_type (unformat_input_t * input, va_list * args)
491 {
492   u8 *r = va_arg (*args, u8 *);
493
494   if (unformat (input, "closest"))
495     *r = QOS_ROUND_TO_CLOSEST;
496   else if (unformat (input, "up"))
497     *r = QOS_ROUND_TO_UP;
498   else if (unformat (input, "down"))
499     *r = QOS_ROUND_TO_DOWN;
500   else
501     return 0;
502   return 1;
503 }
504
505 static uword
506 unformat_policer_type (unformat_input_t * input, va_list * args)
507 {
508   u8 *r = va_arg (*args, u8 *);
509
510   if (unformat (input, "1r2c"))
511     *r = QOS_POLICER_TYPE_1R2C;
512   else if (unformat (input, "1r3c"))
513     *r = QOS_POLICER_TYPE_1R3C_RFC_2697;
514   else if (unformat (input, "2r3c-2698"))
515     *r = QOS_POLICER_TYPE_2R3C_RFC_2698;
516   else if (unformat (input, "2r3c-4115"))
517     *r = QOS_POLICER_TYPE_2R3C_RFC_4115;
518   else if (unformat (input, "2r3c-mef5cf1"))
519     *r = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
520   else
521     return 0;
522   return 1;
523 }
524
525 static uword
526 unformat_dscp (unformat_input_t * input, va_list * va)
527 {
528   u8 *r = va_arg (*va, u8 *);
529
530   if (0);
531 #define _(v, f) else if (unformat (input, #f)) *r = IP_DSCP_##f;
532   foreach_ip_dscp
533 #undef _
534     else return 0;
535   return 1;
536 }
537
538 static uword
539 unformat_policer_action_type (unformat_input_t * input, va_list * va)
540 {
541   qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
542
543   if (unformat (input, "drop"))
544     a->action_type = QOS_ACTION_DROP;
545   else if (unformat (input, "transmit"))
546     a->action_type = QOS_ACTION_TRANSMIT;
547   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
548     a->action_type = QOS_ACTION_MARK_AND_TRANSMIT;
549   else
550     return 0;
551   return 1;
552 }
553
554 static uword
555 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
556 {
557   u32 *r = va_arg (*va, u32 *);
558   u32 tid;
559
560   if (unformat (input, "ip4"))
561     tid = POLICER_CLASSIFY_TABLE_IP4;
562   else if (unformat (input, "ip6"))
563     tid = POLICER_CLASSIFY_TABLE_IP6;
564   else if (unformat (input, "l2"))
565     tid = POLICER_CLASSIFY_TABLE_L2;
566   else
567     return 0;
568
569   *r = tid;
570   return 1;
571 }
572
573 static uword
574 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
575 {
576   u32 *r = va_arg (*va, u32 *);
577   u32 tid;
578
579   if (unformat (input, "ip4"))
580     tid = FLOW_CLASSIFY_TABLE_IP4;
581   else if (unformat (input, "ip6"))
582     tid = FLOW_CLASSIFY_TABLE_IP6;
583   else
584     return 0;
585
586   *r = tid;
587   return 1;
588 }
589
590 #if (VPP_API_TEST_BUILTIN==0)
591
592 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
593 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
594 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
595 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
596
597 uword
598 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
599 {
600   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
601   mfib_itf_attribute_t attr;
602
603   old = *iflags;
604   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
605   {
606     if (unformat (input, mfib_itf_flag_long_names[attr]))
607       *iflags |= (1 << attr);
608   }
609   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
610   {
611     if (unformat (input, mfib_itf_flag_names[attr]))
612       *iflags |= (1 << attr);
613   }
614
615   return (old == *iflags ? 0 : 1);
616 }
617
618 uword
619 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
620 {
621   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
622   mfib_entry_attribute_t attr;
623
624   old = *eflags;
625   FOR_EACH_MFIB_ATTRIBUTE (attr)
626   {
627     if (unformat (input, mfib_flag_long_names[attr]))
628       *eflags |= (1 << attr);
629   }
630   FOR_EACH_MFIB_ATTRIBUTE (attr)
631   {
632     if (unformat (input, mfib_flag_names[attr]))
633       *eflags |= (1 << attr);
634   }
635
636   return (old == *eflags ? 0 : 1);
637 }
638
639 u8 *
640 format_ip4_address (u8 * s, va_list * args)
641 {
642   u8 *a = va_arg (*args, u8 *);
643   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
644 }
645
646 u8 *
647 format_ip6_address (u8 * s, va_list * args)
648 {
649   ip6_address_t *a = va_arg (*args, ip6_address_t *);
650   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
651
652   i_max_n_zero = ARRAY_LEN (a->as_u16);
653   max_n_zeros = 0;
654   i_first_zero = i_max_n_zero;
655   n_zeros = 0;
656   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
657     {
658       u32 is_zero = a->as_u16[i] == 0;
659       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
660         {
661           i_first_zero = i;
662           n_zeros = 0;
663         }
664       n_zeros += is_zero;
665       if ((!is_zero && n_zeros > max_n_zeros)
666           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
667         {
668           i_max_n_zero = i_first_zero;
669           max_n_zeros = n_zeros;
670           i_first_zero = ARRAY_LEN (a->as_u16);
671           n_zeros = 0;
672         }
673     }
674
675   last_double_colon = 0;
676   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
677     {
678       if (i == i_max_n_zero && max_n_zeros > 1)
679         {
680           s = format (s, "::");
681           i += max_n_zeros - 1;
682           last_double_colon = 1;
683         }
684       else
685         {
686           s = format (s, "%s%x",
687                       (last_double_colon || i == 0) ? "" : ":",
688                       clib_net_to_host_u16 (a->as_u16[i]));
689           last_double_colon = 0;
690         }
691     }
692
693   return s;
694 }
695
696 /* Format an IP46 address. */
697 u8 *
698 format_ip46_address (u8 * s, va_list * args)
699 {
700   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
701   ip46_type_t type = va_arg (*args, ip46_type_t);
702   int is_ip4 = 1;
703
704   switch (type)
705     {
706     case IP46_TYPE_ANY:
707       is_ip4 = ip46_address_is_ip4 (ip46);
708       break;
709     case IP46_TYPE_IP4:
710       is_ip4 = 1;
711       break;
712     case IP46_TYPE_IP6:
713       is_ip4 = 0;
714       break;
715     }
716
717   return is_ip4 ?
718     format (s, "%U", format_ip4_address, &ip46->ip4) :
719     format (s, "%U", format_ip6_address, &ip46->ip6);
720 }
721
722 u8 *
723 format_ethernet_address (u8 * s, va_list * args)
724 {
725   u8 *a = va_arg (*args, u8 *);
726
727   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
728                  a[0], a[1], a[2], a[3], a[4], a[5]);
729 }
730 #endif
731
732 static void
733 increment_v4_address (vl_api_ip4_address_t * i)
734 {
735   ip4_address_t *a = (ip4_address_t *) i;
736   u32 v;
737
738   v = ntohl (a->as_u32) + 1;
739   a->as_u32 = ntohl (v);
740 }
741
742 static void
743 increment_v6_address (vl_api_ip6_address_t * i)
744 {
745   ip6_address_t *a = (ip6_address_t *) i;
746   u64 v0, v1;
747
748   v0 = clib_net_to_host_u64 (a->as_u64[0]);
749   v1 = clib_net_to_host_u64 (a->as_u64[1]);
750
751   v1 += 1;
752   if (v1 == 0)
753     v0 += 1;
754   a->as_u64[0] = clib_net_to_host_u64 (v0);
755   a->as_u64[1] = clib_net_to_host_u64 (v1);
756 }
757
758 static void
759 increment_address (vl_api_address_t * a)
760 {
761   if (a->af == ADDRESS_IP4)
762     increment_v4_address (&a->un.ip4);
763   else if (a->af == ADDRESS_IP6)
764     increment_v6_address (&a->un.ip6);
765 }
766
767 static void
768 set_ip4_address (vl_api_address_t * a, u32 v)
769 {
770   if (a->af == ADDRESS_IP4)
771     {
772       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
773       i->as_u32 = v;
774     }
775 }
776
777 void
778 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
779 {
780   if (is_ip4)
781     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
782   else
783     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
784                       sizeof (ip6_address_t));
785 }
786
787 static void
788 increment_mac_address (u8 * mac)
789 {
790   u64 tmp = *((u64 *) mac);
791   tmp = clib_net_to_host_u64 (tmp);
792   tmp += 1 << 16;               /* skip unused (least significant) octets */
793   tmp = clib_host_to_net_u64 (tmp);
794
795   clib_memcpy (mac, &tmp, 6);
796 }
797
798 static void
799 vat_json_object_add_address (vat_json_node_t * node,
800                              const char *str, const vl_api_address_t * addr)
801 {
802   if (ADDRESS_IP6 == addr->af)
803     {
804       struct in6_addr ip6;
805
806       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
807       vat_json_object_add_ip6 (node, str, ip6);
808     }
809   else
810     {
811       struct in_addr ip4;
812
813       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
814       vat_json_object_add_ip4 (node, str, ip4);
815     }
816 }
817
818 static void
819 vat_json_object_add_prefix (vat_json_node_t * node,
820                             const vl_api_prefix_t * prefix)
821 {
822   vat_json_object_add_uint (node, "len", prefix->len);
823   vat_json_object_add_address (node, "address", &prefix->address);
824 }
825
826 static void vl_api_create_loopback_reply_t_handler
827   (vl_api_create_loopback_reply_t * mp)
828 {
829   vat_main_t *vam = &vat_main;
830   i32 retval = ntohl (mp->retval);
831
832   vam->retval = retval;
833   vam->regenerate_interface_table = 1;
834   vam->sw_if_index = ntohl (mp->sw_if_index);
835   vam->result_ready = 1;
836 }
837
838 static void vl_api_create_loopback_reply_t_handler_json
839   (vl_api_create_loopback_reply_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   vat_json_node_t node;
843
844   vat_json_init_object (&node);
845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
846   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
847
848   vat_json_print (vam->ofp, &node);
849   vat_json_free (&node);
850   vam->retval = ntohl (mp->retval);
851   vam->result_ready = 1;
852 }
853
854 static void vl_api_create_loopback_instance_reply_t_handler
855   (vl_api_create_loopback_instance_reply_t * mp)
856 {
857   vat_main_t *vam = &vat_main;
858   i32 retval = ntohl (mp->retval);
859
860   vam->retval = retval;
861   vam->regenerate_interface_table = 1;
862   vam->sw_if_index = ntohl (mp->sw_if_index);
863   vam->result_ready = 1;
864 }
865
866 static void vl_api_create_loopback_instance_reply_t_handler_json
867   (vl_api_create_loopback_instance_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871
872   vat_json_init_object (&node);
873   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
874   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
875
876   vat_json_print (vam->ofp, &node);
877   vat_json_free (&node);
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_af_packet_create_reply_t_handler
883   (vl_api_af_packet_create_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->sw_if_index = ntohl (mp->sw_if_index);
891   vam->result_ready = 1;
892 }
893
894 static void vl_api_af_packet_create_reply_t_handler_json
895   (vl_api_af_packet_create_reply_t * mp)
896 {
897   vat_main_t *vam = &vat_main;
898   vat_json_node_t node;
899
900   vat_json_init_object (&node);
901   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
902   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
903
904   vat_json_print (vam->ofp, &node);
905   vat_json_free (&node);
906
907   vam->retval = ntohl (mp->retval);
908   vam->result_ready = 1;
909 }
910
911 static void vl_api_create_vlan_subif_reply_t_handler
912   (vl_api_create_vlan_subif_reply_t * mp)
913 {
914   vat_main_t *vam = &vat_main;
915   i32 retval = ntohl (mp->retval);
916
917   vam->retval = retval;
918   vam->regenerate_interface_table = 1;
919   vam->sw_if_index = ntohl (mp->sw_if_index);
920   vam->result_ready = 1;
921 }
922
923 static void vl_api_create_vlan_subif_reply_t_handler_json
924   (vl_api_create_vlan_subif_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
932
933   vat_json_print (vam->ofp, &node);
934   vat_json_free (&node);
935
936   vam->retval = ntohl (mp->retval);
937   vam->result_ready = 1;
938 }
939
940 static void vl_api_create_subif_reply_t_handler
941   (vl_api_create_subif_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   i32 retval = ntohl (mp->retval);
945
946   vam->retval = retval;
947   vam->regenerate_interface_table = 1;
948   vam->sw_if_index = ntohl (mp->sw_if_index);
949   vam->result_ready = 1;
950 }
951
952 static void vl_api_create_subif_reply_t_handler_json
953   (vl_api_create_subif_reply_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t node;
957
958   vat_json_init_object (&node);
959   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
960   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
961
962   vat_json_print (vam->ofp, &node);
963   vat_json_free (&node);
964
965   vam->retval = ntohl (mp->retval);
966   vam->result_ready = 1;
967 }
968
969 static void vl_api_interface_name_renumber_reply_t_handler
970   (vl_api_interface_name_renumber_reply_t * mp)
971 {
972   vat_main_t *vam = &vat_main;
973   i32 retval = ntohl (mp->retval);
974
975   vam->retval = retval;
976   vam->regenerate_interface_table = 1;
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_interface_name_renumber_reply_t_handler_json
981   (vl_api_interface_name_renumber_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988
989   vat_json_print (vam->ofp, &node);
990   vat_json_free (&node);
991
992   vam->retval = ntohl (mp->retval);
993   vam->result_ready = 1;
994 }
995
996 /*
997  * Special-case: build the interface table, maintain
998  * the next loopback sw_if_index vbl.
999  */
1000 static void vl_api_sw_interface_details_t_handler
1001   (vl_api_sw_interface_details_t * mp)
1002 {
1003   vat_main_t *vam = &vat_main;
1004   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1005
1006   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1007                 ntohl (mp->sw_if_index));
1008
1009   /* In sub interface case, fill the sub interface table entry */
1010   if (mp->sw_if_index != mp->sup_sw_if_index)
1011     {
1012       sw_interface_subif_t *sub = NULL;
1013
1014       vec_add2 (vam->sw_if_subif_table, sub, 1);
1015
1016       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1017       strncpy ((char *) sub->interface_name, (char *) s,
1018                vec_len (sub->interface_name));
1019       sub->sw_if_index = ntohl (mp->sw_if_index);
1020       sub->sub_id = ntohl (mp->sub_id);
1021
1022       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1023
1024       sub->sub_number_of_tags = mp->sub_number_of_tags;
1025       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1026       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1027
1028       /* vlan tag rewrite */
1029       sub->vtr_op = ntohl (mp->vtr_op);
1030       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1031       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1032       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1033     }
1034 }
1035
1036 static void vl_api_sw_interface_details_t_handler_json
1037   (vl_api_sw_interface_details_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t *node = NULL;
1041
1042   if (VAT_JSON_ARRAY != vam->json_tree.type)
1043     {
1044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1045       vat_json_init_array (&vam->json_tree);
1046     }
1047   node = vat_json_array_add (&vam->json_tree);
1048
1049   vat_json_init_object (node);
1050   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1051   vat_json_object_add_uint (node, "sup_sw_if_index",
1052                             ntohl (mp->sup_sw_if_index));
1053   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1054                              sizeof (mp->l2_address));
1055   vat_json_object_add_string_copy (node, "interface_name",
1056                                    mp->interface_name);
1057   vat_json_object_add_string_copy (node, "interface_dev_type",
1058                                    mp->interface_dev_type);
1059   vat_json_object_add_uint (node, "flags", mp->flags);
1060   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1061   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1062   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1063   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1064   vat_json_object_add_uint (node, "sub_number_of_tags",
1065                             mp->sub_number_of_tags);
1066   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1067                             ntohs (mp->sub_outer_vlan_id));
1068   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1069                             ntohs (mp->sub_inner_vlan_id));
1070   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1071   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1072   vat_json_object_add_uint (node, "vtr_push_dot1q",
1073                             ntohl (mp->vtr_push_dot1q));
1074   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1075   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1076   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1077     {
1078       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1079                                        format (0, "%U",
1080                                                format_ethernet_address,
1081                                                &mp->b_dmac));
1082       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1083                                        format (0, "%U",
1084                                                format_ethernet_address,
1085                                                &mp->b_smac));
1086       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1087       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1088     }
1089 }
1090
1091 #if VPP_API_TEST_BUILTIN == 0
1092 static void vl_api_sw_interface_event_t_handler
1093   (vl_api_sw_interface_event_t * mp)
1094 {
1095   vat_main_t *vam = &vat_main;
1096   if (vam->interface_event_display)
1097     errmsg ("interface flags: sw_if_index %d %s %s",
1098             ntohl (mp->sw_if_index),
1099             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1100             "admin-up" : "admin-down",
1101             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1102             "link-up" : "link-down");
1103 }
1104 #endif
1105
1106 __clib_unused static void
1107 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1108 {
1109   /* JSON output not supported */
1110 }
1111
1112 static void
1113 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   vam->retval = retval;
1119   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1120   vam->result_ready = 1;
1121 }
1122
1123 static void
1124 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1125 {
1126   vat_main_t *vam = &vat_main;
1127   vat_json_node_t node;
1128   void *oldheap;
1129   u8 *reply;
1130
1131   vat_json_init_object (&node);
1132   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1133   vat_json_object_add_uint (&node, "reply_in_shmem",
1134                             ntohl (mp->reply_in_shmem));
1135   /* Toss the shared-memory original... */
1136   oldheap = vl_msg_push_heap ();
1137
1138   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1139   vec_free (reply);
1140
1141   vl_msg_pop_heap (oldheap);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   i32 retval = ntohl (mp->retval);
1155
1156   vec_reset_length (vam->cmd_reply);
1157
1158   vam->retval = retval;
1159   if (retval == 0)
1160     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1161   vam->result_ready = 1;
1162 }
1163
1164 static void
1165 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169   u8 *reply = 0;                /* reply vector */
1170
1171   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1172   vec_reset_length (vam->cmd_reply);
1173
1174   vat_json_init_object (&node);
1175   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1176   vat_json_object_add_string_copy (&node, "reply", reply);
1177
1178   vat_json_print (vam->ofp, &node);
1179   vat_json_free (&node);
1180   vec_free (reply);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_classify_add_del_table_reply_t_handler
1187   (vl_api_classify_add_del_table_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0 &&
1199           ((mp->new_table_index != 0xFFFFFFFF) ||
1200            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1201            (mp->match_n_vectors != 0xFFFFFFFF)))
1202         /*
1203          * Note: this is just barely thread-safe, depends on
1204          * the main thread spinning waiting for an answer...
1205          */
1206         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1207                 ntohl (mp->new_table_index),
1208                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1209       vam->result_ready = 1;
1210     }
1211 }
1212
1213 static void vl_api_classify_add_del_table_reply_t_handler_json
1214   (vl_api_classify_add_del_table_reply_t * mp)
1215 {
1216   vat_main_t *vam = &vat_main;
1217   vat_json_node_t node;
1218
1219   vat_json_init_object (&node);
1220   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1221   vat_json_object_add_uint (&node, "new_table_index",
1222                             ntohl (mp->new_table_index));
1223   vat_json_object_add_uint (&node, "skip_n_vectors",
1224                             ntohl (mp->skip_n_vectors));
1225   vat_json_object_add_uint (&node, "match_n_vectors",
1226                             ntohl (mp->match_n_vectors));
1227
1228   vat_json_print (vam->ofp, &node);
1229   vat_json_free (&node);
1230
1231   vam->retval = ntohl (mp->retval);
1232   vam->result_ready = 1;
1233 }
1234
1235 static void vl_api_get_node_index_reply_t_handler
1236   (vl_api_get_node_index_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   i32 retval = ntohl (mp->retval);
1240   if (vam->async_mode)
1241     {
1242       vam->async_errors += (retval < 0);
1243     }
1244   else
1245     {
1246       vam->retval = retval;
1247       if (retval == 0)
1248         errmsg ("node index %d", ntohl (mp->node_index));
1249       vam->result_ready = 1;
1250     }
1251 }
1252
1253 static void vl_api_get_node_index_reply_t_handler_json
1254   (vl_api_get_node_index_reply_t * mp)
1255 {
1256   vat_main_t *vam = &vat_main;
1257   vat_json_node_t node;
1258
1259   vat_json_init_object (&node);
1260   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1261   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1262
1263   vat_json_print (vam->ofp, &node);
1264   vat_json_free (&node);
1265
1266   vam->retval = ntohl (mp->retval);
1267   vam->result_ready = 1;
1268 }
1269
1270 static void vl_api_get_next_index_reply_t_handler
1271   (vl_api_get_next_index_reply_t * mp)
1272 {
1273   vat_main_t *vam = &vat_main;
1274   i32 retval = ntohl (mp->retval);
1275   if (vam->async_mode)
1276     {
1277       vam->async_errors += (retval < 0);
1278     }
1279   else
1280     {
1281       vam->retval = retval;
1282       if (retval == 0)
1283         errmsg ("next node index %d", ntohl (mp->next_index));
1284       vam->result_ready = 1;
1285     }
1286 }
1287
1288 static void vl_api_get_next_index_reply_t_handler_json
1289   (vl_api_get_next_index_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   vat_json_node_t node;
1293
1294   vat_json_init_object (&node);
1295   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1296   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1297
1298   vat_json_print (vam->ofp, &node);
1299   vat_json_free (&node);
1300
1301   vam->retval = ntohl (mp->retval);
1302   vam->result_ready = 1;
1303 }
1304
1305 static void vl_api_add_node_next_reply_t_handler
1306   (vl_api_add_node_next_reply_t * mp)
1307 {
1308   vat_main_t *vam = &vat_main;
1309   i32 retval = ntohl (mp->retval);
1310   if (vam->async_mode)
1311     {
1312       vam->async_errors += (retval < 0);
1313     }
1314   else
1315     {
1316       vam->retval = retval;
1317       if (retval == 0)
1318         errmsg ("next index %d", ntohl (mp->next_index));
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_add_node_next_reply_t_handler_json
1324   (vl_api_add_node_next_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1332
1333   vat_json_print (vam->ofp, &node);
1334   vat_json_free (&node);
1335
1336   vam->retval = ntohl (mp->retval);
1337   vam->result_ready = 1;
1338 }
1339
1340 static void vl_api_show_version_reply_t_handler
1341   (vl_api_show_version_reply_t * mp)
1342 {
1343   vat_main_t *vam = &vat_main;
1344   i32 retval = ntohl (mp->retval);
1345
1346   if (retval >= 0)
1347     {
1348       errmsg ("        program: %s", mp->program);
1349       errmsg ("        version: %s", mp->version);
1350       errmsg ("     build date: %s", mp->build_date);
1351       errmsg ("build directory: %s", mp->build_directory);
1352     }
1353   vam->retval = retval;
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_version_reply_t_handler_json
1358   (vl_api_show_version_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   vat_json_node_t node;
1362
1363   vat_json_init_object (&node);
1364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1365   vat_json_object_add_string_copy (&node, "program", mp->program);
1366   vat_json_object_add_string_copy (&node, "version", mp->version);
1367   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1368   vat_json_object_add_string_copy (&node, "build_directory",
1369                                    mp->build_directory);
1370
1371   vat_json_print (vam->ofp, &node);
1372   vat_json_free (&node);
1373
1374   vam->retval = ntohl (mp->retval);
1375   vam->result_ready = 1;
1376 }
1377
1378 static void vl_api_show_threads_reply_t_handler
1379   (vl_api_show_threads_reply_t * mp)
1380 {
1381   vat_main_t *vam = &vat_main;
1382   i32 retval = ntohl (mp->retval);
1383   int i, count = 0;
1384
1385   if (retval >= 0)
1386     count = ntohl (mp->count);
1387
1388   for (i = 0; i < count; i++)
1389     print (vam->ofp,
1390            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1391            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1392            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1393            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1394            ntohl (mp->thread_data[i].cpu_socket));
1395
1396   vam->retval = retval;
1397   vam->result_ready = 1;
1398 }
1399
1400 static void vl_api_show_threads_reply_t_handler_json
1401   (vl_api_show_threads_reply_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t node;
1405   vl_api_thread_data_t *td;
1406   i32 retval = ntohl (mp->retval);
1407   int i, count = 0;
1408
1409   if (retval >= 0)
1410     count = ntohl (mp->count);
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", retval);
1414   vat_json_object_add_uint (&node, "count", count);
1415
1416   for (i = 0; i < count; i++)
1417     {
1418       td = &mp->thread_data[i];
1419       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1420       vat_json_object_add_string_copy (&node, "name", td->name);
1421       vat_json_object_add_string_copy (&node, "type", td->type);
1422       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1423       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1424       vat_json_object_add_int (&node, "core", ntohl (td->id));
1425       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1426     }
1427
1428   vat_json_print (vam->ofp, &node);
1429   vat_json_free (&node);
1430
1431   vam->retval = retval;
1432   vam->result_ready = 1;
1433 }
1434
1435 static int
1436 api_show_threads (vat_main_t * vam)
1437 {
1438   vl_api_show_threads_t *mp;
1439   int ret;
1440
1441   print (vam->ofp,
1442          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1443          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1444
1445   M (SHOW_THREADS, mp);
1446
1447   S (mp);
1448   W (ret);
1449   return ret;
1450 }
1451
1452 static void
1453 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1454 {
1455   u32 n_macs = ntohl (mp->n_macs);
1456   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1457           ntohl (mp->pid), mp->client_index, n_macs);
1458   int i;
1459   for (i = 0; i < n_macs; i++)
1460     {
1461       vl_api_mac_entry_t *mac = &mp->mac[i];
1462       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1463               i + 1, ntohl (mac->sw_if_index),
1464               format_ethernet_address, mac->mac_addr, mac->action);
1465       if (i == 1000)
1466         break;
1467     }
1468 }
1469
1470 static void
1471 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1472 {
1473   /* JSON output not supported */
1474 }
1475
1476 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1477 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1478
1479 /*
1480  * Special-case: build the bridge domain table, maintain
1481  * the next bd id vbl.
1482  */
1483 static void vl_api_bridge_domain_details_t_handler
1484   (vl_api_bridge_domain_details_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1488   int i;
1489
1490   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1491          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1492
1493   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1494          ntohl (mp->bd_id), mp->learn, mp->forward,
1495          mp->flood, ntohl (mp->bvi_sw_if_index),
1496          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1497
1498   if (n_sw_ifs)
1499     {
1500       vl_api_bridge_domain_sw_if_t *sw_ifs;
1501       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1502              "Interface Name");
1503
1504       sw_ifs = mp->sw_if_details;
1505       for (i = 0; i < n_sw_ifs; i++)
1506         {
1507           u8 *sw_if_name = 0;
1508           u32 sw_if_index;
1509           hash_pair_t *p;
1510
1511           sw_if_index = ntohl (sw_ifs->sw_if_index);
1512
1513           /* *INDENT-OFF* */
1514           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1515                              ({
1516                                if ((u32) p->value[0] == sw_if_index)
1517                                  {
1518                                    sw_if_name = (u8 *)(p->key);
1519                                    break;
1520                                  }
1521                              }));
1522           /* *INDENT-ON* */
1523           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1524                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1525                  "sw_if_index not found!");
1526
1527           sw_ifs++;
1528         }
1529     }
1530 }
1531
1532 static void vl_api_bridge_domain_details_t_handler_json
1533   (vl_api_bridge_domain_details_t * mp)
1534 {
1535   vat_main_t *vam = &vat_main;
1536   vat_json_node_t *node, *array = NULL;
1537   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1538
1539   if (VAT_JSON_ARRAY != vam->json_tree.type)
1540     {
1541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1542       vat_json_init_array (&vam->json_tree);
1543     }
1544   node = vat_json_array_add (&vam->json_tree);
1545
1546   vat_json_init_object (node);
1547   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1548   vat_json_object_add_uint (node, "flood", mp->flood);
1549   vat_json_object_add_uint (node, "forward", mp->forward);
1550   vat_json_object_add_uint (node, "learn", mp->learn);
1551   vat_json_object_add_uint (node, "bvi_sw_if_index",
1552                             ntohl (mp->bvi_sw_if_index));
1553   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1554   array = vat_json_object_add (node, "sw_if");
1555   vat_json_init_array (array);
1556
1557
1558
1559   if (n_sw_ifs)
1560     {
1561       vl_api_bridge_domain_sw_if_t *sw_ifs;
1562       int i;
1563
1564       sw_ifs = mp->sw_if_details;
1565       for (i = 0; i < n_sw_ifs; i++)
1566         {
1567           node = vat_json_array_add (array);
1568           vat_json_init_object (node);
1569           vat_json_object_add_uint (node, "sw_if_index",
1570                                     ntohl (sw_ifs->sw_if_index));
1571           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1572           sw_ifs++;
1573         }
1574     }
1575 }
1576
1577 static void vl_api_control_ping_reply_t_handler
1578   (vl_api_control_ping_reply_t * mp)
1579 {
1580   vat_main_t *vam = &vat_main;
1581   i32 retval = ntohl (mp->retval);
1582   if (vam->async_mode)
1583     {
1584       vam->async_errors += (retval < 0);
1585     }
1586   else
1587     {
1588       vam->retval = retval;
1589       vam->result_ready = 1;
1590     }
1591   if (vam->socket_client_main)
1592     vam->socket_client_main->control_pings_outstanding--;
1593 }
1594
1595 static void vl_api_control_ping_reply_t_handler_json
1596   (vl_api_control_ping_reply_t * mp)
1597 {
1598   vat_main_t *vam = &vat_main;
1599   i32 retval = ntohl (mp->retval);
1600
1601   if (VAT_JSON_NONE != vam->json_tree.type)
1602     {
1603       vat_json_print (vam->ofp, &vam->json_tree);
1604       vat_json_free (&vam->json_tree);
1605       vam->json_tree.type = VAT_JSON_NONE;
1606     }
1607   else
1608     {
1609       /* just print [] */
1610       vat_json_init_array (&vam->json_tree);
1611       vat_json_print (vam->ofp, &vam->json_tree);
1612       vam->json_tree.type = VAT_JSON_NONE;
1613     }
1614
1615   vam->retval = retval;
1616   vam->result_ready = 1;
1617 }
1618
1619 static void
1620   vl_api_bridge_domain_set_mac_age_reply_t_handler
1621   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1622 {
1623   vat_main_t *vam = &vat_main;
1624   i32 retval = ntohl (mp->retval);
1625   if (vam->async_mode)
1626     {
1627       vam->async_errors += (retval < 0);
1628     }
1629   else
1630     {
1631       vam->retval = retval;
1632       vam->result_ready = 1;
1633     }
1634 }
1635
1636 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1637   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1638 {
1639   vat_main_t *vam = &vat_main;
1640   vat_json_node_t node;
1641
1642   vat_json_init_object (&node);
1643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1644
1645   vat_json_print (vam->ofp, &node);
1646   vat_json_free (&node);
1647
1648   vam->retval = ntohl (mp->retval);
1649   vam->result_ready = 1;
1650 }
1651
1652 static void
1653 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1654 {
1655   vat_main_t *vam = &vat_main;
1656   i32 retval = ntohl (mp->retval);
1657   if (vam->async_mode)
1658     {
1659       vam->async_errors += (retval < 0);
1660     }
1661   else
1662     {
1663       vam->retval = retval;
1664       vam->result_ready = 1;
1665     }
1666 }
1667
1668 static void vl_api_l2_flags_reply_t_handler_json
1669   (vl_api_l2_flags_reply_t * mp)
1670 {
1671   vat_main_t *vam = &vat_main;
1672   vat_json_node_t node;
1673
1674   vat_json_init_object (&node);
1675   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1676   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1677                             ntohl (mp->resulting_feature_bitmap));
1678
1679   vat_json_print (vam->ofp, &node);
1680   vat_json_free (&node);
1681
1682   vam->retval = ntohl (mp->retval);
1683   vam->result_ready = 1;
1684 }
1685
1686 static void vl_api_bridge_flags_reply_t_handler
1687   (vl_api_bridge_flags_reply_t * mp)
1688 {
1689   vat_main_t *vam = &vat_main;
1690   i32 retval = ntohl (mp->retval);
1691   if (vam->async_mode)
1692     {
1693       vam->async_errors += (retval < 0);
1694     }
1695   else
1696     {
1697       vam->retval = retval;
1698       vam->result_ready = 1;
1699     }
1700 }
1701
1702 static void vl_api_bridge_flags_reply_t_handler_json
1703   (vl_api_bridge_flags_reply_t * mp)
1704 {
1705   vat_main_t *vam = &vat_main;
1706   vat_json_node_t node;
1707
1708   vat_json_init_object (&node);
1709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1710   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1711                             ntohl (mp->resulting_feature_bitmap));
1712
1713   vat_json_print (vam->ofp, &node);
1714   vat_json_free (&node);
1715
1716   vam->retval = ntohl (mp->retval);
1717   vam->result_ready = 1;
1718 }
1719
1720 static void
1721 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   i32 retval = ntohl (mp->retval);
1725   if (vam->async_mode)
1726     {
1727       vam->async_errors += (retval < 0);
1728     }
1729   else
1730     {
1731       vam->retval = retval;
1732       vam->sw_if_index = ntohl (mp->sw_if_index);
1733       vam->result_ready = 1;
1734     }
1735
1736 }
1737
1738 static void vl_api_tap_create_v2_reply_t_handler_json
1739   (vl_api_tap_create_v2_reply_t * mp)
1740 {
1741   vat_main_t *vam = &vat_main;
1742   vat_json_node_t node;
1743
1744   vat_json_init_object (&node);
1745   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1746   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753
1754 }
1755
1756 static void
1757 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   i32 retval = ntohl (mp->retval);
1761   if (vam->async_mode)
1762     {
1763       vam->async_errors += (retval < 0);
1764     }
1765   else
1766     {
1767       vam->retval = retval;
1768       vam->result_ready = 1;
1769     }
1770 }
1771
1772 static void vl_api_tap_delete_v2_reply_t_handler_json
1773   (vl_api_tap_delete_v2_reply_t * mp)
1774 {
1775   vat_main_t *vam = &vat_main;
1776   vat_json_node_t node;
1777
1778   vat_json_init_object (&node);
1779   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void
1789 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1790                                           mp)
1791 {
1792   vat_main_t *vam = &vat_main;
1793   i32 retval = ntohl (mp->retval);
1794   if (vam->async_mode)
1795     {
1796       vam->async_errors += (retval < 0);
1797     }
1798   else
1799     {
1800       vam->retval = retval;
1801       vam->sw_if_index = ntohl (mp->sw_if_index);
1802       vam->result_ready = 1;
1803     }
1804 }
1805
1806 static void vl_api_virtio_pci_create_reply_t_handler_json
1807   (vl_api_virtio_pci_create_reply_t * mp)
1808 {
1809   vat_main_t *vam = &vat_main;
1810   vat_json_node_t node;
1811
1812   vat_json_init_object (&node);
1813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1814   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1815
1816   vat_json_print (vam->ofp, &node);
1817   vat_json_free (&node);
1818
1819   vam->retval = ntohl (mp->retval);
1820   vam->result_ready = 1;
1821
1822 }
1823
1824 static void
1825   vl_api_virtio_pci_create_v2_reply_t_handler
1826   (vl_api_virtio_pci_create_v2_reply_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829   i32 retval = ntohl (mp->retval);
1830   if (vam->async_mode)
1831     {
1832       vam->async_errors += (retval < 0);
1833     }
1834   else
1835     {
1836       vam->retval = retval;
1837       vam->sw_if_index = ntohl (mp->sw_if_index);
1838       vam->result_ready = 1;
1839     }
1840 }
1841
1842 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1843   (vl_api_virtio_pci_create_v2_reply_t * mp)
1844 {
1845   vat_main_t *vam = &vat_main;
1846   vat_json_node_t node;
1847
1848   vat_json_init_object (&node);
1849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1851
1852   vat_json_print (vam->ofp, &node);
1853   vat_json_free (&node);
1854
1855   vam->retval = ntohl (mp->retval);
1856   vam->result_ready = 1;
1857 }
1858
1859 static void
1860 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1861                                           mp)
1862 {
1863   vat_main_t *vam = &vat_main;
1864   i32 retval = ntohl (mp->retval);
1865   if (vam->async_mode)
1866     {
1867       vam->async_errors += (retval < 0);
1868     }
1869   else
1870     {
1871       vam->retval = retval;
1872       vam->result_ready = 1;
1873     }
1874 }
1875
1876 static void vl_api_virtio_pci_delete_reply_t_handler_json
1877   (vl_api_virtio_pci_delete_reply_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880   vat_json_node_t node;
1881
1882   vat_json_init_object (&node);
1883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1884
1885   vat_json_print (vam->ofp, &node);
1886   vat_json_free (&node);
1887
1888   vam->retval = ntohl (mp->retval);
1889   vam->result_ready = 1;
1890 }
1891
1892 static void
1893 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1894 {
1895   vat_main_t *vam = &vat_main;
1896   i32 retval = ntohl (mp->retval);
1897
1898   if (vam->async_mode)
1899     {
1900       vam->async_errors += (retval < 0);
1901     }
1902   else
1903     {
1904       vam->retval = retval;
1905       vam->sw_if_index = ntohl (mp->sw_if_index);
1906       vam->result_ready = 1;
1907     }
1908 }
1909
1910 static void vl_api_bond_create_reply_t_handler_json
1911   (vl_api_bond_create_reply_t * mp)
1912 {
1913   vat_main_t *vam = &vat_main;
1914   vat_json_node_t node;
1915
1916   vat_json_init_object (&node);
1917   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1918   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1919
1920   vat_json_print (vam->ofp, &node);
1921   vat_json_free (&node);
1922
1923   vam->retval = ntohl (mp->retval);
1924   vam->result_ready = 1;
1925 }
1926
1927 static void
1928 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1929 {
1930   vat_main_t *vam = &vat_main;
1931   i32 retval = ntohl (mp->retval);
1932
1933   if (vam->async_mode)
1934     {
1935       vam->async_errors += (retval < 0);
1936     }
1937   else
1938     {
1939       vam->retval = retval;
1940       vam->sw_if_index = ntohl (mp->sw_if_index);
1941       vam->result_ready = 1;
1942     }
1943 }
1944
1945 static void vl_api_bond_create2_reply_t_handler_json
1946   (vl_api_bond_create2_reply_t * mp)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   vat_json_node_t node;
1950
1951   vat_json_init_object (&node);
1952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1953   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1954
1955   vat_json_print (vam->ofp, &node);
1956   vat_json_free (&node);
1957
1958   vam->retval = ntohl (mp->retval);
1959   vam->result_ready = 1;
1960 }
1961
1962 static void
1963 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   i32 retval = ntohl (mp->retval);
1967
1968   if (vam->async_mode)
1969     {
1970       vam->async_errors += (retval < 0);
1971     }
1972   else
1973     {
1974       vam->retval = retval;
1975       vam->result_ready = 1;
1976     }
1977 }
1978
1979 static void vl_api_bond_delete_reply_t_handler_json
1980   (vl_api_bond_delete_reply_t * mp)
1981 {
1982   vat_main_t *vam = &vat_main;
1983   vat_json_node_t node;
1984
1985   vat_json_init_object (&node);
1986   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1987
1988   vat_json_print (vam->ofp, &node);
1989   vat_json_free (&node);
1990
1991   vam->retval = ntohl (mp->retval);
1992   vam->result_ready = 1;
1993 }
1994
1995 static void
1996 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1997 {
1998   vat_main_t *vam = &vat_main;
1999   i32 retval = ntohl (mp->retval);
2000
2001   if (vam->async_mode)
2002     {
2003       vam->async_errors += (retval < 0);
2004     }
2005   else
2006     {
2007       vam->retval = retval;
2008       vam->result_ready = 1;
2009     }
2010 }
2011
2012 static void vl_api_bond_add_member_reply_t_handler_json
2013   (vl_api_bond_add_member_reply_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vat_json_node_t node;
2017
2018   vat_json_init_object (&node);
2019   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2020
2021   vat_json_print (vam->ofp, &node);
2022   vat_json_free (&node);
2023
2024   vam->retval = ntohl (mp->retval);
2025   vam->result_ready = 1;
2026 }
2027
2028 static void
2029 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2030                                            mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   i32 retval = ntohl (mp->retval);
2034
2035   if (vam->async_mode)
2036     {
2037       vam->async_errors += (retval < 0);
2038     }
2039   else
2040     {
2041       vam->retval = retval;
2042       vam->result_ready = 1;
2043     }
2044 }
2045
2046 static void vl_api_bond_detach_member_reply_t_handler_json
2047   (vl_api_bond_detach_member_reply_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   vat_json_node_t node;
2051
2052   vat_json_init_object (&node);
2053   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2054
2055   vat_json_print (vam->ofp, &node);
2056   vat_json_free (&node);
2057
2058   vam->retval = ntohl (mp->retval);
2059   vam->result_ready = 1;
2060 }
2061
2062 static int
2063 api_sw_interface_set_bond_weight (vat_main_t * vam)
2064 {
2065   unformat_input_t *i = vam->input;
2066   vl_api_sw_interface_set_bond_weight_t *mp;
2067   u32 sw_if_index = ~0;
2068   u32 weight = 0;
2069   u8 weight_enter = 0;
2070   int ret;
2071
2072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2073     {
2074       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2075         ;
2076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2077         ;
2078       else if (unformat (i, "weight %u", &weight))
2079         weight_enter = 1;
2080       else
2081         break;
2082     }
2083
2084   if (sw_if_index == ~0)
2085     {
2086       errmsg ("missing interface name or sw_if_index");
2087       return -99;
2088     }
2089   if (weight_enter == 0)
2090     {
2091       errmsg ("missing valid weight");
2092       return -99;
2093     }
2094
2095   /* Construct the API message */
2096   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2097   mp->sw_if_index = ntohl (sw_if_index);
2098   mp->weight = ntohl (weight);
2099
2100   S (mp);
2101   W (ret);
2102   return ret;
2103 }
2104
2105 static void vl_api_sw_bond_interface_details_t_handler
2106   (vl_api_sw_bond_interface_details_t * mp)
2107 {
2108   vat_main_t *vam = &vat_main;
2109
2110   print (vam->ofp,
2111          "%-16s %-12d %-12U %-13U %-14u %-14u",
2112          mp->interface_name, ntohl (mp->sw_if_index),
2113          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2114          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2115 }
2116
2117 static void vl_api_sw_bond_interface_details_t_handler_json
2118   (vl_api_sw_bond_interface_details_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t *node = NULL;
2122
2123   if (VAT_JSON_ARRAY != vam->json_tree.type)
2124     {
2125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2126       vat_json_init_array (&vam->json_tree);
2127     }
2128   node = vat_json_array_add (&vam->json_tree);
2129
2130   vat_json_init_object (node);
2131   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2132   vat_json_object_add_string_copy (node, "interface_name",
2133                                    mp->interface_name);
2134   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2135   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2136   vat_json_object_add_uint (node, "active_members",
2137                             ntohl (mp->active_members));
2138   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2139 }
2140
2141 static int
2142 api_sw_bond_interface_dump (vat_main_t * vam)
2143 {
2144   unformat_input_t *i = vam->input;
2145   vl_api_sw_bond_interface_dump_t *mp;
2146   vl_api_control_ping_t *mp_ping;
2147   int ret;
2148   u32 sw_if_index = ~0;
2149
2150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2151     {
2152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2153         ;
2154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2155         ;
2156       else
2157         break;
2158     }
2159
2160   print (vam->ofp,
2161          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2162          "interface name", "sw_if_index", "mode", "load balance",
2163          "active members", "members");
2164
2165   /* Get list of bond interfaces */
2166   M (SW_BOND_INTERFACE_DUMP, mp);
2167   mp->sw_if_index = ntohl (sw_if_index);
2168   S (mp);
2169
2170   /* Use a control ping for synchronization */
2171   MPING (CONTROL_PING, mp_ping);
2172   S (mp_ping);
2173
2174   W (ret);
2175   return ret;
2176 }
2177
2178 static void vl_api_sw_member_interface_details_t_handler
2179   (vl_api_sw_member_interface_details_t * mp)
2180 {
2181   vat_main_t *vam = &vat_main;
2182
2183   print (vam->ofp,
2184          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2185          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2186          ntohl (mp->weight), mp->is_local_numa);
2187 }
2188
2189 static void vl_api_sw_member_interface_details_t_handler_json
2190   (vl_api_sw_member_interface_details_t * mp)
2191 {
2192   vat_main_t *vam = &vat_main;
2193   vat_json_node_t *node = NULL;
2194
2195   if (VAT_JSON_ARRAY != vam->json_tree.type)
2196     {
2197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2198       vat_json_init_array (&vam->json_tree);
2199     }
2200   node = vat_json_array_add (&vam->json_tree);
2201
2202   vat_json_init_object (node);
2203   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2204   vat_json_object_add_string_copy (node, "interface_name",
2205                                    mp->interface_name);
2206   vat_json_object_add_uint (node, "passive", mp->is_passive);
2207   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2208   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2209   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2210 }
2211
2212 static int
2213 api_sw_member_interface_dump (vat_main_t * vam)
2214 {
2215   unformat_input_t *i = vam->input;
2216   vl_api_sw_member_interface_dump_t *mp;
2217   vl_api_control_ping_t *mp_ping;
2218   u32 sw_if_index = ~0;
2219   u8 sw_if_index_set = 0;
2220   int ret;
2221
2222   /* Parse args required to build the message */
2223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2224     {
2225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2226         sw_if_index_set = 1;
2227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2228         sw_if_index_set = 1;
2229       else
2230         break;
2231     }
2232
2233   if (sw_if_index_set == 0)
2234     {
2235       errmsg ("missing vpp interface name. ");
2236       return -99;
2237     }
2238
2239   print (vam->ofp,
2240          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2241          "member interface name", "sw_if_index", "passive", "long_timeout",
2242          "weight", "local numa");
2243
2244   /* Get list of bond interfaces */
2245   M (SW_MEMBER_INTERFACE_DUMP, mp);
2246   mp->sw_if_index = ntohl (sw_if_index);
2247   S (mp);
2248
2249   /* Use a control ping for synchronization */
2250   MPING (CONTROL_PING, mp_ping);
2251   S (mp_ping);
2252
2253   W (ret);
2254   return ret;
2255 }
2256
2257 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2258   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   i32 retval = ntohl (mp->retval);
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->sw_if_index = ntohl (mp->sw_if_index);
2270       vam->result_ready = 1;
2271     }
2272   vam->regenerate_interface_table = 1;
2273 }
2274
2275 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2276   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   vat_json_node_t node;
2280
2281   vat_json_init_object (&node);
2282   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2283   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2284                             ntohl (mp->sw_if_index));
2285
2286   vat_json_print (vam->ofp, &node);
2287   vat_json_free (&node);
2288
2289   vam->retval = ntohl (mp->retval);
2290   vam->result_ready = 1;
2291 }
2292
2293 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2294   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2295 {
2296   vat_main_t *vam = &vat_main;
2297   i32 retval = ntohl (mp->retval);
2298   if (vam->async_mode)
2299     {
2300       vam->async_errors += (retval < 0);
2301     }
2302   else
2303     {
2304       vam->retval = retval;
2305       vam->sw_if_index = ntohl (mp->sw_if_index);
2306       vam->result_ready = 1;
2307     }
2308   vam->regenerate_interface_table = 1;
2309 }
2310
2311 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2312   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vat_json_node_t node;
2316
2317   vat_json_init_object (&node);
2318   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2319   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2320
2321   vat_json_print (vam->ofp, &node);
2322   vat_json_free (&node);
2323
2324   vam->retval = ntohl (mp->retval);
2325   vam->result_ready = 1;
2326 }
2327
2328 static void vl_api_vxlan_offload_rx_reply_t_handler
2329   (vl_api_vxlan_offload_rx_reply_t * mp)
2330 {
2331   vat_main_t *vam = &vat_main;
2332   i32 retval = ntohl (mp->retval);
2333   if (vam->async_mode)
2334     {
2335       vam->async_errors += (retval < 0);
2336     }
2337   else
2338     {
2339       vam->retval = retval;
2340       vam->result_ready = 1;
2341     }
2342 }
2343
2344 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2345   (vl_api_vxlan_offload_rx_reply_t * mp)
2346 {
2347   vat_main_t *vam = &vat_main;
2348   vat_json_node_t node;
2349
2350   vat_json_init_object (&node);
2351   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2352
2353   vat_json_print (vam->ofp, &node);
2354   vat_json_free (&node);
2355
2356   vam->retval = ntohl (mp->retval);
2357   vam->result_ready = 1;
2358 }
2359
2360 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2361   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2362 {
2363   vat_main_t *vam = &vat_main;
2364   i32 retval = ntohl (mp->retval);
2365   if (vam->async_mode)
2366     {
2367       vam->async_errors += (retval < 0);
2368     }
2369   else
2370     {
2371       vam->retval = retval;
2372       vam->sw_if_index = ntohl (mp->sw_if_index);
2373       vam->result_ready = 1;
2374     }
2375   vam->regenerate_interface_table = 1;
2376 }
2377
2378 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2379   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2380 {
2381   vat_main_t *vam = &vat_main;
2382   vat_json_node_t node;
2383
2384   vat_json_init_object (&node);
2385   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2386   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2387
2388   vat_json_print (vam->ofp, &node);
2389   vat_json_free (&node);
2390
2391   vam->retval = ntohl (mp->retval);
2392   vam->result_ready = 1;
2393 }
2394
2395 static void vl_api_create_vhost_user_if_reply_t_handler
2396   (vl_api_create_vhost_user_if_reply_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   i32 retval = ntohl (mp->retval);
2400   if (vam->async_mode)
2401     {
2402       vam->async_errors += (retval < 0);
2403     }
2404   else
2405     {
2406       vam->retval = retval;
2407       vam->sw_if_index = ntohl (mp->sw_if_index);
2408       vam->result_ready = 1;
2409     }
2410   vam->regenerate_interface_table = 1;
2411 }
2412
2413 static void vl_api_create_vhost_user_if_reply_t_handler_json
2414   (vl_api_create_vhost_user_if_reply_t * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417   vat_json_node_t node;
2418
2419   vat_json_init_object (&node);
2420   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2421   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2422
2423   vat_json_print (vam->ofp, &node);
2424   vat_json_free (&node);
2425
2426   vam->retval = ntohl (mp->retval);
2427   vam->result_ready = 1;
2428 }
2429
2430 static void vl_api_create_vhost_user_if_v2_reply_t_handler
2431   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   i32 retval = ntohl (mp->retval);
2435   if (vam->async_mode)
2436     {
2437       vam->async_errors += (retval < 0);
2438     }
2439   else
2440     {
2441       vam->retval = retval;
2442       vam->sw_if_index = ntohl (mp->sw_if_index);
2443       vam->result_ready = 1;
2444     }
2445   vam->regenerate_interface_table = 1;
2446 }
2447
2448 static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2449   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   vat_json_node_t node;
2453
2454   vat_json_init_object (&node);
2455   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2456   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2457
2458   vat_json_print (vam->ofp, &node);
2459   vat_json_free (&node);
2460
2461   vam->retval = ntohl (mp->retval);
2462   vam->result_ready = 1;
2463 }
2464
2465 static void vl_api_ip_address_details_t_handler
2466   (vl_api_ip_address_details_t * mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   static ip_address_details_t empty_ip_address_details = { {0} };
2470   ip_address_details_t *address = NULL;
2471   ip_details_t *current_ip_details = NULL;
2472   ip_details_t *details = NULL;
2473
2474   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2475
2476   if (!details || vam->current_sw_if_index >= vec_len (details)
2477       || !details[vam->current_sw_if_index].present)
2478     {
2479       errmsg ("ip address details arrived but not stored");
2480       errmsg ("ip_dump should be called first");
2481       return;
2482     }
2483
2484   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2485
2486 #define addresses (current_ip_details->addr)
2487
2488   vec_validate_init_empty (addresses, vec_len (addresses),
2489                            empty_ip_address_details);
2490
2491   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2492
2493   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2494   address->prefix_length = mp->prefix.len;
2495 #undef addresses
2496 }
2497
2498 static void vl_api_ip_address_details_t_handler_json
2499   (vl_api_ip_address_details_t * mp)
2500 {
2501   vat_main_t *vam = &vat_main;
2502   vat_json_node_t *node = NULL;
2503
2504   if (VAT_JSON_ARRAY != vam->json_tree.type)
2505     {
2506       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2507       vat_json_init_array (&vam->json_tree);
2508     }
2509   node = vat_json_array_add (&vam->json_tree);
2510
2511   vat_json_init_object (node);
2512   vat_json_object_add_prefix (node, &mp->prefix);
2513 }
2514
2515 static void
2516 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   static ip_details_t empty_ip_details = { 0 };
2520   ip_details_t *ip = NULL;
2521   u32 sw_if_index = ~0;
2522
2523   sw_if_index = ntohl (mp->sw_if_index);
2524
2525   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2526                            sw_if_index, empty_ip_details);
2527
2528   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2529                          sw_if_index);
2530
2531   ip->present = 1;
2532 }
2533
2534 static void
2535 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2536 {
2537   vat_main_t *vam = &vat_main;
2538
2539   if (VAT_JSON_ARRAY != vam->json_tree.type)
2540     {
2541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2542       vat_json_init_array (&vam->json_tree);
2543     }
2544   vat_json_array_add_uint (&vam->json_tree,
2545                            clib_net_to_host_u32 (mp->sw_if_index));
2546 }
2547
2548 static void vl_api_get_first_msg_id_reply_t_handler
2549   (vl_api_get_first_msg_id_reply_t * mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   i32 retval = ntohl (mp->retval);
2553
2554   if (vam->async_mode)
2555     {
2556       vam->async_errors += (retval < 0);
2557     }
2558   else
2559     {
2560       vam->retval = retval;
2561       vam->result_ready = 1;
2562     }
2563   if (retval >= 0)
2564     {
2565       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2566     }
2567 }
2568
2569 static void vl_api_get_first_msg_id_reply_t_handler_json
2570   (vl_api_get_first_msg_id_reply_t * mp)
2571 {
2572   vat_main_t *vam = &vat_main;
2573   vat_json_node_t node;
2574
2575   vat_json_init_object (&node);
2576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2577   vat_json_object_add_uint (&node, "first_msg_id",
2578                             (uint) ntohs (mp->first_msg_id));
2579
2580   vat_json_print (vam->ofp, &node);
2581   vat_json_free (&node);
2582
2583   vam->retval = ntohl (mp->retval);
2584   vam->result_ready = 1;
2585 }
2586
2587 static void vl_api_get_node_graph_reply_t_handler
2588   (vl_api_get_node_graph_reply_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   i32 retval = ntohl (mp->retval);
2592   u8 *pvt_copy, *reply;
2593   void *oldheap;
2594   vlib_node_t *node;
2595   int i;
2596
2597   if (vam->async_mode)
2598     {
2599       vam->async_errors += (retval < 0);
2600     }
2601   else
2602     {
2603       vam->retval = retval;
2604       vam->result_ready = 1;
2605     }
2606
2607   /* "Should never happen..." */
2608   if (retval != 0)
2609     return;
2610
2611   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2612   pvt_copy = vec_dup (reply);
2613
2614   /* Toss the shared-memory original... */
2615   oldheap = vl_msg_push_heap ();
2616
2617   vec_free (reply);
2618
2619   vl_msg_pop_heap (oldheap);
2620
2621   if (vam->graph_nodes)
2622     {
2623       hash_free (vam->graph_node_index_by_name);
2624
2625       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2626         {
2627           node = vam->graph_nodes[0][i];
2628           vec_free (node->name);
2629           vec_free (node->next_nodes);
2630           vec_free (node);
2631         }
2632       vec_free (vam->graph_nodes[0]);
2633       vec_free (vam->graph_nodes);
2634     }
2635
2636   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2637   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2638   vec_free (pvt_copy);
2639
2640   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2641     {
2642       node = vam->graph_nodes[0][i];
2643       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2644     }
2645 }
2646
2647 static void vl_api_get_node_graph_reply_t_handler_json
2648   (vl_api_get_node_graph_reply_t * mp)
2649 {
2650   vat_main_t *vam = &vat_main;
2651   void *oldheap;
2652   vat_json_node_t node;
2653   u8 *reply;
2654
2655   /* $$$$ make this real? */
2656   vat_json_init_object (&node);
2657   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2658   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2659
2660   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2661
2662   /* Toss the shared-memory original... */
2663   oldheap = vl_msg_push_heap ();
2664
2665   vec_free (reply);
2666
2667   vl_msg_pop_heap (oldheap);
2668
2669   vat_json_print (vam->ofp, &node);
2670   vat_json_free (&node);
2671
2672   vam->retval = ntohl (mp->retval);
2673   vam->result_ready = 1;
2674 }
2675
2676 static u8 *
2677 format_policer_type (u8 * s, va_list * va)
2678 {
2679   u32 i = va_arg (*va, u32);
2680
2681   if (i == QOS_POLICER_TYPE_1R2C)
2682     s = format (s, "1r2c");
2683   else if (i == QOS_POLICER_TYPE_1R3C_RFC_2697)
2684     s = format (s, "1r3c");
2685   else if (i == QOS_POLICER_TYPE_2R3C_RFC_2698)
2686     s = format (s, "2r3c-2698");
2687   else if (i == QOS_POLICER_TYPE_2R3C_RFC_4115)
2688     s = format (s, "2r3c-4115");
2689   else if (i == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2690     s = format (s, "2r3c-mef5cf1");
2691   else
2692     s = format (s, "ILLEGAL");
2693   return s;
2694 }
2695
2696 static u8 *
2697 format_policer_rate_type (u8 * s, va_list * va)
2698 {
2699   u32 i = va_arg (*va, u32);
2700
2701   if (i == QOS_RATE_KBPS)
2702     s = format (s, "kbps");
2703   else if (i == QOS_RATE_PPS)
2704     s = format (s, "pps");
2705   else
2706     s = format (s, "ILLEGAL");
2707   return s;
2708 }
2709
2710 static u8 *
2711 format_policer_round_type (u8 * s, va_list * va)
2712 {
2713   u32 i = va_arg (*va, u32);
2714
2715   if (i == QOS_ROUND_TO_CLOSEST)
2716     s = format (s, "closest");
2717   else if (i == QOS_ROUND_TO_UP)
2718     s = format (s, "up");
2719   else if (i == QOS_ROUND_TO_DOWN)
2720     s = format (s, "down");
2721   else
2722     s = format (s, "ILLEGAL");
2723   return s;
2724 }
2725
2726 static u8 *
2727 format_policer_action_type (u8 * s, va_list * va)
2728 {
2729   u32 i = va_arg (*va, u32);
2730
2731   if (i == QOS_ACTION_DROP)
2732     s = format (s, "drop");
2733   else if (i == QOS_ACTION_TRANSMIT)
2734     s = format (s, "transmit");
2735   else if (i == QOS_ACTION_MARK_AND_TRANSMIT)
2736     s = format (s, "mark-and-transmit");
2737   else
2738     s = format (s, "ILLEGAL");
2739   return s;
2740 }
2741
2742 static u8 *
2743 format_dscp (u8 * s, va_list * va)
2744 {
2745   u32 i = va_arg (*va, u32);
2746   char *t = 0;
2747
2748   switch (i)
2749     {
2750 #define _(v, f)                                                               \
2751   case IP_DSCP_##f:                                                           \
2752     return (format (s, "%s", #f));
2753       foreach_ip_dscp
2754 #undef _
2755     }
2756   s = format (s, "%s", t);
2757   return (format (s, "ILLEGAL"));
2758 }
2759
2760 static void
2761 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2765
2766   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2767     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2768   else
2769     conform_dscp_str = format (0, "");
2770
2771   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2772     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2773   else
2774     exceed_dscp_str = format (0, "");
2775
2776   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2777     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2778   else
2779     violate_dscp_str = format (0, "");
2780
2781   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2782          "rate type %U, round type %U, %s rate, %s color-aware, "
2783          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2784          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2785          "conform action %U%s, exceed action %U%s, violate action %U%s",
2786          mp->name,
2787          format_policer_type, mp->type,
2788          ntohl (mp->cir),
2789          ntohl (mp->eir),
2790          clib_net_to_host_u64 (mp->cb),
2791          clib_net_to_host_u64 (mp->eb),
2792          format_policer_rate_type, mp->rate_type,
2793          format_policer_round_type, mp->round_type,
2794          mp->single_rate ? "single" : "dual",
2795          mp->color_aware ? "is" : "not",
2796          ntohl (mp->cir_tokens_per_period),
2797          ntohl (mp->pir_tokens_per_period),
2798          ntohl (mp->scale),
2799          ntohl (mp->current_limit),
2800          ntohl (mp->current_bucket),
2801          ntohl (mp->extended_limit),
2802          ntohl (mp->extended_bucket),
2803          clib_net_to_host_u64 (mp->last_update_time),
2804          format_policer_action_type, mp->conform_action.type,
2805          conform_dscp_str,
2806          format_policer_action_type, mp->exceed_action.type,
2807          exceed_dscp_str,
2808          format_policer_action_type, mp->violate_action.type,
2809          violate_dscp_str);
2810
2811   vec_free (conform_dscp_str);
2812   vec_free (exceed_dscp_str);
2813   vec_free (violate_dscp_str);
2814 }
2815
2816 static void vl_api_policer_details_t_handler_json
2817   (vl_api_policer_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node;
2821   u8 *rate_type_str, *round_type_str, *type_str;
2822   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2823
2824   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2825   round_type_str =
2826     format (0, "%U", format_policer_round_type, mp->round_type);
2827   type_str = format (0, "%U", format_policer_type, mp->type);
2828   conform_action_str = format (0, "%U", format_policer_action_type,
2829                                mp->conform_action.type);
2830   exceed_action_str = format (0, "%U", format_policer_action_type,
2831                               mp->exceed_action.type);
2832   violate_action_str = format (0, "%U", format_policer_action_type,
2833                                mp->violate_action.type);
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841
2842   vat_json_init_object (node);
2843   vat_json_object_add_string_copy (node, "name", mp->name);
2844   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2845   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2846   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2847   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
2848   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2849   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2850   vat_json_object_add_string_copy (node, "type", type_str);
2851   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2852   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2853   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2854   vat_json_object_add_uint (node, "cir_tokens_per_period",
2855                             ntohl (mp->cir_tokens_per_period));
2856   vat_json_object_add_uint (node, "eir_tokens_per_period",
2857                             ntohl (mp->pir_tokens_per_period));
2858   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2859   vat_json_object_add_uint (node, "current_bucket",
2860                             ntohl (mp->current_bucket));
2861   vat_json_object_add_uint (node, "extended_limit",
2862                             ntohl (mp->extended_limit));
2863   vat_json_object_add_uint (node, "extended_bucket",
2864                             ntohl (mp->extended_bucket));
2865   vat_json_object_add_uint (node, "last_update_time",
2866                             ntohl (mp->last_update_time));
2867   vat_json_object_add_string_copy (node, "conform_action",
2868                                    conform_action_str);
2869   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2870     {
2871       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2872       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2873       vec_free (dscp_str);
2874     }
2875   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2876   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2877     {
2878       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2879       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2880       vec_free (dscp_str);
2881     }
2882   vat_json_object_add_string_copy (node, "violate_action",
2883                                    violate_action_str);
2884   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2885     {
2886       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2887       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2888       vec_free (dscp_str);
2889     }
2890
2891   vec_free (rate_type_str);
2892   vec_free (round_type_str);
2893   vec_free (type_str);
2894   vec_free (conform_action_str);
2895   vec_free (exceed_action_str);
2896   vec_free (violate_action_str);
2897 }
2898
2899 static void
2900 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2901                                            mp)
2902 {
2903   vat_main_t *vam = &vat_main;
2904   int i, count = ntohl (mp->count);
2905
2906   if (count > 0)
2907     print (vam->ofp, "classify table ids (%d) : ", count);
2908   for (i = 0; i < count; i++)
2909     {
2910       print (vam->ofp, "%d", ntohl (mp->ids[i]));
2911       print (vam->ofp, (i < count - 1) ? "," : "");
2912     }
2913   vam->retval = ntohl (mp->retval);
2914   vam->result_ready = 1;
2915 }
2916
2917 static void
2918   vl_api_classify_table_ids_reply_t_handler_json
2919   (vl_api_classify_table_ids_reply_t * mp)
2920 {
2921   vat_main_t *vam = &vat_main;
2922   int i, count = ntohl (mp->count);
2923
2924   if (count > 0)
2925     {
2926       vat_json_node_t node;
2927
2928       vat_json_init_object (&node);
2929       for (i = 0; i < count; i++)
2930         {
2931           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2932         }
2933       vat_json_print (vam->ofp, &node);
2934       vat_json_free (&node);
2935     }
2936   vam->retval = ntohl (mp->retval);
2937   vam->result_ready = 1;
2938 }
2939
2940 static void
2941   vl_api_classify_table_by_interface_reply_t_handler
2942   (vl_api_classify_table_by_interface_reply_t * mp)
2943 {
2944   vat_main_t *vam = &vat_main;
2945   u32 table_id;
2946
2947   table_id = ntohl (mp->l2_table_id);
2948   if (table_id != ~0)
2949     print (vam->ofp, "l2 table id : %d", table_id);
2950   else
2951     print (vam->ofp, "l2 table id : No input ACL tables configured");
2952   table_id = ntohl (mp->ip4_table_id);
2953   if (table_id != ~0)
2954     print (vam->ofp, "ip4 table id : %d", table_id);
2955   else
2956     print (vam->ofp, "ip4 table id : No input ACL tables configured");
2957   table_id = ntohl (mp->ip6_table_id);
2958   if (table_id != ~0)
2959     print (vam->ofp, "ip6 table id : %d", table_id);
2960   else
2961     print (vam->ofp, "ip6 table id : No input ACL tables configured");
2962   vam->retval = ntohl (mp->retval);
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_classify_table_by_interface_reply_t_handler_json
2968   (vl_api_classify_table_by_interface_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   vat_json_node_t node;
2972
2973   vat_json_init_object (&node);
2974
2975   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2976   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2977   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2978
2979   vat_json_print (vam->ofp, &node);
2980   vat_json_free (&node);
2981
2982   vam->retval = ntohl (mp->retval);
2983   vam->result_ready = 1;
2984 }
2985
2986 static void vl_api_policer_add_del_reply_t_handler
2987   (vl_api_policer_add_del_reply_t * mp)
2988 {
2989   vat_main_t *vam = &vat_main;
2990   i32 retval = ntohl (mp->retval);
2991   if (vam->async_mode)
2992     {
2993       vam->async_errors += (retval < 0);
2994     }
2995   else
2996     {
2997       vam->retval = retval;
2998       vam->result_ready = 1;
2999       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3000         /*
3001          * Note: this is just barely thread-safe, depends on
3002          * the main thread spinning waiting for an answer...
3003          */
3004         errmsg ("policer index %d", ntohl (mp->policer_index));
3005     }
3006 }
3007
3008 static void vl_api_policer_add_del_reply_t_handler_json
3009   (vl_api_policer_add_del_reply_t * mp)
3010 {
3011   vat_main_t *vam = &vat_main;
3012   vat_json_node_t node;
3013
3014   vat_json_init_object (&node);
3015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3016   vat_json_object_add_uint (&node, "policer_index",
3017                             ntohl (mp->policer_index));
3018
3019   vat_json_print (vam->ofp, &node);
3020   vat_json_free (&node);
3021
3022   vam->retval = ntohl (mp->retval);
3023   vam->result_ready = 1;
3024 }
3025
3026 /* Format hex dump. */
3027 u8 *
3028 format_hex_bytes (u8 * s, va_list * va)
3029 {
3030   u8 *bytes = va_arg (*va, u8 *);
3031   int n_bytes = va_arg (*va, int);
3032   uword i;
3033
3034   /* Print short or long form depending on byte count. */
3035   uword short_form = n_bytes <= 32;
3036   u32 indent = format_get_indent (s);
3037
3038   if (n_bytes == 0)
3039     return s;
3040
3041   for (i = 0; i < n_bytes; i++)
3042     {
3043       if (!short_form && (i % 32) == 0)
3044         s = format (s, "%08x: ", i);
3045       s = format (s, "%02x", bytes[i]);
3046       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3047         s = format (s, "\n%U", format_white_space, indent);
3048     }
3049
3050   return s;
3051 }
3052
3053 static void
3054 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3055                                             * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058   i32 retval = ntohl (mp->retval);
3059   if (retval == 0)
3060     {
3061       print (vam->ofp, "classify table info :");
3062       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3063              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3064              ntohl (mp->miss_next_index));
3065       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3066              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3067              ntohl (mp->match_n_vectors));
3068       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3069              ntohl (mp->mask_length));
3070     }
3071   vam->retval = retval;
3072   vam->result_ready = 1;
3073 }
3074
3075 static void
3076   vl_api_classify_table_info_reply_t_handler_json
3077   (vl_api_classify_table_info_reply_t * mp)
3078 {
3079   vat_main_t *vam = &vat_main;
3080   vat_json_node_t node;
3081
3082   i32 retval = ntohl (mp->retval);
3083   if (retval == 0)
3084     {
3085       vat_json_init_object (&node);
3086
3087       vat_json_object_add_int (&node, "sessions",
3088                                ntohl (mp->active_sessions));
3089       vat_json_object_add_int (&node, "nexttbl",
3090                                ntohl (mp->next_table_index));
3091       vat_json_object_add_int (&node, "nextnode",
3092                                ntohl (mp->miss_next_index));
3093       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3094       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3095       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3096       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3097                       ntohl (mp->mask_length), 0);
3098       vat_json_object_add_string_copy (&node, "mask", s);
3099
3100       vat_json_print (vam->ofp, &node);
3101       vat_json_free (&node);
3102     }
3103   vam->retval = ntohl (mp->retval);
3104   vam->result_ready = 1;
3105 }
3106
3107 static void
3108 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3109                                            mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112
3113   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3114          ntohl (mp->hit_next_index), ntohl (mp->advance),
3115          ntohl (mp->opaque_index));
3116   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3117          ntohl (mp->match_length));
3118 }
3119
3120 static void
3121   vl_api_classify_session_details_t_handler_json
3122   (vl_api_classify_session_details_t * mp)
3123 {
3124   vat_main_t *vam = &vat_main;
3125   vat_json_node_t *node = NULL;
3126
3127   if (VAT_JSON_ARRAY != vam->json_tree.type)
3128     {
3129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3130       vat_json_init_array (&vam->json_tree);
3131     }
3132   node = vat_json_array_add (&vam->json_tree);
3133
3134   vat_json_init_object (node);
3135   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3136   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3137   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3138   u8 *s =
3139     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3140             0);
3141   vat_json_object_add_string_copy (node, "match", s);
3142 }
3143
3144 static void vl_api_pg_create_interface_reply_t_handler
3145   (vl_api_pg_create_interface_reply_t * mp)
3146 {
3147   vat_main_t *vam = &vat_main;
3148
3149   vam->retval = ntohl (mp->retval);
3150   vam->result_ready = 1;
3151 }
3152
3153 static void vl_api_pg_create_interface_reply_t_handler_json
3154   (vl_api_pg_create_interface_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   vat_json_node_t node;
3158
3159   i32 retval = ntohl (mp->retval);
3160   if (retval == 0)
3161     {
3162       vat_json_init_object (&node);
3163
3164       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3165
3166       vat_json_print (vam->ofp, &node);
3167       vat_json_free (&node);
3168     }
3169   vam->retval = ntohl (mp->retval);
3170   vam->result_ready = 1;
3171 }
3172
3173 static void vl_api_policer_classify_details_t_handler
3174   (vl_api_policer_classify_details_t * mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177
3178   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3179          ntohl (mp->table_index));
3180 }
3181
3182 static void vl_api_policer_classify_details_t_handler_json
3183   (vl_api_policer_classify_details_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   vat_json_node_t *node;
3187
3188   if (VAT_JSON_ARRAY != vam->json_tree.type)
3189     {
3190       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3191       vat_json_init_array (&vam->json_tree);
3192     }
3193   node = vat_json_array_add (&vam->json_tree);
3194
3195   vat_json_init_object (node);
3196   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3197   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3198 }
3199
3200 static void vl_api_flow_classify_details_t_handler
3201   (vl_api_flow_classify_details_t * mp)
3202 {
3203   vat_main_t *vam = &vat_main;
3204
3205   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3206          ntohl (mp->table_index));
3207 }
3208
3209 static void vl_api_flow_classify_details_t_handler_json
3210   (vl_api_flow_classify_details_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t *node;
3214
3215   if (VAT_JSON_ARRAY != vam->json_tree.type)
3216     {
3217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3218       vat_json_init_array (&vam->json_tree);
3219     }
3220   node = vat_json_array_add (&vam->json_tree);
3221
3222   vat_json_init_object (node);
3223   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3224   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3225 }
3226
3227 /*
3228  * Generate boilerplate reply handlers, which
3229  * dig the return value out of the xxx_reply_t API message,
3230  * stick it into vam->retval, and set vam->result_ready
3231  *
3232  * Could also do this by pointing N message decode slots at
3233  * a single function, but that could break in subtle ways.
3234  */
3235
3236 #define foreach_standard_reply_retval_handler           \
3237 _(sw_interface_set_flags_reply)                         \
3238 _(sw_interface_add_del_address_reply)                   \
3239 _(sw_interface_set_rx_mode_reply)                       \
3240 _(sw_interface_set_rx_placement_reply)                  \
3241 _(sw_interface_set_table_reply)                         \
3242 _(sw_interface_set_mpls_enable_reply)                   \
3243 _(sw_interface_set_vpath_reply)                         \
3244 _(sw_interface_set_vxlan_bypass_reply)                  \
3245 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
3246 _(sw_interface_set_l2_bridge_reply)                     \
3247 _(sw_interface_set_bond_weight_reply)                   \
3248 _(bridge_domain_add_del_reply)                          \
3249 _(sw_interface_set_l2_xconnect_reply)                   \
3250 _(l2fib_add_del_reply)                                  \
3251 _(l2fib_flush_int_reply)                                \
3252 _(l2fib_flush_bd_reply)                                 \
3253 _(ip_route_add_del_reply)                               \
3254 _(ip_table_add_del_reply)                               \
3255 _(ip_table_replace_begin_reply)                         \
3256 _(ip_table_flush_reply)                                 \
3257 _(ip_table_replace_end_reply)                           \
3258 _(ip_mroute_add_del_reply)                              \
3259 _(mpls_route_add_del_reply)                             \
3260 _(mpls_table_add_del_reply)                             \
3261 _(mpls_ip_bind_unbind_reply)                            \
3262 _(sw_interface_set_unnumbered_reply)                    \
3263 _(set_ip_flow_hash_reply)                               \
3264 _(sw_interface_ip6_enable_disable_reply)                \
3265 _(l2_patch_add_del_reply)                               \
3266 _(sr_mpls_policy_add_reply)                             \
3267 _(sr_mpls_policy_mod_reply)                             \
3268 _(sr_mpls_policy_del_reply)                             \
3269 _(sr_policy_add_reply)                                  \
3270 _(sr_policy_mod_reply)                                  \
3271 _(sr_policy_del_reply)                                  \
3272 _(sr_localsid_add_del_reply)                            \
3273 _(sr_steering_add_del_reply)                            \
3274 _(classify_add_del_session_reply)                       \
3275 _(classify_set_interface_ip_table_reply)                \
3276 _(classify_set_interface_l2_tables_reply)               \
3277 _(l2_fib_clear_table_reply)                             \
3278 _(l2_interface_efp_filter_reply)                        \
3279 _(l2_interface_vlan_tag_rewrite_reply)                  \
3280 _(modify_vhost_user_if_reply)                           \
3281 _(modify_vhost_user_if_v2_reply)                        \
3282 _(delete_vhost_user_if_reply)                           \
3283 _(want_l2_macs_events_reply)                            \
3284 _(input_acl_set_interface_reply)                        \
3285 _(ipsec_spd_add_del_reply)                              \
3286 _(ipsec_interface_add_del_spd_reply)                    \
3287 _(ipsec_spd_entry_add_del_reply)                        \
3288 _(ipsec_sad_entry_add_del_reply)                        \
3289 _(delete_loopback_reply)                                \
3290 _(bd_ip_mac_add_del_reply)                              \
3291 _(bd_ip_mac_flush_reply)                                \
3292 _(want_interface_events_reply)                          \
3293 _(sw_interface_clear_stats_reply)                       \
3294 _(ioam_enable_reply)                                    \
3295 _(ioam_disable_reply)                                   \
3296 _(af_packet_delete_reply)                               \
3297 _(policer_classify_set_interface_reply)                 \
3298 _(set_ipfix_exporter_reply)                             \
3299 _(set_ipfix_classify_stream_reply)                      \
3300 _(ipfix_classify_table_add_del_reply)                   \
3301 _(flow_classify_set_interface_reply)                    \
3302 _(sw_interface_span_enable_disable_reply)               \
3303 _(pg_capture_reply)                                     \
3304 _(pg_enable_disable_reply)                              \
3305 _(pg_interface_enable_disable_coalesce_reply)           \
3306 _(ip_source_and_port_range_check_add_del_reply)         \
3307 _(ip_source_and_port_range_check_interface_add_del_reply)\
3308 _(delete_subif_reply)                                   \
3309 _(l2_interface_pbb_tag_rewrite_reply)                   \
3310 _(set_punt_reply)                                       \
3311 _(feature_enable_disable_reply)                         \
3312 _(feature_gso_enable_disable_reply)                     \
3313 _(sw_interface_tag_add_del_reply)                       \
3314 _(sw_interface_add_del_mac_address_reply)               \
3315 _(hw_interface_set_mtu_reply)                           \
3316 _(p2p_ethernet_add_reply)                               \
3317 _(p2p_ethernet_del_reply)                               \
3318 _(tcp_configure_src_addresses_reply)                    \
3319 _(session_rule_add_del_reply)                           \
3320 _(ip_container_proxy_add_del_reply)                     \
3321 _(output_acl_set_interface_reply)                       \
3322 _(qos_record_enable_disable_reply)                      \
3323 _(flow_add_reply)
3324
3325 #define _(n)                                    \
3326     static void vl_api_##n##_t_handler          \
3327     (vl_api_##n##_t * mp)                       \
3328     {                                           \
3329         vat_main_t * vam = &vat_main;           \
3330         i32 retval = ntohl(mp->retval);         \
3331         if (vam->async_mode) {                  \
3332             vam->async_errors += (retval < 0);  \
3333         } else {                                \
3334             vam->retval = retval;               \
3335             vam->result_ready = 1;              \
3336         }                                       \
3337     }
3338 foreach_standard_reply_retval_handler;
3339 #undef _
3340
3341 #define _(n)                                    \
3342     static void vl_api_##n##_t_handler_json     \
3343     (vl_api_##n##_t * mp)                       \
3344     {                                           \
3345         vat_main_t * vam = &vat_main;           \
3346         vat_json_node_t node;                   \
3347         vat_json_init_object(&node);            \
3348         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3349         vat_json_print(vam->ofp, &node);        \
3350         vam->retval = ntohl(mp->retval);        \
3351         vam->result_ready = 1;                  \
3352     }
3353 foreach_standard_reply_retval_handler;
3354 #undef _
3355
3356 /*
3357  * Table of message reply handlers, must include boilerplate handlers
3358  * we just generated
3359  */
3360
3361 #define foreach_vpe_api_reply_msg                                       \
3362 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3363 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
3364 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3365 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3366 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3367 _(CLI_REPLY, cli_reply)                                                 \
3368 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3369 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3370   sw_interface_add_del_address_reply)                                   \
3371 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
3372 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
3373 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
3374 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3375 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3376 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3377 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3378 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
3379 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3380   sw_interface_set_l2_xconnect_reply)                                   \
3381 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3382   sw_interface_set_l2_bridge_reply)                                     \
3383 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3384 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3385 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
3386 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3387 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
3388 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
3389 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3390 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3391 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
3392 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
3393 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
3394 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
3395 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
3396 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
3397 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
3398 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
3399 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
3400 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
3401 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
3402 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
3403 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
3404 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
3405 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
3406 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
3407 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
3408 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
3409 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
3410 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
3411 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3412 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
3413 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3414 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3415 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3416 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3417   sw_interface_set_unnumbered_reply)                                    \
3418 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3419 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3420 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3421 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3422   sw_interface_ip6_enable_disable_reply)                                \
3423 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3424 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
3425 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
3426 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
3427 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
3428 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
3429 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
3430 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
3431 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
3432 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3433 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3434 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3435 classify_set_interface_ip_table_reply)                                  \
3436 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3437   classify_set_interface_l2_tables_reply)                               \
3438 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3439 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3440 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3441 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
3442 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3443 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3444 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3445 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3446 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3447 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3448 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3449 _(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply)         \
3450 _(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply)         \
3451 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3452 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3453 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
3454 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
3455 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
3456 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3457 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3458 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
3459 _(L2_MACS_EVENT, l2_macs_event)                                         \
3460 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3461 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3462 _(IP_DETAILS, ip_details)                                               \
3463 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3464 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3465 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
3466 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
3467 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
3468 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3469 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3470 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
3471 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
3472 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3473 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3474 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3475 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3476 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3477 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3478 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3479 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3480 _(AF_PACKET_DETAILS, af_packet_details)                                 \
3481 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3482 _(POLICER_DETAILS, policer_details)                                     \
3483 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3484 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3485 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3486 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
3487 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
3488 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3489 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3490 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3491 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3492 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3493 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3494 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3495 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3496 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3497 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3498 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3499 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3500 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3501 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3502 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3503 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3504 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3505 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3506 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
3507 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3508  ip_source_and_port_range_check_add_del_reply)                          \
3509 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3510  ip_source_and_port_range_check_interface_add_del_reply)                \
3511 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3512 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3513 _(SET_PUNT_REPLY, set_punt_reply)                                       \
3514 _(IP_TABLE_DETAILS, ip_table_details)                                   \
3515 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
3516 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3517 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
3518 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3519 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
3520 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3521 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
3522 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
3523 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
3524 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
3525 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
3526 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
3527 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
3528 _(SESSION_RULES_DETAILS, session_rules_details)                         \
3529 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
3530 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
3531 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
3532 _(FLOW_ADD_REPLY, flow_add_reply)   \
3533
3534 #define foreach_standalone_reply_msg                                    \
3535 _(SW_INTERFACE_EVENT, sw_interface_event)
3536
3537 typedef struct
3538 {
3539   u8 *name;
3540   u32 value;
3541 } name_sort_t;
3542
3543 #define STR_VTR_OP_CASE(op)     \
3544     case L2_VTR_ ## op:         \
3545         return "" # op;
3546
3547 static const char *
3548 str_vtr_op (u32 vtr_op)
3549 {
3550   switch (vtr_op)
3551     {
3552       STR_VTR_OP_CASE (DISABLED);
3553       STR_VTR_OP_CASE (PUSH_1);
3554       STR_VTR_OP_CASE (PUSH_2);
3555       STR_VTR_OP_CASE (POP_1);
3556       STR_VTR_OP_CASE (POP_2);
3557       STR_VTR_OP_CASE (TRANSLATE_1_1);
3558       STR_VTR_OP_CASE (TRANSLATE_1_2);
3559       STR_VTR_OP_CASE (TRANSLATE_2_1);
3560       STR_VTR_OP_CASE (TRANSLATE_2_2);
3561     }
3562
3563   return "UNKNOWN";
3564 }
3565
3566 static int
3567 dump_sub_interface_table (vat_main_t * vam)
3568 {
3569   const sw_interface_subif_t *sub = NULL;
3570
3571   if (vam->json_output)
3572     {
3573       clib_warning
3574         ("JSON output supported only for VPE API calls and dump_stats_table");
3575       return -99;
3576     }
3577
3578   print (vam->ofp,
3579          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3580          "Interface", "sw_if_index",
3581          "sub id", "dot1ad", "tags", "outer id",
3582          "inner id", "exact", "default", "outer any", "inner any");
3583
3584   vec_foreach (sub, vam->sw_if_subif_table)
3585   {
3586     print (vam->ofp,
3587            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3588            sub->interface_name,
3589            sub->sw_if_index,
3590            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3591            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3592            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3593            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3594     if (sub->vtr_op != L2_VTR_DISABLED)
3595       {
3596         print (vam->ofp,
3597                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3598                "tag1: %d tag2: %d ]",
3599                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3600                sub->vtr_tag1, sub->vtr_tag2);
3601       }
3602   }
3603
3604   return 0;
3605 }
3606
3607 static int
3608 name_sort_cmp (void *a1, void *a2)
3609 {
3610   name_sort_t *n1 = a1;
3611   name_sort_t *n2 = a2;
3612
3613   return strcmp ((char *) n1->name, (char *) n2->name);
3614 }
3615
3616 static int
3617 dump_interface_table (vat_main_t * vam)
3618 {
3619   hash_pair_t *p;
3620   name_sort_t *nses = 0, *ns;
3621
3622   if (vam->json_output)
3623     {
3624       clib_warning
3625         ("JSON output supported only for VPE API calls and dump_stats_table");
3626       return -99;
3627     }
3628
3629   /* *INDENT-OFF* */
3630   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3631   ({
3632     vec_add2 (nses, ns, 1);
3633     ns->name = (u8 *)(p->key);
3634     ns->value = (u32) p->value[0];
3635   }));
3636   /* *INDENT-ON* */
3637
3638   vec_sort_with_function (nses, name_sort_cmp);
3639
3640   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3641   vec_foreach (ns, nses)
3642   {
3643     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3644   }
3645   vec_free (nses);
3646   return 0;
3647 }
3648
3649 static int
3650 dump_ip_table (vat_main_t * vam, int is_ipv6)
3651 {
3652   const ip_details_t *det = NULL;
3653   const ip_address_details_t *address = NULL;
3654   u32 i = ~0;
3655
3656   print (vam->ofp, "%-12s", "sw_if_index");
3657
3658   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3659   {
3660     i++;
3661     if (!det->present)
3662       {
3663         continue;
3664       }
3665     print (vam->ofp, "%-12d", i);
3666     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
3667     if (!det->addr)
3668       {
3669         continue;
3670       }
3671     vec_foreach (address, det->addr)
3672     {
3673       print (vam->ofp,
3674              "            %-30U%-13d",
3675              is_ipv6 ? format_ip6_address : format_ip4_address,
3676              address->ip, address->prefix_length);
3677     }
3678   }
3679
3680   return 0;
3681 }
3682
3683 static int
3684 dump_ipv4_table (vat_main_t * vam)
3685 {
3686   if (vam->json_output)
3687     {
3688       clib_warning
3689         ("JSON output supported only for VPE API calls and dump_stats_table");
3690       return -99;
3691     }
3692
3693   return dump_ip_table (vam, 0);
3694 }
3695
3696 static int
3697 dump_ipv6_table (vat_main_t * vam)
3698 {
3699   if (vam->json_output)
3700     {
3701       clib_warning
3702         ("JSON output supported only for VPE API calls and dump_stats_table");
3703       return -99;
3704     }
3705
3706   return dump_ip_table (vam, 1);
3707 }
3708
3709 /*
3710  * Pass CLI buffers directly in the CLI_INBAND API message,
3711  * instead of an additional shared memory area.
3712  */
3713 static int
3714 exec_inband (vat_main_t * vam)
3715 {
3716   vl_api_cli_inband_t *mp;
3717   unformat_input_t *i = vam->input;
3718   int ret;
3719
3720   if (vec_len (i->buffer) == 0)
3721     return -1;
3722
3723   if (vam->exec_mode == 0 && unformat (i, "mode"))
3724     {
3725       vam->exec_mode = 1;
3726       return 0;
3727     }
3728   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3729     {
3730       vam->exec_mode = 0;
3731       return 0;
3732     }
3733
3734   /*
3735    * In order for the CLI command to work, it
3736    * must be a vector ending in \n, not a C-string ending
3737    * in \n\0.
3738    */
3739   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3740   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
3741
3742   S (mp);
3743   W (ret);
3744   /* json responses may or may not include a useful reply... */
3745   if (vec_len (vam->cmd_reply))
3746     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
3747   return ret;
3748 }
3749
3750 int
3751 exec (vat_main_t * vam)
3752 {
3753   return exec_inband (vam);
3754 }
3755
3756 static int
3757 api_create_loopback (vat_main_t * vam)
3758 {
3759   unformat_input_t *i = vam->input;
3760   vl_api_create_loopback_t *mp;
3761   vl_api_create_loopback_instance_t *mp_lbi;
3762   u8 mac_address[6];
3763   u8 mac_set = 0;
3764   u8 is_specified = 0;
3765   u32 user_instance = 0;
3766   int ret;
3767
3768   clib_memset (mac_address, 0, sizeof (mac_address));
3769
3770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3771     {
3772       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3773         mac_set = 1;
3774       if (unformat (i, "instance %d", &user_instance))
3775         is_specified = 1;
3776       else
3777         break;
3778     }
3779
3780   if (is_specified)
3781     {
3782       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3783       mp_lbi->is_specified = is_specified;
3784       if (is_specified)
3785         mp_lbi->user_instance = htonl (user_instance);
3786       if (mac_set)
3787         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3788       S (mp_lbi);
3789     }
3790   else
3791     {
3792       /* Construct the API message */
3793       M (CREATE_LOOPBACK, mp);
3794       if (mac_set)
3795         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3796       S (mp);
3797     }
3798
3799   W (ret);
3800   return ret;
3801 }
3802
3803 static int
3804 api_delete_loopback (vat_main_t * vam)
3805 {
3806   unformat_input_t *i = vam->input;
3807   vl_api_delete_loopback_t *mp;
3808   u32 sw_if_index = ~0;
3809   int ret;
3810
3811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3812     {
3813       if (unformat (i, "sw_if_index %d", &sw_if_index))
3814         ;
3815       else
3816         break;
3817     }
3818
3819   if (sw_if_index == ~0)
3820     {
3821       errmsg ("missing sw_if_index");
3822       return -99;
3823     }
3824
3825   /* Construct the API message */
3826   M (DELETE_LOOPBACK, mp);
3827   mp->sw_if_index = ntohl (sw_if_index);
3828
3829   S (mp);
3830   W (ret);
3831   return ret;
3832 }
3833
3834 static int
3835 api_want_interface_events (vat_main_t * vam)
3836 {
3837   unformat_input_t *i = vam->input;
3838   vl_api_want_interface_events_t *mp;
3839   int enable = -1;
3840   int ret;
3841
3842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3843     {
3844       if (unformat (i, "enable"))
3845         enable = 1;
3846       else if (unformat (i, "disable"))
3847         enable = 0;
3848       else
3849         break;
3850     }
3851
3852   if (enable == -1)
3853     {
3854       errmsg ("missing enable|disable");
3855       return -99;
3856     }
3857
3858   M (WANT_INTERFACE_EVENTS, mp);
3859   mp->enable_disable = enable;
3860
3861   vam->interface_event_display = enable;
3862
3863   S (mp);
3864   W (ret);
3865   return ret;
3866 }
3867
3868
3869 /* Note: non-static, called once to set up the initial intfc table */
3870 int
3871 api_sw_interface_dump (vat_main_t * vam)
3872 {
3873   vl_api_sw_interface_dump_t *mp;
3874   vl_api_control_ping_t *mp_ping;
3875   hash_pair_t *p;
3876   name_sort_t *nses = 0, *ns;
3877   sw_interface_subif_t *sub = NULL;
3878   int ret;
3879
3880   /* Toss the old name table */
3881   /* *INDENT-OFF* */
3882   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3883   ({
3884     vec_add2 (nses, ns, 1);
3885     ns->name = (u8 *)(p->key);
3886     ns->value = (u32) p->value[0];
3887   }));
3888   /* *INDENT-ON* */
3889
3890   hash_free (vam->sw_if_index_by_interface_name);
3891
3892   vec_foreach (ns, nses) vec_free (ns->name);
3893
3894   vec_free (nses);
3895
3896   vec_foreach (sub, vam->sw_if_subif_table)
3897   {
3898     vec_free (sub->interface_name);
3899   }
3900   vec_free (vam->sw_if_subif_table);
3901
3902   /* recreate the interface name hash table */
3903   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3904
3905   /*
3906    * Ask for all interface names. Otherwise, the epic catalog of
3907    * name filters becomes ridiculously long, and vat ends up needing
3908    * to be taught about new interface types.
3909    */
3910   M (SW_INTERFACE_DUMP, mp);
3911   S (mp);
3912
3913   /* Use a control ping for synchronization */
3914   MPING (CONTROL_PING, mp_ping);
3915   S (mp_ping);
3916
3917   W (ret);
3918   return ret;
3919 }
3920
3921 static int
3922 api_sw_interface_set_flags (vat_main_t * vam)
3923 {
3924   unformat_input_t *i = vam->input;
3925   vl_api_sw_interface_set_flags_t *mp;
3926   u32 sw_if_index;
3927   u8 sw_if_index_set = 0;
3928   u8 admin_up = 0;
3929   int ret;
3930
3931   /* Parse args required to build the message */
3932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3933     {
3934       if (unformat (i, "admin-up"))
3935         admin_up = 1;
3936       else if (unformat (i, "admin-down"))
3937         admin_up = 0;
3938       else
3939         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3940         sw_if_index_set = 1;
3941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3942         sw_if_index_set = 1;
3943       else
3944         break;
3945     }
3946
3947   if (sw_if_index_set == 0)
3948     {
3949       errmsg ("missing interface name or sw_if_index");
3950       return -99;
3951     }
3952
3953   /* Construct the API message */
3954   M (SW_INTERFACE_SET_FLAGS, mp);
3955   mp->sw_if_index = ntohl (sw_if_index);
3956   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
3957
3958   /* send it... */
3959   S (mp);
3960
3961   /* Wait for a reply, return the good/bad news... */
3962   W (ret);
3963   return ret;
3964 }
3965
3966 static int
3967 api_sw_interface_set_rx_mode (vat_main_t * vam)
3968 {
3969   unformat_input_t *i = vam->input;
3970   vl_api_sw_interface_set_rx_mode_t *mp;
3971   u32 sw_if_index;
3972   u8 sw_if_index_set = 0;
3973   int ret;
3974   u8 queue_id_valid = 0;
3975   u32 queue_id;
3976   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
3977
3978   /* Parse args required to build the message */
3979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3980     {
3981       if (unformat (i, "queue %d", &queue_id))
3982         queue_id_valid = 1;
3983       else if (unformat (i, "polling"))
3984         mode = VNET_HW_IF_RX_MODE_POLLING;
3985       else if (unformat (i, "interrupt"))
3986         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
3987       else if (unformat (i, "adaptive"))
3988         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
3989       else
3990         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3991         sw_if_index_set = 1;
3992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3993         sw_if_index_set = 1;
3994       else
3995         break;
3996     }
3997
3998   if (sw_if_index_set == 0)
3999     {
4000       errmsg ("missing interface name or sw_if_index");
4001       return -99;
4002     }
4003   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
4004     {
4005       errmsg ("missing rx-mode");
4006       return -99;
4007     }
4008
4009   /* Construct the API message */
4010   M (SW_INTERFACE_SET_RX_MODE, mp);
4011   mp->sw_if_index = ntohl (sw_if_index);
4012   mp->mode = (vl_api_rx_mode_t) mode;
4013   mp->queue_id_valid = queue_id_valid;
4014   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4015
4016   /* send it... */
4017   S (mp);
4018
4019   /* Wait for a reply, return the good/bad news... */
4020   W (ret);
4021   return ret;
4022 }
4023
4024 static int
4025 api_sw_interface_set_rx_placement (vat_main_t * vam)
4026 {
4027   unformat_input_t *i = vam->input;
4028   vl_api_sw_interface_set_rx_placement_t *mp;
4029   u32 sw_if_index;
4030   u8 sw_if_index_set = 0;
4031   int ret;
4032   u8 is_main = 0;
4033   u32 queue_id, thread_index;
4034
4035   /* Parse args required to build the message */
4036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4037     {
4038       if (unformat (i, "queue %d", &queue_id))
4039         ;
4040       else if (unformat (i, "main"))
4041         is_main = 1;
4042       else if (unformat (i, "worker %d", &thread_index))
4043         ;
4044       else
4045         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4046         sw_if_index_set = 1;
4047       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4048         sw_if_index_set = 1;
4049       else
4050         break;
4051     }
4052
4053   if (sw_if_index_set == 0)
4054     {
4055       errmsg ("missing interface name or sw_if_index");
4056       return -99;
4057     }
4058
4059   if (is_main)
4060     thread_index = 0;
4061   /* Construct the API message */
4062   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4063   mp->sw_if_index = ntohl (sw_if_index);
4064   mp->worker_id = ntohl (thread_index);
4065   mp->queue_id = ntohl (queue_id);
4066   mp->is_main = is_main;
4067
4068   /* send it... */
4069   S (mp);
4070   /* Wait for a reply, return the good/bad news... */
4071   W (ret);
4072   return ret;
4073 }
4074
4075 static void vl_api_sw_interface_rx_placement_details_t_handler
4076   (vl_api_sw_interface_rx_placement_details_t * mp)
4077 {
4078   vat_main_t *vam = &vat_main;
4079   u32 worker_id = ntohl (mp->worker_id);
4080
4081   print (vam->ofp,
4082          "\n%-11d %-11s %-6d %-5d %-9s",
4083          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4084          worker_id, ntohl (mp->queue_id),
4085          (mp->mode ==
4086           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4087 }
4088
4089 static void vl_api_sw_interface_rx_placement_details_t_handler_json
4090   (vl_api_sw_interface_rx_placement_details_t * mp)
4091 {
4092   vat_main_t *vam = &vat_main;
4093   vat_json_node_t *node = NULL;
4094
4095   if (VAT_JSON_ARRAY != vam->json_tree.type)
4096     {
4097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4098       vat_json_init_array (&vam->json_tree);
4099     }
4100   node = vat_json_array_add (&vam->json_tree);
4101
4102   vat_json_init_object (node);
4103   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4104   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4105   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4106   vat_json_object_add_uint (node, "mode", mp->mode);
4107 }
4108
4109 static int
4110 api_sw_interface_rx_placement_dump (vat_main_t * vam)
4111 {
4112   unformat_input_t *i = vam->input;
4113   vl_api_sw_interface_rx_placement_dump_t *mp;
4114   vl_api_control_ping_t *mp_ping;
4115   int ret;
4116   u32 sw_if_index;
4117   u8 sw_if_index_set = 0;
4118
4119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4120     {
4121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4122         sw_if_index_set++;
4123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4124         sw_if_index_set++;
4125       else
4126         break;
4127     }
4128
4129   print (vam->ofp,
4130          "\n%-11s %-11s %-6s %-5s %-4s",
4131          "sw_if_index", "main/worker", "thread", "queue", "mode");
4132
4133   /* Dump Interface rx placement */
4134   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4135
4136   if (sw_if_index_set)
4137     mp->sw_if_index = htonl (sw_if_index);
4138   else
4139     mp->sw_if_index = ~0;
4140
4141   S (mp);
4142
4143   /* Use a control ping for synchronization */
4144   MPING (CONTROL_PING, mp_ping);
4145   S (mp_ping);
4146
4147   W (ret);
4148   return ret;
4149 }
4150
4151 static int
4152 api_sw_interface_clear_stats (vat_main_t * vam)
4153 {
4154   unformat_input_t *i = vam->input;
4155   vl_api_sw_interface_clear_stats_t *mp;
4156   u32 sw_if_index;
4157   u8 sw_if_index_set = 0;
4158   int ret;
4159
4160   /* Parse args required to build the message */
4161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4162     {
4163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4164         sw_if_index_set = 1;
4165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4166         sw_if_index_set = 1;
4167       else
4168         break;
4169     }
4170
4171   /* Construct the API message */
4172   M (SW_INTERFACE_CLEAR_STATS, mp);
4173
4174   if (sw_if_index_set == 1)
4175     mp->sw_if_index = ntohl (sw_if_index);
4176   else
4177     mp->sw_if_index = ~0;
4178
4179   /* send it... */
4180   S (mp);
4181
4182   /* Wait for a reply, return the good/bad news... */
4183   W (ret);
4184   return ret;
4185 }
4186
4187 static int
4188 api_sw_interface_add_del_address (vat_main_t * vam)
4189 {
4190   unformat_input_t *i = vam->input;
4191   vl_api_sw_interface_add_del_address_t *mp;
4192   u32 sw_if_index;
4193   u8 sw_if_index_set = 0;
4194   u8 is_add = 1, del_all = 0;
4195   u32 address_length = 0;
4196   u8 v4_address_set = 0;
4197   u8 v6_address_set = 0;
4198   ip4_address_t v4address;
4199   ip6_address_t v6address;
4200   int ret;
4201
4202   /* Parse args required to build the message */
4203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4204     {
4205       if (unformat (i, "del-all"))
4206         del_all = 1;
4207       else if (unformat (i, "del"))
4208         is_add = 0;
4209       else
4210         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4211         sw_if_index_set = 1;
4212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4213         sw_if_index_set = 1;
4214       else if (unformat (i, "%U/%d",
4215                          unformat_ip4_address, &v4address, &address_length))
4216         v4_address_set = 1;
4217       else if (unformat (i, "%U/%d",
4218                          unformat_ip6_address, &v6address, &address_length))
4219         v6_address_set = 1;
4220       else
4221         break;
4222     }
4223
4224   if (sw_if_index_set == 0)
4225     {
4226       errmsg ("missing interface name or sw_if_index");
4227       return -99;
4228     }
4229   if (v4_address_set && v6_address_set)
4230     {
4231       errmsg ("both v4 and v6 addresses set");
4232       return -99;
4233     }
4234   if (!v4_address_set && !v6_address_set && !del_all)
4235     {
4236       errmsg ("no addresses set");
4237       return -99;
4238     }
4239
4240   /* Construct the API message */
4241   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
4242
4243   mp->sw_if_index = ntohl (sw_if_index);
4244   mp->is_add = is_add;
4245   mp->del_all = del_all;
4246   if (v6_address_set)
4247     {
4248       mp->prefix.address.af = ADDRESS_IP6;
4249       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
4250     }
4251   else
4252     {
4253       mp->prefix.address.af = ADDRESS_IP4;
4254       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
4255     }
4256   mp->prefix.len = address_length;
4257
4258   /* send it... */
4259   S (mp);
4260
4261   /* Wait for a reply, return good/bad news  */
4262   W (ret);
4263   return ret;
4264 }
4265
4266 static int
4267 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4268 {
4269   unformat_input_t *i = vam->input;
4270   vl_api_sw_interface_set_mpls_enable_t *mp;
4271   u32 sw_if_index;
4272   u8 sw_if_index_set = 0;
4273   u8 enable = 1;
4274   int ret;
4275
4276   /* Parse args required to build the message */
4277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4278     {
4279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4280         sw_if_index_set = 1;
4281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4282         sw_if_index_set = 1;
4283       else if (unformat (i, "disable"))
4284         enable = 0;
4285       else if (unformat (i, "dis"))
4286         enable = 0;
4287       else
4288         break;
4289     }
4290
4291   if (sw_if_index_set == 0)
4292     {
4293       errmsg ("missing interface name or sw_if_index");
4294       return -99;
4295     }
4296
4297   /* Construct the API message */
4298   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
4299
4300   mp->sw_if_index = ntohl (sw_if_index);
4301   mp->enable = enable;
4302
4303   /* send it... */
4304   S (mp);
4305
4306   /* Wait for a reply... */
4307   W (ret);
4308   return ret;
4309 }
4310
4311 static int
4312 api_sw_interface_set_table (vat_main_t * vam)
4313 {
4314   unformat_input_t *i = vam->input;
4315   vl_api_sw_interface_set_table_t *mp;
4316   u32 sw_if_index, vrf_id = 0;
4317   u8 sw_if_index_set = 0;
4318   u8 is_ipv6 = 0;
4319   int ret;
4320
4321   /* Parse args required to build the message */
4322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4323     {
4324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4325         sw_if_index_set = 1;
4326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4327         sw_if_index_set = 1;
4328       else if (unformat (i, "vrf %d", &vrf_id))
4329         ;
4330       else if (unformat (i, "ipv6"))
4331         is_ipv6 = 1;
4332       else
4333         break;
4334     }
4335
4336   if (sw_if_index_set == 0)
4337     {
4338       errmsg ("missing interface name or sw_if_index");
4339       return -99;
4340     }
4341
4342   /* Construct the API message */
4343   M (SW_INTERFACE_SET_TABLE, mp);
4344
4345   mp->sw_if_index = ntohl (sw_if_index);
4346   mp->is_ipv6 = is_ipv6;
4347   mp->vrf_id = ntohl (vrf_id);
4348
4349   /* send it... */
4350   S (mp);
4351
4352   /* Wait for a reply... */
4353   W (ret);
4354   return ret;
4355 }
4356
4357 static void vl_api_sw_interface_get_table_reply_t_handler
4358   (vl_api_sw_interface_get_table_reply_t * mp)
4359 {
4360   vat_main_t *vam = &vat_main;
4361
4362   print (vam->ofp, "%d", ntohl (mp->vrf_id));
4363
4364   vam->retval = ntohl (mp->retval);
4365   vam->result_ready = 1;
4366
4367 }
4368
4369 static void vl_api_sw_interface_get_table_reply_t_handler_json
4370   (vl_api_sw_interface_get_table_reply_t * mp)
4371 {
4372   vat_main_t *vam = &vat_main;
4373   vat_json_node_t node;
4374
4375   vat_json_init_object (&node);
4376   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4377   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4378
4379   vat_json_print (vam->ofp, &node);
4380   vat_json_free (&node);
4381
4382   vam->retval = ntohl (mp->retval);
4383   vam->result_ready = 1;
4384 }
4385
4386 static int
4387 api_sw_interface_get_table (vat_main_t * vam)
4388 {
4389   unformat_input_t *i = vam->input;
4390   vl_api_sw_interface_get_table_t *mp;
4391   u32 sw_if_index;
4392   u8 sw_if_index_set = 0;
4393   u8 is_ipv6 = 0;
4394   int ret;
4395
4396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4397     {
4398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4399         sw_if_index_set = 1;
4400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4401         sw_if_index_set = 1;
4402       else if (unformat (i, "ipv6"))
4403         is_ipv6 = 1;
4404       else
4405         break;
4406     }
4407
4408   if (sw_if_index_set == 0)
4409     {
4410       errmsg ("missing interface name or sw_if_index");
4411       return -99;
4412     }
4413
4414   M (SW_INTERFACE_GET_TABLE, mp);
4415   mp->sw_if_index = htonl (sw_if_index);
4416   mp->is_ipv6 = is_ipv6;
4417
4418   S (mp);
4419   W (ret);
4420   return ret;
4421 }
4422
4423 static int
4424 api_sw_interface_set_vpath (vat_main_t * vam)
4425 {
4426   unformat_input_t *i = vam->input;
4427   vl_api_sw_interface_set_vpath_t *mp;
4428   u32 sw_if_index = 0;
4429   u8 sw_if_index_set = 0;
4430   u8 is_enable = 0;
4431   int ret;
4432
4433   /* Parse args required to build the message */
4434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4435     {
4436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4437         sw_if_index_set = 1;
4438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4439         sw_if_index_set = 1;
4440       else if (unformat (i, "enable"))
4441         is_enable = 1;
4442       else if (unformat (i, "disable"))
4443         is_enable = 0;
4444       else
4445         break;
4446     }
4447
4448   if (sw_if_index_set == 0)
4449     {
4450       errmsg ("missing interface name or sw_if_index");
4451       return -99;
4452     }
4453
4454   /* Construct the API message */
4455   M (SW_INTERFACE_SET_VPATH, mp);
4456
4457   mp->sw_if_index = ntohl (sw_if_index);
4458   mp->enable = is_enable;
4459
4460   /* send it... */
4461   S (mp);
4462
4463   /* Wait for a reply... */
4464   W (ret);
4465   return ret;
4466 }
4467
4468 static int
4469 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4470 {
4471   unformat_input_t *i = vam->input;
4472   vl_api_sw_interface_set_vxlan_bypass_t *mp;
4473   u32 sw_if_index = 0;
4474   u8 sw_if_index_set = 0;
4475   u8 is_enable = 1;
4476   u8 is_ipv6 = 0;
4477   int ret;
4478
4479   /* Parse args required to build the message */
4480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4481     {
4482       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4483         sw_if_index_set = 1;
4484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4485         sw_if_index_set = 1;
4486       else if (unformat (i, "enable"))
4487         is_enable = 1;
4488       else if (unformat (i, "disable"))
4489         is_enable = 0;
4490       else if (unformat (i, "ip4"))
4491         is_ipv6 = 0;
4492       else if (unformat (i, "ip6"))
4493         is_ipv6 = 1;
4494       else
4495         break;
4496     }
4497
4498   if (sw_if_index_set == 0)
4499     {
4500       errmsg ("missing interface name or sw_if_index");
4501       return -99;
4502     }
4503
4504   /* Construct the API message */
4505   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
4506
4507   mp->sw_if_index = ntohl (sw_if_index);
4508   mp->enable = is_enable;
4509   mp->is_ipv6 = is_ipv6;
4510
4511   /* send it... */
4512   S (mp);
4513
4514   /* Wait for a reply... */
4515   W (ret);
4516   return ret;
4517 }
4518
4519 static int
4520 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4521 {
4522   unformat_input_t *i = vam->input;
4523   vl_api_sw_interface_set_l2_xconnect_t *mp;
4524   u32 rx_sw_if_index;
4525   u8 rx_sw_if_index_set = 0;
4526   u32 tx_sw_if_index;
4527   u8 tx_sw_if_index_set = 0;
4528   u8 enable = 1;
4529   int ret;
4530
4531   /* Parse args required to build the message */
4532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4533     {
4534       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4535         rx_sw_if_index_set = 1;
4536       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4537         tx_sw_if_index_set = 1;
4538       else if (unformat (i, "rx"))
4539         {
4540           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4541             {
4542               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4543                             &rx_sw_if_index))
4544                 rx_sw_if_index_set = 1;
4545             }
4546           else
4547             break;
4548         }
4549       else if (unformat (i, "tx"))
4550         {
4551           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552             {
4553               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4554                             &tx_sw_if_index))
4555                 tx_sw_if_index_set = 1;
4556             }
4557           else
4558             break;
4559         }
4560       else if (unformat (i, "enable"))
4561         enable = 1;
4562       else if (unformat (i, "disable"))
4563         enable = 0;
4564       else
4565         break;
4566     }
4567
4568   if (rx_sw_if_index_set == 0)
4569     {
4570       errmsg ("missing rx interface name or rx_sw_if_index");
4571       return -99;
4572     }
4573
4574   if (enable && (tx_sw_if_index_set == 0))
4575     {
4576       errmsg ("missing tx interface name or tx_sw_if_index");
4577       return -99;
4578     }
4579
4580   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
4581
4582   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4583   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4584   mp->enable = enable;
4585
4586   S (mp);
4587   W (ret);
4588   return ret;
4589 }
4590
4591 static int
4592 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4593 {
4594   unformat_input_t *i = vam->input;
4595   vl_api_sw_interface_set_l2_bridge_t *mp;
4596   vl_api_l2_port_type_t port_type;
4597   u32 rx_sw_if_index;
4598   u8 rx_sw_if_index_set = 0;
4599   u32 bd_id;
4600   u8 bd_id_set = 0;
4601   u32 shg = 0;
4602   u8 enable = 1;
4603   int ret;
4604
4605   port_type = L2_API_PORT_TYPE_NORMAL;
4606
4607   /* Parse args required to build the message */
4608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4609     {
4610       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4611         rx_sw_if_index_set = 1;
4612       else if (unformat (i, "bd_id %d", &bd_id))
4613         bd_id_set = 1;
4614       else
4615         if (unformat
4616             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4617         rx_sw_if_index_set = 1;
4618       else if (unformat (i, "shg %d", &shg))
4619         ;
4620       else if (unformat (i, "bvi"))
4621         port_type = L2_API_PORT_TYPE_BVI;
4622       else if (unformat (i, "uu-fwd"))
4623         port_type = L2_API_PORT_TYPE_UU_FWD;
4624       else if (unformat (i, "enable"))
4625         enable = 1;
4626       else if (unformat (i, "disable"))
4627         enable = 0;
4628       else
4629         break;
4630     }
4631
4632   if (rx_sw_if_index_set == 0)
4633     {
4634       errmsg ("missing rx interface name or sw_if_index");
4635       return -99;
4636     }
4637
4638   if (enable && (bd_id_set == 0))
4639     {
4640       errmsg ("missing bridge domain");
4641       return -99;
4642     }
4643
4644   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
4645
4646   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4647   mp->bd_id = ntohl (bd_id);
4648   mp->shg = (u8) shg;
4649   mp->port_type = ntohl (port_type);
4650   mp->enable = enable;
4651
4652   S (mp);
4653   W (ret);
4654   return ret;
4655 }
4656
4657 static int
4658 api_bridge_domain_dump (vat_main_t * vam)
4659 {
4660   unformat_input_t *i = vam->input;
4661   vl_api_bridge_domain_dump_t *mp;
4662   vl_api_control_ping_t *mp_ping;
4663   u32 bd_id = ~0;
4664   int ret;
4665
4666   /* Parse args required to build the message */
4667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4668     {
4669       if (unformat (i, "bd_id %d", &bd_id))
4670         ;
4671       else
4672         break;
4673     }
4674
4675   M (BRIDGE_DOMAIN_DUMP, mp);
4676   mp->bd_id = ntohl (bd_id);
4677   S (mp);
4678
4679   /* Use a control ping for synchronization */
4680   MPING (CONTROL_PING, mp_ping);
4681   S (mp_ping);
4682
4683   W (ret);
4684   return ret;
4685 }
4686
4687 static int
4688 api_bridge_domain_add_del (vat_main_t * vam)
4689 {
4690   unformat_input_t *i = vam->input;
4691   vl_api_bridge_domain_add_del_t *mp;
4692   u32 bd_id = ~0;
4693   u8 is_add = 1;
4694   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4695   u8 *bd_tag = NULL;
4696   u32 mac_age = 0;
4697   int ret;
4698
4699   /* Parse args required to build the message */
4700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701     {
4702       if (unformat (i, "bd_id %d", &bd_id))
4703         ;
4704       else if (unformat (i, "flood %d", &flood))
4705         ;
4706       else if (unformat (i, "uu-flood %d", &uu_flood))
4707         ;
4708       else if (unformat (i, "forward %d", &forward))
4709         ;
4710       else if (unformat (i, "learn %d", &learn))
4711         ;
4712       else if (unformat (i, "arp-term %d", &arp_term))
4713         ;
4714       else if (unformat (i, "mac-age %d", &mac_age))
4715         ;
4716       else if (unformat (i, "bd-tag %s", &bd_tag))
4717         ;
4718       else if (unformat (i, "del"))
4719         {
4720           is_add = 0;
4721           flood = uu_flood = forward = learn = 0;
4722         }
4723       else
4724         break;
4725     }
4726
4727   if (bd_id == ~0)
4728     {
4729       errmsg ("missing bridge domain");
4730       ret = -99;
4731       goto done;
4732     }
4733
4734   if (mac_age > 255)
4735     {
4736       errmsg ("mac age must be less than 256 ");
4737       ret = -99;
4738       goto done;
4739     }
4740
4741   if ((bd_tag) && (vec_len (bd_tag) > 63))
4742     {
4743       errmsg ("bd-tag cannot be longer than 63");
4744       ret = -99;
4745       goto done;
4746     }
4747
4748   M (BRIDGE_DOMAIN_ADD_DEL, mp);
4749
4750   mp->bd_id = ntohl (bd_id);
4751   mp->flood = flood;
4752   mp->uu_flood = uu_flood;
4753   mp->forward = forward;
4754   mp->learn = learn;
4755   mp->arp_term = arp_term;
4756   mp->is_add = is_add;
4757   mp->mac_age = (u8) mac_age;
4758   if (bd_tag)
4759     {
4760       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4761       mp->bd_tag[vec_len (bd_tag)] = 0;
4762     }
4763   S (mp);
4764   W (ret);
4765
4766 done:
4767   vec_free (bd_tag);
4768   return ret;
4769 }
4770
4771 static int
4772 api_l2fib_flush_bd (vat_main_t * vam)
4773 {
4774   unformat_input_t *i = vam->input;
4775   vl_api_l2fib_flush_bd_t *mp;
4776   u32 bd_id = ~0;
4777   int ret;
4778
4779   /* Parse args required to build the message */
4780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4781     {
4782       if (unformat (i, "bd_id %d", &bd_id));
4783       else
4784         break;
4785     }
4786
4787   if (bd_id == ~0)
4788     {
4789       errmsg ("missing bridge domain");
4790       return -99;
4791     }
4792
4793   M (L2FIB_FLUSH_BD, mp);
4794
4795   mp->bd_id = htonl (bd_id);
4796
4797   S (mp);
4798   W (ret);
4799   return ret;
4800 }
4801
4802 static int
4803 api_l2fib_flush_int (vat_main_t * vam)
4804 {
4805   unformat_input_t *i = vam->input;
4806   vl_api_l2fib_flush_int_t *mp;
4807   u32 sw_if_index = ~0;
4808   int ret;
4809
4810   /* Parse args required to build the message */
4811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4812     {
4813       if (unformat (i, "sw_if_index %d", &sw_if_index));
4814       else
4815         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4816       else
4817         break;
4818     }
4819
4820   if (sw_if_index == ~0)
4821     {
4822       errmsg ("missing interface name or sw_if_index");
4823       return -99;
4824     }
4825
4826   M (L2FIB_FLUSH_INT, mp);
4827
4828   mp->sw_if_index = ntohl (sw_if_index);
4829
4830   S (mp);
4831   W (ret);
4832   return ret;
4833 }
4834
4835 static int
4836 api_l2fib_add_del (vat_main_t * vam)
4837 {
4838   unformat_input_t *i = vam->input;
4839   vl_api_l2fib_add_del_t *mp;
4840   f64 timeout;
4841   u8 mac[6] = { 0 };
4842   u8 mac_set = 0;
4843   u32 bd_id;
4844   u8 bd_id_set = 0;
4845   u32 sw_if_index = 0;
4846   u8 sw_if_index_set = 0;
4847   u8 is_add = 1;
4848   u8 static_mac = 0;
4849   u8 filter_mac = 0;
4850   u8 bvi_mac = 0;
4851   int count = 1;
4852   f64 before = 0;
4853   int j;
4854
4855   /* Parse args required to build the message */
4856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4857     {
4858       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
4859         mac_set = 1;
4860       else if (unformat (i, "bd_id %d", &bd_id))
4861         bd_id_set = 1;
4862       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4863         sw_if_index_set = 1;
4864       else if (unformat (i, "sw_if"))
4865         {
4866           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4867             {
4868               if (unformat
4869                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4870                 sw_if_index_set = 1;
4871             }
4872           else
4873             break;
4874         }
4875       else if (unformat (i, "static"))
4876         static_mac = 1;
4877       else if (unformat (i, "filter"))
4878         {
4879           filter_mac = 1;
4880           static_mac = 1;
4881         }
4882       else if (unformat (i, "bvi"))
4883         {
4884           bvi_mac = 1;
4885           static_mac = 1;
4886         }
4887       else if (unformat (i, "del"))
4888         is_add = 0;
4889       else if (unformat (i, "count %d", &count))
4890         ;
4891       else
4892         break;
4893     }
4894
4895   if (mac_set == 0)
4896     {
4897       errmsg ("missing mac address");
4898       return -99;
4899     }
4900
4901   if (bd_id_set == 0)
4902     {
4903       errmsg ("missing bridge domain");
4904       return -99;
4905     }
4906
4907   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4908     {
4909       errmsg ("missing interface name or sw_if_index");
4910       return -99;
4911     }
4912
4913   if (count > 1)
4914     {
4915       /* Turn on async mode */
4916       vam->async_mode = 1;
4917       vam->async_errors = 0;
4918       before = vat_time_now (vam);
4919     }
4920
4921   for (j = 0; j < count; j++)
4922     {
4923       M (L2FIB_ADD_DEL, mp);
4924
4925       clib_memcpy (mp->mac, mac, 6);
4926       mp->bd_id = ntohl (bd_id);
4927       mp->is_add = is_add;
4928       mp->sw_if_index = ntohl (sw_if_index);
4929
4930       if (is_add)
4931         {
4932           mp->static_mac = static_mac;
4933           mp->filter_mac = filter_mac;
4934           mp->bvi_mac = bvi_mac;
4935         }
4936       increment_mac_address (mac);
4937       /* send it... */
4938       S (mp);
4939     }
4940
4941   if (count > 1)
4942     {
4943       vl_api_control_ping_t *mp_ping;
4944       f64 after;
4945
4946       /* Shut off async mode */
4947       vam->async_mode = 0;
4948
4949       MPING (CONTROL_PING, mp_ping);
4950       S (mp_ping);
4951
4952       timeout = vat_time_now (vam) + 1.0;
4953       while (vat_time_now (vam) < timeout)
4954         if (vam->result_ready == 1)
4955           goto out;
4956       vam->retval = -99;
4957
4958     out:
4959       if (vam->retval == -99)
4960         errmsg ("timeout");
4961
4962       if (vam->async_errors > 0)
4963         {
4964           errmsg ("%d asynchronous errors", vam->async_errors);
4965           vam->retval = -98;
4966         }
4967       vam->async_errors = 0;
4968       after = vat_time_now (vam);
4969
4970       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4971              count, after - before, count / (after - before));
4972     }
4973   else
4974     {
4975       int ret;
4976
4977       /* Wait for a reply... */
4978       W (ret);
4979       return ret;
4980     }
4981   /* Return the good/bad news */
4982   return (vam->retval);
4983 }
4984
4985 static int
4986 api_bridge_domain_set_mac_age (vat_main_t * vam)
4987 {
4988   unformat_input_t *i = vam->input;
4989   vl_api_bridge_domain_set_mac_age_t *mp;
4990   u32 bd_id = ~0;
4991   u32 mac_age = 0;
4992   int ret;
4993
4994   /* Parse args required to build the message */
4995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4996     {
4997       if (unformat (i, "bd_id %d", &bd_id));
4998       else if (unformat (i, "mac-age %d", &mac_age));
4999       else
5000         break;
5001     }
5002
5003   if (bd_id == ~0)
5004     {
5005       errmsg ("missing bridge domain");
5006       return -99;
5007     }
5008
5009   if (mac_age > 255)
5010     {
5011       errmsg ("mac age must be less than 256 ");
5012       return -99;
5013     }
5014
5015   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5016
5017   mp->bd_id = htonl (bd_id);
5018   mp->mac_age = (u8) mac_age;
5019
5020   S (mp);
5021   W (ret);
5022   return ret;
5023 }
5024
5025 static int
5026 api_l2_flags (vat_main_t * vam)
5027 {
5028   unformat_input_t *i = vam->input;
5029   vl_api_l2_flags_t *mp;
5030   u32 sw_if_index;
5031   u32 flags = 0;
5032   u8 sw_if_index_set = 0;
5033   u8 is_set = 0;
5034   int ret;
5035
5036   /* Parse args required to build the message */
5037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5038     {
5039       if (unformat (i, "sw_if_index %d", &sw_if_index))
5040         sw_if_index_set = 1;
5041       else if (unformat (i, "sw_if"))
5042         {
5043           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044             {
5045               if (unformat
5046                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5047                 sw_if_index_set = 1;
5048             }
5049           else
5050             break;
5051         }
5052       else if (unformat (i, "learn"))
5053         flags |= L2_LEARN;
5054       else if (unformat (i, "forward"))
5055         flags |= L2_FWD;
5056       else if (unformat (i, "flood"))
5057         flags |= L2_FLOOD;
5058       else if (unformat (i, "uu-flood"))
5059         flags |= L2_UU_FLOOD;
5060       else if (unformat (i, "arp-term"))
5061         flags |= L2_ARP_TERM;
5062       else if (unformat (i, "off"))
5063         is_set = 0;
5064       else if (unformat (i, "disable"))
5065         is_set = 0;
5066       else
5067         break;
5068     }
5069
5070   if (sw_if_index_set == 0)
5071     {
5072       errmsg ("missing interface name or sw_if_index");
5073       return -99;
5074     }
5075
5076   M (L2_FLAGS, mp);
5077
5078   mp->sw_if_index = ntohl (sw_if_index);
5079   mp->feature_bitmap = ntohl (flags);
5080   mp->is_set = is_set;
5081
5082   S (mp);
5083   W (ret);
5084   return ret;
5085 }
5086
5087 static int
5088 api_bridge_flags (vat_main_t * vam)
5089 {
5090   unformat_input_t *i = vam->input;
5091   vl_api_bridge_flags_t *mp;
5092   u32 bd_id;
5093   u8 bd_id_set = 0;
5094   u8 is_set = 1;
5095   bd_flags_t flags = 0;
5096   int ret;
5097
5098   /* Parse args required to build the message */
5099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5100     {
5101       if (unformat (i, "bd_id %d", &bd_id))
5102         bd_id_set = 1;
5103       else if (unformat (i, "learn"))
5104         flags |= BRIDGE_API_FLAG_LEARN;
5105       else if (unformat (i, "forward"))
5106         flags |= BRIDGE_API_FLAG_FWD;
5107       else if (unformat (i, "flood"))
5108         flags |= BRIDGE_API_FLAG_FLOOD;
5109       else if (unformat (i, "uu-flood"))
5110         flags |= BRIDGE_API_FLAG_UU_FLOOD;
5111       else if (unformat (i, "arp-term"))
5112         flags |= BRIDGE_API_FLAG_ARP_TERM;
5113       else if (unformat (i, "off"))
5114         is_set = 0;
5115       else if (unformat (i, "disable"))
5116         is_set = 0;
5117       else
5118         break;
5119     }
5120
5121   if (bd_id_set == 0)
5122     {
5123       errmsg ("missing bridge domain");
5124       return -99;
5125     }
5126
5127   M (BRIDGE_FLAGS, mp);
5128
5129   mp->bd_id = ntohl (bd_id);
5130   mp->flags = ntohl (flags);
5131   mp->is_set = is_set;
5132
5133   S (mp);
5134   W (ret);
5135   return ret;
5136 }
5137
5138 static int
5139 api_bd_ip_mac_add_del (vat_main_t * vam)
5140 {
5141   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
5142   vl_api_mac_address_t mac = { 0 };
5143   unformat_input_t *i = vam->input;
5144   vl_api_bd_ip_mac_add_del_t *mp;
5145   u32 bd_id;
5146   u8 is_add = 1;
5147   u8 bd_id_set = 0;
5148   u8 ip_set = 0;
5149   u8 mac_set = 0;
5150   int ret;
5151
5152
5153   /* Parse args required to build the message */
5154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5155     {
5156       if (unformat (i, "bd_id %d", &bd_id))
5157         {
5158           bd_id_set++;
5159         }
5160       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
5161         {
5162           ip_set++;
5163         }
5164       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5165         {
5166           mac_set++;
5167         }
5168       else if (unformat (i, "del"))
5169         is_add = 0;
5170       else
5171         break;
5172     }
5173
5174   if (bd_id_set == 0)
5175     {
5176       errmsg ("missing bridge domain");
5177       return -99;
5178     }
5179   else if (ip_set == 0)
5180     {
5181       errmsg ("missing IP address");
5182       return -99;
5183     }
5184   else if (mac_set == 0)
5185     {
5186       errmsg ("missing MAC address");
5187       return -99;
5188     }
5189
5190   M (BD_IP_MAC_ADD_DEL, mp);
5191
5192   mp->entry.bd_id = ntohl (bd_id);
5193   mp->is_add = is_add;
5194
5195   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5196   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
5197
5198   S (mp);
5199   W (ret);
5200   return ret;
5201 }
5202
5203 static int
5204 api_bd_ip_mac_flush (vat_main_t * vam)
5205 {
5206   unformat_input_t *i = vam->input;
5207   vl_api_bd_ip_mac_flush_t *mp;
5208   u32 bd_id;
5209   u8 bd_id_set = 0;
5210   int ret;
5211
5212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5213     {
5214       if (unformat (i, "bd_id %d", &bd_id))
5215         {
5216           bd_id_set++;
5217         }
5218       else
5219         break;
5220     }
5221
5222   if (bd_id_set == 0)
5223     {
5224       errmsg ("missing bridge domain");
5225       return -99;
5226     }
5227
5228   M (BD_IP_MAC_FLUSH, mp);
5229
5230   mp->bd_id = ntohl (bd_id);
5231
5232   S (mp);
5233   W (ret);
5234   return ret;
5235 }
5236
5237 static void vl_api_bd_ip_mac_details_t_handler
5238   (vl_api_bd_ip_mac_details_t * mp)
5239 {
5240   vat_main_t *vam = &vat_main;
5241
5242   print (vam->ofp,
5243          "\n%-5d %U %U",
5244          ntohl (mp->entry.bd_id),
5245          format_vl_api_mac_address, mp->entry.mac,
5246          format_vl_api_address, &mp->entry.ip);
5247 }
5248
5249 static void vl_api_bd_ip_mac_details_t_handler_json
5250   (vl_api_bd_ip_mac_details_t * mp)
5251 {
5252   vat_main_t *vam = &vat_main;
5253   vat_json_node_t *node = NULL;
5254
5255   if (VAT_JSON_ARRAY != vam->json_tree.type)
5256     {
5257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5258       vat_json_init_array (&vam->json_tree);
5259     }
5260   node = vat_json_array_add (&vam->json_tree);
5261
5262   vat_json_init_object (node);
5263   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
5264   vat_json_object_add_string_copy (node, "mac_address",
5265                                    format (0, "%U", format_vl_api_mac_address,
5266                                            &mp->entry.mac));
5267   u8 *ip = 0;
5268
5269   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
5270   vat_json_object_add_string_copy (node, "ip_address", ip);
5271   vec_free (ip);
5272 }
5273
5274 static int
5275 api_bd_ip_mac_dump (vat_main_t * vam)
5276 {
5277   unformat_input_t *i = vam->input;
5278   vl_api_bd_ip_mac_dump_t *mp;
5279   vl_api_control_ping_t *mp_ping;
5280   int ret;
5281   u32 bd_id;
5282   u8 bd_id_set = 0;
5283
5284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5285     {
5286       if (unformat (i, "bd_id %d", &bd_id))
5287         {
5288           bd_id_set++;
5289         }
5290       else
5291         break;
5292     }
5293
5294   print (vam->ofp,
5295          "\n%-5s %-7s %-20s %-30s",
5296          "bd_id", "is_ipv6", "mac_address", "ip_address");
5297
5298   /* Dump Bridge Domain Ip to Mac entries */
5299   M (BD_IP_MAC_DUMP, mp);
5300
5301   if (bd_id_set)
5302     mp->bd_id = htonl (bd_id);
5303   else
5304     mp->bd_id = ~0;
5305
5306   S (mp);
5307
5308   /* Use a control ping for synchronization */
5309   MPING (CONTROL_PING, mp_ping);
5310   S (mp_ping);
5311
5312   W (ret);
5313   return ret;
5314 }
5315
5316 static int
5317 api_tap_create_v2 (vat_main_t * vam)
5318 {
5319   unformat_input_t *i = vam->input;
5320   vl_api_tap_create_v2_t *mp;
5321   u8 mac_address[6];
5322   u8 random_mac = 1;
5323   u32 id = ~0;
5324   u32 num_rx_queues = 0;
5325   u8 *host_if_name = 0;
5326   u8 host_if_name_set = 0;
5327   u8 *host_ns = 0;
5328   u8 host_ns_set = 0;
5329   u8 host_mac_addr[6];
5330   u8 host_mac_addr_set = 0;
5331   u8 *host_bridge = 0;
5332   u8 host_bridge_set = 0;
5333   u8 host_ip4_prefix_set = 0;
5334   u8 host_ip6_prefix_set = 0;
5335   ip4_address_t host_ip4_addr;
5336   ip4_address_t host_ip4_gw;
5337   u8 host_ip4_gw_set = 0;
5338   u32 host_ip4_prefix_len = 0;
5339   ip6_address_t host_ip6_addr;
5340   ip6_address_t host_ip6_gw;
5341   u8 host_ip6_gw_set = 0;
5342   u32 host_ip6_prefix_len = 0;
5343   u32 host_mtu_size = 0;
5344   u8 host_mtu_set = 0;
5345   u32 tap_flags = 0;
5346   int ret;
5347   u32 rx_ring_sz = 0, tx_ring_sz = 0;
5348
5349   clib_memset (mac_address, 0, sizeof (mac_address));
5350
5351   /* Parse args required to build the message */
5352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5353     {
5354       if (unformat (i, "id %u", &id))
5355         ;
5356       else
5357         if (unformat
5358             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5359         random_mac = 0;
5360       else if (unformat (i, "host-if-name %s", &host_if_name))
5361         host_if_name_set = 1;
5362       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
5363         ;
5364       else if (unformat (i, "host-ns %s", &host_ns))
5365         host_ns_set = 1;
5366       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5367                          host_mac_addr))
5368         host_mac_addr_set = 1;
5369       else if (unformat (i, "host-bridge %s", &host_bridge))
5370         host_bridge_set = 1;
5371       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
5372                          &host_ip4_addr, &host_ip4_prefix_len))
5373         host_ip4_prefix_set = 1;
5374       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
5375                          &host_ip6_addr, &host_ip6_prefix_len))
5376         host_ip6_prefix_set = 1;
5377       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5378                          &host_ip4_gw))
5379         host_ip4_gw_set = 1;
5380       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5381                          &host_ip6_gw))
5382         host_ip6_gw_set = 1;
5383       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
5384         ;
5385       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
5386         ;
5387       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
5388         host_mtu_set = 1;
5389       else if (unformat (i, "no-gso"))
5390         tap_flags &= ~TAP_API_FLAG_GSO;
5391       else if (unformat (i, "gso"))
5392         tap_flags |= TAP_API_FLAG_GSO;
5393       else if (unformat (i, "csum-offload"))
5394         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
5395       else if (unformat (i, "persist"))
5396         tap_flags |= TAP_API_FLAG_PERSIST;
5397       else if (unformat (i, "attach"))
5398         tap_flags |= TAP_API_FLAG_ATTACH;
5399       else if (unformat (i, "tun"))
5400         tap_flags |= TAP_API_FLAG_TUN;
5401       else if (unformat (i, "gro-coalesce"))
5402         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
5403       else if (unformat (i, "packed"))
5404         tap_flags |= TAP_API_FLAG_PACKED;
5405       else if (unformat (i, "in-order"))
5406         tap_flags |= TAP_API_FLAG_IN_ORDER;
5407       else
5408         break;
5409     }
5410
5411   if (vec_len (host_if_name) > 63)
5412     {
5413       errmsg ("tap name too long. ");
5414       return -99;
5415     }
5416   if (vec_len (host_ns) > 63)
5417     {
5418       errmsg ("host name space too long. ");
5419       return -99;
5420     }
5421   if (vec_len (host_bridge) > 63)
5422     {
5423       errmsg ("host bridge name too long. ");
5424       return -99;
5425     }
5426   if (host_ip4_prefix_len > 32)
5427     {
5428       errmsg ("host ip4 prefix length not valid. ");
5429       return -99;
5430     }
5431   if (host_ip6_prefix_len > 128)
5432     {
5433       errmsg ("host ip6 prefix length not valid. ");
5434       return -99;
5435     }
5436   if (!is_pow2 (rx_ring_sz))
5437     {
5438       errmsg ("rx ring size must be power of 2. ");
5439       return -99;
5440     }
5441   if (rx_ring_sz > 32768)
5442     {
5443       errmsg ("rx ring size must be 32768 or lower. ");
5444       return -99;
5445     }
5446   if (!is_pow2 (tx_ring_sz))
5447     {
5448       errmsg ("tx ring size must be power of 2. ");
5449       return -99;
5450     }
5451   if (tx_ring_sz > 32768)
5452     {
5453       errmsg ("tx ring size must be 32768 or lower. ");
5454       return -99;
5455     }
5456   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5457     {
5458       errmsg ("host MTU size must be in between 64 and 65355. ");
5459       return -99;
5460     }
5461
5462   /* Construct the API message */
5463   M (TAP_CREATE_V2, mp);
5464
5465   mp->id = ntohl (id);
5466   mp->use_random_mac = random_mac;
5467   mp->num_rx_queues = (u8) num_rx_queues;
5468   mp->tx_ring_sz = ntohs (tx_ring_sz);
5469   mp->rx_ring_sz = ntohs (rx_ring_sz);
5470   mp->host_mtu_set = host_mtu_set;
5471   mp->host_mtu_size = ntohl (host_mtu_size);
5472   mp->host_mac_addr_set = host_mac_addr_set;
5473   mp->host_ip4_prefix_set = host_ip4_prefix_set;
5474   mp->host_ip6_prefix_set = host_ip6_prefix_set;
5475   mp->host_ip4_gw_set = host_ip4_gw_set;
5476   mp->host_ip6_gw_set = host_ip6_gw_set;
5477   mp->tap_flags = ntohl (tap_flags);
5478   mp->host_namespace_set = host_ns_set;
5479   mp->host_if_name_set = host_if_name_set;
5480   mp->host_bridge_set = host_bridge_set;
5481
5482   if (random_mac == 0)
5483     clib_memcpy (mp->mac_address, mac_address, 6);
5484   if (host_mac_addr_set)
5485     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
5486   if (host_if_name_set)
5487     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
5488   if (host_ns_set)
5489     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
5490   if (host_bridge_set)
5491     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
5492   if (host_ip4_prefix_set)
5493     {
5494       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5495       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5496     }
5497   if (host_ip6_prefix_set)
5498     {
5499       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5500       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5501     }
5502   if (host_ip4_gw_set)
5503     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5504   if (host_ip6_gw_set)
5505     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
5506
5507   vec_free (host_ns);
5508   vec_free (host_if_name);
5509   vec_free (host_bridge);
5510
5511   /* send it... */
5512   S (mp);
5513
5514   /* Wait for a reply... */
5515   W (ret);
5516   return ret;
5517 }
5518
5519 static int
5520 api_tap_delete_v2 (vat_main_t * vam)
5521 {
5522   unformat_input_t *i = vam->input;
5523   vl_api_tap_delete_v2_t *mp;
5524   u32 sw_if_index = ~0;
5525   u8 sw_if_index_set = 0;
5526   int ret;
5527
5528   /* Parse args required to build the message */
5529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5530     {
5531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5532         sw_if_index_set = 1;
5533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5534         sw_if_index_set = 1;
5535       else
5536         break;
5537     }
5538
5539   if (sw_if_index_set == 0)
5540     {
5541       errmsg ("missing vpp interface name. ");
5542       return -99;
5543     }
5544
5545   /* Construct the API message */
5546   M (TAP_DELETE_V2, mp);
5547
5548   mp->sw_if_index = ntohl (sw_if_index);
5549
5550   /* send it... */
5551   S (mp);
5552
5553   /* Wait for a reply... */
5554   W (ret);
5555   return ret;
5556 }
5557
5558 uword
5559 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
5560 {
5561   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
5562   u32 x[4];
5563
5564   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5565     return 0;
5566
5567   addr->domain = x[0];
5568   addr->bus = x[1];
5569   addr->slot = x[2];
5570   addr->function = x[3];
5571
5572   return 1;
5573 }
5574
5575 static int
5576 api_virtio_pci_create_v2 (vat_main_t * vam)
5577 {
5578   unformat_input_t *i = vam->input;
5579   vl_api_virtio_pci_create_v2_t *mp;
5580   u8 mac_address[6];
5581   u8 random_mac = 1;
5582   u32 pci_addr = 0;
5583   u64 features = (u64) ~ (0ULL);
5584   u32 virtio_flags = 0;
5585   int ret;
5586
5587   clib_memset (mac_address, 0, sizeof (mac_address));
5588
5589   /* Parse args required to build the message */
5590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5591     {
5592       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5593         {
5594           random_mac = 0;
5595         }
5596       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
5597         ;
5598       else if (unformat (i, "features 0x%llx", &features))
5599         ;
5600       else if (unformat (i, "gso-enabled"))
5601         virtio_flags |= VIRTIO_API_FLAG_GSO;
5602       else if (unformat (i, "csum-offload-enabled"))
5603         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5604       else if (unformat (i, "gro-coalesce"))
5605         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5606       else if (unformat (i, "packed"))
5607         virtio_flags |= VIRTIO_API_FLAG_PACKED;
5608       else if (unformat (i, "in-order"))
5609         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
5610       else if (unformat (i, "buffering"))
5611         virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
5612       else
5613         break;
5614     }
5615
5616   if (pci_addr == 0)
5617     {
5618       errmsg ("pci address must be non zero. ");
5619       return -99;
5620     }
5621
5622   /* Construct the API message */
5623   M (VIRTIO_PCI_CREATE_V2, mp);
5624
5625   mp->use_random_mac = random_mac;
5626
5627   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5628   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5629   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5630   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5631
5632   mp->features = clib_host_to_net_u64 (features);
5633   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
5634
5635   if (random_mac == 0)
5636     clib_memcpy (mp->mac_address, mac_address, 6);
5637
5638   /* send it... */
5639   S (mp);
5640
5641   /* Wait for a reply... */
5642   W (ret);
5643   return ret;
5644 }
5645
5646 static int
5647 api_virtio_pci_delete (vat_main_t * vam)
5648 {
5649   unformat_input_t *i = vam->input;
5650   vl_api_virtio_pci_delete_t *mp;
5651   u32 sw_if_index = ~0;
5652   u8 sw_if_index_set = 0;
5653   int ret;
5654
5655   /* Parse args required to build the message */
5656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5657     {
5658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5659         sw_if_index_set = 1;
5660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5661         sw_if_index_set = 1;
5662       else
5663         break;
5664     }
5665
5666   if (sw_if_index_set == 0)
5667     {
5668       errmsg ("missing vpp interface name. ");
5669       return -99;
5670     }
5671
5672   /* Construct the API message */
5673   M (VIRTIO_PCI_DELETE, mp);
5674
5675   mp->sw_if_index = htonl (sw_if_index);
5676
5677   /* send it... */
5678   S (mp);
5679
5680   /* Wait for a reply... */
5681   W (ret);
5682   return ret;
5683 }
5684
5685 static int
5686 api_bond_create (vat_main_t * vam)
5687 {
5688   unformat_input_t *i = vam->input;
5689   vl_api_bond_create_t *mp;
5690   u8 mac_address[6];
5691   u8 custom_mac = 0;
5692   int ret;
5693   u8 mode;
5694   u8 lb;
5695   u8 mode_is_set = 0;
5696   u32 id = ~0;
5697   u8 numa_only = 0;
5698
5699   clib_memset (mac_address, 0, sizeof (mac_address));
5700   lb = BOND_LB_L2;
5701
5702   /* Parse args required to build the message */
5703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5704     {
5705       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5706         mode_is_set = 1;
5707       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5708                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5709         ;
5710       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5711                          mac_address))
5712         custom_mac = 1;
5713       else if (unformat (i, "numa-only"))
5714         numa_only = 1;
5715       else if (unformat (i, "id %u", &id))
5716         ;
5717       else
5718         break;
5719     }
5720
5721   if (mode_is_set == 0)
5722     {
5723       errmsg ("Missing bond mode. ");
5724       return -99;
5725     }
5726
5727   /* Construct the API message */
5728   M (BOND_CREATE, mp);
5729
5730   mp->use_custom_mac = custom_mac;
5731
5732   mp->mode = htonl (mode);
5733   mp->lb = htonl (lb);
5734   mp->id = htonl (id);
5735   mp->numa_only = numa_only;
5736
5737   if (custom_mac)
5738     clib_memcpy (mp->mac_address, mac_address, 6);
5739
5740   /* send it... */
5741   S (mp);
5742
5743   /* Wait for a reply... */
5744   W (ret);
5745   return ret;
5746 }
5747
5748 static int
5749 api_bond_create2 (vat_main_t * vam)
5750 {
5751   unformat_input_t *i = vam->input;
5752   vl_api_bond_create2_t *mp;
5753   u8 mac_address[6];
5754   u8 custom_mac = 0;
5755   int ret;
5756   u8 mode;
5757   u8 lb;
5758   u8 mode_is_set = 0;
5759   u32 id = ~0;
5760   u8 numa_only = 0;
5761   u8 gso = 0;
5762
5763   clib_memset (mac_address, 0, sizeof (mac_address));
5764   lb = BOND_LB_L2;
5765
5766   /* Parse args required to build the message */
5767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5768     {
5769       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5770         mode_is_set = 1;
5771       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5772                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5773         ;
5774       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5775                          mac_address))
5776         custom_mac = 1;
5777       else if (unformat (i, "numa-only"))
5778         numa_only = 1;
5779       else if (unformat (i, "gso"))
5780         gso = 1;
5781       else if (unformat (i, "id %u", &id))
5782         ;
5783       else
5784         break;
5785     }
5786
5787   if (mode_is_set == 0)
5788     {
5789       errmsg ("Missing bond mode. ");
5790       return -99;
5791     }
5792
5793   /* Construct the API message */
5794   M (BOND_CREATE2, mp);
5795
5796   mp->use_custom_mac = custom_mac;
5797
5798   mp->mode = htonl (mode);
5799   mp->lb = htonl (lb);
5800   mp->id = htonl (id);
5801   mp->numa_only = numa_only;
5802   mp->enable_gso = gso;
5803
5804   if (custom_mac)
5805     clib_memcpy (mp->mac_address, mac_address, 6);
5806
5807   /* send it... */
5808   S (mp);
5809
5810   /* Wait for a reply... */
5811   W (ret);
5812   return ret;
5813 }
5814
5815 static int
5816 api_bond_delete (vat_main_t * vam)
5817 {
5818   unformat_input_t *i = vam->input;
5819   vl_api_bond_delete_t *mp;
5820   u32 sw_if_index = ~0;
5821   u8 sw_if_index_set = 0;
5822   int ret;
5823
5824   /* Parse args required to build the message */
5825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5826     {
5827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5828         sw_if_index_set = 1;
5829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5830         sw_if_index_set = 1;
5831       else
5832         break;
5833     }
5834
5835   if (sw_if_index_set == 0)
5836     {
5837       errmsg ("missing vpp interface name. ");
5838       return -99;
5839     }
5840
5841   /* Construct the API message */
5842   M (BOND_DELETE, mp);
5843
5844   mp->sw_if_index = ntohl (sw_if_index);
5845
5846   /* send it... */
5847   S (mp);
5848
5849   /* Wait for a reply... */
5850   W (ret);
5851   return ret;
5852 }
5853
5854 static int
5855 api_bond_add_member (vat_main_t * vam)
5856 {
5857   unformat_input_t *i = vam->input;
5858   vl_api_bond_add_member_t *mp;
5859   u32 bond_sw_if_index;
5860   int ret;
5861   u8 is_passive;
5862   u8 is_long_timeout;
5863   u32 bond_sw_if_index_is_set = 0;
5864   u32 sw_if_index;
5865   u8 sw_if_index_is_set = 0;
5866
5867   /* Parse args required to build the message */
5868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5869     {
5870       if (unformat (i, "sw_if_index %d", &sw_if_index))
5871         sw_if_index_is_set = 1;
5872       else if (unformat (i, "bond %u", &bond_sw_if_index))
5873         bond_sw_if_index_is_set = 1;
5874       else if (unformat (i, "passive %d", &is_passive))
5875         ;
5876       else if (unformat (i, "long-timeout %d", &is_long_timeout))
5877         ;
5878       else
5879         break;
5880     }
5881
5882   if (bond_sw_if_index_is_set == 0)
5883     {
5884       errmsg ("Missing bond sw_if_index. ");
5885       return -99;
5886     }
5887   if (sw_if_index_is_set == 0)
5888     {
5889       errmsg ("Missing member sw_if_index. ");
5890       return -99;
5891     }
5892
5893   /* Construct the API message */
5894   M (BOND_ADD_MEMBER, mp);
5895
5896   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5897   mp->sw_if_index = ntohl (sw_if_index);
5898   mp->is_long_timeout = is_long_timeout;
5899   mp->is_passive = is_passive;
5900
5901   /* send it... */
5902   S (mp);
5903
5904   /* Wait for a reply... */
5905   W (ret);
5906   return ret;
5907 }
5908
5909 static int
5910 api_bond_detach_member (vat_main_t * vam)
5911 {
5912   unformat_input_t *i = vam->input;
5913   vl_api_bond_detach_member_t *mp;
5914   u32 sw_if_index = ~0;
5915   u8 sw_if_index_set = 0;
5916   int ret;
5917
5918   /* Parse args required to build the message */
5919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5920     {
5921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5922         sw_if_index_set = 1;
5923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5924         sw_if_index_set = 1;
5925       else
5926         break;
5927     }
5928
5929   if (sw_if_index_set == 0)
5930     {
5931       errmsg ("missing vpp interface name. ");
5932       return -99;
5933     }
5934
5935   /* Construct the API message */
5936   M (BOND_DETACH_MEMBER, mp);
5937
5938   mp->sw_if_index = ntohl (sw_if_index);
5939
5940   /* send it... */
5941   S (mp);
5942
5943   /* Wait for a reply... */
5944   W (ret);
5945   return ret;
5946 }
5947
5948 static int
5949 api_ip_table_add_del (vat_main_t * vam)
5950 {
5951   unformat_input_t *i = vam->input;
5952   vl_api_ip_table_add_del_t *mp;
5953   u32 table_id = ~0;
5954   u8 is_ipv6 = 0;
5955   u8 is_add = 1;
5956   int ret = 0;
5957
5958   /* Parse args required to build the message */
5959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5960     {
5961       if (unformat (i, "ipv6"))
5962         is_ipv6 = 1;
5963       else if (unformat (i, "del"))
5964         is_add = 0;
5965       else if (unformat (i, "add"))
5966         is_add = 1;
5967       else if (unformat (i, "table %d", &table_id))
5968         ;
5969       else
5970         {
5971           clib_warning ("parse error '%U'", format_unformat_error, i);
5972           return -99;
5973         }
5974     }
5975
5976   if (~0 == table_id)
5977     {
5978       errmsg ("missing table-ID");
5979       return -99;
5980     }
5981
5982   /* Construct the API message */
5983   M (IP_TABLE_ADD_DEL, mp);
5984
5985   mp->table.table_id = ntohl (table_id);
5986   mp->table.is_ip6 = is_ipv6;
5987   mp->is_add = is_add;
5988
5989   /* send it... */
5990   S (mp);
5991
5992   /* Wait for a reply... */
5993   W (ret);
5994
5995   return ret;
5996 }
5997
5998 uword
5999 unformat_fib_path (unformat_input_t * input, va_list * args)
6000 {
6001   vat_main_t *vam = va_arg (*args, vat_main_t *);
6002   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6003   u32 weight, preference;
6004   mpls_label_t out_label;
6005
6006   clib_memset (path, 0, sizeof (*path));
6007   path->weight = 1;
6008   path->sw_if_index = ~0;
6009   path->rpf_id = ~0;
6010   path->n_labels = 0;
6011
6012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6013     {
6014       if (unformat (input, "%U %U",
6015                     unformat_vl_api_ip4_address,
6016                     &path->nh.address.ip4,
6017                     api_unformat_sw_if_index, vam, &path->sw_if_index))
6018         {
6019           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6020         }
6021       else if (unformat (input, "%U %U",
6022                          unformat_vl_api_ip6_address,
6023                          &path->nh.address.ip6,
6024                          api_unformat_sw_if_index, vam, &path->sw_if_index))
6025         {
6026           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6027         }
6028       else if (unformat (input, "weight %u", &weight))
6029         {
6030           path->weight = weight;
6031         }
6032       else if (unformat (input, "preference %u", &preference))
6033         {
6034           path->preference = preference;
6035         }
6036       else if (unformat (input, "%U next-hop-table %d",
6037                          unformat_vl_api_ip4_address,
6038                          &path->nh.address.ip4, &path->table_id))
6039         {
6040           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6041         }
6042       else if (unformat (input, "%U next-hop-table %d",
6043                          unformat_vl_api_ip6_address,
6044                          &path->nh.address.ip6, &path->table_id))
6045         {
6046           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6047         }
6048       else if (unformat (input, "%U",
6049                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
6050         {
6051           /*
6052            * the recursive next-hops are by default in the default table
6053            */
6054           path->table_id = 0;
6055           path->sw_if_index = ~0;
6056           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6057         }
6058       else if (unformat (input, "%U",
6059                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
6060         {
6061           /*
6062            * the recursive next-hops are by default in the default table
6063            */
6064           path->table_id = 0;
6065           path->sw_if_index = ~0;
6066           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6067         }
6068       else if (unformat (input, "resolve-via-host"))
6069         {
6070           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6071         }
6072       else if (unformat (input, "resolve-via-attached"))
6073         {
6074           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6075         }
6076       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6077         {
6078           path->type = FIB_API_PATH_TYPE_LOCAL;
6079           path->sw_if_index = ~0;
6080           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6081         }
6082       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6083         {
6084           path->type = FIB_API_PATH_TYPE_LOCAL;
6085           path->sw_if_index = ~0;
6086           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6087         }
6088       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6089         ;
6090       else if (unformat (input, "via-label %d", &path->nh.via_label))
6091         {
6092           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6093           path->sw_if_index = ~0;
6094         }
6095       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6096         {
6097           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6098           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6099         }
6100       else if (unformat (input, "local"))
6101         {
6102           path->type = FIB_API_PATH_TYPE_LOCAL;
6103         }
6104       else if (unformat (input, "out-labels"))
6105         {
6106           while (unformat (input, "%d", &out_label))
6107             {
6108               path->label_stack[path->n_labels].label = out_label;
6109               path->label_stack[path->n_labels].is_uniform = 0;
6110               path->label_stack[path->n_labels].ttl = 64;
6111               path->n_labels++;
6112             }
6113         }
6114       else if (unformat (input, "via"))
6115         {
6116           /* new path, back up and return */
6117           unformat_put_input (input);
6118           unformat_put_input (input);
6119           unformat_put_input (input);
6120           unformat_put_input (input);
6121           break;
6122         }
6123       else
6124         {
6125           return (0);
6126         }
6127     }
6128
6129   path->proto = ntohl (path->proto);
6130   path->type = ntohl (path->type);
6131   path->flags = ntohl (path->flags);
6132   path->table_id = ntohl (path->table_id);
6133   path->sw_if_index = ntohl (path->sw_if_index);
6134
6135   return (1);
6136 }
6137
6138 static int
6139 api_ip_route_add_del (vat_main_t * vam)
6140 {
6141   unformat_input_t *i = vam->input;
6142   vl_api_ip_route_add_del_t *mp;
6143   u32 vrf_id = 0;
6144   u8 is_add = 1;
6145   u8 is_multipath = 0;
6146   u8 prefix_set = 0;
6147   u8 path_count = 0;
6148   vl_api_prefix_t pfx = { };
6149   vl_api_fib_path_t paths[8];
6150   int count = 1;
6151   int j;
6152   f64 before = 0;
6153   u32 random_add_del = 0;
6154   u32 *random_vector = 0;
6155   u32 random_seed = 0xdeaddabe;
6156
6157   /* Parse args required to build the message */
6158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6159     {
6160       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6161         prefix_set = 1;
6162       else if (unformat (i, "del"))
6163         is_add = 0;
6164       else if (unformat (i, "add"))
6165         is_add = 1;
6166       else if (unformat (i, "vrf %d", &vrf_id))
6167         ;
6168       else if (unformat (i, "count %d", &count))
6169         ;
6170       else if (unformat (i, "random"))
6171         random_add_del = 1;
6172       else if (unformat (i, "multipath"))
6173         is_multipath = 1;
6174       else if (unformat (i, "seed %d", &random_seed))
6175         ;
6176       else
6177         if (unformat
6178             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6179         {
6180           path_count++;
6181           if (8 == path_count)
6182             {
6183               errmsg ("max 8 paths");
6184               return -99;
6185             }
6186         }
6187       else
6188         {
6189           clib_warning ("parse error '%U'", format_unformat_error, i);
6190           return -99;
6191         }
6192     }
6193
6194   if (!path_count)
6195     {
6196       errmsg ("specify a path; via ...");
6197       return -99;
6198     }
6199   if (prefix_set == 0)
6200     {
6201       errmsg ("missing prefix");
6202       return -99;
6203     }
6204
6205   /* Generate a pile of unique, random routes */
6206   if (random_add_del)
6207     {
6208       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
6209       u32 this_random_address;
6210       uword *random_hash;
6211
6212       random_hash = hash_create (count, sizeof (uword));
6213
6214       hash_set (random_hash, i->as_u32, 1);
6215       for (j = 0; j <= count; j++)
6216         {
6217           do
6218             {
6219               this_random_address = random_u32 (&random_seed);
6220               this_random_address =
6221                 clib_host_to_net_u32 (this_random_address);
6222             }
6223           while (hash_get (random_hash, this_random_address));
6224           vec_add1 (random_vector, this_random_address);
6225           hash_set (random_hash, this_random_address, 1);
6226         }
6227       hash_free (random_hash);
6228       set_ip4_address (&pfx.address, random_vector[0]);
6229     }
6230
6231   if (count > 1)
6232     {
6233       /* Turn on async mode */
6234       vam->async_mode = 1;
6235       vam->async_errors = 0;
6236       before = vat_time_now (vam);
6237     }
6238
6239   for (j = 0; j < count; j++)
6240     {
6241       /* Construct the API message */
6242       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6243
6244       mp->is_add = is_add;
6245       mp->is_multipath = is_multipath;
6246
6247       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6248       mp->route.table_id = ntohl (vrf_id);
6249       mp->route.n_paths = path_count;
6250
6251       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6252
6253       if (random_add_del)
6254         set_ip4_address (&pfx.address, random_vector[j + 1]);
6255       else
6256         increment_address (&pfx.address);
6257       /* send it... */
6258       S (mp);
6259       /* If we receive SIGTERM, stop now... */
6260       if (vam->do_exit)
6261         break;
6262     }
6263
6264   /* When testing multiple add/del ops, use a control-ping to sync */
6265   if (count > 1)
6266     {
6267       vl_api_control_ping_t *mp_ping;
6268       f64 after;
6269       f64 timeout;
6270
6271       /* Shut off async mode */
6272       vam->async_mode = 0;
6273
6274       MPING (CONTROL_PING, mp_ping);
6275       S (mp_ping);
6276
6277       timeout = vat_time_now (vam) + 1.0;
6278       while (vat_time_now (vam) < timeout)
6279         if (vam->result_ready == 1)
6280           goto out;
6281       vam->retval = -99;
6282
6283     out:
6284       if (vam->retval == -99)
6285         errmsg ("timeout");
6286
6287       if (vam->async_errors > 0)
6288         {
6289           errmsg ("%d asynchronous errors", vam->async_errors);
6290           vam->retval = -98;
6291         }
6292       vam->async_errors = 0;
6293       after = vat_time_now (vam);
6294
6295       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6296       if (j > 0)
6297         count = j;
6298
6299       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6300              count, after - before, count / (after - before));
6301     }
6302   else
6303     {
6304       int ret;
6305
6306       /* Wait for a reply... */
6307       W (ret);
6308       return ret;
6309     }
6310
6311   /* Return the good/bad news */
6312   return (vam->retval);
6313 }
6314
6315 static int
6316 api_ip_mroute_add_del (vat_main_t * vam)
6317 {
6318   unformat_input_t *i = vam->input;
6319   u8 path_set = 0, prefix_set = 0, is_add = 1;
6320   vl_api_ip_mroute_add_del_t *mp;
6321   mfib_entry_flags_t eflags = 0;
6322   vl_api_mfib_path_t path;
6323   vl_api_mprefix_t pfx = { };
6324   u32 vrf_id = 0;
6325   int ret;
6326
6327   /* Parse args required to build the message */
6328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6329     {
6330       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
6331         {
6332           prefix_set = 1;
6333           pfx.grp_address_length = htons (pfx.grp_address_length);
6334         }
6335       else if (unformat (i, "del"))
6336         is_add = 0;
6337       else if (unformat (i, "add"))
6338         is_add = 1;
6339       else if (unformat (i, "vrf %d", &vrf_id))
6340         ;
6341       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6342         path.itf_flags = htonl (path.itf_flags);
6343       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6344         ;
6345       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6346         path_set = 1;
6347       else
6348         {
6349           clib_warning ("parse error '%U'", format_unformat_error, i);
6350           return -99;
6351         }
6352     }
6353
6354   if (prefix_set == 0)
6355     {
6356       errmsg ("missing addresses\n");
6357       return -99;
6358     }
6359   if (path_set == 0)
6360     {
6361       errmsg ("missing path\n");
6362       return -99;
6363     }
6364
6365   /* Construct the API message */
6366   M (IP_MROUTE_ADD_DEL, mp);
6367
6368   mp->is_add = is_add;
6369   mp->is_multipath = 1;
6370
6371   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6372   mp->route.table_id = htonl (vrf_id);
6373   mp->route.n_paths = 1;
6374   mp->route.entry_flags = htonl (eflags);
6375
6376   clib_memcpy (&mp->route.paths, &path, sizeof (path));
6377
6378   /* send it... */
6379   S (mp);
6380   /* Wait for a reply... */
6381   W (ret);
6382   return ret;
6383 }
6384
6385 static int
6386 api_mpls_table_add_del (vat_main_t * vam)
6387 {
6388   unformat_input_t *i = vam->input;
6389   vl_api_mpls_table_add_del_t *mp;
6390   u32 table_id = ~0;
6391   u8 is_add = 1;
6392   int ret = 0;
6393
6394   /* Parse args required to build the message */
6395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6396     {
6397       if (unformat (i, "table %d", &table_id))
6398         ;
6399       else if (unformat (i, "del"))
6400         is_add = 0;
6401       else if (unformat (i, "add"))
6402         is_add = 1;
6403       else
6404         {
6405           clib_warning ("parse error '%U'", format_unformat_error, i);
6406           return -99;
6407         }
6408     }
6409
6410   if (~0 == table_id)
6411     {
6412       errmsg ("missing table-ID");
6413       return -99;
6414     }
6415
6416   /* Construct the API message */
6417   M (MPLS_TABLE_ADD_DEL, mp);
6418
6419   mp->mt_table.mt_table_id = ntohl (table_id);
6420   mp->mt_is_add = is_add;
6421
6422   /* send it... */
6423   S (mp);
6424
6425   /* Wait for a reply... */
6426   W (ret);
6427
6428   return ret;
6429 }
6430
6431 static int
6432 api_mpls_route_add_del (vat_main_t * vam)
6433 {
6434   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6435   mpls_label_t local_label = MPLS_LABEL_INVALID;
6436   unformat_input_t *i = vam->input;
6437   vl_api_mpls_route_add_del_t *mp;
6438   vl_api_fib_path_t paths[8];
6439   int count = 1, j;
6440   f64 before = 0;
6441
6442   /* Parse args required to build the message */
6443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6444     {
6445       if (unformat (i, "%d", &local_label))
6446         ;
6447       else if (unformat (i, "eos"))
6448         is_eos = 1;
6449       else if (unformat (i, "non-eos"))
6450         is_eos = 0;
6451       else if (unformat (i, "del"))
6452         is_add = 0;
6453       else if (unformat (i, "add"))
6454         is_add = 1;
6455       else if (unformat (i, "multipath"))
6456         is_multipath = 1;
6457       else if (unformat (i, "count %d", &count))
6458         ;
6459       else
6460         if (unformat
6461             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6462         {
6463           path_count++;
6464           if (8 == path_count)
6465             {
6466               errmsg ("max 8 paths");
6467               return -99;
6468             }
6469         }
6470       else
6471         {
6472           clib_warning ("parse error '%U'", format_unformat_error, i);
6473           return -99;
6474         }
6475     }
6476
6477   if (!path_count)
6478     {
6479       errmsg ("specify a path; via ...");
6480       return -99;
6481     }
6482
6483   if (MPLS_LABEL_INVALID == local_label)
6484     {
6485       errmsg ("missing label");
6486       return -99;
6487     }
6488
6489   if (count > 1)
6490     {
6491       /* Turn on async mode */
6492       vam->async_mode = 1;
6493       vam->async_errors = 0;
6494       before = vat_time_now (vam);
6495     }
6496
6497   for (j = 0; j < count; j++)
6498     {
6499       /* Construct the API message */
6500       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6501
6502       mp->mr_is_add = is_add;
6503       mp->mr_is_multipath = is_multipath;
6504
6505       mp->mr_route.mr_label = local_label;
6506       mp->mr_route.mr_eos = is_eos;
6507       mp->mr_route.mr_table_id = 0;
6508       mp->mr_route.mr_n_paths = path_count;
6509
6510       clib_memcpy (&mp->mr_route.mr_paths, paths,
6511                    sizeof (paths[0]) * path_count);
6512
6513       local_label++;
6514
6515       /* send it... */
6516       S (mp);
6517       /* If we receive SIGTERM, stop now... */
6518       if (vam->do_exit)
6519         break;
6520     }
6521
6522   /* When testing multiple add/del ops, use a control-ping to sync */
6523   if (count > 1)
6524     {
6525       vl_api_control_ping_t *mp_ping;
6526       f64 after;
6527       f64 timeout;
6528
6529       /* Shut off async mode */
6530       vam->async_mode = 0;
6531
6532       MPING (CONTROL_PING, mp_ping);
6533       S (mp_ping);
6534
6535       timeout = vat_time_now (vam) + 1.0;
6536       while (vat_time_now (vam) < timeout)
6537         if (vam->result_ready == 1)
6538           goto out;
6539       vam->retval = -99;
6540
6541     out:
6542       if (vam->retval == -99)
6543         errmsg ("timeout");
6544
6545       if (vam->async_errors > 0)
6546         {
6547           errmsg ("%d asynchronous errors", vam->async_errors);
6548           vam->retval = -98;
6549         }
6550       vam->async_errors = 0;
6551       after = vat_time_now (vam);
6552
6553       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6554       if (j > 0)
6555         count = j;
6556
6557       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6558              count, after - before, count / (after - before));
6559     }
6560   else
6561     {
6562       int ret;
6563
6564       /* Wait for a reply... */
6565       W (ret);
6566       return ret;
6567     }
6568
6569   /* Return the good/bad news */
6570   return (vam->retval);
6571   return (0);
6572 }
6573
6574 static int
6575 api_mpls_ip_bind_unbind (vat_main_t * vam)
6576 {
6577   unformat_input_t *i = vam->input;
6578   vl_api_mpls_ip_bind_unbind_t *mp;
6579   u32 ip_table_id = 0;
6580   u8 is_bind = 1;
6581   vl_api_prefix_t pfx;
6582   u8 prefix_set = 0;
6583   mpls_label_t local_label = MPLS_LABEL_INVALID;
6584   int ret;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6590         prefix_set = 1;
6591       else if (unformat (i, "%d", &local_label))
6592         ;
6593       else if (unformat (i, "table-id %d", &ip_table_id))
6594         ;
6595       else if (unformat (i, "unbind"))
6596         is_bind = 0;
6597       else if (unformat (i, "bind"))
6598         is_bind = 1;
6599       else
6600         {
6601           clib_warning ("parse error '%U'", format_unformat_error, i);
6602           return -99;
6603         }
6604     }
6605
6606   if (!prefix_set)
6607     {
6608       errmsg ("IP prefix not set");
6609       return -99;
6610     }
6611
6612   if (MPLS_LABEL_INVALID == local_label)
6613     {
6614       errmsg ("missing label");
6615       return -99;
6616     }
6617
6618   /* Construct the API message */
6619   M (MPLS_IP_BIND_UNBIND, mp);
6620
6621   mp->mb_is_bind = is_bind;
6622   mp->mb_ip_table_id = ntohl (ip_table_id);
6623   mp->mb_mpls_table_id = 0;
6624   mp->mb_label = ntohl (local_label);
6625   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
6626
6627   /* send it... */
6628   S (mp);
6629
6630   /* Wait for a reply... */
6631   W (ret);
6632   return ret;
6633   return (0);
6634 }
6635
6636 static int
6637 api_sr_mpls_policy_add (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_sr_mpls_policy_add_t *mp;
6641   u32 bsid = 0;
6642   u32 weight = 1;
6643   u8 type = 0;
6644   u8 n_segments = 0;
6645   u32 sid;
6646   u32 *segments = NULL;
6647   int ret;
6648
6649   /* Parse args required to build the message */
6650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6651     {
6652       if (unformat (i, "bsid %d", &bsid))
6653         ;
6654       else if (unformat (i, "weight %d", &weight))
6655         ;
6656       else if (unformat (i, "spray"))
6657         type = 1;
6658       else if (unformat (i, "next %d", &sid))
6659         {
6660           n_segments += 1;
6661           vec_add1 (segments, htonl (sid));
6662         }
6663       else
6664         {
6665           clib_warning ("parse error '%U'", format_unformat_error, i);
6666           return -99;
6667         }
6668     }
6669
6670   if (bsid == 0)
6671     {
6672       errmsg ("bsid not set");
6673       return -99;
6674     }
6675
6676   if (n_segments == 0)
6677     {
6678       errmsg ("no sid in segment stack");
6679       return -99;
6680     }
6681
6682   /* Construct the API message */
6683   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6684
6685   mp->bsid = htonl (bsid);
6686   mp->weight = htonl (weight);
6687   mp->is_spray = type;
6688   mp->n_segments = n_segments;
6689   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6690   vec_free (segments);
6691
6692   /* send it... */
6693   S (mp);
6694
6695   /* Wait for a reply... */
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_sr_mpls_policy_del (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sr_mpls_policy_del_t *mp;
6705   u32 bsid = 0;
6706   int ret;
6707
6708   /* Parse args required to build the message */
6709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6710     {
6711       if (unformat (i, "bsid %d", &bsid))
6712         ;
6713       else
6714         {
6715           clib_warning ("parse error '%U'", format_unformat_error, i);
6716           return -99;
6717         }
6718     }
6719
6720   if (bsid == 0)
6721     {
6722       errmsg ("bsid not set");
6723       return -99;
6724     }
6725
6726   /* Construct the API message */
6727   M (SR_MPLS_POLICY_DEL, mp);
6728
6729   mp->bsid = htonl (bsid);
6730
6731   /* send it... */
6732   S (mp);
6733
6734   /* Wait for a reply... */
6735   W (ret);
6736   return ret;
6737 }
6738
6739 static int
6740 api_mpls_tunnel_add_del (vat_main_t * vam)
6741 {
6742   unformat_input_t *i = vam->input;
6743   vl_api_mpls_tunnel_add_del_t *mp;
6744
6745   vl_api_fib_path_t paths[8];
6746   u32 sw_if_index = ~0;
6747   u8 path_count = 0;
6748   u8 l2_only = 0;
6749   u8 is_add = 1;
6750   int ret;
6751
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "add"))
6755         is_add = 1;
6756       else
6757         if (unformat
6758             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6759         is_add = 0;
6760       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6761         is_add = 0;
6762       else if (unformat (i, "l2-only"))
6763         l2_only = 1;
6764       else
6765         if (unformat
6766             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6767         {
6768           path_count++;
6769           if (8 == path_count)
6770             {
6771               errmsg ("max 8 paths");
6772               return -99;
6773             }
6774         }
6775       else
6776         {
6777           clib_warning ("parse error '%U'", format_unformat_error, i);
6778           return -99;
6779         }
6780     }
6781
6782   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6783
6784   mp->mt_is_add = is_add;
6785   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6786   mp->mt_tunnel.mt_l2_only = l2_only;
6787   mp->mt_tunnel.mt_is_multicast = 0;
6788   mp->mt_tunnel.mt_n_paths = path_count;
6789
6790   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6791                sizeof (paths[0]) * path_count);
6792
6793   S (mp);
6794   W (ret);
6795   return ret;
6796 }
6797
6798 static int
6799 api_sw_interface_set_unnumbered (vat_main_t * vam)
6800 {
6801   unformat_input_t *i = vam->input;
6802   vl_api_sw_interface_set_unnumbered_t *mp;
6803   u32 sw_if_index;
6804   u32 unnum_sw_index = ~0;
6805   u8 is_add = 1;
6806   u8 sw_if_index_set = 0;
6807   int ret;
6808
6809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6810     {
6811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6812         sw_if_index_set = 1;
6813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6814         sw_if_index_set = 1;
6815       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6816         ;
6817       else if (unformat (i, "del"))
6818         is_add = 0;
6819       else
6820         {
6821           clib_warning ("parse error '%U'", format_unformat_error, i);
6822           return -99;
6823         }
6824     }
6825
6826   if (sw_if_index_set == 0)
6827     {
6828       errmsg ("missing interface name or sw_if_index");
6829       return -99;
6830     }
6831
6832   M (SW_INTERFACE_SET_UNNUMBERED, mp);
6833
6834   mp->sw_if_index = ntohl (sw_if_index);
6835   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6836   mp->is_add = is_add;
6837
6838   S (mp);
6839   W (ret);
6840   return ret;
6841 }
6842
6843
6844 static int
6845 api_create_vlan_subif (vat_main_t * vam)
6846 {
6847   unformat_input_t *i = vam->input;
6848   vl_api_create_vlan_subif_t *mp;
6849   u32 sw_if_index;
6850   u8 sw_if_index_set = 0;
6851   u32 vlan_id;
6852   u8 vlan_id_set = 0;
6853   int ret;
6854
6855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6856     {
6857       if (unformat (i, "sw_if_index %d", &sw_if_index))
6858         sw_if_index_set = 1;
6859       else
6860         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6861         sw_if_index_set = 1;
6862       else if (unformat (i, "vlan %d", &vlan_id))
6863         vlan_id_set = 1;
6864       else
6865         {
6866           clib_warning ("parse error '%U'", format_unformat_error, i);
6867           return -99;
6868         }
6869     }
6870
6871   if (sw_if_index_set == 0)
6872     {
6873       errmsg ("missing interface name or sw_if_index");
6874       return -99;
6875     }
6876
6877   if (vlan_id_set == 0)
6878     {
6879       errmsg ("missing vlan_id");
6880       return -99;
6881     }
6882   M (CREATE_VLAN_SUBIF, mp);
6883
6884   mp->sw_if_index = ntohl (sw_if_index);
6885   mp->vlan_id = ntohl (vlan_id);
6886
6887   S (mp);
6888   W (ret);
6889   return ret;
6890 }
6891
6892 #define foreach_create_subif_bit                \
6893 _(no_tags)                                      \
6894 _(one_tag)                                      \
6895 _(two_tags)                                     \
6896 _(dot1ad)                                       \
6897 _(exact_match)                                  \
6898 _(default_sub)                                  \
6899 _(outer_vlan_id_any)                            \
6900 _(inner_vlan_id_any)
6901
6902 #define foreach_create_subif_flag               \
6903 _(0, "no_tags")                                 \
6904 _(1, "one_tag")                                 \
6905 _(2, "two_tags")                                \
6906 _(3, "dot1ad")                                  \
6907 _(4, "exact_match")                             \
6908 _(5, "default_sub")                             \
6909 _(6, "outer_vlan_id_any")                       \
6910 _(7, "inner_vlan_id_any")
6911
6912 static int
6913 api_create_subif (vat_main_t * vam)
6914 {
6915   unformat_input_t *i = vam->input;
6916   vl_api_create_subif_t *mp;
6917   u32 sw_if_index;
6918   u8 sw_if_index_set = 0;
6919   u32 sub_id;
6920   u8 sub_id_set = 0;
6921   u32 __attribute__ ((unused)) no_tags = 0;
6922   u32 __attribute__ ((unused)) one_tag = 0;
6923   u32 __attribute__ ((unused)) two_tags = 0;
6924   u32 __attribute__ ((unused)) dot1ad = 0;
6925   u32 __attribute__ ((unused)) exact_match = 0;
6926   u32 __attribute__ ((unused)) default_sub = 0;
6927   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
6928   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
6929   u32 tmp;
6930   u16 outer_vlan_id = 0;
6931   u16 inner_vlan_id = 0;
6932   int ret;
6933
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "sw_if_index %d", &sw_if_index))
6937         sw_if_index_set = 1;
6938       else
6939         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6940         sw_if_index_set = 1;
6941       else if (unformat (i, "sub_id %d", &sub_id))
6942         sub_id_set = 1;
6943       else if (unformat (i, "outer_vlan_id %d", &tmp))
6944         outer_vlan_id = tmp;
6945       else if (unformat (i, "inner_vlan_id %d", &tmp))
6946         inner_vlan_id = tmp;
6947
6948 #define _(a) else if (unformat (i, #a)) a = 1 ;
6949       foreach_create_subif_bit
6950 #undef _
6951         else
6952         {
6953           clib_warning ("parse error '%U'", format_unformat_error, i);
6954           return -99;
6955         }
6956     }
6957
6958   if (sw_if_index_set == 0)
6959     {
6960       errmsg ("missing interface name or sw_if_index");
6961       return -99;
6962     }
6963
6964   if (sub_id_set == 0)
6965     {
6966       errmsg ("missing sub_id");
6967       return -99;
6968     }
6969   M (CREATE_SUBIF, mp);
6970
6971   mp->sw_if_index = ntohl (sw_if_index);
6972   mp->sub_id = ntohl (sub_id);
6973
6974 #define _(a,b) mp->sub_if_flags |= (1 << a);
6975   foreach_create_subif_flag;
6976 #undef _
6977
6978   mp->outer_vlan_id = ntohs (outer_vlan_id);
6979   mp->inner_vlan_id = ntohs (inner_vlan_id);
6980
6981   S (mp);
6982   W (ret);
6983   return ret;
6984 }
6985
6986 static int
6987 api_ip_table_replace_begin (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_ip_table_replace_begin_t *mp;
6991   u32 table_id = 0;
6992   u8 is_ipv6 = 0;
6993
6994   int ret;
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "table %d", &table_id))
6998         ;
6999       else if (unformat (i, "ipv6"))
7000         is_ipv6 = 1;
7001       else
7002         {
7003           clib_warning ("parse error '%U'", format_unformat_error, i);
7004           return -99;
7005         }
7006     }
7007
7008   M (IP_TABLE_REPLACE_BEGIN, mp);
7009
7010   mp->table.table_id = ntohl (table_id);
7011   mp->table.is_ip6 = is_ipv6;
7012
7013   S (mp);
7014   W (ret);
7015   return ret;
7016 }
7017
7018 static int
7019 api_ip_table_flush (vat_main_t * vam)
7020 {
7021   unformat_input_t *i = vam->input;
7022   vl_api_ip_table_flush_t *mp;
7023   u32 table_id = 0;
7024   u8 is_ipv6 = 0;
7025
7026   int ret;
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "table %d", &table_id))
7030         ;
7031       else if (unformat (i, "ipv6"))
7032         is_ipv6 = 1;
7033       else
7034         {
7035           clib_warning ("parse error '%U'", format_unformat_error, i);
7036           return -99;
7037         }
7038     }
7039
7040   M (IP_TABLE_FLUSH, mp);
7041
7042   mp->table.table_id = ntohl (table_id);
7043   mp->table.is_ip6 = is_ipv6;
7044
7045   S (mp);
7046   W (ret);
7047   return ret;
7048 }
7049
7050 static int
7051 api_ip_table_replace_end (vat_main_t * vam)
7052 {
7053   unformat_input_t *i = vam->input;
7054   vl_api_ip_table_replace_end_t *mp;
7055   u32 table_id = 0;
7056   u8 is_ipv6 = 0;
7057
7058   int ret;
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "table %d", &table_id))
7062         ;
7063       else if (unformat (i, "ipv6"))
7064         is_ipv6 = 1;
7065       else
7066         {
7067           clib_warning ("parse error '%U'", format_unformat_error, i);
7068           return -99;
7069         }
7070     }
7071
7072   M (IP_TABLE_REPLACE_END, mp);
7073
7074   mp->table.table_id = ntohl (table_id);
7075   mp->table.is_ip6 = is_ipv6;
7076
7077   S (mp);
7078   W (ret);
7079   return ret;
7080 }
7081
7082 static int
7083 api_set_ip_flow_hash (vat_main_t * vam)
7084 {
7085   unformat_input_t *i = vam->input;
7086   vl_api_set_ip_flow_hash_t *mp;
7087   u32 vrf_id = 0;
7088   u8 is_ipv6 = 0;
7089   u8 vrf_id_set = 0;
7090   u8 src = 0;
7091   u8 dst = 0;
7092   u8 sport = 0;
7093   u8 dport = 0;
7094   u8 proto = 0;
7095   u8 reverse = 0;
7096   int ret;
7097
7098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7099     {
7100       if (unformat (i, "vrf %d", &vrf_id))
7101         vrf_id_set = 1;
7102       else if (unformat (i, "ipv6"))
7103         is_ipv6 = 1;
7104       else if (unformat (i, "src"))
7105         src = 1;
7106       else if (unformat (i, "dst"))
7107         dst = 1;
7108       else if (unformat (i, "sport"))
7109         sport = 1;
7110       else if (unformat (i, "dport"))
7111         dport = 1;
7112       else if (unformat (i, "proto"))
7113         proto = 1;
7114       else if (unformat (i, "reverse"))
7115         reverse = 1;
7116
7117       else
7118         {
7119           clib_warning ("parse error '%U'", format_unformat_error, i);
7120           return -99;
7121         }
7122     }
7123
7124   if (vrf_id_set == 0)
7125     {
7126       errmsg ("missing vrf id");
7127       return -99;
7128     }
7129
7130   M (SET_IP_FLOW_HASH, mp);
7131   mp->src = src;
7132   mp->dst = dst;
7133   mp->sport = sport;
7134   mp->dport = dport;
7135   mp->proto = proto;
7136   mp->reverse = reverse;
7137   mp->vrf_id = ntohl (vrf_id);
7138   mp->is_ipv6 = is_ipv6;
7139
7140   S (mp);
7141   W (ret);
7142   return ret;
7143 }
7144
7145 static int
7146 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_sw_interface_ip6_enable_disable_t *mp;
7150   u32 sw_if_index;
7151   u8 sw_if_index_set = 0;
7152   u8 enable = 0;
7153   int ret;
7154
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7160         sw_if_index_set = 1;
7161       else if (unformat (i, "enable"))
7162         enable = 1;
7163       else if (unformat (i, "disable"))
7164         enable = 0;
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   if (sw_if_index_set == 0)
7173     {
7174       errmsg ("missing interface name or sw_if_index");
7175       return -99;
7176     }
7177
7178   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7179
7180   mp->sw_if_index = ntohl (sw_if_index);
7181   mp->enable = enable;
7182
7183   S (mp);
7184   W (ret);
7185   return ret;
7186 }
7187
7188
7189 static int
7190 api_l2_patch_add_del (vat_main_t * vam)
7191 {
7192   unformat_input_t *i = vam->input;
7193   vl_api_l2_patch_add_del_t *mp;
7194   u32 rx_sw_if_index;
7195   u8 rx_sw_if_index_set = 0;
7196   u32 tx_sw_if_index;
7197   u8 tx_sw_if_index_set = 0;
7198   u8 is_add = 1;
7199   int ret;
7200
7201   /* Parse args required to build the message */
7202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7203     {
7204       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7205         rx_sw_if_index_set = 1;
7206       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7207         tx_sw_if_index_set = 1;
7208       else if (unformat (i, "rx"))
7209         {
7210           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211             {
7212               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7213                             &rx_sw_if_index))
7214                 rx_sw_if_index_set = 1;
7215             }
7216           else
7217             break;
7218         }
7219       else if (unformat (i, "tx"))
7220         {
7221           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222             {
7223               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7224                             &tx_sw_if_index))
7225                 tx_sw_if_index_set = 1;
7226             }
7227           else
7228             break;
7229         }
7230       else if (unformat (i, "del"))
7231         is_add = 0;
7232       else
7233         break;
7234     }
7235
7236   if (rx_sw_if_index_set == 0)
7237     {
7238       errmsg ("missing rx interface name or rx_sw_if_index");
7239       return -99;
7240     }
7241
7242   if (tx_sw_if_index_set == 0)
7243     {
7244       errmsg ("missing tx interface name or tx_sw_if_index");
7245       return -99;
7246     }
7247
7248   M (L2_PATCH_ADD_DEL, mp);
7249
7250   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7251   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7252   mp->is_add = is_add;
7253
7254   S (mp);
7255   W (ret);
7256   return ret;
7257 }
7258
7259 u8 is_del;
7260 u8 localsid_addr[16];
7261 u8 end_psp;
7262 u8 behavior;
7263 u32 sw_if_index;
7264 u32 vlan_index;
7265 u32 fib_table;
7266 u8 nh_addr[16];
7267
7268 static int
7269 api_sr_localsid_add_del (vat_main_t * vam)
7270 {
7271   unformat_input_t *i = vam->input;
7272   vl_api_sr_localsid_add_del_t *mp;
7273
7274   u8 is_del;
7275   ip6_address_t localsid;
7276   u8 end_psp = 0;
7277   u8 behavior = ~0;
7278   u32 sw_if_index;
7279   u32 fib_table = ~(u32) 0;
7280   ip46_address_t nh_addr;
7281   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
7282
7283   bool nexthop_set = 0;
7284
7285   int ret;
7286
7287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7288     {
7289       if (unformat (i, "del"))
7290         is_del = 1;
7291       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
7292       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
7293         nexthop_set = 1;
7294       else if (unformat (i, "behavior %u", &behavior));
7295       else if (unformat (i, "sw_if_index %u", &sw_if_index));
7296       else if (unformat (i, "fib-table %u", &fib_table));
7297       else if (unformat (i, "end.psp %u", &behavior));
7298       else
7299         break;
7300     }
7301
7302   M (SR_LOCALSID_ADD_DEL, mp);
7303
7304   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
7305
7306   if (nexthop_set)
7307     {
7308       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
7309     }
7310   mp->behavior = behavior;
7311   mp->sw_if_index = ntohl (sw_if_index);
7312   mp->fib_table = ntohl (fib_table);
7313   mp->end_psp = end_psp;
7314   mp->is_del = is_del;
7315
7316   S (mp);
7317   W (ret);
7318   return ret;
7319 }
7320
7321 static int
7322 api_ioam_enable (vat_main_t * vam)
7323 {
7324   unformat_input_t *input = vam->input;
7325   vl_api_ioam_enable_t *mp;
7326   u32 id = 0;
7327   int has_trace_option = 0;
7328   int has_pot_option = 0;
7329   int has_seqno_option = 0;
7330   int has_analyse_option = 0;
7331   int ret;
7332
7333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7334     {
7335       if (unformat (input, "trace"))
7336         has_trace_option = 1;
7337       else if (unformat (input, "pot"))
7338         has_pot_option = 1;
7339       else if (unformat (input, "seqno"))
7340         has_seqno_option = 1;
7341       else if (unformat (input, "analyse"))
7342         has_analyse_option = 1;
7343       else
7344         break;
7345     }
7346   M (IOAM_ENABLE, mp);
7347   mp->id = htons (id);
7348   mp->seqno = has_seqno_option;
7349   mp->analyse = has_analyse_option;
7350   mp->pot_enable = has_pot_option;
7351   mp->trace_enable = has_trace_option;
7352
7353   S (mp);
7354   W (ret);
7355   return ret;
7356 }
7357
7358
7359 static int
7360 api_ioam_disable (vat_main_t * vam)
7361 {
7362   vl_api_ioam_disable_t *mp;
7363   int ret;
7364
7365   M (IOAM_DISABLE, mp);
7366   S (mp);
7367   W (ret);
7368   return ret;
7369 }
7370
7371 #define foreach_tcp_proto_field                 \
7372 _(src_port)                                     \
7373 _(dst_port)
7374
7375 #define foreach_udp_proto_field                 \
7376 _(src_port)                                     \
7377 _(dst_port)
7378
7379 #define foreach_ip4_proto_field                 \
7380 _(src_address)                                  \
7381 _(dst_address)                                  \
7382 _(tos)                                          \
7383 _(length)                                       \
7384 _(fragment_id)                                  \
7385 _(ttl)                                          \
7386 _(protocol)                                     \
7387 _(checksum)
7388
7389 typedef struct
7390 {
7391   u16 src_port, dst_port;
7392 } tcpudp_header_t;
7393
7394 #if VPP_API_TEST_BUILTIN == 0
7395 uword
7396 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7397 {
7398   u8 **maskp = va_arg (*args, u8 **);
7399   u8 *mask = 0;
7400   u8 found_something = 0;
7401   tcp_header_t *tcp;
7402
7403 #define _(a) u8 a=0;
7404   foreach_tcp_proto_field;
7405 #undef _
7406
7407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7408     {
7409       if (0);
7410 #define _(a) else if (unformat (input, #a)) a=1;
7411       foreach_tcp_proto_field
7412 #undef _
7413         else
7414         break;
7415     }
7416
7417 #define _(a) found_something += a;
7418   foreach_tcp_proto_field;
7419 #undef _
7420
7421   if (found_something == 0)
7422     return 0;
7423
7424   vec_validate (mask, sizeof (*tcp) - 1);
7425
7426   tcp = (tcp_header_t *) mask;
7427
7428 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
7429   foreach_tcp_proto_field;
7430 #undef _
7431
7432   *maskp = mask;
7433   return 1;
7434 }
7435
7436 uword
7437 unformat_udp_mask (unformat_input_t * input, va_list * args)
7438 {
7439   u8 **maskp = va_arg (*args, u8 **);
7440   u8 *mask = 0;
7441   u8 found_something = 0;
7442   udp_header_t *udp;
7443
7444 #define _(a) u8 a=0;
7445   foreach_udp_proto_field;
7446 #undef _
7447
7448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (0);
7451 #define _(a) else if (unformat (input, #a)) a=1;
7452       foreach_udp_proto_field
7453 #undef _
7454         else
7455         break;
7456     }
7457
7458 #define _(a) found_something += a;
7459   foreach_udp_proto_field;
7460 #undef _
7461
7462   if (found_something == 0)
7463     return 0;
7464
7465   vec_validate (mask, sizeof (*udp) - 1);
7466
7467   udp = (udp_header_t *) mask;
7468
7469 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
7470   foreach_udp_proto_field;
7471 #undef _
7472
7473   *maskp = mask;
7474   return 1;
7475 }
7476
7477 uword
7478 unformat_l4_mask (unformat_input_t * input, va_list * args)
7479 {
7480   u8 **maskp = va_arg (*args, u8 **);
7481   u16 src_port = 0, dst_port = 0;
7482   tcpudp_header_t *tcpudp;
7483
7484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7485     {
7486       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7487         return 1;
7488       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7489         return 1;
7490       else if (unformat (input, "src_port"))
7491         src_port = 0xFFFF;
7492       else if (unformat (input, "dst_port"))
7493         dst_port = 0xFFFF;
7494       else
7495         return 0;
7496     }
7497
7498   if (!src_port && !dst_port)
7499     return 0;
7500
7501   u8 *mask = 0;
7502   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7503
7504   tcpudp = (tcpudp_header_t *) mask;
7505   tcpudp->src_port = src_port;
7506   tcpudp->dst_port = dst_port;
7507
7508   *maskp = mask;
7509
7510   return 1;
7511 }
7512
7513 uword
7514 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7515 {
7516   u8 **maskp = va_arg (*args, u8 **);
7517   u8 *mask = 0;
7518   u8 found_something = 0;
7519   ip4_header_t *ip;
7520
7521 #define _(a) u8 a=0;
7522   foreach_ip4_proto_field;
7523 #undef _
7524   u8 version = 0;
7525   u8 hdr_length = 0;
7526
7527
7528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7529     {
7530       if (unformat (input, "version"))
7531         version = 1;
7532       else if (unformat (input, "hdr_length"))
7533         hdr_length = 1;
7534       else if (unformat (input, "src"))
7535         src_address = 1;
7536       else if (unformat (input, "dst"))
7537         dst_address = 1;
7538       else if (unformat (input, "proto"))
7539         protocol = 1;
7540
7541 #define _(a) else if (unformat (input, #a)) a=1;
7542       foreach_ip4_proto_field
7543 #undef _
7544         else
7545         break;
7546     }
7547
7548 #define _(a) found_something += a;
7549   foreach_ip4_proto_field;
7550 #undef _
7551
7552   if (found_something == 0)
7553     return 0;
7554
7555   vec_validate (mask, sizeof (*ip) - 1);
7556
7557   ip = (ip4_header_t *) mask;
7558
7559 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7560   foreach_ip4_proto_field;
7561 #undef _
7562
7563   ip->ip_version_and_header_length = 0;
7564
7565   if (version)
7566     ip->ip_version_and_header_length |= 0xF0;
7567
7568   if (hdr_length)
7569     ip->ip_version_and_header_length |= 0x0F;
7570
7571   *maskp = mask;
7572   return 1;
7573 }
7574
7575 #define foreach_ip6_proto_field                 \
7576 _(src_address)                                  \
7577 _(dst_address)                                  \
7578 _(payload_length)                               \
7579 _(hop_limit)                                    \
7580 _(protocol)
7581
7582 uword
7583 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7584 {
7585   u8 **maskp = va_arg (*args, u8 **);
7586   u8 *mask = 0;
7587   u8 found_something = 0;
7588   ip6_header_t *ip;
7589   u32 ip_version_traffic_class_and_flow_label;
7590
7591 #define _(a) u8 a=0;
7592   foreach_ip6_proto_field;
7593 #undef _
7594   u8 version = 0;
7595   u8 traffic_class = 0;
7596   u8 flow_label = 0;
7597
7598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7599     {
7600       if (unformat (input, "version"))
7601         version = 1;
7602       else if (unformat (input, "traffic-class"))
7603         traffic_class = 1;
7604       else if (unformat (input, "flow-label"))
7605         flow_label = 1;
7606       else if (unformat (input, "src"))
7607         src_address = 1;
7608       else if (unformat (input, "dst"))
7609         dst_address = 1;
7610       else if (unformat (input, "proto"))
7611         protocol = 1;
7612
7613 #define _(a) else if (unformat (input, #a)) a=1;
7614       foreach_ip6_proto_field
7615 #undef _
7616         else
7617         break;
7618     }
7619
7620 #define _(a) found_something += a;
7621   foreach_ip6_proto_field;
7622 #undef _
7623
7624   if (found_something == 0)
7625     return 0;
7626
7627   vec_validate (mask, sizeof (*ip) - 1);
7628
7629   ip = (ip6_header_t *) mask;
7630
7631 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7632   foreach_ip6_proto_field;
7633 #undef _
7634
7635   ip_version_traffic_class_and_flow_label = 0;
7636
7637   if (version)
7638     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7639
7640   if (traffic_class)
7641     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7642
7643   if (flow_label)
7644     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7645
7646   ip->ip_version_traffic_class_and_flow_label =
7647     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7648
7649   *maskp = mask;
7650   return 1;
7651 }
7652
7653 uword
7654 unformat_l3_mask (unformat_input_t * input, va_list * args)
7655 {
7656   u8 **maskp = va_arg (*args, u8 **);
7657
7658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7659     {
7660       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7661         return 1;
7662       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7663         return 1;
7664       else
7665         break;
7666     }
7667   return 0;
7668 }
7669
7670 uword
7671 unformat_l2_mask (unformat_input_t * input, va_list * args)
7672 {
7673   u8 **maskp = va_arg (*args, u8 **);
7674   u8 *mask = 0;
7675   u8 src = 0;
7676   u8 dst = 0;
7677   u8 proto = 0;
7678   u8 tag1 = 0;
7679   u8 tag2 = 0;
7680   u8 ignore_tag1 = 0;
7681   u8 ignore_tag2 = 0;
7682   u8 cos1 = 0;
7683   u8 cos2 = 0;
7684   u8 dot1q = 0;
7685   u8 dot1ad = 0;
7686   int len = 14;
7687
7688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7689     {
7690       if (unformat (input, "src"))
7691         src = 1;
7692       else if (unformat (input, "dst"))
7693         dst = 1;
7694       else if (unformat (input, "proto"))
7695         proto = 1;
7696       else if (unformat (input, "tag1"))
7697         tag1 = 1;
7698       else if (unformat (input, "tag2"))
7699         tag2 = 1;
7700       else if (unformat (input, "ignore-tag1"))
7701         ignore_tag1 = 1;
7702       else if (unformat (input, "ignore-tag2"))
7703         ignore_tag2 = 1;
7704       else if (unformat (input, "cos1"))
7705         cos1 = 1;
7706       else if (unformat (input, "cos2"))
7707         cos2 = 1;
7708       else if (unformat (input, "dot1q"))
7709         dot1q = 1;
7710       else if (unformat (input, "dot1ad"))
7711         dot1ad = 1;
7712       else
7713         break;
7714     }
7715   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7716        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7717     return 0;
7718
7719   if (tag1 || ignore_tag1 || cos1 || dot1q)
7720     len = 18;
7721   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7722     len = 22;
7723
7724   vec_validate (mask, len - 1);
7725
7726   if (dst)
7727     clib_memset (mask, 0xff, 6);
7728
7729   if (src)
7730     clib_memset (mask + 6, 0xff, 6);
7731
7732   if (tag2 || dot1ad)
7733     {
7734       /* inner vlan tag */
7735       if (tag2)
7736         {
7737           mask[19] = 0xff;
7738           mask[18] = 0x0f;
7739         }
7740       if (cos2)
7741         mask[18] |= 0xe0;
7742       if (proto)
7743         mask[21] = mask[20] = 0xff;
7744       if (tag1)
7745         {
7746           mask[15] = 0xff;
7747           mask[14] = 0x0f;
7748         }
7749       if (cos1)
7750         mask[14] |= 0xe0;
7751       *maskp = mask;
7752       return 1;
7753     }
7754   if (tag1 | dot1q)
7755     {
7756       if (tag1)
7757         {
7758           mask[15] = 0xff;
7759           mask[14] = 0x0f;
7760         }
7761       if (cos1)
7762         mask[14] |= 0xe0;
7763       if (proto)
7764         mask[16] = mask[17] = 0xff;
7765
7766       *maskp = mask;
7767       return 1;
7768     }
7769   if (cos2)
7770     mask[18] |= 0xe0;
7771   if (cos1)
7772     mask[14] |= 0xe0;
7773   if (proto)
7774     mask[12] = mask[13] = 0xff;
7775
7776   *maskp = mask;
7777   return 1;
7778 }
7779
7780 uword
7781 unformat_classify_mask (unformat_input_t * input, va_list * args)
7782 {
7783   u8 **maskp = va_arg (*args, u8 **);
7784   u32 *skipp = va_arg (*args, u32 *);
7785   u32 *matchp = va_arg (*args, u32 *);
7786   u32 match;
7787   u8 *mask = 0;
7788   u8 *l2 = 0;
7789   u8 *l3 = 0;
7790   u8 *l4 = 0;
7791   int i;
7792
7793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7794     {
7795       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7796         ;
7797       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7798         ;
7799       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7800         ;
7801       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7802         ;
7803       else
7804         break;
7805     }
7806
7807   if (l4 && !l3)
7808     {
7809       vec_free (mask);
7810       vec_free (l2);
7811       vec_free (l4);
7812       return 0;
7813     }
7814
7815   if (mask || l2 || l3 || l4)
7816     {
7817       if (l2 || l3 || l4)
7818         {
7819           /* "With a free Ethernet header in every package" */
7820           if (l2 == 0)
7821             vec_validate (l2, 13);
7822           mask = l2;
7823           if (vec_len (l3))
7824             {
7825               vec_append (mask, l3);
7826               vec_free (l3);
7827             }
7828           if (vec_len (l4))
7829             {
7830               vec_append (mask, l4);
7831               vec_free (l4);
7832             }
7833         }
7834
7835       /* Scan forward looking for the first significant mask octet */
7836       for (i = 0; i < vec_len (mask); i++)
7837         if (mask[i])
7838           break;
7839
7840       /* compute (skip, match) params */
7841       *skipp = i / sizeof (u32x4);
7842       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7843
7844       /* Pad mask to an even multiple of the vector size */
7845       while (vec_len (mask) % sizeof (u32x4))
7846         vec_add1 (mask, 0);
7847
7848       match = vec_len (mask) / sizeof (u32x4);
7849
7850       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7851         {
7852           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7853           if (*tmp || *(tmp + 1))
7854             break;
7855           match--;
7856         }
7857       if (match == 0)
7858         clib_warning ("BUG: match 0");
7859
7860       _vec_len (mask) = match * sizeof (u32x4);
7861
7862       *matchp = match;
7863       *maskp = mask;
7864
7865       return 1;
7866     }
7867
7868   return 0;
7869 }
7870 #endif /* VPP_API_TEST_BUILTIN */
7871
7872 #define foreach_l2_next                         \
7873 _(drop, DROP)                                   \
7874 _(ethernet, ETHERNET_INPUT)                     \
7875 _(ip4, IP4_INPUT)                               \
7876 _(ip6, IP6_INPUT)
7877
7878 uword
7879 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7880 {
7881   u32 *miss_next_indexp = va_arg (*args, u32 *);
7882   u32 next_index = 0;
7883   u32 tmp;
7884
7885 #define _(n,N) \
7886   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7887   foreach_l2_next;
7888 #undef _
7889
7890   if (unformat (input, "%d", &tmp))
7891     {
7892       next_index = tmp;
7893       goto out;
7894     }
7895
7896   return 0;
7897
7898 out:
7899   *miss_next_indexp = next_index;
7900   return 1;
7901 }
7902
7903 #define foreach_ip_next                         \
7904 _(drop, DROP)                                   \
7905 _(local, LOCAL)                                 \
7906 _(rewrite, REWRITE)
7907
7908 uword
7909 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
7910 {
7911   u32 *miss_next_indexp = va_arg (*args, u32 *);
7912   u32 next_index = 0;
7913   u32 tmp;
7914
7915 #define _(n,N) \
7916   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7917   foreach_ip_next;
7918 #undef _
7919
7920   if (unformat (input, "%d", &tmp))
7921     {
7922       next_index = tmp;
7923       goto out;
7924     }
7925
7926   return 0;
7927
7928 out:
7929   *miss_next_indexp = next_index;
7930   return 1;
7931 }
7932
7933 #define foreach_acl_next                        \
7934 _(deny, DENY)
7935
7936 uword
7937 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
7938 {
7939   u32 *miss_next_indexp = va_arg (*args, u32 *);
7940   u32 next_index = 0;
7941   u32 tmp;
7942
7943 #define _(n,N) \
7944   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7945   foreach_acl_next;
7946 #undef _
7947
7948   if (unformat (input, "permit"))
7949     {
7950       next_index = ~0;
7951       goto out;
7952     }
7953   else if (unformat (input, "%d", &tmp))
7954     {
7955       next_index = tmp;
7956       goto out;
7957     }
7958
7959   return 0;
7960
7961 out:
7962   *miss_next_indexp = next_index;
7963   return 1;
7964 }
7965
7966 uword
7967 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7968 {
7969   u32 *r = va_arg (*args, u32 *);
7970
7971   if (unformat (input, "conform-color"))
7972     *r = POLICE_CONFORM;
7973   else if (unformat (input, "exceed-color"))
7974     *r = POLICE_EXCEED;
7975   else
7976     return 0;
7977
7978   return 1;
7979 }
7980
7981 static int
7982 api_classify_add_del_table (vat_main_t * vam)
7983 {
7984   unformat_input_t *i = vam->input;
7985   vl_api_classify_add_del_table_t *mp;
7986
7987   u32 nbuckets = 2;
7988   u32 skip = ~0;
7989   u32 match = ~0;
7990   int is_add = 1;
7991   int del_chain = 0;
7992   u32 table_index = ~0;
7993   u32 next_table_index = ~0;
7994   u32 miss_next_index = ~0;
7995   u32 memory_size = 32 << 20;
7996   u8 *mask = 0;
7997   u32 current_data_flag = 0;
7998   int current_data_offset = 0;
7999   int ret;
8000
8001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8002     {
8003       if (unformat (i, "del"))
8004         is_add = 0;
8005       else if (unformat (i, "del-chain"))
8006         {
8007           is_add = 0;
8008           del_chain = 1;
8009         }
8010       else if (unformat (i, "buckets %d", &nbuckets))
8011         ;
8012       else if (unformat (i, "memory_size %d", &memory_size))
8013         ;
8014       else if (unformat (i, "skip %d", &skip))
8015         ;
8016       else if (unformat (i, "match %d", &match))
8017         ;
8018       else if (unformat (i, "table %d", &table_index))
8019         ;
8020       else if (unformat (i, "mask %U", unformat_classify_mask,
8021                          &mask, &skip, &match))
8022         ;
8023       else if (unformat (i, "next-table %d", &next_table_index))
8024         ;
8025       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8026                          &miss_next_index))
8027         ;
8028       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8029                          &miss_next_index))
8030         ;
8031       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
8032                          &miss_next_index))
8033         ;
8034       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8035         ;
8036       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8037         ;
8038       else
8039         break;
8040     }
8041
8042   if (is_add && mask == 0)
8043     {
8044       errmsg ("Mask required");
8045       return -99;
8046     }
8047
8048   if (is_add && skip == ~0)
8049     {
8050       errmsg ("skip count required");
8051       return -99;
8052     }
8053
8054   if (is_add && match == ~0)
8055     {
8056       errmsg ("match count required");
8057       return -99;
8058     }
8059
8060   if (!is_add && table_index == ~0)
8061     {
8062       errmsg ("table index required for delete");
8063       return -99;
8064     }
8065
8066   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
8067
8068   mp->is_add = is_add;
8069   mp->del_chain = del_chain;
8070   mp->table_index = ntohl (table_index);
8071   mp->nbuckets = ntohl (nbuckets);
8072   mp->memory_size = ntohl (memory_size);
8073   mp->skip_n_vectors = ntohl (skip);
8074   mp->match_n_vectors = ntohl (match);
8075   mp->next_table_index = ntohl (next_table_index);
8076   mp->miss_next_index = ntohl (miss_next_index);
8077   mp->current_data_flag = ntohl (current_data_flag);
8078   mp->current_data_offset = ntohl (current_data_offset);
8079   mp->mask_len = ntohl (vec_len (mask));
8080   clib_memcpy (mp->mask, mask, vec_len (mask));
8081
8082   vec_free (mask);
8083
8084   S (mp);
8085   W (ret);
8086   return ret;
8087 }
8088
8089 #if VPP_API_TEST_BUILTIN == 0
8090 uword
8091 unformat_l4_match (unformat_input_t * input, va_list * args)
8092 {
8093   u8 **matchp = va_arg (*args, u8 **);
8094
8095   u8 *proto_header = 0;
8096   int src_port = 0;
8097   int dst_port = 0;
8098
8099   tcpudp_header_t h;
8100
8101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8102     {
8103       if (unformat (input, "src_port %d", &src_port))
8104         ;
8105       else if (unformat (input, "dst_port %d", &dst_port))
8106         ;
8107       else
8108         return 0;
8109     }
8110
8111   h.src_port = clib_host_to_net_u16 (src_port);
8112   h.dst_port = clib_host_to_net_u16 (dst_port);
8113   vec_validate (proto_header, sizeof (h) - 1);
8114   memcpy (proto_header, &h, sizeof (h));
8115
8116   *matchp = proto_header;
8117
8118   return 1;
8119 }
8120
8121 uword
8122 unformat_ip4_match (unformat_input_t * input, va_list * args)
8123 {
8124   u8 **matchp = va_arg (*args, u8 **);
8125   u8 *match = 0;
8126   ip4_header_t *ip;
8127   int version = 0;
8128   u32 version_val;
8129   int hdr_length = 0;
8130   u32 hdr_length_val;
8131   int src = 0, dst = 0;
8132   ip4_address_t src_val, dst_val;
8133   int proto = 0;
8134   u32 proto_val;
8135   int tos = 0;
8136   u32 tos_val;
8137   int length = 0;
8138   u32 length_val;
8139   int fragment_id = 0;
8140   u32 fragment_id_val;
8141   int ttl = 0;
8142   int ttl_val;
8143   int checksum = 0;
8144   u32 checksum_val;
8145
8146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8147     {
8148       if (unformat (input, "version %d", &version_val))
8149         version = 1;
8150       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8151         hdr_length = 1;
8152       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8153         src = 1;
8154       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8155         dst = 1;
8156       else if (unformat (input, "proto %d", &proto_val))
8157         proto = 1;
8158       else if (unformat (input, "tos %d", &tos_val))
8159         tos = 1;
8160       else if (unformat (input, "length %d", &length_val))
8161         length = 1;
8162       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8163         fragment_id = 1;
8164       else if (unformat (input, "ttl %d", &ttl_val))
8165         ttl = 1;
8166       else if (unformat (input, "checksum %d", &checksum_val))
8167         checksum = 1;
8168       else
8169         break;
8170     }
8171
8172   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8173       + ttl + checksum == 0)
8174     return 0;
8175
8176   /*
8177    * Aligned because we use the real comparison functions
8178    */
8179   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8180
8181   ip = (ip4_header_t *) match;
8182
8183   /* These are realistically matched in practice */
8184   if (src)
8185     ip->src_address.as_u32 = src_val.as_u32;
8186
8187   if (dst)
8188     ip->dst_address.as_u32 = dst_val.as_u32;
8189
8190   if (proto)
8191     ip->protocol = proto_val;
8192
8193
8194   /* These are not, but they're included for completeness */
8195   if (version)
8196     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8197
8198   if (hdr_length)
8199     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8200
8201   if (tos)
8202     ip->tos = tos_val;
8203
8204   if (length)
8205     ip->length = clib_host_to_net_u16 (length_val);
8206
8207   if (ttl)
8208     ip->ttl = ttl_val;
8209
8210   if (checksum)
8211     ip->checksum = clib_host_to_net_u16 (checksum_val);
8212
8213   *matchp = match;
8214   return 1;
8215 }
8216
8217 uword
8218 unformat_ip6_match (unformat_input_t * input, va_list * args)
8219 {
8220   u8 **matchp = va_arg (*args, u8 **);
8221   u8 *match = 0;
8222   ip6_header_t *ip;
8223   int version = 0;
8224   u32 version_val;
8225   u8 traffic_class = 0;
8226   u32 traffic_class_val = 0;
8227   u8 flow_label = 0;
8228   u8 flow_label_val;
8229   int src = 0, dst = 0;
8230   ip6_address_t src_val, dst_val;
8231   int proto = 0;
8232   u32 proto_val;
8233   int payload_length = 0;
8234   u32 payload_length_val;
8235   int hop_limit = 0;
8236   int hop_limit_val;
8237   u32 ip_version_traffic_class_and_flow_label;
8238
8239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8240     {
8241       if (unformat (input, "version %d", &version_val))
8242         version = 1;
8243       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8244         traffic_class = 1;
8245       else if (unformat (input, "flow_label %d", &flow_label_val))
8246         flow_label = 1;
8247       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8248         src = 1;
8249       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8250         dst = 1;
8251       else if (unformat (input, "proto %d", &proto_val))
8252         proto = 1;
8253       else if (unformat (input, "payload_length %d", &payload_length_val))
8254         payload_length = 1;
8255       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8256         hop_limit = 1;
8257       else
8258         break;
8259     }
8260
8261   if (version + traffic_class + flow_label + src + dst + proto +
8262       payload_length + hop_limit == 0)
8263     return 0;
8264
8265   /*
8266    * Aligned because we use the real comparison functions
8267    */
8268   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8269
8270   ip = (ip6_header_t *) match;
8271
8272   if (src)
8273     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8274
8275   if (dst)
8276     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8277
8278   if (proto)
8279     ip->protocol = proto_val;
8280
8281   ip_version_traffic_class_and_flow_label = 0;
8282
8283   if (version)
8284     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8285
8286   if (traffic_class)
8287     ip_version_traffic_class_and_flow_label |=
8288       (traffic_class_val & 0xFF) << 20;
8289
8290   if (flow_label)
8291     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8292
8293   ip->ip_version_traffic_class_and_flow_label =
8294     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8295
8296   if (payload_length)
8297     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8298
8299   if (hop_limit)
8300     ip->hop_limit = hop_limit_val;
8301
8302   *matchp = match;
8303   return 1;
8304 }
8305
8306 uword
8307 unformat_l3_match (unformat_input_t * input, va_list * args)
8308 {
8309   u8 **matchp = va_arg (*args, u8 **);
8310
8311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8312     {
8313       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8314         return 1;
8315       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8316         return 1;
8317       else
8318         break;
8319     }
8320   return 0;
8321 }
8322
8323 uword
8324 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8325 {
8326   u8 *tagp = va_arg (*args, u8 *);
8327   u32 tag;
8328
8329   if (unformat (input, "%d", &tag))
8330     {
8331       tagp[0] = (tag >> 8) & 0x0F;
8332       tagp[1] = tag & 0xFF;
8333       return 1;
8334     }
8335
8336   return 0;
8337 }
8338
8339 uword
8340 unformat_l2_match (unformat_input_t * input, va_list * args)
8341 {
8342   u8 **matchp = va_arg (*args, u8 **);
8343   u8 *match = 0;
8344   u8 src = 0;
8345   u8 src_val[6];
8346   u8 dst = 0;
8347   u8 dst_val[6];
8348   u8 proto = 0;
8349   u16 proto_val;
8350   u8 tag1 = 0;
8351   u8 tag1_val[2];
8352   u8 tag2 = 0;
8353   u8 tag2_val[2];
8354   int len = 14;
8355   u8 ignore_tag1 = 0;
8356   u8 ignore_tag2 = 0;
8357   u8 cos1 = 0;
8358   u8 cos2 = 0;
8359   u32 cos1_val = 0;
8360   u32 cos2_val = 0;
8361
8362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8363     {
8364       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8365         src = 1;
8366       else
8367         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8368         dst = 1;
8369       else if (unformat (input, "proto %U",
8370                          unformat_ethernet_type_host_byte_order, &proto_val))
8371         proto = 1;
8372       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8373         tag1 = 1;
8374       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8375         tag2 = 1;
8376       else if (unformat (input, "ignore-tag1"))
8377         ignore_tag1 = 1;
8378       else if (unformat (input, "ignore-tag2"))
8379         ignore_tag2 = 1;
8380       else if (unformat (input, "cos1 %d", &cos1_val))
8381         cos1 = 1;
8382       else if (unformat (input, "cos2 %d", &cos2_val))
8383         cos2 = 1;
8384       else
8385         break;
8386     }
8387   if ((src + dst + proto + tag1 + tag2 +
8388        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8389     return 0;
8390
8391   if (tag1 || ignore_tag1 || cos1)
8392     len = 18;
8393   if (tag2 || ignore_tag2 || cos2)
8394     len = 22;
8395
8396   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8397
8398   if (dst)
8399     clib_memcpy (match, dst_val, 6);
8400
8401   if (src)
8402     clib_memcpy (match + 6, src_val, 6);
8403
8404   if (tag2)
8405     {
8406       /* inner vlan tag */
8407       match[19] = tag2_val[1];
8408       match[18] = tag2_val[0];
8409       if (cos2)
8410         match[18] |= (cos2_val & 0x7) << 5;
8411       if (proto)
8412         {
8413           match[21] = proto_val & 0xff;
8414           match[20] = proto_val >> 8;
8415         }
8416       if (tag1)
8417         {
8418           match[15] = tag1_val[1];
8419           match[14] = tag1_val[0];
8420         }
8421       if (cos1)
8422         match[14] |= (cos1_val & 0x7) << 5;
8423       *matchp = match;
8424       return 1;
8425     }
8426   if (tag1)
8427     {
8428       match[15] = tag1_val[1];
8429       match[14] = tag1_val[0];
8430       if (proto)
8431         {
8432           match[17] = proto_val & 0xff;
8433           match[16] = proto_val >> 8;
8434         }
8435       if (cos1)
8436         match[14] |= (cos1_val & 0x7) << 5;
8437
8438       *matchp = match;
8439       return 1;
8440     }
8441   if (cos2)
8442     match[18] |= (cos2_val & 0x7) << 5;
8443   if (cos1)
8444     match[14] |= (cos1_val & 0x7) << 5;
8445   if (proto)
8446     {
8447       match[13] = proto_val & 0xff;
8448       match[12] = proto_val >> 8;
8449     }
8450
8451   *matchp = match;
8452   return 1;
8453 }
8454
8455 uword
8456 unformat_qos_source (unformat_input_t * input, va_list * args)
8457 {
8458   int *qs = va_arg (*args, int *);
8459
8460   if (unformat (input, "ip"))
8461     *qs = QOS_SOURCE_IP;
8462   else if (unformat (input, "mpls"))
8463     *qs = QOS_SOURCE_MPLS;
8464   else if (unformat (input, "ext"))
8465     *qs = QOS_SOURCE_EXT;
8466   else if (unformat (input, "vlan"))
8467     *qs = QOS_SOURCE_VLAN;
8468   else
8469     return 0;
8470
8471   return 1;
8472 }
8473 #endif
8474
8475 uword
8476 api_unformat_classify_match (unformat_input_t * input, va_list * args)
8477 {
8478   u8 **matchp = va_arg (*args, u8 **);
8479   u32 skip_n_vectors = va_arg (*args, u32);
8480   u32 match_n_vectors = va_arg (*args, u32);
8481
8482   u8 *match = 0;
8483   u8 *l2 = 0;
8484   u8 *l3 = 0;
8485   u8 *l4 = 0;
8486
8487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (input, "hex %U", unformat_hex_string, &match))
8490         ;
8491       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8492         ;
8493       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8494         ;
8495       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8496         ;
8497       else
8498         break;
8499     }
8500
8501   if (l4 && !l3)
8502     {
8503       vec_free (match);
8504       vec_free (l2);
8505       vec_free (l4);
8506       return 0;
8507     }
8508
8509   if (match || l2 || l3 || l4)
8510     {
8511       if (l2 || l3 || l4)
8512         {
8513           /* "Win a free Ethernet header in every packet" */
8514           if (l2 == 0)
8515             vec_validate_aligned (l2, 13, sizeof (u32x4));
8516           match = l2;
8517           if (vec_len (l3))
8518             {
8519               vec_append_aligned (match, l3, sizeof (u32x4));
8520               vec_free (l3);
8521             }
8522           if (vec_len (l4))
8523             {
8524               vec_append_aligned (match, l4, sizeof (u32x4));
8525               vec_free (l4);
8526             }
8527         }
8528
8529       /* Make sure the vector is big enough even if key is all 0's */
8530       vec_validate_aligned
8531         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8532          sizeof (u32x4));
8533
8534       /* Set size, include skipped vectors */
8535       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8536
8537       *matchp = match;
8538
8539       return 1;
8540     }
8541
8542   return 0;
8543 }
8544
8545 static int
8546 api_classify_add_del_session (vat_main_t * vam)
8547 {
8548   unformat_input_t *i = vam->input;
8549   vl_api_classify_add_del_session_t *mp;
8550   int is_add = 1;
8551   u32 table_index = ~0;
8552   u32 hit_next_index = ~0;
8553   u32 opaque_index = ~0;
8554   u8 *match = 0;
8555   i32 advance = 0;
8556   u32 skip_n_vectors = 0;
8557   u32 match_n_vectors = 0;
8558   u32 action = 0;
8559   u32 metadata = 0;
8560   int ret;
8561
8562   /*
8563    * Warning: you have to supply skip_n and match_n
8564    * because the API client cant simply look at the classify
8565    * table object.
8566    */
8567
8568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (i, "del"))
8571         is_add = 0;
8572       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
8573                          &hit_next_index))
8574         ;
8575       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8576                          &hit_next_index))
8577         ;
8578       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
8579                          &hit_next_index))
8580         ;
8581       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8582         ;
8583       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8584         ;
8585       else if (unformat (i, "opaque-index %d", &opaque_index))
8586         ;
8587       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8588         ;
8589       else if (unformat (i, "match_n %d", &match_n_vectors))
8590         ;
8591       else if (unformat (i, "match %U", api_unformat_classify_match,
8592                          &match, skip_n_vectors, match_n_vectors))
8593         ;
8594       else if (unformat (i, "advance %d", &advance))
8595         ;
8596       else if (unformat (i, "table-index %d", &table_index))
8597         ;
8598       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8599         action = 1;
8600       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8601         action = 2;
8602       else if (unformat (i, "action %d", &action))
8603         ;
8604       else if (unformat (i, "metadata %d", &metadata))
8605         ;
8606       else
8607         break;
8608     }
8609
8610   if (table_index == ~0)
8611     {
8612       errmsg ("Table index required");
8613       return -99;
8614     }
8615
8616   if (is_add && match == 0)
8617     {
8618       errmsg ("Match value required");
8619       return -99;
8620     }
8621
8622   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
8623
8624   mp->is_add = is_add;
8625   mp->table_index = ntohl (table_index);
8626   mp->hit_next_index = ntohl (hit_next_index);
8627   mp->opaque_index = ntohl (opaque_index);
8628   mp->advance = ntohl (advance);
8629   mp->action = action;
8630   mp->metadata = ntohl (metadata);
8631   mp->match_len = ntohl (vec_len (match));
8632   clib_memcpy (mp->match, match, vec_len (match));
8633   vec_free (match);
8634
8635   S (mp);
8636   W (ret);
8637   return ret;
8638 }
8639
8640 static int
8641 api_classify_set_interface_ip_table (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_classify_set_interface_ip_table_t *mp;
8645   u32 sw_if_index;
8646   int sw_if_index_set;
8647   u32 table_index = ~0;
8648   u8 is_ipv6 = 0;
8649   int ret;
8650
8651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8652     {
8653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8654         sw_if_index_set = 1;
8655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8656         sw_if_index_set = 1;
8657       else if (unformat (i, "table %d", &table_index))
8658         ;
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (sw_if_index_set == 0)
8667     {
8668       errmsg ("missing interface name or sw_if_index");
8669       return -99;
8670     }
8671
8672
8673   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
8674
8675   mp->sw_if_index = ntohl (sw_if_index);
8676   mp->table_index = ntohl (table_index);
8677   mp->is_ipv6 = is_ipv6;
8678
8679   S (mp);
8680   W (ret);
8681   return ret;
8682 }
8683
8684 static int
8685 api_classify_set_interface_l2_tables (vat_main_t * vam)
8686 {
8687   unformat_input_t *i = vam->input;
8688   vl_api_classify_set_interface_l2_tables_t *mp;
8689   u32 sw_if_index;
8690   int sw_if_index_set;
8691   u32 ip4_table_index = ~0;
8692   u32 ip6_table_index = ~0;
8693   u32 other_table_index = ~0;
8694   u32 is_input = 1;
8695   int ret;
8696
8697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8698     {
8699       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8700         sw_if_index_set = 1;
8701       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8702         sw_if_index_set = 1;
8703       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8704         ;
8705       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8706         ;
8707       else if (unformat (i, "other-table %d", &other_table_index))
8708         ;
8709       else if (unformat (i, "is-input %d", &is_input))
8710         ;
8711       else
8712         {
8713           clib_warning ("parse error '%U'", format_unformat_error, i);
8714           return -99;
8715         }
8716     }
8717
8718   if (sw_if_index_set == 0)
8719     {
8720       errmsg ("missing interface name or sw_if_index");
8721       return -99;
8722     }
8723
8724
8725   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
8726
8727   mp->sw_if_index = ntohl (sw_if_index);
8728   mp->ip4_table_index = ntohl (ip4_table_index);
8729   mp->ip6_table_index = ntohl (ip6_table_index);
8730   mp->other_table_index = ntohl (other_table_index);
8731   mp->is_input = (u8) is_input;
8732
8733   S (mp);
8734   W (ret);
8735   return ret;
8736 }
8737
8738 static int
8739 api_set_ipfix_exporter (vat_main_t * vam)
8740 {
8741   unformat_input_t *i = vam->input;
8742   vl_api_set_ipfix_exporter_t *mp;
8743   ip4_address_t collector_address;
8744   u8 collector_address_set = 0;
8745   u32 collector_port = ~0;
8746   ip4_address_t src_address;
8747   u8 src_address_set = 0;
8748   u32 vrf_id = ~0;
8749   u32 path_mtu = ~0;
8750   u32 template_interval = ~0;
8751   u8 udp_checksum = 0;
8752   int ret;
8753
8754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8755     {
8756       if (unformat (i, "collector_address %U", unformat_ip4_address,
8757                     &collector_address))
8758         collector_address_set = 1;
8759       else if (unformat (i, "collector_port %d", &collector_port))
8760         ;
8761       else if (unformat (i, "src_address %U", unformat_ip4_address,
8762                          &src_address))
8763         src_address_set = 1;
8764       else if (unformat (i, "vrf_id %d", &vrf_id))
8765         ;
8766       else if (unformat (i, "path_mtu %d", &path_mtu))
8767         ;
8768       else if (unformat (i, "template_interval %d", &template_interval))
8769         ;
8770       else if (unformat (i, "udp_checksum"))
8771         udp_checksum = 1;
8772       else
8773         break;
8774     }
8775
8776   if (collector_address_set == 0)
8777     {
8778       errmsg ("collector_address required");
8779       return -99;
8780     }
8781
8782   if (src_address_set == 0)
8783     {
8784       errmsg ("src_address required");
8785       return -99;
8786     }
8787
8788   M (SET_IPFIX_EXPORTER, mp);
8789
8790   memcpy (mp->collector_address.un.ip4, collector_address.data,
8791           sizeof (collector_address.data));
8792   mp->collector_port = htons ((u16) collector_port);
8793   memcpy (mp->src_address.un.ip4, src_address.data,
8794           sizeof (src_address.data));
8795   mp->vrf_id = htonl (vrf_id);
8796   mp->path_mtu = htonl (path_mtu);
8797   mp->template_interval = htonl (template_interval);
8798   mp->udp_checksum = udp_checksum;
8799
8800   S (mp);
8801   W (ret);
8802   return ret;
8803 }
8804
8805 static int
8806 api_set_ipfix_classify_stream (vat_main_t * vam)
8807 {
8808   unformat_input_t *i = vam->input;
8809   vl_api_set_ipfix_classify_stream_t *mp;
8810   u32 domain_id = 0;
8811   u32 src_port = UDP_DST_PORT_ipfix;
8812   int ret;
8813
8814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8815     {
8816       if (unformat (i, "domain %d", &domain_id))
8817         ;
8818       else if (unformat (i, "src_port %d", &src_port))
8819         ;
8820       else
8821         {
8822           errmsg ("unknown input `%U'", format_unformat_error, i);
8823           return -99;
8824         }
8825     }
8826
8827   M (SET_IPFIX_CLASSIFY_STREAM, mp);
8828
8829   mp->domain_id = htonl (domain_id);
8830   mp->src_port = htons ((u16) src_port);
8831
8832   S (mp);
8833   W (ret);
8834   return ret;
8835 }
8836
8837 static int
8838 api_ipfix_classify_table_add_del (vat_main_t * vam)
8839 {
8840   unformat_input_t *i = vam->input;
8841   vl_api_ipfix_classify_table_add_del_t *mp;
8842   int is_add = -1;
8843   u32 classify_table_index = ~0;
8844   u8 ip_version = 0;
8845   u8 transport_protocol = 255;
8846   int ret;
8847
8848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8849     {
8850       if (unformat (i, "add"))
8851         is_add = 1;
8852       else if (unformat (i, "del"))
8853         is_add = 0;
8854       else if (unformat (i, "table %d", &classify_table_index))
8855         ;
8856       else if (unformat (i, "ip4"))
8857         ip_version = 4;
8858       else if (unformat (i, "ip6"))
8859         ip_version = 6;
8860       else if (unformat (i, "tcp"))
8861         transport_protocol = 6;
8862       else if (unformat (i, "udp"))
8863         transport_protocol = 17;
8864       else
8865         {
8866           errmsg ("unknown input `%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (is_add == -1)
8872     {
8873       errmsg ("expecting: add|del");
8874       return -99;
8875     }
8876   if (classify_table_index == ~0)
8877     {
8878       errmsg ("classifier table not specified");
8879       return -99;
8880     }
8881   if (ip_version == 0)
8882     {
8883       errmsg ("IP version not specified");
8884       return -99;
8885     }
8886
8887   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
8888
8889   mp->is_add = is_add;
8890   mp->table_id = htonl (classify_table_index);
8891   mp->ip_version = ip_version;
8892   mp->transport_protocol = transport_protocol;
8893
8894   S (mp);
8895   W (ret);
8896   return ret;
8897 }
8898
8899 static int
8900 api_get_node_index (vat_main_t * vam)
8901 {
8902   unformat_input_t *i = vam->input;
8903   vl_api_get_node_index_t *mp;
8904   u8 *name = 0;
8905   int ret;
8906
8907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8908     {
8909       if (unformat (i, "node %s", &name))
8910         ;
8911       else
8912         break;
8913     }
8914   if (name == 0)
8915     {
8916       errmsg ("node name required");
8917       return -99;
8918     }
8919   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8920     {
8921       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
8922       return -99;
8923     }
8924
8925   M (GET_NODE_INDEX, mp);
8926   clib_memcpy (mp->node_name, name, vec_len (name));
8927   vec_free (name);
8928
8929   S (mp);
8930   W (ret);
8931   return ret;
8932 }
8933
8934 static int
8935 api_get_next_index (vat_main_t * vam)
8936 {
8937   unformat_input_t *i = vam->input;
8938   vl_api_get_next_index_t *mp;
8939   u8 *node_name = 0, *next_node_name = 0;
8940   int ret;
8941
8942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (i, "node-name %s", &node_name))
8945         ;
8946       else if (unformat (i, "next-node-name %s", &next_node_name))
8947         break;
8948     }
8949
8950   if (node_name == 0)
8951     {
8952       errmsg ("node name required");
8953       return -99;
8954     }
8955   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8956     {
8957       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
8958       return -99;
8959     }
8960
8961   if (next_node_name == 0)
8962     {
8963       errmsg ("next node name required");
8964       return -99;
8965     }
8966   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8967     {
8968       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
8969       return -99;
8970     }
8971
8972   M (GET_NEXT_INDEX, mp);
8973   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8974   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8975   vec_free (node_name);
8976   vec_free (next_node_name);
8977
8978   S (mp);
8979   W (ret);
8980   return ret;
8981 }
8982
8983 static int
8984 api_add_node_next (vat_main_t * vam)
8985 {
8986   unformat_input_t *i = vam->input;
8987   vl_api_add_node_next_t *mp;
8988   u8 *name = 0;
8989   u8 *next = 0;
8990   int ret;
8991
8992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (i, "node %s", &name))
8995         ;
8996       else if (unformat (i, "next %s", &next))
8997         ;
8998       else
8999         break;
9000     }
9001   if (name == 0)
9002     {
9003       errmsg ("node name required");
9004       return -99;
9005     }
9006   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9007     {
9008       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9009       return -99;
9010     }
9011   if (next == 0)
9012     {
9013       errmsg ("next node required");
9014       return -99;
9015     }
9016   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9017     {
9018       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9019       return -99;
9020     }
9021
9022   M (ADD_NODE_NEXT, mp);
9023   clib_memcpy (mp->node_name, name, vec_len (name));
9024   clib_memcpy (mp->next_name, next, vec_len (next));
9025   vec_free (name);
9026   vec_free (next);
9027
9028   S (mp);
9029   W (ret);
9030   return ret;
9031 }
9032
9033 static void vl_api_sw_interface_tap_v2_details_t_handler
9034   (vl_api_sw_interface_tap_v2_details_t * mp)
9035 {
9036   vat_main_t *vam = &vat_main;
9037
9038   u8 *ip4 =
9039     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9040             mp->host_ip4_prefix.len);
9041   u8 *ip6 =
9042     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9043             mp->host_ip6_prefix.len);
9044
9045   print (vam->ofp,
9046          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
9047          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9048          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9049          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
9050          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
9051
9052   vec_free (ip4);
9053   vec_free (ip6);
9054 }
9055
9056 static void vl_api_sw_interface_tap_v2_details_t_handler_json
9057   (vl_api_sw_interface_tap_v2_details_t * mp)
9058 {
9059   vat_main_t *vam = &vat_main;
9060   vat_json_node_t *node = NULL;
9061
9062   if (VAT_JSON_ARRAY != vam->json_tree.type)
9063     {
9064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9065       vat_json_init_array (&vam->json_tree);
9066     }
9067   node = vat_json_array_add (&vam->json_tree);
9068
9069   vat_json_init_object (node);
9070   vat_json_object_add_uint (node, "id", ntohl (mp->id));
9071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9072   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
9073   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9074   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9075   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9076   vat_json_object_add_string_copy (node, "host_mac_addr",
9077                                    format (0, "%U", format_ethernet_address,
9078                                            &mp->host_mac_addr));
9079   vat_json_object_add_string_copy (node, "host_namespace",
9080                                    mp->host_namespace);
9081   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9082   vat_json_object_add_string_copy (node, "host_ip4_addr",
9083                                    format (0, "%U/%d", format_ip4_address,
9084                                            mp->host_ip4_prefix.address,
9085                                            mp->host_ip4_prefix.len));
9086   vat_json_object_add_string_copy (node, "host_ip6_prefix",
9087                                    format (0, "%U/%d", format_ip6_address,
9088                                            mp->host_ip6_prefix.address,
9089                                            mp->host_ip6_prefix.len));
9090
9091 }
9092
9093 static int
9094 api_sw_interface_tap_v2_dump (vat_main_t * vam)
9095 {
9096   vl_api_sw_interface_tap_v2_dump_t *mp;
9097   vl_api_control_ping_t *mp_ping;
9098   int ret;
9099
9100   print (vam->ofp,
9101          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9102          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9103          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9104          "host_ip6_addr");
9105
9106   /* Get list of tap interfaces */
9107   M (SW_INTERFACE_TAP_V2_DUMP, mp);
9108   S (mp);
9109
9110   /* Use a control ping for synchronization */
9111   MPING (CONTROL_PING, mp_ping);
9112   S (mp_ping);
9113
9114   W (ret);
9115   return ret;
9116 }
9117
9118 static void vl_api_sw_interface_virtio_pci_details_t_handler
9119   (vl_api_sw_interface_virtio_pci_details_t * mp)
9120 {
9121   vat_main_t *vam = &vat_main;
9122
9123   typedef union
9124   {
9125     struct
9126     {
9127       u16 domain;
9128       u8 bus;
9129       u8 slot:5;
9130       u8 function:3;
9131     };
9132     u32 as_u32;
9133   } pci_addr_t;
9134   pci_addr_t addr;
9135
9136   addr.domain = ntohs (mp->pci_addr.domain);
9137   addr.bus = mp->pci_addr.bus;
9138   addr.slot = mp->pci_addr.slot;
9139   addr.function = mp->pci_addr.function;
9140
9141   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9142                          addr.slot, addr.function);
9143
9144   print (vam->ofp,
9145          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9146          pci_addr, ntohl (mp->sw_if_index),
9147          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9148          format_ethernet_address, mp->mac_addr,
9149          clib_net_to_host_u64 (mp->features));
9150   vec_free (pci_addr);
9151 }
9152
9153 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9154   (vl_api_sw_interface_virtio_pci_details_t * mp)
9155 {
9156   vat_main_t *vam = &vat_main;
9157   vat_json_node_t *node = NULL;
9158   vlib_pci_addr_t pci_addr;
9159
9160   if (VAT_JSON_ARRAY != vam->json_tree.type)
9161     {
9162       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9163       vat_json_init_array (&vam->json_tree);
9164     }
9165   node = vat_json_array_add (&vam->json_tree);
9166
9167   pci_addr.domain = ntohs (mp->pci_addr.domain);
9168   pci_addr.bus = mp->pci_addr.bus;
9169   pci_addr.slot = mp->pci_addr.slot;
9170   pci_addr.function = mp->pci_addr.function;
9171
9172   vat_json_init_object (node);
9173   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
9174   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9175   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9176   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9177   vat_json_object_add_uint (node, "features",
9178                             clib_net_to_host_u64 (mp->features));
9179   vat_json_object_add_string_copy (node, "mac_addr",
9180                                    format (0, "%U", format_ethernet_address,
9181                                            &mp->mac_addr));
9182 }
9183
9184 static int
9185 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9186 {
9187   vl_api_sw_interface_virtio_pci_dump_t *mp;
9188   vl_api_control_ping_t *mp_ping;
9189   int ret;
9190
9191   print (vam->ofp,
9192          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9193          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9194          "mac_addr", "features");
9195
9196   /* Get list of tap interfaces */
9197   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9198   S (mp);
9199
9200   /* Use a control ping for synchronization */
9201   MPING (CONTROL_PING, mp_ping);
9202   S (mp_ping);
9203
9204   W (ret);
9205   return ret;
9206 }
9207
9208 static int
9209 api_vxlan_offload_rx (vat_main_t * vam)
9210 {
9211   unformat_input_t *line_input = vam->input;
9212   vl_api_vxlan_offload_rx_t *mp;
9213   u32 hw_if_index = ~0, rx_if_index = ~0;
9214   u8 is_add = 1;
9215   int ret;
9216
9217   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9218     {
9219       if (unformat (line_input, "del"))
9220         is_add = 0;
9221       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9222                          &hw_if_index))
9223         ;
9224       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9225         ;
9226       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9227                          &rx_if_index))
9228         ;
9229       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9230         ;
9231       else
9232         {
9233           errmsg ("parse error '%U'", format_unformat_error, line_input);
9234           return -99;
9235         }
9236     }
9237
9238   if (hw_if_index == ~0)
9239     {
9240       errmsg ("no hw interface");
9241       return -99;
9242     }
9243
9244   if (rx_if_index == ~0)
9245     {
9246       errmsg ("no rx tunnel");
9247       return -99;
9248     }
9249
9250   M (VXLAN_OFFLOAD_RX, mp);
9251
9252   mp->hw_if_index = ntohl (hw_if_index);
9253   mp->sw_if_index = ntohl (rx_if_index);
9254   mp->enable = is_add;
9255
9256   S (mp);
9257   W (ret);
9258   return ret;
9259 }
9260
9261 static uword unformat_vxlan_decap_next
9262   (unformat_input_t * input, va_list * args)
9263 {
9264   u32 *result = va_arg (*args, u32 *);
9265   u32 tmp;
9266
9267   if (unformat (input, "l2"))
9268     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9269   else if (unformat (input, "%d", &tmp))
9270     *result = tmp;
9271   else
9272     return 0;
9273   return 1;
9274 }
9275
9276 static int
9277 api_vxlan_add_del_tunnel (vat_main_t * vam)
9278 {
9279   unformat_input_t *line_input = vam->input;
9280   vl_api_vxlan_add_del_tunnel_t *mp;
9281   ip46_address_t src, dst;
9282   u8 is_add = 1;
9283   u8 ipv4_set = 0, ipv6_set = 0;
9284   u8 src_set = 0;
9285   u8 dst_set = 0;
9286   u8 grp_set = 0;
9287   u32 instance = ~0;
9288   u32 mcast_sw_if_index = ~0;
9289   u32 encap_vrf_id = 0;
9290   u32 decap_next_index = ~0;
9291   u32 vni = 0;
9292   int ret;
9293
9294   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
9295   clib_memset (&src, 0, sizeof src);
9296   clib_memset (&dst, 0, sizeof dst);
9297
9298   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (line_input, "del"))
9301         is_add = 0;
9302       else if (unformat (line_input, "instance %d", &instance))
9303         ;
9304       else
9305         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9306         {
9307           ipv4_set = 1;
9308           src_set = 1;
9309         }
9310       else
9311         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9312         {
9313           ipv4_set = 1;
9314           dst_set = 1;
9315         }
9316       else
9317         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9318         {
9319           ipv6_set = 1;
9320           src_set = 1;
9321         }
9322       else
9323         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9324         {
9325           ipv6_set = 1;
9326           dst_set = 1;
9327         }
9328       else if (unformat (line_input, "group %U %U",
9329                          unformat_ip4_address, &dst.ip4,
9330                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9331         {
9332           grp_set = dst_set = 1;
9333           ipv4_set = 1;
9334         }
9335       else if (unformat (line_input, "group %U",
9336                          unformat_ip4_address, &dst.ip4))
9337         {
9338           grp_set = dst_set = 1;
9339           ipv4_set = 1;
9340         }
9341       else if (unformat (line_input, "group %U %U",
9342                          unformat_ip6_address, &dst.ip6,
9343                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9344         {
9345           grp_set = dst_set = 1;
9346           ipv6_set = 1;
9347         }
9348       else if (unformat (line_input, "group %U",
9349                          unformat_ip6_address, &dst.ip6))
9350         {
9351           grp_set = dst_set = 1;
9352           ipv6_set = 1;
9353         }
9354       else
9355         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9356         ;
9357       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9358         ;
9359       else if (unformat (line_input, "decap-next %U",
9360                          unformat_vxlan_decap_next, &decap_next_index))
9361         ;
9362       else if (unformat (line_input, "vni %d", &vni))
9363         ;
9364       else
9365         {
9366           errmsg ("parse error '%U'", format_unformat_error, line_input);
9367           return -99;
9368         }
9369     }
9370
9371   if (src_set == 0)
9372     {
9373       errmsg ("tunnel src address not specified");
9374       return -99;
9375     }
9376   if (dst_set == 0)
9377     {
9378       errmsg ("tunnel dst address not specified");
9379       return -99;
9380     }
9381
9382   if (grp_set && !ip46_address_is_multicast (&dst))
9383     {
9384       errmsg ("tunnel group address not multicast");
9385       return -99;
9386     }
9387   if (grp_set && mcast_sw_if_index == ~0)
9388     {
9389       errmsg ("tunnel nonexistent multicast device");
9390       return -99;
9391     }
9392   if (grp_set == 0 && ip46_address_is_multicast (&dst))
9393     {
9394       errmsg ("tunnel dst address must be unicast");
9395       return -99;
9396     }
9397
9398
9399   if (ipv4_set && ipv6_set)
9400     {
9401       errmsg ("both IPv4 and IPv6 addresses specified");
9402       return -99;
9403     }
9404
9405   if ((vni == 0) || (vni >> 24))
9406     {
9407       errmsg ("vni not specified or out of range");
9408       return -99;
9409     }
9410
9411   M (VXLAN_ADD_DEL_TUNNEL, mp);
9412
9413   if (ipv6_set)
9414     {
9415       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9416       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
9417     }
9418   else
9419     {
9420       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9421       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
9422     }
9423   mp->src_address.af = ipv6_set;
9424   mp->dst_address.af = ipv6_set;
9425
9426   mp->instance = htonl (instance);
9427   mp->encap_vrf_id = ntohl (encap_vrf_id);
9428   mp->decap_next_index = ntohl (decap_next_index);
9429   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9430   mp->vni = ntohl (vni);
9431   mp->is_add = is_add;
9432
9433   S (mp);
9434   W (ret);
9435   return ret;
9436 }
9437
9438 static void vl_api_vxlan_tunnel_details_t_handler
9439   (vl_api_vxlan_tunnel_details_t * mp)
9440 {
9441   vat_main_t *vam = &vat_main;
9442   ip46_address_t src =
9443     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9444   ip46_address_t dst =
9445     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
9446
9447   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
9448          ntohl (mp->sw_if_index),
9449          ntohl (mp->instance),
9450          format_ip46_address, &src, IP46_TYPE_ANY,
9451          format_ip46_address, &dst, IP46_TYPE_ANY,
9452          ntohl (mp->encap_vrf_id),
9453          ntohl (mp->decap_next_index), ntohl (mp->vni),
9454          ntohl (mp->mcast_sw_if_index));
9455 }
9456
9457 static void vl_api_vxlan_tunnel_details_t_handler_json
9458   (vl_api_vxlan_tunnel_details_t * mp)
9459 {
9460   vat_main_t *vam = &vat_main;
9461   vat_json_node_t *node = NULL;
9462
9463   if (VAT_JSON_ARRAY != vam->json_tree.type)
9464     {
9465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9466       vat_json_init_array (&vam->json_tree);
9467     }
9468   node = vat_json_array_add (&vam->json_tree);
9469
9470   vat_json_init_object (node);
9471   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9472
9473   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9474
9475   if (mp->src_address.af)
9476     {
9477       struct in6_addr ip6;
9478
9479       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
9480       vat_json_object_add_ip6 (node, "src_address", ip6);
9481       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
9482       vat_json_object_add_ip6 (node, "dst_address", ip6);
9483     }
9484   else
9485     {
9486       struct in_addr ip4;
9487
9488       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
9489       vat_json_object_add_ip4 (node, "src_address", ip4);
9490       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
9491       vat_json_object_add_ip4 (node, "dst_address", ip4);
9492     }
9493   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9494   vat_json_object_add_uint (node, "decap_next_index",
9495                             ntohl (mp->decap_next_index));
9496   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9497   vat_json_object_add_uint (node, "mcast_sw_if_index",
9498                             ntohl (mp->mcast_sw_if_index));
9499 }
9500
9501 static int
9502 api_vxlan_tunnel_dump (vat_main_t * vam)
9503 {
9504   unformat_input_t *i = vam->input;
9505   vl_api_vxlan_tunnel_dump_t *mp;
9506   vl_api_control_ping_t *mp_ping;
9507   u32 sw_if_index;
9508   u8 sw_if_index_set = 0;
9509   int ret;
9510
9511   /* Parse args required to build the message */
9512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9513     {
9514       if (unformat (i, "sw_if_index %d", &sw_if_index))
9515         sw_if_index_set = 1;
9516       else
9517         break;
9518     }
9519
9520   if (sw_if_index_set == 0)
9521     {
9522       sw_if_index = ~0;
9523     }
9524
9525   if (!vam->json_output)
9526     {
9527       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9528              "sw_if_index", "instance", "src_address", "dst_address",
9529              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9530     }
9531
9532   /* Get list of vxlan-tunnel interfaces */
9533   M (VXLAN_TUNNEL_DUMP, mp);
9534
9535   mp->sw_if_index = htonl (sw_if_index);
9536
9537   S (mp);
9538
9539   /* Use a control ping for synchronization */
9540   MPING (CONTROL_PING, mp_ping);
9541   S (mp_ping);
9542
9543   W (ret);
9544   return ret;
9545 }
9546
9547 static int
9548 api_l2_fib_clear_table (vat_main_t * vam)
9549 {
9550 //  unformat_input_t * i = vam->input;
9551   vl_api_l2_fib_clear_table_t *mp;
9552   int ret;
9553
9554   M (L2_FIB_CLEAR_TABLE, mp);
9555
9556   S (mp);
9557   W (ret);
9558   return ret;
9559 }
9560
9561 static int
9562 api_l2_interface_efp_filter (vat_main_t * vam)
9563 {
9564   unformat_input_t *i = vam->input;
9565   vl_api_l2_interface_efp_filter_t *mp;
9566   u32 sw_if_index;
9567   u8 enable = 1;
9568   u8 sw_if_index_set = 0;
9569   int ret;
9570
9571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9572     {
9573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9574         sw_if_index_set = 1;
9575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9576         sw_if_index_set = 1;
9577       else if (unformat (i, "enable"))
9578         enable = 1;
9579       else if (unformat (i, "disable"))
9580         enable = 0;
9581       else
9582         {
9583           clib_warning ("parse error '%U'", format_unformat_error, i);
9584           return -99;
9585         }
9586     }
9587
9588   if (sw_if_index_set == 0)
9589     {
9590       errmsg ("missing sw_if_index");
9591       return -99;
9592     }
9593
9594   M (L2_INTERFACE_EFP_FILTER, mp);
9595
9596   mp->sw_if_index = ntohl (sw_if_index);
9597   mp->enable_disable = enable;
9598
9599   S (mp);
9600   W (ret);
9601   return ret;
9602 }
9603
9604 #define foreach_vtr_op                          \
9605 _("disable",  L2_VTR_DISABLED)                  \
9606 _("push-1",  L2_VTR_PUSH_1)                     \
9607 _("push-2",  L2_VTR_PUSH_2)                     \
9608 _("pop-1",  L2_VTR_POP_1)                       \
9609 _("pop-2",  L2_VTR_POP_2)                       \
9610 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9611 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9612 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9613 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9614
9615 static int
9616 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9617 {
9618   unformat_input_t *i = vam->input;
9619   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9620   u32 sw_if_index;
9621   u8 sw_if_index_set = 0;
9622   u8 vtr_op_set = 0;
9623   u32 vtr_op = 0;
9624   u32 push_dot1q = 1;
9625   u32 tag1 = ~0;
9626   u32 tag2 = ~0;
9627   int ret;
9628
9629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9630     {
9631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9632         sw_if_index_set = 1;
9633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9634         sw_if_index_set = 1;
9635       else if (unformat (i, "vtr_op %d", &vtr_op))
9636         vtr_op_set = 1;
9637 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9638       foreach_vtr_op
9639 #undef _
9640         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9641         ;
9642       else if (unformat (i, "tag1 %d", &tag1))
9643         ;
9644       else if (unformat (i, "tag2 %d", &tag2))
9645         ;
9646       else
9647         {
9648           clib_warning ("parse error '%U'", format_unformat_error, i);
9649           return -99;
9650         }
9651     }
9652
9653   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9654     {
9655       errmsg ("missing vtr operation or sw_if_index");
9656       return -99;
9657     }
9658
9659   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9660   mp->sw_if_index = ntohl (sw_if_index);
9661   mp->vtr_op = ntohl (vtr_op);
9662   mp->push_dot1q = ntohl (push_dot1q);
9663   mp->tag1 = ntohl (tag1);
9664   mp->tag2 = ntohl (tag2);
9665
9666   S (mp);
9667   W (ret);
9668   return ret;
9669 }
9670
9671 static int
9672 api_create_vhost_user_if (vat_main_t * vam)
9673 {
9674   unformat_input_t *i = vam->input;
9675   vl_api_create_vhost_user_if_t *mp;
9676   u8 *file_name;
9677   u8 is_server = 0;
9678   u8 file_name_set = 0;
9679   u32 custom_dev_instance = ~0;
9680   u8 hwaddr[6];
9681   u8 use_custom_mac = 0;
9682   u8 disable_mrg_rxbuf = 0;
9683   u8 disable_indirect_desc = 0;
9684   u8 *tag = 0;
9685   u8 enable_gso = 0;
9686   u8 enable_packed = 0;
9687   int ret;
9688
9689   /* Shut up coverity */
9690   clib_memset (hwaddr, 0, sizeof (hwaddr));
9691
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "socket %s", &file_name))
9695         {
9696           file_name_set = 1;
9697         }
9698       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9699         ;
9700       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9701         use_custom_mac = 1;
9702       else if (unformat (i, "server"))
9703         is_server = 1;
9704       else if (unformat (i, "disable_mrg_rxbuf"))
9705         disable_mrg_rxbuf = 1;
9706       else if (unformat (i, "disable_indirect_desc"))
9707         disable_indirect_desc = 1;
9708       else if (unformat (i, "gso"))
9709         enable_gso = 1;
9710       else if (unformat (i, "packed"))
9711         enable_packed = 1;
9712       else if (unformat (i, "tag %s", &tag))
9713         ;
9714       else
9715         break;
9716     }
9717
9718   if (file_name_set == 0)
9719     {
9720       errmsg ("missing socket file name");
9721       return -99;
9722     }
9723
9724   if (vec_len (file_name) > 255)
9725     {
9726       errmsg ("socket file name too long");
9727       return -99;
9728     }
9729   vec_add1 (file_name, 0);
9730
9731   M (CREATE_VHOST_USER_IF, mp);
9732
9733   mp->is_server = is_server;
9734   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9735   mp->disable_indirect_desc = disable_indirect_desc;
9736   mp->enable_gso = enable_gso;
9737   mp->enable_packed = enable_packed;
9738   mp->custom_dev_instance = ntohl (custom_dev_instance);
9739   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9740   vec_free (file_name);
9741   if (custom_dev_instance != ~0)
9742     mp->renumber = 1;
9743
9744   mp->use_custom_mac = use_custom_mac;
9745   clib_memcpy (mp->mac_address, hwaddr, 6);
9746   if (tag)
9747     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9748   vec_free (tag);
9749
9750   S (mp);
9751   W (ret);
9752   return ret;
9753 }
9754
9755 static int
9756 api_modify_vhost_user_if (vat_main_t * vam)
9757 {
9758   unformat_input_t *i = vam->input;
9759   vl_api_modify_vhost_user_if_t *mp;
9760   u8 *file_name;
9761   u8 is_server = 0;
9762   u8 file_name_set = 0;
9763   u32 custom_dev_instance = ~0;
9764   u8 sw_if_index_set = 0;
9765   u32 sw_if_index = (u32) ~ 0;
9766   u8 enable_gso = 0;
9767   u8 enable_packed = 0;
9768   int ret;
9769
9770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9771     {
9772       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9773         sw_if_index_set = 1;
9774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9775         sw_if_index_set = 1;
9776       else if (unformat (i, "socket %s", &file_name))
9777         {
9778           file_name_set = 1;
9779         }
9780       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9781         ;
9782       else if (unformat (i, "server"))
9783         is_server = 1;
9784       else if (unformat (i, "gso"))
9785         enable_gso = 1;
9786       else if (unformat (i, "packed"))
9787         enable_packed = 1;
9788       else
9789         break;
9790     }
9791
9792   if (sw_if_index_set == 0)
9793     {
9794       errmsg ("missing sw_if_index or interface name");
9795       return -99;
9796     }
9797
9798   if (file_name_set == 0)
9799     {
9800       errmsg ("missing socket file name");
9801       return -99;
9802     }
9803
9804   if (vec_len (file_name) > 255)
9805     {
9806       errmsg ("socket file name too long");
9807       return -99;
9808     }
9809   vec_add1 (file_name, 0);
9810
9811   M (MODIFY_VHOST_USER_IF, mp);
9812
9813   mp->sw_if_index = ntohl (sw_if_index);
9814   mp->is_server = is_server;
9815   mp->enable_gso = enable_gso;
9816   mp->enable_packed = enable_packed;
9817   mp->custom_dev_instance = ntohl (custom_dev_instance);
9818   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9819   vec_free (file_name);
9820   if (custom_dev_instance != ~0)
9821     mp->renumber = 1;
9822
9823   S (mp);
9824   W (ret);
9825   return ret;
9826 }
9827
9828 static int
9829 api_create_vhost_user_if_v2 (vat_main_t * vam)
9830 {
9831   unformat_input_t *i = vam->input;
9832   vl_api_create_vhost_user_if_v2_t *mp;
9833   u8 *file_name;
9834   u8 is_server = 0;
9835   u8 file_name_set = 0;
9836   u32 custom_dev_instance = ~0;
9837   u8 hwaddr[6];
9838   u8 use_custom_mac = 0;
9839   u8 disable_mrg_rxbuf = 0;
9840   u8 disable_indirect_desc = 0;
9841   u8 *tag = 0;
9842   u8 enable_gso = 0;
9843   u8 enable_packed = 0;
9844   u8 enable_event_idx = 0;
9845   int ret;
9846
9847   /* Shut up coverity */
9848   clib_memset (hwaddr, 0, sizeof (hwaddr));
9849
9850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9851     {
9852       if (unformat (i, "socket %s", &file_name))
9853         {
9854           file_name_set = 1;
9855         }
9856       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9857         ;
9858       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9859         use_custom_mac = 1;
9860       else if (unformat (i, "server"))
9861         is_server = 1;
9862       else if (unformat (i, "disable_mrg_rxbuf"))
9863         disable_mrg_rxbuf = 1;
9864       else if (unformat (i, "disable_indirect_desc"))
9865         disable_indirect_desc = 1;
9866       else if (unformat (i, "gso"))
9867         enable_gso = 1;
9868       else if (unformat (i, "packed"))
9869         enable_packed = 1;
9870       else if (unformat (i, "event-idx"))
9871         enable_event_idx = 1;
9872       else if (unformat (i, "tag %s", &tag))
9873         ;
9874       else
9875         break;
9876     }
9877
9878   if (file_name_set == 0)
9879     {
9880       errmsg ("missing socket file name");
9881       return -99;
9882     }
9883
9884   if (vec_len (file_name) > 255)
9885     {
9886       errmsg ("socket file name too long");
9887       return -99;
9888     }
9889   vec_add1 (file_name, 0);
9890
9891   M (CREATE_VHOST_USER_IF_V2, mp);
9892
9893   mp->is_server = is_server;
9894   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9895   mp->disable_indirect_desc = disable_indirect_desc;
9896   mp->enable_gso = enable_gso;
9897   mp->enable_packed = enable_packed;
9898   mp->enable_event_idx = enable_event_idx;
9899   mp->custom_dev_instance = ntohl (custom_dev_instance);
9900   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9901   vec_free (file_name);
9902   if (custom_dev_instance != ~0)
9903     mp->renumber = 1;
9904
9905   mp->use_custom_mac = use_custom_mac;
9906   clib_memcpy (mp->mac_address, hwaddr, 6);
9907   if (tag)
9908     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9909   vec_free (tag);
9910
9911   S (mp);
9912   W (ret);
9913   return ret;
9914 }
9915
9916 static int
9917 api_modify_vhost_user_if_v2 (vat_main_t * vam)
9918 {
9919   unformat_input_t *i = vam->input;
9920   vl_api_modify_vhost_user_if_v2_t *mp;
9921   u8 *file_name;
9922   u8 is_server = 0;
9923   u8 file_name_set = 0;
9924   u32 custom_dev_instance = ~0;
9925   u8 sw_if_index_set = 0;
9926   u32 sw_if_index = (u32) ~ 0;
9927   u8 enable_gso = 0;
9928   u8 enable_packed = 0;
9929   u8 enable_event_idx = 0;
9930   int ret;
9931
9932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9933     {
9934       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9935         sw_if_index_set = 1;
9936       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9937         sw_if_index_set = 1;
9938       else if (unformat (i, "socket %s", &file_name))
9939         {
9940           file_name_set = 1;
9941         }
9942       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9943         ;
9944       else if (unformat (i, "server"))
9945         is_server = 1;
9946       else if (unformat (i, "gso"))
9947         enable_gso = 1;
9948       else if (unformat (i, "packed"))
9949         enable_packed = 1;
9950       else if (unformat (i, "event-idx"))
9951         enable_event_idx = 1;
9952       else
9953         break;
9954     }
9955
9956   if (sw_if_index_set == 0)
9957     {
9958       errmsg ("missing sw_if_index or interface name");
9959       return -99;
9960     }
9961
9962   if (file_name_set == 0)
9963     {
9964       errmsg ("missing socket file name");
9965       return -99;
9966     }
9967
9968   if (vec_len (file_name) > 255)
9969     {
9970       errmsg ("socket file name too long");
9971       return -99;
9972     }
9973   vec_add1 (file_name, 0);
9974
9975   M (MODIFY_VHOST_USER_IF_V2, mp);
9976
9977   mp->sw_if_index = ntohl (sw_if_index);
9978   mp->is_server = is_server;
9979   mp->enable_gso = enable_gso;
9980   mp->enable_packed = enable_packed;
9981   mp->enable_event_idx = enable_event_idx;
9982   mp->custom_dev_instance = ntohl (custom_dev_instance);
9983   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9984   vec_free (file_name);
9985   if (custom_dev_instance != ~0)
9986     mp->renumber = 1;
9987
9988   S (mp);
9989   W (ret);
9990   return ret;
9991 }
9992
9993 static int
9994 api_delete_vhost_user_if (vat_main_t * vam)
9995 {
9996   unformat_input_t *i = vam->input;
9997   vl_api_delete_vhost_user_if_t *mp;
9998   u32 sw_if_index = ~0;
9999   u8 sw_if_index_set = 0;
10000   int ret;
10001
10002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10003     {
10004       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10005         sw_if_index_set = 1;
10006       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10007         sw_if_index_set = 1;
10008       else
10009         break;
10010     }
10011
10012   if (sw_if_index_set == 0)
10013     {
10014       errmsg ("missing sw_if_index or interface name");
10015       return -99;
10016     }
10017
10018
10019   M (DELETE_VHOST_USER_IF, mp);
10020
10021   mp->sw_if_index = ntohl (sw_if_index);
10022
10023   S (mp);
10024   W (ret);
10025   return ret;
10026 }
10027
10028 static void vl_api_sw_interface_vhost_user_details_t_handler
10029   (vl_api_sw_interface_vhost_user_details_t * mp)
10030 {
10031   vat_main_t *vam = &vat_main;
10032   u64 features;
10033
10034   features =
10035     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10036                                                     clib_net_to_host_u32
10037                                                     (mp->features_last_32) <<
10038                                                     32);
10039
10040   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %16llx %6d %7d %s",
10041          (char *) mp->interface_name, ntohl (mp->sw_if_index),
10042          ntohl (mp->virtio_net_hdr_sz), features, mp->is_server,
10043          ntohl (mp->num_regions), (char *) mp->sock_filename);
10044   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10045 }
10046
10047 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10048   (vl_api_sw_interface_vhost_user_details_t * mp)
10049 {
10050   vat_main_t *vam = &vat_main;
10051   vat_json_node_t *node = NULL;
10052
10053   if (VAT_JSON_ARRAY != vam->json_tree.type)
10054     {
10055       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10056       vat_json_init_array (&vam->json_tree);
10057     }
10058   node = vat_json_array_add (&vam->json_tree);
10059
10060   vat_json_init_object (node);
10061   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10062   vat_json_object_add_string_copy (node, "interface_name",
10063                                    mp->interface_name);
10064   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10065                             ntohl (mp->virtio_net_hdr_sz));
10066   vat_json_object_add_uint (node, "features_first_32",
10067                             clib_net_to_host_u32 (mp->features_first_32));
10068   vat_json_object_add_uint (node, "features_last_32",
10069                             clib_net_to_host_u32 (mp->features_last_32));
10070   vat_json_object_add_uint (node, "is_server", mp->is_server);
10071   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10072   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10073   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10074 }
10075
10076 static int
10077 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10078 {
10079   unformat_input_t *i = vam->input;
10080   vl_api_sw_interface_vhost_user_dump_t *mp;
10081   vl_api_control_ping_t *mp_ping;
10082   int ret;
10083   u32 sw_if_index = ~0;
10084
10085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10086     {
10087       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10088         ;
10089       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10090         ;
10091       else
10092         break;
10093     }
10094
10095   print (vam->ofp, "Interface name            idx hdr_sz         features "
10096                    "server regions filename");
10097
10098   /* Get list of vhost-user interfaces */
10099   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
10100   mp->sw_if_index = ntohl (sw_if_index);
10101   S (mp);
10102
10103   /* Use a control ping for synchronization */
10104   MPING (CONTROL_PING, mp_ping);
10105   S (mp_ping);
10106
10107   W (ret);
10108   return ret;
10109 }
10110
10111 static int
10112 api_show_version (vat_main_t * vam)
10113 {
10114   vl_api_show_version_t *mp;
10115   int ret;
10116
10117   M (SHOW_VERSION, mp);
10118
10119   S (mp);
10120   W (ret);
10121   return ret;
10122 }
10123
10124
10125 static int
10126 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10127 {
10128   unformat_input_t *line_input = vam->input;
10129   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10130   ip46_address_t local, remote;
10131   u8 is_add = 1;
10132   u8 local_set = 0;
10133   u8 remote_set = 0;
10134   u8 grp_set = 0;
10135   u32 mcast_sw_if_index = ~0;
10136   u32 encap_vrf_id = 0;
10137   u32 decap_vrf_id = 0;
10138   u8 protocol = ~0;
10139   u32 vni;
10140   u8 vni_set = 0;
10141   int ret;
10142
10143   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (line_input, "del"))
10146         is_add = 0;
10147       else if (unformat (line_input, "local %U",
10148                          unformat_ip46_address, &local))
10149         {
10150           local_set = 1;
10151         }
10152       else if (unformat (line_input, "remote %U",
10153                          unformat_ip46_address, &remote))
10154         {
10155           remote_set = 1;
10156         }
10157       else if (unformat (line_input, "group %U %U",
10158                          unformat_ip46_address, &remote,
10159                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10160         {
10161           grp_set = remote_set = 1;
10162         }
10163       else if (unformat (line_input, "group %U",
10164                          unformat_ip46_address, &remote))
10165         {
10166           grp_set = remote_set = 1;
10167         }
10168       else
10169         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10170         ;
10171       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10172         ;
10173       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10174         ;
10175       else if (unformat (line_input, "vni %d", &vni))
10176         vni_set = 1;
10177       else if (unformat (line_input, "next-ip4"))
10178         protocol = 1;
10179       else if (unformat (line_input, "next-ip6"))
10180         protocol = 2;
10181       else if (unformat (line_input, "next-ethernet"))
10182         protocol = 3;
10183       else if (unformat (line_input, "next-nsh"))
10184         protocol = 4;
10185       else
10186         {
10187           errmsg ("parse error '%U'", format_unformat_error, line_input);
10188           return -99;
10189         }
10190     }
10191
10192   if (local_set == 0)
10193     {
10194       errmsg ("tunnel local address not specified");
10195       return -99;
10196     }
10197   if (remote_set == 0)
10198     {
10199       errmsg ("tunnel remote address not specified");
10200       return -99;
10201     }
10202   if (grp_set && mcast_sw_if_index == ~0)
10203     {
10204       errmsg ("tunnel nonexistent multicast device");
10205       return -99;
10206     }
10207   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
10208     {
10209       errmsg ("both IPv4 and IPv6 addresses specified");
10210       return -99;
10211     }
10212
10213   if (vni_set == 0)
10214     {
10215       errmsg ("vni not specified");
10216       return -99;
10217     }
10218
10219   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
10220
10221   ip_address_encode (&local,
10222                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10223                      IP46_TYPE_IP6, &mp->local);
10224   ip_address_encode (&remote,
10225                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10226                      IP46_TYPE_IP6, &mp->remote);
10227
10228   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10229   mp->encap_vrf_id = ntohl (encap_vrf_id);
10230   mp->decap_vrf_id = ntohl (decap_vrf_id);
10231   mp->protocol = protocol;
10232   mp->vni = ntohl (vni);
10233   mp->is_add = is_add;
10234
10235   S (mp);
10236   W (ret);
10237   return ret;
10238 }
10239
10240 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10241   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10242 {
10243   vat_main_t *vam = &vat_main;
10244   ip46_address_t local, remote;
10245
10246   ip_address_decode (&mp->local, &local);
10247   ip_address_decode (&mp->remote, &remote);
10248
10249   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
10250          ntohl (mp->sw_if_index),
10251          format_ip46_address, &local, IP46_TYPE_ANY,
10252          format_ip46_address, &remote, IP46_TYPE_ANY,
10253          ntohl (mp->vni), mp->protocol,
10254          ntohl (mp->mcast_sw_if_index),
10255          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10256 }
10257
10258
10259 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10260   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10261 {
10262   vat_main_t *vam = &vat_main;
10263   vat_json_node_t *node = NULL;
10264   struct in_addr ip4;
10265   struct in6_addr ip6;
10266   ip46_address_t local, remote;
10267
10268   ip_address_decode (&mp->local, &local);
10269   ip_address_decode (&mp->remote, &remote);
10270
10271   if (VAT_JSON_ARRAY != vam->json_tree.type)
10272     {
10273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10274       vat_json_init_array (&vam->json_tree);
10275     }
10276   node = vat_json_array_add (&vam->json_tree);
10277
10278   vat_json_init_object (node);
10279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10280   if (ip46_address_is_ip4 (&local))
10281     {
10282       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10283       vat_json_object_add_ip4 (node, "local", ip4);
10284       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10285       vat_json_object_add_ip4 (node, "remote", ip4);
10286     }
10287   else
10288     {
10289       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10290       vat_json_object_add_ip6 (node, "local", ip6);
10291       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10292       vat_json_object_add_ip6 (node, "remote", ip6);
10293     }
10294   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10295   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10296   vat_json_object_add_uint (node, "mcast_sw_if_index",
10297                             ntohl (mp->mcast_sw_if_index));
10298   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10299   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10300   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10301 }
10302
10303 static int
10304 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10305 {
10306   unformat_input_t *i = vam->input;
10307   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10308   vl_api_control_ping_t *mp_ping;
10309   u32 sw_if_index;
10310   u8 sw_if_index_set = 0;
10311   int ret;
10312
10313   /* Parse args required to build the message */
10314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10315     {
10316       if (unformat (i, "sw_if_index %d", &sw_if_index))
10317         sw_if_index_set = 1;
10318       else
10319         break;
10320     }
10321
10322   if (sw_if_index_set == 0)
10323     {
10324       sw_if_index = ~0;
10325     }
10326
10327   if (!vam->json_output)
10328     {
10329       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
10330              "sw_if_index", "local", "remote", "vni",
10331              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
10332     }
10333
10334   /* Get list of vxlan-tunnel interfaces */
10335   M (VXLAN_GPE_TUNNEL_DUMP, mp);
10336
10337   mp->sw_if_index = htonl (sw_if_index);
10338
10339   S (mp);
10340
10341   /* Use a control ping for synchronization */
10342   MPING (CONTROL_PING, mp_ping);
10343   S (mp_ping);
10344
10345   W (ret);
10346   return ret;
10347 }
10348
10349 static void vl_api_l2_fib_table_details_t_handler
10350   (vl_api_l2_fib_table_details_t * mp)
10351 {
10352   vat_main_t *vam = &vat_main;
10353
10354   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10355          "       %d       %d     %d",
10356          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
10357          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10358          mp->bvi_mac);
10359 }
10360
10361 static void vl_api_l2_fib_table_details_t_handler_json
10362   (vl_api_l2_fib_table_details_t * mp)
10363 {
10364   vat_main_t *vam = &vat_main;
10365   vat_json_node_t *node = NULL;
10366
10367   if (VAT_JSON_ARRAY != vam->json_tree.type)
10368     {
10369       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10370       vat_json_init_array (&vam->json_tree);
10371     }
10372   node = vat_json_array_add (&vam->json_tree);
10373
10374   vat_json_init_object (node);
10375   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10376   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
10377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10378   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10379   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10380   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10381 }
10382
10383 static int
10384 api_l2_fib_table_dump (vat_main_t * vam)
10385 {
10386   unformat_input_t *i = vam->input;
10387   vl_api_l2_fib_table_dump_t *mp;
10388   vl_api_control_ping_t *mp_ping;
10389   u32 bd_id;
10390   u8 bd_id_set = 0;
10391   int ret;
10392
10393   /* Parse args required to build the message */
10394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10395     {
10396       if (unformat (i, "bd_id %d", &bd_id))
10397         bd_id_set = 1;
10398       else
10399         break;
10400     }
10401
10402   if (bd_id_set == 0)
10403     {
10404       errmsg ("missing bridge domain");
10405       return -99;
10406     }
10407
10408   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
10409
10410   /* Get list of l2 fib entries */
10411   M (L2_FIB_TABLE_DUMP, mp);
10412
10413   mp->bd_id = ntohl (bd_id);
10414   S (mp);
10415
10416   /* Use a control ping for synchronization */
10417   MPING (CONTROL_PING, mp_ping);
10418   S (mp_ping);
10419
10420   W (ret);
10421   return ret;
10422 }
10423
10424
10425 static int
10426 api_interface_name_renumber (vat_main_t * vam)
10427 {
10428   unformat_input_t *line_input = vam->input;
10429   vl_api_interface_name_renumber_t *mp;
10430   u32 sw_if_index = ~0;
10431   u32 new_show_dev_instance = ~0;
10432   int ret;
10433
10434   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10435     {
10436       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10437                     &sw_if_index))
10438         ;
10439       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10440         ;
10441       else if (unformat (line_input, "new_show_dev_instance %d",
10442                          &new_show_dev_instance))
10443         ;
10444       else
10445         break;
10446     }
10447
10448   if (sw_if_index == ~0)
10449     {
10450       errmsg ("missing interface name or sw_if_index");
10451       return -99;
10452     }
10453
10454   if (new_show_dev_instance == ~0)
10455     {
10456       errmsg ("missing new_show_dev_instance");
10457       return -99;
10458     }
10459
10460   M (INTERFACE_NAME_RENUMBER, mp);
10461
10462   mp->sw_if_index = ntohl (sw_if_index);
10463   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10464
10465   S (mp);
10466   W (ret);
10467   return ret;
10468 }
10469
10470 static int
10471 api_want_l2_macs_events (vat_main_t * vam)
10472 {
10473   unformat_input_t *line_input = vam->input;
10474   vl_api_want_l2_macs_events_t *mp;
10475   u8 enable_disable = 1;
10476   u32 scan_delay = 0;
10477   u32 max_macs_in_event = 0;
10478   u32 learn_limit = 0;
10479   int ret;
10480
10481   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10482     {
10483       if (unformat (line_input, "learn-limit %d", &learn_limit))
10484         ;
10485       else if (unformat (line_input, "scan-delay %d", &scan_delay))
10486         ;
10487       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10488         ;
10489       else if (unformat (line_input, "disable"))
10490         enable_disable = 0;
10491       else
10492         break;
10493     }
10494
10495   M (WANT_L2_MACS_EVENTS, mp);
10496   mp->enable_disable = enable_disable;
10497   mp->pid = htonl (getpid ());
10498   mp->learn_limit = htonl (learn_limit);
10499   mp->scan_delay = (u8) scan_delay;
10500   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10501   S (mp);
10502   W (ret);
10503   return ret;
10504 }
10505
10506 static int
10507 api_input_acl_set_interface (vat_main_t * vam)
10508 {
10509   unformat_input_t *i = vam->input;
10510   vl_api_input_acl_set_interface_t *mp;
10511   u32 sw_if_index;
10512   int sw_if_index_set;
10513   u32 ip4_table_index = ~0;
10514   u32 ip6_table_index = ~0;
10515   u32 l2_table_index = ~0;
10516   u8 is_add = 1;
10517   int ret;
10518
10519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10520     {
10521       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10522         sw_if_index_set = 1;
10523       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10524         sw_if_index_set = 1;
10525       else if (unformat (i, "del"))
10526         is_add = 0;
10527       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10528         ;
10529       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10530         ;
10531       else if (unformat (i, "l2-table %d", &l2_table_index))
10532         ;
10533       else
10534         {
10535           clib_warning ("parse error '%U'", format_unformat_error, i);
10536           return -99;
10537         }
10538     }
10539
10540   if (sw_if_index_set == 0)
10541     {
10542       errmsg ("missing interface name or sw_if_index");
10543       return -99;
10544     }
10545
10546   M (INPUT_ACL_SET_INTERFACE, mp);
10547
10548   mp->sw_if_index = ntohl (sw_if_index);
10549   mp->ip4_table_index = ntohl (ip4_table_index);
10550   mp->ip6_table_index = ntohl (ip6_table_index);
10551   mp->l2_table_index = ntohl (l2_table_index);
10552   mp->is_add = is_add;
10553
10554   S (mp);
10555   W (ret);
10556   return ret;
10557 }
10558
10559 static int
10560 api_output_acl_set_interface (vat_main_t * vam)
10561 {
10562   unformat_input_t *i = vam->input;
10563   vl_api_output_acl_set_interface_t *mp;
10564   u32 sw_if_index;
10565   int sw_if_index_set;
10566   u32 ip4_table_index = ~0;
10567   u32 ip6_table_index = ~0;
10568   u32 l2_table_index = ~0;
10569   u8 is_add = 1;
10570   int ret;
10571
10572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10573     {
10574       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10575         sw_if_index_set = 1;
10576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10577         sw_if_index_set = 1;
10578       else if (unformat (i, "del"))
10579         is_add = 0;
10580       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10581         ;
10582       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10583         ;
10584       else if (unformat (i, "l2-table %d", &l2_table_index))
10585         ;
10586       else
10587         {
10588           clib_warning ("parse error '%U'", format_unformat_error, i);
10589           return -99;
10590         }
10591     }
10592
10593   if (sw_if_index_set == 0)
10594     {
10595       errmsg ("missing interface name or sw_if_index");
10596       return -99;
10597     }
10598
10599   M (OUTPUT_ACL_SET_INTERFACE, mp);
10600
10601   mp->sw_if_index = ntohl (sw_if_index);
10602   mp->ip4_table_index = ntohl (ip4_table_index);
10603   mp->ip6_table_index = ntohl (ip6_table_index);
10604   mp->l2_table_index = ntohl (l2_table_index);
10605   mp->is_add = is_add;
10606
10607   S (mp);
10608   W (ret);
10609   return ret;
10610 }
10611
10612 static int
10613 api_ip_address_dump (vat_main_t * vam)
10614 {
10615   unformat_input_t *i = vam->input;
10616   vl_api_ip_address_dump_t *mp;
10617   vl_api_control_ping_t *mp_ping;
10618   u32 sw_if_index = ~0;
10619   u8 sw_if_index_set = 0;
10620   u8 ipv4_set = 0;
10621   u8 ipv6_set = 0;
10622   int ret;
10623
10624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10625     {
10626       if (unformat (i, "sw_if_index %d", &sw_if_index))
10627         sw_if_index_set = 1;
10628       else
10629         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10630         sw_if_index_set = 1;
10631       else if (unformat (i, "ipv4"))
10632         ipv4_set = 1;
10633       else if (unformat (i, "ipv6"))
10634         ipv6_set = 1;
10635       else
10636         break;
10637     }
10638
10639   if (ipv4_set && ipv6_set)
10640     {
10641       errmsg ("ipv4 and ipv6 flags cannot be both set");
10642       return -99;
10643     }
10644
10645   if ((!ipv4_set) && (!ipv6_set))
10646     {
10647       errmsg ("no ipv4 nor ipv6 flag set");
10648       return -99;
10649     }
10650
10651   if (sw_if_index_set == 0)
10652     {
10653       errmsg ("missing interface name or sw_if_index");
10654       return -99;
10655     }
10656
10657   vam->current_sw_if_index = sw_if_index;
10658   vam->is_ipv6 = ipv6_set;
10659
10660   M (IP_ADDRESS_DUMP, mp);
10661   mp->sw_if_index = ntohl (sw_if_index);
10662   mp->is_ipv6 = ipv6_set;
10663   S (mp);
10664
10665   /* Use a control ping for synchronization */
10666   MPING (CONTROL_PING, mp_ping);
10667   S (mp_ping);
10668
10669   W (ret);
10670   return ret;
10671 }
10672
10673 static int
10674 api_ip_dump (vat_main_t * vam)
10675 {
10676   vl_api_ip_dump_t *mp;
10677   vl_api_control_ping_t *mp_ping;
10678   unformat_input_t *in = vam->input;
10679   int ipv4_set = 0;
10680   int ipv6_set = 0;
10681   int is_ipv6;
10682   int i;
10683   int ret;
10684
10685   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10686     {
10687       if (unformat (in, "ipv4"))
10688         ipv4_set = 1;
10689       else if (unformat (in, "ipv6"))
10690         ipv6_set = 1;
10691       else
10692         break;
10693     }
10694
10695   if (ipv4_set && ipv6_set)
10696     {
10697       errmsg ("ipv4 and ipv6 flags cannot be both set");
10698       return -99;
10699     }
10700
10701   if ((!ipv4_set) && (!ipv6_set))
10702     {
10703       errmsg ("no ipv4 nor ipv6 flag set");
10704       return -99;
10705     }
10706
10707   is_ipv6 = ipv6_set;
10708   vam->is_ipv6 = is_ipv6;
10709
10710   /* free old data */
10711   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10712     {
10713       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10714     }
10715   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10716
10717   M (IP_DUMP, mp);
10718   mp->is_ipv6 = ipv6_set;
10719   S (mp);
10720
10721   /* Use a control ping for synchronization */
10722   MPING (CONTROL_PING, mp_ping);
10723   S (mp_ping);
10724
10725   W (ret);
10726   return ret;
10727 }
10728
10729 static int
10730 api_ipsec_spd_add_del (vat_main_t * vam)
10731 {
10732   unformat_input_t *i = vam->input;
10733   vl_api_ipsec_spd_add_del_t *mp;
10734   u32 spd_id = ~0;
10735   u8 is_add = 1;
10736   int ret;
10737
10738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10739     {
10740       if (unformat (i, "spd_id %d", &spd_id))
10741         ;
10742       else if (unformat (i, "del"))
10743         is_add = 0;
10744       else
10745         {
10746           clib_warning ("parse error '%U'", format_unformat_error, i);
10747           return -99;
10748         }
10749     }
10750   if (spd_id == ~0)
10751     {
10752       errmsg ("spd_id must be set");
10753       return -99;
10754     }
10755
10756   M (IPSEC_SPD_ADD_DEL, mp);
10757
10758   mp->spd_id = ntohl (spd_id);
10759   mp->is_add = is_add;
10760
10761   S (mp);
10762   W (ret);
10763   return ret;
10764 }
10765
10766 static int
10767 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10768 {
10769   unformat_input_t *i = vam->input;
10770   vl_api_ipsec_interface_add_del_spd_t *mp;
10771   u32 sw_if_index;
10772   u8 sw_if_index_set = 0;
10773   u32 spd_id = (u32) ~ 0;
10774   u8 is_add = 1;
10775   int ret;
10776
10777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10778     {
10779       if (unformat (i, "del"))
10780         is_add = 0;
10781       else if (unformat (i, "spd_id %d", &spd_id))
10782         ;
10783       else
10784         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10785         sw_if_index_set = 1;
10786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10787         sw_if_index_set = 1;
10788       else
10789         {
10790           clib_warning ("parse error '%U'", format_unformat_error, i);
10791           return -99;
10792         }
10793
10794     }
10795
10796   if (spd_id == (u32) ~ 0)
10797     {
10798       errmsg ("spd_id must be set");
10799       return -99;
10800     }
10801
10802   if (sw_if_index_set == 0)
10803     {
10804       errmsg ("missing interface name or sw_if_index");
10805       return -99;
10806     }
10807
10808   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
10809
10810   mp->spd_id = ntohl (spd_id);
10811   mp->sw_if_index = ntohl (sw_if_index);
10812   mp->is_add = is_add;
10813
10814   S (mp);
10815   W (ret);
10816   return ret;
10817 }
10818
10819 static int
10820 api_ipsec_spd_entry_add_del (vat_main_t * vam)
10821 {
10822   unformat_input_t *i = vam->input;
10823   vl_api_ipsec_spd_entry_add_del_t *mp;
10824   u8 is_add = 1, is_outbound = 0;
10825   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10826   i32 priority = 0;
10827   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10828   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10829   vl_api_address_t laddr_start = { }, laddr_stop =
10830   {
10831   }, raddr_start =
10832   {
10833   }, raddr_stop =
10834   {
10835   };
10836   int ret;
10837
10838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (i, "del"))
10841         is_add = 0;
10842       if (unformat (i, "outbound"))
10843         is_outbound = 1;
10844       if (unformat (i, "inbound"))
10845         is_outbound = 0;
10846       else if (unformat (i, "spd_id %d", &spd_id))
10847         ;
10848       else if (unformat (i, "sa_id %d", &sa_id))
10849         ;
10850       else if (unformat (i, "priority %d", &priority))
10851         ;
10852       else if (unformat (i, "protocol %d", &protocol))
10853         ;
10854       else if (unformat (i, "lport_start %d", &lport_start))
10855         ;
10856       else if (unformat (i, "lport_stop %d", &lport_stop))
10857         ;
10858       else if (unformat (i, "rport_start %d", &rport_start))
10859         ;
10860       else if (unformat (i, "rport_stop %d", &rport_stop))
10861         ;
10862       else if (unformat (i, "laddr_start %U",
10863                          unformat_vl_api_address, &laddr_start))
10864         ;
10865       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
10866                          &laddr_stop))
10867         ;
10868       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
10869                          &raddr_start))
10870         ;
10871       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
10872                          &raddr_stop))
10873         ;
10874       else
10875         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10876         {
10877           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10878             {
10879               clib_warning ("unsupported action: 'resolve'");
10880               return -99;
10881             }
10882         }
10883       else
10884         {
10885           clib_warning ("parse error '%U'", format_unformat_error, i);
10886           return -99;
10887         }
10888
10889     }
10890
10891   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
10892
10893   mp->is_add = is_add;
10894
10895   mp->entry.spd_id = ntohl (spd_id);
10896   mp->entry.priority = ntohl (priority);
10897   mp->entry.is_outbound = is_outbound;
10898
10899   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
10900                sizeof (vl_api_address_t));
10901   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
10902                sizeof (vl_api_address_t));
10903   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
10904                sizeof (vl_api_address_t));
10905   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
10906                sizeof (vl_api_address_t));
10907
10908   mp->entry.protocol = (u8) protocol;
10909   mp->entry.local_port_start = ntohs ((u16) lport_start);
10910   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
10911   mp->entry.remote_port_start = ntohs ((u16) rport_start);
10912   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
10913   mp->entry.policy = (u8) policy;
10914   mp->entry.sa_id = ntohl (sa_id);
10915
10916   S (mp);
10917   W (ret);
10918   return ret;
10919 }
10920
10921 static int
10922 api_ipsec_sad_entry_add_del (vat_main_t * vam)
10923 {
10924   unformat_input_t *i = vam->input;
10925   vl_api_ipsec_sad_entry_add_del_t *mp;
10926   u32 sad_id = 0, spi = 0;
10927   u8 *ck = 0, *ik = 0;
10928   u8 is_add = 1;
10929
10930   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
10931   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
10932   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
10933   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
10934   vl_api_address_t tun_src, tun_dst;
10935   int ret;
10936
10937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10938     {
10939       if (unformat (i, "del"))
10940         is_add = 0;
10941       else if (unformat (i, "sad_id %d", &sad_id))
10942         ;
10943       else if (unformat (i, "spi %d", &spi))
10944         ;
10945       else if (unformat (i, "esp"))
10946         protocol = IPSEC_API_PROTO_ESP;
10947       else
10948         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
10949         {
10950           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10951           if (ADDRESS_IP6 == tun_src.af)
10952             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10953         }
10954       else
10955         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
10956         {
10957           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10958           if (ADDRESS_IP6 == tun_src.af)
10959             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10960         }
10961       else
10962         if (unformat (i, "crypto_alg %U",
10963                       unformat_ipsec_api_crypto_alg, &crypto_alg))
10964         ;
10965       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10966         ;
10967       else if (unformat (i, "integ_alg %U",
10968                          unformat_ipsec_api_integ_alg, &integ_alg))
10969         ;
10970       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10971         ;
10972       else
10973         {
10974           clib_warning ("parse error '%U'", format_unformat_error, i);
10975           return -99;
10976         }
10977
10978     }
10979
10980   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
10981
10982   mp->is_add = is_add;
10983   mp->entry.sad_id = ntohl (sad_id);
10984   mp->entry.protocol = protocol;
10985   mp->entry.spi = ntohl (spi);
10986   mp->entry.flags = flags;
10987
10988   mp->entry.crypto_algorithm = crypto_alg;
10989   mp->entry.integrity_algorithm = integ_alg;
10990   mp->entry.crypto_key.length = vec_len (ck);
10991   mp->entry.integrity_key.length = vec_len (ik);
10992
10993   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
10994     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
10995
10996   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
10997     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
10998
10999   if (ck)
11000     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
11001   if (ik)
11002     clib_memcpy (mp->entry.integrity_key.data, ik,
11003                  mp->entry.integrity_key.length);
11004
11005   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
11006     {
11007       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11008                    sizeof (mp->entry.tunnel_src));
11009       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11010                    sizeof (mp->entry.tunnel_dst));
11011     }
11012
11013   S (mp);
11014   W (ret);
11015   return ret;
11016 }
11017
11018 static void
11019 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11020 {
11021   vat_main_t *vam = &vat_main;
11022
11023   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
11024          "crypto_key %U integ_alg %u integ_key %U flags %x "
11025          "tunnel_src_addr %U tunnel_dst_addr %U "
11026          "salt %u seq_outbound %lu last_seq_inbound %lu "
11027          "replay_window %lu stat_index %u\n",
11028          ntohl (mp->entry.sad_id),
11029          ntohl (mp->sw_if_index),
11030          ntohl (mp->entry.spi),
11031          ntohl (mp->entry.protocol),
11032          ntohl (mp->entry.crypto_algorithm),
11033          format_hex_bytes, mp->entry.crypto_key.data,
11034          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11035          format_hex_bytes, mp->entry.integrity_key.data,
11036          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11037          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11038          &mp->entry.tunnel_dst, ntohl (mp->salt),
11039          clib_net_to_host_u64 (mp->seq_outbound),
11040          clib_net_to_host_u64 (mp->last_seq_inbound),
11041          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
11042 }
11043
11044 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11045 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
11046
11047 static void vl_api_ipsec_sa_details_t_handler_json
11048   (vl_api_ipsec_sa_details_t * mp)
11049 {
11050   vat_main_t *vam = &vat_main;
11051   vat_json_node_t *node = NULL;
11052   vl_api_ipsec_sad_flags_t flags;
11053
11054   if (VAT_JSON_ARRAY != vam->json_tree.type)
11055     {
11056       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11057       vat_json_init_array (&vam->json_tree);
11058     }
11059   node = vat_json_array_add (&vam->json_tree);
11060
11061   vat_json_init_object (node);
11062   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
11063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11064   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11065   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11066   vat_json_object_add_uint (node, "crypto_alg",
11067                             ntohl (mp->entry.crypto_algorithm));
11068   vat_json_object_add_uint (node, "integ_alg",
11069                             ntohl (mp->entry.integrity_algorithm));
11070   flags = ntohl (mp->entry.flags);
11071   vat_json_object_add_uint (node, "use_esn",
11072                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
11073   vat_json_object_add_uint (node, "use_anti_replay",
11074                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11075   vat_json_object_add_uint (node, "is_tunnel",
11076                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11077   vat_json_object_add_uint (node, "is_tunnel_ip6",
11078                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11079   vat_json_object_add_uint (node, "udp_encap",
11080                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11081   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11082                              mp->entry.crypto_key.length);
11083   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11084                              mp->entry.integrity_key.length);
11085   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11086   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
11087   vat_json_object_add_uint (node, "replay_window",
11088                             clib_net_to_host_u64 (mp->replay_window));
11089   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
11090 }
11091
11092 static int
11093 api_ipsec_sa_dump (vat_main_t * vam)
11094 {
11095   unformat_input_t *i = vam->input;
11096   vl_api_ipsec_sa_dump_t *mp;
11097   vl_api_control_ping_t *mp_ping;
11098   u32 sa_id = ~0;
11099   int ret;
11100
11101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (i, "sa_id %d", &sa_id))
11104         ;
11105       else
11106         {
11107           clib_warning ("parse error '%U'", format_unformat_error, i);
11108           return -99;
11109         }
11110     }
11111
11112   M (IPSEC_SA_DUMP, mp);
11113
11114   mp->sa_id = ntohl (sa_id);
11115
11116   S (mp);
11117
11118   /* Use a control ping for synchronization */
11119   M (CONTROL_PING, mp_ping);
11120   S (mp_ping);
11121
11122   W (ret);
11123   return ret;
11124 }
11125
11126 static int
11127 api_get_first_msg_id (vat_main_t * vam)
11128 {
11129   vl_api_get_first_msg_id_t *mp;
11130   unformat_input_t *i = vam->input;
11131   u8 *name;
11132   u8 name_set = 0;
11133   int ret;
11134
11135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (i, "client %s", &name))
11138         name_set = 1;
11139       else
11140         break;
11141     }
11142
11143   if (name_set == 0)
11144     {
11145       errmsg ("missing client name");
11146       return -99;
11147     }
11148   vec_add1 (name, 0);
11149
11150   if (vec_len (name) > 63)
11151     {
11152       errmsg ("client name too long");
11153       return -99;
11154     }
11155
11156   M (GET_FIRST_MSG_ID, mp);
11157   clib_memcpy (mp->name, name, vec_len (name));
11158   S (mp);
11159   W (ret);
11160   return ret;
11161 }
11162
11163 static int
11164 api_get_node_graph (vat_main_t * vam)
11165 {
11166   vl_api_get_node_graph_t *mp;
11167   int ret;
11168
11169   M (GET_NODE_GRAPH, mp);
11170
11171   /* send it... */
11172   S (mp);
11173   /* Wait for the reply */
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static int
11179 api_af_packet_create (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_af_packet_create_t *mp;
11183   u8 *host_if_name = 0;
11184   u8 hw_addr[6];
11185   u8 random_hw_addr = 1;
11186   int ret;
11187
11188   clib_memset (hw_addr, 0, sizeof (hw_addr));
11189
11190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11191     {
11192       if (unformat (i, "name %s", &host_if_name))
11193         vec_add1 (host_if_name, 0);
11194       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11195         random_hw_addr = 0;
11196       else
11197         break;
11198     }
11199
11200   if (!vec_len (host_if_name))
11201     {
11202       errmsg ("host-interface name must be specified");
11203       return -99;
11204     }
11205
11206   if (vec_len (host_if_name) > 64)
11207     {
11208       errmsg ("host-interface name too long");
11209       return -99;
11210     }
11211
11212   M (AF_PACKET_CREATE, mp);
11213
11214   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11215   clib_memcpy (mp->hw_addr, hw_addr, 6);
11216   mp->use_random_hw_addr = random_hw_addr;
11217   vec_free (host_if_name);
11218
11219   S (mp);
11220
11221   /* *INDENT-OFF* */
11222   W2 (ret,
11223       ({
11224         if (ret == 0)
11225           fprintf (vam->ofp ? vam->ofp : stderr,
11226                    " new sw_if_index = %d\n", vam->sw_if_index);
11227       }));
11228   /* *INDENT-ON* */
11229   return ret;
11230 }
11231
11232 static int
11233 api_af_packet_delete (vat_main_t * vam)
11234 {
11235   unformat_input_t *i = vam->input;
11236   vl_api_af_packet_delete_t *mp;
11237   u8 *host_if_name = 0;
11238   int ret;
11239
11240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11241     {
11242       if (unformat (i, "name %s", &host_if_name))
11243         vec_add1 (host_if_name, 0);
11244       else
11245         break;
11246     }
11247
11248   if (!vec_len (host_if_name))
11249     {
11250       errmsg ("host-interface name must be specified");
11251       return -99;
11252     }
11253
11254   if (vec_len (host_if_name) > 64)
11255     {
11256       errmsg ("host-interface name too long");
11257       return -99;
11258     }
11259
11260   M (AF_PACKET_DELETE, mp);
11261
11262   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11263   vec_free (host_if_name);
11264
11265   S (mp);
11266   W (ret);
11267   return ret;
11268 }
11269
11270 static void vl_api_af_packet_details_t_handler
11271   (vl_api_af_packet_details_t * mp)
11272 {
11273   vat_main_t *vam = &vat_main;
11274
11275   print (vam->ofp, "%-16s %d",
11276          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11277 }
11278
11279 static void vl_api_af_packet_details_t_handler_json
11280   (vl_api_af_packet_details_t * mp)
11281 {
11282   vat_main_t *vam = &vat_main;
11283   vat_json_node_t *node = NULL;
11284
11285   if (VAT_JSON_ARRAY != vam->json_tree.type)
11286     {
11287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11288       vat_json_init_array (&vam->json_tree);
11289     }
11290   node = vat_json_array_add (&vam->json_tree);
11291
11292   vat_json_init_object (node);
11293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11294   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11295 }
11296
11297 static int
11298 api_af_packet_dump (vat_main_t * vam)
11299 {
11300   vl_api_af_packet_dump_t *mp;
11301   vl_api_control_ping_t *mp_ping;
11302   int ret;
11303
11304   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11305   /* Get list of tap interfaces */
11306   M (AF_PACKET_DUMP, mp);
11307   S (mp);
11308
11309   /* Use a control ping for synchronization */
11310   MPING (CONTROL_PING, mp_ping);
11311   S (mp_ping);
11312
11313   W (ret);
11314   return ret;
11315 }
11316
11317 static int
11318 api_policer_add_del (vat_main_t * vam)
11319 {
11320   unformat_input_t *i = vam->input;
11321   vl_api_policer_add_del_t *mp;
11322   u8 is_add = 1;
11323   u8 *name = 0;
11324   u32 cir = 0;
11325   u32 eir = 0;
11326   u64 cb = 0;
11327   u64 eb = 0;
11328   u8 rate_type = 0;
11329   u8 round_type = 0;
11330   u8 type = 0;
11331   u8 color_aware = 0;
11332   qos_pol_action_params_st conform_action, exceed_action, violate_action;
11333   int ret;
11334
11335   conform_action.action_type = QOS_ACTION_TRANSMIT;
11336   conform_action.dscp = 0;
11337   exceed_action.action_type = QOS_ACTION_MARK_AND_TRANSMIT;
11338   exceed_action.dscp = 0;
11339   violate_action.action_type = QOS_ACTION_DROP;
11340   violate_action.dscp = 0;
11341
11342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11343     {
11344       if (unformat (i, "del"))
11345         is_add = 0;
11346       else if (unformat (i, "name %s", &name))
11347         vec_add1 (name, 0);
11348       else if (unformat (i, "cir %u", &cir))
11349         ;
11350       else if (unformat (i, "eir %u", &eir))
11351         ;
11352       else if (unformat (i, "cb %u", &cb))
11353         ;
11354       else if (unformat (i, "eb %u", &eb))
11355         ;
11356       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11357                          &rate_type))
11358         ;
11359       else if (unformat (i, "round_type %U", unformat_policer_round_type,
11360                          &round_type))
11361         ;
11362       else if (unformat (i, "type %U", unformat_policer_type, &type))
11363         ;
11364       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11365                          &conform_action))
11366         ;
11367       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11368                          &exceed_action))
11369         ;
11370       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11371                          &violate_action))
11372         ;
11373       else if (unformat (i, "color-aware"))
11374         color_aware = 1;
11375       else
11376         break;
11377     }
11378
11379   if (!vec_len (name))
11380     {
11381       errmsg ("policer name must be specified");
11382       return -99;
11383     }
11384
11385   if (vec_len (name) > 64)
11386     {
11387       errmsg ("policer name too long");
11388       return -99;
11389     }
11390
11391   M (POLICER_ADD_DEL, mp);
11392
11393   clib_memcpy (mp->name, name, vec_len (name));
11394   vec_free (name);
11395   mp->is_add = is_add;
11396   mp->cir = ntohl (cir);
11397   mp->eir = ntohl (eir);
11398   mp->cb = clib_net_to_host_u64 (cb);
11399   mp->eb = clib_net_to_host_u64 (eb);
11400   mp->rate_type = rate_type;
11401   mp->round_type = round_type;
11402   mp->type = type;
11403   mp->conform_action.type =
11404     (vl_api_sse2_qos_action_type_t) conform_action.action_type;
11405   mp->conform_action.dscp = conform_action.dscp;
11406   mp->exceed_action.type =
11407     (vl_api_sse2_qos_action_type_t) exceed_action.action_type;
11408   mp->exceed_action.dscp = exceed_action.dscp;
11409   mp->violate_action.type =
11410     (vl_api_sse2_qos_action_type_t) violate_action.action_type;
11411   mp->violate_action.dscp = violate_action.dscp;
11412   mp->color_aware = color_aware;
11413
11414   S (mp);
11415   W (ret);
11416   return ret;
11417 }
11418
11419 static int
11420 api_policer_dump (vat_main_t * vam)
11421 {
11422   unformat_input_t *i = vam->input;
11423   vl_api_policer_dump_t *mp;
11424   vl_api_control_ping_t *mp_ping;
11425   u8 *match_name = 0;
11426   u8 match_name_valid = 0;
11427   int ret;
11428
11429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (i, "name %s", &match_name))
11432         {
11433           vec_add1 (match_name, 0);
11434           match_name_valid = 1;
11435         }
11436       else
11437         break;
11438     }
11439
11440   M (POLICER_DUMP, mp);
11441   mp->match_name_valid = match_name_valid;
11442   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11443   vec_free (match_name);
11444   /* send it... */
11445   S (mp);
11446
11447   /* Use a control ping for synchronization */
11448   MPING (CONTROL_PING, mp_ping);
11449   S (mp_ping);
11450
11451   /* Wait for a reply... */
11452   W (ret);
11453   return ret;
11454 }
11455
11456 static int
11457 api_policer_classify_set_interface (vat_main_t * vam)
11458 {
11459   unformat_input_t *i = vam->input;
11460   vl_api_policer_classify_set_interface_t *mp;
11461   u32 sw_if_index;
11462   int sw_if_index_set;
11463   u32 ip4_table_index = ~0;
11464   u32 ip6_table_index = ~0;
11465   u32 l2_table_index = ~0;
11466   u8 is_add = 1;
11467   int ret;
11468
11469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11470     {
11471       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11472         sw_if_index_set = 1;
11473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11474         sw_if_index_set = 1;
11475       else if (unformat (i, "del"))
11476         is_add = 0;
11477       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11478         ;
11479       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11480         ;
11481       else if (unformat (i, "l2-table %d", &l2_table_index))
11482         ;
11483       else
11484         {
11485           clib_warning ("parse error '%U'", format_unformat_error, i);
11486           return -99;
11487         }
11488     }
11489
11490   if (sw_if_index_set == 0)
11491     {
11492       errmsg ("missing interface name or sw_if_index");
11493       return -99;
11494     }
11495
11496   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
11497
11498   mp->sw_if_index = ntohl (sw_if_index);
11499   mp->ip4_table_index = ntohl (ip4_table_index);
11500   mp->ip6_table_index = ntohl (ip6_table_index);
11501   mp->l2_table_index = ntohl (l2_table_index);
11502   mp->is_add = is_add;
11503
11504   S (mp);
11505   W (ret);
11506   return ret;
11507 }
11508
11509 static int
11510 api_policer_classify_dump (vat_main_t * vam)
11511 {
11512   unformat_input_t *i = vam->input;
11513   vl_api_policer_classify_dump_t *mp;
11514   vl_api_control_ping_t *mp_ping;
11515   u8 type = POLICER_CLASSIFY_N_TABLES;
11516   int ret;
11517
11518   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11519     ;
11520   else
11521     {
11522       errmsg ("classify table type must be specified");
11523       return -99;
11524     }
11525
11526   if (!vam->json_output)
11527     {
11528       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11529     }
11530
11531   M (POLICER_CLASSIFY_DUMP, mp);
11532   mp->type = type;
11533   /* send it... */
11534   S (mp);
11535
11536   /* Use a control ping for synchronization */
11537   MPING (CONTROL_PING, mp_ping);
11538   S (mp_ping);
11539
11540   /* Wait for a reply... */
11541   W (ret);
11542   return ret;
11543 }
11544
11545 static u8 *
11546 format_fib_api_path_nh_proto (u8 * s, va_list * args)
11547 {
11548   vl_api_fib_path_nh_proto_t proto =
11549     va_arg (*args, vl_api_fib_path_nh_proto_t);
11550
11551   switch (proto)
11552     {
11553     case FIB_API_PATH_NH_PROTO_IP4:
11554       s = format (s, "ip4");
11555       break;
11556     case FIB_API_PATH_NH_PROTO_IP6:
11557       s = format (s, "ip6");
11558       break;
11559     case FIB_API_PATH_NH_PROTO_MPLS:
11560       s = format (s, "mpls");
11561       break;
11562     case FIB_API_PATH_NH_PROTO_BIER:
11563       s = format (s, "bier");
11564       break;
11565     case FIB_API_PATH_NH_PROTO_ETHERNET:
11566       s = format (s, "ethernet");
11567       break;
11568     }
11569
11570   return (s);
11571 }
11572
11573 static u8 *
11574 format_vl_api_ip_address_union (u8 * s, va_list * args)
11575 {
11576   vl_api_address_family_t af = va_arg (*args, int);
11577   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11578
11579   switch (af)
11580     {
11581     case ADDRESS_IP4:
11582       s = format (s, "%U", format_ip4_address, u->ip4);
11583       break;
11584     case ADDRESS_IP6:
11585       s = format (s, "%U", format_ip6_address, u->ip6);
11586       break;
11587     }
11588   return (s);
11589 }
11590
11591 static u8 *
11592 format_vl_api_fib_path_type (u8 * s, va_list * args)
11593 {
11594   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11595
11596   switch (t)
11597     {
11598     case FIB_API_PATH_TYPE_NORMAL:
11599       s = format (s, "normal");
11600       break;
11601     case FIB_API_PATH_TYPE_LOCAL:
11602       s = format (s, "local");
11603       break;
11604     case FIB_API_PATH_TYPE_DROP:
11605       s = format (s, "drop");
11606       break;
11607     case FIB_API_PATH_TYPE_UDP_ENCAP:
11608       s = format (s, "udp-encap");
11609       break;
11610     case FIB_API_PATH_TYPE_BIER_IMP:
11611       s = format (s, "bier-imp");
11612       break;
11613     case FIB_API_PATH_TYPE_ICMP_UNREACH:
11614       s = format (s, "unreach");
11615       break;
11616     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11617       s = format (s, "prohibit");
11618       break;
11619     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11620       s = format (s, "src-lookup");
11621       break;
11622     case FIB_API_PATH_TYPE_DVR:
11623       s = format (s, "dvr");
11624       break;
11625     case FIB_API_PATH_TYPE_INTERFACE_RX:
11626       s = format (s, "interface-rx");
11627       break;
11628     case FIB_API_PATH_TYPE_CLASSIFY:
11629       s = format (s, "classify");
11630       break;
11631     }
11632
11633   return (s);
11634 }
11635
11636 static void
11637 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11638 {
11639   print (vam->ofp,
11640          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11641          ntohl (fp->weight), ntohl (fp->sw_if_index),
11642          format_vl_api_fib_path_type, fp->type,
11643          format_fib_api_path_nh_proto, fp->proto,
11644          format_vl_api_ip_address_union, &fp->nh.address);
11645 }
11646
11647 static void
11648 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
11649                                  vl_api_fib_path_t * fp)
11650 {
11651   struct in_addr ip4;
11652   struct in6_addr ip6;
11653
11654   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11655   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
11656   vat_json_object_add_uint (node, "type", fp->type);
11657   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11658   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
11659     {
11660       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
11661       vat_json_object_add_ip4 (node, "next_hop", ip4);
11662     }
11663   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
11664     {
11665       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
11666       vat_json_object_add_ip6 (node, "next_hop", ip6);
11667     }
11668 }
11669
11670 static void
11671 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
11672 {
11673   vat_main_t *vam = &vat_main;
11674   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11675   vl_api_fib_path_t *fp;
11676   i32 i;
11677
11678   print (vam->ofp, "sw_if_index %d via:",
11679          ntohl (mp->mt_tunnel.mt_sw_if_index));
11680   fp = mp->mt_tunnel.mt_paths;
11681   for (i = 0; i < count; i++)
11682     {
11683       vl_api_fib_path_print (vam, fp);
11684       fp++;
11685     }
11686
11687   print (vam->ofp, "");
11688 }
11689
11690 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11691 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11692
11693 static void
11694 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
11695 {
11696   vat_main_t *vam = &vat_main;
11697   vat_json_node_t *node = NULL;
11698   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11699   vl_api_fib_path_t *fp;
11700   i32 i;
11701
11702   if (VAT_JSON_ARRAY != vam->json_tree.type)
11703     {
11704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11705       vat_json_init_array (&vam->json_tree);
11706     }
11707   node = vat_json_array_add (&vam->json_tree);
11708
11709   vat_json_init_object (node);
11710   vat_json_object_add_uint (node, "sw_if_index",
11711                             ntohl (mp->mt_tunnel.mt_sw_if_index));
11712
11713   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
11714
11715   fp = mp->mt_tunnel.mt_paths;
11716   for (i = 0; i < count; i++)
11717     {
11718       vl_api_mpls_fib_path_json_print (node, fp);
11719       fp++;
11720     }
11721 }
11722
11723 static int
11724 api_mpls_tunnel_dump (vat_main_t * vam)
11725 {
11726   vl_api_mpls_tunnel_dump_t *mp;
11727   vl_api_control_ping_t *mp_ping;
11728   int ret;
11729
11730   M (MPLS_TUNNEL_DUMP, mp);
11731
11732   S (mp);
11733
11734   /* Use a control ping for synchronization */
11735   MPING (CONTROL_PING, mp_ping);
11736   S (mp_ping);
11737
11738   W (ret);
11739   return ret;
11740 }
11741
11742 #define vl_api_mpls_table_details_t_endian vl_noop_handler
11743 #define vl_api_mpls_table_details_t_print vl_noop_handler
11744
11745
11746 static void
11747 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
11748 {
11749   vat_main_t *vam = &vat_main;
11750
11751   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
11752 }
11753
11754 static void vl_api_mpls_table_details_t_handler_json
11755   (vl_api_mpls_table_details_t * mp)
11756 {
11757   vat_main_t *vam = &vat_main;
11758   vat_json_node_t *node = NULL;
11759
11760   if (VAT_JSON_ARRAY != vam->json_tree.type)
11761     {
11762       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11763       vat_json_init_array (&vam->json_tree);
11764     }
11765   node = vat_json_array_add (&vam->json_tree);
11766
11767   vat_json_init_object (node);
11768   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
11769 }
11770
11771 static int
11772 api_mpls_table_dump (vat_main_t * vam)
11773 {
11774   vl_api_mpls_table_dump_t *mp;
11775   vl_api_control_ping_t *mp_ping;
11776   int ret;
11777
11778   M (MPLS_TABLE_DUMP, mp);
11779   S (mp);
11780
11781   /* Use a control ping for synchronization */
11782   MPING (CONTROL_PING, mp_ping);
11783   S (mp_ping);
11784
11785   W (ret);
11786   return ret;
11787 }
11788
11789 #define vl_api_mpls_route_details_t_endian vl_noop_handler
11790 #define vl_api_mpls_route_details_t_print vl_noop_handler
11791
11792 static void
11793 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
11797   vl_api_fib_path_t *fp;
11798   int i;
11799
11800   print (vam->ofp,
11801          "table-id %d, label %u, ess_bit %u",
11802          ntohl (mp->mr_route.mr_table_id),
11803          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
11804   fp = mp->mr_route.mr_paths;
11805   for (i = 0; i < count; i++)
11806     {
11807       vl_api_fib_path_print (vam, fp);
11808       fp++;
11809     }
11810 }
11811
11812 static void vl_api_mpls_route_details_t_handler_json
11813   (vl_api_mpls_route_details_t * mp)
11814 {
11815   vat_main_t *vam = &vat_main;
11816   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
11817   vat_json_node_t *node = NULL;
11818   vl_api_fib_path_t *fp;
11819   int i;
11820
11821   if (VAT_JSON_ARRAY != vam->json_tree.type)
11822     {
11823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11824       vat_json_init_array (&vam->json_tree);
11825     }
11826   node = vat_json_array_add (&vam->json_tree);
11827
11828   vat_json_init_object (node);
11829   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
11830   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
11831   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
11832   vat_json_object_add_uint (node, "path_count", count);
11833   fp = mp->mr_route.mr_paths;
11834   for (i = 0; i < count; i++)
11835     {
11836       vl_api_mpls_fib_path_json_print (node, fp);
11837       fp++;
11838     }
11839 }
11840
11841 static int
11842 api_mpls_route_dump (vat_main_t * vam)
11843 {
11844   unformat_input_t *input = vam->input;
11845   vl_api_mpls_route_dump_t *mp;
11846   vl_api_control_ping_t *mp_ping;
11847   u32 table_id;
11848   int ret;
11849
11850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11851     {
11852       if (unformat (input, "table_id %d", &table_id))
11853         ;
11854       else
11855         break;
11856     }
11857   if (table_id == ~0)
11858     {
11859       errmsg ("missing table id");
11860       return -99;
11861     }
11862
11863   M (MPLS_ROUTE_DUMP, mp);
11864
11865   mp->table.mt_table_id = ntohl (table_id);
11866   S (mp);
11867
11868   /* Use a control ping for synchronization */
11869   MPING (CONTROL_PING, mp_ping);
11870   S (mp_ping);
11871
11872   W (ret);
11873   return ret;
11874 }
11875
11876 #define vl_api_ip_table_details_t_endian vl_noop_handler
11877 #define vl_api_ip_table_details_t_print vl_noop_handler
11878
11879 static void
11880 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
11881 {
11882   vat_main_t *vam = &vat_main;
11883
11884   print (vam->ofp,
11885          "%s; table-id %d, prefix %U/%d",
11886          mp->table.name, ntohl (mp->table.table_id));
11887 }
11888
11889
11890 static void vl_api_ip_table_details_t_handler_json
11891   (vl_api_ip_table_details_t * mp)
11892 {
11893   vat_main_t *vam = &vat_main;
11894   vat_json_node_t *node = NULL;
11895
11896   if (VAT_JSON_ARRAY != vam->json_tree.type)
11897     {
11898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11899       vat_json_init_array (&vam->json_tree);
11900     }
11901   node = vat_json_array_add (&vam->json_tree);
11902
11903   vat_json_init_object (node);
11904   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
11905 }
11906
11907 static int
11908 api_ip_table_dump (vat_main_t * vam)
11909 {
11910   vl_api_ip_table_dump_t *mp;
11911   vl_api_control_ping_t *mp_ping;
11912   int ret;
11913
11914   M (IP_TABLE_DUMP, mp);
11915   S (mp);
11916
11917   /* Use a control ping for synchronization */
11918   MPING (CONTROL_PING, mp_ping);
11919   S (mp_ping);
11920
11921   W (ret);
11922   return ret;
11923 }
11924
11925 static int
11926 api_ip_mtable_dump (vat_main_t * vam)
11927 {
11928   vl_api_ip_mtable_dump_t *mp;
11929   vl_api_control_ping_t *mp_ping;
11930   int ret;
11931
11932   M (IP_MTABLE_DUMP, mp);
11933   S (mp);
11934
11935   /* Use a control ping for synchronization */
11936   MPING (CONTROL_PING, mp_ping);
11937   S (mp_ping);
11938
11939   W (ret);
11940   return ret;
11941 }
11942
11943 static int
11944 api_ip_mroute_dump (vat_main_t * vam)
11945 {
11946   unformat_input_t *input = vam->input;
11947   vl_api_control_ping_t *mp_ping;
11948   vl_api_ip_mroute_dump_t *mp;
11949   int ret, is_ip6;
11950   u32 table_id;
11951
11952   is_ip6 = 0;
11953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11954     {
11955       if (unformat (input, "table_id %d", &table_id))
11956         ;
11957       else if (unformat (input, "ip6"))
11958         is_ip6 = 1;
11959       else if (unformat (input, "ip4"))
11960         is_ip6 = 0;
11961       else
11962         break;
11963     }
11964   if (table_id == ~0)
11965     {
11966       errmsg ("missing table id");
11967       return -99;
11968     }
11969
11970   M (IP_MROUTE_DUMP, mp);
11971   mp->table.table_id = table_id;
11972   mp->table.is_ip6 = is_ip6;
11973   S (mp);
11974
11975   /* Use a control ping for synchronization */
11976   MPING (CONTROL_PING, mp_ping);
11977   S (mp_ping);
11978
11979   W (ret);
11980   return ret;
11981 }
11982
11983 #define vl_api_ip_route_details_t_endian vl_noop_handler
11984 #define vl_api_ip_route_details_t_print vl_noop_handler
11985
11986 static void
11987 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
11988 {
11989   vat_main_t *vam = &vat_main;
11990   u8 count = mp->route.n_paths;
11991   vl_api_fib_path_t *fp;
11992   int i;
11993
11994   print (vam->ofp,
11995          "table-id %d, prefix %U/%d",
11996          ntohl (mp->route.table_id),
11997          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
11998   for (i = 0; i < count; i++)
11999     {
12000       fp = &mp->route.paths[i];
12001
12002       vl_api_fib_path_print (vam, fp);
12003       fp++;
12004     }
12005 }
12006
12007 static void vl_api_ip_route_details_t_handler_json
12008   (vl_api_ip_route_details_t * mp)
12009 {
12010   vat_main_t *vam = &vat_main;
12011   u8 count = mp->route.n_paths;
12012   vat_json_node_t *node = NULL;
12013   struct in_addr ip4;
12014   struct in6_addr ip6;
12015   vl_api_fib_path_t *fp;
12016   int i;
12017
12018   if (VAT_JSON_ARRAY != vam->json_tree.type)
12019     {
12020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12021       vat_json_init_array (&vam->json_tree);
12022     }
12023   node = vat_json_array_add (&vam->json_tree);
12024
12025   vat_json_init_object (node);
12026   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12027   if (ADDRESS_IP6 == mp->route.prefix.address.af)
12028     {
12029       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12030       vat_json_object_add_ip6 (node, "prefix", ip6);
12031     }
12032   else
12033     {
12034       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12035       vat_json_object_add_ip4 (node, "prefix", ip4);
12036     }
12037   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
12038   vat_json_object_add_uint (node, "path_count", count);
12039   for (i = 0; i < count; i++)
12040     {
12041       fp = &mp->route.paths[i];
12042       vl_api_mpls_fib_path_json_print (node, fp);
12043     }
12044 }
12045
12046 static int
12047 api_ip_route_dump (vat_main_t * vam)
12048 {
12049   unformat_input_t *input = vam->input;
12050   vl_api_ip_route_dump_t *mp;
12051   vl_api_control_ping_t *mp_ping;
12052   u32 table_id;
12053   u8 is_ip6;
12054   int ret;
12055
12056   is_ip6 = 0;
12057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12058     {
12059       if (unformat (input, "table_id %d", &table_id))
12060         ;
12061       else if (unformat (input, "ip6"))
12062         is_ip6 = 1;
12063       else if (unformat (input, "ip4"))
12064         is_ip6 = 0;
12065       else
12066         break;
12067     }
12068   if (table_id == ~0)
12069     {
12070       errmsg ("missing table id");
12071       return -99;
12072     }
12073
12074   M (IP_ROUTE_DUMP, mp);
12075
12076   mp->table.table_id = table_id;
12077   mp->table.is_ip6 = is_ip6;
12078
12079   S (mp);
12080
12081   /* Use a control ping for synchronization */
12082   MPING (CONTROL_PING, mp_ping);
12083   S (mp_ping);
12084
12085   W (ret);
12086   return ret;
12087 }
12088
12089 int
12090 api_classify_table_ids (vat_main_t * vam)
12091 {
12092   vl_api_classify_table_ids_t *mp;
12093   int ret;
12094
12095   /* Construct the API message */
12096   M (CLASSIFY_TABLE_IDS, mp);
12097   mp->context = 0;
12098
12099   S (mp);
12100   W (ret);
12101   return ret;
12102 }
12103
12104 int
12105 api_classify_table_by_interface (vat_main_t * vam)
12106 {
12107   unformat_input_t *input = vam->input;
12108   vl_api_classify_table_by_interface_t *mp;
12109
12110   u32 sw_if_index = ~0;
12111   int ret;
12112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12115         ;
12116       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12117         ;
12118       else
12119         break;
12120     }
12121   if (sw_if_index == ~0)
12122     {
12123       errmsg ("missing interface name or sw_if_index");
12124       return -99;
12125     }
12126
12127   /* Construct the API message */
12128   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
12129   mp->context = 0;
12130   mp->sw_if_index = ntohl (sw_if_index);
12131
12132   S (mp);
12133   W (ret);
12134   return ret;
12135 }
12136
12137 int
12138 api_classify_table_info (vat_main_t * vam)
12139 {
12140   unformat_input_t *input = vam->input;
12141   vl_api_classify_table_info_t *mp;
12142
12143   u32 table_id = ~0;
12144   int ret;
12145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12146     {
12147       if (unformat (input, "table_id %d", &table_id))
12148         ;
12149       else
12150         break;
12151     }
12152   if (table_id == ~0)
12153     {
12154       errmsg ("missing table id");
12155       return -99;
12156     }
12157
12158   /* Construct the API message */
12159   M (CLASSIFY_TABLE_INFO, mp);
12160   mp->context = 0;
12161   mp->table_id = ntohl (table_id);
12162
12163   S (mp);
12164   W (ret);
12165   return ret;
12166 }
12167
12168 int
12169 api_classify_session_dump (vat_main_t * vam)
12170 {
12171   unformat_input_t *input = vam->input;
12172   vl_api_classify_session_dump_t *mp;
12173   vl_api_control_ping_t *mp_ping;
12174
12175   u32 table_id = ~0;
12176   int ret;
12177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12178     {
12179       if (unformat (input, "table_id %d", &table_id))
12180         ;
12181       else
12182         break;
12183     }
12184   if (table_id == ~0)
12185     {
12186       errmsg ("missing table id");
12187       return -99;
12188     }
12189
12190   /* Construct the API message */
12191   M (CLASSIFY_SESSION_DUMP, mp);
12192   mp->context = 0;
12193   mp->table_id = ntohl (table_id);
12194   S (mp);
12195
12196   /* Use a control ping for synchronization */
12197   MPING (CONTROL_PING, mp_ping);
12198   S (mp_ping);
12199
12200   W (ret);
12201   return ret;
12202 }
12203
12204 static void
12205 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12206 {
12207   vat_main_t *vam = &vat_main;
12208
12209   print (vam->ofp, "collector_address %U, collector_port %d, "
12210          "src_address %U, vrf_id %d, path_mtu %u, "
12211          "template_interval %u, udp_checksum %d",
12212          format_ip4_address, mp->collector_address,
12213          ntohs (mp->collector_port),
12214          format_ip4_address, mp->src_address,
12215          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12216          ntohl (mp->template_interval), mp->udp_checksum);
12217
12218   vam->retval = 0;
12219   vam->result_ready = 1;
12220 }
12221
12222 static void
12223   vl_api_ipfix_exporter_details_t_handler_json
12224   (vl_api_ipfix_exporter_details_t * mp)
12225 {
12226   vat_main_t *vam = &vat_main;
12227   vat_json_node_t node;
12228   struct in_addr collector_address;
12229   struct in_addr src_address;
12230
12231   vat_json_init_object (&node);
12232   clib_memcpy (&collector_address, &mp->collector_address,
12233                sizeof (collector_address));
12234   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12235   vat_json_object_add_uint (&node, "collector_port",
12236                             ntohs (mp->collector_port));
12237   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12238   vat_json_object_add_ip4 (&node, "src_address", src_address);
12239   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12240   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12241   vat_json_object_add_uint (&node, "template_interval",
12242                             ntohl (mp->template_interval));
12243   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12244
12245   vat_json_print (vam->ofp, &node);
12246   vat_json_free (&node);
12247   vam->retval = 0;
12248   vam->result_ready = 1;
12249 }
12250
12251 int
12252 api_ipfix_exporter_dump (vat_main_t * vam)
12253 {
12254   vl_api_ipfix_exporter_dump_t *mp;
12255   int ret;
12256
12257   /* Construct the API message */
12258   M (IPFIX_EXPORTER_DUMP, mp);
12259   mp->context = 0;
12260
12261   S (mp);
12262   W (ret);
12263   return ret;
12264 }
12265
12266 static int
12267 api_ipfix_classify_stream_dump (vat_main_t * vam)
12268 {
12269   vl_api_ipfix_classify_stream_dump_t *mp;
12270   int ret;
12271
12272   /* Construct the API message */
12273   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
12274   mp->context = 0;
12275
12276   S (mp);
12277   W (ret);
12278   return ret;
12279   /* NOTREACHED */
12280   return 0;
12281 }
12282
12283 static void
12284   vl_api_ipfix_classify_stream_details_t_handler
12285   (vl_api_ipfix_classify_stream_details_t * mp)
12286 {
12287   vat_main_t *vam = &vat_main;
12288   print (vam->ofp, "domain_id %d, src_port %d",
12289          ntohl (mp->domain_id), ntohs (mp->src_port));
12290   vam->retval = 0;
12291   vam->result_ready = 1;
12292 }
12293
12294 static void
12295   vl_api_ipfix_classify_stream_details_t_handler_json
12296   (vl_api_ipfix_classify_stream_details_t * mp)
12297 {
12298   vat_main_t *vam = &vat_main;
12299   vat_json_node_t node;
12300
12301   vat_json_init_object (&node);
12302   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12303   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12304
12305   vat_json_print (vam->ofp, &node);
12306   vat_json_free (&node);
12307   vam->retval = 0;
12308   vam->result_ready = 1;
12309 }
12310
12311 static int
12312 api_ipfix_classify_table_dump (vat_main_t * vam)
12313 {
12314   vl_api_ipfix_classify_table_dump_t *mp;
12315   vl_api_control_ping_t *mp_ping;
12316   int ret;
12317
12318   if (!vam->json_output)
12319     {
12320       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12321              "transport_protocol");
12322     }
12323
12324   /* Construct the API message */
12325   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
12326
12327   /* send it... */
12328   S (mp);
12329
12330   /* Use a control ping for synchronization */
12331   MPING (CONTROL_PING, mp_ping);
12332   S (mp_ping);
12333
12334   W (ret);
12335   return ret;
12336 }
12337
12338 static void
12339   vl_api_ipfix_classify_table_details_t_handler
12340   (vl_api_ipfix_classify_table_details_t * mp)
12341 {
12342   vat_main_t *vam = &vat_main;
12343   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12344          mp->transport_protocol);
12345 }
12346
12347 static void
12348   vl_api_ipfix_classify_table_details_t_handler_json
12349   (vl_api_ipfix_classify_table_details_t * mp)
12350 {
12351   vat_json_node_t *node = NULL;
12352   vat_main_t *vam = &vat_main;
12353
12354   if (VAT_JSON_ARRAY != vam->json_tree.type)
12355     {
12356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12357       vat_json_init_array (&vam->json_tree);
12358     }
12359
12360   node = vat_json_array_add (&vam->json_tree);
12361   vat_json_init_object (node);
12362
12363   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12364   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12365   vat_json_object_add_uint (node, "transport_protocol",
12366                             mp->transport_protocol);
12367 }
12368
12369 static int
12370 api_sw_interface_span_enable_disable (vat_main_t * vam)
12371 {
12372   unformat_input_t *i = vam->input;
12373   vl_api_sw_interface_span_enable_disable_t *mp;
12374   u32 src_sw_if_index = ~0;
12375   u32 dst_sw_if_index = ~0;
12376   u8 state = 3;
12377   int ret;
12378   u8 is_l2 = 0;
12379
12380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12381     {
12382       if (unformat
12383           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12384         ;
12385       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12386         ;
12387       else
12388         if (unformat
12389             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12390         ;
12391       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12392         ;
12393       else if (unformat (i, "disable"))
12394         state = 0;
12395       else if (unformat (i, "rx"))
12396         state = 1;
12397       else if (unformat (i, "tx"))
12398         state = 2;
12399       else if (unformat (i, "both"))
12400         state = 3;
12401       else if (unformat (i, "l2"))
12402         is_l2 = 1;
12403       else
12404         break;
12405     }
12406
12407   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
12408
12409   mp->sw_if_index_from = htonl (src_sw_if_index);
12410   mp->sw_if_index_to = htonl (dst_sw_if_index);
12411   mp->state = state;
12412   mp->is_l2 = is_l2;
12413
12414   S (mp);
12415   W (ret);
12416   return ret;
12417 }
12418
12419 static void
12420 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12421                                             * mp)
12422 {
12423   vat_main_t *vam = &vat_main;
12424   u8 *sw_if_from_name = 0;
12425   u8 *sw_if_to_name = 0;
12426   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12427   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12428   char *states[] = { "none", "rx", "tx", "both" };
12429   hash_pair_t *p;
12430
12431   /* *INDENT-OFF* */
12432   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12433   ({
12434     if ((u32) p->value[0] == sw_if_index_from)
12435       {
12436         sw_if_from_name = (u8 *)(p->key);
12437         if (sw_if_to_name)
12438           break;
12439       }
12440     if ((u32) p->value[0] == sw_if_index_to)
12441       {
12442         sw_if_to_name = (u8 *)(p->key);
12443         if (sw_if_from_name)
12444           break;
12445       }
12446   }));
12447   /* *INDENT-ON* */
12448   print (vam->ofp, "%20s => %20s (%s) %s",
12449          sw_if_from_name, sw_if_to_name, states[mp->state],
12450          mp->is_l2 ? "l2" : "device");
12451 }
12452
12453 static void
12454   vl_api_sw_interface_span_details_t_handler_json
12455   (vl_api_sw_interface_span_details_t * mp)
12456 {
12457   vat_main_t *vam = &vat_main;
12458   vat_json_node_t *node = NULL;
12459   u8 *sw_if_from_name = 0;
12460   u8 *sw_if_to_name = 0;
12461   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12462   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12463   hash_pair_t *p;
12464
12465   /* *INDENT-OFF* */
12466   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12467   ({
12468     if ((u32) p->value[0] == sw_if_index_from)
12469       {
12470         sw_if_from_name = (u8 *)(p->key);
12471         if (sw_if_to_name)
12472           break;
12473       }
12474     if ((u32) p->value[0] == sw_if_index_to)
12475       {
12476         sw_if_to_name = (u8 *)(p->key);
12477         if (sw_if_from_name)
12478           break;
12479       }
12480   }));
12481   /* *INDENT-ON* */
12482
12483   if (VAT_JSON_ARRAY != vam->json_tree.type)
12484     {
12485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12486       vat_json_init_array (&vam->json_tree);
12487     }
12488   node = vat_json_array_add (&vam->json_tree);
12489
12490   vat_json_init_object (node);
12491   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12492   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12493   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
12494   if (0 != sw_if_to_name)
12495     {
12496       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12497     }
12498   vat_json_object_add_uint (node, "state", mp->state);
12499   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
12500 }
12501
12502 static int
12503 api_sw_interface_span_dump (vat_main_t * vam)
12504 {
12505   unformat_input_t *input = vam->input;
12506   vl_api_sw_interface_span_dump_t *mp;
12507   vl_api_control_ping_t *mp_ping;
12508   u8 is_l2 = 0;
12509   int ret;
12510
12511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (input, "l2"))
12514         is_l2 = 1;
12515       else
12516         break;
12517     }
12518
12519   M (SW_INTERFACE_SPAN_DUMP, mp);
12520   mp->is_l2 = is_l2;
12521   S (mp);
12522
12523   /* Use a control ping for synchronization */
12524   MPING (CONTROL_PING, mp_ping);
12525   S (mp_ping);
12526
12527   W (ret);
12528   return ret;
12529 }
12530
12531 int
12532 api_pg_create_interface (vat_main_t * vam)
12533 {
12534   unformat_input_t *input = vam->input;
12535   vl_api_pg_create_interface_t *mp;
12536
12537   u32 if_id = ~0, gso_size = 0;
12538   u8 gso_enabled = 0;
12539   int ret;
12540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12541     {
12542       if (unformat (input, "if_id %d", &if_id))
12543         ;
12544       else if (unformat (input, "gso-enabled"))
12545         {
12546           gso_enabled = 1;
12547           if (unformat (input, "gso-size %u", &gso_size))
12548             ;
12549           else
12550             {
12551               errmsg ("missing gso-size");
12552               return -99;
12553             }
12554         }
12555       else
12556         break;
12557     }
12558   if (if_id == ~0)
12559     {
12560       errmsg ("missing pg interface index");
12561       return -99;
12562     }
12563
12564   /* Construct the API message */
12565   M (PG_CREATE_INTERFACE, mp);
12566   mp->context = 0;
12567   mp->interface_id = ntohl (if_id);
12568   mp->gso_enabled = gso_enabled;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 int
12576 api_pg_capture (vat_main_t * vam)
12577 {
12578   unformat_input_t *input = vam->input;
12579   vl_api_pg_capture_t *mp;
12580
12581   u32 if_id = ~0;
12582   u8 enable = 1;
12583   u32 count = 1;
12584   u8 pcap_file_set = 0;
12585   u8 *pcap_file = 0;
12586   int ret;
12587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12588     {
12589       if (unformat (input, "if_id %d", &if_id))
12590         ;
12591       else if (unformat (input, "pcap %s", &pcap_file))
12592         pcap_file_set = 1;
12593       else if (unformat (input, "count %d", &count))
12594         ;
12595       else if (unformat (input, "disable"))
12596         enable = 0;
12597       else
12598         break;
12599     }
12600   if (if_id == ~0)
12601     {
12602       errmsg ("missing pg interface index");
12603       return -99;
12604     }
12605   if (pcap_file_set > 0)
12606     {
12607       if (vec_len (pcap_file) > 255)
12608         {
12609           errmsg ("pcap file name is too long");
12610           return -99;
12611         }
12612     }
12613
12614   /* Construct the API message */
12615   M (PG_CAPTURE, mp);
12616   mp->context = 0;
12617   mp->interface_id = ntohl (if_id);
12618   mp->is_enabled = enable;
12619   mp->count = ntohl (count);
12620   if (pcap_file_set != 0)
12621     {
12622       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
12623     }
12624   vec_free (pcap_file);
12625
12626   S (mp);
12627   W (ret);
12628   return ret;
12629 }
12630
12631 int
12632 api_pg_enable_disable (vat_main_t * vam)
12633 {
12634   unformat_input_t *input = vam->input;
12635   vl_api_pg_enable_disable_t *mp;
12636
12637   u8 enable = 1;
12638   u8 stream_name_set = 0;
12639   u8 *stream_name = 0;
12640   int ret;
12641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12642     {
12643       if (unformat (input, "stream %s", &stream_name))
12644         stream_name_set = 1;
12645       else if (unformat (input, "disable"))
12646         enable = 0;
12647       else
12648         break;
12649     }
12650
12651   if (stream_name_set > 0)
12652     {
12653       if (vec_len (stream_name) > 255)
12654         {
12655           errmsg ("stream name too long");
12656           return -99;
12657         }
12658     }
12659
12660   /* Construct the API message */
12661   M (PG_ENABLE_DISABLE, mp);
12662   mp->context = 0;
12663   mp->is_enabled = enable;
12664   if (stream_name_set != 0)
12665     {
12666       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
12667     }
12668   vec_free (stream_name);
12669
12670   S (mp);
12671   W (ret);
12672   return ret;
12673 }
12674
12675 int
12676 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12677 {
12678   unformat_input_t *input = vam->input;
12679   vl_api_pg_interface_enable_disable_coalesce_t *mp;
12680
12681   u32 sw_if_index = ~0;
12682   u8 enable = 1;
12683   int ret;
12684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12685     {
12686       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12687         ;
12688       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12689         ;
12690       else if (unformat (input, "disable"))
12691         enable = 0;
12692       else
12693         break;
12694     }
12695
12696   if (sw_if_index == ~0)
12697     {
12698       errmsg ("Interface required but not specified");
12699       return -99;
12700     }
12701
12702   /* Construct the API message */
12703   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12704   mp->context = 0;
12705   mp->coalesce_enabled = enable;
12706   mp->sw_if_index = htonl (sw_if_index);
12707
12708   S (mp);
12709   W (ret);
12710   return ret;
12711 }
12712
12713 int
12714 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12715 {
12716   unformat_input_t *input = vam->input;
12717   vl_api_ip_source_and_port_range_check_add_del_t *mp;
12718
12719   u16 *low_ports = 0;
12720   u16 *high_ports = 0;
12721   u16 this_low;
12722   u16 this_hi;
12723   vl_api_prefix_t prefix;
12724   u32 tmp, tmp2;
12725   u8 prefix_set = 0;
12726   u32 vrf_id = ~0;
12727   u8 is_add = 1;
12728   int ret;
12729
12730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12731     {
12732       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12733         prefix_set = 1;
12734       else if (unformat (input, "vrf %d", &vrf_id))
12735         ;
12736       else if (unformat (input, "del"))
12737         is_add = 0;
12738       else if (unformat (input, "port %d", &tmp))
12739         {
12740           if (tmp == 0 || tmp > 65535)
12741             {
12742               errmsg ("port %d out of range", tmp);
12743               return -99;
12744             }
12745           this_low = tmp;
12746           this_hi = this_low + 1;
12747           vec_add1 (low_ports, this_low);
12748           vec_add1 (high_ports, this_hi);
12749         }
12750       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
12751         {
12752           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
12753             {
12754               errmsg ("incorrect range parameters");
12755               return -99;
12756             }
12757           this_low = tmp;
12758           /* Note: in debug CLI +1 is added to high before
12759              passing to real fn that does "the work"
12760              (ip_source_and_port_range_check_add_del).
12761              This fn is a wrapper around the binary API fn a
12762              control plane will call, which expects this increment
12763              to have occurred. Hence letting the binary API control
12764              plane fn do the increment for consistency between VAT
12765              and other control planes.
12766            */
12767           this_hi = tmp2;
12768           vec_add1 (low_ports, this_low);
12769           vec_add1 (high_ports, this_hi);
12770         }
12771       else
12772         break;
12773     }
12774
12775   if (prefix_set == 0)
12776     {
12777       errmsg ("<address>/<mask> not specified");
12778       return -99;
12779     }
12780
12781   if (vrf_id == ~0)
12782     {
12783       errmsg ("VRF ID required, not specified");
12784       return -99;
12785     }
12786
12787   if (vrf_id == 0)
12788     {
12789       errmsg
12790         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12791       return -99;
12792     }
12793
12794   if (vec_len (low_ports) == 0)
12795     {
12796       errmsg ("At least one port or port range required");
12797       return -99;
12798     }
12799
12800   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
12801
12802   mp->is_add = is_add;
12803
12804   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
12805
12806   mp->number_of_ranges = vec_len (low_ports);
12807
12808   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
12809   vec_free (low_ports);
12810
12811   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
12812   vec_free (high_ports);
12813
12814   mp->vrf_id = ntohl (vrf_id);
12815
12816   S (mp);
12817   W (ret);
12818   return ret;
12819 }
12820
12821 int
12822 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
12823 {
12824   unformat_input_t *input = vam->input;
12825   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
12826   u32 sw_if_index = ~0;
12827   int vrf_set = 0;
12828   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
12829   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
12830   u8 is_add = 1;
12831   int ret;
12832
12833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12834     {
12835       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12836         ;
12837       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12838         ;
12839       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
12840         vrf_set = 1;
12841       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
12842         vrf_set = 1;
12843       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
12844         vrf_set = 1;
12845       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
12846         vrf_set = 1;
12847       else if (unformat (input, "del"))
12848         is_add = 0;
12849       else
12850         break;
12851     }
12852
12853   if (sw_if_index == ~0)
12854     {
12855       errmsg ("Interface required but not specified");
12856       return -99;
12857     }
12858
12859   if (vrf_set == 0)
12860     {
12861       errmsg ("VRF ID required but not specified");
12862       return -99;
12863     }
12864
12865   if (tcp_out_vrf_id == 0
12866       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
12867     {
12868       errmsg
12869         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12870       return -99;
12871     }
12872
12873   /* Construct the API message */
12874   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
12875
12876   mp->sw_if_index = ntohl (sw_if_index);
12877   mp->is_add = is_add;
12878   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
12879   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
12880   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
12881   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
12882
12883   /* send it... */
12884   S (mp);
12885
12886   /* Wait for a reply... */
12887   W (ret);
12888   return ret;
12889 }
12890
12891 static int
12892 api_set_punt (vat_main_t * vam)
12893 {
12894   unformat_input_t *i = vam->input;
12895   vl_api_address_family_t af;
12896   vl_api_set_punt_t *mp;
12897   u32 protocol = ~0;
12898   u32 port = ~0;
12899   int is_add = 1;
12900   int ret;
12901
12902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12903     {
12904       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
12905         ;
12906       else if (unformat (i, "protocol %d", &protocol))
12907         ;
12908       else if (unformat (i, "port %d", &port))
12909         ;
12910       else if (unformat (i, "del"))
12911         is_add = 0;
12912       else
12913         {
12914           clib_warning ("parse error '%U'", format_unformat_error, i);
12915           return -99;
12916         }
12917     }
12918
12919   M (SET_PUNT, mp);
12920
12921   mp->is_add = (u8) is_add;
12922   mp->punt.type = PUNT_API_TYPE_L4;
12923   mp->punt.punt.l4.af = af;
12924   mp->punt.punt.l4.protocol = (u8) protocol;
12925   mp->punt.punt.l4.port = htons ((u16) port);
12926
12927   S (mp);
12928   W (ret);
12929   return ret;
12930 }
12931
12932 static int
12933 api_delete_subif (vat_main_t * vam)
12934 {
12935   unformat_input_t *i = vam->input;
12936   vl_api_delete_subif_t *mp;
12937   u32 sw_if_index = ~0;
12938   int ret;
12939
12940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12941     {
12942       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12943         ;
12944       if (unformat (i, "sw_if_index %d", &sw_if_index))
12945         ;
12946       else
12947         break;
12948     }
12949
12950   if (sw_if_index == ~0)
12951     {
12952       errmsg ("missing sw_if_index");
12953       return -99;
12954     }
12955
12956   /* Construct the API message */
12957   M (DELETE_SUBIF, mp);
12958   mp->sw_if_index = ntohl (sw_if_index);
12959
12960   S (mp);
12961   W (ret);
12962   return ret;
12963 }
12964
12965 #define foreach_pbb_vtr_op      \
12966 _("disable",  L2_VTR_DISABLED)  \
12967 _("pop",  L2_VTR_POP_2)         \
12968 _("push",  L2_VTR_PUSH_2)
12969
12970 static int
12971 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
12972 {
12973   unformat_input_t *i = vam->input;
12974   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
12975   u32 sw_if_index = ~0, vtr_op = ~0;
12976   u16 outer_tag = ~0;
12977   u8 dmac[6], smac[6];
12978   u8 dmac_set = 0, smac_set = 0;
12979   u16 vlanid = 0;
12980   u32 sid = ~0;
12981   u32 tmp;
12982   int ret;
12983
12984   /* Shut up coverity */
12985   clib_memset (dmac, 0, sizeof (dmac));
12986   clib_memset (smac, 0, sizeof (smac));
12987
12988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12989     {
12990       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12991         ;
12992       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12993         ;
12994       else if (unformat (i, "vtr_op %d", &vtr_op))
12995         ;
12996 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
12997       foreach_pbb_vtr_op
12998 #undef _
12999         else if (unformat (i, "translate_pbb_stag"))
13000         {
13001           if (unformat (i, "%d", &tmp))
13002             {
13003               vtr_op = L2_VTR_TRANSLATE_2_1;
13004               outer_tag = tmp;
13005             }
13006           else
13007             {
13008               errmsg
13009                 ("translate_pbb_stag operation requires outer tag definition");
13010               return -99;
13011             }
13012         }
13013       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13014         dmac_set++;
13015       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13016         smac_set++;
13017       else if (unformat (i, "sid %d", &sid))
13018         ;
13019       else if (unformat (i, "vlanid %d", &tmp))
13020         vlanid = tmp;
13021       else
13022         {
13023           clib_warning ("parse error '%U'", format_unformat_error, i);
13024           return -99;
13025         }
13026     }
13027
13028   if ((sw_if_index == ~0) || (vtr_op == ~0))
13029     {
13030       errmsg ("missing sw_if_index or vtr operation");
13031       return -99;
13032     }
13033   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13034       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13035     {
13036       errmsg
13037         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13038       return -99;
13039     }
13040
13041   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
13042   mp->sw_if_index = ntohl (sw_if_index);
13043   mp->vtr_op = ntohl (vtr_op);
13044   mp->outer_tag = ntohs (outer_tag);
13045   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13046   clib_memcpy (mp->b_smac, smac, sizeof (smac));
13047   mp->b_vlanid = ntohs (vlanid);
13048   mp->i_sid = ntohl (sid);
13049
13050   S (mp);
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_flow_classify_set_interface (vat_main_t * vam)
13057 {
13058   unformat_input_t *i = vam->input;
13059   vl_api_flow_classify_set_interface_t *mp;
13060   u32 sw_if_index;
13061   int sw_if_index_set;
13062   u32 ip4_table_index = ~0;
13063   u32 ip6_table_index = ~0;
13064   u8 is_add = 1;
13065   int ret;
13066
13067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13070         sw_if_index_set = 1;
13071       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13072         sw_if_index_set = 1;
13073       else if (unformat (i, "del"))
13074         is_add = 0;
13075       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13076         ;
13077       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13078         ;
13079       else
13080         {
13081           clib_warning ("parse error '%U'", format_unformat_error, i);
13082           return -99;
13083         }
13084     }
13085
13086   if (sw_if_index_set == 0)
13087     {
13088       errmsg ("missing interface name or sw_if_index");
13089       return -99;
13090     }
13091
13092   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
13093
13094   mp->sw_if_index = ntohl (sw_if_index);
13095   mp->ip4_table_index = ntohl (ip4_table_index);
13096   mp->ip6_table_index = ntohl (ip6_table_index);
13097   mp->is_add = is_add;
13098
13099   S (mp);
13100   W (ret);
13101   return ret;
13102 }
13103
13104 static int
13105 api_flow_classify_dump (vat_main_t * vam)
13106 {
13107   unformat_input_t *i = vam->input;
13108   vl_api_flow_classify_dump_t *mp;
13109   vl_api_control_ping_t *mp_ping;
13110   u8 type = FLOW_CLASSIFY_N_TABLES;
13111   int ret;
13112
13113   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13114     ;
13115   else
13116     {
13117       errmsg ("classify table type must be specified");
13118       return -99;
13119     }
13120
13121   if (!vam->json_output)
13122     {
13123       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13124     }
13125
13126   M (FLOW_CLASSIFY_DUMP, mp);
13127   mp->type = type;
13128   /* send it... */
13129   S (mp);
13130
13131   /* Use a control ping for synchronization */
13132   MPING (CONTROL_PING, mp_ping);
13133   S (mp_ping);
13134
13135   /* Wait for a reply... */
13136   W (ret);
13137   return ret;
13138 }
13139
13140 static int
13141 api_feature_enable_disable (vat_main_t * vam)
13142 {
13143   unformat_input_t *i = vam->input;
13144   vl_api_feature_enable_disable_t *mp;
13145   u8 *arc_name = 0;
13146   u8 *feature_name = 0;
13147   u32 sw_if_index = ~0;
13148   u8 enable = 1;
13149   int ret;
13150
13151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13152     {
13153       if (unformat (i, "arc_name %s", &arc_name))
13154         ;
13155       else if (unformat (i, "feature_name %s", &feature_name))
13156         ;
13157       else
13158         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13159         ;
13160       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13161         ;
13162       else if (unformat (i, "disable"))
13163         enable = 0;
13164       else
13165         break;
13166     }
13167
13168   if (arc_name == 0)
13169     {
13170       errmsg ("missing arc name");
13171       return -99;
13172     }
13173   if (vec_len (arc_name) > 63)
13174     {
13175       errmsg ("arc name too long");
13176     }
13177
13178   if (feature_name == 0)
13179     {
13180       errmsg ("missing feature name");
13181       return -99;
13182     }
13183   if (vec_len (feature_name) > 63)
13184     {
13185       errmsg ("feature name too long");
13186     }
13187
13188   if (sw_if_index == ~0)
13189     {
13190       errmsg ("missing interface name or sw_if_index");
13191       return -99;
13192     }
13193
13194   /* Construct the API message */
13195   M (FEATURE_ENABLE_DISABLE, mp);
13196   mp->sw_if_index = ntohl (sw_if_index);
13197   mp->enable = enable;
13198   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13199   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13200   vec_free (arc_name);
13201   vec_free (feature_name);
13202
13203   S (mp);
13204   W (ret);
13205   return ret;
13206 }
13207
13208 static int
13209 api_feature_gso_enable_disable (vat_main_t * vam)
13210 {
13211   unformat_input_t *i = vam->input;
13212   vl_api_feature_gso_enable_disable_t *mp;
13213   u32 sw_if_index = ~0;
13214   u8 enable = 1;
13215   int ret;
13216
13217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13218     {
13219       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13220         ;
13221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13222         ;
13223       else if (unformat (i, "enable"))
13224         enable = 1;
13225       else if (unformat (i, "disable"))
13226         enable = 0;
13227       else
13228         break;
13229     }
13230
13231   if (sw_if_index == ~0)
13232     {
13233       errmsg ("missing interface name or sw_if_index");
13234       return -99;
13235     }
13236
13237   /* Construct the API message */
13238   M (FEATURE_GSO_ENABLE_DISABLE, mp);
13239   mp->sw_if_index = ntohl (sw_if_index);
13240   mp->enable_disable = enable;
13241
13242   S (mp);
13243   W (ret);
13244   return ret;
13245 }
13246
13247 static int
13248 api_sw_interface_tag_add_del (vat_main_t * vam)
13249 {
13250   unformat_input_t *i = vam->input;
13251   vl_api_sw_interface_tag_add_del_t *mp;
13252   u32 sw_if_index = ~0;
13253   u8 *tag = 0;
13254   u8 enable = 1;
13255   int ret;
13256
13257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (i, "tag %s", &tag))
13260         ;
13261       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13262         ;
13263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13264         ;
13265       else if (unformat (i, "del"))
13266         enable = 0;
13267       else
13268         break;
13269     }
13270
13271   if (sw_if_index == ~0)
13272     {
13273       errmsg ("missing interface name or sw_if_index");
13274       return -99;
13275     }
13276
13277   if (enable && (tag == 0))
13278     {
13279       errmsg ("no tag specified");
13280       return -99;
13281     }
13282
13283   /* Construct the API message */
13284   M (SW_INTERFACE_TAG_ADD_DEL, mp);
13285   mp->sw_if_index = ntohl (sw_if_index);
13286   mp->is_add = enable;
13287   if (enable)
13288     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13289   vec_free (tag);
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static int
13297 api_sw_interface_add_del_mac_address (vat_main_t * vam)
13298 {
13299   unformat_input_t *i = vam->input;
13300   vl_api_mac_address_t mac = { 0 };
13301   vl_api_sw_interface_add_del_mac_address_t *mp;
13302   u32 sw_if_index = ~0;
13303   u8 is_add = 1;
13304   u8 mac_set = 0;
13305   int ret;
13306
13307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13308     {
13309       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13310         ;
13311       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13312         ;
13313       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13314         mac_set++;
13315       else if (unformat (i, "del"))
13316         is_add = 0;
13317       else
13318         break;
13319     }
13320
13321   if (sw_if_index == ~0)
13322     {
13323       errmsg ("missing interface name or sw_if_index");
13324       return -99;
13325     }
13326
13327   if (!mac_set)
13328     {
13329       errmsg ("missing MAC address");
13330       return -99;
13331     }
13332
13333   /* Construct the API message */
13334   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13335   mp->sw_if_index = ntohl (sw_if_index);
13336   mp->is_add = is_add;
13337   clib_memcpy (&mp->addr, &mac, sizeof (mac));
13338
13339   S (mp);
13340   W (ret);
13341   return ret;
13342 }
13343
13344 static void vl_api_l2_xconnect_details_t_handler
13345   (vl_api_l2_xconnect_details_t * mp)
13346 {
13347   vat_main_t *vam = &vat_main;
13348
13349   print (vam->ofp, "%15d%15d",
13350          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13351 }
13352
13353 static void vl_api_l2_xconnect_details_t_handler_json
13354   (vl_api_l2_xconnect_details_t * mp)
13355 {
13356   vat_main_t *vam = &vat_main;
13357   vat_json_node_t *node = NULL;
13358
13359   if (VAT_JSON_ARRAY != vam->json_tree.type)
13360     {
13361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13362       vat_json_init_array (&vam->json_tree);
13363     }
13364   node = vat_json_array_add (&vam->json_tree);
13365
13366   vat_json_init_object (node);
13367   vat_json_object_add_uint (node, "rx_sw_if_index",
13368                             ntohl (mp->rx_sw_if_index));
13369   vat_json_object_add_uint (node, "tx_sw_if_index",
13370                             ntohl (mp->tx_sw_if_index));
13371 }
13372
13373 static int
13374 api_l2_xconnect_dump (vat_main_t * vam)
13375 {
13376   vl_api_l2_xconnect_dump_t *mp;
13377   vl_api_control_ping_t *mp_ping;
13378   int ret;
13379
13380   if (!vam->json_output)
13381     {
13382       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13383     }
13384
13385   M (L2_XCONNECT_DUMP, mp);
13386
13387   S (mp);
13388
13389   /* Use a control ping for synchronization */
13390   MPING (CONTROL_PING, mp_ping);
13391   S (mp_ping);
13392
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_hw_interface_set_mtu (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_hw_interface_set_mtu_t *mp;
13402   u32 sw_if_index = ~0;
13403   u32 mtu = 0;
13404   int ret;
13405
13406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13407     {
13408       if (unformat (i, "mtu %d", &mtu))
13409         ;
13410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13411         ;
13412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13413         ;
13414       else
13415         break;
13416     }
13417
13418   if (sw_if_index == ~0)
13419     {
13420       errmsg ("missing interface name or sw_if_index");
13421       return -99;
13422     }
13423
13424   if (mtu == 0)
13425     {
13426       errmsg ("no mtu specified");
13427       return -99;
13428     }
13429
13430   /* Construct the API message */
13431   M (HW_INTERFACE_SET_MTU, mp);
13432   mp->sw_if_index = ntohl (sw_if_index);
13433   mp->mtu = ntohs ((u16) mtu);
13434
13435   S (mp);
13436   W (ret);
13437   return ret;
13438 }
13439
13440 static int
13441 api_p2p_ethernet_add (vat_main_t * vam)
13442 {
13443   unformat_input_t *i = vam->input;
13444   vl_api_p2p_ethernet_add_t *mp;
13445   u32 parent_if_index = ~0;
13446   u32 sub_id = ~0;
13447   u8 remote_mac[6];
13448   u8 mac_set = 0;
13449   int ret;
13450
13451   clib_memset (remote_mac, 0, sizeof (remote_mac));
13452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13453     {
13454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13455         ;
13456       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13457         ;
13458       else
13459         if (unformat
13460             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13461         mac_set++;
13462       else if (unformat (i, "sub_id %d", &sub_id))
13463         ;
13464       else
13465         {
13466           clib_warning ("parse error '%U'", format_unformat_error, i);
13467           return -99;
13468         }
13469     }
13470
13471   if (parent_if_index == ~0)
13472     {
13473       errmsg ("missing interface name or sw_if_index");
13474       return -99;
13475     }
13476   if (mac_set == 0)
13477     {
13478       errmsg ("missing remote mac address");
13479       return -99;
13480     }
13481   if (sub_id == ~0)
13482     {
13483       errmsg ("missing sub-interface id");
13484       return -99;
13485     }
13486
13487   M (P2P_ETHERNET_ADD, mp);
13488   mp->parent_if_index = ntohl (parent_if_index);
13489   mp->subif_id = ntohl (sub_id);
13490   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13491
13492   S (mp);
13493   W (ret);
13494   return ret;
13495 }
13496
13497 static int
13498 api_p2p_ethernet_del (vat_main_t * vam)
13499 {
13500   unformat_input_t *i = vam->input;
13501   vl_api_p2p_ethernet_del_t *mp;
13502   u32 parent_if_index = ~0;
13503   u8 remote_mac[6];
13504   u8 mac_set = 0;
13505   int ret;
13506
13507   clib_memset (remote_mac, 0, sizeof (remote_mac));
13508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509     {
13510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13511         ;
13512       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13513         ;
13514       else
13515         if (unformat
13516             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13517         mac_set++;
13518       else
13519         {
13520           clib_warning ("parse error '%U'", format_unformat_error, i);
13521           return -99;
13522         }
13523     }
13524
13525   if (parent_if_index == ~0)
13526     {
13527       errmsg ("missing interface name or sw_if_index");
13528       return -99;
13529     }
13530   if (mac_set == 0)
13531     {
13532       errmsg ("missing remote mac address");
13533       return -99;
13534     }
13535
13536   M (P2P_ETHERNET_DEL, mp);
13537   mp->parent_if_index = ntohl (parent_if_index);
13538   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13539
13540   S (mp);
13541   W (ret);
13542   return ret;
13543 }
13544
13545 static int
13546 api_tcp_configure_src_addresses (vat_main_t * vam)
13547 {
13548   vl_api_tcp_configure_src_addresses_t *mp;
13549   unformat_input_t *i = vam->input;
13550   vl_api_address_t first, last;
13551   u8 range_set = 0;
13552   u32 vrf_id = 0;
13553   int ret;
13554
13555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13556     {
13557       if (unformat (i, "%U - %U",
13558                     unformat_vl_api_address, &first,
13559                     unformat_vl_api_address, &last))
13560         {
13561           if (range_set)
13562             {
13563               errmsg ("one range per message (range already set)");
13564               return -99;
13565             }
13566           range_set = 1;
13567         }
13568       else if (unformat (i, "vrf %d", &vrf_id))
13569         ;
13570       else
13571         break;
13572     }
13573
13574   if (range_set == 0)
13575     {
13576       errmsg ("address range not set");
13577       return -99;
13578     }
13579
13580   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
13581
13582   mp->vrf_id = ntohl (vrf_id);
13583   clib_memcpy (&mp->first_address, &first, sizeof (first));
13584   clib_memcpy (&mp->last_address, &last, sizeof (last));
13585
13586   S (mp);
13587   W (ret);
13588   return ret;
13589 }
13590
13591 static void vl_api_app_namespace_add_del_reply_t_handler
13592   (vl_api_app_namespace_add_del_reply_t * mp)
13593 {
13594   vat_main_t *vam = &vat_main;
13595   i32 retval = ntohl (mp->retval);
13596   if (vam->async_mode)
13597     {
13598       vam->async_errors += (retval < 0);
13599     }
13600   else
13601     {
13602       vam->retval = retval;
13603       if (retval == 0)
13604         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13605       vam->result_ready = 1;
13606     }
13607 }
13608
13609 static void vl_api_app_namespace_add_del_reply_t_handler_json
13610   (vl_api_app_namespace_add_del_reply_t * mp)
13611 {
13612   vat_main_t *vam = &vat_main;
13613   vat_json_node_t node;
13614
13615   vat_json_init_object (&node);
13616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13617   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13618
13619   vat_json_print (vam->ofp, &node);
13620   vat_json_free (&node);
13621
13622   vam->retval = ntohl (mp->retval);
13623   vam->result_ready = 1;
13624 }
13625
13626 static int
13627 api_app_namespace_add_del (vat_main_t * vam)
13628 {
13629   vl_api_app_namespace_add_del_t *mp;
13630   unformat_input_t *i = vam->input;
13631   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13632   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13633   u64 secret;
13634   int ret;
13635
13636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13637     {
13638       if (unformat (i, "id %_%v%_", &ns_id))
13639         ;
13640       else if (unformat (i, "secret %lu", &secret))
13641         secret_set = 1;
13642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13643         sw_if_index_set = 1;
13644       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13645         ;
13646       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13647         ;
13648       else
13649         break;
13650     }
13651   if (!ns_id || !secret_set || !sw_if_index_set)
13652     {
13653       errmsg ("namespace id, secret and sw_if_index must be set");
13654       return -99;
13655     }
13656   if (vec_len (ns_id) > 64)
13657     {
13658       errmsg ("namespace id too long");
13659       return -99;
13660     }
13661   M (APP_NAMESPACE_ADD_DEL, mp);
13662
13663   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
13664   mp->secret = clib_host_to_net_u64 (secret);
13665   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13666   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13667   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13668   vec_free (ns_id);
13669   S (mp);
13670   W (ret);
13671   return ret;
13672 }
13673
13674 static int
13675 api_sock_init_shm (vat_main_t * vam)
13676 {
13677 #if VPP_API_TEST_BUILTIN == 0
13678   unformat_input_t *i = vam->input;
13679   vl_api_shm_elem_config_t *config = 0;
13680   u64 size = 64 << 20;
13681   int rv;
13682
13683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13684     {
13685       if (unformat (i, "size %U", unformat_memory_size, &size))
13686         ;
13687       else
13688         break;
13689     }
13690
13691   /*
13692    * Canned custom ring allocator config.
13693    * Should probably parse all of this
13694    */
13695   vec_validate (config, 6);
13696   config[0].type = VL_API_VLIB_RING;
13697   config[0].size = 256;
13698   config[0].count = 32;
13699
13700   config[1].type = VL_API_VLIB_RING;
13701   config[1].size = 1024;
13702   config[1].count = 16;
13703
13704   config[2].type = VL_API_VLIB_RING;
13705   config[2].size = 4096;
13706   config[2].count = 2;
13707
13708   config[3].type = VL_API_CLIENT_RING;
13709   config[3].size = 256;
13710   config[3].count = 32;
13711
13712   config[4].type = VL_API_CLIENT_RING;
13713   config[4].size = 1024;
13714   config[4].count = 16;
13715
13716   config[5].type = VL_API_CLIENT_RING;
13717   config[5].size = 4096;
13718   config[5].count = 2;
13719
13720   config[6].type = VL_API_QUEUE;
13721   config[6].count = 128;
13722   config[6].size = sizeof (uword);
13723
13724   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
13725   if (!rv)
13726     vam->client_index_invalid = 1;
13727   return rv;
13728 #else
13729   return -99;
13730 #endif
13731 }
13732
13733 static void
13734 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13735 {
13736   vat_main_t *vam = &vat_main;
13737   fib_prefix_t lcl, rmt;
13738
13739   ip_prefix_decode (&mp->lcl, &lcl);
13740   ip_prefix_decode (&mp->rmt, &rmt);
13741
13742   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13743     {
13744       print (vam->ofp,
13745              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13746              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13747              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
13748              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
13749              &rmt.fp_addr.ip4, rmt.fp_len,
13750              clib_net_to_host_u16 (mp->rmt_port),
13751              clib_net_to_host_u32 (mp->action_index), mp->tag);
13752     }
13753   else
13754     {
13755       print (vam->ofp,
13756              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13757              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13758              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
13759              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
13760              &rmt.fp_addr.ip6, rmt.fp_len,
13761              clib_net_to_host_u16 (mp->rmt_port),
13762              clib_net_to_host_u32 (mp->action_index), mp->tag);
13763     }
13764 }
13765
13766 static void
13767 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
13768                                              mp)
13769 {
13770   vat_main_t *vam = &vat_main;
13771   vat_json_node_t *node = NULL;
13772   struct in6_addr ip6;
13773   struct in_addr ip4;
13774
13775   fib_prefix_t lcl, rmt;
13776
13777   ip_prefix_decode (&mp->lcl, &lcl);
13778   ip_prefix_decode (&mp->rmt, &rmt);
13779
13780   if (VAT_JSON_ARRAY != vam->json_tree.type)
13781     {
13782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13783       vat_json_init_array (&vam->json_tree);
13784     }
13785   node = vat_json_array_add (&vam->json_tree);
13786   vat_json_init_object (node);
13787
13788   vat_json_object_add_uint (node, "appns_index",
13789                             clib_net_to_host_u32 (mp->appns_index));
13790   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
13791   vat_json_object_add_uint (node, "scope", mp->scope);
13792   vat_json_object_add_uint (node, "action_index",
13793                             clib_net_to_host_u32 (mp->action_index));
13794   vat_json_object_add_uint (node, "lcl_port",
13795                             clib_net_to_host_u16 (mp->lcl_port));
13796   vat_json_object_add_uint (node, "rmt_port",
13797                             clib_net_to_host_u16 (mp->rmt_port));
13798   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
13799   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
13800   vat_json_object_add_string_copy (node, "tag", mp->tag);
13801   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13802     {
13803       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
13804       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
13805       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
13806       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
13807     }
13808   else
13809     {
13810       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
13811       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
13812       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
13813       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
13814     }
13815 }
13816
13817 static int
13818 api_session_rule_add_del (vat_main_t * vam)
13819 {
13820   vl_api_session_rule_add_del_t *mp;
13821   unformat_input_t *i = vam->input;
13822   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
13823   u32 appns_index = 0, scope = 0;
13824   ip4_address_t lcl_ip4, rmt_ip4;
13825   ip6_address_t lcl_ip6, rmt_ip6;
13826   u8 is_ip4 = 1, conn_set = 0;
13827   u8 is_add = 1, *tag = 0;
13828   int ret;
13829   fib_prefix_t lcl, rmt;
13830
13831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13832     {
13833       if (unformat (i, "del"))
13834         is_add = 0;
13835       else if (unformat (i, "add"))
13836         ;
13837       else if (unformat (i, "proto tcp"))
13838         proto = 0;
13839       else if (unformat (i, "proto udp"))
13840         proto = 1;
13841       else if (unformat (i, "appns %d", &appns_index))
13842         ;
13843       else if (unformat (i, "scope %d", &scope))
13844         ;
13845       else if (unformat (i, "tag %_%v%_", &tag))
13846         ;
13847       else
13848         if (unformat
13849             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
13850              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
13851              &rmt_port))
13852         {
13853           is_ip4 = 1;
13854           conn_set = 1;
13855         }
13856       else
13857         if (unformat
13858             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
13859              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
13860              &rmt_port))
13861         {
13862           is_ip4 = 0;
13863           conn_set = 1;
13864         }
13865       else if (unformat (i, "action %d", &action))
13866         ;
13867       else
13868         break;
13869     }
13870   if (proto == ~0 || !conn_set || action == ~0)
13871     {
13872       errmsg ("transport proto, connection and action must be set");
13873       return -99;
13874     }
13875
13876   if (scope > 3)
13877     {
13878       errmsg ("scope should be 0-3");
13879       return -99;
13880     }
13881
13882   M (SESSION_RULE_ADD_DEL, mp);
13883
13884   clib_memset (&lcl, 0, sizeof (lcl));
13885   clib_memset (&rmt, 0, sizeof (rmt));
13886   if (is_ip4)
13887     {
13888       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
13889       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
13890       lcl.fp_len = lcl_plen;
13891       rmt.fp_len = rmt_plen;
13892     }
13893   else
13894     {
13895       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
13896       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
13897       lcl.fp_len = lcl_plen;
13898       rmt.fp_len = rmt_plen;
13899     }
13900
13901
13902   ip_prefix_encode (&lcl, &mp->lcl);
13903   ip_prefix_encode (&rmt, &mp->rmt);
13904   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
13905   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
13906   mp->transport_proto =
13907     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
13908   mp->action_index = clib_host_to_net_u32 (action);
13909   mp->appns_index = clib_host_to_net_u32 (appns_index);
13910   mp->scope = scope;
13911   mp->is_add = is_add;
13912   if (tag)
13913     {
13914       clib_memcpy (mp->tag, tag, vec_len (tag));
13915       vec_free (tag);
13916     }
13917
13918   S (mp);
13919   W (ret);
13920   return ret;
13921 }
13922
13923 static int
13924 api_session_rules_dump (vat_main_t * vam)
13925 {
13926   vl_api_session_rules_dump_t *mp;
13927   vl_api_control_ping_t *mp_ping;
13928   int ret;
13929
13930   if (!vam->json_output)
13931     {
13932       print (vam->ofp, "%=20s", "Session Rules");
13933     }
13934
13935   M (SESSION_RULES_DUMP, mp);
13936   /* send it... */
13937   S (mp);
13938
13939   /* Use a control ping for synchronization */
13940   MPING (CONTROL_PING, mp_ping);
13941   S (mp_ping);
13942
13943   /* Wait for a reply... */
13944   W (ret);
13945   return ret;
13946 }
13947
13948 static int
13949 api_ip_container_proxy_add_del (vat_main_t * vam)
13950 {
13951   vl_api_ip_container_proxy_add_del_t *mp;
13952   unformat_input_t *i = vam->input;
13953   u32 sw_if_index = ~0;
13954   vl_api_prefix_t pfx = { };
13955   u8 is_add = 1;
13956   int ret;
13957
13958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13959     {
13960       if (unformat (i, "del"))
13961         is_add = 0;
13962       else if (unformat (i, "add"))
13963         ;
13964       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
13965         ;
13966       else if (unformat (i, "sw_if_index %u", &sw_if_index))
13967         ;
13968       else
13969         break;
13970     }
13971   if (sw_if_index == ~0 || pfx.len == 0)
13972     {
13973       errmsg ("address and sw_if_index must be set");
13974       return -99;
13975     }
13976
13977   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
13978
13979   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13980   mp->is_add = is_add;
13981   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
13982
13983   S (mp);
13984   W (ret);
13985   return ret;
13986 }
13987
13988 static int
13989 api_qos_record_enable_disable (vat_main_t * vam)
13990 {
13991   unformat_input_t *i = vam->input;
13992   vl_api_qos_record_enable_disable_t *mp;
13993   u32 sw_if_index, qs = 0xff;
13994   u8 sw_if_index_set = 0;
13995   u8 enable = 1;
13996   int ret;
13997
13998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13999     {
14000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14001         sw_if_index_set = 1;
14002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14003         sw_if_index_set = 1;
14004       else if (unformat (i, "%U", unformat_qos_source, &qs))
14005         ;
14006       else if (unformat (i, "disable"))
14007         enable = 0;
14008       else
14009         {
14010           clib_warning ("parse error '%U'", format_unformat_error, i);
14011           return -99;
14012         }
14013     }
14014
14015   if (sw_if_index_set == 0)
14016     {
14017       errmsg ("missing interface name or sw_if_index");
14018       return -99;
14019     }
14020   if (qs == 0xff)
14021     {
14022       errmsg ("input location must be specified");
14023       return -99;
14024     }
14025
14026   M (QOS_RECORD_ENABLE_DISABLE, mp);
14027
14028   mp->record.sw_if_index = ntohl (sw_if_index);
14029   mp->record.input_source = qs;
14030   mp->enable = enable;
14031
14032   S (mp);
14033   W (ret);
14034   return ret;
14035 }
14036
14037
14038 static int
14039 q_or_quit (vat_main_t * vam)
14040 {
14041 #if VPP_API_TEST_BUILTIN == 0
14042   longjmp (vam->jump_buf, 1);
14043 #endif
14044   return 0;                     /* not so much */
14045 }
14046
14047 static int
14048 q (vat_main_t * vam)
14049 {
14050   return q_or_quit (vam);
14051 }
14052
14053 static int
14054 quit (vat_main_t * vam)
14055 {
14056   return q_or_quit (vam);
14057 }
14058
14059 static int
14060 comment (vat_main_t * vam)
14061 {
14062   return 0;
14063 }
14064
14065 static int
14066 elog_save (vat_main_t * vam)
14067 {
14068 #if VPP_API_TEST_BUILTIN == 0
14069   elog_main_t *em = &vam->elog_main;
14070   unformat_input_t *i = vam->input;
14071   char *file, *chroot_file;
14072   clib_error_t *error;
14073
14074   if (!unformat (i, "%s", &file))
14075     {
14076       errmsg ("expected file name, got `%U'", format_unformat_error, i);
14077       return 0;
14078     }
14079
14080   /* It's fairly hard to get "../oopsie" through unformat; just in case */
14081   if (strstr (file, "..") || index (file, '/'))
14082     {
14083       errmsg ("illegal characters in filename '%s'", file);
14084       return 0;
14085     }
14086
14087   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14088
14089   vec_free (file);
14090
14091   errmsg ("Saving %wd of %wd events to %s",
14092           elog_n_events_in_buffer (em),
14093           elog_buffer_capacity (em), chroot_file);
14094
14095   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14096   vec_free (chroot_file);
14097
14098   if (error)
14099     clib_error_report (error);
14100 #else
14101   errmsg ("Use the vpp event loger...");
14102 #endif
14103
14104   return 0;
14105 }
14106
14107 static int
14108 elog_setup (vat_main_t * vam)
14109 {
14110 #if VPP_API_TEST_BUILTIN == 0
14111   elog_main_t *em = &vam->elog_main;
14112   unformat_input_t *i = vam->input;
14113   u32 nevents = 128 << 10;
14114
14115   (void) unformat (i, "nevents %d", &nevents);
14116
14117   elog_init (em, nevents);
14118   vl_api_set_elog_main (em);
14119   vl_api_set_elog_trace_api_messages (1);
14120   errmsg ("Event logger initialized with %u events", nevents);
14121 #else
14122   errmsg ("Use the vpp event loger...");
14123 #endif
14124   return 0;
14125 }
14126
14127 static int
14128 elog_enable (vat_main_t * vam)
14129 {
14130 #if VPP_API_TEST_BUILTIN == 0
14131   elog_main_t *em = &vam->elog_main;
14132
14133   elog_enable_disable (em, 1 /* enable */ );
14134   vl_api_set_elog_trace_api_messages (1);
14135   errmsg ("Event logger enabled...");
14136 #else
14137   errmsg ("Use the vpp event loger...");
14138 #endif
14139   return 0;
14140 }
14141
14142 static int
14143 elog_disable (vat_main_t * vam)
14144 {
14145 #if VPP_API_TEST_BUILTIN == 0
14146   elog_main_t *em = &vam->elog_main;
14147
14148   elog_enable_disable (em, 0 /* enable */ );
14149   vl_api_set_elog_trace_api_messages (1);
14150   errmsg ("Event logger disabled...");
14151 #else
14152   errmsg ("Use the vpp event loger...");
14153 #endif
14154   return 0;
14155 }
14156
14157 static int
14158 statseg (vat_main_t * vam)
14159 {
14160   ssvm_private_t *ssvmp = &vam->stat_segment;
14161   ssvm_shared_header_t *shared_header = ssvmp->sh;
14162   vlib_counter_t **counters;
14163   u64 thread0_index1_packets;
14164   u64 thread0_index1_bytes;
14165   f64 vector_rate, input_rate;
14166   uword *p;
14167
14168   uword *counter_vector_by_name;
14169   if (vam->stat_segment_lockp == 0)
14170     {
14171       errmsg ("Stat segment not mapped...");
14172       return -99;
14173     }
14174
14175   /* look up "/if/rx for sw_if_index 1 as a test */
14176
14177   clib_spinlock_lock (vam->stat_segment_lockp);
14178
14179   counter_vector_by_name = (uword *) shared_header->opaque[1];
14180
14181   p = hash_get_mem (counter_vector_by_name, "/if/rx");
14182   if (p == 0)
14183     {
14184       clib_spinlock_unlock (vam->stat_segment_lockp);
14185       errmsg ("/if/tx not found?");
14186       return -99;
14187     }
14188
14189   /* Fish per-thread vector of combined counters from shared memory */
14190   counters = (vlib_counter_t **) p[0];
14191
14192   if (vec_len (counters[0]) < 2)
14193     {
14194       clib_spinlock_unlock (vam->stat_segment_lockp);
14195       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14196       return -99;
14197     }
14198
14199   /* Read thread 0 sw_if_index 1 counter */
14200   thread0_index1_packets = counters[0][1].packets;
14201   thread0_index1_bytes = counters[0][1].bytes;
14202
14203   p = hash_get_mem (counter_vector_by_name, "vector_rate");
14204   if (p == 0)
14205     {
14206       clib_spinlock_unlock (vam->stat_segment_lockp);
14207       errmsg ("vector_rate not found?");
14208       return -99;
14209     }
14210
14211   vector_rate = *(f64 *) (p[0]);
14212   p = hash_get_mem (counter_vector_by_name, "input_rate");
14213   if (p == 0)
14214     {
14215       clib_spinlock_unlock (vam->stat_segment_lockp);
14216       errmsg ("input_rate not found?");
14217       return -99;
14218     }
14219   input_rate = *(f64 *) (p[0]);
14220
14221   clib_spinlock_unlock (vam->stat_segment_lockp);
14222
14223   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14224          vector_rate, input_rate);
14225   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14226          thread0_index1_packets, thread0_index1_bytes);
14227
14228   return 0;
14229 }
14230
14231 static int
14232 cmd_cmp (void *a1, void *a2)
14233 {
14234   u8 **c1 = a1;
14235   u8 **c2 = a2;
14236
14237   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14238 }
14239
14240 static int
14241 help (vat_main_t * vam)
14242 {
14243   u8 **cmds = 0;
14244   u8 *name = 0;
14245   hash_pair_t *p;
14246   unformat_input_t *i = vam->input;
14247   int j;
14248
14249   if (unformat (i, "%s", &name))
14250     {
14251       uword *hs;
14252
14253       vec_add1 (name, 0);
14254
14255       hs = hash_get_mem (vam->help_by_name, name);
14256       if (hs)
14257         print (vam->ofp, "usage: %s %s", name, hs[0]);
14258       else
14259         print (vam->ofp, "No such msg / command '%s'", name);
14260       vec_free (name);
14261       return 0;
14262     }
14263
14264   print (vam->ofp, "Help is available for the following:");
14265
14266     /* *INDENT-OFF* */
14267     hash_foreach_pair (p, vam->function_by_name,
14268     ({
14269       vec_add1 (cmds, (u8 *)(p->key));
14270     }));
14271     /* *INDENT-ON* */
14272
14273   vec_sort_with_function (cmds, cmd_cmp);
14274
14275   for (j = 0; j < vec_len (cmds); j++)
14276     print (vam->ofp, "%s", cmds[j]);
14277
14278   vec_free (cmds);
14279   return 0;
14280 }
14281
14282 static int
14283 set (vat_main_t * vam)
14284 {
14285   u8 *name = 0, *value = 0;
14286   unformat_input_t *i = vam->input;
14287
14288   if (unformat (i, "%s", &name))
14289     {
14290       /* The input buffer is a vector, not a string. */
14291       value = vec_dup (i->buffer);
14292       vec_delete (value, i->index, 0);
14293       /* Almost certainly has a trailing newline */
14294       if (value[vec_len (value) - 1] == '\n')
14295         value[vec_len (value) - 1] = 0;
14296       /* Make sure it's a proper string, one way or the other */
14297       vec_add1 (value, 0);
14298       (void) clib_macro_set_value (&vam->macro_main,
14299                                    (char *) name, (char *) value);
14300     }
14301   else
14302     errmsg ("usage: set <name> <value>");
14303
14304   vec_free (name);
14305   vec_free (value);
14306   return 0;
14307 }
14308
14309 static int
14310 unset (vat_main_t * vam)
14311 {
14312   u8 *name = 0;
14313
14314   if (unformat (vam->input, "%s", &name))
14315     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14316       errmsg ("unset: %s wasn't set", name);
14317   vec_free (name);
14318   return 0;
14319 }
14320
14321 typedef struct
14322 {
14323   u8 *name;
14324   u8 *value;
14325 } macro_sort_t;
14326
14327
14328 static int
14329 macro_sort_cmp (void *a1, void *a2)
14330 {
14331   macro_sort_t *s1 = a1;
14332   macro_sort_t *s2 = a2;
14333
14334   return strcmp ((char *) (s1->name), (char *) (s2->name));
14335 }
14336
14337 static int
14338 dump_macro_table (vat_main_t * vam)
14339 {
14340   macro_sort_t *sort_me = 0, *sm;
14341   int i;
14342   hash_pair_t *p;
14343
14344     /* *INDENT-OFF* */
14345     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14346     ({
14347       vec_add2 (sort_me, sm, 1);
14348       sm->name = (u8 *)(p->key);
14349       sm->value = (u8 *) (p->value[0]);
14350     }));
14351     /* *INDENT-ON* */
14352
14353   vec_sort_with_function (sort_me, macro_sort_cmp);
14354
14355   if (vec_len (sort_me))
14356     print (vam->ofp, "%-15s%s", "Name", "Value");
14357   else
14358     print (vam->ofp, "The macro table is empty...");
14359
14360   for (i = 0; i < vec_len (sort_me); i++)
14361     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14362   return 0;
14363 }
14364
14365 static int
14366 dump_node_table (vat_main_t * vam)
14367 {
14368   int i, j;
14369   vlib_node_t *node, *next_node;
14370
14371   if (vec_len (vam->graph_nodes) == 0)
14372     {
14373       print (vam->ofp, "Node table empty, issue get_node_graph...");
14374       return 0;
14375     }
14376
14377   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
14378     {
14379       node = vam->graph_nodes[0][i];
14380       print (vam->ofp, "[%d] %s", i, node->name);
14381       for (j = 0; j < vec_len (node->next_nodes); j++)
14382         {
14383           if (node->next_nodes[j] != ~0)
14384             {
14385               next_node = vam->graph_nodes[0][node->next_nodes[j]];
14386               print (vam->ofp, "  [%d] %s", j, next_node->name);
14387             }
14388         }
14389     }
14390   return 0;
14391 }
14392
14393 static int
14394 value_sort_cmp (void *a1, void *a2)
14395 {
14396   name_sort_t *n1 = a1;
14397   name_sort_t *n2 = a2;
14398
14399   if (n1->value < n2->value)
14400     return -1;
14401   if (n1->value > n2->value)
14402     return 1;
14403   return 0;
14404 }
14405
14406
14407 static int
14408 dump_msg_api_table (vat_main_t * vam)
14409 {
14410   api_main_t *am = vlibapi_get_main ();
14411   name_sort_t *nses = 0, *ns;
14412   hash_pair_t *hp;
14413   int i;
14414
14415   /* *INDENT-OFF* */
14416   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14417   ({
14418     vec_add2 (nses, ns, 1);
14419     ns->name = (u8 *)(hp->key);
14420     ns->value = (u32) hp->value[0];
14421   }));
14422   /* *INDENT-ON* */
14423
14424   vec_sort_with_function (nses, value_sort_cmp);
14425
14426   for (i = 0; i < vec_len (nses); i++)
14427     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14428   vec_free (nses);
14429   return 0;
14430 }
14431
14432 static int
14433 get_msg_id (vat_main_t * vam)
14434 {
14435   u8 *name_and_crc;
14436   u32 message_index;
14437
14438   if (unformat (vam->input, "%s", &name_and_crc))
14439     {
14440       message_index = vl_msg_api_get_msg_index (name_and_crc);
14441       if (message_index == ~0)
14442         {
14443           print (vam->ofp, " '%s' not found", name_and_crc);
14444           return 0;
14445         }
14446       print (vam->ofp, " '%s' has message index %d",
14447              name_and_crc, message_index);
14448       return 0;
14449     }
14450   errmsg ("name_and_crc required...");
14451   return 0;
14452 }
14453
14454 static int
14455 search_node_table (vat_main_t * vam)
14456 {
14457   unformat_input_t *line_input = vam->input;
14458   u8 *node_to_find;
14459   int j;
14460   vlib_node_t *node, *next_node;
14461   uword *p;
14462
14463   if (vam->graph_node_index_by_name == 0)
14464     {
14465       print (vam->ofp, "Node table empty, issue get_node_graph...");
14466       return 0;
14467     }
14468
14469   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14470     {
14471       if (unformat (line_input, "%s", &node_to_find))
14472         {
14473           vec_add1 (node_to_find, 0);
14474           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14475           if (p == 0)
14476             {
14477               print (vam->ofp, "%s not found...", node_to_find);
14478               goto out;
14479             }
14480           node = vam->graph_nodes[0][p[0]];
14481           print (vam->ofp, "[%d] %s", p[0], node->name);
14482           for (j = 0; j < vec_len (node->next_nodes); j++)
14483             {
14484               if (node->next_nodes[j] != ~0)
14485                 {
14486                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
14487                   print (vam->ofp, "  [%d] %s", j, next_node->name);
14488                 }
14489             }
14490         }
14491
14492       else
14493         {
14494           clib_warning ("parse error '%U'", format_unformat_error,
14495                         line_input);
14496           return -99;
14497         }
14498
14499     out:
14500       vec_free (node_to_find);
14501
14502     }
14503
14504   return 0;
14505 }
14506
14507
14508 static int
14509 script (vat_main_t * vam)
14510 {
14511 #if (VPP_API_TEST_BUILTIN==0)
14512   u8 *s = 0;
14513   char *save_current_file;
14514   unformat_input_t save_input;
14515   jmp_buf save_jump_buf;
14516   u32 save_line_number;
14517
14518   FILE *new_fp, *save_ifp;
14519
14520   if (unformat (vam->input, "%s", &s))
14521     {
14522       new_fp = fopen ((char *) s, "r");
14523       if (new_fp == 0)
14524         {
14525           errmsg ("Couldn't open script file %s", s);
14526           vec_free (s);
14527           return -99;
14528         }
14529     }
14530   else
14531     {
14532       errmsg ("Missing script name");
14533       return -99;
14534     }
14535
14536   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14537   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14538   save_ifp = vam->ifp;
14539   save_line_number = vam->input_line_number;
14540   save_current_file = (char *) vam->current_file;
14541
14542   vam->input_line_number = 0;
14543   vam->ifp = new_fp;
14544   vam->current_file = s;
14545   do_one_file (vam);
14546
14547   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
14548   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14549   vam->ifp = save_ifp;
14550   vam->input_line_number = save_line_number;
14551   vam->current_file = (u8 *) save_current_file;
14552   vec_free (s);
14553
14554   return 0;
14555 #else
14556   clib_warning ("use the exec command...");
14557   return -99;
14558 #endif
14559 }
14560
14561 static int
14562 echo (vat_main_t * vam)
14563 {
14564   print (vam->ofp, "%v", vam->input->buffer);
14565   return 0;
14566 }
14567
14568 /* List of API message constructors, CLI names map to api_xxx */
14569 #define foreach_vpe_api_msg                                             \
14570 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
14571 _(sw_interface_dump,"")                                                 \
14572 _(sw_interface_set_flags,                                               \
14573   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14574 _(sw_interface_add_del_address,                                         \
14575   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
14576 _(sw_interface_set_rx_mode,                                             \
14577   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
14578 _(sw_interface_set_rx_placement,                                        \
14579   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
14580 _(sw_interface_rx_placement_dump,                                       \
14581   "[<intfc> | sw_if_index <id>]")                                         \
14582 _(sw_interface_set_table,                                               \
14583   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
14584 _(sw_interface_set_mpls_enable,                                         \
14585   "<intfc> | sw_if_index [disable | dis]")                              \
14586 _(sw_interface_set_vpath,                                               \
14587   "<intfc> | sw_if_index <id> enable | disable")                        \
14588 _(sw_interface_set_vxlan_bypass,                                        \
14589   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
14590 _(sw_interface_set_l2_xconnect,                                         \
14591   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14592   "enable | disable")                                                   \
14593 _(sw_interface_set_l2_bridge,                                           \
14594   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
14595   "[shg <split-horizon-group>] [bvi]\n"                                 \
14596   "enable | disable")                                                   \
14597 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
14598 _(bridge_domain_add_del,                                                \
14599   "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") \
14600 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
14601 _(l2fib_add_del,                                                        \
14602   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
14603 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
14604 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
14605 _(l2_flags,                                                             \
14606   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14607 _(bridge_flags,                                                         \
14608   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14609 _(tap_create_v2,                                                        \
14610   "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]") \
14611 _(tap_delete_v2,                                                        \
14612   "<vpp-if-name> | sw_if_index <id>")                                   \
14613 _(sw_interface_tap_v2_dump, "")                                         \
14614 _(virtio_pci_create_v2,                                                    \
14615   "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]") \
14616 _(virtio_pci_delete,                                                    \
14617   "<vpp-if-name> | sw_if_index <id>")                                   \
14618 _(sw_interface_virtio_pci_dump, "")                                     \
14619 _(bond_create,                                                          \
14620   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
14621   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14622   "[id <if-id>]")                                                       \
14623 _(bond_create2,                                                         \
14624   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
14625   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14626   "[id <if-id>] [gso]")                                                 \
14627 _(bond_delete,                                                          \
14628   "<vpp-if-name> | sw_if_index <id>")                                   \
14629 _(bond_add_member,                                                      \
14630   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
14631 _(bond_detach_member,                                                   \
14632   "sw_if_index <n>")                                                    \
14633  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
14634  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
14635  _(sw_member_interface_dump,                                            \
14636   "<vpp-if-name> | sw_if_index <id>")                                   \
14637 _(ip_table_add_del,                                                     \
14638   "table <n> [ipv6] [add | del]\n")                                     \
14639 _(ip_route_add_del,                                                     \
14640   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14641   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
14642   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
14643   "[multipath] [count <n>] [del]")                                      \
14644 _(ip_mroute_add_del,                                                    \
14645   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
14646   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
14647 _(mpls_table_add_del,                                                   \
14648   "table <n> [add | del]\n")                                            \
14649 _(mpls_route_add_del,                                                   \
14650   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
14651   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
14652   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
14653   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
14654   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
14655   "[count <n>] [del]")                                                  \
14656 _(mpls_ip_bind_unbind,                                                  \
14657   "<label> <addr/len>")                                                 \
14658 _(mpls_tunnel_add_del,                                                  \
14659   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14660   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
14661   "[l2-only]  [out-label <n>]")                                         \
14662 _(sr_mpls_policy_add,                                                   \
14663   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
14664 _(sr_mpls_policy_del,                                                   \
14665   "bsid <id>")                                                          \
14666 _(sw_interface_set_unnumbered,                                          \
14667   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
14668 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
14669 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
14670   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
14671   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
14672   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
14673 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
14674 _(ip_table_flush, "table <n> [ipv6]")                                   \
14675 _(ip_table_replace_end, "table <n> [ipv6]")                             \
14676 _(set_ip_flow_hash,                                                     \
14677   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
14678 _(sw_interface_ip6_enable_disable,                                      \
14679   "<intfc> | sw_if_index <id> enable | disable")                        \
14680 _(l2_patch_add_del,                                                     \
14681   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14682   "enable | disable")                                                   \
14683 _(sr_localsid_add_del,                                                  \
14684   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
14685   "fib-table <num> (end.psp) sw_if_index <num>")                        \
14686 _(classify_add_del_table,                                               \
14687   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
14688   " [del] [del-chain] mask <mask-value>\n"                              \
14689   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
14690   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
14691 _(classify_add_del_session,                                             \
14692   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
14693   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
14694   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
14695   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
14696 _(classify_set_interface_ip_table,                                      \
14697   "<intfc> | sw_if_index <nn> table <nn>")                              \
14698 _(classify_set_interface_l2_tables,                                     \
14699   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14700   "  [other-table <nn>]")                                               \
14701 _(get_node_index, "node <node-name")                                    \
14702 _(add_node_next, "node <node-name> next <next-node-name>")              \
14703 _(vxlan_offload_rx,                                                     \
14704   "hw { <interface name> | hw_if_index <nn>} "                          \
14705   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
14706 _(vxlan_add_del_tunnel,                                                 \
14707   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
14708   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
14709   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
14710 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
14711 _(l2_fib_clear_table, "")                                               \
14712 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
14713 _(l2_interface_vlan_tag_rewrite,                                        \
14714   "<intfc> | sw_if_index <nn> \n"                                       \
14715   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
14716   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
14717 _(create_vhost_user_if,                                                 \
14718         "socket <filename> [server] [renumber <dev_instance>] "         \
14719         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14720         "[mac <mac_address>] [packed]")                                 \
14721 _(modify_vhost_user_if,                                                 \
14722         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14723         "[server] [renumber <dev_instance>] [gso] [packed]")            \
14724 _(create_vhost_user_if_v2,                                              \
14725         "socket <filename> [server] [renumber <dev_instance>] "         \
14726         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14727         "[mac <mac_address>] [packed] [event-idx]")                     \
14728 _(modify_vhost_user_if_v2,                                              \
14729         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14730         "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
14731 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
14732 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
14733 _(show_version, "")                                                     \
14734 _(show_threads, "")                                                     \
14735 _(vxlan_gpe_add_del_tunnel,                                             \
14736   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
14737   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
14738   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
14739   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
14740 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
14741 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
14742 _(interface_name_renumber,                                              \
14743   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
14744 _(input_acl_set_interface,                                              \
14745   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14746   "  [l2-table <nn>] [del]")                                            \
14747 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
14748 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
14749 _(ip_dump, "ipv4 | ipv6")                                               \
14750 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
14751 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
14752   "  spid_id <n> ")                                                     \
14753 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
14754   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
14755   "  integ_alg <alg> integ_key <hex>")                                  \
14756 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
14757   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
14758   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
14759   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
14760 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
14761 _(delete_loopback,"sw_if_index <nn>")                                   \
14762 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
14763 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
14764 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
14765 _(want_interface_events,  "enable|disable")                             \
14766 _(get_first_msg_id, "client <name>")                                    \
14767 _(get_node_graph, " ")                                                  \
14768 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
14769 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
14770 _(ioam_disable, "")                                                     \
14771 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
14772 _(af_packet_delete, "name <host interface name>")                       \
14773 _(af_packet_dump, "")                                                   \
14774 _(policer_add_del, "name <policer name> <params> [del]")                \
14775 _(policer_dump, "[name <policer name>]")                                \
14776 _(policer_classify_set_interface,                                       \
14777   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14778   "  [l2-table <nn>] [del]")                                            \
14779 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
14780 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
14781 _(mpls_table_dump, "")                                                  \
14782 _(mpls_route_dump, "table-id <ID>")                                     \
14783 _(classify_table_ids, "")                                               \
14784 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
14785 _(classify_table_info, "table_id <nn>")                                 \
14786 _(classify_session_dump, "table_id <nn>")                               \
14787 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
14788     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
14789     "[template_interval <nn>] [udp_checksum]")                          \
14790 _(ipfix_exporter_dump, "")                                              \
14791 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
14792 _(ipfix_classify_stream_dump, "")                                       \
14793 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
14794 _(ipfix_classify_table_dump, "")                                        \
14795 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
14796 _(sw_interface_span_dump, "[l2]")                                           \
14797 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
14798 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
14799 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
14800 _(pg_enable_disable, "[stream <id>] disable")                           \
14801 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
14802 _(ip_source_and_port_range_check_add_del,                               \
14803   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
14804 _(ip_source_and_port_range_check_interface_add_del,                     \
14805   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
14806   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
14807 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
14808 _(l2_interface_pbb_tag_rewrite,                                         \
14809   "<intfc> | sw_if_index <nn> \n"                                       \
14810   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
14811   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
14812 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
14813 _(flow_classify_set_interface,                                          \
14814   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
14815 _(flow_classify_dump, "type [ip4|ip6]")                                 \
14816 _(ip_table_dump, "")                                                    \
14817 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
14818 _(ip_mtable_dump, "")                                                   \
14819 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
14820 _(feature_enable_disable, "arc_name <arc_name> "                        \
14821   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
14822 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
14823   "[enable | disable] ")                                                \
14824 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
14825 "[disable]")                                                            \
14826 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
14827   "mac <mac-address> [del]")                                            \
14828 _(l2_xconnect_dump, "")                                                 \
14829 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
14830 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
14831 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
14832 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
14833 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
14834 _(sock_init_shm, "size <nnn>")                                          \
14835 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
14836 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
14837   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
14838 _(session_rules_dump, "")                                               \
14839 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
14840 _(output_acl_set_interface,                                             \
14841   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14842   "  [l2-table <nn>] [del]")                                            \
14843 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
14844
14845 /* List of command functions, CLI names map directly to functions */
14846 #define foreach_cli_function                                    \
14847 _(comment, "usage: comment <ignore-rest-of-line>")              \
14848 _(dump_interface_table, "usage: dump_interface_table")          \
14849 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
14850 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
14851 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
14852 _(dump_macro_table, "usage: dump_macro_table ")                 \
14853 _(dump_node_table, "usage: dump_node_table")                    \
14854 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
14855 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
14856 _(elog_disable, "usage: elog_disable")                          \
14857 _(elog_enable, "usage: elog_enable")                            \
14858 _(elog_save, "usage: elog_save <filename>")                     \
14859 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
14860 _(echo, "usage: echo <message>")                                \
14861 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
14862 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
14863 _(help, "usage: help")                                          \
14864 _(q, "usage: quit")                                             \
14865 _(quit, "usage: quit")                                          \
14866 _(search_node_table, "usage: search_node_table <name>...")      \
14867 _(set, "usage: set <variable-name> <value>")                    \
14868 _(script, "usage: script <file-name>")                          \
14869 _(statseg, "usage: statseg")                                    \
14870 _(unset, "usage: unset <variable-name>")
14871
14872 #define _(N,n)                                  \
14873     static void vl_api_##n##_t_handler_uni      \
14874     (vl_api_##n##_t * mp)                       \
14875     {                                           \
14876         vat_main_t * vam = &vat_main;           \
14877         if (vam->json_output) {                 \
14878             vl_api_##n##_t_handler_json(mp);    \
14879         } else {                                \
14880             vl_api_##n##_t_handler(mp);         \
14881         }                                       \
14882     }
14883 foreach_vpe_api_reply_msg;
14884 #if VPP_API_TEST_BUILTIN == 0
14885 foreach_standalone_reply_msg;
14886 #endif
14887 #undef _
14888
14889 void
14890 vat_api_hookup (vat_main_t * vam)
14891 {
14892 #define _(N,n)                                                  \
14893     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
14894                            vl_api_##n##_t_handler_uni,          \
14895                            vl_noop_handler,                     \
14896                            vl_api_##n##_t_endian,               \
14897                            vl_api_##n##_t_print,                \
14898                            sizeof(vl_api_##n##_t), 1);
14899   foreach_vpe_api_reply_msg;
14900 #if VPP_API_TEST_BUILTIN == 0
14901   foreach_standalone_reply_msg;
14902 #endif
14903 #undef _
14904
14905 #if (VPP_API_TEST_BUILTIN==0)
14906   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
14907
14908   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
14909
14910   vam->function_by_name = hash_create_string (0, sizeof (uword));
14911
14912   vam->help_by_name = hash_create_string (0, sizeof (uword));
14913 #endif
14914
14915   /* API messages we can send */
14916 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
14917   foreach_vpe_api_msg;
14918 #undef _
14919
14920   /* Help strings */
14921 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14922   foreach_vpe_api_msg;
14923 #undef _
14924
14925   /* CLI functions */
14926 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
14927   foreach_cli_function;
14928 #undef _
14929
14930   /* Help strings */
14931 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14932   foreach_cli_function;
14933 #undef _
14934 }
14935
14936 #if VPP_API_TEST_BUILTIN
14937 static clib_error_t *
14938 vat_api_hookup_shim (vlib_main_t * vm)
14939 {
14940   vat_api_hookup (&vat_main);
14941   return 0;
14942 }
14943
14944 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
14945 #endif
14946
14947 /*
14948  * fd.io coding-style-patch-verification: ON
14949  *
14950  * Local Variables:
14951  * eval: (c-set-style "gnu")
14952  * End:
14953  */